Version 1.15.0-dev.4.0

Merge commit '78b0f6f353b5349a50c3e38ef5f44ded1f7e1ee4' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 55db4b3..a4cf5bf 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -17,6 +17,10 @@
     The method now only supports one argument for the PEM file name containing
     the trusted certificates.
   * Added support to SecurityContext for PKCS12 certificate and key containers.
+  * All calls in `SecurityContext` that accept certificate data now accept an
+    optional named parameter `password`, similar to
+    `SecurityContext.usePrivateKeyBytes`, for use as the password for PKCS12
+    data.
 * `dart:async`
   * Made `StreamView` class a `const` class.
 
diff --git a/DEPS b/DEPS
index 702e439..274afa0 100644
--- a/DEPS
+++ b/DEPS
@@ -38,7 +38,7 @@
   "crypto_rev" : "@2df57a1e26dd88e8d0614207d4b062c73209917d",
   "csslib_tag" : "@0.12.0",
   "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
-  "dartdoc_tag" : "@v0.8.5",
+  "dartdoc_tag" : "@v0.9.0",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.4",
   "dev_compiler_rev": "@0.1.9",
@@ -52,7 +52,7 @@
   "intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@1.1.1",
-  "linter_rev": "@87f066f9243b36540c33186e742a798b87e76f8e",
+  "linter_rev": "@ce7aa0ec03ee738f4d314138228e0b4742845810",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
   "matcher_tag": "@0.12.0",
@@ -71,6 +71,7 @@
   "pub_cache_tag": "@v0.1.0",
   "pub_semver_tag": "@1.2.1",
   "quiver_tag": "@0.21.4",
+  "resource_rev":"@a49101ba2deb29c728acba6fb86000a8f730f4b1",
   "root_certificates_rev": "@c3a41df63afacec62fcb8135196177e35fe72f71",
   "scheduled_test_tag": "@0.12.4+2",
   "shelf_tag": "@0.6.4+3",
@@ -224,6 +225,8 @@
       Var("chromium_git")
       + "/external/github.com/google/quiver-dart.git"
       + Var("quiver_tag"),
+  Var("dart_root") + "/third_party/pkg/resource":
+    "https://github.com/dart-lang/resource.git" + Var("resource_rev"),
   Var("dart_root") + "/third_party/pkg/scheduled_test":
       (Var("github_mirror") % "scheduled_test") + Var("scheduled_test_tag"),
   Var("dart_root") + "/third_party/pkg/shelf":
diff --git a/create_sdk.gyp b/create_sdk.gyp
index 749cda5..b13adda 100644
--- a/create_sdk.gyp
+++ b/create_sdk.gyp
@@ -41,6 +41,8 @@
             '<(SHARED_INTERMEDIATE_DIR)/dartfmt.dart.snapshot',
             '<(SHARED_INTERMEDIATE_DIR)/analysis_server.dart.snapshot',
             '<(SHARED_INTERMEDIATE_DIR)/dartdoc.dart.snapshot',
+            '<(SHARED_INTERMEDIATE_DIR)/spec.sum',
+            '<(SHARED_INTERMEDIATE_DIR)/strong.sum',
             'tools/VERSION'
           ],
           'outputs': [
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index f2c4df2..fd1e1ef 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -757,17 +757,28 @@
           </dd><dt class="field"><b><i>packageRoots ( <span style="color:#999999">optional</span> Map&lt;<a href="#type_FilePath">FilePath</a>, <a href="#type_FilePath">FilePath</a>&gt; )</i></b></dt><dd>
             
             <p>
-              A mapping from source directories to target directories
+              A mapping from source directories to package roots
               that should override the normal package: URI resolution
-              mechanism.  The analyzer will behave as though each
+              mechanism.
+            </p>
+            <p>
+              If a package root is a directory, then
+              the analyzer will behave as though the associated
               source directory in the map contains a special
               pubspec.yaml file which resolves any package: URI to the
-              corresponding path within the target directory.  The
-              effect is the same as specifying the target directory as
+              corresponding path within that package root directory.  The
+              effect is the same as specifying the package root directory as
               a "--package_root" parameter to the Dart VM when
               executing any Dart file inside the source directory.
             </p>
             <p>
+              If a package root is a file, then the analyzer
+              will behave as though that file is a ".packages" file in the
+              source directory. The effect is the same as specifying the file
+              as a "--packages" parameter to the Dart VM when
+              executing any Dart file inside the source directory.
+            </p>
+            <p>
               Files in any directories that are not overridden by this
               mapping have their package: URI's resolved using the
               normal pubspec.yaml mechanism.  If this field is absent,
diff --git a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
index d90344f..eab48cd 100644
--- a/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
+++ b/pkg/analysis_server/lib/plugin/protocol/generated_protocol.dart
@@ -1663,12 +1663,19 @@
   }
 
   /**
-   * A mapping from source directories to target directories that should
-   * override the normal package: URI resolution mechanism. The analyzer will
-   * behave as though each source directory in the map contains a special
-   * pubspec.yaml file which resolves any package: URI to the corresponding
-   * path within the target directory. The effect is the same as specifying the
-   * target directory as a "--package_root" parameter to the Dart VM when
+   * A mapping from source directories to package roots that should override
+   * the normal package: URI resolution mechanism.
+   *
+   * If a package root is a directory, then the analyzer will behave as though
+   * the associated source directory in the map contains a special pubspec.yaml
+   * file which resolves any package: URI to the corresponding path within that
+   * package root directory. The effect is the same as specifying the package
+   * root directory as a "--package_root" parameter to the Dart VM when
+   * executing any Dart file inside the source directory.
+   *
+   * If a package root is a file, then the analyzer will behave as though that
+   * file is a ".packages" file in the source directory. The effect is the same
+   * as specifying the file as a "--packages" parameter to the Dart VM when
    * executing any Dart file inside the source directory.
    *
    * Files in any directories that are not overridden by this mapping have
@@ -1679,12 +1686,19 @@
   Map<String, String> get packageRoots => _packageRoots;
 
   /**
-   * A mapping from source directories to target directories that should
-   * override the normal package: URI resolution mechanism. The analyzer will
-   * behave as though each source directory in the map contains a special
-   * pubspec.yaml file which resolves any package: URI to the corresponding
-   * path within the target directory. The effect is the same as specifying the
-   * target directory as a "--package_root" parameter to the Dart VM when
+   * A mapping from source directories to package roots that should override
+   * the normal package: URI resolution mechanism.
+   *
+   * If a package root is a directory, then the analyzer will behave as though
+   * the associated source directory in the map contains a special pubspec.yaml
+   * file which resolves any package: URI to the corresponding path within that
+   * package root directory. The effect is the same as specifying the package
+   * root directory as a "--package_root" parameter to the Dart VM when
+   * executing any Dart file inside the source directory.
+   *
+   * If a package root is a file, then the analyzer will behave as though that
+   * file is a ".packages" file in the source directory. The effect is the same
+   * as specifying the file as a "--packages" parameter to the Dart VM when
    * executing any Dart file inside the source directory.
    *
    * Files in any directories that are not overridden by this mapping have
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 992cf55..8575086 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -960,10 +960,10 @@
     if (packageRoot != null) {
       // TODO(paulberry): We shouldn't be using JavaFile here because it
       // makes the code untestable (see dartbug.com/23909).
-      JavaFile packagesDir = new JavaFile(packageRoot);
+      JavaFile packagesDirOrFile = new JavaFile(packageRoot);
       Map<String, List<Folder>> packageMap = new Map<String, List<Folder>>();
-      if (packagesDir.isDirectory()) {
-        for (JavaFile file in packagesDir.listFiles()) {
+      if (packagesDirOrFile.isDirectory()) {
+        for (JavaFile file in packagesDirOrFile.listFiles()) {
           // Ensure symlinks in packages directory are canonicalized
           // to prevent 'type X cannot be assigned to type X' warnings
           String path;
@@ -980,6 +980,12 @@
           }
         }
         return new PackageMapDisposition(packageMap, packageRoot: packageRoot);
+      } else if (packagesDirOrFile.isFile()) {
+        File packageSpecFile = resourceProvider.getFile(packageRoot);
+        Packages packages = _readPackagespec(packageSpecFile);
+        if (packages != null) {
+          return new PackagesFileDisposition(packages);
+        }
       }
       // The package root does not exist (or is not a folder).  Since
       // [setRoots] ignores any package roots that don't exist (or aren't
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 36eb5b9..01ddada 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -1239,6 +1239,7 @@
       isFirst = false;
     }
     // merge getter/setter pairs into fields
+    String prefix = utils.getIndent(1);
     for (int i = 0; i < elements.length; i++) {
       ExecutableElement element = elements[i];
       if (element.kind == ElementKind.GETTER && i + 1 < elements.length) {
@@ -1249,9 +1250,16 @@
           elements.removeAt(i);
           i--;
           numElements--;
-          // add field
+          // separator
           addEolIfNotFirst();
-          sb.append(utils.getIndent(1));
+          // @override
+          {
+            sb.append(prefix);
+            sb.append('@override');
+            sb.append(eol);
+          }
+          // add field
+          sb.append(prefix);
           _appendType(sb, element.type.returnType, orVar: true);
           sb.append(element.name);
           sb.append(';');
diff --git a/pkg/analysis_server/lib/src/status/validator.dart b/pkg/analysis_server/lib/src/status/validator.dart
index 07f34b3..5651b8e 100644
--- a/pkg/analysis_server/lib/src/status/validator.dart
+++ b/pkg/analysis_server/lib/src/status/validator.dart
@@ -708,24 +708,6 @@
           (VariableElement element) =>
               element.isFinal ? 'a final $kind' : 'a non-final $kind');
     }
-    if (expected.isPotentiallyMutatedInClosure !=
-        actual.isPotentiallyMutatedInClosure) {
-      _writeMismatch(
-          expected,
-          actual,
-          (VariableElement element) => element.isPotentiallyMutatedInClosure
-              ? 'a $kind that is potentially mutated in a closure'
-              : 'a $kind that is not mutated in a closure');
-    }
-    if (expected.isPotentiallyMutatedInScope !=
-        actual.isPotentiallyMutatedInScope) {
-      _writeMismatch(
-          expected,
-          actual,
-          (VariableElement element) => element.isPotentiallyMutatedInScope
-              ? 'a $kind that is potentially mutated in its scope'
-              : 'a $kind that is not mutated in its scope');
-    }
     if (expected.isStatic != actual.isStatic) {
       _writeMismatch(
           expected,
diff --git a/pkg/analysis_server/test/integration/integration_test_methods.dart b/pkg/analysis_server/test/integration/integration_test_methods.dart
index af165f2..2508d56 100644
--- a/pkg/analysis_server/test/integration/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/integration_test_methods.dart
@@ -429,13 +429,20 @@
    *
    * packageRoots ( optional Map<FilePath, FilePath> )
    *
-   *   A mapping from source directories to target directories that should
-   *   override the normal package: URI resolution mechanism. The analyzer will
-   *   behave as though each source directory in the map contains a special
+   *   A mapping from source directories to package roots that should override
+   *   the normal package: URI resolution mechanism.
+   *
+   *   If a package root is a directory, then the analyzer will behave as
+   *   though the associated source directory in the map contains a special
    *   pubspec.yaml file which resolves any package: URI to the corresponding
-   *   path within the target directory. The effect is the same as specifying
-   *   the target directory as a "--package_root" parameter to the Dart VM when
-   *   executing any Dart file inside the source directory.
+   *   path within that package root directory. The effect is the same as
+   *   specifying the package root directory as a "--package_root" parameter to
+   *   the Dart VM when executing any Dart file inside the source directory.
+   *
+   *   If a package root is a file, then the analyzer will behave as though
+   *   that file is a ".packages" file in the source directory. The effect is
+   *   the same as specifying the file as a "--packages" parameter to the Dart
+   *   VM when executing any Dart file inside the source directory.
    *
    *   Files in any directories that are not overridden by this mapping have
    *   their package: URI's resolved using the normal pubspec.yaml mechanism.
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index dfb6a60..0d89134 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -2144,6 +2144,7 @@
 }
 
 class B implements A {
+  @override
   var f;
 }
 ''');
@@ -2336,8 +2337,10 @@
 }
 
 class B implements A {
+  @override
   int ma;
 
+  @override
   double mc;
 
   @override
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index e465571..8fb6d55 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -174,13 +174,17 @@
    * @param included A list of the files and directories that should be analyzed.
    * @param excluded A list of the files and directories within the included directories that should
    *         not be analyzed.
-   * @param packageRoots A mapping from source directories to target directories that should override
-   *         the normal package: URI resolution mechanism. The analyzer will behave as though each
-   *         source directory in the map contains a special pubspec.yaml file which resolves any
-   *         package: URI to the corresponding path within the target directory. The effect is the
-   *         same as specifying the target directory as a "--package_root" parameter to the Dart VM
-   *         when executing any Dart file inside the source directory. Files in any directories that
-   *         are not overridden by this mapping have their package: URI's resolved using the normal
+   * @param packageRoots A mapping from source directories to package roots that should override the
+   *         normal package: URI resolution mechanism. If a package root is a directory, then the
+   *         analyzer will behave as though the associated source directory in the map contains a
+   *         special pubspec.yaml file which resolves any package: URI to the corresponding path
+   *         within that package root directory. The effect is the same as specifying the package
+   *         root directory as a "--package_root" parameter to the Dart VM when executing any Dart
+   *         file inside the source directory. If a package root is a file, then the analyzer will
+   *         behave as though that file is a ".packages" file in the source directory. The effect is
+   *         the same as specifying the file as a "--packages" parameter to the Dart VM when
+   *         executing any Dart file inside the source directory. Files in any directories that are
+   *         not overridden by this mapping have their package: URI's resolved using the normal
    *         pubspec.yaml mechanism. If this field is absent, or the empty map is specified, that
    *         indicates that the normal pubspec.yaml mechanism should always be used.
    */
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index c26da51..fa4664f 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -615,17 +615,28 @@
               <value><ref>FilePath</ref></value>
             </map>
             <p>
-              A mapping from source directories to target directories
+              A mapping from source directories to package roots
               that should override the normal package: URI resolution
-              mechanism.  The analyzer will behave as though each
+              mechanism.
+            </p>
+            <p>
+              If a package root is a directory, then
+              the analyzer will behave as though the associated
               source directory in the map contains a special
               pubspec.yaml file which resolves any package: URI to the
-              corresponding path within the target directory.  The
-              effect is the same as specifying the target directory as
+              corresponding path within that package root directory.  The
+              effect is the same as specifying the package root directory as
               a "--package_root" parameter to the Dart VM when
               executing any Dart file inside the source directory.
             </p>
             <p>
+              If a package root is a file, then the analyzer
+              will behave as though that file is a ".packages" file in the
+              source directory. The effect is the same as specifying the file
+              as a "--packages" parameter to the Dart VM when
+              executing any Dart file inside the source directory.
+            </p>
+            <p>
               Files in any directories that are not overridden by this
               mapping have their package: URI's resolved using the
               normal pubspec.yaml mechanism.  If this field is absent,
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 598d611..547094b 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -536,7 +536,7 @@
    * (either AST nodes or tokens) that make up the contents of this node,
    * including doc comments but excluding other comments.
    */
-  Iterable /*<AstNode | Token>*/ get childEntities;
+  Iterable/*<AstNode | Token>*/ get childEntities;
 
   /**
    * Return the offset of the character immediately following the last character
@@ -591,7 +591,7 @@
    * Use the given [visitor] to visit this node. Return the value returned by
    * the visitor as a result of visiting this node.
    */
-  dynamic /* =E */ accept /*<E>*/ (AstVisitor /*<E>*/ visitor);
+  dynamic /* =E */ accept/*<E>*/(AstVisitor/*<E>*/ visitor);
 
   /**
    * Return the most immediate ancestor of this node for which the [predicate]
@@ -3994,7 +3994,7 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class FunctionExpressionInvocation extends Expression {
+abstract class FunctionExpressionInvocation extends InvocationExpression {
   /**
    * Initialize a newly created function expression invocation.
    */
@@ -4004,11 +4004,6 @@
       ArgumentList argumentList) = FunctionExpressionInvocationImpl;
 
   /**
-   * Return the list of arguments to the method.
-   */
-  ArgumentList get argumentList;
-
-  /**
    * Set the list of arguments to the method to the given [argumentList].
    */
   void set argumentList(ArgumentList argumentList);
@@ -4094,12 +4089,6 @@
   void set staticInvokeType(DartType type);
 
   /**
-   * Return the type arguments to be applied to the method being invoked, or
-   * `null` if no type arguments were provided.
-   */
-  TypeArgumentList get typeArguments;
-
-  /**
    * Set the type arguments to be applied to the method being invoked to the
    * given [typeArguments].
    */
@@ -4978,6 +4967,73 @@
 }
 
 /**
+ * The invocation of a function or method; either a
+ * [FunctionExpressionInvocation] or a [MethodInvocation].
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class InvocationExpression extends Expression {
+  /**
+   * Return the list of arguments to the method.
+   */
+  ArgumentList get argumentList;
+
+  /**
+   * The expression that identifies the function or method being invoked.
+   * For example:
+   *
+   *     (o.m)<TArgs>(args); // target will be `o.m`
+   *     o.m<TArgs>(args);   // target will be `m`
+   *
+   * In either case, the [function.staticType] will be the
+   * [staticInvokeType] before applying type arguments `TArgs`. Similarly,
+   * [function.propagatedType] will be the [propagatedInvokeType]
+   * before applying type arguments `TArgs`.
+   */
+  Expression get function;
+
+  /**
+   * Return the function type of the invocation based on the propagated type
+   * information, or `null` if the AST structure has not been resolved, or if
+   * the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType get propagatedInvokeType;
+
+  /**
+   * Sets the function type of the invocation based on the propagated type
+   * information.
+   */
+  void set propagatedInvokeType(DartType value);
+
+  /**
+   * Return the function type of the invocation based on the static type
+   * information, or `null` if the AST structure has not been resolved, or if
+   * the invoke could not be resolved.
+   *
+   * This will usually be a [FunctionType], but it can also be an
+   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
+   * interface type that implements `Function`.
+   */
+  DartType get staticInvokeType;
+
+  /**
+   * Sets the function type of the invocation based on the static type
+   * information.
+   */
+  void set staticInvokeType(DartType value);
+
+  /**
+   * Return the type arguments to be applied to the method being invoked, or
+   * `null` if no type arguments were provided.
+   */
+  TypeArgumentList get typeArguments;
+}
+
+/**
  * An is expression.
  *
  * > isExpression ::=
@@ -5519,7 +5575,7 @@
  *
  * Clients may not extend, implement or mix-in this class.
  */
-abstract class MethodInvocation extends Expression {
+abstract class MethodInvocation extends InvocationExpression {
   /**
    * Initialize a newly created method invocation. The [target] and [operator]
    * can be `null` if there is no target.
@@ -5532,11 +5588,6 @@
       ArgumentList argumentList) = MethodInvocationImpl;
 
   /**
-   * Return the list of arguments to the method.
-   */
-  ArgumentList get argumentList;
-
-  /**
    * Set the list of arguments to the method to the given [argumentList].
    */
   void set argumentList(ArgumentList argumentList);
@@ -5631,12 +5682,6 @@
   void set target(Expression expression);
 
   /**
-   * Return the type arguments to be applied to the method being invoked, or
-   * `null` if no type arguments were provided.
-   */
-  TypeArgumentList get typeArguments;
-
-  /**
    * Set the type arguments to be applied to the method being invoked to the
    * given [typeArguments].
    */
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 370f53e..d210229 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1911,7 +1911,12 @@
    * closure. This information is only available for local variables (including
    * parameters) and only after the compilation unit containing the variable has
    * been resolved.
+   *
+   * This getter is deprecated--it now returns `true` for all local variables
+   * and parameters.  Please use [FunctionBody.isPotentiallyMutatedInClosure]
+   * instead.
    */
+  @deprecated
   bool get isPotentiallyMutatedInClosure;
 
   /**
@@ -1919,7 +1924,12 @@
    * scope. This information is only available for local variables (including
    * parameters) and only after the compilation unit containing the variable has
    * been resolved.
+   *
+   * This getter is deprecated--it now returns `true` for all local variables
+   * and parameters.  Please use [FunctionBody.isPotentiallyMutatedInClosure]
+   * instead.
    */
+  @deprecated
   bool get isPotentiallyMutatedInScope;
 
   /**
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index afe0216..bbb0e69 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -7,6 +7,8 @@
 import 'dart:async';
 import 'dart:collection';
 
+import 'package:analyzer/src/dart/element/element.dart'
+    show ElementImpl, Modifier;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -239,7 +241,11 @@
           AnalysisEngine.instance.logger
               .logInformation('Removed the cache entry for $target.');
         }
-        return partition.remove(target);
+        CacheEntry entry = partition.remove(target);
+        if (entry != null) {
+          entry.dispose();
+        }
+        return entry;
       }
     }
     return null;
@@ -307,7 +313,11 @@
   Map<ResultDescriptor, ResultData> _resultMap =
       new HashMap<ResultDescriptor, ResultData>();
 
-  CacheEntry(this.target);
+  CacheEntry(this.target) {
+    if (target is ElementImpl) {
+      (target as ElementImpl).setModifier(Modifier.CACHE_KEY, true);
+    }
+  }
 
   /**
    * The exception that caused one or more values to have a state of
@@ -350,6 +360,9 @@
       }
     });
     _resultMap.clear();
+    if (target is ElementImpl) {
+      (target as ElementImpl).setModifier(Modifier.CACHE_KEY, false);
+    }
   }
 
   /**
@@ -384,7 +397,7 @@
    * Return the value of the result represented by the given [descriptor], or
    * the default value for the result if this entry does not have a valid value.
    */
-  dynamic /*=V*/ getValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor) {
+  dynamic/*=V*/ getValue/*<V>*/(ResultDescriptor/*<V>*/ descriptor) {
     ResultData data = _resultMap[descriptor];
     if (data == null) {
       return descriptor.defaultValue;
@@ -482,8 +495,8 @@
    * Set the value of the result represented by the given [descriptor] to the
    * given [value].
    */
-  void setValue /*<V>*/ (ResultDescriptor /*<V>*/ descriptor,
-      dynamic /*=V*/ value, List<TargetedResult> dependedOn) {
+  void setValue/*<V>*/(ResultDescriptor/*<V>*/ descriptor, dynamic/*=V*/ value,
+      List<TargetedResult> dependedOn) {
 //    {
 //      String valueStr = '$value';
 //      if (valueStr.length > 20) {
@@ -581,7 +594,10 @@
     _invalidateDependentResults(id, thisData, delta, level + 1);
     // If empty and not explicitly added, remove the entry altogether.
     if (_resultMap.isEmpty && !explicitlyAdded) {
-      _partition.entryMap.remove(target);
+      CacheEntry entry = _partition.entryMap.remove(target);
+      if (entry != null) {
+        entry.dispose();
+      }
       _partition._removeIfSource(target);
     }
     // Notify controller.
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index e931197..cc1d41e 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -725,7 +725,8 @@
     LibraryElementImpl mockLib = new LibraryElementImpl.forNode(
         this, AstFactory.libraryIdentifier2(["dart.async"]));
     mockLib.definingCompilationUnit = asyncUnit;
-    mockLib.publicNamespace = new PublicNamespaceBuilder().build(mockLib);
+    mockLib.publicNamespace =
+        new NamespaceBuilder().createPublicNamespaceForLibrary(mockLib);
     return mockLib;
   }
 
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 4a9826e..48332fb 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -5054,7 +5054,7 @@
  * > functionExpressionInvocation ::=
  * >     [Expression] [TypeArgumentList]? [ArgumentList]
  */
-class FunctionExpressionInvocationImpl extends ExpressionImpl
+class FunctionExpressionInvocationImpl extends InvocationExpressionImpl
     implements FunctionExpressionInvocation {
   /**
    * The expression producing the function being invoked.
@@ -5062,17 +5062,6 @@
   Expression _function;
 
   /**
-   * The type arguments to be applied to the method being invoked, or `null` if
-   * no type arguments were provided.
-   */
-  TypeArgumentList _typeArguments;
-
-  /**
-   * The list of arguments to the function.
-   */
-  ArgumentList _argumentList;
-
-  /**
    * The element associated with the function being invoked based on static type
    * information, or `null` if the AST structure has not been resolved or the
    * function could not be resolved.
@@ -5080,16 +5069,6 @@
   ExecutableElement staticElement;
 
   /**
-   * The function type of the method invocation, or `null` if the AST
-   * structure has not been resolved, or if the invoke could not be resolved.
-   *
-   * This will usually be a [FunctionType], but it can also be an
-   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
-   * interface type that implements `Function`.
-   */
-  DartType staticInvokeType;
-
-  /**
    * The element associated with the function being invoked based on propagated
    * type information, or `null` if the AST structure has not been resolved or
    * the function could not be resolved.
@@ -5097,26 +5076,12 @@
   ExecutableElement propagatedElement;
 
   /**
-   * Like [staticInvokeType], but reflects propagated type information.
-   */
-  DartType propagatedInvokeType;
-
-  /**
    * Initialize a newly created function expression invocation.
    */
   FunctionExpressionInvocationImpl(Expression function,
-      TypeArgumentList typeArguments, ArgumentList argumentList) {
+      TypeArgumentList typeArguments, ArgumentList argumentList)
+      : super(typeArguments, argumentList) {
     _function = _becomeParentOf(function);
-    _typeArguments = _becomeParentOf(typeArguments);
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  @override
-  ArgumentList get argumentList => _argumentList;
-
-  @override
-  void set argumentList(ArgumentList argumentList) {
-    _argumentList = _becomeParentOf(argumentList);
   }
 
   @override
@@ -5150,14 +5115,6 @@
   int get precedence => 15;
 
   @override
-  TypeArgumentList get typeArguments => _typeArguments;
-
-  @override
-  void set typeArguments(TypeArgumentList typeArguments) {
-    _typeArguments = _becomeParentOf(typeArguments);
-  }
-
-  @override
   accept(AstVisitor visitor) => visitor.visitFunctionExpressionInvocation(this);
 
   @override
@@ -6167,6 +6124,55 @@
 }
 
 /**
+ * Common base class for [FunctionExpressionInvocationImpl] and
+ * [MethodInvocationImpl].
+ */
+abstract class InvocationExpressionImpl extends ExpressionImpl
+    implements InvocationExpression {
+  /**
+   * The list of arguments to the function.
+   */
+  ArgumentList _argumentList;
+
+  /**
+   * The type arguments to be applied to the method being invoked, or `null` if
+   * no type arguments were provided.
+   */
+  TypeArgumentList _typeArguments;
+
+  @override
+  DartType propagatedInvokeType;
+
+  @override
+  DartType staticInvokeType;
+
+  /**
+   * Initialize a newly created invocation.
+   */
+  InvocationExpressionImpl(
+      TypeArgumentList typeArguments, ArgumentList argumentList) {
+    _typeArguments = _becomeParentOf(typeArguments);
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  ArgumentList get argumentList => _argumentList;
+
+  @override
+  void set argumentList(ArgumentList argumentList) {
+    _argumentList = _becomeParentOf(argumentList);
+  }
+
+  @override
+  TypeArgumentList get typeArguments => _typeArguments;
+
+  @override
+  void set typeArguments(TypeArgumentList typeArguments) {
+    _typeArguments = _becomeParentOf(typeArguments);
+  }
+}
+
+/**
  * An is expression.
  *
  * > isExpression ::=
@@ -6959,7 +6965,8 @@
  * > methodInvocation ::=
  * >     ([Expression] '.')? [SimpleIdentifier] [TypeArgumentList]? [ArgumentList]
  */
-class MethodInvocationImpl extends ExpressionImpl implements MethodInvocation {
+class MethodInvocationImpl extends InvocationExpressionImpl
+    implements MethodInvocation {
   /**
    * The expression producing the object on which the method is defined, or
    * `null` if there is no target (that is, the target is implicitly `this`).
@@ -6980,32 +6987,6 @@
   SimpleIdentifier _methodName;
 
   /**
-   * The type arguments to be applied to the method being invoked, or `null` if
-   * no type arguments were provided.
-   */
-  TypeArgumentList _typeArguments;
-
-  /**
-   * The list of arguments to the method.
-   */
-  ArgumentList _argumentList;
-
-  /**
-   * The function type of the method invocation, or `null` if the AST
-   * structure has not been resolved, or if the invoke could not be resolved.
-   *
-   * This will usually be a [FunctionType], but it can also be an
-   * [InterfaceType] with a `call` method, `dynamic`, `Function`, or a `@proxy`
-   * interface type that implements `Function`.
-   */
-  DartType staticInvokeType;
-
-  /**
-   * Like [staticInvokeType], but reflects propagated type information.
-   */
-  DartType propagatedInvokeType;
-
-  /**
    * Initialize a newly created method invocation. The [target] and [operator]
    * can be `null` if there is no target.
    */
@@ -7014,19 +6995,10 @@
       this.operator,
       SimpleIdentifier methodName,
       TypeArgumentList typeArguments,
-      ArgumentList argumentList) {
+      ArgumentList argumentList)
+      : super(typeArguments, argumentList) {
     _target = _becomeParentOf(target);
     _methodName = _becomeParentOf(methodName);
-    _typeArguments = _becomeParentOf(typeArguments);
-    _argumentList = _becomeParentOf(argumentList);
-  }
-
-  @override
-  ArgumentList get argumentList => _argumentList;
-
-  @override
-  void set argumentList(ArgumentList argumentList) {
-    _argumentList = _becomeParentOf(argumentList);
   }
 
   @override
@@ -7050,6 +7022,9 @@
   Token get endToken => _argumentList.endToken;
 
   @override
+  Expression get function => methodName;
+
+  @override
   bool get isCascaded =>
       operator != null && operator.type == TokenType.PERIOD_PERIOD;
 
@@ -7088,14 +7063,6 @@
   }
 
   @override
-  TypeArgumentList get typeArguments => _typeArguments;
-
-  @override
-  void set typeArguments(TypeArgumentList typeArguments) {
-    _typeArguments = _becomeParentOf(typeArguments);
-  }
-
-  @override
   accept(AstVisitor visitor) => visitor.visitMethodInvocation(this);
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/ast/token.dart b/pkg/analyzer/lib/src/dart/ast/token.dart
index 607df7b..02d28e5 100644
--- a/pkg/analyzer/lib/src/dart/ast/token.dart
+++ b/pkg/analyzer/lib/src/dart/ast/token.dart
@@ -35,7 +35,7 @@
 /**
  * A begin token that is preceded by comments.
  */
-class BeginTokenWithComment extends BeginToken {
+class BeginTokenWithComment extends BeginToken implements TokenWithComment {
   /**
    * The first comment in the list of comments that precede this token.
    */
@@ -79,9 +79,9 @@
  */
 class CommentToken extends StringToken {
   /**
-   * The [Token] that contains this comment.
+   * The token that contains this comment.
    */
-  Token parent;
+  TokenWithComment parent;
 
   /**
    * Initialize a newly created token to represent a token of the given [type]
@@ -92,6 +92,21 @@
 
   @override
   CommentToken copy() => new CommentToken(type, _value, offset);
+
+  /**
+   * Remove this comment token from the list.
+   *
+   * This is used when we decide to interpret the comment as syntax.
+   */
+  void remove() {
+    if (previous != null) {
+      previous.setNextWithoutSettingPrevious(next);
+      next?.previous = previous;
+    } else {
+      assert(parent.precedingComments == this);
+      parent.precedingComments = next;
+    }
+  }
 }
 
 /**
@@ -149,7 +164,7 @@
 /**
  * A keyword token that is preceded by comments.
  */
-class KeywordTokenWithComment extends KeywordToken {
+class KeywordTokenWithComment extends KeywordToken implements TokenWithComment {
   /**
    * The first comment in the list of comments that precede this token.
    */
@@ -340,7 +355,7 @@
 /**
  * A string token that is preceded by comments.
  */
-class StringTokenWithComment extends StringToken {
+class StringTokenWithComment extends StringToken implements TokenWithComment {
   /**
    * The first comment in the list of comments that precede this token.
    */
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index 05ff07f..dbbba10 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -934,6 +934,10 @@
     if (token is CommentToken) {
       token = (token as CommentToken).parent;
     }
+    if (_lastCloned == null) {
+      _lastCloned = new Token(TokenType.EOF, -1);
+      _lastCloned.setNext(_lastCloned);
+    }
     while (token != null) {
       Token clone = token.copy();
       {
@@ -952,7 +956,7 @@
         }
       }
       _clonedTokens[token] = clone;
-      _lastCloned?.setNext(clone);
+      _lastCloned.setNext(clone);
       _lastCloned = clone;
       if (token.type == TokenType.EOF) {
         break;
@@ -4946,7 +4950,7 @@
     } else if (_replaceInList(node.variables)) {
       return true;
     }
-    return visitNode(node);
+    return visitAnnotatedNode(node);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
index ef51b61..82d3761 100644
--- a/pkg/analyzer/lib/src/dart/element/builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -331,6 +331,24 @@
   }
 
   @override
+  Object visitAnnotation(Annotation node) {
+    // Although it isn't valid to do so because closures are not constant
+    // expressions, it's possible for one of the arguments to the constructor to
+    // contain a closure. Wrapping the processing of the annotation this way
+    // prevents these closures from being added to the list of functions in the
+    // annotated declaration.
+    ElementHolder holder = new ElementHolder();
+    ElementHolder previousHolder = _currentHolder;
+    _currentHolder = holder;
+    try {
+      super.visitAnnotation(node);
+    } finally {
+      _currentHolder = previousHolder;
+    }
+    return null;
+  }
+
+  @override
   Object visitCatchClause(CatchClause node) {
     SimpleIdentifier exceptionParameter = node.exceptionParameter;
     if (exceptionParameter != null) {
@@ -539,11 +557,13 @@
       _visit(holder, defaultValue);
       FunctionElementImpl initializer =
           new FunctionElementImpl.forOffset(defaultValue.beginToken.offset);
+      initializer.hasImplicitReturnType = true;
       initializer.functions = holder.functions;
       initializer.labels = holder.labels;
       initializer.localVariables = holder.localVariables;
       initializer.parameters = holder.parameters;
       initializer.synthetic = true;
+      initializer.type = new FunctionTypeImpl(initializer);
       parameter.initializer = initializer;
       parameter.defaultValueCode = defaultValue.toSource();
     }
@@ -846,7 +866,7 @@
     for (Label label in node.labels) {
       SimpleIdentifier labelName = label.label;
       LabelElementImpl element =
-          new LabelElementImpl(labelName, onSwitchStatement, false);
+          new LabelElementImpl.forNode(labelName, onSwitchStatement, false);
       _currentHolder.addLabel(element);
       labelName.staticElement = element;
     }
@@ -1045,7 +1065,7 @@
   Object visitSwitchCase(SwitchCase node) {
     for (Label label in node.labels) {
       SimpleIdentifier labelName = label.label;
-      LabelElementImpl element = new LabelElementImpl(labelName, false, true);
+      LabelElementImpl element = new LabelElementImpl.forNode(labelName, false, true);
       _currentHolder.addLabel(element);
       labelName.staticElement = element;
     }
@@ -1056,7 +1076,7 @@
   Object visitSwitchDefault(SwitchDefault node) {
     for (Label label in node.labels) {
       SimpleIdentifier labelName = label.label;
-      LabelElementImpl element = new LabelElementImpl(labelName, false, true);
+      LabelElementImpl element = new LabelElementImpl.forNode(labelName, false, true);
       _currentHolder.addLabel(element);
       labelName.staticElement = element;
     }
@@ -1139,10 +1159,12 @@
       _visit(holder, node.initializer);
       FunctionElementImpl initializer =
           new FunctionElementImpl.forOffset(node.initializer.beginToken.offset);
+      initializer.hasImplicitReturnType = true;
       initializer.functions = holder.functions;
       initializer.labels = holder.labels;
       initializer.localVariables = holder.localVariables;
       initializer.synthetic = true;
+      initializer.type = new FunctionTypeImpl(initializer);
       element.initializer = initializer;
       holder.validate();
     }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9677e89..5305395 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -114,11 +114,6 @@
   List<TypeParameterElement> _typeParameters = TypeParameterElement.EMPTY_LIST;
 
   /**
-   * The [SourceRange] of the `with` clause, `null` if there is no one.
-   */
-  SourceRange withClauseRange;
-
-  /**
    * A flag indicating whether the types associated with the instance members of
    * this class have been inferred.
    */
@@ -710,7 +705,6 @@
           new ConstructorElementImpl(superclassConstructor.name, -1);
       implicitConstructor.synthetic = true;
       implicitConstructor.redirectedConstructor = superclassConstructor;
-      implicitConstructor.const2 = superclassConstructor.isConst;
       implicitConstructor.returnType = type;
       List<ParameterElement> superParameters = superclassConstructor.parameters;
       int count = superParameters.length;
@@ -1789,11 +1783,12 @@
 
   /**
    * Set the enclosing element of this element to the given [element].
+   *
+   * Throws [FrozenHashCodeException] if the hashCode can't be changed.
    */
   void set enclosingElement(Element element) {
     _enclosingElement = element as ElementImpl;
-    _cachedLocation = null;
-    _cachedHashCode = null;
+    _updateCaches();
   }
 
   @override
@@ -1865,10 +1860,14 @@
   @override
   String get name => _name;
 
+  /**
+   * Changes the name of this element.
+   *
+   * Throws [FrozenHashCodeException] if the hashCode can't be changed.
+   */
   void set name(String name) {
     this._name = name;
-    _cachedLocation = null;
-    _cachedHashCode = null;
+    _updateCaches();
   }
 
   @override
@@ -1880,11 +1879,12 @@
   /**
    * Sets the offset of the name of this element in the file that contains the
    * declaration of this element.
+   *
+   * Throws [FrozenHashCodeException] if the hashCode can't be changed.
    */
   void set nameOffset(int offset) {
     _nameOffset = offset;
-    _cachedHashCode = null;
-    _cachedLocation = null;
+    _updateCaches();
   }
 
   @override
@@ -2045,6 +2045,35 @@
   void visitChildren(ElementVisitor visitor) {
     // There are no children to visit
   }
+
+  /**
+   *  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;
+    }
+
+    // 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)");
+    }
+  }
 }
 
 /**
@@ -2575,6 +2604,18 @@
 }
 
 /**
+ * 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
@@ -2935,7 +2976,17 @@
    * `switch` statement and [onSwitchMember] should be `true` if this label is
    * associated with a `switch` member.
    */
-  LabelElementImpl(
+  LabelElementImpl(String name, int nameOffset, this._onSwitchStatement,
+      this._onSwitchMember)
+      : super(name, nameOffset);
+
+  /**
+   * Initialize a newly created label element to have the given [name].
+   * [onSwitchStatement] should be `true` if this label is associated with a
+   * `switch` statement and [onSwitchMember] should be `true` if this label is
+   * associated with a `switch` member.
+   */
+  LabelElementImpl.forNode(
       Identifier name, this._onSwitchStatement, this._onSwitchMember)
       : super.forNode(name);
 
@@ -3557,12 +3608,10 @@
   }
 
   @override
-  bool get isPotentiallyMutatedInClosure =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
+  bool get isPotentiallyMutatedInClosure => true;
 
   @override
-  bool get isPotentiallyMutatedInScope =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
+  bool get isPotentiallyMutatedInScope => true;
 
   @override
   ElementKind get kind => ElementKind.LOCAL_VARIABLE;
@@ -3590,20 +3639,6 @@
       getNodeMatching((node) => node is VariableDeclaration);
 
   /**
-   * Specifies that this variable is potentially mutated somewhere in closure.
-   */
-  void markPotentiallyMutatedInClosure() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
-  }
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in its scope.
-   */
-  void markPotentiallyMutatedInScope() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
-  }
-
-  /**
    * Set the visible range for this element to the range starting at the given
    * [offset] with the given [length].
    */
@@ -3778,34 +3813,20 @@
       const Modifier('MIXIN_APPLICATION', 12);
 
   /**
-   * Indicates that the value of a parameter or local variable might be mutated
-   * within the context.
-   */
-  static const Modifier POTENTIALLY_MUTATED_IN_CONTEXT =
-      const Modifier('POTENTIALLY_MUTATED_IN_CONTEXT', 13);
-
-  /**
-   * Indicates that the value of a parameter or local variable might be mutated
-   * within the scope.
-   */
-  static const Modifier POTENTIALLY_MUTATED_IN_SCOPE =
-      const Modifier('POTENTIALLY_MUTATED_IN_SCOPE', 14);
-
-  /**
    * Indicates that a class contains an explicit reference to 'super'.
    */
   static const Modifier REFERENCES_SUPER =
-      const Modifier('REFERENCES_SUPER', 15);
+      const Modifier('REFERENCES_SUPER', 13);
 
   /**
    * Indicates that the pseudo-modifier 'set' was applied to the element.
    */
-  static const Modifier SETTER = const Modifier('SETTER', 16);
+  static const Modifier SETTER = const Modifier('SETTER', 14);
 
   /**
    * Indicates that the modifier 'static' was applied to the element.
    */
-  static const Modifier STATIC = const Modifier('STATIC', 17);
+  static const Modifier STATIC = const Modifier('STATIC', 15);
 
   /**
    * Indicates that the element does not appear in the source code but was
@@ -3813,9 +3834,14 @@
    * constructors, an implicit zero-argument constructor will be created and it
    * will be marked as being synthetic.
    */
-  static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 18);
+  static const Modifier SYNTHETIC = const Modifier('SYNTHETIC', 16);
 
-  static const List<Modifier> values = const [
+  /**
+   * 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 [
     ABSTRACT,
     ASYNCHRONOUS,
     CONST,
@@ -3829,14 +3855,17 @@
     HAS_EXT_URI,
     IMPLICIT_TYPE,
     MIXIN_APPLICATION,
-    POTENTIALLY_MUTATED_IN_CONTEXT,
-    POTENTIALLY_MUTATED_IN_SCOPE,
     REFERENCES_SUPER,
     SETTER,
     STATIC,
     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);
 }
 
@@ -4161,12 +4190,10 @@
   bool get isInitializingFormal => false;
 
   @override
-  bool get isPotentiallyMutatedInClosure =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT);
+  bool get isPotentiallyMutatedInClosure => true;
 
   @override
-  bool get isPotentiallyMutatedInScope =>
-      hasModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE);
+  bool get isPotentiallyMutatedInScope => true;
 
   @override
   ElementKind get kind => ElementKind.PARAMETER;
@@ -4244,20 +4271,6 @@
   }
 
   /**
-   * Specifies that this variable is potentially mutated somewhere in closure.
-   */
-  void markPotentiallyMutatedInClosure() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_CONTEXT, true);
-  }
-
-  /**
-   * Specifies that this variable is potentially mutated somewhere in its scope.
-   */
-  void markPotentiallyMutatedInScope() {
-    setModifier(Modifier.POTENTIALLY_MUTATED_IN_SCOPE, true);
-  }
-
-  /**
    * Set the visible range for this element to the range starting at the given
    * [offset] with the given [length].
    */
@@ -4600,6 +4613,11 @@
   TypeParameterElementImpl(String name, int offset) : super(name, offset);
 
   /**
+   * Initialize a newly created type parameter element to have the given [name].
+   */
+  TypeParameterElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
    * Initialize a newly created synthetic type parameter element to have the
    * given [name], and with [synthetic] set to true.
    */
@@ -4607,11 +4625,6 @@
     synthetic = true;
   }
 
-  /**
-   * Initialize a newly created type parameter element to have the given [name].
-   */
-  TypeParameterElementImpl.forNode(Identifier name) : super.forNode(name);
-
   @override
   ElementKind get kind => ElementKind.TYPE_PARAMETER;
 
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 938aa23..446ca59 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -12,6 +12,8 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart' show ScannerErrorCode;
+import 'package:analyzer/src/generated/generated/shared_messages.dart'
+    as shared_messages;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/source.dart';
@@ -2220,24 +2222,21 @@
    * <i>rethrow;</i> is not enclosed within a on-catch clause.
    */
   static const CompileTimeErrorCode RETHROW_OUTSIDE_CATCH =
-      const CompileTimeErrorCode(
-          'RETHROW_OUTSIDE_CATCH', "rethrow must be inside of a catch clause");
+      shared_messages.RETHROW_OUTSIDE_CATCH;
 
   /**
    * 13.12 Return: It is a compile-time error if a return statement of the form
    * <i>return e;</i> appears in a generative constructor.
    */
   static const CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR =
-      const CompileTimeErrorCode('RETURN_IN_GENERATIVE_CONSTRUCTOR',
-          "Constructors cannot return a value");
+      shared_messages.RETURN_IN_GENERATIVE_CONSTRUCTOR;
 
   /**
    * 13.12 Return: It is a compile-time error if a return statement of the form
    * <i>return e;</i> appears in a generator function.
    */
   static const CompileTimeErrorCode RETURN_IN_GENERATOR =
-      const CompileTimeErrorCode('RETURN_IN_GENERATOR',
-          "Cannot return a value from a generator function (one marked with either 'async*' or 'sync*')");
+      shared_messages.RETURN_IN_GENERATOR;
 
   /**
    * 14.1 Imports: It is a compile-time error if a prefix used in a deferred
@@ -2961,6 +2960,7 @@
     ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS,
     ParserErrorCode.POSITIONAL_AFTER_NAMED_ARGUMENT,
     ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP,
+    ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY,
     ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR,
     ParserErrorCode.SETTER_IN_FUNCTION,
     ParserErrorCode.STATIC_AFTER_CONST,
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 5de25974..32b4d31 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -682,6 +682,14 @@
   }
 
   @override
+  Object visitForStatement(ForStatement node) {
+    if (node.condition != null) {
+      _checkForNonBoolCondition(node.condition);
+    }
+    return super.visitForStatement(node);
+  }
+
+  @override
   Object visitFunctionDeclaration(FunctionDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
     try {
@@ -1928,7 +1936,9 @@
     } else if (_inGenerator) {
       // RETURN_IN_GENERATOR
       _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.RETURN_IN_GENERATOR, statement);
+          CompileTimeErrorCode.RETURN_IN_GENERATOR,
+          statement,
+          [_inAsync ? "async*" : "sync*"]);
     }
     // RETURN_OF_INVALID_TYPE
     return _checkForReturnOfInvalidType(returnExpression, expectedReturnType);
diff --git a/pkg/analyzer/lib/src/generated/generated/shared_messages.dart b/pkg/analyzer/lib/src/generated/generated/shared_messages.dart
index 5faa0c0..c0be1d2 100644
--- a/pkg/analyzer/lib/src/generated/generated/shared_messages.dart
+++ b/pkg/analyzer/lib/src/generated/generated/shared_messages.dart
@@ -9,6 +9,7 @@
 After any change to that file, run `bin/publish.dart` to generate a new version
 of the json, dart2js and analyzer representations.
 */
+import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 
 const ParserErrorCode CONST_CONSTRUCTOR_WITH_BODY = const ParserErrorCode(
@@ -19,4 +20,64 @@
 const ParserErrorCode CONST_FACTORY = const ParserErrorCode(
     'CONST_FACTORY',
     "Only redirecting factory constructors can be declared to be 'const'.",
-    "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target");  // Generated. Don't edit.
+    "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target.");  // Generated. Don't edit.
+
+const ParserErrorCode CONST_CLASS = const ParserErrorCode(
+    'CONST_CLASS',
+    "Classes can't be declared to be 'const'",
+    "Try removing the 'const' keyword or moving to the class' constructor(s).");  // Generated. Don't edit.
+
+const ParserErrorCode CONST_METHOD = const ParserErrorCode(
+    'CONST_METHOD',
+    "Getters, setters and methods can't be declared to be 'const'",
+    "Try removing the 'const' keyword.");  // Generated. Don't edit.
+
+const ParserErrorCode CONST_ENUM = const ParserErrorCode(
+    'CONST_ENUM',
+    "Enums can't be declared to be 'const'",
+    "Try removing the 'const' keyword.");  // Generated. Don't edit.
+
+const ParserErrorCode CONST_TYPEDEF = const ParserErrorCode(
+    'CONST_TYPEDEF',
+    "Type aliases can't be declared to be 'const'",
+    "Try removing the 'const' keyword.");  // Generated. Don't edit.
+
+const ParserErrorCode CONST_AND_FINAL = const ParserErrorCode(
+    'CONST_AND_FINAL',
+    "Members can't be declared to be both 'const' and 'final'",
+    "Try removing either the 'const' or 'final' keyword.");  // Generated. Don't edit.
+
+const ParserErrorCode CONST_AND_VAR = const ParserErrorCode(
+    'CONST_AND_VAR',
+    "Members can't be declared to be both 'const' and 'var'",
+    "Try removing either the 'const' or 'var' keyword.");  // Generated. Don't edit.
+
+const ParserErrorCode CLASS_IN_CLASS = const ParserErrorCode(
+    'CLASS_IN_CLASS',
+    "Classes can't be declared inside other classes.",
+    "Try moving the class to the top-level.");  // Generated. Don't edit.
+
+const ParserErrorCode CONSTRUCTOR_WITH_RETURN_TYPE = const ParserErrorCode(
+    'CONSTRUCTOR_WITH_RETURN_TYPE',
+    "Constructors can't have a return type",
+    "Try removing the return type.");  // Generated. Don't edit.
+
+const ParserErrorCode MISSING_EXPRESSION_IN_THROW = const ParserErrorCode(
+    'MISSING_EXPRESSION_IN_THROW',
+    "Missing expression after 'throw'.",
+    "Did you mean 'rethrow'?");  // Generated. Don't edit.
+
+const CompileTimeErrorCode RETHROW_OUTSIDE_CATCH = const CompileTimeErrorCode(
+    'RETHROW_OUTSIDE_CATCH',
+    "Rethrow must be inside of catch clause",
+    "Try moving the expression into a catch clause, or using a 'throw' expression.");  // Generated. Don't edit.
+
+const CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR = const CompileTimeErrorCode(
+    'RETURN_IN_GENERATIVE_CONSTRUCTOR',
+    "Constructors can't return values.",
+    "Try removing the return statement or using a factory constructor.");  // Generated. Don't edit.
+
+const CompileTimeErrorCode RETURN_IN_GENERATOR = const CompileTimeErrorCode(
+    'RETURN_IN_GENERATOR',
+    "Can't return a value from a generator function (using the '{0}' modifier).",
+    "Try removing the value, replacing 'return' with 'yield' or changing the method body modifier");  // Generated. Don't edit.
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
index f0f7a4c7..cf2c0dd 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolution_validator.dart
@@ -28,10 +28,15 @@
 class IncrementalResolutionMismatch {
   final String message;
   IncrementalResolutionMismatch(this.message);
+
+  @override
+  String toString() => "IncrementalResolutionMismatch: $message";
 }
 
 class _SameResolutionValidator implements AstVisitor {
   final bool validateTypes;
+
+  /// The expected node to compare with the visted node.
   AstNode other;
 
   _SameResolutionValidator(this.validateTypes, this.other);
@@ -887,11 +892,11 @@
     _assertNode(a, b);
   }
 
-  void _visitList(NodeList nodeList, NodeList otherList) {
+  void _visitList(NodeList nodeList, NodeList expected) {
     int length = nodeList.length;
-    _expectLength(otherList, length);
+    _expectLength(nodeList, expected.length);
     for (int i = 0; i < length; i++) {
-      _visitNode(nodeList[i], otherList[i]);
+      _visitNode(nodeList[i], expected[i]);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index f102201..7cc84d3 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -118,12 +118,14 @@
       _gatherElements(element);
       node.accept(this);
     } on _DeclarationMismatchException {
+      logger.log("mismatched");
       return DeclarationMatchKind.MISMATCH;
     } finally {
       logger.exit();
     }
     // no API changes
     if (_removedElements.isEmpty && _addedElements.isEmpty) {
+      logger.log("no API changes");
       return DeclarationMatchKind.MATCH;
     }
     // simple API change
@@ -2070,12 +2072,12 @@
     if (nameOffset > updateOffset) {
       // TODO(scheglov) make sure that we don't put local variables
       // and functions into the cache at all.
-      if (element is LocalVariableElement ||
-          element is FunctionElement &&
-              element.enclosingElement is ExecutableElement) {
+      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) {
         ConstVariableElement constVariable = element as ConstVariableElement;
         Expression initializer = constVariable.constantInitializer;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index ad18d2c..8ec719a 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -3951,6 +3951,8 @@
           String comment = t.lexeme.substring(prefixLen, t.lexeme.length - 2);
           Token list = _scanGenericMethodComment(comment, t.offset + prefixLen);
           if (list != null) {
+            // Remove the token from the comment stream.
+            t.remove();
             // Insert the tokens into the stream.
             _injectTokenList(list);
             return true;
@@ -5457,9 +5459,12 @@
         if (constKeyword != null) {
           _reportErrorForNode(
               ParserErrorCode.CONST_CONSTRUCTOR_WITH_BODY, body);
-        } else if (!bodyAllowed) {
+        } else if (externalKeyword != null) {
           _reportErrorForNode(
               ParserErrorCode.EXTERNAL_CONSTRUCTOR_WITH_BODY, body);
+        } else if (!bodyAllowed) {
+          _reportErrorForNode(
+              ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY, body);
         }
       }
     }
@@ -9398,41 +9403,31 @@
       'BREAK_OUTSIDE_OF_LOOP',
       "A break statement cannot be used outside of a loop or switch statement");
 
-  static const ParserErrorCode CLASS_IN_CLASS = const ParserErrorCode(
-      'CLASS_IN_CLASS', "Classes cannot be declared inside other classes");
+  static const ParserErrorCode CLASS_IN_CLASS = shared_messages.CLASS_IN_CLASS;
 
   static const ParserErrorCode COLON_IN_PLACE_OF_IN = const ParserErrorCode(
       'COLON_IN_PLACE_OF_IN', "For-in loops use 'in' rather than a colon");
 
-  static const ParserErrorCode CONST_AND_FINAL = const ParserErrorCode(
-      'CONST_AND_FINAL',
-      "Members cannot be declared to be both 'const' and 'final'");
+  static const ParserErrorCode CONST_AND_FINAL =
+      shared_messages.CONST_AND_FINAL;
 
-  static const ParserErrorCode CONST_AND_VAR = const ParserErrorCode(
-      'CONST_AND_VAR',
-      "Members cannot be declared to be both 'const' and 'var'");
+  static const ParserErrorCode CONST_AND_VAR = shared_messages.CONST_AND_VAR;
 
-  static const ParserErrorCode CONST_CLASS = const ParserErrorCode(
-      'CONST_CLASS', "Classes cannot be declared to be 'const'");
+  static const ParserErrorCode CONST_CLASS = shared_messages.CONST_CLASS;
 
   static const ParserErrorCode CONST_CONSTRUCTOR_WITH_BODY =
       shared_messages.CONST_CONSTRUCTOR_WITH_BODY;
 
-  static const ParserErrorCode CONST_ENUM = const ParserErrorCode(
-      'CONST_ENUM', "Enums cannot be declared to be 'const'");
+  static const ParserErrorCode CONST_ENUM = shared_messages.CONST_ENUM;
 
   static const ParserErrorCode CONST_FACTORY = shared_messages.CONST_FACTORY;
 
-  static const ParserErrorCode CONST_METHOD = const ParserErrorCode(
-      'CONST_METHOD',
-      "Getters, setters and methods cannot be declared to be 'const'");
+  static const ParserErrorCode CONST_METHOD = shared_messages.CONST_METHOD;
 
-  static const ParserErrorCode CONST_TYPEDEF = const ParserErrorCode(
-      'CONST_TYPEDEF', "Type aliases cannot be declared to be 'const'");
+  static const ParserErrorCode CONST_TYPEDEF = shared_messages.CONST_TYPEDEF;
 
   static const ParserErrorCode CONSTRUCTOR_WITH_RETURN_TYPE =
-      const ParserErrorCode('CONSTRUCTOR_WITH_RETURN_TYPE',
-          "Constructors cannot have a return type");
+      shared_messages.CONSTRUCTOR_WITH_RETURN_TYPE;
 
   static const ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP = const ParserErrorCode(
       'CONTINUE_OUTSIDE_OF_LOOP',
@@ -9692,8 +9687,7 @@
           "Expected an expression after the assignment operator");
 
   static const ParserErrorCode MISSING_EXPRESSION_IN_THROW =
-      const ParserErrorCode('MISSING_EXPRESSION_IN_THROW',
-          "Throw expressions must compute the object to be thrown");
+      shared_messages.MISSING_EXPRESSION_IN_THROW;
 
   static const ParserErrorCode MISSING_FUNCTION_BODY = const ParserErrorCode(
       'MISSING_FUNCTION_BODY', "A function body must be provided");
@@ -9838,6 +9832,10 @@
       const ParserErrorCode('POSITIONAL_PARAMETER_OUTSIDE_GROUP',
           "Positional parameters must be enclosed in square brackets ('[' and ']')");
 
+  static const ParserErrorCode REDIRECTING_CONSTRUCTOR_WITH_BODY =
+      const ParserErrorCode('REDIRECTING_CONSTRUCTOR_WITH_BODY',
+          "Redirecting constructors cannot have a body");
+
   static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR =
       const ParserErrorCode('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR',
           "Only factory constructor can specify '=' redirection.");
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index fab4ed1..45c75b2 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2394,8 +2394,11 @@
       SimpleIdentifier methodName = node.name;
       String nameOfMethod = methodName.name;
       if (property == null) {
+        String elementName = nameOfMethod == '-' &&
+            node.parameters != null &&
+            node.parameters.parameters.isEmpty ? 'unary-' : nameOfMethod;
         _enclosingExecutable = _findWithNameAndOffset(_enclosingClass.methods,
-            methodName, nameOfMethod, methodName.offset);
+            methodName, elementName, methodName.offset);
         _expectedElements.remove(_enclosingExecutable);
         methodName.staticElement = _enclosingExecutable;
       } else {
@@ -2404,7 +2407,7 @@
           accessor = _findIdentifier(_enclosingClass.accessors, methodName);
         } else if ((property as KeywordToken).keyword == Keyword.SET) {
           accessor = _findWithNameAndOffset(_enclosingClass.accessors,
-              methodName, methodName.name + '=', methodName.offset);
+              methodName, nameOfMethod + '=', methodName.offset);
           _expectedElements.remove(accessor);
           methodName.staticElement = accessor;
         }
@@ -2500,6 +2503,12 @@
             _findIdentifier(_enclosingAlias.typeParameters, parameterName);
       }
     }
+    if (element == null) {
+      String name = parameterName.name;
+      int offset = parameterName.offset;
+      _mismatch(
+          'Could not find type parameter with name "$name" at $offset', node);
+    }
     super.visitTypeParameter(node);
     _resolveMetadata(node.metadata, element);
     return null;
@@ -4006,7 +4015,6 @@
  * An [AstVisitor] that fills [UsedLocalElements].
  */
 class GatherUsedLocalElementsVisitor extends RecursiveAstVisitor {
-  final List<Element> definedElements = <Element>[];
   final UsedLocalElements usedElements = new UsedLocalElements();
 
   final LibraryElement _enclosingLibrary;
@@ -4076,13 +4084,10 @@
 
   @override
   visitSimpleIdentifier(SimpleIdentifier node) {
-    Element element = node.staticElement;
     if (node.inDeclarationContext()) {
-      if (element != null) {
-        definedElements.add(element);
-      }
       return;
     }
+    Element element = node.staticElement;
     bool isIdentifierRead = _isReadIdentifier(node);
     if (element is LocalVariableElement) {
       if (isIdentifierRead) {
@@ -6571,14 +6576,6 @@
    */
   HashMap<String, Element> _createExportMapping(
       LibraryElement library, HashSet<LibraryElement> visitedElements) {
-    // Check if the export namespace has been already computed.
-    {
-      Namespace exportNamespace = library.exportNamespace;
-      if (exportNamespace != null) {
-        return exportNamespace.definedNames;
-      }
-    }
-    // TODO(scheglov) Remove this after switching to the new task model.
     visitedElements.add(library);
     try {
       HashMap<String, Element> definedNames = new HashMap<String, Element>();
@@ -7108,7 +7105,7 @@
    */
   StaticTypeAnalyzer typeAnalyzer;
 
-  /*
+  /**
    * The type system in use during resolution.
    */
   TypeSystem typeSystem;
@@ -7160,6 +7157,11 @@
   bool resolveOnlyCommentInFunctionBody = false;
 
   /**
+   * Body of the function currently being analyzed, if any.
+   */
+  FunctionBody _currentFunctionBody;
+
+  /**
    * Initialize a newly created visitor to resolve the nodes in an AST node.
    *
    * The [definingLibrary] is the element for the library containing the node
@@ -7291,13 +7293,7 @@
   /**
    * Prepares this [ResolverVisitor] to using it for incremental resolution.
    */
-  void initForIncrementalResolution([Declaration declaration = null]) {
-    if (declaration != null) {
-      Element element = declaration.element;
-      if (element is ExecutableElement) {
-        _enclosingFunction = element;
-      }
-    }
+  void initForIncrementalResolution() {
     _overrideManager.enterScope();
   }
 
@@ -7851,12 +7847,15 @@
   @override
   Object visitConstructorDeclaration(ConstructorDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
+    FunctionBody outerFunctionBody = _currentFunctionBody;
     try {
+      _currentFunctionBody = node.body;
       _enclosingFunction = node.element;
       FunctionType type = _enclosingFunction.type;
       InferenceContext.setType(node.body, type.returnType);
       super.visitConstructorDeclaration(node);
     } finally {
+      _currentFunctionBody = outerFunctionBody;
       _enclosingFunction = outerFunction;
     }
     ConstructorElementImpl constructor = node.element;
@@ -8100,13 +8099,16 @@
   @override
   Object visitFunctionDeclaration(FunctionDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
+    FunctionBody outerFunctionBody = _currentFunctionBody;
     try {
       SimpleIdentifier functionName = node.name;
+      _currentFunctionBody = node.functionExpression.body;
       _enclosingFunction = functionName.staticElement as ExecutableElement;
       InferenceContext.setType(
           node.functionExpression, _enclosingFunction.type);
       super.visitFunctionDeclaration(node);
     } finally {
+      _currentFunctionBody = outerFunctionBody;
       _enclosingFunction = outerFunction;
     }
     return null;
@@ -8121,7 +8123,9 @@
   @override
   Object visitFunctionExpression(FunctionExpression node) {
     ExecutableElement outerFunction = _enclosingFunction;
+    FunctionBody outerFunctionBody = _currentFunctionBody;
     try {
+      _currentFunctionBody = node.body;
       _enclosingFunction = node.element;
       _overrideManager.enterScope();
       try {
@@ -8143,6 +8147,7 @@
         _overrideManager.exitScope();
       }
     } finally {
+      _currentFunctionBody = outerFunctionBody;
       _enclosingFunction = outerFunction;
     }
     return null;
@@ -8153,7 +8158,7 @@
     safelyVisit(node.function);
     node.accept(elementResolver);
     _inferFunctionExpressionsParametersTypes(node.argumentList);
-    InferenceContext.setType(node.argumentList, node.function.staticType);
+    _inferArgumentTypesFromContext(node);
     safelyVisit(node.argumentList);
     node.accept(typeAnalyzer);
     return null;
@@ -8339,7 +8344,9 @@
   @override
   Object visitMethodDeclaration(MethodDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
+    FunctionBody outerFunctionBody = _currentFunctionBody;
     try {
+      _currentFunctionBody = node.body;
       _enclosingFunction = node.element;
       DartType returnType = _computeReturnOrYieldType(
           _enclosingFunction.type?.returnType,
@@ -8348,6 +8355,7 @@
       InferenceContext.setType(node.body, returnType);
       super.visitMethodDeclaration(node);
     } finally {
+      _currentFunctionBody = outerFunctionBody;
       _enclosingFunction = outerFunction;
     }
     return null;
@@ -8369,15 +8377,32 @@
     safelyVisit(node.typeArguments);
     node.accept(elementResolver);
     _inferFunctionExpressionsParametersTypes(node.argumentList);
-    DartType contextType = node.staticInvokeType;
-    if (contextType is FunctionType) {
-      InferenceContext.setType(node.argumentList, contextType);
-    }
+    _inferArgumentTypesFromContext(node);
     safelyVisit(node.argumentList);
     node.accept(typeAnalyzer);
     return null;
   }
 
+  void _inferArgumentTypesFromContext(InvocationExpression node) {
+    DartType contextType = node.staticInvokeType;
+    if (contextType is FunctionType) {
+      DartType originalType = node.function.staticType;
+      DartType returnContextType = InferenceContext.getType(node);
+      TypeSystem ts = typeSystem;
+      if (returnContextType != null &&
+          node.typeArguments == null &&
+          originalType is FunctionType &&
+          originalType.typeFormals.isNotEmpty &&
+          ts is StrongTypeSystemImpl) {
+
+        contextType = ts.inferGenericFunctionCall(typeProvider, originalType,
+            DartType.EMPTY_LIST, DartType.EMPTY_LIST, returnContextType);
+      }
+
+      InferenceContext.setType(node.argumentList, contextType);
+    }
+  }
+
   @override
   Object visitNamedExpression(NamedExpression node) {
     InferenceContext.setType(node.expression, InferenceContext.getType(node));
@@ -8593,7 +8618,7 @@
   void _clearTypePromotionsIfAccessedInClosureAndProtentiallyMutated(
       AstNode target) {
     for (Element element in _promoteManager.promotedElements) {
-      if ((element as VariableElementImpl).isPotentiallyMutatedInScope) {
+      if (_currentFunctionBody.isPotentiallyMutatedInScope(element)) {
         if (_isVariableAccessedInClosure(element, target)) {
           _promoteManager.setType(element, null);
         }
@@ -8886,7 +8911,7 @@
     VariableElement element = getPromotionStaticElement(expression);
     if (element != null) {
       // may be mutated somewhere in closure
-      if (element.isPotentiallyMutatedInClosure) {
+      if (_currentFunctionBody.isPotentiallyMutatedInClosure(element)) {
         return;
       }
       // prepare current variable type
@@ -12037,8 +12062,6 @@
           CompileTimeErrorCode.MIXIN_OF_NON_CLASS);
       if (classElement != null) {
         classElement.mixins = mixinTypes;
-        classElement.withClauseRange =
-            new SourceRange(withClause.offset, withClause.length);
       }
     }
     if (implementsClause != null) {
@@ -12210,7 +12233,7 @@
  * structure looking for cases of [HintCode.UNUSED_ELEMENT],
  * [HintCode.UNUSED_FIELD], [HintCode.UNUSED_LOCAL_VARIABLE], etc.
  */
-class UnusedLocalElementsVerifier extends SimpleElementVisitor {
+class UnusedLocalElementsVerifier extends RecursiveElementVisitor {
   /**
    * The error listener to which errors will be reported.
    */
@@ -12486,6 +12509,12 @@
             nameScope: nameScope);
 
   @override
+  Object visitBlockFunctionBody(BlockFunctionBody node) {
+    assert(_localVariableInfo != null);
+    return super.visitBlockFunctionBody(node);
+  }
+
+  @override
   Object visitConstructorDeclaration(ConstructorDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
     LocalVariableInfo outerLocalVariableInfo = _localVariableInfo;
@@ -12504,6 +12533,12 @@
   Object visitExportDirective(ExportDirective node) => null;
 
   @override
+  Object visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    assert(_localVariableInfo != null);
+    return super.visitExpressionFunctionBody(node);
+  }
+
+  @override
   Object visitFunctionDeclaration(FunctionDeclaration node) {
     ExecutableElement outerFunction = _enclosingFunction;
     LocalVariableInfo outerLocalVariableInfo = _localVariableInfo;
@@ -12597,29 +12632,11 @@
     }
     // Must be local or parameter.
     ElementKind kind = element.kind;
-    if (kind == ElementKind.LOCAL_VARIABLE) {
+    if (kind == ElementKind.LOCAL_VARIABLE || kind == ElementKind.PARAMETER) {
       node.staticElement = element;
-      LocalVariableElementImpl variableImpl =
-          element as LocalVariableElementImpl;
       if (node.inSetterContext()) {
-        variableImpl.markPotentiallyMutatedInScope();
         _localVariableInfo.potentiallyMutatedInScope.add(element);
         if (element.enclosingElement != _enclosingFunction) {
-          variableImpl.markPotentiallyMutatedInClosure();
-          _localVariableInfo.potentiallyMutatedInClosure.add(element);
-        }
-      }
-    } else if (kind == ElementKind.PARAMETER) {
-      node.staticElement = element;
-      if (node.inSetterContext()) {
-        ParameterElementImpl parameterImpl = element as ParameterElementImpl;
-        parameterImpl.markPotentiallyMutatedInScope();
-        _localVariableInfo.potentiallyMutatedInScope.add(element);
-        // If we are in some closure, check if it is not the same as where
-        // variable is declared.
-        if (_enclosingFunction != null &&
-            (element.enclosingElement != _enclosingFunction)) {
-          parameterImpl.markPotentiallyMutatedInClosure();
           _localVariableInfo.potentiallyMutatedInClosure.add(element);
         }
       }
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 51c6ccc..7319a72 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -142,8 +142,8 @@
   /**
    * A table mapping Dart library URI's to the library.
    */
-  HashMap<String, SdkLibraryImpl> _libraryMap =
-      new HashMap<String, SdkLibraryImpl>();
+  LinkedHashMap<String, SdkLibraryImpl> _libraryMap =
+      new LinkedHashMap<String, SdkLibraryImpl>();
 
   /**
    * Return a list containing all of the sdk libraries in this mapping.
@@ -153,7 +153,7 @@
   /**
    * Return a list containing the library URI's for which a mapping is available.
    */
-  List<String> get uris => new List.from(_libraryMap.keys.toSet());
+  List<String> get uris => _libraryMap.keys.toList();
 
   /**
    * Return the library with the given 'dart:' [uri], or `null` if the URI does
diff --git a/pkg/analyzer/lib/src/generated/sdk_io.dart b/pkg/analyzer/lib/src/generated/sdk_io.dart
index 6a1e38d..e7a9dea 100644
--- a/pkg/analyzer/lib/src/generated/sdk_io.dart
+++ b/pkg/analyzer/lib/src/generated/sdk_io.dart
@@ -20,7 +20,7 @@
 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 SdkBundle;
+import 'package:analyzer/src/summary/idl.dart' show PackageBundle;
 import 'package:analyzer/src/summary/summary_sdk.dart';
 import 'package:path/path.dart' as pathos;
 
@@ -266,7 +266,7 @@
       _analysisContext.sourceFactory = factory;
       // Try to use summaries.
       if (_useSummary) {
-        SdkBundle sdkBundle = _getSummarySdkBundle();
+        PackageBundle sdkBundle = _getSummarySdkBundle();
         if (sdkBundle != null) {
           _analysisContext.resultProvider =
               new SdkSummaryResultProvider(_analysisContext, sdkBundle);
@@ -470,7 +470,7 @@
           return null;
         }
       }
-      libraryPath = new JavaFile(libraryPath).getParent();
+      libraryPath = new JavaFile(library.path).getParent();
       if (filePath.startsWith("$libraryPath${JavaFile.separator}")) {
         String path =
             "${library.shortName}/${filePath.substring(libraryPath.length + 1)}";
@@ -553,16 +553,16 @@
   }
 
   /**
-   * Return the [SdkBundle] for this SDK, if it exists, or `null` otherwise.
+   * Return the [PackageBundle] for this SDK, if it exists, or `null` otherwise.
    */
-  SdkBundle _getSummarySdkBundle() {
+  PackageBundle _getSummarySdkBundle() {
     String rootPath = directory.getAbsolutePath();
     String path = pathos.join(rootPath, 'lib', '_internal', 'spec.sum');
     try {
       File file = new File(path);
       if (file.existsSync()) {
         List<int> bytes = file.readAsBytesSync();
-        return new SdkBundle.fromBuffer(bytes);
+        return new PackageBundle.fromBuffer(bytes);
       }
     } catch (exception, stackTrace) {
       AnalysisEngine.instance.logger.logError(
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 4a2362f..c487796 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -510,7 +510,7 @@
   @override
   Object visitFunctionExpressionInvocation(FunctionExpressionInvocation node) {
     if (_strongMode) {
-      _inferFunctionInvocationGeneric(node);
+      _inferGenericInvoke(node);
     }
     DartType staticType = _computeInvokeReturnType(node.staticInvokeType);
     _recordStaticType(node, staticType);
@@ -626,14 +626,18 @@
           staticType = argumentType;
         }
       }
-    } else {
+    } else if (_strongMode) {
       DartType contextType = InferenceContext.getType(node);
-      if (_strongMode &&
-          contextType is InterfaceType &&
+      if (contextType is InterfaceType &&
           contextType.typeArguments.length == 1 &&
           contextType.element == _typeProvider.listType.element) {
         staticType = contextType.typeArguments[0];
         _resolver.inferenceContext.recordInference(node, contextType);
+      } else if (node.elements.isNotEmpty) {
+        // Infer the list type from the arguments.
+        staticType =
+            node.elements.map((e) => e.staticType).reduce(_leastUpperBound);
+        // TODO(jmesserly): record inference here?
       }
     }
     _recordStaticType(
@@ -672,15 +676,22 @@
           staticValueType = entryValueType;
         }
       }
-    } else {
+    } else if (_strongMode) {
       DartType contextType = InferenceContext.getType(node);
-      if (_strongMode &&
-          contextType is InterfaceType &&
+      if (contextType is InterfaceType &&
           contextType.typeArguments.length == 2 &&
           contextType.element == _typeProvider.mapType.element) {
         staticKeyType = contextType.typeArguments[0] ?? staticKeyType;
         staticValueType = contextType.typeArguments[1] ?? staticValueType;
         _resolver.inferenceContext.recordInference(node, contextType);
+      } else if (node.entries.isNotEmpty) {
+        // Infer the list type from the arguments.
+        staticKeyType =
+            node.entries.map((e) => e.key.staticType).reduce(_leastUpperBound);
+        staticValueType = node.entries
+            .map((e) => e.value.staticType)
+            .reduce(_leastUpperBound);
+        // TODO(jmesserly): record inference here?
       }
     }
     _recordStaticType(
@@ -731,7 +742,7 @@
     SimpleIdentifier methodNameNode = node.methodName;
     Element staticMethodElement = methodNameNode.staticElement;
     if (_strongMode) {
-      _inferMethodInvocationGeneric(node);
+      _inferGenericInvoke(node);
     }
     // Record types of the variable invoked as a function.
     if (staticMethodElement is VariableElement) {
@@ -1535,8 +1546,8 @@
     }
   }
 
-  // TODO(vsm): Use leafp's matchType here?
   DartType _findIteratedType(DartType type, DartType targetType) {
+    // TODO(vsm): Use leafp's matchType here?
     // Set by _find if match is found
     DartType result;
     // Elements we've already visited on a given inheritance path.
@@ -1600,6 +1611,12 @@
       }
       ClassElement returnType = library.getType(elementName);
       if (returnType != null) {
+        if (returnType.typeParameters.isNotEmpty) {
+          // Caller can't deal with unbound type parameters, so substitute
+          // `dynamic`.
+          return returnType.type.substitute4(
+              returnType.typeParameters.map((_) => _dynamicType).toList());
+        }
         return returnType.type;
       }
     }
@@ -1798,26 +1815,6 @@
   }
 
   /**
-   * Similar to [_inferMethodInvocationGeneric] but for function expression
-   * invocations.
-   */
-  // TODO(jmesserly): if we had a common AST interface between these two nodes,
-  // we could remove this duplicated code.
-  bool _inferFunctionInvocationGeneric(FunctionExpressionInvocation node) {
-    DartType instantiatedType = node.staticInvokeType;
-    DartType originalType = node.function.staticType;
-    if (instantiatedType is FunctionType && originalType is FunctionType) {
-      FunctionType inferred = _inferGenericInvoke(instantiatedType,
-          originalType, node.typeArguments, node.argumentList);
-      if (inferred != null) {
-        node.staticInvokeType = inferred;
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
    * Given an uninstantiated generic type, try to infer the instantiated generic
    * type from the surrounding context.
    */
@@ -1832,41 +1829,42 @@
     return type;
   }
 
-  FunctionType _inferGenericInvoke(FunctionType invokeType, FunctionType fnType,
-      TypeArgumentList typeArguments, ArgumentList argumentList) {
+  bool _inferGenericInvoke(InvocationExpression node) {
     TypeSystem ts = _typeSystem;
-    if (typeArguments == null && ts is StrongTypeSystemImpl) {
-      if (fnType.typeFormals.isNotEmpty &&
-          ts.instantiateToBounds(fnType) == invokeType) {
-        // Get the parameters that correspond to the uninstantiated generic.
-        List<ParameterElement> rawParameters =
-            ResolverVisitor.resolveArgumentsToParameters(
-                argumentList, fnType.parameters, null);
+    DartType fnType = node.function.staticType;
+    if (node.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);
 
-        List<DartType> paramTypes = <DartType>[];
-        List<DartType> argTypes = <DartType>[];
-        for (int i = 0, length = rawParameters.length; i < length; i++) {
-          ParameterElement parameter = rawParameters[i];
-          if (parameter != null) {
-            paramTypes.add(parameter.type);
-            argTypes.add(argumentList.arguments[i].staticType);
-          }
-        }
-
-        FunctionType inferred = ts.inferCallFromArguments(
-            _typeProvider, fnType, paramTypes, argTypes);
-
-        if (inferred != fnType) {
-          // Fix up the parameter elements based on inferred method.
-          List<ParameterElement> inferredParameters =
-              ResolverVisitor.resolveArgumentsToParameters(
-                  argumentList, inferred.parameters, null);
-          argumentList.correspondingStaticParameters = inferredParameters;
-          return inferred;
+      List<DartType> paramTypes = <DartType>[];
+      List<DartType> argTypes = <DartType>[];
+      for (int i = 0, length = rawParameters.length; i < length; i++) {
+        ParameterElement parameter = rawParameters[i];
+        if (parameter != null) {
+          paramTypes.add(parameter.type);
+          argTypes.add(argumentList.arguments[i].staticType);
         }
       }
+
+      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;
+      }
     }
-    return null;
+    return false;
   }
 
   /**
@@ -1889,27 +1887,6 @@
   }
 
   /**
-   * Given a generic method invocation [node], attempt to infer the method's
-   * type variables, using the actual types of the arguments.
-   */
-  bool _inferMethodInvocationGeneric(MethodInvocation node) {
-    DartType instantiatedType = node.staticInvokeType;
-    DartType originalType = node.methodName.staticType;
-    // TODO(jmesserly): support generic `call` methods.
-    // Perhaps we should always record a FunctionType in staticInvokeType
-    // and the methodName's staticType.
-    if (instantiatedType is FunctionType && originalType is FunctionType) {
-      FunctionType inferred = _inferGenericInvoke(instantiatedType,
-          originalType, node.typeArguments, node.argumentList);
-      if (inferred != null) {
-        node.staticInvokeType = inferred;
-        return true;
-      }
-    }
-    return false;
-  }
-
-  /**
    * Given a method invocation [node], attempt to infer a better
    * type for the result if it is an inline JS invocation
    */
@@ -2056,6 +2033,14 @@
   }
 
   /**
+   * Computes the least upper bound between two types.
+   *
+   * See [TypeSystem.getLeastUpperBound].
+   */
+  DartType _leastUpperBound(DartType s, DartType t) =>
+      _typeSystem.getLeastUpperBound(_typeProvider, s, t);
+
+  /**
    * Record that the propagated type of the given node is the given type.
    *
    * @param expression the node whose type is to be recorded
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index b94cb64..d5ac50f 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -100,6 +100,14 @@
     ConstructorElementImpl constructor = name == null
         ? new ConstructorElementImpl("", -1)
         : new ConstructorElementImpl(name, 0);
+    if (name != null) {
+      if (name.isEmpty) {
+        constructor.nameEnd = definingClass.name.length;
+      } else {
+        constructor.periodOffset = definingClass.name.length;
+        constructor.nameEnd = definingClass.name.length + name.length + 1;
+      }
+    }
     constructor.synthetic = name == null;
     constructor.const2 = isConst;
     if (argumentTypes != null) {
@@ -501,12 +509,13 @@
   }
 
   static ParameterElementImpl namedParameter3(String name,
-      {DartType type, Expression initializer}) {
+      {DartType type, Expression initializer, String initializerCode}) {
     DefaultParameterElementImpl parameter =
         new DefaultParameterElementImpl(name, 0);
     parameter.parameterKind = ParameterKind.NAMED;
     parameter.type = type;
     parameter.constantInitializer = initializer;
+    parameter.defaultValueCode = initializerCode;
     return parameter;
   }
 
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 48c4f98..06f4bee 100644
--- a/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
+++ b/pkg/analyzer/lib/src/generated/testing/test_type_provider.dart
@@ -171,7 +171,9 @@
       fromEnvironment.parameters = <ParameterElement>[
         ElementFactory.requiredParameter2("name", stringType),
         ElementFactory.namedParameter3("defaultValue",
-            type: _boolType, initializer: AstFactory.booleanLiteral(false))
+            type: _boolType,
+            initializer: AstFactory.booleanLiteral(false),
+            initializerCode: 'false')
       ];
       fromEnvironment.factory = true;
       fromEnvironment.isCycleFree = true;
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 851a990..ee4d0a1 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -68,11 +68,12 @@
   /// As a simplification, we do not actually store all constraints on each type
   /// parameter Tj. Instead we track Uj and Lj where U is the upper bound and
   /// L is the lower bound of that type parameter.
-  FunctionType inferCallFromArguments(
+  FunctionType inferGenericFunctionCall(
       TypeProvider typeProvider,
       FunctionType fnType,
       List<DartType> correspondingParameterTypes,
-      List<DartType> argumentTypes) {
+      List<DartType> argumentTypes,
+      DartType returnContextType) {
     if (fnType.typeFormals.isEmpty) {
       return fnType;
     }
@@ -84,6 +85,10 @@
     var inferringTypeSystem =
         new _StrongInferenceTypeSystem(typeProvider, fnType.typeFormals);
 
+    if (returnContextType != null) {
+      inferringTypeSystem.isSubtypeOf(fnType.returnType, returnContextType);
+    }
+
     for (int i = 0; i < argumentTypes.length; i++) {
       // Try to pass each argument to each parameter, recording any type
       // parameter bounds that were implied by this assignment.
@@ -105,7 +110,7 @@
    * 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.
    *
-   * This is similar to [inferCallFromArguments], but the return type is also
+   * This is similar to [inferGenericFunctionCall], but the return type is also
    * considered as part of the solution.
    *
    * If this function is called with a [contextType] that is also
@@ -284,18 +289,15 @@
   /**
    * Check that [f1] is a subtype of [f2].
    *
-   * [fuzzyArrows] indicates whether or not the f1 and f2 should be
-   * treated as fuzzy arrow types (and hence dynamic parameters to f2 treated
-   * as bottom).
+   * This will always assume function types use fuzzy arrows, in other words
+   * that dynamic parameters of f1 and f2 are treated as bottom.
    */
-  bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2,
-      {bool fuzzyArrows: true}) {
-
+  bool _isFunctionSubtypeOf(FunctionType f1, FunctionType f2) {
     return FunctionTypeImpl.relate(
         f1,
         f2,
         (DartType t1, DartType t2) =>
-            _isSubtypeOf(t2, t1, null, dynamicIsBottom: fuzzyArrows),
+            _isSubtypeOf(t2, t1, null, dynamicIsBottom: true),
         instantiateToBounds,
         returnRelation: isSubtypeOf);
   }
diff --git a/pkg/analyzer/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart
index b742db9..3cfbd2e 100644
--- a/pkg/analyzer/lib/src/string_source.dart
+++ b/pkg/analyzer/lib/src/string_source.dart
@@ -20,18 +20,22 @@
   final String fullName;
 
   @override
+  final Uri uri;
+
+  @override
   final int modificationStamp;
 
-  StringSource(this._contents, this.fullName)
-      : modificationStamp = new DateTime.now().millisecondsSinceEpoch;
+  StringSource(this._contents, String fullName)
+      : this.fullName = fullName,
+        uri = fullName == null ? null : new Uri.file(fullName),
+        modificationStamp = new DateTime.now().millisecondsSinceEpoch;
 
   @override
   TimestampedData<String> get contents =>
       new TimestampedData(modificationStamp, _contents);
 
   @override
-  String get encoding =>
-      throw new UnsupportedError("StringSource doesn't support encoding.");
+  String get encoding => uri.toString();
 
   @override
   int get hashCode => _contents.hashCode ^ fullName.hashCode;
@@ -43,11 +47,7 @@
   String get shortName => fullName;
 
   @override
-  Uri get uri =>
-      throw new UnsupportedError("StringSource doesn't support uri.");
-
-  UriKind get uriKind =>
-      throw new UnsupportedError("StringSource doesn't support uriKind.");
+  UriKind get uriKind => UriKind.FILE_URI;
 
   /**
    * Return `true` if the given [object] is a string source that is equal to
@@ -63,8 +63,7 @@
   bool exists() => true;
 
   @override
-  Uri resolveRelativeUri(Uri relativeUri) => throw new UnsupportedError(
-      "StringSource doesn't support resolveRelative.");
+  Uri resolveRelativeUri(Uri relativeUri) => uri.resolveUri(relativeUri);
 
   @override
   String toString() => 'StringSource ($fullName)';
diff --git a/pkg/analyzer/lib/src/summary/base.dart b/pkg/analyzer/lib/src/summary/base.dart
index c4a4cdb..1a1626e 100644
--- a/pkg/analyzer/lib/src/summary/base.dart
+++ b/pkg/analyzer/lib/src/summary/base.dart
@@ -33,4 +33,15 @@
    * Intended for testing and debugging only.
    */
   Map<String, Object> toMap();
+
+  /**
+   * Translate the data in this class into a JSON map, whose keys are the names
+   * of fields and whose values are the data stored in those fields,
+   * recursively converted into JSON.
+   *
+   * Fields containing their default value are elided.
+   *
+   * Intended for testing and debugging only.
+   */
+  Map<String, Object> toJson();
 }
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 5507871..99dbbce 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -9,6 +9,7 @@
 
 import 'flat_buffers.dart' as fb;
 import 'idl.dart' as idl;
+import 'dart:convert' as convert;
 
 class _ReferenceKindReader extends fb.Reader<idl.ReferenceKind> {
   const _ReferenceKindReader() : super();
@@ -274,6 +275,17 @@
 
 abstract class _EntityRefMixin implements idl.EntityRef {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (implicitFunctionTypeIndices.isNotEmpty) _result["implicitFunctionTypeIndices"] = implicitFunctionTypeIndices;
+    if (paramReference != 0) _result["paramReference"] = paramReference;
+    if (reference != 0) _result["reference"] = reference;
+    if (slot != 0) _result["slot"] = slot;
+    if (typeArguments.isNotEmpty) _result["typeArguments"] = typeArguments.map((_value) => _value.toJson()).toList();
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "implicitFunctionTypeIndices": implicitFunctionTypeIndices,
     "paramReference": paramReference,
@@ -281,6 +293,9 @@
     "slot": slot,
     "typeArguments": typeArguments,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class LinkedDependencyBuilder extends Object with _LinkedDependencyMixin implements idl.LinkedDependency {
@@ -372,10 +387,21 @@
 
 abstract class _LinkedDependencyMixin implements idl.LinkedDependency {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (parts.isNotEmpty) _result["parts"] = parts;
+    if (uri != '') _result["uri"] = uri;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "parts": parts,
     "uri": uri,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class LinkedExportNameBuilder extends Object with _LinkedExportNameMixin implements idl.LinkedExportName {
@@ -511,12 +537,25 @@
 
 abstract class _LinkedExportNameMixin implements idl.LinkedExportName {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (dependency != 0) _result["dependency"] = dependency;
+    if (kind != idl.ReferenceKind.classOrEnum) _result["kind"] = kind.toString().split('.')[1];
+    if (name != '') _result["name"] = name;
+    if (unit != 0) _result["unit"] = unit;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "dependency": dependency,
     "kind": kind,
     "name": name,
     "unit": unit,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class LinkedLibraryBuilder extends Object with _LinkedLibraryMixin implements idl.LinkedLibrary {
@@ -715,6 +754,17 @@
 
 abstract class _LinkedLibraryMixin implements idl.LinkedLibrary {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (dependencies.isNotEmpty) _result["dependencies"] = dependencies.map((_value) => _value.toJson()).toList();
+    if (exportNames.isNotEmpty) _result["exportNames"] = exportNames.map((_value) => _value.toJson()).toList();
+    if (importDependencies.isNotEmpty) _result["importDependencies"] = importDependencies;
+    if (numPrelinkedDependencies != 0) _result["numPrelinkedDependencies"] = numPrelinkedDependencies;
+    if (units.isNotEmpty) _result["units"] = units.map((_value) => _value.toJson()).toList();
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "dependencies": dependencies,
     "exportNames": exportNames,
@@ -722,6 +772,9 @@
     "numPrelinkedDependencies": numPrelinkedDependencies,
     "units": units,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class LinkedReferenceBuilder extends Object with _LinkedReferenceMixin implements idl.LinkedReference {
@@ -730,6 +783,7 @@
   int _containingReference;
   int _dependency;
   idl.ReferenceKind _kind;
+  int _localIndex;
   String _name;
   int _numTypeParameters;
   int _unit;
@@ -783,6 +837,22 @@
   }
 
   @override
+  int get localIndex => _localIndex ??= 0;
+
+  /**
+   * If [kind] is [ReferenceKind.function] (that is, the entity being referred
+   * to is a local function), the index of the function within
+   * [UnlinkedExecutable.localFunctions].  If [kind] is
+   * [ReferenceKind.variable], the index of the variable within
+   * [UnlinkedExecutable.localVariables].  Otherwise zero.
+   */
+  void set localIndex(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _localIndex = _value;
+  }
+
+  @override
   String get name => _name ??= '';
 
   /**
@@ -800,7 +870,8 @@
 
   /**
    * If the entity being referred to is generic, the number of type parameters
-   * it accepts.  Otherwise zero.
+   * it declares (does not include type parameters of enclosing entities).
+   * Otherwise zero.
    */
   void set numTypeParameters(int _value) {
     assert(!_finished);
@@ -826,10 +897,11 @@
     _unit = _value;
   }
 
-  LinkedReferenceBuilder({int containingReference, int dependency, idl.ReferenceKind kind, String name, int numTypeParameters, int unit})
+  LinkedReferenceBuilder({int containingReference, int dependency, idl.ReferenceKind kind, int localIndex, String name, int numTypeParameters, int unit})
     : _containingReference = containingReference,
       _dependency = dependency,
       _kind = kind,
+      _localIndex = localIndex,
       _name = name,
       _numTypeParameters = numTypeParameters,
       _unit = unit;
@@ -851,6 +923,9 @@
     if (_kind != null && _kind != idl.ReferenceKind.classOrEnum) {
       fbBuilder.addUint8(2, _kind.index);
     }
+    if (_localIndex != null && _localIndex != 0) {
+      fbBuilder.addUint32(6, _localIndex);
+    }
     if (offset_name != null) {
       fbBuilder.addOffset(3, offset_name);
     }
@@ -879,6 +954,7 @@
   int _containingReference;
   int _dependency;
   idl.ReferenceKind _kind;
+  int _localIndex;
   String _name;
   int _numTypeParameters;
   int _unit;
@@ -902,6 +978,12 @@
   }
 
   @override
+  int get localIndex {
+    _localIndex ??= const fb.Uint32Reader().vTableGet(_bp, 6, 0);
+    return _localIndex;
+  }
+
+  @override
   String get name {
     _name ??= const fb.StringReader().vTableGet(_bp, 3, '');
     return _name;
@@ -922,14 +1004,31 @@
 
 abstract class _LinkedReferenceMixin implements idl.LinkedReference {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (containingReference != 0) _result["containingReference"] = containingReference;
+    if (dependency != 0) _result["dependency"] = dependency;
+    if (kind != idl.ReferenceKind.classOrEnum) _result["kind"] = kind.toString().split('.')[1];
+    if (localIndex != 0) _result["localIndex"] = localIndex;
+    if (name != '') _result["name"] = name;
+    if (numTypeParameters != 0) _result["numTypeParameters"] = numTypeParameters;
+    if (unit != 0) _result["unit"] = unit;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "containingReference": containingReference,
     "dependency": dependency,
     "kind": kind,
+    "localIndex": localIndex,
     "name": name,
     "numTypeParameters": numTypeParameters,
     "unit": unit,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class LinkedUnitBuilder extends Object with _LinkedUnitMixin implements idl.LinkedUnit {
@@ -1022,17 +1121,29 @@
 
 abstract class _LinkedUnitMixin implements idl.LinkedUnit {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (references.isNotEmpty) _result["references"] = references.map((_value) => _value.toJson()).toList();
+    if (types.isNotEmpty) _result["types"] = types.map((_value) => _value.toJson()).toList();
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "references": references,
     "types": types,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
-class SdkBundleBuilder extends Object with _SdkBundleMixin implements idl.SdkBundle {
+class PackageBundleBuilder extends Object with _PackageBundleMixin implements idl.PackageBundle {
   bool _finished = false;
 
   List<LinkedLibraryBuilder> _linkedLibraries;
   List<String> _linkedLibraryUris;
+  List<String> _unlinkedUnitHashes;
   List<UnlinkedUnitBuilder> _unlinkedUnits;
   List<String> _unlinkedUnitUris;
 
@@ -1051,7 +1162,8 @@
   List<String> get linkedLibraryUris => _linkedLibraryUris ??= <String>[];
 
   /**
-   * The list of URIs of items in [linkedLibraries], e.g. `dart:core`.
+   * The list of URIs of items in [linkedLibraries], e.g. `dart:core` or
+   * `package:foo/bar.dart`.
    */
   void set linkedLibraryUris(List<String> _value) {
     assert(!_finished);
@@ -1059,10 +1171,22 @@
   }
 
   @override
+  List<String> get unlinkedUnitHashes => _unlinkedUnitHashes ??= <String>[];
+
+  /**
+   * List of MD5 hashes of the files listed in [unlinkedUnitUris].  Each hash
+   * is encoded as a hexadecimal string using lower case letters.
+   */
+  void set unlinkedUnitHashes(List<String> _value) {
+    assert(!_finished);
+    _unlinkedUnitHashes = _value;
+  }
+
+  @override
   List<UnlinkedUnitBuilder> get unlinkedUnits => _unlinkedUnits ??= <UnlinkedUnitBuilder>[];
 
   /**
-   * Unlinked information for the compilation units constituting the SDK.
+   * Unlinked information for the compilation units constituting the package.
    */
   void set unlinkedUnits(List<UnlinkedUnitBuilder> _value) {
     assert(!_finished);
@@ -1080,9 +1204,10 @@
     _unlinkedUnitUris = _value;
   }
 
-  SdkBundleBuilder({List<LinkedLibraryBuilder> linkedLibraries, List<String> linkedLibraryUris, List<UnlinkedUnitBuilder> unlinkedUnits, List<String> unlinkedUnitUris})
+  PackageBundleBuilder({List<LinkedLibraryBuilder> linkedLibraries, List<String> linkedLibraryUris, List<String> unlinkedUnitHashes, List<UnlinkedUnitBuilder> unlinkedUnits, List<String> unlinkedUnitUris})
     : _linkedLibraries = linkedLibraries,
       _linkedLibraryUris = linkedLibraryUris,
+      _unlinkedUnitHashes = unlinkedUnitHashes,
       _unlinkedUnits = unlinkedUnits,
       _unlinkedUnitUris = unlinkedUnitUris;
 
@@ -1096,6 +1221,7 @@
     _finished = true;
     fb.Offset offset_linkedLibraries;
     fb.Offset offset_linkedLibraryUris;
+    fb.Offset offset_unlinkedUnitHashes;
     fb.Offset offset_unlinkedUnits;
     fb.Offset offset_unlinkedUnitUris;
     if (!(_linkedLibraries == null || _linkedLibraries.isEmpty)) {
@@ -1104,6 +1230,9 @@
     if (!(_linkedLibraryUris == null || _linkedLibraryUris.isEmpty)) {
       offset_linkedLibraryUris = fbBuilder.writeList(_linkedLibraryUris.map((b) => fbBuilder.writeString(b)).toList());
     }
+    if (!(_unlinkedUnitHashes == null || _unlinkedUnitHashes.isEmpty)) {
+      offset_unlinkedUnitHashes = fbBuilder.writeList(_unlinkedUnitHashes.map((b) => fbBuilder.writeString(b)).toList());
+    }
     if (!(_unlinkedUnits == null || _unlinkedUnits.isEmpty)) {
       offset_unlinkedUnits = fbBuilder.writeList(_unlinkedUnits.map((b) => b.finish(fbBuilder)).toList());
     }
@@ -1117,6 +1246,9 @@
     if (offset_linkedLibraryUris != null) {
       fbBuilder.addOffset(1, offset_linkedLibraryUris);
     }
+    if (offset_unlinkedUnitHashes != null) {
+      fbBuilder.addOffset(4, offset_unlinkedUnitHashes);
+    }
     if (offset_unlinkedUnits != null) {
       fbBuilder.addOffset(2, offset_unlinkedUnits);
     }
@@ -1127,25 +1259,26 @@
   }
 }
 
-idl.SdkBundle readSdkBundle(List<int> buffer) {
+idl.PackageBundle readPackageBundle(List<int> buffer) {
   fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
-  return const _SdkBundleReader().read(rootRef);
+  return const _PackageBundleReader().read(rootRef);
 }
 
-class _SdkBundleReader extends fb.TableReader<_SdkBundleImpl> {
-  const _SdkBundleReader();
+class _PackageBundleReader extends fb.TableReader<_PackageBundleImpl> {
+  const _PackageBundleReader();
 
   @override
-  _SdkBundleImpl createObject(fb.BufferPointer bp) => new _SdkBundleImpl(bp);
+  _PackageBundleImpl createObject(fb.BufferPointer bp) => new _PackageBundleImpl(bp);
 }
 
-class _SdkBundleImpl extends Object with _SdkBundleMixin implements idl.SdkBundle {
+class _PackageBundleImpl extends Object with _PackageBundleMixin implements idl.PackageBundle {
   final fb.BufferPointer _bp;
 
-  _SdkBundleImpl(this._bp);
+  _PackageBundleImpl(this._bp);
 
   List<idl.LinkedLibrary> _linkedLibraries;
   List<String> _linkedLibraryUris;
+  List<String> _unlinkedUnitHashes;
   List<idl.UnlinkedUnit> _unlinkedUnits;
   List<String> _unlinkedUnitUris;
 
@@ -1162,6 +1295,12 @@
   }
 
   @override
+  List<String> get unlinkedUnitHashes {
+    _unlinkedUnitHashes ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 4, const <String>[]);
+    return _unlinkedUnitHashes;
+  }
+
+  @override
   List<idl.UnlinkedUnit> get unlinkedUnits {
     _unlinkedUnits ??= const fb.ListReader<idl.UnlinkedUnit>(const _UnlinkedUnitReader()).vTableGet(_bp, 2, const <idl.UnlinkedUnit>[]);
     return _unlinkedUnits;
@@ -1174,14 +1313,29 @@
   }
 }
 
-abstract class _SdkBundleMixin implements idl.SdkBundle {
+abstract class _PackageBundleMixin implements idl.PackageBundle {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (linkedLibraries.isNotEmpty) _result["linkedLibraries"] = linkedLibraries.map((_value) => _value.toJson()).toList();
+    if (linkedLibraryUris.isNotEmpty) _result["linkedLibraryUris"] = linkedLibraryUris;
+    if (unlinkedUnitHashes.isNotEmpty) _result["unlinkedUnitHashes"] = unlinkedUnitHashes;
+    if (unlinkedUnits.isNotEmpty) _result["unlinkedUnits"] = unlinkedUnits.map((_value) => _value.toJson()).toList();
+    if (unlinkedUnitUris.isNotEmpty) _result["unlinkedUnitUris"] = unlinkedUnitUris;
+    return _result;
+  }
+
   @override
   Map<String, Object> toMap() => {
     "linkedLibraries": linkedLibraries,
     "linkedLibraryUris": linkedLibraryUris,
+    "unlinkedUnitHashes": unlinkedUnitHashes,
     "unlinkedUnits": unlinkedUnits,
     "unlinkedUnitUris": unlinkedUnitUris,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedClassBuilder extends Object with _UnlinkedClassMixin implements idl.UnlinkedClass {
@@ -1554,6 +1708,25 @@
 
 abstract class _UnlinkedClassMixin implements idl.UnlinkedClass {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (documentationComment != null) _result["documentationComment"] = documentationComment.toJson();
+    if (executables.isNotEmpty) _result["executables"] = executables.map((_value) => _value.toJson()).toList();
+    if (fields.isNotEmpty) _result["fields"] = fields.map((_value) => _value.toJson()).toList();
+    if (hasNoSupertype != false) _result["hasNoSupertype"] = hasNoSupertype;
+    if (interfaces.isNotEmpty) _result["interfaces"] = interfaces.map((_value) => _value.toJson()).toList();
+    if (isAbstract != false) _result["isAbstract"] = isAbstract;
+    if (isMixinApplication != false) _result["isMixinApplication"] = isMixinApplication;
+    if (mixins.isNotEmpty) _result["mixins"] = mixins.map((_value) => _value.toJson()).toList();
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    if (supertype != null) _result["supertype"] = supertype.toJson();
+    if (typeParameters.isNotEmpty) _result["typeParameters"] = typeParameters.map((_value) => _value.toJson()).toList();
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "documentationComment": documentationComment,
@@ -1569,15 +1742,33 @@
     "supertype": supertype,
     "typeParameters": typeParameters,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedCombinatorBuilder extends Object with _UnlinkedCombinatorMixin implements idl.UnlinkedCombinator {
   bool _finished = false;
 
+  int _end;
   List<String> _hides;
+  int _offset;
   List<String> _shows;
 
   @override
+  int get end => _end ??= 0;
+
+  /**
+   * If this is a `show` combinator, offset of the end of the list of shown
+   * names.  Otherwise zero.
+   */
+  void set end(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _end = _value;
+  }
+
+  @override
   List<String> get hides => _hides ??= <String>[];
 
   /**
@@ -1589,6 +1780,19 @@
   }
 
   @override
+  int get offset => _offset ??= 0;
+
+  /**
+   * If this is a `show` combinator, offset of the `show` keyword.  Otherwise
+   * zero.
+   */
+  void set offset(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _offset = _value;
+  }
+
+  @override
   List<String> get shows => _shows ??= <String>[];
 
   /**
@@ -1599,8 +1803,10 @@
     _shows = _value;
   }
 
-  UnlinkedCombinatorBuilder({List<String> hides, List<String> shows})
-    : _hides = hides,
+  UnlinkedCombinatorBuilder({int end, List<String> hides, int offset, List<String> shows})
+    : _end = end,
+      _hides = hides,
+      _offset = offset,
       _shows = shows;
 
   fb.Offset finish(fb.Builder fbBuilder) {
@@ -1615,9 +1821,15 @@
       offset_shows = fbBuilder.writeList(_shows.map((b) => fbBuilder.writeString(b)).toList());
     }
     fbBuilder.startTable();
+    if (_end != null && _end != 0) {
+      fbBuilder.addUint32(3, _end);
+    }
     if (offset_hides != null) {
       fbBuilder.addOffset(1, offset_hides);
     }
+    if (_offset != null && _offset != 0) {
+      fbBuilder.addUint32(2, _offset);
+    }
     if (offset_shows != null) {
       fbBuilder.addOffset(0, offset_shows);
     }
@@ -1637,16 +1849,30 @@
 
   _UnlinkedCombinatorImpl(this._bp);
 
+  int _end;
   List<String> _hides;
+  int _offset;
   List<String> _shows;
 
   @override
+  int get end {
+    _end ??= const fb.Uint32Reader().vTableGet(_bp, 3, 0);
+    return _end;
+  }
+
+  @override
   List<String> get hides {
     _hides ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
     return _hides;
   }
 
   @override
+  int get offset {
+    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    return _offset;
+  }
+
+  @override
   List<String> get shows {
     _shows ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
     return _shows;
@@ -1655,10 +1881,25 @@
 
 abstract class _UnlinkedCombinatorMixin implements idl.UnlinkedCombinator {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (end != 0) _result["end"] = end;
+    if (hides.isNotEmpty) _result["hides"] = hides;
+    if (offset != 0) _result["offset"] = offset;
+    if (shows.isNotEmpty) _result["shows"] = shows;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
+    "end": end,
     "hides": hides,
+    "offset": offset,
     "shows": shows,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedConstBuilder extends Object with _UnlinkedConstMixin implements idl.UnlinkedConst {
@@ -1858,6 +2099,18 @@
 
 abstract class _UnlinkedConstMixin implements idl.UnlinkedConst {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (doubles.isNotEmpty) _result["doubles"] = doubles.map((_value) => _value.isFinite ? _value : _value.toString()).toList();
+    if (ints.isNotEmpty) _result["ints"] = ints;
+    if (isInvalid != false) _result["isInvalid"] = isInvalid;
+    if (operations.isNotEmpty) _result["operations"] = operations.map((_value) => _value.toString().split('.')[1]).toList();
+    if (references.isNotEmpty) _result["references"] = references.map((_value) => _value.toJson()).toList();
+    if (strings.isNotEmpty) _result["strings"] = strings;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "doubles": doubles,
     "ints": ints,
@@ -1866,6 +2119,9 @@
     "references": references,
     "strings": strings,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedConstructorInitializerBuilder extends Object with _UnlinkedConstructorInitializerMixin implements idl.UnlinkedConstructorInitializer {
@@ -2007,12 +2263,25 @@
 
 abstract class _UnlinkedConstructorInitializerMixin implements idl.UnlinkedConstructorInitializer {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (arguments.isNotEmpty) _result["arguments"] = arguments.map((_value) => _value.toJson()).toList();
+    if (expression != null) _result["expression"] = expression.toJson();
+    if (kind != idl.UnlinkedConstructorInitializerKind.field) _result["kind"] = kind.toString().split('.')[1];
+    if (name != '') _result["name"] = name;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "arguments": arguments,
     "expression": expression,
     "kind": kind,
     "name": name,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedDocumentationCommentBuilder extends Object with _UnlinkedDocumentationCommentMixin implements idl.UnlinkedDocumentationComment {
@@ -2124,11 +2393,23 @@
 
 abstract class _UnlinkedDocumentationCommentMixin implements idl.UnlinkedDocumentationComment {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (length != 0) _result["length"] = length;
+    if (offset != 0) _result["offset"] = offset;
+    if (text != '') _result["text"] = text;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "length": length,
     "offset": offset,
     "text": text,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedEnumBuilder extends Object with _UnlinkedEnumMixin implements idl.UnlinkedEnum {
@@ -2294,6 +2575,17 @@
 
 abstract class _UnlinkedEnumMixin implements idl.UnlinkedEnum {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (documentationComment != null) _result["documentationComment"] = documentationComment.toJson();
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    if (values.isNotEmpty) _result["values"] = values.map((_value) => _value.toJson()).toList();
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "documentationComment": documentationComment,
@@ -2301,6 +2593,9 @@
     "nameOffset": nameOffset,
     "values": values,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedEnumValueBuilder extends Object with _UnlinkedEnumValueMixin implements idl.UnlinkedEnumValue {
@@ -2412,11 +2707,23 @@
 
 abstract class _UnlinkedEnumValueMixin implements idl.UnlinkedEnumValue {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (documentationComment != null) _result["documentationComment"] = documentationComment.toJson();
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "documentationComment": documentationComment,
     "name": name,
     "nameOffset": nameOffset,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedExecutableBuilder extends Object with _UnlinkedExecutableMixin implements idl.UnlinkedExecutable {
@@ -2434,10 +2741,13 @@
   bool _isStatic;
   idl.UnlinkedExecutableKind _kind;
   List<UnlinkedExecutableBuilder> _localFunctions;
+  List<UnlinkedLabelBuilder> _localLabels;
   List<UnlinkedVariableBuilder> _localVariables;
   String _name;
+  int _nameEnd;
   int _nameOffset;
   List<UnlinkedParamBuilder> _parameters;
+  int _periodOffset;
   EntityRefBuilder _redirectedConstructor;
   String _redirectedConstructorName;
   EntityRefBuilder _returnType;
@@ -2590,6 +2900,17 @@
   }
 
   @override
+  List<UnlinkedLabelBuilder> get localLabels => _localLabels ??= <UnlinkedLabelBuilder>[];
+
+  /**
+   * The list of local labels.
+   */
+  void set localLabels(List<UnlinkedLabelBuilder> _value) {
+    assert(!_finished);
+    _localLabels = _value;
+  }
+
+  @override
   List<UnlinkedVariableBuilder> get localVariables => _localVariables ??= <UnlinkedVariableBuilder>[];
 
   /**
@@ -2614,6 +2935,19 @@
   }
 
   @override
+  int get nameEnd => _nameEnd ??= 0;
+
+  /**
+   * If [kind] is [UnlinkedExecutableKind.constructor] and [name] is not empty,
+   * the offset of the end of the constructor name.  Otherwise zero.
+   */
+  void set nameEnd(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _nameEnd = _value;
+  }
+
+  @override
   int get nameOffset => _nameOffset ??= 0;
 
   /**
@@ -2642,6 +2976,19 @@
   }
 
   @override
+  int get periodOffset => _periodOffset ??= 0;
+
+  /**
+   * If [kind] is [UnlinkedExecutableKind.constructor] and [name] is not empty,
+   * the offset of the period before the constructor name.  Otherwise zero.
+   */
+  void set periodOffset(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _periodOffset = _value;
+  }
+
+  @override
   EntityRefBuilder get redirectedConstructor => _redirectedConstructor;
 
   /**
@@ -2671,7 +3018,10 @@
 
   /**
    * Declared return type of the executable.  Absent if the executable is a
-   * constructor or the return type is implicit.
+   * constructor or the return type is implicit.  Absent for executables
+   * associated with variable initializers and closures, since these
+   * executables may have return types that are not accessible via direct
+   * imports.
    */
   void set returnType(EntityRefBuilder _value) {
     assert(!_finished);
@@ -2714,7 +3064,7 @@
     _visibleOffset = _value;
   }
 
-  UnlinkedExecutableBuilder({List<UnlinkedConstBuilder> annotations, List<UnlinkedConstructorInitializerBuilder> constantInitializers, UnlinkedDocumentationCommentBuilder documentationComment, int inferredReturnTypeSlot, bool isAbstract, bool isConst, bool isExternal, bool isFactory, bool isRedirectedConstructor, bool isStatic, idl.UnlinkedExecutableKind kind, List<UnlinkedExecutableBuilder> localFunctions, List<UnlinkedVariableBuilder> localVariables, String name, int nameOffset, List<UnlinkedParamBuilder> parameters, EntityRefBuilder redirectedConstructor, String redirectedConstructorName, EntityRefBuilder returnType, List<UnlinkedTypeParamBuilder> typeParameters, int visibleLength, int visibleOffset})
+  UnlinkedExecutableBuilder({List<UnlinkedConstBuilder> annotations, List<UnlinkedConstructorInitializerBuilder> constantInitializers, UnlinkedDocumentationCommentBuilder documentationComment, int inferredReturnTypeSlot, bool isAbstract, bool isConst, bool isExternal, bool isFactory, bool isRedirectedConstructor, bool isStatic, idl.UnlinkedExecutableKind kind, List<UnlinkedExecutableBuilder> localFunctions, List<UnlinkedLabelBuilder> localLabels, List<UnlinkedVariableBuilder> localVariables, String name, int nameEnd, int nameOffset, List<UnlinkedParamBuilder> parameters, int periodOffset, EntityRefBuilder redirectedConstructor, String redirectedConstructorName, EntityRefBuilder returnType, List<UnlinkedTypeParamBuilder> typeParameters, int visibleLength, int visibleOffset})
     : _annotations = annotations,
       _constantInitializers = constantInitializers,
       _documentationComment = documentationComment,
@@ -2727,10 +3077,13 @@
       _isStatic = isStatic,
       _kind = kind,
       _localFunctions = localFunctions,
+      _localLabels = localLabels,
       _localVariables = localVariables,
       _name = name,
+      _nameEnd = nameEnd,
       _nameOffset = nameOffset,
       _parameters = parameters,
+      _periodOffset = periodOffset,
       _redirectedConstructor = redirectedConstructor,
       _redirectedConstructorName = redirectedConstructorName,
       _returnType = returnType,
@@ -2745,6 +3098,7 @@
     fb.Offset offset_constantInitializers;
     fb.Offset offset_documentationComment;
     fb.Offset offset_localFunctions;
+    fb.Offset offset_localLabels;
     fb.Offset offset_localVariables;
     fb.Offset offset_name;
     fb.Offset offset_parameters;
@@ -2764,6 +3118,9 @@
     if (!(_localFunctions == null || _localFunctions.isEmpty)) {
       offset_localFunctions = fbBuilder.writeList(_localFunctions.map((b) => b.finish(fbBuilder)).toList());
     }
+    if (!(_localLabels == null || _localLabels.isEmpty)) {
+      offset_localLabels = fbBuilder.writeList(_localLabels.map((b) => b.finish(fbBuilder)).toList());
+    }
     if (!(_localVariables == null || _localVariables.isEmpty)) {
       offset_localVariables = fbBuilder.writeList(_localVariables.map((b) => b.finish(fbBuilder)).toList());
     }
@@ -2822,18 +3179,27 @@
     if (offset_localFunctions != null) {
       fbBuilder.addOffset(18, offset_localFunctions);
     }
+    if (offset_localLabels != null) {
+      fbBuilder.addOffset(22, offset_localLabels);
+    }
     if (offset_localVariables != null) {
       fbBuilder.addOffset(19, offset_localVariables);
     }
     if (offset_name != null) {
       fbBuilder.addOffset(1, offset_name);
     }
+    if (_nameEnd != null && _nameEnd != 0) {
+      fbBuilder.addUint32(23, _nameEnd);
+    }
     if (_nameOffset != null && _nameOffset != 0) {
       fbBuilder.addUint32(0, _nameOffset);
     }
     if (offset_parameters != null) {
       fbBuilder.addOffset(2, offset_parameters);
     }
+    if (_periodOffset != null && _periodOffset != 0) {
+      fbBuilder.addUint32(24, _periodOffset);
+    }
     if (offset_redirectedConstructor != null) {
       fbBuilder.addOffset(15, offset_redirectedConstructor);
     }
@@ -2880,10 +3246,13 @@
   bool _isStatic;
   idl.UnlinkedExecutableKind _kind;
   List<idl.UnlinkedExecutable> _localFunctions;
+  List<idl.UnlinkedLabel> _localLabels;
   List<idl.UnlinkedVariable> _localVariables;
   String _name;
+  int _nameEnd;
   int _nameOffset;
   List<idl.UnlinkedParam> _parameters;
+  int _periodOffset;
   idl.EntityRef _redirectedConstructor;
   String _redirectedConstructorName;
   idl.EntityRef _returnType;
@@ -2964,6 +3333,12 @@
   }
 
   @override
+  List<idl.UnlinkedLabel> get localLabels {
+    _localLabels ??= const fb.ListReader<idl.UnlinkedLabel>(const _UnlinkedLabelReader()).vTableGet(_bp, 22, const <idl.UnlinkedLabel>[]);
+    return _localLabels;
+  }
+
+  @override
   List<idl.UnlinkedVariable> get localVariables {
     _localVariables ??= const fb.ListReader<idl.UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bp, 19, const <idl.UnlinkedVariable>[]);
     return _localVariables;
@@ -2976,6 +3351,12 @@
   }
 
   @override
+  int get nameEnd {
+    _nameEnd ??= const fb.Uint32Reader().vTableGet(_bp, 23, 0);
+    return _nameEnd;
+  }
+
+  @override
   int get nameOffset {
     _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
     return _nameOffset;
@@ -2988,6 +3369,12 @@
   }
 
   @override
+  int get periodOffset {
+    _periodOffset ??= const fb.Uint32Reader().vTableGet(_bp, 24, 0);
+    return _periodOffset;
+  }
+
+  @override
   idl.EntityRef get redirectedConstructor {
     _redirectedConstructor ??= const _EntityRefReader().vTableGet(_bp, 15, null);
     return _redirectedConstructor;
@@ -3026,6 +3413,37 @@
 
 abstract class _UnlinkedExecutableMixin implements idl.UnlinkedExecutable {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (constantInitializers.isNotEmpty) _result["constantInitializers"] = constantInitializers.map((_value) => _value.toJson()).toList();
+    if (documentationComment != null) _result["documentationComment"] = documentationComment.toJson();
+    if (inferredReturnTypeSlot != 0) _result["inferredReturnTypeSlot"] = inferredReturnTypeSlot;
+    if (isAbstract != false) _result["isAbstract"] = isAbstract;
+    if (isConst != false) _result["isConst"] = isConst;
+    if (isExternal != false) _result["isExternal"] = isExternal;
+    if (isFactory != false) _result["isFactory"] = isFactory;
+    if (isRedirectedConstructor != false) _result["isRedirectedConstructor"] = isRedirectedConstructor;
+    if (isStatic != false) _result["isStatic"] = isStatic;
+    if (kind != idl.UnlinkedExecutableKind.functionOrMethod) _result["kind"] = kind.toString().split('.')[1];
+    if (localFunctions.isNotEmpty) _result["localFunctions"] = localFunctions.map((_value) => _value.toJson()).toList();
+    if (localLabels.isNotEmpty) _result["localLabels"] = localLabels.map((_value) => _value.toJson()).toList();
+    if (localVariables.isNotEmpty) _result["localVariables"] = localVariables.map((_value) => _value.toJson()).toList();
+    if (name != '') _result["name"] = name;
+    if (nameEnd != 0) _result["nameEnd"] = nameEnd;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    if (parameters.isNotEmpty) _result["parameters"] = parameters.map((_value) => _value.toJson()).toList();
+    if (periodOffset != 0) _result["periodOffset"] = periodOffset;
+    if (redirectedConstructor != null) _result["redirectedConstructor"] = redirectedConstructor.toJson();
+    if (redirectedConstructorName != '') _result["redirectedConstructorName"] = redirectedConstructorName;
+    if (returnType != null) _result["returnType"] = returnType.toJson();
+    if (typeParameters.isNotEmpty) _result["typeParameters"] = typeParameters.map((_value) => _value.toJson()).toList();
+    if (visibleLength != 0) _result["visibleLength"] = visibleLength;
+    if (visibleOffset != 0) _result["visibleOffset"] = visibleOffset;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "constantInitializers": constantInitializers,
@@ -3039,10 +3457,13 @@
     "isStatic": isStatic,
     "kind": kind,
     "localFunctions": localFunctions,
+    "localLabels": localLabels,
     "localVariables": localVariables,
     "name": name,
+    "nameEnd": nameEnd,
     "nameOffset": nameOffset,
     "parameters": parameters,
+    "periodOffset": periodOffset,
     "redirectedConstructor": redirectedConstructor,
     "redirectedConstructorName": redirectedConstructorName,
     "returnType": returnType,
@@ -3050,6 +3471,9 @@
     "visibleLength": visibleLength,
     "visibleOffset": visibleOffset,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedExportNonPublicBuilder extends Object with _UnlinkedExportNonPublicMixin implements idl.UnlinkedExportNonPublic {
@@ -3183,12 +3607,25 @@
 
 abstract class _UnlinkedExportNonPublicMixin implements idl.UnlinkedExportNonPublic {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (offset != 0) _result["offset"] = offset;
+    if (uriEnd != 0) _result["uriEnd"] = uriEnd;
+    if (uriOffset != 0) _result["uriOffset"] = uriOffset;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "offset": offset,
     "uriEnd": uriEnd,
     "uriOffset": uriOffset,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedExportPublicBuilder extends Object with _UnlinkedExportPublicMixin implements idl.UnlinkedExportPublic {
@@ -3275,10 +3712,21 @@
 
 abstract class _UnlinkedExportPublicMixin implements idl.UnlinkedExportPublic {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (combinators.isNotEmpty) _result["combinators"] = combinators.map((_value) => _value.toJson()).toList();
+    if (uri != '') _result["uri"] = uri;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "combinators": combinators,
     "uri": uri,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedImportBuilder extends Object with _UnlinkedImportMixin implements idl.UnlinkedImport {
@@ -3565,6 +4013,22 @@
 
 abstract class _UnlinkedImportMixin implements idl.UnlinkedImport {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (combinators.isNotEmpty) _result["combinators"] = combinators.map((_value) => _value.toJson()).toList();
+    if (isDeferred != false) _result["isDeferred"] = isDeferred;
+    if (isImplicit != false) _result["isImplicit"] = isImplicit;
+    if (offset != 0) _result["offset"] = offset;
+    if (prefixOffset != 0) _result["prefixOffset"] = prefixOffset;
+    if (prefixReference != 0) _result["prefixReference"] = prefixReference;
+    if (uri != '') _result["uri"] = uri;
+    if (uriEnd != 0) _result["uriEnd"] = uriEnd;
+    if (uriOffset != 0) _result["uriOffset"] = uriOffset;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "combinators": combinators,
@@ -3577,6 +4041,158 @@
     "uriEnd": uriEnd,
     "uriOffset": uriOffset,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
+}
+
+class UnlinkedLabelBuilder extends Object with _UnlinkedLabelMixin implements idl.UnlinkedLabel {
+  bool _finished = false;
+
+  bool _isOnSwitchMember;
+  bool _isOnSwitchStatement;
+  String _name;
+  int _nameOffset;
+
+  @override
+  bool get isOnSwitchMember => _isOnSwitchMember ??= false;
+
+  /**
+   * Return `true` if this label is associated with a `switch` member (`case` or
+   * `default`).
+   */
+  void set isOnSwitchMember(bool _value) {
+    assert(!_finished);
+    _isOnSwitchMember = _value;
+  }
+
+  @override
+  bool get isOnSwitchStatement => _isOnSwitchStatement ??= false;
+
+  /**
+   * Return `true` if this label is associated with a `switch` statement.
+   */
+  void set isOnSwitchStatement(bool _value) {
+    assert(!_finished);
+    _isOnSwitchStatement = _value;
+  }
+
+  @override
+  String get name => _name ??= '';
+
+  /**
+   * Name of the label.
+   */
+  void set name(String _value) {
+    assert(!_finished);
+    _name = _value;
+  }
+
+  @override
+  int get nameOffset => _nameOffset ??= 0;
+
+  /**
+   * Offset of the label relative to the beginning of the file.
+   */
+  void set nameOffset(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _nameOffset = _value;
+  }
+
+  UnlinkedLabelBuilder({bool isOnSwitchMember, bool isOnSwitchStatement, String name, int nameOffset})
+    : _isOnSwitchMember = isOnSwitchMember,
+      _isOnSwitchStatement = isOnSwitchStatement,
+      _name = name,
+      _nameOffset = nameOffset;
+
+  fb.Offset finish(fb.Builder fbBuilder) {
+    assert(!_finished);
+    _finished = true;
+    fb.Offset offset_name;
+    if (_name != null) {
+      offset_name = fbBuilder.writeString(_name);
+    }
+    fbBuilder.startTable();
+    if (_isOnSwitchMember == true) {
+      fbBuilder.addBool(2, true);
+    }
+    if (_isOnSwitchStatement == true) {
+      fbBuilder.addBool(3, true);
+    }
+    if (offset_name != null) {
+      fbBuilder.addOffset(0, offset_name);
+    }
+    if (_nameOffset != null && _nameOffset != 0) {
+      fbBuilder.addUint32(1, _nameOffset);
+    }
+    return fbBuilder.endTable();
+  }
+}
+
+class _UnlinkedLabelReader extends fb.TableReader<_UnlinkedLabelImpl> {
+  const _UnlinkedLabelReader();
+
+  @override
+  _UnlinkedLabelImpl createObject(fb.BufferPointer bp) => new _UnlinkedLabelImpl(bp);
+}
+
+class _UnlinkedLabelImpl extends Object with _UnlinkedLabelMixin implements idl.UnlinkedLabel {
+  final fb.BufferPointer _bp;
+
+  _UnlinkedLabelImpl(this._bp);
+
+  bool _isOnSwitchMember;
+  bool _isOnSwitchStatement;
+  String _name;
+  int _nameOffset;
+
+  @override
+  bool get isOnSwitchMember {
+    _isOnSwitchMember ??= const fb.BoolReader().vTableGet(_bp, 2, false);
+    return _isOnSwitchMember;
+  }
+
+  @override
+  bool get isOnSwitchStatement {
+    _isOnSwitchStatement ??= const fb.BoolReader().vTableGet(_bp, 3, false);
+    return _isOnSwitchStatement;
+  }
+
+  @override
+  String get name {
+    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    return _name;
+  }
+
+  @override
+  int get nameOffset {
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    return _nameOffset;
+  }
+}
+
+abstract class _UnlinkedLabelMixin implements idl.UnlinkedLabel {
+  @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (isOnSwitchMember != false) _result["isOnSwitchMember"] = isOnSwitchMember;
+    if (isOnSwitchStatement != false) _result["isOnSwitchStatement"] = isOnSwitchStatement;
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    return _result;
+  }
+
+  @override
+  Map<String, Object> toMap() => {
+    "isOnSwitchMember": isOnSwitchMember,
+    "isOnSwitchStatement": isOnSwitchStatement,
+    "name": name,
+    "nameOffset": nameOffset,
+  };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedParamBuilder extends Object with _UnlinkedParamMixin implements idl.UnlinkedParam {
@@ -3584,7 +4200,9 @@
 
   List<UnlinkedConstBuilder> _annotations;
   UnlinkedConstBuilder _defaultValue;
+  String _defaultValueCode;
   int _inferredTypeSlot;
+  UnlinkedExecutableBuilder _initializer;
   bool _isFunctionTyped;
   bool _isInitializingFormal;
   idl.UnlinkedParamKind _kind;
@@ -3620,6 +4238,18 @@
   }
 
   @override
+  String get defaultValueCode => _defaultValueCode ??= '';
+
+  /**
+   * If the parameter has a default value, the source text of the constant
+   * expression in the default value.  Otherwise the empty string.
+   */
+  void set defaultValueCode(String _value) {
+    assert(!_finished);
+    _defaultValueCode = _value;
+  }
+
+  @override
   int get inferredTypeSlot => _inferredTypeSlot ??= 0;
 
   /**
@@ -3640,6 +4270,18 @@
   }
 
   @override
+  UnlinkedExecutableBuilder get initializer => _initializer;
+
+  /**
+   * The synthetic initializer function of the parameter.  Absent if the variable
+   * does not have an initializer.
+   */
+  void set initializer(UnlinkedExecutableBuilder _value) {
+    assert(!_finished);
+    _initializer = _value;
+  }
+
+  @override
   bool get isFunctionTyped => _isFunctionTyped ??= false;
 
   /**
@@ -3744,10 +4386,12 @@
     _visibleOffset = _value;
   }
 
-  UnlinkedParamBuilder({List<UnlinkedConstBuilder> annotations, UnlinkedConstBuilder defaultValue, int inferredTypeSlot, bool isFunctionTyped, bool isInitializingFormal, idl.UnlinkedParamKind kind, String name, int nameOffset, List<UnlinkedParamBuilder> parameters, EntityRefBuilder type, int visibleLength, int visibleOffset})
+  UnlinkedParamBuilder({List<UnlinkedConstBuilder> annotations, UnlinkedConstBuilder defaultValue, String defaultValueCode, int inferredTypeSlot, UnlinkedExecutableBuilder initializer, bool isFunctionTyped, bool isInitializingFormal, idl.UnlinkedParamKind kind, String name, int nameOffset, List<UnlinkedParamBuilder> parameters, EntityRefBuilder type, int visibleLength, int visibleOffset})
     : _annotations = annotations,
       _defaultValue = defaultValue,
+      _defaultValueCode = defaultValueCode,
       _inferredTypeSlot = inferredTypeSlot,
+      _initializer = initializer,
       _isFunctionTyped = isFunctionTyped,
       _isInitializingFormal = isInitializingFormal,
       _kind = kind,
@@ -3763,6 +4407,8 @@
     _finished = true;
     fb.Offset offset_annotations;
     fb.Offset offset_defaultValue;
+    fb.Offset offset_defaultValueCode;
+    fb.Offset offset_initializer;
     fb.Offset offset_name;
     fb.Offset offset_parameters;
     fb.Offset offset_type;
@@ -3772,6 +4418,12 @@
     if (_defaultValue != null) {
       offset_defaultValue = _defaultValue.finish(fbBuilder);
     }
+    if (_defaultValueCode != null) {
+      offset_defaultValueCode = fbBuilder.writeString(_defaultValueCode);
+    }
+    if (_initializer != null) {
+      offset_initializer = _initializer.finish(fbBuilder);
+    }
     if (_name != null) {
       offset_name = fbBuilder.writeString(_name);
     }
@@ -3788,9 +4440,15 @@
     if (offset_defaultValue != null) {
       fbBuilder.addOffset(7, offset_defaultValue);
     }
+    if (offset_defaultValueCode != null) {
+      fbBuilder.addOffset(13, offset_defaultValueCode);
+    }
     if (_inferredTypeSlot != null && _inferredTypeSlot != 0) {
       fbBuilder.addUint32(2, _inferredTypeSlot);
     }
+    if (offset_initializer != null) {
+      fbBuilder.addOffset(12, offset_initializer);
+    }
     if (_isFunctionTyped == true) {
       fbBuilder.addBool(5, true);
     }
@@ -3836,7 +4494,9 @@
 
   List<idl.UnlinkedConst> _annotations;
   idl.UnlinkedConst _defaultValue;
+  String _defaultValueCode;
   int _inferredTypeSlot;
+  idl.UnlinkedExecutable _initializer;
   bool _isFunctionTyped;
   bool _isInitializingFormal;
   idl.UnlinkedParamKind _kind;
@@ -3860,12 +4520,24 @@
   }
 
   @override
+  String get defaultValueCode {
+    _defaultValueCode ??= const fb.StringReader().vTableGet(_bp, 13, '');
+    return _defaultValueCode;
+  }
+
+  @override
   int get inferredTypeSlot {
     _inferredTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
     return _inferredTypeSlot;
   }
 
   @override
+  idl.UnlinkedExecutable get initializer {
+    _initializer ??= const _UnlinkedExecutableReader().vTableGet(_bp, 12, null);
+    return _initializer;
+  }
+
+  @override
   bool get isFunctionTyped {
     _isFunctionTyped ??= const fb.BoolReader().vTableGet(_bp, 5, false);
     return _isFunctionTyped;
@@ -3922,10 +4594,32 @@
 
 abstract class _UnlinkedParamMixin implements idl.UnlinkedParam {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (defaultValue != null) _result["defaultValue"] = defaultValue.toJson();
+    if (defaultValueCode != '') _result["defaultValueCode"] = defaultValueCode;
+    if (inferredTypeSlot != 0) _result["inferredTypeSlot"] = inferredTypeSlot;
+    if (initializer != null) _result["initializer"] = initializer.toJson();
+    if (isFunctionTyped != false) _result["isFunctionTyped"] = isFunctionTyped;
+    if (isInitializingFormal != false) _result["isInitializingFormal"] = isInitializingFormal;
+    if (kind != idl.UnlinkedParamKind.required) _result["kind"] = kind.toString().split('.')[1];
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    if (parameters.isNotEmpty) _result["parameters"] = parameters.map((_value) => _value.toJson()).toList();
+    if (type != null) _result["type"] = type.toJson();
+    if (visibleLength != 0) _result["visibleLength"] = visibleLength;
+    if (visibleOffset != 0) _result["visibleOffset"] = visibleOffset;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "defaultValue": defaultValue,
+    "defaultValueCode": defaultValueCode,
     "inferredTypeSlot": inferredTypeSlot,
+    "initializer": initializer,
     "isFunctionTyped": isFunctionTyped,
     "isInitializingFormal": isInitializingFormal,
     "kind": kind,
@@ -3936,6 +4630,9 @@
     "visibleLength": visibleLength,
     "visibleOffset": visibleOffset,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedPartBuilder extends Object with _UnlinkedPartMixin implements idl.UnlinkedPart {
@@ -4045,11 +4742,23 @@
 
 abstract class _UnlinkedPartMixin implements idl.UnlinkedPart {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (uriEnd != 0) _result["uriEnd"] = uriEnd;
+    if (uriOffset != 0) _result["uriOffset"] = uriOffset;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "uriEnd": uriEnd,
     "uriOffset": uriOffset,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedPublicNameBuilder extends Object with _UnlinkedPublicNameMixin implements idl.UnlinkedPublicName {
@@ -4189,12 +4898,25 @@
 
 abstract class _UnlinkedPublicNameMixin implements idl.UnlinkedPublicName {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (kind != idl.ReferenceKind.classOrEnum) _result["kind"] = kind.toString().split('.')[1];
+    if (members.isNotEmpty) _result["members"] = members.map((_value) => _value.toJson()).toList();
+    if (name != '') _result["name"] = name;
+    if (numTypeParameters != 0) _result["numTypeParameters"] = numTypeParameters;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "kind": kind,
     "members": members,
     "name": name,
     "numTypeParameters": numTypeParameters,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedPublicNamespaceBuilder extends Object with _UnlinkedPublicNamespaceMixin implements idl.UnlinkedPublicNamespace {
@@ -4321,11 +5043,23 @@
 
 abstract class _UnlinkedPublicNamespaceMixin implements idl.UnlinkedPublicNamespace {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (exports.isNotEmpty) _result["exports"] = exports.map((_value) => _value.toJson()).toList();
+    if (names.isNotEmpty) _result["names"] = names.map((_value) => _value.toJson()).toList();
+    if (parts.isNotEmpty) _result["parts"] = parts;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "exports": exports,
     "names": names,
     "parts": parts,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedReferenceBuilder extends Object with _UnlinkedReferenceMixin implements idl.UnlinkedReference {
@@ -4340,6 +5074,7 @@
   /**
    * Name of the entity being referred to.  For the pseudo-type `dynamic`, the
    * string is "dynamic".  For the pseudo-type `void`, the string is "void".
+   * For the pseudo-type `bottom`, the string is "*bottom*".
    */
   void set name(String _value) {
     assert(!_finished);
@@ -4415,10 +5150,21 @@
 
 abstract class _UnlinkedReferenceMixin implements idl.UnlinkedReference {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (name != '') _result["name"] = name;
+    if (prefixReference != 0) _result["prefixReference"] = prefixReference;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "name": name,
     "prefixReference": prefixReference,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedTypedefBuilder extends Object with _UnlinkedTypedefMixin implements idl.UnlinkedTypedef {
@@ -4638,6 +5384,19 @@
 
 abstract class _UnlinkedTypedefMixin implements idl.UnlinkedTypedef {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (documentationComment != null) _result["documentationComment"] = documentationComment.toJson();
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    if (parameters.isNotEmpty) _result["parameters"] = parameters.map((_value) => _value.toJson()).toList();
+    if (returnType != null) _result["returnType"] = returnType.toJson();
+    if (typeParameters.isNotEmpty) _result["typeParameters"] = typeParameters.map((_value) => _value.toJson()).toList();
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "documentationComment": documentationComment,
@@ -4647,6 +5406,9 @@
     "returnType": returnType,
     "typeParameters": typeParameters,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedTypeParamBuilder extends Object with _UnlinkedTypeParamMixin implements idl.UnlinkedTypeParam {
@@ -4785,12 +5547,25 @@
 
 abstract class _UnlinkedTypeParamMixin implements idl.UnlinkedTypeParam {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (bound != null) _result["bound"] = bound.toJson();
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "bound": bound,
     "name": name,
     "nameOffset": nameOffset,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedUnitBuilder extends Object with _UnlinkedUnitMixin implements idl.UnlinkedUnit {
@@ -5241,6 +6016,27 @@
 
 abstract class _UnlinkedUnitMixin implements idl.UnlinkedUnit {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (classes.isNotEmpty) _result["classes"] = classes.map((_value) => _value.toJson()).toList();
+    if (enums.isNotEmpty) _result["enums"] = enums.map((_value) => _value.toJson()).toList();
+    if (executables.isNotEmpty) _result["executables"] = executables.map((_value) => _value.toJson()).toList();
+    if (exports.isNotEmpty) _result["exports"] = exports.map((_value) => _value.toJson()).toList();
+    if (imports.isNotEmpty) _result["imports"] = imports.map((_value) => _value.toJson()).toList();
+    if (libraryAnnotations.isNotEmpty) _result["libraryAnnotations"] = libraryAnnotations.map((_value) => _value.toJson()).toList();
+    if (libraryDocumentationComment != null) _result["libraryDocumentationComment"] = libraryDocumentationComment.toJson();
+    if (libraryName != '') _result["libraryName"] = libraryName;
+    if (libraryNameLength != 0) _result["libraryNameLength"] = libraryNameLength;
+    if (libraryNameOffset != 0) _result["libraryNameOffset"] = libraryNameOffset;
+    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();
+    if (typedefs.isNotEmpty) _result["typedefs"] = typedefs.map((_value) => _value.toJson()).toList();
+    if (variables.isNotEmpty) _result["variables"] = variables.map((_value) => _value.toJson()).toList();
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "classes": classes,
     "enums": enums,
@@ -5258,6 +6054,9 @@
     "typedefs": typedefs,
     "variables": variables,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
 class UnlinkedVariableBuilder extends Object with _UnlinkedVariableMixin implements idl.UnlinkedVariable {
@@ -5267,6 +6066,7 @@
   UnlinkedConstBuilder _constExpr;
   UnlinkedDocumentationCommentBuilder _documentationComment;
   int _inferredTypeSlot;
+  UnlinkedExecutableBuilder _initializer;
   bool _isConst;
   bool _isFinal;
   bool _isStatic;
@@ -5329,6 +6129,18 @@
   }
 
   @override
+  UnlinkedExecutableBuilder get initializer => _initializer;
+
+  /**
+   * The synthetic initializer function of the variable.  Absent if the variable
+   * does not have an initializer.
+   */
+  void set initializer(UnlinkedExecutableBuilder _value) {
+    assert(!_finished);
+    _initializer = _value;
+  }
+
+  @override
   bool get isConst => _isConst ??= false;
 
   /**
@@ -5440,11 +6252,12 @@
     _visibleOffset = _value;
   }
 
-  UnlinkedVariableBuilder({List<UnlinkedConstBuilder> annotations, UnlinkedConstBuilder constExpr, UnlinkedDocumentationCommentBuilder documentationComment, int inferredTypeSlot, bool isConst, bool isFinal, bool isStatic, String name, int nameOffset, int propagatedTypeSlot, EntityRefBuilder type, int visibleLength, int visibleOffset})
+  UnlinkedVariableBuilder({List<UnlinkedConstBuilder> annotations, UnlinkedConstBuilder constExpr, UnlinkedDocumentationCommentBuilder documentationComment, int inferredTypeSlot, UnlinkedExecutableBuilder initializer, bool isConst, bool isFinal, bool isStatic, String name, int nameOffset, int propagatedTypeSlot, EntityRefBuilder type, int visibleLength, int visibleOffset})
     : _annotations = annotations,
       _constExpr = constExpr,
       _documentationComment = documentationComment,
       _inferredTypeSlot = inferredTypeSlot,
+      _initializer = initializer,
       _isConst = isConst,
       _isFinal = isFinal,
       _isStatic = isStatic,
@@ -5461,6 +6274,7 @@
     fb.Offset offset_annotations;
     fb.Offset offset_constExpr;
     fb.Offset offset_documentationComment;
+    fb.Offset offset_initializer;
     fb.Offset offset_name;
     fb.Offset offset_type;
     if (!(_annotations == null || _annotations.isEmpty)) {
@@ -5472,6 +6286,9 @@
     if (_documentationComment != null) {
       offset_documentationComment = _documentationComment.finish(fbBuilder);
     }
+    if (_initializer != null) {
+      offset_initializer = _initializer.finish(fbBuilder);
+    }
     if (_name != null) {
       offset_name = fbBuilder.writeString(_name);
     }
@@ -5491,6 +6308,9 @@
     if (_inferredTypeSlot != null && _inferredTypeSlot != 0) {
       fbBuilder.addUint32(9, _inferredTypeSlot);
     }
+    if (offset_initializer != null) {
+      fbBuilder.addOffset(13, offset_initializer);
+    }
     if (_isConst == true) {
       fbBuilder.addBool(6, true);
     }
@@ -5538,6 +6358,7 @@
   idl.UnlinkedConst _constExpr;
   idl.UnlinkedDocumentationComment _documentationComment;
   int _inferredTypeSlot;
+  idl.UnlinkedExecutable _initializer;
   bool _isConst;
   bool _isFinal;
   bool _isStatic;
@@ -5573,6 +6394,12 @@
   }
 
   @override
+  idl.UnlinkedExecutable get initializer {
+    _initializer ??= const _UnlinkedExecutableReader().vTableGet(_bp, 13, null);
+    return _initializer;
+  }
+
+  @override
   bool get isConst {
     _isConst ??= const fb.BoolReader().vTableGet(_bp, 6, false);
     return _isConst;
@@ -5629,11 +6456,32 @@
 
 abstract class _UnlinkedVariableMixin implements idl.UnlinkedVariable {
   @override
+  Map<String, Object> toJson() {
+    Map<String, Object> _result = <String, Object>{};
+    if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (constExpr != null) _result["constExpr"] = constExpr.toJson();
+    if (documentationComment != null) _result["documentationComment"] = documentationComment.toJson();
+    if (inferredTypeSlot != 0) _result["inferredTypeSlot"] = inferredTypeSlot;
+    if (initializer != null) _result["initializer"] = initializer.toJson();
+    if (isConst != false) _result["isConst"] = isConst;
+    if (isFinal != false) _result["isFinal"] = isFinal;
+    if (isStatic != false) _result["isStatic"] = isStatic;
+    if (name != '') _result["name"] = name;
+    if (nameOffset != 0) _result["nameOffset"] = nameOffset;
+    if (propagatedTypeSlot != 0) _result["propagatedTypeSlot"] = propagatedTypeSlot;
+    if (type != null) _result["type"] = type.toJson();
+    if (visibleLength != 0) _result["visibleLength"] = visibleLength;
+    if (visibleOffset != 0) _result["visibleOffset"] = visibleOffset;
+    return _result;
+  }
+
+  @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "constExpr": constExpr,
     "documentationComment": documentationComment,
     "inferredTypeSlot": inferredTypeSlot,
+    "initializer": initializer,
     "isConst": isConst,
     "isFinal": isFinal,
     "isStatic": isStatic,
@@ -5644,5 +6492,8 @@
     "visibleLength": visibleLength,
     "visibleOffset": visibleOffset,
   };
+
+  @override
+  String toString() => convert.JSON.encode(toJson());
 }
 
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index fca673c..9d840b9 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -292,6 +292,16 @@
   ReferenceKind get kind;
 
   /**
+   * If [kind] is [ReferenceKind.function] (that is, the entity being referred
+   * to is a local function), the index of the function within
+   * [UnlinkedExecutable.localFunctions].  If [kind] is
+   * [ReferenceKind.variable], the index of the variable within
+   * [UnlinkedExecutable.localVariables].  Otherwise zero.
+   */
+  @Id(6)
+  int get localIndex;
+
+  /**
    * If this [LinkedReference] doesn't have an associated [UnlinkedReference],
    * name of the entity being referred to.  For the pseudo-type `dynamic`, the
    * string is "dynamic".  For the pseudo-type `void`, the string is "void".
@@ -301,7 +311,8 @@
 
   /**
    * If the entity being referred to is generic, the number of type parameters
-   * it accepts.  Otherwise zero.
+   * it declares (does not include type parameters of enclosing entities).
+   * Otherwise zero.
    */
   @Id(4)
   int get numTypeParameters;
@@ -343,6 +354,47 @@
 }
 
 /**
+ * Summary information about a package.
+ */
+@topLevel
+abstract class PackageBundle extends base.SummaryClass {
+  factory PackageBundle.fromBuffer(List<int> buffer) =>
+      generated.readPackageBundle(buffer);
+
+  /**
+   * Linked libraries.
+   */
+  @Id(0)
+  List<LinkedLibrary> get linkedLibraries;
+
+  /**
+   * The list of URIs of items in [linkedLibraries], e.g. `dart:core` or
+   * `package:foo/bar.dart`.
+   */
+  @Id(1)
+  List<String> get linkedLibraryUris;
+
+  /**
+   * List of MD5 hashes of the files listed in [unlinkedUnitUris].  Each hash
+   * is encoded as a hexadecimal string using lower case letters.
+   */
+  @Id(4)
+  List<String> get unlinkedUnitHashes;
+
+  /**
+   * Unlinked information for the compilation units constituting the package.
+   */
+  @Id(2)
+  List<UnlinkedUnit> get unlinkedUnits;
+
+  /**
+   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
+   */
+  @Id(3)
+  List<String> get unlinkedUnitUris;
+}
+
+/**
  * Enum used to indicate the kind of entity referred to by a
  * [LinkedReference].
  */
@@ -380,6 +432,16 @@
   typedef,
 
   /**
+   * The entity is a local function.
+   */
+  function,
+
+  /**
+   * The entity is a local variable.
+   */
+  variable,
+
+  /**
    * The entity is a top level function.
    */
   topLevelFunction,
@@ -401,39 +463,6 @@
 }
 
 /**
- * Information about SDK.
- */
-@topLevel
-abstract class SdkBundle extends base.SummaryClass {
-  factory SdkBundle.fromBuffer(List<int> buffer) =>
-      generated.readSdkBundle(buffer);
-
-  /**
-   * Linked libraries.
-   */
-  @Id(0)
-  List<LinkedLibrary> get linkedLibraries;
-
-  /**
-   * The list of URIs of items in [linkedLibraries], e.g. `dart:core`.
-   */
-  @Id(1)
-  List<String> get linkedLibraryUris;
-
-  /**
-   * Unlinked information for the compilation units constituting the SDK.
-   */
-  @Id(2)
-  List<UnlinkedUnit> get unlinkedUnits;
-
-  /**
-   * The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
-   */
-  @Id(3)
-  List<String> get unlinkedUnitUris;
-}
-
-/**
  * Unlinked summary information about a class declaration.
  */
 abstract class UnlinkedClass extends base.SummaryClass {
@@ -528,12 +557,28 @@
  */
 abstract class UnlinkedCombinator extends base.SummaryClass {
   /**
+   * If this is a `show` combinator, offset of the end of the list of shown
+   * names.  Otherwise zero.
+   */
+  @informative
+  @Id(3)
+  int get end;
+
+  /**
    * List of names which are hidden.  Empty if this is a `show` combinator.
    */
   @Id(1)
   List<String> get hides;
 
   /**
+   * If this is a `show` combinator, offset of the `show` keyword.  Otherwise
+   * zero.
+   */
+  @informative
+  @Id(2)
+  int get offset;
+
+  /**
    * List of names which are shown.  Empty if this is a `hide` combinator.
    */
   @Id(0)
@@ -1122,6 +1167,12 @@
   List<UnlinkedExecutable> get localFunctions;
 
   /**
+   * The list of local labels.
+   */
+  @Id(22)
+  List<UnlinkedLabel> get localLabels;
+
+  /**
    * The list of local variables.
    */
   @Id(19)
@@ -1136,6 +1187,14 @@
   String get name;
 
   /**
+   * If [kind] is [UnlinkedExecutableKind.constructor] and [name] is not empty,
+   * the offset of the end of the constructor name.  Otherwise zero.
+   */
+  @informative
+  @Id(23)
+  int get nameEnd;
+
+  /**
    * Offset of the executable name relative to the beginning of the file.  For
    * named constructors, this excludes the class name and excludes the ".".
    * For unnamed constructors, this is the offset of the class name (i.e. the
@@ -1154,6 +1213,14 @@
   List<UnlinkedParam> get parameters;
 
   /**
+   * If [kind] is [UnlinkedExecutableKind.constructor] and [name] is not empty,
+   * the offset of the period before the constructor name.  Otherwise zero.
+   */
+  @informative
+  @Id(24)
+  int get periodOffset;
+
+  /**
    * If [isRedirectedConstructor] and [isFactory] are both `true`, the
    * constructor to which this constructor redirects; otherwise empty.
    */
@@ -1170,7 +1237,10 @@
 
   /**
    * Declared return type of the executable.  Absent if the executable is a
-   * constructor or the return type is implicit.
+   * constructor or the return type is implicit.  Absent for executables
+   * associated with variable initializers and closures, since these
+   * executables may have return types that are not accessible via direct
+   * imports.
    */
   @Id(3)
   EntityRef get returnType;
@@ -1350,6 +1420,37 @@
 }
 
 /**
+ * Unlinked summary information about a label.
+ */
+abstract class UnlinkedLabel extends base.SummaryClass {
+  /**
+   * Return `true` if this label is associated with a `switch` member (`case` or
+   * `default`).
+   */
+  @Id(2)
+  bool get isOnSwitchMember;
+
+  /**
+   * Return `true` if this label is associated with a `switch` statement.
+   */
+  @Id(3)
+  bool get isOnSwitchStatement;
+
+  /**
+   * Name of the label.
+   */
+  @Id(0)
+  String get name;
+
+  /**
+   * Offset of the label relative to the beginning of the file.
+   */
+  @informative
+  @Id(1)
+  int get nameOffset;
+}
+
+/**
  * Unlinked summary information about a function parameter.
  */
 abstract class UnlinkedParam extends base.SummaryClass {
@@ -1368,6 +1469,14 @@
   UnlinkedConst get defaultValue;
 
   /**
+   * If the parameter has a default value, the source text of the constant
+   * expression in the default value.  Otherwise the empty string.
+   */
+  @informative
+  @Id(13)
+  String get defaultValueCode;
+
+  /**
    * If this parameter's type is inferable, nonzero slot id identifying which
    * entry in [LinkedLibrary.types] contains the inferred type.  If there is no
    * matching entry in [LinkedLibrary.types], then no type was inferred for
@@ -1382,6 +1491,13 @@
   int get inferredTypeSlot;
 
   /**
+   * The synthetic initializer function of the parameter.  Absent if the variable
+   * does not have an initializer.
+   */
+  @Id(12)
+  UnlinkedExecutable get initializer;
+
+  /**
    * Indicates whether this is a function-typed parameter.
    */
   @Id(5)
@@ -1567,6 +1683,7 @@
   /**
    * Name of the entity being referred to.  For the pseudo-type `dynamic`, the
    * string is "dynamic".  For the pseudo-type `void`, the string is "void".
+   * For the pseudo-type `bottom`, the string is "*bottom*".
    */
   @Id(0)
   String get name;
@@ -1812,6 +1929,13 @@
   int get inferredTypeSlot;
 
   /**
+   * The synthetic initializer function of the variable.  Absent if the variable
+   * does not have an initializer.
+   */
+  @Id(13)
+  UnlinkedExecutable get initializer;
+
+  /**
    * Indicates whether the variable is declared using the `const` keyword.
    */
   @Id(6)
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index d6210db..3273c9f 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -32,7 +32,10 @@
 
   @override
   UnlinkedCombinatorBuilder visitShowCombinator(ShowCombinator node) {
-    return new UnlinkedCombinatorBuilder(shows: encodeNames(node.shownNames));
+    return new UnlinkedCombinatorBuilder(
+        shows: encodeNames(node.shownNames),
+        offset: node.offset,
+        end: node.end);
   }
 }
 
@@ -92,8 +95,7 @@
                     member.typeParameters?.typeParameters?.length ?? 0));
           }
         }
-        if (member is ConstructorDeclaration &&
-            member.name != null) {
+        if (member is ConstructorDeclaration && member.name != null) {
           String name = member.name.name;
           if (isPublic(name)) {
             cls.members.add(new UnlinkedPublicNameBuilder(
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index de64232..4f6eb20 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/element_handle.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -439,9 +440,20 @@
         case UnlinkedConstOperation.pushReference:
           EntityRef ref = uc.references[refPtr++];
           _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
-          SimpleIdentifier node = AstFactory.identifier3(info.name);
-          node.staticElement = info.element;
-          _push(node);
+          if (info.enclosing != null &&
+              info.enclosing.element != null &&
+              info.enclosing.element is! ClassElement) {
+            SimpleIdentifier prefix = AstFactory.identifier3(
+                info.enclosing.name)..staticElement = info.enclosing.element;
+            SimpleIdentifier name = AstFactory.identifier3(info.name)
+              ..staticElement = info.element;
+            PrefixedIdentifier node = AstFactory.identifier(prefix, name);
+            _push(node);
+          } else {
+            SimpleIdentifier node = AstFactory.identifier3(info.name);
+            node.staticElement = info.element;
+            _push(node);
+          }
           break;
         case UnlinkedConstOperation.invokeConstructor:
           _pushInstanceCreation();
@@ -678,6 +690,102 @@
 }
 
 /**
+ * Local function element representing the intializer for a variable that has
+ * been resynthesized from a summary.  The actual element won't be constructed
+ * until it is requested.  But properties [context] and [enclosingElement] can
+ * be used without creating the actual element.
+ */
+class _DeferredInitializerElement extends FunctionElementHandle {
+  /**
+   * The variable element containing this element.
+   */
+  @override
+  final VariableElement enclosingElement;
+
+  _DeferredInitializerElement(this.enclosingElement) : super(null, null);
+
+  @override
+  FunctionElement get actualElement => enclosingElement.initializer;
+
+  @override
+  AnalysisContext get context => enclosingElement.context;
+
+  @override
+  ElementLocation get location => actualElement.location;
+}
+
+/**
+ * Local function element that has been resynthesized from a summary.  The
+ * actual element won't be constructed until it is requested.  But properties
+ * [context] and [enclosingElement] can be used without creating the actual
+ * element.
+ */
+class _DeferredLocalFunctionElement extends FunctionElementHandle {
+  /**
+   * The executable element containing this element.
+   */
+  @override
+  final ExecutableElement enclosingElement;
+
+  /**
+   * The index of this function within [ExecutableElement.functions].
+   */
+  final int _localIndex;
+
+  _DeferredLocalFunctionElement(this.enclosingElement, this._localIndex)
+      : super(null, null);
+
+  @override
+  FunctionElement get actualElement {
+    ExecutableElement enclosingElement = this.enclosingElement;
+    if (enclosingElement is PropertyAccessorElement &&
+        enclosingElement.isSynthetic) {
+      return enclosingElement.variable.initializer;
+    } else {
+      return enclosingElement.functions[_localIndex];
+    }
+  }
+
+  @override
+  AnalysisContext get context => enclosingElement.context;
+
+  @override
+  ElementLocation get location => actualElement.location;
+}
+
+/**
+ * Local variable element that has been resynthesized from a summary.  The
+ * actual element won't be constructed until it is requested.  But properties
+ * [context] and [enclosingElement] can be used without creating the actual
+ * element.
+ */
+class _DeferredLocalVariableElement extends LocalVariableElementHandle {
+  /**
+   * The executable element containing this element.
+   */
+  @override
+  final ExecutableElement enclosingElement;
+
+  /**
+   * The index of this variable within [ExecutableElement.localVariables].
+   */
+  final int _localIndex;
+
+  _DeferredLocalVariableElement(this.enclosingElement, this._localIndex)
+      : super(null, null);
+
+  @override
+  LocalVariableElement get actualElement =>
+      enclosingElement.localVariables[_localIndex];
+
+  @override
+  AnalysisContext get context => enclosingElement.context;
+
+  @override
+  ElementLocation get location => actualElement.location;
+}
+
+/**
  * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the
  * elements in a single library from that library's summary.
  */
@@ -922,6 +1030,8 @@
       // Note: we call toList() so that we don't retain a reference to the
       // deserialized data structure.
       combinator.shownNames = serializedCombinator.shows.toList();
+      combinator.offset = serializedCombinator.offset;
+      combinator.end = serializedCombinator.end;
       return combinator;
     } else {
       HideElementCombinatorImpl combinator = new HideElementCombinatorImpl();
@@ -965,6 +1075,13 @@
     assert(serializedExecutable.kind == UnlinkedExecutableKind.constructor);
     currentConstructor = new ConstructorElementImpl(
         serializedExecutable.name, serializedExecutable.nameOffset);
+    if (serializedExecutable.name.isEmpty) {
+      currentConstructor.nameEnd =
+          serializedExecutable.nameOffset + classType.name.length;
+    } else {
+      currentConstructor.nameEnd = serializedExecutable.nameEnd;
+      currentConstructor.periodOffset = serializedExecutable.periodOffset;
+    }
     constructors[serializedExecutable.name] = currentConstructor;
     currentConstructor.returnType = classType;
     buildExecutableCommonParts(currentConstructor, serializedExecutable);
@@ -1026,12 +1143,14 @@
     buildDocumentation(classElement, serializedEnum.documentationComment);
     buildAnnotations(classElement, serializedEnum.annotations);
     ElementHolder memberHolder = new ElementHolder();
+    // Build the 'index' field.
     FieldElementImpl indexField = new FieldElementImpl('index', -1);
     indexField.final2 = true;
     indexField.synthetic = true;
     indexField.type = summaryResynthesizer.typeProvider.intType;
     memberHolder.addField(indexField);
     buildImplicitAccessors(indexField, memberHolder);
+    // Build the 'values' field.
     FieldElementImpl valuesField = new ConstFieldElementImpl('values', -1);
     valuesField.synthetic = true;
     valuesField.const3 = true;
@@ -1040,16 +1159,34 @@
         .substitute4(<DartType>[enumType]);
     memberHolder.addField(valuesField);
     buildImplicitAccessors(valuesField, memberHolder);
-    for (UnlinkedEnumValue serializedEnumValue in serializedEnum.values) {
-      ConstFieldElementImpl valueField = new ConstFieldElementImpl(
-          serializedEnumValue.name, serializedEnumValue.nameOffset);
-      buildDocumentation(valueField, serializedEnumValue.documentationComment);
-      valueField.const3 = true;
-      valueField.static = true;
-      valueField.type = enumType;
-      memberHolder.addField(valueField);
-      buildImplicitAccessors(valueField, memberHolder);
+    // Build fields for all enum constants.
+    List<DartObjectImpl> constantValues = <DartObjectImpl>[];
+    for (int i = 0; i < serializedEnum.values.length; i++) {
+      UnlinkedEnumValue serializedEnumValue = serializedEnum.values[i];
+      String fieldName = serializedEnumValue.name;
+      ConstFieldElementImpl field =
+          new ConstFieldElementImpl(fieldName, serializedEnumValue.nameOffset);
+      buildDocumentation(field, serializedEnumValue.documentationComment);
+      field.const3 = true;
+      field.static = true;
+      field.type = enumType;
+      // Create a value for the constant.
+      Map<String, DartObjectImpl> fieldMap = <String, DartObjectImpl>{
+        fieldName: new DartObjectImpl(
+            summaryResynthesizer.typeProvider.intType, new IntState(i))
+      };
+      DartObjectImpl value =
+          new DartObjectImpl(enumType, new GenericState(fieldMap));
+      constantValues.add(value);
+      field.evaluationResult = new EvaluationResultImpl(value);
+      // Add the field.
+      memberHolder.addField(field);
+      buildImplicitAccessors(field, memberHolder);
     }
+    // Build the value of the 'values' field.
+    valuesField.evaluationResult = new EvaluationResultImpl(
+        new DartObjectImpl(valuesField.type, new ListState(constantValues)));
+    // done
     classElement.fields = memberHolder.fields;
     classElement.accessors = memberHolder.accessors;
     classElement.constructors = <ConstructorElement>[];
@@ -1162,6 +1299,8 @@
     buildAnnotations(executableElement, serializedExecutable.annotations);
     executableElement.functions =
         serializedExecutable.localFunctions.map(buildLocalFunction).toList();
+    executableElement.labels =
+        serializedExecutable.localLabels.map(buildLocalLabel).toList();
     executableElement.localVariables =
         serializedExecutable.localVariables.map(buildLocalVariable).toList();
     currentTypeParameters.removeLast();
@@ -1215,11 +1354,13 @@
         return new PropertyAccessorElementHandle(
             summaryResynthesizer, location);
       case ReferenceKind.constructor:
+      case ReferenceKind.function:
       case ReferenceKind.propertyAccessor:
       case ReferenceKind.method:
       case ReferenceKind.length:
       case ReferenceKind.prefix:
       case ReferenceKind.unresolved:
+      case ReferenceKind.variable:
         // Should never happen.  Exported names never refer to import prefixes,
         // and they always refer to defined top-level entities.
         throw new StateError('Unexpected export name kind: ${exportName.kind}');
@@ -1465,7 +1606,8 @@
   /**
    * Resynthesize a local [FunctionElement].
    */
-  FunctionElement buildLocalFunction(UnlinkedExecutable serializedExecutable) {
+  FunctionElementImpl buildLocalFunction(
+      UnlinkedExecutable serializedExecutable) {
     FunctionElementImpl element = new FunctionElementImpl(
         serializedExecutable.name, serializedExecutable.nameOffset);
     if (serializedExecutable.visibleOffset != 0) {
@@ -1477,6 +1619,17 @@
   }
 
   /**
+   * Resynthesize a [LabelElement].
+   */
+  LabelElement buildLocalLabel(UnlinkedLabel serializedLabel) {
+    return new LabelElementImpl(
+        serializedLabel.name,
+        serializedLabel.nameOffset,
+        serializedLabel.isOnSwitchStatement,
+        serializedLabel.isOnSwitchMember);
+  }
+
+  /**
    * Resynthesize a [LocalVariableElement].
    */
   LocalVariableElement buildLocalVariable(UnlinkedVariable serializedVariable) {
@@ -1518,6 +1671,8 @@
         if (serializedParameter.defaultValue != null) {
           defaultParameter.constantInitializer =
               _buildConstExpression(serializedParameter.defaultValue);
+          defaultParameter.defaultValueCode =
+              serializedParameter.defaultValueCode;
         }
       }
       parameterElement = initializingParameter;
@@ -1534,6 +1689,8 @@
         if (serializedParameter.defaultValue != null) {
           defaultParameter.constantInitializer =
               _buildConstExpression(serializedParameter.defaultValue);
+          defaultParameter.defaultValueCode =
+              serializedParameter.defaultValueCode;
         }
       }
     }
@@ -1562,6 +1719,7 @@
       }
       parameterElement.hasImplicitType = serializedParameter.type == null;
     }
+    buildVariableInitializer(parameterElement, serializedParameter.initializer);
     switch (serializedParameter.kind) {
       case UnlinkedParamKind.named:
         parameterElement.parameterKind = ParameterKind.NAMED;
@@ -1573,6 +1731,10 @@
         parameterElement.parameterKind = ParameterKind.REQUIRED;
         break;
     }
+    if (serializedParameter.visibleOffset != 0) {
+      parameterElement.setVisibleRange(
+          serializedParameter.visibleOffset, serializedParameter.visibleLength);
+    }
     return parameterElement;
   }
 
@@ -1745,11 +1907,27 @@
     element.const3 = serializedVariable.isConst;
     element.final2 = serializedVariable.isFinal;
     element.hasImplicitType = serializedVariable.type == null;
+    buildVariableInitializer(element, serializedVariable.initializer);
     buildDocumentation(element, serializedVariable.documentationComment);
     buildAnnotations(element, serializedVariable.annotations);
   }
 
   /**
+   * If the given [serializedInitializer] is not `null`, create the
+   * corresponding [FunctionElementImpl] and set it for the [variable].
+   */
+  void buildVariableInitializer(
+      VariableElementImpl variable, UnlinkedExecutable serializedInitializer) {
+    if (serializedInitializer == null) {
+      return null;
+    }
+    FunctionElementImpl initializerElement =
+        buildLocalFunction(serializedInitializer);
+    initializerElement.synthetic = true;
+    variable.initializer = initializerElement;
+  }
+
+  /**
    * Finish creating a [TypeParameterElement] by deserializing its bound.
    */
   void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter,
@@ -1878,6 +2056,9 @@
       } else if (name == 'void') {
         type = VoidTypeImpl.instance;
         element = type.element;
+      } else if (name == '*bottom*') {
+        type = BottomTypeImpl.instance;
+        element = null;
       } else {
         List<String> locationComponents;
         if (enclosingInfo != null && enclosingInfo.element is ClassElement) {
@@ -1892,6 +2073,9 @@
         }
         ElementLocation location =
             new ElementLocationImpl.con3(locationComponents);
+        if (enclosingInfo != null) {
+          numTypeParameters += enclosingInfo.numTypeParameters;
+        }
         switch (linkedReference.kind) {
           case ReferenceKind.classOrEnum:
             element = new ClassElementHandle(summaryResynthesizer, location);
@@ -1900,7 +2084,6 @@
             assert(location.components.length == 4);
             element =
                 new ConstructorElementHandle(summaryResynthesizer, location);
-            numTypeParameters = enclosingInfo.numTypeParameters;
             break;
           case ReferenceKind.length:
             element = _buildStringLengthPropertyAccessorElement();
@@ -1926,6 +2109,28 @@
             element = new FunctionTypeAliasElementHandle(
                 summaryResynthesizer, location);
             break;
+          case ReferenceKind.variable:
+            Element enclosingElement = enclosingInfo.element;
+            if (enclosingElement is ExecutableElement) {
+              element = new _DeferredLocalVariableElement(
+                  enclosingElement, linkedReference.localIndex);
+            } else {
+              throw new StateError('Unexpected element enclosing variable:'
+                  ' ${enclosingElement.runtimeType}');
+            }
+            break;
+          case ReferenceKind.function:
+            Element enclosingElement = enclosingInfo.element;
+            if (enclosingElement is VariableElement) {
+              element = new _DeferredInitializerElement(enclosingElement);
+            } else if (enclosingElement is ExecutableElement) {
+              element = new _DeferredLocalFunctionElement(
+                  enclosingElement, linkedReference.localIndex);
+            } else {
+              throw new StateError('Unexpected element enclosing function:'
+                  ' ${enclosingElement.runtimeType}');
+            }
+            break;
           case ReferenceKind.prefix:
           case ReferenceKind.unresolved:
             break;
@@ -2138,7 +2343,7 @@
     if (specialType != null) {
       type = specialType;
     } else {
-      type = _buildType((_) => DynamicTypeImpl.instance, null);
+      type = _buildType((_) => DynamicTypeImpl.instance, const []);
     }
   }
 
@@ -2181,36 +2386,56 @@
    */
   DartType _buildType(
       DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
-    List<DartType> typeArguments = const <DartType>[];
-    if (numTypeParameters != 0) {
-      typeArguments = <DartType>[];
-      for (int i = 0; i < numTypeParameters; i++) {
-        typeArguments.add(getTypeArgument(i));
-      }
-    }
     ElementHandle element = this.element; // To allow type promotion
     if (element is ClassElementHandle) {
-      return new InterfaceTypeImpl.elementWithNameAndArgs(
-          element, name, typeArguments);
+      return new InterfaceTypeImpl.elementWithNameAndArgs(element, name,
+          _buildTypeArguments(numTypeParameters, getTypeArgument));
     } else if (element is FunctionTypeAliasElementHandle) {
       return new FunctionTypeImpl.elementWithNameAndArgs(
-          element, name, typeArguments, typeArguments.isNotEmpty);
+          element,
+          name,
+          _buildTypeArguments(numTypeParameters, getTypeArgument),
+          numTypeParameters != 0);
     } else if (element is FunctionTypedElement) {
-      FunctionTypedElementComputer computer =
-          implicitFunctionTypeIndices != null
-              ? () {
-                  FunctionTypedElement element = this.element;
-                  for (int index in implicitFunctionTypeIndices) {
-                    element = element.parameters[index].type.element;
-                  }
-                  return element;
-                }
-              : () => this.element;
+      int numTypeArguments;
+      FunctionTypedElementComputer computer;
+      if (implicitFunctionTypeIndices.isNotEmpty) {
+        numTypeArguments = numTypeParameters;
+        computer = () {
+          FunctionTypedElement element = this.element;
+          for (int index in implicitFunctionTypeIndices) {
+            element = element.parameters[index].type.element;
+          }
+          return element;
+        };
+      } else {
+        // For a type that refers to a generic executable, the type arguments are
+        // not supposed to include the arguments to the executable itself.
+        numTypeArguments = enclosing == null ? 0 : enclosing.numTypeParameters;
+        computer = () => this.element;
+      }
       // TODO(paulberry): Is it a bug that we have to pass `false` for
       // isInstantiated?
-      return new DeferredFunctionTypeImpl(computer, null, typeArguments, false);
+      return new DeferredFunctionTypeImpl(computer, null,
+          _buildTypeArguments(numTypeArguments, getTypeArgument), false);
     } else {
       return null;
     }
   }
+
+  /**
+   * Build a list of type arguments having length [numTypeArguments] where each
+   * type argument is obtained by calling [getTypeArgument].
+   */
+  List<DartType> _buildTypeArguments(
+      int numTypeArguments, DartType getTypeArgument(int i)) {
+    List<DartType> typeArguments = const <DartType>[];
+    if (numTypeArguments != 0) {
+      typeArguments = <DartType>[];
+      for (int i = 0; i < numTypeArguments; i++) {
+        typeArguments.add(getTypeArgument(i));
+      }
+    }
+    return typeArguments;
+  }
 }
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index a3d915b..cd9ff61 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -93,8 +93,9 @@
     Expression target = access.target;
     if (target is Identifier) {
       EntityRefBuilder targetRef = serializeIdentifier(target);
-      return new EntityRefBuilder(reference: visitor.serializeReference(
-          targetRef.reference, access.propertyName.name));
+      return new EntityRefBuilder(
+          reference: visitor.serializeReference(
+              targetRef.reference, access.propertyName.name));
     } else {
       // TODO(scheglov) should we handle other targets in malformed constants?
       throw new StateError('Unexpected target type: ${target.runtimeType}');
@@ -193,6 +194,12 @@
       <UnlinkedExportNonPublicBuilder>[];
 
   /**
+   * List of objects which should be written to
+   * [UnlinkedExecutable.localLabels].
+   */
+  List<UnlinkedLabelBuilder> labels = <UnlinkedLabelBuilder>[];
+
+  /**
    * List of objects which should be written to [UnlinkedUnit.parts].
    */
   final List<UnlinkedPartBuilder> parts = <UnlinkedPartBuilder>[];
@@ -402,6 +409,8 @@
     if (combinator is ShowCombinator) {
       b.shows =
           combinator.shownNames.map((SimpleIdentifier id) => id.name).toList();
+      b.offset = combinator.offset;
+      b.end = combinator.end;
     } else if (combinator is HideCombinator) {
       b.hides =
           combinator.hiddenNames.map((SimpleIdentifier id) => id.name).toList();
@@ -475,7 +484,8 @@
    * [UnlinkedExecutable].
    */
   UnlinkedExecutableBuilder serializeExecutable(
-      SimpleIdentifier name,
+      String name,
+      int nameOffset,
       bool isGetter,
       bool isSetter,
       TypeName returnType,
@@ -491,7 +501,7 @@
     _TypeParameterScope typeParameterScope = new _TypeParameterScope();
     scopes.add(typeParameterScope);
     UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
-    String nameString = name.name;
+    String nameString = name;
     if (isGetter) {
       b.kind = UnlinkedExecutableKind.getter;
     } else if (isSetter) {
@@ -502,7 +512,7 @@
     }
     b.isAbstract = body is EmptyFunctionBody;
     b.name = nameString;
-    b.nameOffset = name.offset;
+    b.nameOffset = nameOffset;
     b.typeParameters =
         serializeTypeParameters(typeParameters, typeParameterScope);
     if (!isTopLevel) {
@@ -537,7 +547,12 @@
     return b;
   }
 
-  void serializeFunctionBody(UnlinkedExecutableBuilder b, FunctionBody body) {
+  /**
+   * Record local functions and variables into the given executable. The given
+   * [body] is usually an actual [FunctionBody], but may be an [Expression]
+   * when we process a synthetic variable initializer function.
+   */
+  void serializeFunctionBody(UnlinkedExecutableBuilder b, AstNode body) {
     if (body is BlockFunctionBody || body is ExpressionFunctionBody) {
       for (UnlinkedParamBuilder parameter in b.parameters) {
         parameter.visibleOffset = body.offset;
@@ -545,13 +560,17 @@
       }
     }
     List<UnlinkedExecutableBuilder> oldExecutables = executables;
+    List<UnlinkedLabelBuilder> oldLabels = labels;
     List<UnlinkedVariableBuilder> oldVariables = variables;
     executables = <UnlinkedExecutableBuilder>[];
+    labels = <UnlinkedLabelBuilder>[];
     variables = <UnlinkedVariableBuilder>[];
     body.accept(this);
     b.localFunctions = executables;
+    b.localLabels = labels;
     b.localVariables = variables;
     executables = oldExecutables;
+    labels = oldLabels;
     variables = oldVariables;
   }
 
@@ -571,6 +590,22 @@
   }
 
   /**
+   * If the given [expression] is not `null`, serialize it as an
+   * [UnlinkedExecutableBuilder], otherwise return `null`.
+   */
+  UnlinkedExecutableBuilder serializeInitializerFunction(
+      Expression expression) {
+    if (expression == null) {
+      return null;
+    }
+    UnlinkedExecutableBuilder initializer =
+        new UnlinkedExecutableBuilder(nameOffset: expression.offset);
+    serializeFunctionBody(initializer, expression);
+    initializer.inferredReturnTypeSlot = assignTypeSlot();
+    return initializer;
+  }
+
+  /**
    * Serialize a [FieldFormalParameter], [FunctionTypedFormalParameter], or
    * [SimpleFormalParameter] into an [UnlinkedParam].
    */
@@ -754,6 +789,7 @@
       }
       b.visibleOffset = enclosingBlock?.offset;
       b.visibleLength = enclosingBlock?.length;
+      b.initializer = serializeInitializerFunction(variable.initializer);
       this.variables.add(b);
     }
   }
@@ -806,6 +842,8 @@
     if (node.name != null) {
       b.name = node.name.name;
       b.nameOffset = node.name.offset;
+      b.periodOffset = node.period.offset;
+      b.nameEnd = node.name.end;
     } else {
       b.nameOffset = node.returnType.offset;
     }
@@ -853,7 +891,9 @@
     UnlinkedParamBuilder b = node.parameter.accept(this);
     if (node.defaultValue != null) {
       b.defaultValue = serializeConstExpr(node.defaultValue);
+      b.defaultValueCode = node.defaultValue.toSource();
     }
+    b.initializer = serializeInitializerFunction(node.defaultValue);
     return b;
   }
 
@@ -906,7 +946,8 @@
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     executables.add(serializeExecutable(
-        node.name,
+        node.name.name,
+        node.name.offset,
         node.isGetter,
         node.isSetter,
         node.returnType,
@@ -921,6 +962,26 @@
   }
 
   @override
+  void visitFunctionExpression(FunctionExpression node) {
+    if (node.parent is! FunctionDeclaration) {
+      executables.add(serializeExecutable(
+          null,
+          node.offset,
+          false,
+          false,
+          null,
+          node.parameters,
+          node.body,
+          false,
+          false,
+          null,
+          null,
+          node.typeParameters,
+          false));
+    }
+  }
+
+  @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
     int oldScopesLength = scopes.length;
     _TypeParameterScope typeParameterScope = new _TypeParameterScope();
@@ -974,6 +1035,17 @@
   }
 
   @override
+  void visitLabel(Label node) {
+    AstNode parent = node.parent;
+    labels.add(new UnlinkedLabelBuilder(
+        name: node.label.name,
+        nameOffset: node.offset,
+        isOnSwitchMember: parent is SwitchMember,
+        isOnSwitchStatement:
+            parent is LabeledStatement && parent.statement is SwitchStatement));
+  }
+
+  @override
   void visitLibraryDirective(LibraryDirective node) {
     libraryName =
         node.name.components.map((SimpleIdentifier id) => id.name).join('.');
@@ -987,7 +1059,8 @@
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
     executables.add(serializeExecutable(
-        node.name,
+        node.name.name,
+        node.name.offset,
         node.isGetter,
         node.isSetter,
         node.returnType,
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index b631287..afd3ab1 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -26,8 +26,8 @@
     LibraryElement lib, TypeProvider typeProvider, bool strongMode) {
   var serializer = new _LibrarySerializer(lib, typeProvider, strongMode);
   LinkedLibraryBuilder linked = serializer.serializeLibrary();
-  return new LibrarySerializationResult(
-      linked, serializer.unlinkedUnits, serializer.unitUris);
+  return new LibrarySerializationResult(linked, serializer.unlinkedUnits,
+      serializer.unitUris, serializer.unitSources);
 }
 
 ReferenceKind _getReferenceKind(Element element) {
@@ -38,7 +38,10 @@
   } else if (element is ConstructorElement) {
     return ReferenceKind.constructor;
   } else if (element is FunctionElement) {
-    return ReferenceKind.topLevelFunction;
+    if (element.enclosingElement is CompilationUnitElement) {
+      return ReferenceKind.topLevelFunction;
+    }
+    return ReferenceKind.function;
   } else if (element is FunctionTypeAliasElement) {
     return ReferenceKind.typedef;
   } else if (element is PropertyAccessorElement) {
@@ -48,6 +51,16 @@
     return ReferenceKind.topLevelPropertyAccessor;
   } else if (element is MethodElement) {
     return ReferenceKind.method;
+  } else if (element is TopLevelVariableElement) {
+    // Summaries don't need to distinguish between references to a variable and
+    // references to its getter.
+    return ReferenceKind.topLevelPropertyAccessor;
+  } else if (element is LocalVariableElement) {
+    return ReferenceKind.variable;
+  } else if (element is FieldElement) {
+    // Summaries don't need to distinguish between references to a field and
+    // references to its getter.
+    return ReferenceKind.propertyAccessor;
   } else {
     throw new Exception('Unexpected element kind: ${element.runtimeType}');
   }
@@ -82,7 +95,14 @@
    */
   final List<String> unitUris;
 
-  LibrarySerializationResult(this.linked, this.unlinkedUnits, this.unitUris);
+  /**
+   * Source object corresponding to each compilation unit appearing in the
+   * library.
+   */
+  final List<Source> unitSources;
+
+  LibrarySerializationResult(
+      this.linked, this.unlinkedUnits, this.unitUris, this.unitSources);
 }
 
 /**
@@ -117,9 +137,9 @@
    */
   final UnlinkedUnitBuilder unlinkedUnit = new UnlinkedUnitBuilder();
 
-/**
- * Absolute URI of the compilation unit.
- */
+  /**
+   * Absolute URI of the compilation unit.
+   */
   String unitUri;
 
   /**
@@ -158,10 +178,22 @@
    */
   int unresolvedReferenceIndex = null;
 
+  /**
+   * Index into the "references table" representing the "bottom" type, if such
+   * an index exists.  `null` if no such entry has been made in the references
+   * table yet.
+   */
+  int bottomReferenceIndex = null;
+
   _CompilationUnitSerializer(
       this.librarySerializer, this.compilationUnit, this.unitNum);
 
   /**
+   * Source object for the compilation unit.
+   */
+  Source get unitSource => compilationUnit.source;
+
+  /**
    * Add all classes, enums, typedefs, executables, and top level variables
    * from the given compilation unit [element] to the compilation unit summary.
    * [unitNum] indicates the ordinal position of this compilation unit in the
@@ -354,6 +386,23 @@
   }
 
   /**
+   * Return the index of the entry in the references table
+   * ([LinkedLibrary.references]) used for the "bottom" type.  A new entry is
+   * added to the table if necessary to satisfy the request.
+   */
+  int serializeBottomReference() {
+    if (bottomReferenceIndex == null) {
+      // References to the "bottom" type are always implicit, since there is no
+      // way to explicitly refer to the "bottom" type.  Therefore they should
+      // be stored only in the linked references table.
+      bottomReferenceIndex = linkedReferences.length;
+      linkedReferences.add(new LinkedReferenceBuilder(
+          name: '*bottom*', kind: ReferenceKind.classOrEnum));
+    }
+    return bottomReferenceIndex;
+  }
+
+  /**
    * Serialize the given [classElement], creating an [UnlinkedClass].
    */
   UnlinkedClassBuilder serializeClass(ClassElement classElement) {
@@ -456,6 +505,8 @@
     UnlinkedCombinatorBuilder b = new UnlinkedCombinatorBuilder();
     if (combinator is ShowElementCombinator) {
       b.shows = combinator.shownNames;
+      b.offset = combinator.offset;
+      b.end = combinator.end;
     } else if (combinator is HideElementCombinator) {
       b.hides = combinator.hiddenNames;
     }
@@ -519,7 +570,12 @@
     UnlinkedExecutableBuilder b = new UnlinkedExecutableBuilder();
     b.name = executableElement.name;
     b.nameOffset = executableElement.nameOffset;
-    if (executableElement is! ConstructorElement) {
+    if (executableElement is ConstructorElement) {
+      if (executableElement.name.isNotEmpty) {
+        b.nameEnd = executableElement.nameEnd;
+        b.periodOffset = executableElement.periodOffset;
+      }
+    } else {
       if (!executableElement.hasImplicitReturnType) {
         b.returnType = serializeTypeRef(
             executableElement.type.returnType, executableElement);
@@ -598,6 +654,7 @@
     }
     b.localFunctions =
         executableElement.functions.map(serializeExecutable).toList();
+    b.localLabels = executableElement.labels.map(serializeLabel).toList();
     b.localVariables =
         executableElement.localVariables.map(serializeVariable).toList();
     return b;
@@ -652,6 +709,18 @@
   }
 
   /**
+   * Serialize the given [label], creating an [UnlinkedLabelBuilder].
+   */
+  UnlinkedLabelBuilder serializeLabel(LabelElementImpl label) {
+    UnlinkedLabelBuilder b = new UnlinkedLabelBuilder();
+    b.name = label.name;
+    b.nameOffset = label.nameOffset;
+    b.isOnSwitchMember = label.isOnSwitchMember;
+    b.isOnSwitchStatement = label.isOnSwitchStatement;
+    return b;
+  }
+
+  /**
    * Serialize the given [parameter] into an [UnlinkedParam].
    */
   UnlinkedParamBuilder serializeParam(ParameterElement parameter,
@@ -683,7 +752,7 @@
         b.inferredTypeSlot = storeInferredType(type, context);
       }
     } else {
-      if (type is FunctionType) {
+      if (type is FunctionType && type.element.isSynthetic) {
         b.isFunctionTyped = true;
         b.type = serializeTypeRef(type.returnType, parameter);
         b.parameters = type.parameters
@@ -698,8 +767,13 @@
       Expression initializer = constParameter.constantInitializer;
       if (initializer != null) {
         b.defaultValue = serializeConstExpr(initializer);
+        b.defaultValueCode = parameter.defaultValueCode;
       }
     }
+    // TODO(scheglov) VariableMember.initializer is not implemented
+    if (parameter is! VariableMember && parameter.initializer != null) {
+      b.initializer = serializeExecutable(parameter.initializer);
+    }
     {
       SourceRange visibleRange = parameter.visibleRange;
       if (visibleRange != null) {
@@ -728,6 +802,13 @@
     Element element = type.element;
     LibraryElement dependentLibrary = element?.library;
     if (dependentLibrary == null) {
+      if (type.isBottom) {
+        // References to the "bottom" type are always implicit, since there is
+        // no way to explicitly refer to the "bottom" type.  Therefore they
+        // should always be linked.
+        assert(linked);
+        return serializeBottomReference();
+      }
       assert(type.isDynamic || type.isVoid);
       if (type is UndefinedTypeImpl) {
         return serializeUnresolvedReference();
@@ -865,8 +946,8 @@
     // the element model.  For the moment we use a name that can't possibly
     // ever exist.
     if (unresolvedReferenceIndex == null) {
-      return serializeUnlinkedReference(
-          '*unresolved*', ReferenceKind.unresolved);
+      unresolvedReferenceIndex =
+          serializeUnlinkedReference('*unresolved*', ReferenceKind.unresolved);
     }
     return unresolvedReferenceIndex;
   }
@@ -913,21 +994,24 @@
         b.visibleLength = visibleRange.length;
       }
     }
+    // TODO(scheglov) VariableMember.initializer is not implemented
+    if (variable is! VariableMember && variable.initializer != null) {
+      b.initializer = serializeExecutable(variable.initializer);
+    }
     return b;
   }
 
   /**
    * Create a slot id for the given [type] (which is an inferred type).  If
-   * strong mode is enabled and [type] is not `dynamic`, it is stored in
-   * [linkedTypes] so that once the compilation unit has been fully visited, it
-   * will be serialized into [LinkedUnit.types].
+   * [type] is not `dynamic`, it is stored in [linkedTypes] so that once the
+   * compilation unit has been fully visited, it will be serialized into
+   * [LinkedUnit.types].
    *
    * [context] is the element within which the slot id will appear; this is
    * used to serialize type parameters.
    */
   int storeInferredType(DartType type, Element context) {
-    return storeLinkedType(
-        librarySerializer.strongMode && !type.isDynamic ? type : null, context);
+    return storeLinkedType(type.isDynamic ? null : type, context);
   }
 
   /**
@@ -950,23 +1034,17 @@
 
   int _getElementReferenceId(Element element, {bool linked: false}) {
     return referenceMap.putIfAbsent(element, () {
-      LibraryElement dependentLibrary;
+      LibraryElement dependentLibrary = librarySerializer.libraryElement;
+      int unit = 0;
+      Element enclosingElement;
       if (element != null) {
-        Element enclosingElement = element.enclosingElement;
+        enclosingElement = element.enclosingElement;
         if (enclosingElement is CompilationUnitElement) {
           dependentLibrary = enclosingElement.library;
+          unit = dependentLibrary.units.indexOf(enclosingElement);
+          assert(unit != -1);
         }
       }
-      int unit;
-      if (dependentLibrary == null) {
-        unit = 0;
-        dependentLibrary = librarySerializer.libraryElement;
-      } else {
-        CompilationUnitElement unitElement =
-            element.getAncestor((Element e) => e is CompilationUnitElement);
-        unit = dependentLibrary.units.indexOf(unitElement);
-        assert(unit != -1);
-      }
       ReferenceKind kind = _getReferenceKind(element);
       String name = element == null ? 'void' : element.name;
       int index;
@@ -974,11 +1052,31 @@
       if (linked) {
         linkedReference =
             new LinkedReferenceBuilder(kind: kind, unit: unit, name: name);
-        Element enclosing = element?.enclosingElement;
-        if (enclosing is ClassElement) {
+        if (enclosingElement != null &&
+            enclosingElement is! CompilationUnitElement) {
           linkedReference.containingReference =
-              _getElementReferenceId(enclosing, linked: linked);
-          linkedReference.numTypeParameters = enclosing.typeParameters.length;
+              _getElementReferenceId(enclosingElement, linked: linked);
+          if (enclosingElement is ClassElement) {
+            // Nothing to do.
+          } else if (enclosingElement is ExecutableElement) {
+            if (element is FunctionElement) {
+              assert(enclosingElement.functions.contains(element));
+              linkedReference.localIndex =
+                  enclosingElement.functions.indexOf(element);
+            } else if (element is LocalVariableElement) {
+              assert(enclosingElement.localVariables.contains(element));
+              linkedReference.localIndex =
+                  enclosingElement.localVariables.indexOf(element);
+            } else {
+              throw new StateError(
+                  'Unexpected enclosed element type: ${element.runtimeType}');
+            }
+          } else if (enclosingElement is VariableElement) {
+            assert(identical(enclosingElement.initializer, element));
+          } else {
+            throw new StateError(
+                'Unexpected enclosing element type: ${enclosingElement.runtimeType}');
+          }
         }
         index = linkedReferences.length;
         linkedReferences.add(linkedReference);
@@ -1231,6 +1329,13 @@
   }
 
   /**
+   * Retrieve a list of the Sources for the compilation units in the library.
+   */
+  List<String> get unitSources => compilationUnitSerializers
+      .map((_CompilationUnitSerializer s) => s.unitSource)
+      .toList();
+
+  /**
    * Retrieve a list of the URIs for the compilation units in the library.
    */
   List<String> get unitUris => compilationUnitSerializers
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 2108b74..ad422ca 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/context/cache.dart' show CacheEntry;
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -23,7 +24,7 @@
 
 class SdkSummaryResultProvider implements SummaryResultProvider {
   final InternalAnalysisContext context;
-  final SdkBundle bundle;
+  final PackageBundle bundle;
   final SummaryTypeProvider typeProvider = new SummaryTypeProvider();
 
   @override
@@ -49,7 +50,6 @@
     if (target.source == null || !target.source.isInSystemLibrary) {
       return false;
     }
-//    print('SummarySdkAnalysisContext: $result of $target');
     // Constant expressions are always resolved in summaries.
     if (result == CONSTANT_EXPRESSION_RESOLVED &&
         target is ConstantEvaluationTarget) {
@@ -89,6 +89,21 @@
 //        throw new UnimplementedError('$result of $target');
       }
     }
+    if (target is LibrarySpecificUnit) {
+      if (target.library == null || !target.library.isInSystemLibrary) {
+        return false;
+      }
+      if (result == COMPILATION_UNIT_ELEMENT) {
+        String libraryUri = target.library.uri.toString();
+        String unitUri = target.unit.uri.toString();
+        CompilationUnitElement unit = resynthesizer.getElement(
+            new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
+        if (unit != null) {
+          entry.setValue(result, unit, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+      }
+    }
     return false;
   }
 
@@ -120,7 +135,7 @@
  * The implementation of [SummaryResynthesizer] for Dart SDK.
  */
 class SdkSummaryResynthesizer extends SummaryResynthesizer {
-  final SdkBundle bundle;
+  final PackageBundle bundle;
   final Map<String, UnlinkedUnit> unlinkedSummaries = <String, UnlinkedUnit>{};
   final Map<String, LinkedLibrary> linkedSummaries = <String, LinkedLibrary>{};
 
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index b492bb2..d21914c 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -271,13 +271,6 @@
     new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT9', false);
 
 /**
- * The [Element]s defined in a [LibrarySpecificUnit].
- */
-final ListResultDescriptor<Element> DEFINED_ELEMENTS =
-    new ListResultDescriptor<Element>('DEFINED_ELEMENTS', null,
-        cachingPolicy: ELEMENT_CACHING_POLICY);
-
-/**
  * The sources representing the export closure of a library.
  * The [Source]s include only library sources, not their units.
  *
@@ -877,13 +870,24 @@
     Source source = getRequiredSource();
     CompilationUnit unit = getRequiredInput(PARSED_UNIT_INPUT_NAME);
     //
+    // Try to get the existing CompilationUnitElement.
+    //
+    CompilationUnitElement element;
+    {
+      InternalAnalysisContext internalContext =
+          context as InternalAnalysisContext;
+      AnalysisCache analysisCache = internalContext.analysisCache;
+      CacheEntry cacheEntry = internalContext.getCacheEntry(target);
+      element = analysisCache.getValue(target, COMPILATION_UNIT_ELEMENT);
+      if (element == null &&
+          internalContext.aboutToComputeResult(
+              cacheEntry, COMPILATION_UNIT_ELEMENT)) {
+        element = analysisCache.getValue(target, COMPILATION_UNIT_ELEMENT);
+      }
+    }
+    //
     // Build or reuse CompilationUnitElement.
     //
-//    unit = AstCloner.clone(unit);
-    AnalysisCache analysisCache =
-        (context as InternalAnalysisContext).analysisCache;
-    CompilationUnitElement element =
-        analysisCache.getValue(target, COMPILATION_UNIT_ELEMENT);
     if (element == null) {
       CompilationUnitBuilder builder = new CompilationUnitBuilder();
       element = builder.buildCompilationUnit(
@@ -1168,8 +1172,8 @@
     //
     // Compute export namespace.
     //
-    ExportNamespaceBuilder builder = new ExportNamespaceBuilder();
-    Namespace namespace = builder.build(library);
+    NamespaceBuilder builder = new NamespaceBuilder();
+    Namespace namespace = builder.createExportNamespaceForLibrary(library);
     library.exportNamespace = namespace;
     //
     // Update entry point.
@@ -1356,22 +1360,41 @@
       InternalAnalysisContext internalContext = context;
       owningContext = internalContext.getContextFor(librarySource);
     }
-    LibraryElementImpl libraryElement =
-        new LibraryElementImpl.forNode(owningContext, libraryNameNode);
-    libraryElement.definingCompilationUnit = definingCompilationUnitElement;
-    libraryElement.entryPoint = entryPoint;
-    libraryElement.parts = sourcedCompilationUnits;
-    for (Directive directive in directivesToResolve) {
-      directive.element = libraryElement;
+    //
+    // Try to get the existing LibraryElement.
+    //
+    LibraryElementImpl libraryElement;
+    {
+      InternalAnalysisContext internalContext =
+          context as InternalAnalysisContext;
+      AnalysisCache analysisCache = internalContext.analysisCache;
+      CacheEntry cacheEntry = internalContext.getCacheEntry(target);
+      libraryElement = analysisCache.getValue(target, LIBRARY_ELEMENT1);
+      if (libraryElement == null &&
+          internalContext.aboutToComputeResult(cacheEntry, LIBRARY_ELEMENT1)) {
+        libraryElement = analysisCache.getValue(target, LIBRARY_ELEMENT1);
+      }
     }
-    BuildLibraryElementUtils.patchTopLevelAccessors(libraryElement);
-    // set the library documentation to the docs associated with the first
-    // directive in the compilation unit.
-    if (definingCompilationUnit.directives.isNotEmpty) {
-      setElementDocumentationComment(
-          libraryElement, definingCompilationUnit.directives.first);
+    //
+    // Create a new LibraryElement.
+    //
+    if (libraryElement == null) {
+      libraryElement =
+          new LibraryElementImpl.forNode(owningContext, libraryNameNode);
+      libraryElement.definingCompilationUnit = definingCompilationUnitElement;
+      libraryElement.entryPoint = entryPoint;
+      libraryElement.parts = sourcedCompilationUnits;
+      for (Directive directive in directivesToResolve) {
+        directive.element = libraryElement;
+      }
+      BuildLibraryElementUtils.patchTopLevelAccessors(libraryElement);
+      // set the library documentation to the docs associated with the first
+      // directive in the compilation unit.
+      if (definingCompilationUnit.directives.isNotEmpty) {
+        setElementDocumentationComment(
+            libraryElement, definingCompilationUnit.directives.first);
+      }
     }
-
     //
     // Record outputs.
     //
@@ -1465,7 +1488,8 @@
   @override
   void internalPerform() {
     LibraryElementImpl library = getRequiredInput(LIBRARY_INPUT);
-    library.publicNamespace = new PublicNamespaceBuilder().build(library);
+    NamespaceBuilder builder = new NamespaceBuilder();
+    library.publicNamespace = builder.createPublicNamespaceForLibrary(library);
     outputs[LIBRARY_ELEMENT3] = library;
   }
 
@@ -1578,7 +1602,11 @@
   @override
   void internalPerform() {
     LibraryElement coreLibrary = getRequiredInput(CORE_INPUT);
-    LibraryElement asyncLibrary = getRequiredInput(ASYNC_INPUT);
+    LibraryElement asyncLibrary = getOptionalInput(ASYNC_INPUT);
+    if (asyncLibrary == null) {
+      asyncLibrary =
+          (context as AnalysisContextImpl).createMockAsyncLib(coreLibrary);
+    }
     Namespace coreNamespace = coreLibrary.publicNamespace;
     Namespace asyncNamespace = asyncLibrary.publicNamespace;
     //
@@ -1600,6 +1628,9 @@
     SourceFactory sourceFactory = contextTarget.context.sourceFactory;
     Source coreSource = sourceFactory.forUri(DartSdk.DART_CORE);
     Source asyncSource = sourceFactory.forUri(DartSdk.DART_ASYNC);
+    if (asyncSource == null) {
+      return <String, TaskInput>{CORE_INPUT: LIBRARY_ELEMENT3.of(coreSource)};
+    }
     return <String, TaskInput>{
       CORE_INPUT: LIBRARY_ELEMENT3.of(coreSource),
       ASYNC_INPUT: LIBRARY_ELEMENT3.of(asyncSource)
@@ -2224,6 +2255,16 @@
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor('DartErrorsTask',
       createTask, buildInputs, <ResultDescriptor>[DART_ERRORS]);
 
+  /**
+   * The name of the [LINE_INFO_INPUT] input.
+   */
+  static const String LINE_INFO_INPUT = 'LINE_INFO_INPUT';
+
+  /**
+   * The name of the [PARSED_UNIT_INPUT] input.
+   */
+  static const String PARSED_UNIT_INPUT = 'PARSED_UNIT_INPUT';
+
   // Prefix for comments ignoring error codes.
   static const String _normalizedIgnorePrefix = '//#ignore:';
 
@@ -2274,14 +2315,9 @@
     // Sort errors.
     errors.sort((AnalysisError e1, AnalysisError e2) => e1.offset - e2.offset);
 
-    Source source = target;
-    String contents = context.getContents(source).data;
-    Scanner scanner = new Scanner(source, new CharSequenceReader(contents),
-        AnalysisErrorListener.NULL_LISTENER);
-
-    // Scan.
-    Token token = scanner.tokenize();
-    LineInfo lineInfo = new LineInfo(scanner.lineStarts);
+    CompilationUnit cu = getRequiredInput(PARSED_UNIT_INPUT);
+    Token token = cu.beginToken;
+    LineInfo lineInfo = getRequiredInput(LINE_INFO_INPUT);
 
     int errorIndex = 0;
 
@@ -2344,6 +2380,8 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     Source source = target;
     Map<String, TaskInput> inputs = <String, TaskInput>{};
+    inputs[LINE_INFO_INPUT] = LINE_INFO.of(source);
+    inputs[PARSED_UNIT_INPUT] = PARSED_UNIT.of(source);
     EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin;
     // for Source
     for (ResultDescriptor result in enginePlugin.dartErrorsForSource) {
@@ -2438,109 +2476,6 @@
 }
 
 /**
- * The helper for building the export [Namespace] of a [LibraryElement].
- */
-class ExportNamespaceBuilder {
-  /**
-   * Build the export [Namespace] of the given [LibraryElement].
-   */
-  Namespace build(LibraryElement library) {
-    return new Namespace(
-        _createExportMapping(library, new HashSet<LibraryElement>()));
-  }
-
-  /**
-   * Create a mapping table representing the export namespace of the given
-   * [library].
-   *
-   * The given [visitedElements] a set of libraries that do not need to be
-   * visited when processing the export directives of the given library because
-   * all of the names defined by them will be added by another library.
-   */
-  HashMap<String, Element> _createExportMapping(
-      LibraryElement library, HashSet<LibraryElement> visitedElements) {
-    visitedElements.add(library);
-    try {
-      HashMap<String, Element> definedNames = new HashMap<String, Element>();
-      // Add names of the export directives.
-      for (ExportElement element in library.exports) {
-        LibraryElement exportedLibrary = element.exportedLibrary;
-        if (exportedLibrary != null &&
-            !visitedElements.contains(exportedLibrary)) {
-          //
-          // The exported library will be null if the URI does not reference a
-          // valid library.
-          //
-          HashMap<String, Element> exportedNames =
-              _createExportMapping(exportedLibrary, visitedElements);
-          exportedNames = _applyCombinators(exportedNames, element.combinators);
-          definedNames.addAll(exportedNames);
-        }
-      }
-      // Add names of the public namespace.
-      {
-        Namespace publicNamespace = library.publicNamespace;
-        if (publicNamespace != null) {
-          definedNames.addAll(publicNamespace.definedNames);
-        }
-      }
-      return definedNames;
-    } finally {
-      visitedElements.remove(library);
-    }
-  }
-
-  /**
-   * Apply the given [combinators] to all of the names in [definedNames].
-   */
-  static HashMap<String, Element> _applyCombinators(
-      HashMap<String, Element> definedNames,
-      List<NamespaceCombinator> combinators) {
-    for (NamespaceCombinator combinator in combinators) {
-      if (combinator is HideElementCombinator) {
-        _hide(definedNames, combinator.hiddenNames);
-      } else if (combinator is ShowElementCombinator) {
-        definedNames = _show(definedNames, combinator.shownNames);
-      }
-    }
-    return definedNames;
-  }
-
-  /**
-   * Hide all of the [hiddenNames] by removing them from the given
-   * [definedNames].
-   */
-  static void _hide(
-      HashMap<String, Element> definedNames, List<String> hiddenNames) {
-    for (String name in hiddenNames) {
-      definedNames.remove(name);
-      definedNames.remove('$name=');
-    }
-  }
-
-  /**
-   * Show only the given [shownNames] by removing all other names from the given
-   * [definedNames].
-   */
-  static HashMap<String, Element> _show(
-      HashMap<String, Element> definedNames, List<String> shownNames) {
-    HashMap<String, Element> newNames = new HashMap<String, Element>();
-    for (String name in shownNames) {
-      Element element = definedNames[name];
-      if (element != null) {
-        newNames[name] = element;
-      }
-      String setterName = '$name=';
-      element = definedNames[setterName];
-      if (element != null) {
-        newNames[setterName] = element;
-      }
-    }
-    return newNames;
-  }
-}
-
-/**
  * A task that builds [USED_IMPORTED_ELEMENTS] for a unit.
  */
 class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
@@ -2618,7 +2553,7 @@
       'GatherUsedLocalElementsTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[DEFINED_ELEMENTS, USED_LOCAL_ELEMENTS]);
+      <ResultDescriptor>[USED_LOCAL_ELEMENTS]);
 
   GatherUsedLocalElementsTask(
       InternalAnalysisContext context, AnalysisTarget target)
@@ -2633,7 +2568,7 @@
     CompilationUnitElement unitElement = unit.element;
     LibraryElement libraryElement = unitElement.library;
     //
-    // Prepare defined and used local elements.
+    // Prepare used local elements.
     //
     GatherUsedLocalElementsVisitor visitor =
         new GatherUsedLocalElementsVisitor(libraryElement);
@@ -2641,7 +2576,6 @@
     //
     // Record outputs.
     //
-    outputs[DEFINED_ELEMENTS] = visitor.definedElements;
     outputs[USED_LOCAL_ELEMENTS] = visitor.usedElements;
   }
 
@@ -2675,11 +2609,6 @@
   static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT';
 
   /**
-   * The name of a list of [DEFINED_ELEMENTS] for each library unit input.
-   */
-  static const String DEFINED_ELEMENTS_INPUT = 'DEFINED_ELEMENTS';
-
-  /**
    * The name of a list of [USED_LOCAL_ELEMENTS] for each library unit input.
    */
   static const String USED_LOCAL_ELEMENTS_INPUT = 'USED_LOCAL_ELEMENTS';
@@ -2725,8 +2654,6 @@
     CompilationUnit unit = getRequiredInput(RESOLVED_UNIT_INPUT);
     List<UsedImportedElements> usedImportedElementsList =
         getRequiredInput(USED_IMPORTED_ELEMENTS_INPUT);
-    List<List<Element>> definedElementsList =
-        getRequiredInput(DEFINED_ELEMENTS_INPUT);
     List<UsedLocalElements> usedLocalElementsList =
         getRequiredInput(USED_LOCAL_ELEMENTS_INPUT);
     CompilationUnitElement unitElement = unit.element;
@@ -2751,11 +2678,7 @@
           new UsedLocalElements.merge(usedLocalElementsList);
       UnusedLocalElementsVerifier visitor =
           new UnusedLocalElementsVerifier(errorListener, usedElements);
-      for (List<Element> definedElements in definedElementsList) {
-        for (Element element in definedElements) {
-          element.accept(visitor);
-        }
-      }
+      unitElement.accept(visitor);
     }
     // Dart2js analysis.
     if (analysisOptions.dart2jsHint) {
@@ -2787,8 +2710,6 @@
     Source libSource = unit.library;
     return <String, TaskInput>{
       RESOLVED_UNIT_INPUT: RESOLVED_UNIT.of(unit),
-      DEFINED_ELEMENTS_INPUT:
-          LIBRARY_SPECIFIC_UNITS.of(libSource).toListOf(DEFINED_ELEMENTS),
       USED_LOCAL_ELEMENTS_INPUT:
           LIBRARY_SPECIFIC_UNITS.of(libSource).toListOf(USED_LOCAL_ELEMENTS),
       USED_IMPORTED_ELEMENTS_INPUT:
@@ -3968,45 +3889,6 @@
 }
 
 /**
- * The helper for building the public [Namespace] of a [LibraryElement].
- */
-class PublicNamespaceBuilder {
-  final HashMap<String, Element> definedNames = new HashMap<String, Element>();
-
-  /**
-   * Build a public [Namespace] of the given [library].
-   */
-  Namespace build(LibraryElement library) {
-    definedNames.clear();
-    _addPublicNames(library.definingCompilationUnit);
-    library.parts.forEach(_addPublicNames);
-    return new Namespace(definedNames);
-  }
-
-  /**
-   * Add the given [element] if it has a publicly visible name.
-   */
-  void _addIfPublic(Element element) {
-    String name = element.name;
-    if (name != null && !Scope.isPrivateName(name)) {
-      definedNames[name] = element;
-    }
-  }
-
-  /**
-   * Add all of the public top-level names that are defined in the given
-   * [compilationUnit].
-   */
-  void _addPublicNames(CompilationUnitElement compilationUnit) {
-    compilationUnit.accessors.forEach(_addIfPublic);
-    compilationUnit.enums.forEach(_addIfPublic);
-    compilationUnit.functions.forEach(_addIfPublic);
-    compilationUnit.functionTypeAliases.forEach(_addIfPublic);
-    compilationUnit.types.forEach(_addIfPublic);
-  }
-}
-
-/**
  * A task that ensures that [LIBRARY_ELEMENT2] is ready for the target library
  * source and its import/export closure.
  */
@@ -5113,9 +4995,11 @@
     //
     TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
-    if (context.analysisOptions.strongMode) {
+    AnalysisOptionsImpl options = context.analysisOptions;
+    if (options.strongMode) {
       unit.accept(new CodeChecker(
-          typeProvider, new StrongTypeSystemImpl(), errorListener));
+          typeProvider, new StrongTypeSystemImpl(), errorListener,
+          hints: options.strongModeHints));
     }
     //
     // Record outputs.
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index b391517..8f0c9de 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:analyzer/src/generated/type_system.dart';
@@ -565,7 +566,7 @@
   }
 
   StaticInfo _checkAssignment(Expression expr, DartType toT) {
-    final fromT = expr.staticType ?? DynamicTypeImpl.instance;
+    final fromT = _getStaticType(expr);
     final Coercion c = _coerceTo(fromT, toT);
     if (c is Identity) return null;
     if (c is CoercionError) return new StaticTypeError(rules, expr, toT);
@@ -770,7 +771,63 @@
   }
 
   DartType _getStaticType(Expression expr) {
-    return expr.staticType ?? DynamicTypeImpl.instance;
+    DartType t = expr.staticType ?? DynamicTypeImpl.instance;
+
+    // Remove fuzzy arrow if possible.
+    if (t is FunctionType && StaticInfo.isKnownFunction(expr)) {
+      t = _removeFuzz(t);
+    }
+
+    return t;
+  }
+
+  /// Remove "fuzzy arrow" in this function type.
+  ///
+  /// Normally we treat dynamically typed parameters as bottom for function
+  /// types. This allows type tests such as `if (f is SingleArgFunction)`.
+  /// It also requires a dynamic check on the parameter type to call these
+  /// functions.
+  ///
+  /// When we convert to a strict arrow, dynamically typed parameters become
+  /// top. This is safe to do for known functions, like top-level or local
+  /// functions and static methods. Those functions must already be essentially
+  /// treating dynamic as top.
+  ///
+  /// Only the outer-most arrow can be strict. Any others must be fuzzy, because
+  /// we don't know what function value will be passed there.
+  // TODO(jmesserly): should we use a real "fuzzyArrow" bit on the function
+  // type? That would allow us to implement this in the subtype relation.
+  // TODO(jmesserly): we'll need to factor this differently if we want to
+  // move CodeChecker's functionality into existing analyzer. Likely we can
+  // let the Expression have a strict arrow, then in places were we do
+  // inference, convert back to a fuzzy arrow.
+  FunctionType _removeFuzz(FunctionType t) {
+    bool foundFuzz = false;
+    List<ParameterElement> parameters = <ParameterElement>[];
+    for (ParameterElement p in t.parameters) {
+      ParameterElement newP = _removeParameterFuzz(p);
+      parameters.add(newP);
+      if (p != newP) foundFuzz = true;
+    }
+    if (!foundFuzz) {
+      return t;
+    }
+
+    FunctionElementImpl function = new FunctionElementImpl("", -1);
+    function.synthetic = true;
+    function.returnType = t.returnType;
+    function.shareTypeParameters(t.typeFormals);
+    function.shareParameters(parameters);
+    return function.type = new FunctionTypeImpl(function);
+  }
+
+  /// Removes fuzzy arrow, see [_removeFuzz].
+  ParameterElement _removeParameterFuzz(ParameterElement p) {
+    if (p.type.isDynamic) {
+      return new ParameterElementImpl.synthetic(
+          p.name, typeProvider.objectType, p.parameterKind);
+    }
+    return p;
   }
 
   /// Given an expression, return its type assuming it is
diff --git a/pkg/analyzer/lib/src/task/strong/info.dart b/pkg/analyzer/lib/src/task/strong/info.dart
index c3a5839..6169815 100644
--- a/pkg/analyzer/lib/src/task/strong/info.dart
+++ b/pkg/analyzer/lib/src/task/strong/info.dart
@@ -138,16 +138,7 @@
       }
     }
 
-    Element element = null;
-    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.
-    if (element is FunctionElement ||
-        element is MethodElement && element.isStatic) {
+    if (StaticInfo.isKnownFunction(expression)) {
       return new StaticTypeError(rules, expression, toT);
     }
 
@@ -551,6 +542,19 @@
   // TODO(jmesserly): review the usage of error codes. We probably want our own,
   // as well as some DDC specific [ErrorType]s.
   ErrorCode toErrorCode();
+
+  static bool isKnownFunction(Expression expression) {
+    Element element = null;
+    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;
+  }
 }
 
 class StaticTypeError extends StaticError {
diff --git a/pkg/analyzer/lib/task/model.dart b/pkg/analyzer/lib/task/model.dart
index 58e095b..8144f17 100644
--- a/pkg/analyzer/lib/task/model.dart
+++ b/pkg/analyzer/lib/task/model.dart
@@ -171,6 +171,17 @@
   bool get handlesDependencyCycles => false;
 
   /**
+   * Return the value of the input with the given [name], or `null` if the input
+   * value is not defined.
+   */
+  Object getOptionalInput(String name) {
+    if (inputs == null || !inputs.containsKey(name)) {
+      return null;
+    }
+    return inputs[name];
+  }
+
+  /**
    * Return the value of the input with the given [name]. Throw an exception if
    * the input value is not defined.
    */
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index c376533..bb328c2 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -7,6 +7,7 @@
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
   args: '>=0.12.1 <0.14.0'
+  crypto: ^0.9.0
   glob: ^1.0.3
   html: ^0.12.0
   package_config: ^0.1.1
diff --git a/pkg/analyzer/test/enum_test.dart b/pkg/analyzer/test/enum_test.dart
index a61765d..0ba5a98 100644
--- a/pkg/analyzer/test/enum_test.dart
+++ b/pkg/analyzer/test/enum_test.dart
@@ -69,7 +69,8 @@
   }
 
   void test_Modifier() {
-    new EnumTester<Modifier>()
+    new EnumTester<Modifier>(
+        ignoreGetters: ["persistedValues", "transientValues"])
       ..check_getters()
       ..check_explicit_values();
   }
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 3eb5cd0..5d74e2c 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -176,6 +176,31 @@
     expect(source.uri.toString(), "dart:core");
   }
 
+  void test_fromFile_library_firstExact() {
+    DirectoryBasedDartSdk sdk = _createDartSdk();
+    JavaFile dirHtml = new JavaFile.relative(sdk.libraryDirectory, "html");
+    JavaFile dirDartium = new JavaFile.relative(dirHtml, "dartium");
+    JavaFile file = new JavaFile.relative(dirDartium, "html_dartium.dart");
+    expect(file.isFile(), isTrue);
+    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() {
+    DirectoryBasedDartSdk sdk = _createDartSdk();
+    JavaFile dirHtml = new JavaFile.relative(sdk.libraryDirectory, "html");
+    JavaFile dirCommon = new JavaFile.relative(dirHtml, "html_common");
+    JavaFile file =
+        new JavaFile.relative(dirCommon, "html_common_dart2js.dart");
+    expect(file.isFile(), isTrue);
+    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() {
     DirectoryBasedDartSdk sdk = _createDartSdk();
     Source source = sdk.fromFileUri(new JavaFile.relative(
@@ -275,11 +300,19 @@
    * resulting [ElementHolder].
    */
   ElementHolder buildElementsForText(String code) {
-    compilationUnit = ParserTestCase.parseCompilationUnit(code);
-    ElementHolder holder = new ElementHolder();
-    ElementBuilder builder = new ElementBuilder(holder, compilationUnitElement);
-    compilationUnit.accept(builder);
-    return holder;
+    TestLogger logger = new TestLogger();
+    AnalysisEngine.instance.logger = logger;
+    try {
+      compilationUnit = ParserTestCase.parseCompilationUnit(code);
+      ElementHolder holder = new ElementHolder();
+      ElementBuilder builder =
+          new ElementBuilder(holder, compilationUnitElement);
+      compilationUnit.accept(builder);
+      return holder;
+    } finally {
+      expect(logger.log, hasLength(0));
+      AnalysisEngine.instance.logger = Logger.NULL;
+    }
   }
 
   /**
@@ -587,6 +620,38 @@
     expect(type.isSynthetic, isFalse);
   }
 
+  void test_visitClassDeclaration_invalidFunctionInAnnotation_class() {
+    // https://github.com/dart-lang/sdk/issues/25696
+    String code = r'''
+class A {
+  const A({f});
+}
+
+@A(f: () {})
+class C {}
+''';
+    buildElementsForText(code);
+  }
+
+  void test_visitClassDeclaration_invalidFunctionInAnnotation_method() {
+    String code = r'''
+class A {
+  const A({f});
+}
+
+class C {
+  @A(f: () {})
+  void m() {}
+}
+''';
+    ElementHolder holder = buildElementsForText(code);
+    ClassElement elementC = holder.types[1];
+    expect(elementC, isNotNull);
+    MethodElement methodM = elementC.methods[0];
+    expect(methodM, isNotNull);
+    expect(methodM.functions, isEmpty);
+  }
+
   void test_visitClassDeclaration_minimal() {
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = _makeBuilder(holder);
@@ -986,6 +1051,9 @@
     expect(parameters, hasLength(1));
     ParameterElement parameter = parameters[0];
     expect(parameter.hasImplicitType, isTrue);
+    expect(parameter.initializer, isNotNull);
+    expect(parameter.initializer.type, isNotNull);
+    expect(parameter.initializer.hasImplicitReturnType, isTrue);
     expect(parameter.isConst, isFalse);
     expect(parameter.isDeprecated, isFalse);
     expect(parameter.isFinal, isFalse);
@@ -1012,6 +1080,9 @@
     expect(parameters, hasLength(1));
     ParameterElement parameter = parameters[0];
     expect(parameter.hasImplicitType, isFalse);
+    expect(parameter.initializer, isNotNull);
+    expect(parameter.initializer.type, isNotNull);
+    expect(parameter.initializer.hasImplicitReturnType, isTrue);
     expect(parameter.isConst, isFalse);
     expect(parameter.isDeprecated, isFalse);
     expect(parameter.isFinal, isFalse);
@@ -1931,6 +2002,7 @@
     FunctionElement initializer = parameter.initializer;
     expect(initializer, isNotNull);
     expect(initializer.isSynthetic, isTrue);
+    expect(initializer.hasImplicitReturnType, isTrue);
   }
 
   void test_visitSimpleFormalParameter_noType() {
@@ -2165,6 +2237,7 @@
     expect(fieldElement, isNotNull);
     FunctionElement initializerElement = fieldElement.initializer;
     expect(initializerElement, isNotNull);
+    expect(initializerElement.hasImplicitReturnType, isTrue);
     List<FunctionElement> functionElements = initializerElement.functions;
     expect(functionElements, hasLength(1));
     List<LocalVariableElement> variableElements =
@@ -2217,6 +2290,8 @@
     TopLevelVariableElement variable = variables[0];
     expect(variable, new isInstanceOf<ConstTopLevelVariableElementImpl>());
     expect(variable.initializer, isNotNull);
+    expect(variable.initializer.type, isNotNull);
+    expect(variable.initializer.hasImplicitReturnType, isTrue);
     expect(variable.name, variableName);
     expect(variable.hasImplicitType, isTrue);
     expect(variable.isConst, isTrue);
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 9c4f87c..7c0c15a 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -1462,6 +1462,23 @@
     verify([source]);
   }
 
+  void test_constWithNonConst_with() {
+    Source source = addSource(r'''
+class B {
+  const B();
+}
+class C = B with M;
+class M {}
+const x = const C();
+main() {
+  print(x);
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [CompileTimeErrorCode.CONST_WITH_NON_CONST]);
+    verify([source]);
+  }
+
   void test_constWithNonConstantArgument_annotation() {
     Source source = addSource(r'''
 class A {
@@ -1669,24 +1686,6 @@
     verify([librarySource, sourceA, sourceB]);
   }
 
-  void test_duplicateDefinition_inPart() {
-    Source librarySource = addNamedSource(
-        "/lib.dart",
-        r'''
-library test;
-part 'a.dart';
-class A {}''');
-    Source sourceA = addNamedSource(
-        "/a.dart",
-        r'''
-part of test;
-class A {}''');
-    computeLibrarySourceErrors(librarySource);
-    assertErrors(sourceA, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
-    assertNoErrors(librarySource);
-    verify([librarySource, sourceA]);
-  }
-
   void test_duplicateDefinition_catch() {
     Source source = addSource(r'''
 main() {
@@ -1730,6 +1729,24 @@
     verify([source]);
   }
 
+  void test_duplicateDefinition_inPart() {
+    Source librarySource = addNamedSource(
+        "/lib.dart",
+        r'''
+library test;
+part 'a.dart';
+class A {}''');
+    Source sourceA = addNamedSource(
+        "/a.dart",
+        r'''
+part of test;
+class A {}''');
+    computeLibrarySourceErrors(librarySource);
+    assertErrors(sourceA, [CompileTimeErrorCode.DUPLICATE_DEFINITION]);
+    assertNoErrors(librarySource);
+    verify([librarySource, sourceA]);
+  }
+
   void test_duplicateDefinition_locals_inCase() {
     Source source = addSource(r'''
 main() {
diff --git a/pkg/analyzer/test/generated/declaration_resolver_test.dart b/pkg/analyzer/test/generated/declaration_resolver_test.dart
index 8d6bf51..0f1112d 100644
--- a/pkg/analyzer/test/generated/declaration_resolver_test.dart
+++ b/pkg/analyzer/test/generated/declaration_resolver_test.dart
@@ -314,6 +314,19 @@
     // no other validations than built into DeclarationResolver
   }
 
+  void test_visitMethodDeclaration_unaryMinus() {
+    String code = r'''
+class C {
+  C operator -() => null;
+  C operator -(C other) => null;
+}
+''';
+    CompilationUnit unit = resolveSource(code);
+    // re-resolve
+    _cloneResolveUnit(unit);
+    // no other validations than built into DeclarationResolver
+  }
+
   void test_visitMethodDeclaration_getter_duplicate() {
     String code = r'''
 class C {
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 5c52f17..80e4264 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -3501,11 +3501,7 @@
     }
     _checkCacheEntries(cache);
 
-    try {
-      assertSameResolution(unit, fullNewUnit);
-    } on IncrementalResolutionMismatch catch (mismatch) {
-      fail(mismatch.message);
-    }
+    assertSameResolution(unit, fullNewUnit);
     // errors
     List<AnalysisError> newFullErrors =
         analysisContext.getErrors(source).errors;
@@ -4849,11 +4845,44 @@
     }
   }
 
-  void _assertCacheResults({bool expectCachePostConstantsValid: true}) {
+  void test_updateFunctionToForLoop() {
+    _resolveUnit(r'''
+class PlayDrag {
+  final List<num> times = new List<num>();
+
+  PlayDrag.start() {}
+
+  void update(num pos) {
+    fo (int i = times.length - 2; i >= 0; i--) {}
+  }
+}
+''');
+
+    _updateAndValidate(
+        r'''
+class PlayDrag {
+  final List<num> times = new List<num>();
+
+  PlayDrag.start() {}
+
+  void update(num pos) {
+    for (int i = times.length - 2; i >= 0; i--) {}
+  }
+}
+''',
+        expectLibraryUnchanged: false);
+  }
+
+  void _assertCacheResults(
+      {bool expectLibraryUnchanged: true,
+      bool expectCachePostConstantsValid: true}) {
     _assertCacheSourceResult(TOKEN_STREAM);
     _assertCacheSourceResult(SCAN_ERRORS);
     _assertCacheSourceResult(PARSED_UNIT);
     _assertCacheSourceResult(PARSE_ERRORS);
+    if (!expectLibraryUnchanged) {
+      return;
+    }
     _assertCacheSourceResult(LIBRARY_ELEMENT1);
     _assertCacheSourceResult(LIBRARY_ELEMENT2);
     _assertCacheSourceResult(LIBRARY_ELEMENT3);
@@ -4943,6 +4972,7 @@
 
   void _updateAndValidate(String newCode,
       {bool expectedSuccess: true,
+      bool expectLibraryUnchanged: true,
       bool expectCachePostConstantsValid: true,
       bool compareWithFull: true,
       bool runTasksBeforeIncremental: true}) {
@@ -4955,7 +4985,7 @@
     _resetWithIncremental(true);
     analysisContext2.setContents(source, newCode);
     CompilationUnit newUnit = resolveCompilationUnit(source, oldLibrary);
-    expect(logger.hasError, isFalse);
+    logger.expectNoErrors();
     List<AnalysisError> newErrors = analysisContext.computeErrors(source);
     LineInfo newLineInfo = analysisContext.getLineInfo(source);
     // check for expected failure
@@ -4966,6 +4996,7 @@
     // The cache must still have enough results to make the incremental
     // resolution useful.
     _assertCacheResults(
+        expectLibraryUnchanged: expectLibraryUnchanged,
         expectCachePostConstantsValid: expectCachePostConstantsValid);
     // The existing CompilationUnit[Element] should be updated.
     expect(newUnit, same(oldUnit));
@@ -5255,7 +5286,14 @@
 }
 
 class _TestLogger implements logging.Logger {
-  bool hasError = false;
+  Object lastException;
+  Object lastStackTrace;
+
+  void expectNoErrors() {
+    if (lastException != null) {
+      fail("logged an exception:\n$lastException\n$lastStackTrace\n");
+    }
+  }
 
   @override
   void enter(String name) {}
@@ -5268,7 +5306,8 @@
 
   @override
   void logException(Object exception, [Object stackTrace]) {
-    hasError = true;
+    lastException = exception;
+    lastStackTrace = stackTrace;
   }
 
   @override
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 72186b4..710be9b 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1510,6 +1510,49 @@
         reason: 'parser recovers what it can');
   }
 
+  void test_method_invalidTypeParameterExtends() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25739.
+
+    // TODO(jmesserly): ideally we'd be better at parser recovery here.
+    enableGenericMethods = true;
+    MethodDeclaration method = parse3(
+        "parseClassMember",
+        <Object>["C"],
+        "f<E>(E extends num p);",
+        [
+          ParserErrorCode.MISSING_IDENTIFIER, // `extends` is a keyword
+          ParserErrorCode.EXPECTED_TOKEN, // comma
+          ParserErrorCode.EXPECTED_TOKEN, // close paren
+          ParserErrorCode.MISSING_FUNCTION_BODY
+        ]);
+    expect(method.parameters.toString(), '(E, extends)',
+        reason: 'parser recovers what it can');
+  }
+
+  void test_method_invalidTypeParameterExtendsComment() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/25739.
+
+    // TODO(jmesserly): ideally we'd be better at parser recovery here.
+    // Also, this behavior is slightly different from how we would parse a
+    // normal generic method, because we "discover" the comment at a different
+    // point in the parser. This has a slight effect on the AST that results
+    // from error recovery.
+    enableGenericMethodComments = true;
+    MethodDeclaration method = parse3(
+        "parseClassMember",
+        <Object>["C"],
+        "f/*<E>*/(dynamic/*=E extends num*/p);",
+        [
+          ParserErrorCode.MISSING_IDENTIFIER, // `extends` is a keyword
+          ParserErrorCode.EXPECTED_TOKEN, // comma
+          ParserErrorCode.MISSING_IDENTIFIER, // `extends` is a keyword
+          ParserErrorCode.EXPECTED_TOKEN, // close paren
+          ParserErrorCode.MISSING_FUNCTION_BODY
+        ]);
+    expect(method.parameters.toString(), '(E extends, extends)',
+        reason: 'parser recovers what it can');
+  }
+
   void test_method_invalidTypeParameters() {
     // TODO(jmesserly): ideally we'd be better at parser recovery here.
     // It doesn't try to advance past the invalid token `!` to find the
@@ -1904,6 +1947,16 @@
         [ParserErrorCode.POSITIONAL_PARAMETER_OUTSIDE_GROUP]);
   }
 
+  void test_redirectingConstructorWithBody_named() {
+    parse3("parseClassMember", <Object>["C"], "C.x() : this() {}",
+        [ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY]);
+  }
+
+  void test_redirectingConstructorWithBody_unnamed() {
+    parse3("parseClassMember", <Object>["C"], "C() : this.x() {}",
+        [ParserErrorCode.REDIRECTING_CONSTRUCTOR_WITH_BODY]);
+  }
+
   void test_redirectionInNonFactoryConstructor() {
     parse3("parseClassMember", <Object>["C"], "C() = D;",
         [ParserErrorCode.REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR]);
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 4210fef..339d4d1 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -33,7 +33,6 @@
 import 'package:analyzer/src/generated/testing/test_type_provider.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
-import 'package:analyzer/src/task/dart.dart';
 import 'package:unittest/unittest.dart';
 
 import '../reflective_tests.dart';
@@ -220,6 +219,7 @@
       }
       FunctionElementImpl thenOnValue = ElementFactory.functionElement3(
           'onValue', futureThenR, [futureElement.typeParameters[0]], null);
+      thenOnValue.synthetic = true;
 
       DartType futureRType = futureElement.type.substitute4([futureThenR.type]);
       MethodElementImpl thenMethod = ElementFactory
@@ -256,12 +256,13 @@
       ];
       DartType returnType = streamSubscriptionElement.type
           .substitute4(streamElement.type.typeArguments);
-      List<DartType> parameterTypes = <DartType>[
-        ElementFactory
-            .functionElement3('onData', VoidTypeImpl.instance.element,
-                <TypeDefiningElement>[streamElement.typeParameters[0]], null)
-            .type,
-      ];
+      FunctionElementImpl listenOnData = ElementFactory.functionElement3(
+          'onData',
+          VoidTypeImpl.instance.element,
+          <TypeDefiningElement>[streamElement.typeParameters[0]],
+          null);
+      listenOnData.synthetic = true;
+      List<DartType> parameterTypes = <DartType>[listenOnData.type,];
       // TODO(brianwilkerson) This is missing the optional parameters.
       MethodElementImpl listenMethod =
           ElementFactory.methodElement('listen', returnType, parameterTypes);
@@ -426,8 +427,10 @@
     // core library so public and export namespaces are the same.
     //
     for (LibraryElementImpl library in elementMap.values) {
-      library.exportNamespace =
-          library.publicNamespace = new PublicNamespaceBuilder().build(library);
+      Namespace namespace =
+          new NamespaceBuilder().createPublicNamespaceForLibrary(library);
+      library.exportNamespace = namespace;
+      library.publicNamespace = namespace;
     }
     context.recordLibraryElements(elementMap);
     // Create the synthetic element for `loadLibrary`.
@@ -1489,8 +1492,8 @@
     //   break loop;
     // }
     String label = "loop";
-    LabelElementImpl labelElement =
-        new LabelElementImpl(AstFactory.identifier3(label), false, false);
+    LabelElementImpl labelElement = new LabelElementImpl.forNode(
+        AstFactory.identifier3(label), false, false);
     BreakStatement breakStatement = AstFactory.breakStatement2(label);
     Expression condition = AstFactory.booleanLiteral(true);
     WhileStatement whileStatement =
@@ -1579,8 +1582,8 @@
     //   continue loop;
     // }
     String label = "loop";
-    LabelElementImpl labelElement =
-        new LabelElementImpl(AstFactory.identifier3(label), false, false);
+    LabelElementImpl labelElement = new LabelElementImpl.forNode(
+        AstFactory.identifier3(label), false, false);
     ContinueStatement continueStatement = AstFactory.continueStatement(label);
     Expression condition = AstFactory.booleanLiteral(true);
     WhileStatement whileStatement =
@@ -2383,9 +2386,7 @@
   }
   return null;
 }''');
-    SimpleIdentifier y = _findIdentifier('y = ');
-    expect(y.staticType.toString(), 'dynamic');
-    expect(y.propagatedType.toString(), 'List<dynamic>');
+    _expectIdentifierType('y = ', 'dynamic', 'List<dynamic>');
   }
 }
 
@@ -10146,11 +10147,7 @@
 }
 ''';
     _resolveTestUnit(code);
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.isDynamic, isTrue);
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'dynamic', isNull);
   }
 
   void test_FunctionExpressionInvocation_curried() {
@@ -10162,11 +10159,7 @@
 }
 ''';
     _resolveTestUnit(code);
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'int');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'int', isNull);
   }
 
   void test_FunctionExpressionInvocation_expression() {
@@ -10176,11 +10169,7 @@
 }
 ''';
     _resolveTestUnit(code);
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'int');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'int', isNull);
   }
 
   void test_MethodInvocation_nameType_localVariable() {
@@ -10193,9 +10182,7 @@
 """;
     _resolveTestUnit(code);
     // "foo" should be resolved to the "Foo" type
-    SimpleIdentifier identifier = _findIdentifier("foo();");
-    DartType type = identifier.staticType;
-    expect(type, new isInstanceOf<FunctionType>());
+    _expectIdentifierType("foo();", new isInstanceOf<FunctionType>());
   }
 
   void test_MethodInvocation_nameType_parameter_FunctionTypeAlias() {
@@ -10207,9 +10194,7 @@
 """;
     _resolveTestUnit(code);
     // "foo" should be resolved to the "Foo" type
-    SimpleIdentifier identifier = _findIdentifier("foo();");
-    DartType type = identifier.staticType;
-    expect(type, new isInstanceOf<FunctionType>());
+    _expectIdentifierType("foo();", new isInstanceOf<FunctionType>());
   }
 
   void test_MethodInvocation_nameType_parameter_propagatedType() {
@@ -10222,13 +10207,8 @@
 }
 """;
     _resolveTestUnit(code);
-    SimpleIdentifier identifier = _findIdentifier("p()");
-    expect(identifier.staticType, DynamicTypeImpl.instance);
-    {
-      FunctionType type = identifier.propagatedType;
-      expect(type, isNotNull);
-      expect(type.name, 'Foo');
-    }
+    _expectIdentifierType("p()", DynamicTypeImpl.instance,
+        predicate((type) => type.name == 'Foo'));
   }
 
   void test_staticMethods_classTypeParameters() {
@@ -10241,15 +10221,7 @@
 }
 ''';
     _resolveTestUnit(code);
-    SimpleIdentifier identifier = _findIdentifier('m);');
-    FunctionTypeImpl type = identifier.staticType;
-    expect(type.toString(), '() → void');
-    expect(type.typeParameters, isEmpty,
-        reason: 'static methods should not have type parameters');
-    expect(type.typeArguments, isEmpty,
-        reason: 'static methods should not have type arguments');
-    expect(type.typeFormals, isEmpty,
-        reason: 'this static method is not generic');
+    _expectFunctionType('m);', '() → void');
   }
 
   void test_staticMethods_classTypeParameters_genericMethod() {
@@ -10271,16 +10243,11 @@
     // C - m
     TypeParameterType typeS;
     {
-      SimpleIdentifier identifier = _findIdentifier('m);');
-      FunctionTypeImpl type = identifier.staticType;
-      expect(type.toString(), '<S>(S) → void');
-      expect(type.typeParameters, isEmpty,
-          reason: 'static methods should not have type parameters');
-      expect(type.typeArguments, isEmpty,
-          reason: 'static methods should not have type arguments');
-      expect(type.typeFormals.toString(), '[S]');
-      typeS = type.typeFormals[0].type;
+      _expectFunctionType('m);', '<S>(S) → void',
+          elementTypeParams: '[S]', typeFormals: '[S]');
 
+      FunctionTypeImpl type = _findIdentifier('m);').staticType;
+      typeS = type.typeFormals[0].type;
       type = type.instantiate([DynamicTypeImpl.instance]);
       expect(type.toString(), '(dynamic) → void');
       expect(type.typeParameters.toString(), '[S]');
@@ -10289,13 +10256,13 @@
     }
     // C - m - f
     {
-      SimpleIdentifier identifier = _findIdentifier('f);');
-      FunctionTypeImpl type = identifier.staticType;
-      expect(type.toString(), '<U>(S, U) → void');
-      expect(type.typeParameters.toString(), '[S]');
-      expect(type.typeArguments.toString(), '[S]');
-      expect(type.typeFormals.toString(), '[U]');
+      _expectFunctionType('f);', '<U>(S, U) → void',
+          elementTypeParams: '[U]',
+          typeParams: '[S]',
+          typeArgs: '[S]',
+          typeFormals: '[U]');
 
+      FunctionTypeImpl type = _findIdentifier('f);').staticType;
       type = type.instantiate([DynamicTypeImpl.instance]);
       expect(type.toString(), '(S, dynamic) → void');
       expect(type.typeParameters.toString(), '[S, U]');
@@ -13364,20 +13331,13 @@
   var paramTearOffInst = pf/*<int>*/;
 }
 ''');
-    expect(_findIdentifier('methodTearOffInst').staticType.toString(),
-        "(int) → int");
-    expect(_findIdentifier('staticTearOffInst').staticType.toString(),
-        "(int) → int");
-    expect(_findIdentifier('staticFieldTearOffInst').staticType.toString(),
-        "(int) → int");
-    expect(_findIdentifier('topFunTearOffInst').staticType.toString(),
-        "(int) → int");
-    expect(_findIdentifier('topFieldTearOffInst').staticType.toString(),
-        "(int) → int");
-    expect(_findIdentifier('localTearOffInst').staticType.toString(),
-        "(int) → int");
-    expect(_findIdentifier('paramTearOffInst').staticType.toString(),
-        "(int) → int");
+    _expectIdentifierType('methodTearOffInst', "(int) → int");
+    _expectIdentifierType('staticTearOffInst', "(int) → int");
+    _expectIdentifierType('staticFieldTearOffInst', "(int) → int");
+    _expectIdentifierType('topFunTearOffInst', "(int) → int");
+    _expectIdentifierType('topFieldTearOffInst', "(int) → int");
+    _expectIdentifierType('localTearOffInst', "(int) → int");
+    _expectIdentifierType('paramTearOffInst', "(int) → int");
   }
 
   void setUp() {
@@ -13395,12 +13355,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'int');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'int', isNull);
   }
 
   void test_dynamicObjectMethod_toString() {
@@ -13411,47 +13366,34 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'String');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'String', isNull);
   }
 
   void test_genericFunction() {
     _resolveTestUnit(r'/*=T*/ f/*<T>*/(/*=T*/ x) => null;');
+    _expectFunctionType('f', '<T>(T) → T',
+        elementTypeParams: '[T]', typeFormals: '[T]');
     SimpleIdentifier f = _findIdentifier('f');
     FunctionElementImpl e = f.staticElement;
-    expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.typeFormals.toString(), '[T]');
-    expect(e.type.typeParameters.toString(), '[]');
-    expect(e.type.toString(), '<T>(T) → T');
-
     FunctionType ft = e.type.instantiate([typeProvider.stringType]);
     expect(ft.toString(), '(String) → String');
   }
 
   void test_genericFunction_bounds() {
     _resolveTestUnit(r'/*=T*/ f/*<T extends num>*/(/*=T*/ x) => null;');
-    SimpleIdentifier f = _findIdentifier('f');
-    FunctionElementImpl e = f.staticElement;
-    expect(e.typeParameters.toString(), '[T extends num]');
-    expect(e.type.typeFormals.toString(), '[T extends num]');
-    expect(e.type.typeParameters.toString(), '[]');
-    expect(e.type.toString(), '<T extends num>(T) → T');
+    _expectFunctionType('f', '<T extends num>(T) → T',
+        elementTypeParams: '[T extends num]', typeFormals: '[T extends num]');
   }
 
   void test_genericFunction_parameter() {
     _resolveTestUnit(r'''
 void g(/*=T*/ f/*<T>*/(/*=T*/ x)) {}
 ''');
+    _expectFunctionType('f', '<T>(T) → T',
+        elementTypeParams: '[T]', typeFormals: '[T]');
     SimpleIdentifier f = _findIdentifier('f');
     ParameterElementImpl e = f.staticElement;
     FunctionType type = e.type;
-    expect(e.typeParameters.toString(), '[T]');
-    expect(type.typeFormals.toString(), '[T]');
-    expect(type.toString(), '<T>(T) → T');
     FunctionType ft = type.instantiate([typeProvider.stringType]);
     expect(ft.toString(), '(String) → String');
   }
@@ -13462,14 +13404,10 @@
   static /*=T*/ f/*<T>*/(/*=T*/ x) => null;
 }
 ''');
+    _expectFunctionType('f', '<T>(T) → T',
+        elementTypeParams: '[T]', typeFormals: '[T]');
     SimpleIdentifier f = _findIdentifier('f');
     MethodElementImpl e = f.staticElement;
-    expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.typeFormals.toString(), '[T]');
-    expect(e.type.typeParameters.toString(), '[]');
-    expect(e.type.typeArguments.toString(), '[]');
-    expect(e.type.toString(), '<T>(T) → T');
-
     FunctionType ft = e.type.instantiate([typeProvider.stringType]);
     expect(ft.toString(), '(String) → String');
   }
@@ -13507,46 +13445,18 @@
 ''';
     _resolveTestUnit(code);
 
-    {
+    checkBody(String className) {
       List<Statement> statements =
-          AstFinder.getStatementsInMethod(testUnit, "C", "g");
+          AstFinder.getStatementsInMethod(testUnit, className, "g");
 
-      ExpressionStatement exps0 = statements[1];
-      ExpressionStatement exps1 = statements[2];
-      ExpressionStatement exps2 = statements[3];
-      ExpressionStatement exps3 = statements[4];
-      ExpressionStatement exps4 = statements[5];
-      Expression exp0 = exps0.expression;
-      Expression exp1 = exps1.expression;
-      Expression exp2 = exps2.expression;
-      Expression exp3 = exps3.expression;
-      Expression exp4 = exps4.expression;
-      expect(exp0.staticType, typeProvider.dynamicType);
-      expect(exp1.staticType, typeProvider.dynamicType);
-      expect(exp2.staticType, typeProvider.dynamicType);
-      expect(exp3.staticType, typeProvider.dynamicType);
-      expect(exp4.staticType, typeProvider.dynamicType);
+      for (int i = 1; i <= 5; i++) {
+        Expression exp = (statements[i] as ExpressionStatement).expression;
+        expect(exp.staticType, typeProvider.dynamicType);
+      }
     }
-    {
-      List<Statement> statements =
-          AstFinder.getStatementsInMethod(testUnit, "D", "g");
 
-      ExpressionStatement exps0 = statements[1];
-      ExpressionStatement exps1 = statements[2];
-      ExpressionStatement exps2 = statements[3];
-      ExpressionStatement exps3 = statements[4];
-      ExpressionStatement exps4 = statements[5];
-      Expression exp0 = exps0.expression;
-      Expression exp1 = exps1.expression;
-      Expression exp2 = exps2.expression;
-      Expression exp3 = exps3.expression;
-      Expression exp4 = exps4.expression;
-      expect(exp0.staticType, typeProvider.dynamicType);
-      expect(exp1.staticType, typeProvider.dynamicType);
-      expect(exp2.staticType, typeProvider.dynamicType);
-      expect(exp3.staticType, typeProvider.dynamicType);
-      expect(exp4.staticType, typeProvider.dynamicType);
-    }
+    checkBody("C");
+    checkBody("D");
   }
 
   void test_genericMethod() {
@@ -13558,14 +13468,11 @@
   C<String> cOfString;
 }
 ''');
-    SimpleIdentifier f = _findIdentifier('f');
-    MethodElementImpl e = f.staticElement;
-    expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.typeFormals.toString(), '[T]');
-    expect(e.type.typeParameters.toString(), '[E]');
-    expect(e.type.typeArguments.toString(), '[E]');
-    expect(e.type.toString(), '<T>(E) → List<T>');
-
+    _expectFunctionType('f', '<T>(E) → List<T>',
+        elementTypeParams: '[T]',
+        typeParams: '[E]',
+        typeArgs: '[E]',
+        typeFormals: '[T]');
     SimpleIdentifier c = _findIdentifier('cOfString');
     FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
     expect(ft.toString(), '<T>(String) → List<T>');
@@ -13618,14 +13525,14 @@
   var paramCall = (pf)/*<int>*/(3);
 }
 ''');
-    expect(_findIdentifier('methodCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('localCall').staticType.toString(), "int");
-    expect(_findIdentifier('paramCall').staticType.toString(), "int");
-    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
+    _expectIdentifierType('methodCall', "int");
+    _expectIdentifierType('staticCall', "int");
+    _expectIdentifierType('staticFieldCall', "int");
+    _expectIdentifierType('topFunCall', "int");
+    _expectIdentifierType('topFieldCall', "int");
+    _expectIdentifierType('localCall', "int");
+    _expectIdentifierType('paramCall', "int");
+    _expectIdentifierType('lambdaCall', "int");
   }
 
   void test_genericMethod_functionExpressionInvocation_inferred() {
@@ -13652,14 +13559,14 @@
   var paramCall = (pf)(3);
 }
 ''');
-    expect(_findIdentifier('methodCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('localCall').staticType.toString(), "int");
-    expect(_findIdentifier('paramCall').staticType.toString(), "int");
-    expect(_findIdentifier('lambdaCall').staticType.toString(), "int");
+    _expectIdentifierType('methodCall', "int");
+    _expectIdentifierType('staticCall', "int");
+    _expectIdentifierType('staticFieldCall', "int");
+    _expectIdentifierType('topFunCall', "int");
+    _expectIdentifierType('topFieldCall', "int");
+    _expectIdentifierType('localCall', "int");
+    _expectIdentifierType('paramCall', "int");
+    _expectIdentifierType('lambdaCall', "int");
   }
 
   void test_genericMethod_functionInvocation_explicit() {
@@ -13684,13 +13591,13 @@
   var paramCall = pf/*<int>*/(3);
 }
 ''');
-    expect(_findIdentifier('methodCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('localCall').staticType.toString(), "int");
-    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+    _expectIdentifierType('methodCall', "int");
+    _expectIdentifierType('staticCall', "int");
+    _expectIdentifierType('staticFieldCall', "int");
+    _expectIdentifierType('topFunCall', "int");
+    _expectIdentifierType('topFieldCall', "int");
+    _expectIdentifierType('localCall', "int");
+    _expectIdentifierType('paramCall', "int");
   }
 
   void test_genericMethod_functionInvocation_inferred() {
@@ -13715,13 +13622,13 @@
   var paramCall = pf(3);
 }
 ''');
-    expect(_findIdentifier('methodCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticCall').staticType.toString(), "int");
-    expect(_findIdentifier('staticFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFunCall').staticType.toString(), "int");
-    expect(_findIdentifier('topFieldCall').staticType.toString(), "int");
-    expect(_findIdentifier('localCall').staticType.toString(), "int");
-    expect(_findIdentifier('paramCall').staticType.toString(), "int");
+    _expectIdentifierType('methodCall', "int");
+    _expectIdentifierType('staticCall', "int");
+    _expectIdentifierType('staticFieldCall', "int");
+    _expectIdentifierType('topFunCall', "int");
+    _expectIdentifierType('topFieldCall', "int");
+    _expectIdentifierType('localCall', "int");
+    _expectIdentifierType('paramCall', "int");
   }
 
   void test_genericMethod_functionTypedParameter() {
@@ -13733,13 +13640,11 @@
   C<String> cOfString;
 }
 ''');
-    SimpleIdentifier f = _findIdentifier('f');
-    MethodElementImpl e = f.staticElement;
-    expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.typeFormals.toString(), '[T]');
-    expect(e.type.typeParameters.toString(), '[E]');
-    expect(e.type.typeArguments.toString(), '[E]');
-    expect(e.type.toString(), '<T>((E) → T) → List<T>');
+    _expectFunctionType('f', '<T>((E) → T) → List<T>',
+        elementTypeParams: '[T]',
+        typeParams: '[E]',
+        typeArgs: '[E]',
+        typeFormals: '[T]');
 
     SimpleIdentifier c = _findIdentifier('cOfString');
     FunctionType ft = (c.staticType as InterfaceType).getMethod('f').type;
@@ -13761,17 +13666,13 @@
   list.map((e) => e);
   list.map((e) => 3);
 }''');
+    _expectIdentifierType('map((e) => e);', '<T>((dynamic) → T) → T', isNull);
+    _expectIdentifierType('map((e) => 3);', '<T>((dynamic) → T) → T', isNull);
 
-    SimpleIdentifier map1 = _findIdentifier('map((e) => e);');
-    MethodInvocation m1 = map1.parent;
+    MethodInvocation m1 = _findIdentifier('map((e) => e);').parent;
     expect(m1.staticInvokeType.toString(), '((dynamic) → dynamic) → dynamic');
-    expect(map1.staticType.toString(), '<T>((dynamic) → T) → T');
-    expect(map1.propagatedType, isNull);
-    SimpleIdentifier map2 = _findIdentifier('map((e) => 3);');
-    MethodInvocation m2 = map2.parent;
+    MethodInvocation m2 = _findIdentifier('map((e) => 3);').parent;
     expect(m2.staticInvokeType.toString(), '((dynamic) → int) → int');
-    expect(map2.staticType.toString(), '<T>((dynamic) → T) → T');
-    expect(map2.propagatedType, isNull);
   }
 
   void test_genericMethod_max_doubleDouble() {
@@ -13782,12 +13683,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'double');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'double', isNull);
   }
 
   void test_genericMethod_max_doubleDouble_prefixed() {
@@ -13798,12 +13694,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'double');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'double', isNull);
   }
 
   void test_genericMethod_max_doubleInt() {
@@ -13814,12 +13705,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'num');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'num', isNull);
   }
 
   void test_genericMethod_max_intDouble() {
@@ -13830,12 +13716,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'num');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'num', isNull);
   }
 
   void test_genericMethod_max_intInt() {
@@ -13846,12 +13727,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'int');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'int', isNull);
   }
 
   void test_genericMethod_nestedBound() {
@@ -13881,8 +13757,7 @@
     FunctionType ft = f.staticInvokeType;
     expect('${ft.typeArguments}/${ft.typeParameters}', '[S, int]/[T, S]');
 
-    SimpleIdentifier f2 = _findIdentifier('f;');
-    expect(f2.staticType.toString(), '<S₀>(S₀) → S');
+    _expectIdentifierType('f;', '<S₀>(S₀) → S');
   }
 
   void test_genericMethod_nestedFunctions() {
@@ -13892,10 +13767,8 @@
   return null;
 }
 ''');
-    SimpleIdentifier g = _findIdentifier('f');
-    expect(g.staticType.toString(), '<S>(S) → S');
-    SimpleIdentifier f = _findIdentifier('g');
-    expect(f.staticType.toString(), '<S>(S) → dynamic');
+    _expectIdentifierType('f', '<S>(S) → S');
+    _expectIdentifierType('g', '<S>(S) → dynamic');
   }
 
   void test_genericMethod_override() {
@@ -13907,13 +13780,11 @@
   /*=T*/ f/*<T>*/(/*=T*/ x) => null; // from D
 }
 ''');
+    _expectFunctionType('f/*<T>*/(/*=T*/ x) => null; // from D', '<T>(T) → T',
+        elementTypeParams: '[T]', typeFormals: '[T]');
     SimpleIdentifier f =
         _findIdentifier('f/*<T>*/(/*=T*/ x) => null; // from D');
     MethodElementImpl e = f.staticElement;
-    expect(e.typeParameters.toString(), '[T]');
-    expect(e.type.typeFormals.toString(), '[T]');
-    expect(e.type.toString(), '<T>(T) → T');
-
     FunctionType ft = e.type.instantiate([typeProvider.stringType]);
     expect(ft.toString(), '(String) → String');
   }
@@ -14015,9 +13886,7 @@
   }
   return null;
 }''');
-    SimpleIdentifier y = _findIdentifier('y = ');
-    expect(y.staticType.toString(), 'List<C>');
-    expect(y.propagatedType, isNull);
+    _expectIdentifierType('y = ', 'List<C>', isNull);
   }
 
   void test_genericMethod_tearoff() {
@@ -14042,18 +13911,13 @@
   var paramTearOff = pf;
 }
 ''');
-    expect(
-        _findIdentifier('methodTearOff').staticType.toString(), "<T>(int) → T");
-    expect(
-        _findIdentifier('staticTearOff').staticType.toString(), "<T>(T) → T");
-    expect(_findIdentifier('staticFieldTearOff').staticType.toString(),
-        "<T>(T) → T");
-    expect(
-        _findIdentifier('topFunTearOff').staticType.toString(), "<T>(T) → T");
-    expect(
-        _findIdentifier('topFieldTearOff').staticType.toString(), "<T>(T) → T");
-    expect(_findIdentifier('localTearOff').staticType.toString(), "<T>(T) → T");
-    expect(_findIdentifier('paramTearOff').staticType.toString(), "<T>(T) → T");
+    _expectIdentifierType('methodTearOff', "<T>(int) → T");
+    _expectIdentifierType('staticTearOff', "<T>(T) → T");
+    _expectIdentifierType('staticFieldTearOff', "<T>(T) → T");
+    _expectIdentifierType('topFunTearOff', "<T>(T) → T");
+    _expectIdentifierType('topFieldTearOff', "<T>(T) → T");
+    _expectIdentifierType('localTearOff', "<T>(T) → T");
+    _expectIdentifierType('paramTearOff', "<T>(T) → T");
   }
 
   void test_genericMethod_then() {
@@ -14066,13 +13930,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-
-    expect(declaration.initializer.staticType.toString(), "Future<String>");
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'Future<String>', isNull);
   }
 
   void test_genericMethod_then_prefixed() {
@@ -14085,13 +13943,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-
-    expect(declaration.initializer.staticType.toString(), "Future<String>");
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'Future<String>', isNull);
   }
 
   void test_genericMethod_then_propagatedType() {
@@ -14105,9 +13957,7 @@
 ''';
     // This should produce no hints or warnings.
     _resolveTestUnit(code);
-    VariableDeclaration foo = _findIdentifier('foo').parent;
-    expect(foo.initializer.staticType.toString(), "Future<String>");
-    expect(foo.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'Future<String>', isNull);
   }
 
   void test_setterWithDynamicTypeIsError() {
@@ -14190,12 +14040,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'int');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'int', isNull);
   }
 
   void test_ternaryOperator_null_right() {
@@ -14205,12 +14050,7 @@
 }
 ''';
     _resolveTestUnit(code);
-
-    SimpleIdentifier identifier = _findIdentifier('foo');
-    VariableDeclaration declaration =
-        identifier.getAncestor((node) => node is VariableDeclaration);
-    expect(declaration.initializer.staticType.name, 'int');
-    expect(declaration.initializer.propagatedType, isNull);
+    _expectInitializerType('foo', 'int', isNull);
   }
 }
 
@@ -17120,6 +16960,81 @@
   Source testSource;
   CompilationUnit testUnit;
 
+  /**
+   * Looks up the identifier with [name] and validates that its type type
+   * stringifies to [type] and that its generics match the given stringified
+   * output.
+   */
+  _expectFunctionType(String name, String type,
+      {String elementTypeParams: '[]',
+      String typeParams: '[]',
+      String typeArgs: '[]',
+      String typeFormals: '[]'}) {
+    SimpleIdentifier identifier = _findIdentifier(name);
+    // Element is either ExecutableElement or ParameterElement.
+    var element = identifier.staticElement;
+    FunctionTypeImpl functionType = identifier.staticType;
+    expect(functionType.toString(), type);
+    expect(element.typeParameters.toString(), elementTypeParams);
+    expect(functionType.typeParameters.toString(), typeParams);
+    expect(functionType.typeArguments.toString(), typeArgs);
+    expect(functionType.typeFormals.toString(), typeFormals);
+  }
+
+  /**
+   * Looks up the identifier with [name] and validates its static [type].
+   *
+   * If [type] is a string, validates that the identifier's static type
+   * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
+   * to match the type.
+   *
+   * If [propagatedType] is given, also validate's the identifier's propagated
+   * type.
+   */
+  void _expectIdentifierType(String name, type, [propagatedType]) {
+    SimpleIdentifier identifier = _findIdentifier(name);
+    _expectType(identifier.staticType, type);
+    if (propagatedType != null) {
+      _expectType(identifier.propagatedType, propagatedType);
+    }
+  }
+
+  /**
+   * Looks up the initializer for the declaration containing [identifier] and
+   * validates its static [type].
+   *
+   * If [type] is a string, validates that the identifier's static type
+   * stringifies to that text. Otherwise, [type] is used directly a [Matcher]
+   * to match the type.
+   *
+   * If [propagatedType] is given, also validate's the identifier's propagated
+   * type.
+   */
+  void _expectInitializerType(String name, type, [propagatedType]) {
+    SimpleIdentifier identifier = _findIdentifier(name);
+    VariableDeclaration declaration =
+        identifier.getAncestor((node) => node is VariableDeclaration);
+    Expression initializer = declaration.initializer;
+    _expectType(initializer.staticType, type);
+    if (propagatedType != null) {
+      _expectType(initializer.propagatedType, propagatedType);
+    }
+  }
+
+  /**
+   * Validates that [type] matches [expected].
+   *
+   * If [expected] is a string, validates that the type stringifies to that
+   * text. Otherwise, [expected] is used directly a [Matcher] to match the type.
+   */
+  _expectType(DartType type, expected) {
+    if (expected is String) {
+      expect(type.toString(), expected);
+    } else {
+      expect(type, expected);
+    }
+  }
+
   SimpleIdentifier _findIdentifier(String search) {
     SimpleIdentifier identifier = EngineTestCase.findNode(
         testUnit, testCode, search, (node) => node is SimpleIdentifier);
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 5f5d0ef..137deb5 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -703,6 +703,16 @@
     verify([source]);
   }
 
+  void test_nonBoolCondition_for() {
+    Source source = addSource(r'''
+f() {
+  for (;3;) {}
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.NON_BOOL_CONDITION]);
+    verify([source]);
+  }
+
   void test_nonBoolCondition_if() {
     Source source = addSource(r'''
 f() {
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index f9bca44..20d1a821 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -467,6 +467,27 @@
         [intType]);
   }
 
+  void test_returnTypeFromContext() {
+    // <T>() -> T
+    var t = TypeBuilder.variable('T');
+    var f = TypeBuilder.function(types: [t], required: [], result: t);
+    expect(_inferCall(f, [], stringType), [stringType]);
+  }
+
+  void test_returnTypeWithBoundFromContext() {
+    // <T extends num>() -> T
+    var t = TypeBuilder.variable('T', bound: numType);
+    var f = TypeBuilder.function(types: [t], required: [], result: t);
+    expect(_inferCall(f, [], doubleType), [doubleType]);
+  }
+
+  void test_returnTypeWithBoundFromInvalidContext() {
+    // <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]);
+  }
+
   void test_unifyParametersToFunctionParam() {
     // <T>(f(T t), g(T t)) -> T
     var t = TypeBuilder.variable('T');
@@ -498,9 +519,10 @@
     expect(_inferCall(f, []), [numType]);
   }
 
-  List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments) {
-    FunctionType inferred = typeSystem.inferCallFromArguments(
-        typeProvider, ft, ft.parameters.map((p) => p.type).toList(), arguments);
+  List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments,
+      [DartType returnType]) {
+    FunctionType inferred = typeSystem.inferGenericFunctionCall(typeProvider,
+        ft, ft.parameters.map((p) => p.type).toList(), arguments, returnType);
     return inferred.typeArguments;
   }
 }
@@ -1314,7 +1336,7 @@
     if (returns == null) {
       returns = voidType;
     }
-    
+
     return ElementFactory
         .functionElement8(required, returns, optional: optional, named: named)
         .type;
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index f2a2a9e..f6f898a 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1194,6 +1194,10 @@
   static void _assertEqualTokens(AstNode cloneNode, AstNode originalNode) {
     Token clone = cloneNode.beginToken;
     Token original = originalNode.beginToken;
+    if (original is! CommentToken) {
+      _assertHasPrevious(original);
+      _assertHasPrevious(clone);
+    }
     Token stopOriginalToken = originalNode.endToken.next;
     Token skipCloneComment = null;
     Token skipOriginalComment = null;
@@ -1231,6 +1235,26 @@
       }
     }
   }
+
+  /**
+   * Assert that the [token] has `previous` set, and if it `EOF`, then it
+   * points itself.
+   */
+  static void _assertHasPrevious(Token token) {
+    expect(token, isNotNull);
+    if (token.type == TokenType.EOF) {
+      return;
+    }
+    while (token != null) {
+      Token previous = token.previous;
+      expect(previous, isNotNull);
+      if (token.type == TokenType.EOF) {
+        expect(previous, same(token));
+        break;
+      }
+      token = previous;
+    }
+  }
 }
 
 @reflectiveTest
@@ -3727,10 +3751,14 @@
   void test_variableDeclarationList() {
     VariableDeclarationList node = AstFactory.variableDeclarationList(
         null, AstFactory.typeName4("T"), [AstFactory.variableDeclaration("a")]);
+    node.documentationComment =
+        Comment.createEndOfLineComment(EMPTY_TOKEN_LIST);
+    node.metadata.add(AstFactory.annotation(AstFactory.identifier3("a")));
     _assertReplace(
         node, new Getter_NodeReplacerTest_test_variableDeclarationList());
     _assertReplace(
         node, new ListGetter_NodeReplacerTest_test_variableDeclarationList(0));
+    _testAnnotatedNode(node);
   }
 
   void test_variableDeclarationStatement() {
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index 9bf1b79..7d85c4f 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -13,6 +13,55 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 
+const _MockSdkLibrary _LIB_ASYNC = const _MockSdkLibrary(
+    'dart:async',
+    '/lib/async/async.dart',
+    '''
+library dart.async;
+
+import 'dart:math';
+
+part 'stream.dart';
+
+class Future<T> {
+  factory Future(computation()) => null;
+  factory Future.delayed(Duration duration, [T computation()]) => null;
+  factory Future.value([T value]) => null;
+
+  static Future<List/*<T>*/> wait/*<T>*/(
+      Iterable<Future/*<T>*/> futures) => null;
+  Future/*<R>*/ then/*<R>*/(/*=R*/ onValue(T value)) => null;
+}
+''',
+    const <String, String>{
+      '/lib/async/stream.dart': r'''
+part of dart.async;
+class Stream<T> {}
+abstract class StreamTransformer<S, T> {}
+'''
+    });
+
+const _MockSdkLibrary _LIB_COLLECTION = const _MockSdkLibrary(
+    'dart:collection',
+    '/lib/collection/collection.dart',
+    '''
+library dart.collection;
+
+abstract class HashMap<K, V> implements Map<K, V> {}
+''');
+
+const _MockSdkLibrary _LIB_CONVERT = const _MockSdkLibrary(
+    'dart:convert',
+    '/lib/convert/convert.dart',
+    '''
+library dart.convert;
+
+import 'dart:async';
+
+abstract class Converter<S, T> implements StreamTransformer {}
+class JsonDecoder extends Converter<String, Object> {}
+''');
+
 const _MockSdkLibrary _LIB_CORE = const _MockSdkLibrary(
     'dart:core',
     '/lib/core/core.dart',
@@ -36,7 +85,8 @@
   int compareTo(T other);
 }
 
-abstract class String implements Comparable<String> {
+abstract class Pattern {}
+abstract class String implements Comparable<String>, Pattern {
   external factory String.fromCharCodes(Iterable<int> charCodes,
                                         [int start = 0, int end]);
   String operator +(String other) => null;
@@ -47,6 +97,9 @@
   String toUpperCase();
   List<int> get codeUnits;
 }
+abstract class RegExp implements Pattern {
+  external factory RegExp(String source);
+}
 
 class bool extends Object {}
 abstract class num implements Comparable<num> {
@@ -104,6 +157,8 @@
 
 abstract class Map<K, V> extends Object {
   Iterable<K> get keys;
+  V operator [](K key);
+  void operator []=(K key, V value);
 }
 
 external bool identical(Object a, Object b);
@@ -116,55 +171,6 @@
 const Object override = const _Override();
 ''');
 
-const _MockSdkLibrary _LIB_ASYNC = const _MockSdkLibrary(
-    'dart:async',
-    '/lib/async/async.dart',
-    '''
-library dart.async;
-
-import 'dart:math';
-
-part 'stream.dart';
-
-class Future<T> {
-  factory Future(computation()) => null;
-  factory Future.delayed(Duration duration, [T computation()]) => null;
-  factory Future.value([T value]) => null;
-
-  static Future<List/*<T>*/> wait/*<T>*/(
-      Iterable<Future/*<T>*/> futures) => null;
-  Future/*<R>*/ then/*<R>*/(/*=R*/ onValue(T value)) => null;
-}
-''',
-    const <String, String>{
-      '/lib/async/stream.dart': r'''
-part of dart.async;
-class Stream<T> {}
-abstract class StreamTransformer<S, T> {}
-'''
-    });
-
-const _MockSdkLibrary _LIB_COLLECTION = const _MockSdkLibrary(
-    'dart:collection',
-    '/lib/collection/collection.dart',
-    '''
-library dart.collection;
-
-abstract class HashMap<K, V> implements Map<K, V> {}
-''');
-
-const _MockSdkLibrary _LIB_CONVERT = const _MockSdkLibrary(
-    'dart:convert',
-    '/lib/convert/convert.dart',
-    '''
-library dart.convert;
-
-import 'dart:async';
-
-abstract class Converter<S, T> implements StreamTransformer {}
-class JsonDecoder extends Converter<String, Object> {}
-''');
-
 const _MockSdkLibrary _LIB_FOREIGN_HELPER = const _MockSdkLibrary(
     'dart:_foreign_helper',
     '/lib/_foreign_helper/_foreign_helper.dart',
@@ -176,6 +182,14 @@
 {}
 ''');
 
+const _MockSdkLibrary _LIB_HTML = const _MockSdkLibrary(
+    'dart:html',
+    '/lib/html/dartium/html_dartium.dart',
+    '''
+library dart.html;
+class HtmlElement {}
+''');
+
 const _MockSdkLibrary _LIB_MATH = const _MockSdkLibrary(
     'dart:math',
     '/lib/math/math.dart',
@@ -199,14 +213,6 @@
 }
 ''');
 
-const _MockSdkLibrary _LIB_HTML = const _MockSdkLibrary(
-    'dart:html',
-    '/lib/html/dartium/html_dartium.dart',
-    '''
-library dart.html;
-class HtmlElement {}
-''');
-
 const List<SdkLibrary> _LIBRARIES = const [
   _LIB_CORE,
   _LIB_ASYNC,
@@ -218,16 +224,37 @@
 ];
 
 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"
+  };
+
+  static const Map<String, String> NO_ASYNC_URI_MAP = const {
+    "dart:core": "/lib/core/core.dart",
+  };
+
   final resource.MemoryResourceProvider provider =
       new resource.MemoryResourceProvider();
 
+  final Map<String, String> uriMap;
+
   /**
    * The [AnalysisContextImpl] which is used for all of the sources.
    */
   AnalysisContextImpl _analysisContext;
 
+  @override
+  final List<SdkLibrary> sdkLibraries;
+
   MockSdk({bool dartAsync: true})
-      : sdkLibraries = dartAsync ? _LIBRARIES : [_LIB_CORE] {
+      : 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);
       library.parts.forEach((String path, String content) {
@@ -247,9 +274,6 @@
   }
 
   @override
-  final List<SdkLibrary> sdkLibraries;
-
-  @override
   String get sdkVersion => throw new UnimplementedError();
 
   @override
@@ -299,18 +323,7 @@
 
   @override
   Source mapDartUri(String dartUri) {
-    const Map<String, String> uriToPath = 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"
-    };
-
-    String path = uriToPath[dartUri];
+    String path = uriMap[dartUri];
     if (path != null) {
       resource.File file = provider.getResource(path);
       Uri uri = new Uri(scheme: 'dart', path: dartUri.substring(5));
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index 3f6d653..8b1e4dd 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -13,11 +13,13 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/constant.dart' show DartObject;
 import 'package:analyzer/src/generated/element_handle.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart'
     show Namespace, TypeProvider;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
@@ -51,6 +53,17 @@
     otherLibrarySources.add(addNamedSource(filePath, contents));
   }
 
+  /**
+   * Verify that the given prefix is safe to elide from a resynthesized AST.
+   */
+  void checkElidablePrefix(SimpleIdentifier prefix) {
+    if (prefix.staticElement is! PrefixElement &&
+        prefix.staticElement is! ClassElement) {
+      fail('Prefix of type ${prefix.staticElement.runtimeType}'
+          ' should not have been elided');
+    }
+  }
+
   void checkLibrary(String text,
       {bool allowErrors: false, bool dumpSummaries: false}) {
     Source source = addSource(text);
@@ -135,10 +148,6 @@
     if (original is! LocalElement && resynthesized is! LocalElement) {
       return;
     }
-    // TODO(scheglov) add support for parameters
-    if (original is ParameterElement && resynthesized is ParameterElement) {
-      return;
-    }
     if (original is LocalElement && resynthesized is LocalElement) {
       expect(resynthesized.visibleRange, original.visibleRange);
     } else {
@@ -351,9 +360,27 @@
         expect(r.name, o.name, reason: desc);
         compareElements(r.staticElement, o.staticElement, desc);
       } else if (o is PrefixedIdentifier && r is SimpleIdentifier) {
-        // We often don't resynthesize prefixed identifiers.
-        // We use simple identifiers with correct elements.
-        compareConstAsts(r, o.identifier, desc);
+        // We don't resynthesize prefixed identifiers when the prefix refers to
+        // a PrefixElement or a ClassElement.  We use simple identifiers with
+        // correct elements.
+        if (o.prefix.staticElement is PrefixElement ||
+            o.prefix.staticElement is ClassElement) {
+          compareConstAsts(r, o.identifier, desc);
+        } else {
+          fail('Prefix of type ${o.prefix.staticElement.runtimeType} should not'
+              ' have been elided');
+        }
+      } else if (o is PropertyAccess &&
+          o.target is PrefixedIdentifier &&
+          r is PrefixedIdentifier) {
+        // We don't resynthesize prefixed identifiers when the prefix refers to
+        // a PrefixElement or a ClassElement.  Which means that if the original
+        // expression was e.g. `prefix.topLevelVariableName.length`, it will get
+        // resynthesized as `topLevelVariableName.length`
+        PrefixedIdentifier oTarget = o.target;
+        checkElidablePrefix(oTarget.prefix);
+        compareConstAsts(
+            r, AstFactory.identifier(oTarget.identifier, o.propertyName), desc);
       } else if (o is PrefixedIdentifier && r is PrefixedIdentifier) {
         compareConstAsts(r.prefix, o.prefix, desc);
         compareConstAsts(r.identifier, o.identifier, desc);
@@ -362,9 +389,15 @@
         expect(r.propertyName.name, o.propertyName.name, reason: desc);
         compareElements(
             r.propertyName.staticElement, o.propertyName.staticElement, desc);
-      } else if (o is PropertyAccess && r is SimpleIdentifier) {
-        // We don't resynthesize property access.
-        // We use simple identifiers with correct elements.
+      } else if (o is PropertyAccess &&
+          o.target is PrefixedIdentifier &&
+          r is SimpleIdentifier) {
+        // We don't resynthesize property access when it takes the form
+        // `prefixName.className.staticMember`.  We just resynthesize a
+        // SimpleIdentifier correctly resolved to the static member.
+        PrefixedIdentifier oTarget = o.target;
+        checkElidablePrefix(oTarget.prefix);
+        checkElidablePrefix(oTarget.identifier);
         compareConstAsts(r, o.propertyName, desc);
       } else if (o is NullLiteral) {
         expect(r, new isInstanceOf<NullLiteral>(), reason: desc);
@@ -495,6 +528,60 @@
           original.redirectedConstructor, '$desc redirectedConstructor');
     }
     checkPossibleMember(resynthesized, original, desc);
+    expect(resynthesized.nameEnd, original.nameEnd, reason: desc);
+    expect(resynthesized.periodOffset, original.periodOffset, reason: desc);
+  }
+
+  void compareConstValues(
+      DartObject resynthesized, DartObject original, String desc) {
+    if (original == null) {
+      expect(resynthesized, isNull, reason: desc);
+    } else {
+      expect(resynthesized, isNotNull, reason: desc);
+      compareTypes(resynthesized.type, original.type, desc);
+      expect(resynthesized.hasKnownValue, original.hasKnownValue, reason: desc);
+      if (original.isNull) {
+        expect(resynthesized.isNull, isTrue, reason: desc);
+      } else if (original.toBoolValue() != null) {
+        expect(resynthesized.toBoolValue(), original.toBoolValue(),
+            reason: desc);
+      } else if (original.toIntValue() != null) {
+        expect(resynthesized.toIntValue(), original.toIntValue(), reason: desc);
+      } else if (original.toDoubleValue() != null) {
+        expect(resynthesized.toDoubleValue(), original.toDoubleValue(),
+            reason: desc);
+      } else if (original.toListValue() != null) {
+        List<DartObject> resynthesizedList = resynthesized.toListValue();
+        List<DartObject> originalList = original.toListValue();
+        expect(resynthesizedList, hasLength(originalList.length));
+        for (int i = 0; i < originalList.length; i++) {
+          compareConstValues(resynthesizedList[i], originalList[i], desc);
+        }
+      } else if (original.toMapValue() != null) {
+        Map<DartObject, DartObject> resynthesizedMap =
+            resynthesized.toMapValue();
+        Map<DartObject, DartObject> originalMap = original.toMapValue();
+        expect(resynthesizedMap, hasLength(originalMap.length));
+        List<DartObject> resynthesizedKeys = resynthesizedMap.keys.toList();
+        List<DartObject> originalKeys = originalMap.keys.toList();
+        for (int i = 0; i < originalKeys.length; i++) {
+          DartObject resynthesizedKey = resynthesizedKeys[i];
+          DartObject originalKey = originalKeys[i];
+          compareConstValues(resynthesizedKey, originalKey, desc);
+          DartObject resynthesizedValue = resynthesizedMap[resynthesizedKey];
+          DartObject originalValue = originalMap[originalKey];
+          compareConstValues(resynthesizedValue, originalValue, desc);
+        }
+      } else if (original.toStringValue() != null) {
+        expect(resynthesized.toStringValue(), original.toStringValue(),
+            reason: desc);
+      } else if (original.toSymbolValue() != null) {
+        expect(resynthesized.toSymbolValue(), original.toSymbolValue(),
+            reason: desc);
+      } else if (original.toTypeValue() != null) {
+        fail('Not implemented');
+      }
+    }
   }
 
   void compareElementAnnotations(ElementAnnotationImpl resynthesized,
@@ -534,12 +621,19 @@
     compareMetadata(resynthesized.metadata, original.metadata, desc);
     // Modifiers are a pain to test via handles.  So just test them via the
     // actual element.
-    for (Modifier modifier in Modifier.values) {
+    for (Modifier modifier in Modifier.persistedValues) {
       bool got = rImpl.hasModifier(modifier);
       bool want = oImpl.hasModifier(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) {
       expect(rImpl, new isInstanceOf<Member>(), reason: desc);
@@ -551,13 +645,8 @@
   void compareExecutableElements(ExecutableElement resynthesized,
       ExecutableElement original, String desc) {
     compareElements(resynthesized, original, desc);
-    expect(resynthesized.parameters.length, original.parameters.length);
-    for (int i = 0; i < resynthesized.parameters.length; i++) {
-      compareParameterElements(
-          resynthesized.parameters[i],
-          original.parameters[i],
-          '$desc parameter ${original.parameters[i].name}');
-    }
+    compareParameterElementLists(
+        resynthesized.parameters, original.parameters, desc);
     compareTypes(
         resynthesized.returnType, original.returnType, '$desc return type');
     compareTypes(resynthesized.type, original.type, desc);
@@ -578,6 +667,15 @@
       }
     }
     if (original is! Member) {
+      List<LabelElement> rLabels = resynthesized.labels;
+      List<LabelElement> oLabels = original.labels;
+      expect(rLabels, hasLength(oLabels.length));
+      for (int i = 0; i < oLabels.length; i++) {
+        compareLabelElements(
+            rLabels[i], oLabels[i], '$desc label ${oLabels[i].name}');
+      }
+    }
+    if (original is! Member) {
       List<LocalVariableElement> rVariables = resynthesized.localVariables;
       List<LocalVariableElement> oVariables = original.localVariables;
       expect(rVariables, hasLength(oVariables.length));
@@ -607,6 +705,10 @@
 
   void compareFunctionElements(
       FunctionElement resynthesized, FunctionElement original, String desc) {
+    if (original == null && resynthesized == null) {
+      return;
+    }
+    expect(resynthesized, isNotNull, reason: desc);
     compareExecutableElements(resynthesized, original, desc);
     checkPossibleLocalElements(resynthesized, original);
   }
@@ -616,13 +718,8 @@
       FunctionTypeAliasElementImpl original,
       String desc) {
     compareElements(resynthesized, original, desc);
-    expect(resynthesized.parameters.length, original.parameters.length);
-    for (int i = 0; i < resynthesized.parameters.length; i++) {
-      compareParameterElements(
-          resynthesized.parameters[i],
-          original.parameters[i],
-          '$desc parameter ${original.parameters[i].name}');
-    }
+    compareParameterElementLists(
+        resynthesized.parameters, original.parameters, desc);
     compareTypes(
         resynthesized.returnType, original.returnType, '$desc return type');
     compareTypes(resynthesized.type, original.type, desc);
@@ -654,6 +751,15 @@
     }
   }
 
+  void compareLabelElements(
+      LabelElementImpl resynthesized, LabelElementImpl original, String desc) {
+    expect(resynthesized.isOnSwitchMember, original.isOnSwitchMember,
+        reason: desc);
+    expect(resynthesized.isOnSwitchStatement, original.isOnSwitchStatement,
+        reason: desc);
+    compareElements(resynthesized, original, desc);
+  }
+
   void compareMetadata(List<ElementAnnotation> resynthesized,
       List<ElementAnnotation> original, String desc) {
     expect(resynthesized, hasLength(original.length), reason: desc);
@@ -675,6 +781,8 @@
     if (original is ShowElementCombinatorImpl &&
         resynthesized is ShowElementCombinatorImpl) {
       expect(resynthesized.shownNames, original.shownNames);
+      expect(resynthesized.offset, original.offset);
+      expect(resynthesized.end, original.end);
     } else if (original is HideElementCombinatorImpl &&
         resynthesized is HideElementCombinatorImpl) {
       expect(resynthesized.hiddenNames, original.hiddenNames);
@@ -699,16 +807,24 @@
     }
   }
 
+  void compareParameterElementLists(
+      List<ParameterElement> resynthesizedParameters,
+      List<ParameterElement> originalParameters,
+      String desc) {
+    expect(resynthesizedParameters.length, originalParameters.length);
+    for (int i = 0; i < resynthesizedParameters.length; i++) {
+      compareParameterElements(
+          resynthesizedParameters[i],
+          originalParameters[i],
+          '$desc parameter ${originalParameters[i].name}');
+    }
+  }
+
   void compareParameterElements(
       ParameterElement resynthesized, ParameterElement original, String desc) {
     compareVariableElements(resynthesized, original, desc);
-    expect(resynthesized.parameters.length, original.parameters.length);
-    for (int i = 0; i < resynthesized.parameters.length; i++) {
-      compareParameterElements(
-          resynthesized.parameters[i],
-          original.parameters[i],
-          '$desc parameter ${original.parameters[i].name}');
-    }
+    compareParameterElementLists(
+        resynthesized.parameters, original.parameters, desc);
     expect(resynthesized.parameterKind, original.parameterKind);
     expect(resynthesized.isInitializingFormal, original.isInitializingFormal,
         reason: desc);
@@ -724,6 +840,13 @@
             resynthesized.field, original.field, '$desc field');
       }
     }
+    expect(resynthesized.defaultValueCode, original.defaultValueCode,
+        reason: desc);
+    ParameterElementImpl resynthesizedActual =
+        getActualElement(resynthesized, desc);
+    ParameterElementImpl originalActual = getActualElement(original, desc);
+    compareFunctionElements(
+        resynthesizedActual.initializer, originalActual.initializer, desc);
   }
 
   void comparePrefixElements(PrefixElementImpl resynthesized,
@@ -845,6 +968,8 @@
       // TODO(scheglov) In the strong mode constant variable like
       //  `var V = new Unresolved()` gets `UndefinedTypeImpl`, and it gets
       // `DynamicTypeImpl` in the spec mode.
+    } else if (resynthesized is BottomTypeImpl && original is BottomTypeImpl) {
+      expect(resynthesized, same(original));
     } else if (resynthesized.runtimeType != original.runtimeType) {
       fail('Type mismatch: expected ${original.runtimeType},'
           ' got ${resynthesized.runtimeType} ($desc)');
@@ -865,16 +990,24 @@
       VariableElement resynthesized, VariableElement original, String desc) {
     compareElements(resynthesized, original, desc);
     compareTypes(resynthesized.type, original.type, desc);
+    VariableElementImpl resynthesizedActual =
+        getActualElement(resynthesized, desc);
     VariableElementImpl originalActual = getActualElement(original, desc);
+    compareFunctionElements(
+        resynthesizedActual.initializer, originalActual.initializer, desc);
     if (originalActual is ConstVariableElement) {
-      VariableElementImpl resynthesizedActual =
-          getActualElement(resynthesized, desc);
-      Expression initializer = resynthesizedActual.constantInitializer;
-      if (constantInitializersAreInvalid) {
-        _assertUnresolvedIdentifier(initializer, desc);
+      Element oEnclosing = original.enclosingElement;
+      if (oEnclosing is ClassElement && oEnclosing.isEnum) {
+        compareConstValues(
+            resynthesized.constantValue, original.constantValue, desc);
       } else {
-        compareConstAsts(initializer, originalActual.constantInitializer,
-            '$desc initializer');
+        Expression initializer = resynthesizedActual.constantInitializer;
+        if (constantInitializersAreInvalid) {
+          _assertUnresolvedIdentifier(initializer, desc);
+        } else {
+          compareConstAsts(initializer, originalActual.constantInitializer,
+              '$desc initializer');
+        }
       }
     }
     checkPossibleMember(resynthesized, original, desc);
@@ -1315,6 +1448,15 @@
     checkLibrary('class C {} class D {}');
   }
 
+  test_closure_executable_with_return_type_from_closure() {
+    checkLibrary('''
+f() {
+  print(() {});
+  print(() => () => 0);
+}
+''');
+  }
+
   test_const_invalid_field_const() {
     constantInitializersAreInvalid = true;
     checkLibrary(
@@ -2391,6 +2533,13 @@
     checkLibrary('enum E1 { v1 } enum E2 { v2 }');
   }
 
+  test_executable_parameter_type_typedef() {
+    checkLibrary(r'''
+typedef F(int p);
+main(F f) {}
+''');
+  }
+
   test_export_class() {
     addLibrarySource('/a.dart', 'class C {}');
     checkLibrary('export "a.dart";');
@@ -2764,6 +2913,100 @@
     checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
   }
 
+  test_inferred_function_type_for_variable_in_generic_function() {
+    // In the code below, `x` has an inferred type of `() => int`, with 2
+    // (unused) type parameters from the enclosing top level function.
+    checkLibrary('''
+f<U, V>() {
+  var x = () => 0;
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_class_constructor() {
+    // In the code below, `() => () => 0` has an inferred return type of
+    // `() => int`, with 2 (unused) type parameters from the enclosing class.
+    checkLibrary('''
+class C<U, V> {
+  final x;
+  C() : x = (() => () => 0);
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_class_getter() {
+    // In the code below, `() => () => 0` has an inferred return type of
+    // `() => int`, with 2 (unused) type parameters from the enclosing class.
+    checkLibrary('''
+class C<U, V> {
+  get x => () => () => 0;
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_class_in_generic_method() {
+    // In the code below, `() => () => 0` has an inferred return type of
+    // `() => int`, with 3 (unused) type parameters from the enclosing class
+    // and method.
+    checkLibrary('''
+class C<T> {
+  f<U, V>() {
+    print(() => () => 0);
+  }
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_class_setter() {
+    // In the code below, `() => () => 0` has an inferred return type of
+    // `() => int`, with 2 (unused) type parameters from the enclosing class.
+    checkLibrary('''
+class C<U, V> {
+  void set x(value) {
+    print(() => () => 0);
+  }
+}
+''');
+  }
+
+  test_inferred_function_type_in_generic_closure() {
+    if (!options.strongMode) {
+      // The test below uses generic comment syntax because proper generic
+      // method syntax doesn't support generic closures.  So it can only run in
+      // strong mode.
+      // TODO(paulberry): once proper generic method syntax supports generic
+      // closures, rewrite the test below without using generic comment syntax,
+      // and remove this hack.  See dartbug.com/25819
+      return;
+    }
+    // In the code below, `<U, V>() => () => 0` has an inferred return type of
+    // `() => int`, with 3 (unused) type parameters.
+    checkLibrary('''
+f<T>() {
+  print(/*<U, V>*/() => () => 0);
+}
+''');
+  }
+
+  test_inferred_generic_function_type_in_generic_closure() {
+    if (!options.strongMode) {
+      // The test below uses generic comment syntax because proper generic
+      // method syntax doesn't support generic closures.  So it can only run in
+      // strong mode.
+      // TODO(paulberry): once proper generic method syntax supports generic
+      // closures, rewrite the test below without using generic comment syntax,
+      // and remove this hack.  See dartbug.com/25819
+      return;
+    }
+    // In the code below, `<U, V>() => <W, X, Y, Z>() => 0` has an inferred
+    // return type of `() => int`, with 7 (unused) type parameters.
+    checkLibrary('''
+f<T>() {
+  print(/*<U, V>*/() => /*<W, X, Y, Z>*/() => 0);
+}
+''');
+  }
+
   test_inferred_type_is_typedef() {
     checkLibrary('typedef int F(String s);'
         ' class C extends D { var v; }'
@@ -2798,6 +3041,27 @@
         ' abstract class D { void set f(int g(String s)); }');
   }
 
+  test_initializer_executable_with_return_type_from_closure() {
+    checkLibrary('var v = () => 0;');
+  }
+
+  test_initializer_executable_with_return_type_from_closure_field() {
+    checkLibrary('''
+class C {
+  var v = () => 0;
+}
+''');
+  }
+
+  test_initializer_executable_with_return_type_from_closure_local() {
+    checkLibrary('''
+void f() {
+  int u = 0;
+  var v = () => 0;
+}
+''');
+  }
+
   test_library() {
     checkLibrary('');
   }
@@ -2858,6 +3122,46 @@
 ''');
   }
 
+  test_localLabels_inConstructor() {
+    checkLibrary(r'''
+class C {
+  C() {
+    aaa: while (true) {}
+    bbb: switch (42) {
+      ccc: case 0:
+        break;
+    }
+  }
+}
+''');
+  }
+
+  test_localLabels_inMethod() {
+    checkLibrary(r'''
+class C {
+  m() {
+    aaa: while (true) {}
+    bbb: switch (42) {
+      ccc: case 0:
+        break;
+    }
+  }
+}
+''');
+  }
+
+  test_localLabels_inTopLevelFunction() {
+    checkLibrary(r'''
+main() {
+  aaa: while (true) {}
+  bbb: switch (42) {
+    ccc: case 0:
+      break;
+  }
+}
+''');
+  }
+
   test_localVariables_inConstructor() {
     checkLibrary(r'''
 class C {
@@ -3289,6 +3593,15 @@
     checkLibrary('library my.lib; part "a.dart"; part "b.dart";');
   }
 
+  test_propagated_type_refers_to_closure() {
+    checkLibrary('''
+void f() {
+  var x = () => 0;
+  var y = x;
+}
+''');
+  }
+
   test_setter_documented() {
     checkLibrary('''
 // Extra comment so doc comment offset != 0
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 5e2f084..6356d47 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -314,9 +314,9 @@
   }
 
   /**
-   * Test an inferred type.  If strong mode is disabled, verify that the given
-   * [slotId] exists and has no associated type.  Otherwise, behave as in
-   * [checkLinkedTypeSlot].
+   * Test an inferred type.  If [onlyInStrongMode] is `true` (the default) and
+   * strong mode is disabled, verify that the given [slotId] exists and has no
+   * associated type.  Otherwise, behave as in [checkLinkedTypeSlot].
    */
   void checkInferredTypeSlot(
       int slotId, String absoluteUri, String relativeUri, String expectedName,
@@ -325,8 +325,9 @@
       int expectedTargetUnit: 0,
       LinkedUnit linkedSourceUnit,
       UnlinkedUnit unlinkedSourceUnit,
-      int numTypeParameters: 0}) {
-    if (strongMode) {
+      int numTypeParameters: 0,
+      bool onlyInStrongMode: true}) {
+    if (strongMode || !onlyInStrongMode) {
       checkLinkedTypeSlot(slotId, absoluteUri, relativeUri, expectedName,
           allowTypeArguments: allowTypeParameters,
           expectedKind: expectedKind,
@@ -479,7 +480,8 @@
       LinkedUnit linkedSourceUnit,
       UnlinkedUnit unlinkedSourceUnit,
       int numTypeParameters: 0,
-      bool checkAstDerivedDataOverride: false}) {
+      bool checkAstDerivedDataOverride: false,
+      int localIndex: 0}) {
     linkedSourceUnit ??= definingUnit;
     unlinkedSourceUnit ??= unlinkedUnits[0];
     LinkedReference referenceResolution =
@@ -525,6 +527,7 @@
     expect(referenceResolution.kind, expectedKind);
     expect(referenceResolution.unit, expectedTargetUnit);
     expect(referenceResolution.numTypeParameters, numTypeParameters);
+    expect(referenceResolution.localIndex, localIndex);
     return reference;
   }
 
@@ -584,15 +587,8 @@
     } else if (prefixExpectations != null) {
       for (_PrefixExpectation expectation in prefixExpectations) {
         expect(reference.prefixReference, isNot(0));
-        reference = checkReferenceIndex(
-            reference.prefixReference,
-            expectation.inLibraryDefiningUnit
-                ? null
-                : expectation.absoluteUri ?? absoluteUri,
-            expectation.inLibraryDefiningUnit
-                ? null
-                : expectation.relativeUri ?? relativeUri,
-            expectation.name,
+        reference = checkReferenceIndex(reference.prefixReference,
+            expectation.absoluteUri, expectation.relativeUri, expectation.name,
             expectedKind: expectation.kind,
             checkAstDerivedDataOverride: checkAstDerivedDataOverride,
             expectedTargetUnit: expectedTargetUnit,
@@ -782,8 +778,8 @@
    * executable with the given [executableName].
    */
   UnlinkedExecutable serializeExecutableText(String text,
-      [String executableName = 'f']) {
-    serializeLibraryText(text);
+      {String executableName: 'f', bool allowErrors: false}) {
+    serializeLibraryText(text, allowErrors: allowErrors);
     return findExecutable(executableName, failIfAbsent: true);
   }
 
@@ -838,6 +834,20 @@
     return findVariable(variableName, failIfAbsent: true);
   }
 
+  test_bottom_reference_shared() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    // The synthetic executables for both `x` and `y` have type `() => `Bottom`.
+    // Verify that they both use the same reference to `Bottom`.
+    serializeLibraryText('int x = null; int y = null;');
+    EntityRef xInitializerReturnType =
+        getTypeRefForSlot(findVariable('x').initializer.inferredReturnTypeSlot);
+    EntityRef yInitializerReturnType =
+        getTypeRefForSlot(findVariable('y').initializer.inferredReturnTypeSlot);
+    expect(xInitializerReturnType.reference, yInitializerReturnType.reference);
+  }
+
   test_cascaded_export_hide_hide() {
     addNamedSource('/lib1.dart', 'export "lib2.dart" hide C hide B, C;');
     addNamedSource('/lib2.dart', 'class A {} class B {} class C {}');
@@ -1317,6 +1327,86 @@
     expect(unlinkedUnits[0].publicNamespace.names[0].numTypeParameters, 1);
   }
 
+  test_closure_executable_with_bottom_return_type() {
+    UnlinkedExecutable executable =
+        serializeExecutableText('f() { print((() => null)()); }');
+    expect(executable.localFunctions, hasLength(1));
+    expect(executable.localFunctions[0].returnType, isNull);
+    if (strongMode) {
+      // Strong mode infers a type for the closure of `() => dynamic`, so the
+      // inferred return type slot should be empty.
+      expect(
+          getTypeRefForSlot(
+              executable.localFunctions[0].inferredReturnTypeSlot),
+          isNull);
+    } else {
+      // Spec mode infers a type for the closure of `() => Bottom`.
+      checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot,
+          null, null, '*bottom*',
+          onlyInStrongMode: false);
+    }
+  }
+
+  test_closure_executable_with_imported_return_type() {
+    addNamedSource('/a.dart', 'class C { D d; } class D {}');
+    // The closure has type `() => D`; `D` is defined in a library that is
+    // imported.
+    UnlinkedExecutable executable = serializeExecutableText(
+        'import "a.dart"; f() { print((() => new C().d)()); }');
+    expect(executable.localFunctions, hasLength(1));
+    expect(executable.localFunctions[0].returnType, isNull);
+    checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot,
+        absUri('/a.dart'), 'a.dart', 'D',
+        onlyInStrongMode: false);
+    checkHasDependency(absUri('/a.dart'), 'a.dart', fullyLinked: false);
+  }
+
+  test_closure_executable_with_return_type_from_closure() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    // The closure has type `() => () => int`, where the `() => int` part refers
+    // to the nested closure.
+    UnlinkedExecutable executable = serializeExecutableText('''
+f() {
+  print(() {}); // force the closure below to have index 1
+  print(() => () => 0);
+}
+''');
+    expect(executable.localFunctions, hasLength(2));
+    EntityRef closureType =
+        getTypeRefForSlot(executable.localFunctions[1].inferredReturnTypeSlot);
+    checkLinkedTypeRef(closureType, null, null, '',
+        expectedKind: ReferenceKind.function);
+    int outerClosureIndex =
+        definingUnit.references[closureType.reference].containingReference;
+    checkReferenceIndex(outerClosureIndex, null, null, '',
+        expectedKind: ReferenceKind.function, localIndex: 1);
+    int topLevelFunctionIndex =
+        definingUnit.references[outerClosureIndex].containingReference;
+    checkReferenceIndex(topLevelFunctionIndex, null, null, 'f',
+        expectedKind: ReferenceKind.topLevelFunction);
+    expect(
+        definingUnit.references[topLevelFunctionIndex].containingReference, 0);
+  }
+
+  test_closure_executable_with_unimported_return_type() {
+    addNamedSource('/a.dart', 'import "b.dart"; class C { D d; }');
+    addNamedSource('/b.dart', 'class D {}');
+    // The closure has type `() => D`; `D` is defined in a library that is not
+    // imported.
+    UnlinkedExecutable executable = serializeExecutableText(
+        'import "a.dart"; f() { print((() => new C().d)()); }');
+    expect(executable.localFunctions, hasLength(1));
+    expect(executable.localFunctions[0].returnType, isNull);
+    checkInferredTypeSlot(executable.localFunctions[0].inferredReturnTypeSlot,
+        absUri('/b.dart'), 'b.dart', 'D',
+        onlyInStrongMode: false);
+    if (!skipFullyLinkedData) {
+      checkHasDependency(absUri('/b.dart'), 'b.dart', fullyLinked: true);
+    }
+  }
+
   test_constExpr_binary_add() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 + 2;');
     _assertUnlinkedConst(variable.constExpr, operators: [
@@ -1706,8 +1796,7 @@
                   absoluteUri: absUri('/a.dart'),
                   relativeUri: 'a.dart',
                   numTypeParameters: 2),
-              new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                  inLibraryDefiningUnit: true)
+              new _PrefixExpectation(ReferenceKind.prefix, 'p')
             ],
             allowTypeParameters: true);
         checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
@@ -1793,8 +1882,7 @@
             numTypeParameters: 2,
             allowTypeParameters: true,
             prefixExpectations: [
-              new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                  inLibraryDefiningUnit: true)
+              new _PrefixExpectation(ReferenceKind.prefix, 'p')
             ]);
         checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
         checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
@@ -1873,8 +1961,7 @@
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
                     absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true)
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
               ])
     ]);
   }
@@ -1964,8 +2051,7 @@
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
               expectedKind: ReferenceKind.classOrEnum,
               prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true)
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
               ])
     ]);
   }
@@ -2038,8 +2124,7 @@
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
                     absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true)
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
               ])
     ]);
   }
@@ -2063,8 +2148,7 @@
               checkAstDerivedDataOverride: true,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.unresolved, 'C'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true)
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
               ])
     ]);
   }
@@ -2125,8 +2209,7 @@
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
                     absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true)
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
               ])
     ]);
   }
@@ -2209,8 +2292,7 @@
                 new _PrefixExpectation(
                     ReferenceKind.topLevelPropertyAccessor, 'a',
                     absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true)
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
               ])
     ]);
   }
@@ -2579,8 +2661,7 @@
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
                     absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p'),
               ])
     ]);
   }
@@ -2665,8 +2746,7 @@
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
                     absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true)
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
               ])
     ]);
   }
@@ -2736,8 +2816,7 @@
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'f',
               expectedKind: ReferenceKind.topLevelFunction,
               prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true)
+                new _PrefixExpectation(ReferenceKind.prefix, 'p')
               ])
     ]);
   }
@@ -2852,8 +2931,7 @@
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
                     absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p',
-                    inLibraryDefiningUnit: true),
+                new _PrefixExpectation(ReferenceKind.prefix, 'p'),
               ])
     ]);
   }
@@ -2925,6 +3003,8 @@
     expect(executable.returnType, isNull);
     expect(executable.isExternal, isFalse);
     expect(executable.nameOffset, text.indexOf('C();'));
+    expect(executable.periodOffset, 0);
+    expect(executable.nameEnd, 0);
     expect(executable.isRedirectedConstructor, isFalse);
     expect(executable.redirectedConstructor, isNull);
     expect(executable.redirectedConstructorName, isEmpty);
@@ -3208,6 +3288,7 @@
     UnlinkedParam param = executable.parameters[0];
     expect(param.isFunctionTyped, isTrue);
     expect(param.kind, UnlinkedParamKind.positional);
+    expect(param.defaultValueCode, 'foo');
     _assertUnlinkedConst(param.defaultValue, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
@@ -3241,6 +3322,7 @@
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.kind, UnlinkedParamKind.named);
     expect(parameter.defaultValue, isNull);
+    expect(parameter.defaultValueCode, isEmpty);
   }
 
   test_constructor_initializing_formal_named_withDefault() {
@@ -3249,6 +3331,8 @@
             .executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.kind, UnlinkedParamKind.named);
+    expect(parameter.initializer, isNotNull);
+    expect(parameter.defaultValueCode, '42');
     _assertUnlinkedConst(parameter.defaultValue,
         operators: [UnlinkedConstOperation.pushInt], ints: [42]);
   }
@@ -3268,6 +3352,7 @@
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.kind, UnlinkedParamKind.positional);
     expect(parameter.defaultValue, isNull);
+    expect(parameter.defaultValueCode, isEmpty);
   }
 
   test_constructor_initializing_formal_positional_withDefault() {
@@ -3277,6 +3362,8 @@
                 .executables);
     UnlinkedParam parameter = executable.parameters[0];
     expect(parameter.kind, UnlinkedParamKind.positional);
+    expect(parameter.initializer, isNotNull);
+    expect(parameter.defaultValueCode, '42');
     _assertUnlinkedConst(parameter.defaultValue,
         operators: [UnlinkedConstOperation.pushInt], ints: [42]);
   }
@@ -3308,6 +3395,7 @@
 }''').executables);
     UnlinkedParam param = executable.parameters[0];
     expect(param.kind, UnlinkedParamKind.positional);
+    expect(param.defaultValueCode, '42');
     _assertUnlinkedConst(param.defaultValue,
         operators: [UnlinkedConstOperation.pushInt], ints: [42]);
   }
@@ -3318,6 +3406,8 @@
         executables: serializeClassText(text).executables);
     expect(executable.name, 'foo');
     expect(executable.nameOffset, text.indexOf('foo'));
+    expect(executable.periodOffset, text.indexOf('.foo'));
+    expect(executable.nameEnd, text.indexOf('()'));
   }
 
   test_constructor_non_const() {
@@ -3961,7 +4051,7 @@
   }
 
   test_executable_function_private() {
-    serializeExecutableText('_f() {}', '_f');
+    serializeExecutableText('_f() {}', executableName: '_f');
     expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
   }
 
@@ -3987,7 +4077,7 @@
   }
 
   test_executable_getter_private() {
-    serializeExecutableText('int get _f => 1;', '_f');
+    serializeExecutableText('int get _f => 1;', executableName: '_f');
     expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
   }
 
@@ -4025,6 +4115,91 @@
     }
   }
 
+  test_executable_localLabels_inMethod() {
+    String code = r'''
+class C {
+  m() {
+    aaa: while (true) {}
+    bbb: while (true) {}
+  }
+}
+''';
+    UnlinkedExecutable executable =
+        findExecutable('m', executables: serializeClassText(code).executables);
+    List<UnlinkedLabel> labels = executable.localLabels;
+    expect(labels, hasLength(2));
+    {
+      UnlinkedLabel aaa = labels.singleWhere((l) => l.name == 'aaa');
+      expect(aaa, isNotNull);
+      expect(aaa.isOnSwitchMember, isFalse);
+      expect(aaa.isOnSwitchStatement, isFalse);
+    }
+    {
+      UnlinkedLabel bbb = labels.singleWhere((l) => l.name == 'bbb');
+      expect(bbb, isNotNull);
+      expect(bbb.isOnSwitchMember, isFalse);
+      expect(bbb.isOnSwitchStatement, isFalse);
+    }
+  }
+
+  test_executable_localLabels_inTopLevelFunction() {
+    String code = r'''
+f() {
+  aaa: while (true) {}
+  bbb: switch (42) {
+    ccc: case 0:
+      break;
+  }
+}
+''';
+    UnlinkedExecutable executable = serializeExecutableText(code);
+    List<UnlinkedLabel> labels = executable.localLabels;
+    expect(labels, hasLength(3));
+    {
+      UnlinkedLabel aaa = labels.singleWhere((l) => l.name == 'aaa');
+      expect(aaa, isNotNull);
+      expect(aaa.isOnSwitchMember, isFalse);
+      expect(aaa.isOnSwitchStatement, isFalse);
+    }
+    {
+      UnlinkedLabel bbb = labels.singleWhere((l) => l.name == 'bbb');
+      expect(bbb, isNotNull);
+      expect(bbb.isOnSwitchMember, isFalse);
+      expect(bbb.isOnSwitchStatement, isTrue);
+    }
+    {
+      UnlinkedLabel ccc = labels.singleWhere((l) => l.name == 'ccc');
+      expect(ccc, isNotNull);
+      expect(ccc.isOnSwitchMember, isTrue);
+      expect(ccc.isOnSwitchStatement, isFalse);
+    }
+  }
+
+  test_executable_localLabels_inTopLevelGetter() {
+    String code = r'''
+get g {
+  aaa: while (true) {}
+  bbb: while (true) {}
+}
+''';
+    UnlinkedExecutable executable =
+        serializeExecutableText(code, executableName: 'g');
+    List<UnlinkedLabel> labels = executable.localLabels;
+    expect(labels, hasLength(2));
+    {
+      UnlinkedLabel aaa = labels.singleWhere((l) => l.name == 'aaa');
+      expect(aaa, isNotNull);
+      expect(aaa.isOnSwitchMember, isFalse);
+      expect(aaa.isOnSwitchStatement, isFalse);
+    }
+    {
+      UnlinkedLabel bbb = labels.singleWhere((l) => l.name == 'bbb');
+      expect(bbb, isNotNull);
+      expect(bbb.isOnSwitchMember, isFalse);
+      expect(bbb.isOnSwitchStatement, isFalse);
+    }
+  }
+
   test_executable_localVariables_empty() {
     UnlinkedExecutable executable = serializeExecutableText(r'''
 f() {
@@ -4167,7 +4342,8 @@
   f() {}
 } // 2
 ''';
-    UnlinkedExecutable executable = serializeExecutableText(code, 'g');
+    UnlinkedExecutable executable =
+        serializeExecutableText(code, executableName: 'g');
     {
       List<UnlinkedExecutable> functions = executable.localFunctions;
       expect(functions, hasLength(1));
@@ -4397,7 +4573,7 @@
   test_executable_param_function_typed_return_type_implicit() {
     if (!checkAstDerivedData) {
       // TODO(paulberry): this test fails when building the summary from the
-      // element model because the elment model doesn't record whether a
+      // element model because the element model doesn't record whether a
       // function-typed parameter's return type is implicit.
       return;
     }
@@ -4418,6 +4594,8 @@
 ''');
     UnlinkedParam param = executable.parameters[0];
     expect(param.kind, UnlinkedParamKind.positional);
+    expect(param.initializer, isNotNull);
+    expect(param.defaultValueCode, 'foo');
     _assertUnlinkedConst(param.defaultValue, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
@@ -4430,13 +4608,17 @@
     UnlinkedExecutable executable = serializeExecutableText('f({x}) {}');
     UnlinkedParam param = executable.parameters[0];
     expect(param.kind, UnlinkedParamKind.named);
+    expect(param.initializer, isNull);
     expect(param.defaultValue, isNull);
+    expect(param.defaultValueCode, isEmpty);
   }
 
   test_executable_param_kind_named_withDefault() {
     UnlinkedExecutable executable = serializeExecutableText('f({x: 42}) {}');
     UnlinkedParam param = executable.parameters[0];
     expect(param.kind, UnlinkedParamKind.named);
+    expect(param.initializer, isNotNull);
+    expect(param.defaultValueCode, '42');
     _assertUnlinkedConst(param.defaultValue,
         operators: [UnlinkedConstOperation.pushInt], ints: [42]);
   }
@@ -4445,13 +4627,17 @@
     UnlinkedExecutable executable = serializeExecutableText('f([x]) {}');
     UnlinkedParam param = executable.parameters[0];
     expect(param.kind, UnlinkedParamKind.positional);
+    expect(param.initializer, isNull);
     expect(param.defaultValue, isNull);
+    expect(param.defaultValueCode, isEmpty);
   }
 
   test_executable_param_kind_positional_withDefault() {
     UnlinkedExecutable executable = serializeExecutableText('f([x = 42]) {}');
     UnlinkedParam param = executable.parameters[0];
     expect(param.kind, UnlinkedParamKind.positional);
+    expect(param.initializer, isNotNull);
+    expect(param.defaultValueCode, '42');
     _assertUnlinkedConst(param.defaultValue,
         operators: [UnlinkedConstOperation.pushInt], ints: [42]);
   }
@@ -4460,7 +4646,9 @@
     UnlinkedExecutable executable = serializeExecutableText('f(x) {}');
     UnlinkedParam param = executable.parameters[0];
     expect(param.kind, UnlinkedParamKind.required);
+    expect(param.initializer, isNull);
     expect(param.defaultValue, isNull);
+    expect(param.defaultValueCode, isEmpty);
   }
 
   test_executable_param_name() {
@@ -4504,6 +4692,16 @@
     expect(executable.parameters[0].type, isNull);
   }
 
+  test_executable_param_type_typedef() {
+    UnlinkedExecutable executable = serializeExecutableText(r'''
+typedef MyFunction(int p);
+f(MyFunction myFunction) {}
+''');
+    expect(executable.parameters[0].isFunctionTyped, isFalse);
+    checkTypeRef(executable.parameters[0].type, null, null, 'MyFunction',
+        expectedKind: ReferenceKind.typedef);
+  }
+
   test_executable_return_type() {
     UnlinkedExecutable executable = serializeExecutableText('int f() => 1;');
     checkTypeRef(executable.returnType, 'dart:core', 'dart:core', 'int');
@@ -4521,7 +4719,8 @@
 
   test_executable_setter() {
     String text = 'void set f(value) {}';
-    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
+    UnlinkedExecutable executable =
+        serializeExecutableText(text, executableName: 'f=');
     expect(executable.kind, UnlinkedExecutableKind.setter);
     expect(executable.returnType, isNotNull);
     expect(executable.isExternal, isFalse);
@@ -4535,25 +4734,27 @@
   }
 
   test_executable_setter_external() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('external void set f(value);', 'f=');
+    UnlinkedExecutable executable = serializeExecutableText(
+        'external void set f(value);',
+        executableName: 'f=');
     expect(executable.isExternal, isTrue);
   }
 
   test_executable_setter_implicit_return() {
     UnlinkedExecutable executable =
-        serializeExecutableText('set f(value) {}', 'f=');
+        serializeExecutableText('set f(value) {}', executableName: 'f=');
     expect(executable.returnType, isNull);
   }
 
   test_executable_setter_private() {
-    serializeExecutableText('void set _f(value) {}', '_f=');
+    serializeExecutableText('void set _f(value) {}', executableName: '_f=');
     expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
   }
 
   test_executable_setter_type() {
-    UnlinkedExecutable executable =
-        serializeExecutableText('void set f(int value) {}', 'f=');
+    UnlinkedExecutable executable = serializeExecutableText(
+        'void set f(int value) {}',
+        executableName: 'f=');
     checkVoidTypeRef(executable.returnType);
     expect(executable.parameters, hasLength(1));
     expect(executable.parameters[0].name, 'value');
@@ -4688,6 +4889,9 @@
         'Future');
     expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].hides[1],
         'Stream');
+    expect(
+        unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset, 0);
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end, 0);
     expect(linked.exportNames, isNotEmpty);
   }
 
@@ -4780,7 +4984,8 @@
   }
 
   test_export_show_order() {
-    serializeLibraryText('export "dart:async" show Future, Stream;');
+    String libraryText = 'export "dart:async" show Future, Stream;';
+    serializeLibraryText(libraryText);
     expect(unlinkedUnits[0].publicNamespace.exports, hasLength(1));
     expect(
         unlinkedUnits[0].publicNamespace.exports[0].combinators, hasLength(1));
@@ -4792,6 +4997,10 @@
         'Future');
     expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].shows[1],
         'Stream');
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].offset,
+        libraryText.indexOf('show'));
+    expect(unlinkedUnits[0].publicNamespace.exports[0].combinators[0].end,
+        libraryText.indexOf(';'));
   }
 
   test_export_typedef() {
@@ -5126,6 +5335,8 @@
     expect(unlinkedUnits[0].imports[0].combinators[0].hides, hasLength(2));
     expect(unlinkedUnits[0].imports[0].combinators[0].hides[0], 'Future');
     expect(unlinkedUnits[0].imports[0].combinators[0].hides[1], 'Stream');
+    expect(unlinkedUnits[0].imports[0].combinators[0].offset, 0);
+    expect(unlinkedUnits[0].imports[0].combinators[0].end, 0);
   }
 
   test_import_implicit() {
@@ -5318,6 +5529,10 @@
     expect(unlinkedUnits[0].imports[0].combinators[0].hides, isEmpty);
     expect(unlinkedUnits[0].imports[0].combinators[0].shows[0], 'Future');
     expect(unlinkedUnits[0].imports[0].combinators[0].shows[1], 'Stream');
+    expect(unlinkedUnits[0].imports[0].combinators[0].offset,
+        libraryText.indexOf('show'));
+    expect(unlinkedUnits[0].imports[0].combinators[0].end,
+        libraryText.indexOf('; Future'));
   }
 
   test_import_uri() {
@@ -5369,7 +5584,7 @@
     expect(linkedReference.dependency, 0);
     expect(linkedReference.kind, ReferenceKind.method);
     expect(linkedReference.name, 'f');
-    expect(linkedReference.numTypeParameters, 2);
+    expect(linkedReference.numTypeParameters, 0);
     expect(linkedReference.unit, 0);
     expect(linkedReference.containingReference, isNot(0));
     expect(linkedReference.containingReference, lessThan(type.reference));
@@ -5466,6 +5681,142 @@
     checkReferenceIndex(linkedReference.containingReference, null, null, 'D');
   }
 
+  test_initializer_executable_with_bottom_return_type() {
+    // The synthetic executable for `v` has type `() => Bottom`.
+    UnlinkedVariable variable = serializeVariableText('int v = null;');
+    expect(variable.initializer.returnType, isNull);
+    checkInferredTypeSlot(
+        variable.initializer.inferredReturnTypeSlot, null, null, '*bottom*',
+        onlyInStrongMode: false);
+  }
+
+  test_initializer_executable_with_imported_return_type() {
+    addNamedSource('/a.dart', 'class C { D d; } class D {}');
+    // The synthetic executable for `v` has type `() => D`; `D` is defined in
+    // a library that is imported.  Note: `v` is mis-typed as `int` to prevent
+    // type propagation, which would complicate the test.
+    UnlinkedVariable variable = serializeVariableText(
+        'import "a.dart"; int v = new C().d;',
+        allowErrors: true);
+    expect(variable.initializer.returnType, isNull);
+    checkInferredTypeSlot(variable.initializer.inferredReturnTypeSlot,
+        absUri('/a.dart'), 'a.dart', 'D',
+        onlyInStrongMode: false);
+    checkHasDependency(absUri('/a.dart'), 'a.dart', fullyLinked: false);
+  }
+
+  test_initializer_executable_with_return_type_from_closure() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    // The synthetic executable for `v` has type `() => () => int`, where the
+    // `() => int` part refers to the closure declared inside the initializer
+    // for v.  Note: `v` is mis-typed as `int` to prevent type propagation,
+    // which would complicate the test.
+    UnlinkedVariable variable =
+        serializeVariableText('int v = () => 0;', allowErrors: true);
+    EntityRef closureType =
+        getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
+    checkLinkedTypeRef(closureType, null, null, '',
+        expectedKind: ReferenceKind.function);
+    int initializerIndex =
+        definingUnit.references[closureType.reference].containingReference;
+    checkReferenceIndex(initializerIndex, null, null, '',
+        expectedKind: ReferenceKind.function);
+    int variableIndex =
+        definingUnit.references[initializerIndex].containingReference;
+    checkReferenceIndex(variableIndex, null, null, 'v',
+        expectedKind: ReferenceKind.topLevelPropertyAccessor);
+    expect(definingUnit.references[variableIndex].containingReference, 0);
+  }
+
+  test_initializer_executable_with_return_type_from_closure_field() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    // The synthetic executable for `v` has type `() => () => int`, where the
+    // `() => int` part refers to the closure declared inside the initializer
+    // for v.  Note: `v` is mis-typed as `int` to prevent type propagation,
+    // which would complicate the test.
+    UnlinkedClass cls = serializeClassText(
+        '''
+class C {
+  int v = () => 0;
+}
+''',
+        allowErrors: true);
+    UnlinkedVariable variable = cls.fields[0];
+    EntityRef closureType =
+        getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
+    checkLinkedTypeRef(closureType, null, null, '',
+        expectedKind: ReferenceKind.function);
+    int initializerIndex =
+        definingUnit.references[closureType.reference].containingReference;
+    checkReferenceIndex(initializerIndex, null, null, '',
+        expectedKind: ReferenceKind.function);
+    int variableIndex =
+        definingUnit.references[initializerIndex].containingReference;
+    checkReferenceIndex(variableIndex, null, null, 'v',
+        expectedKind: ReferenceKind.propertyAccessor);
+    int classIndex = definingUnit.references[variableIndex].containingReference;
+    checkReferenceIndex(classIndex, null, null, 'C');
+    expect(definingUnit.references[classIndex].containingReference, 0);
+  }
+
+  test_initializer_executable_with_return_type_from_closure_local() {
+    if (skipFullyLinkedData) {
+      return;
+    }
+    // The synthetic executable for `v` has type `() => () => int`, where the
+    // `() => int` part refers to the closure declared inside the initializer
+    // for v.  Note: `v` is mis-typed as `int` to prevent type propagation,
+    // which would complicate the test.
+    UnlinkedExecutable executable = serializeExecutableText(
+        '''
+void f() {
+  int u = 0; // force the variable below to have index 1
+  int v = () => 0;
+}''',
+        allowErrors: true);
+    UnlinkedVariable variable = executable.localVariables[1];
+    EntityRef closureType =
+        getTypeRefForSlot(variable.initializer.inferredReturnTypeSlot);
+    checkLinkedTypeRef(closureType, null, null, '',
+        expectedKind: ReferenceKind.function);
+    int initializerIndex =
+        definingUnit.references[closureType.reference].containingReference;
+    checkReferenceIndex(initializerIndex, null, null, '',
+        expectedKind: ReferenceKind.function);
+    int variableIndex =
+        definingUnit.references[initializerIndex].containingReference;
+    checkReferenceIndex(variableIndex, null, null, 'v',
+        expectedKind: ReferenceKind.variable, localIndex: 1);
+    int topLevelFunctionIndex =
+        definingUnit.references[variableIndex].containingReference;
+    checkReferenceIndex(topLevelFunctionIndex, null, null, 'f',
+        expectedKind: ReferenceKind.topLevelFunction);
+    expect(
+        definingUnit.references[topLevelFunctionIndex].containingReference, 0);
+  }
+
+  test_initializer_executable_with_unimported_return_type() {
+    addNamedSource('/a.dart', 'import "b.dart"; class C { D d; }');
+    addNamedSource('/b.dart', 'class D {}');
+    // The synthetic executable for `v` has type `() => D`; `D` is defined in
+    // a library that is not imported.  Note: `v` is mis-typed as `int` to
+    // prevent type propagation, which would complicate the test.
+    UnlinkedVariable variable = serializeVariableText(
+        'import "a.dart"; int v = new C().d;',
+        allowErrors: true);
+    expect(variable.initializer.returnType, isNull);
+    checkInferredTypeSlot(variable.initializer.inferredReturnTypeSlot,
+        absUri('/b.dart'), 'b.dart', 'D',
+        onlyInStrongMode: false);
+    if (!skipFullyLinkedData) {
+      checkHasDependency(absUri('/b.dart'), 'b.dart', fullyLinked: true);
+    }
+  }
+
   test_invalid_prefix_dynamic() {
     if (checkAstDerivedData) {
       // TODO(paulberry): get this to work properly.
@@ -5744,9 +6095,10 @@
   }
 
   test_metadata_functionDeclaration_setter() {
-    checkAnnotationA(
-        serializeExecutableText('const a = null; @a set f(value) {}', 'f=')
-            .annotations);
+    checkAnnotationA(serializeExecutableText(
+            'const a = null; @a set f(value) {}',
+            executableName: 'f=')
+        .annotations);
   }
 
   test_metadata_functionTypeAlias() {
@@ -6098,7 +6450,8 @@
  * Docs
  */
 void set f(value) {}''';
-    UnlinkedExecutable executable = serializeExecutableText(text, 'f=');
+    UnlinkedExecutable executable =
+        serializeExecutableText(text, executableName: 'f=');
     expect(executable.documentationComment, isNotNull);
     checkDocumentationComment(executable.documentationComment, text);
   }
@@ -6153,12 +6506,13 @@
 
   test_setter_inferred_type_top_level_implicit_param() {
     UnlinkedExecutable f =
-        serializeExecutableText('void set f(value) {}', 'f=');
+        serializeExecutableText('void set f(value) {}', executableName: 'f=');
     expect(f.parameters[0].inferredTypeSlot, 0);
   }
 
   test_setter_inferred_type_top_level_implicit_return() {
-    UnlinkedExecutable f = serializeExecutableText('set f(int value) {}', 'f=');
+    UnlinkedExecutable f =
+        serializeExecutableText('set f(int value) {}', executableName: 'f=');
     expect(f.inferredReturnTypeSlot, 0);
   }
 
@@ -6630,6 +6984,15 @@
         unlinkedSourceUnit: unlinkedUnits[1]);
   }
 
+  test_unresolved_reference_shared() {
+    // Both `x` and `y` use unresolved identifier `C` as their type.  Verify
+    // that they both use the same unresolved reference.
+    serializeLibraryText('C x; C y;', allowErrors: true);
+    EntityRef xType = findVariable('x').type;
+    EntityRef yType = findVariable('y').type;
+    expect(xType.reference, yType.reference);
+  }
+
   test_variable() {
     String text = 'int i;';
     UnlinkedVariable v = serializeVariableText(text, variableName: 'i');
@@ -6697,6 +7060,61 @@
     expect(v.inferredTypeSlot, 0);
   }
 
+  test_variable_initializer_literal() {
+    UnlinkedVariable variable = serializeVariableText('var v = 42;');
+    UnlinkedExecutable initializer = variable.initializer;
+    expect(initializer, isNotNull);
+    expect(initializer.nameOffset, 8);
+    expect(initializer.name, isEmpty);
+    expect(initializer.localFunctions, isEmpty);
+    expect(initializer.localVariables, isEmpty);
+  }
+
+  test_variable_initializer_noInitializer() {
+    UnlinkedVariable variable = serializeVariableText('var v;');
+    expect(variable.initializer, isNull);
+  }
+
+  test_variable_initializer_withLocals() {
+    String text =
+        'var v = <dynamic, dynamic>{"1": () { f1() {} var v1; }, '
+        '"2": () { f2() {} var v2; }};';
+    UnlinkedVariable variable = serializeVariableText(text);
+    UnlinkedExecutable initializer = variable.initializer;
+    expect(initializer, isNotNull);
+    expect(initializer.nameOffset, text.indexOf('<dynamic, dynamic>{"1'));
+    expect(initializer.name, isEmpty);
+    expect(initializer.localFunctions, hasLength(2));
+    // closure: () { f1() {} var v1; }
+    {
+      UnlinkedExecutable closure = initializer.localFunctions[0];
+      expect(closure.nameOffset, text.indexOf('() { f1()'));
+      expect(closure.name, isEmpty);
+      // closure - f1
+      expect(closure.localFunctions, hasLength(1));
+      expect(closure.localFunctions[0].name, 'f1');
+      expect(closure.localFunctions[0].nameOffset, text.indexOf('f1()'));
+      // closure - v1
+      expect(closure.localVariables, hasLength(1));
+      expect(closure.localVariables[0].name, 'v1');
+      expect(closure.localVariables[0].nameOffset, text.indexOf('v1;'));
+    }
+    // closure: () { f2() {} var v2; }
+    {
+      UnlinkedExecutable closure = initializer.localFunctions[1];
+      expect(closure.nameOffset, text.indexOf('() { f2()'));
+      expect(closure.name, isEmpty);
+      // closure - f1
+      expect(closure.localFunctions, hasLength(1));
+      expect(closure.localFunctions[0].name, 'f2');
+      expect(closure.localFunctions[0].nameOffset, text.indexOf('f2()'));
+      // closure - v1
+      expect(closure.localVariables, hasLength(1));
+      expect(closure.localVariables[0].name, 'v2');
+      expect(closure.localVariables[0].nameOffset, text.indexOf('v2;'));
+    }
+  }
+
   test_variable_name() {
     UnlinkedVariable variable =
         serializeVariableText('int i;', variableName: 'i');
@@ -6901,14 +7319,10 @@
 class _PrefixExpectation {
   final ReferenceKind kind;
   final String name;
-  final bool inLibraryDefiningUnit;
   final String absoluteUri;
   final String relativeUri;
   final int numTypeParameters;
 
   _PrefixExpectation(this.kind, this.name,
-      {this.inLibraryDefiningUnit: false,
-      this.absoluteUri,
-      this.relativeUri,
-      this.numTypeParameters: 0});
+      {this.absoluteUri, this.relativeUri, this.numTypeParameters: 0});
 }
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 21c2fd3..9bf0050 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -1145,6 +1145,33 @@
         outputs[CONSTANT_DEPENDENCIES].toSet(), [x, constructorForD].toSet());
   }
 
+  test_annotation_with_nonConstArg() {
+    Source source = newSource(
+        '/test.dart',
+        '''
+class A {
+  const A(x);
+}
+class C {
+  @A(const [(_) => null])
+  String s;
+}
+''');
+    // First compute the resolved unit for the source.
+    LibrarySpecificUnit librarySpecificUnit =
+        new LibrarySpecificUnit(source, source);
+    computeResult(librarySpecificUnit, RESOLVED_UNIT1);
+    CompilationUnit unit = outputs[RESOLVED_UNIT1];
+    // Find the annotation on the field.
+    ClassDeclaration classC = unit.declarations[1];
+    Annotation annotation = classC.members[0].metadata[0];
+    // Now compute the dependencies for the annotation, and check that it is
+    // the right size.
+    computeResult(annotation.elementAnnotation, CONSTANT_DEPENDENCIES,
+        matcher: isComputeConstantDependenciesTask);
+    expect(outputs[CONSTANT_DEPENDENCIES], hasLength(1));
+  }
+
   test_annotation_without_args() {
     Source source = newSource(
         '/test.dart',
@@ -2240,8 +2267,6 @@
 
 @reflectiveTest
 class GatherUsedLocalElementsTaskTest extends _AbstractDartTaskTest {
-  List<Element> definedElements;
-  Set<String> definedElementNames;
   UsedLocalElements usedElements;
   Set<String> usedElementNames;
 
@@ -2306,7 +2331,6 @@
 }''');
     _computeUsedElements(source);
     // validate
-    expect(definedElementNames, unorderedEquals(['main', 'v1', 'v2']));
     expect(usedElementNames, unorderedEquals(['v2']));
   }
 
@@ -2326,30 +2350,14 @@
 ''');
     _computeUsedElements(source);
     // validate
-    expect(definedElementNames,
-        unorderedEquals(['A', '_m1', '_m2', 'main', 'a', 'p']));
     expect(usedElementNames, unorderedEquals(['A', 'a', 'p', '_m2']));
     expect(usedElements.members, unorderedEquals(['_m2', '_m3']));
   }
 
-  test_perform_unresolvedImportWithPrefix() {
-    Source source = newSource(
-        '/test.dart',
-        r'''
-import 'x' as p;
-''');
-    _computeUsedElements(source);
-    // validate
-    expect(definedElementNames, isEmpty);
-    expect(usedElementNames, isEmpty);
-  }
-
   void _computeUsedElements(Source source) {
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
     computeResult(target, USED_LOCAL_ELEMENTS,
         matcher: isGatherUsedLocalElementsTask);
-    definedElements = outputs[DEFINED_ELEMENTS];
-    definedElementNames = definedElements.map((e) => e.name).toSet();
     usedElements = outputs[USED_LOCAL_ELEMENTS];
     usedElementNames = usedElements.elements.map((e) => e.name).toSet();
   }
@@ -4069,8 +4077,6 @@
    */
   void expectMutated(FunctionBody body, VariableElement variable,
       bool mutatedInClosure, bool mutatedInScope) {
-    expect(variable.isPotentiallyMutatedInClosure, mutatedInClosure);
-    expect(variable.isPotentiallyMutatedInScope, mutatedInScope);
     expect(body.isPotentiallyMutatedInClosure(variable), mutatedInClosure);
     expect(body.isPotentiallyMutatedInScope(variable), mutatedInScope);
   }
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index cc7047e..a87577c 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -33,10 +33,10 @@
           // because we're using the spec's LUB on function types, which isn't
           // sound.
           SplayTreeMap([int compare(K key1, K key2),
-                        bool isValidKey(potentialKey)]) {
+                        bool isValidKey(potentialKey)])
             : _comparator = (compare == null) ? Comparable.compare : compare,
-              _validKey = (isValidKey != null) ? isValidKey : ((v) => true);
-             _Predicate<Object> v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
+              _validKey = (isValidKey != null) ? isValidKey : ((v) => true) {
+            _Predicate<Object> v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
                                     ? isValidKey : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
 
             v = (isValidKey != null)
@@ -59,7 +59,7 @@
   test('if/for/do/while statements use boolean conversion', () {
     checkFile('''
       main() {
-        dynamic d = 42;
+        dynamic dyn = 42;
         Object obj = 42;
         int i = 42;
         bool b = false;
@@ -133,12 +133,12 @@
           (/*info:DYNAMIC_INVOKE*/g.call(32.0));
           (/*info:DYNAMIC_INVOKE*/g.col(42.0));
           (/*info:DYNAMIC_INVOKE*/g.foo(42.0));
-          (/*info:DYNAMIC_INVOKE*/g.x);
+          (/*info:DYNAMIC_INVOKE*/g./*info:UNDEFINED_GETTER*/x);
           A f = new B();
           f.call(32.0);
           (/*info:DYNAMIC_INVOKE*/f.col(42.0));
           (/*info:DYNAMIC_INVOKE*/f.foo(42.0));
-          (/*info:DYNAMIC_INVOKE*/f.x);
+          (/*info:DYNAMIC_INVOKE*/f./*warning:UNDEFINED_GETTER*/x);
         }
       }
     ''');
@@ -203,7 +203,7 @@
         (/*info:DYNAMIC_INVOKE*/b2("hello"));
 
         dynamic a1 = new B();
-        (/*info:DYNAMIC_INVOKE*/a1.x);
+        (/*info:DYNAMIC_INVOKE*/a1./*info:UNDEFINED_GETTER*/x);
         a1.toString();
         (/*info:DYNAMIC_INVOKE*/a1.toString(42));
         var toStringClosure = a1.toString;
@@ -263,7 +263,7 @@
   test('Unbound variable', () {
     checkFile('''
       void main() {
-         dynamic y = /*pass should be severe:STATIC_TYPE_ERROR*/unboundVariable;
+         dynamic y = /*warning:UNDEFINED_IDENTIFIER should be error*/unboundVariable;
       }
    ''');
   });
@@ -271,7 +271,7 @@
   test('Unbound type name', () {
     checkFile('''
       void main() {
-         /*pass should be severe:STATIC_TYPE_ERROR*/AToB y;
+         /*warning:UNDEFINED_CLASS should be error*/AToB y;
       }
    ''');
   });
@@ -556,12 +556,11 @@
       typedef A Right(dynamic x);         // Right branch
       typedef A Bottom(A x);              // Bottom of the lattice
 
-      dynamic left(A x) => x;
-      A bot(A x) => x;
-      dynamic top(dynamic x) => x;
-      A right(dynamic x) => /*info:DYNAMIC_CAST*/x;
-
       void main() {
+        Top top;
+        Left left;
+        Right right;
+        Bottom bot;
         {
           Top f;
           f = top;
@@ -571,29 +570,106 @@
         }
         {
           Left f;
-          f = /*severe:STATIC_TYPE_ERROR*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
           f = left;
-          f = /*severe:STATIC_TYPE_ERROR*/right;
+          f = /*warning:DOWN_CAST_COMPOSITE*/right;
           f = bot;
         }
         {
           Right f;
-          f = /*severe:STATIC_TYPE_ERROR*/top;
-          f = /*severe:STATIC_TYPE_ERROR*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
           f = right;
           f = bot;
         }
         {
           Bottom f;
-          f = /*severe:STATIC_TYPE_ERROR*/top;
-          f = /*severe:STATIC_TYPE_ERROR*/left;
-          f = /*severe:STATIC_TYPE_ERROR*/right;
+          f = /*warning:DOWN_CAST_COMPOSITE*/top;
+          f = /*warning:DOWN_CAST_COMPOSITE*/left;
+          f = /*warning:DOWN_CAST_COMPOSITE*/right;
           f = bot;
         }
       }
    ''');
     });
 
+    test('dynamic - known functions', () {
+
+      // Our lattice should look like this:
+      //
+      //
+      //           Bot -> Top
+      //          /        \
+      //      A -> Top    Bot -> A
+      //       /     \      /
+      // Top -> Top   A -> A
+      //         \      /
+      //         Top -> A
+      //
+      checkFile('''
+        class A {}
+
+        typedef dynamic BotTop(dynamic x);
+        typedef dynamic ATop(A x);
+        typedef A BotA(dynamic x);
+        typedef A AA(A x);
+        typedef A TopA(Object x);
+        typedef dynamic TopTop(Object x);
+
+        dynamic aTop(A x) => x;
+        A aa(A x) => x;
+        dynamic topTop(dynamic x) => x;
+        A topA(dynamic x) => /*info:DYNAMIC_CAST*/x;
+
+        void main() {
+          BotTop botTop;
+          BotA botA;
+          {
+            BotTop f;
+            f = topTop;
+            f = aTop;
+            f = topA;
+            f = aa;
+          }
+          {
+            ATop f;
+            f = topTop;
+            f = aTop;
+            f = topA;
+            f = aa;
+          }
+          {
+            BotA f;
+            f = /*severe:STATIC_TYPE_ERROR*/topTop;
+            f = /*severe:STATIC_TYPE_ERROR*/aTop;
+            f = topA;
+            f = aa;
+          }
+          {
+            AA f;
+            f = /*severe:STATIC_TYPE_ERROR*/topTop;
+            f = /*severe:STATIC_TYPE_ERROR*/aTop;
+            f = topA;
+            f = aa;
+          }
+          {
+            TopTop f;
+            f = topTop;
+            f = /*severe:STATIC_TYPE_ERROR*/aTop;
+            f = topA;
+            f = /*severe:STATIC_TYPE_ERROR*/aa;
+          }
+          {
+            TopA f;
+            f = /*severe:STATIC_TYPE_ERROR*/topTop;
+            f = /*severe:STATIC_TYPE_ERROR*/aTop;
+            f = topA;
+            f = /*severe:STATIC_TYPE_ERROR*/aa;
+          }
+        }
+     ''');
+    });
+
     test('function literal variance', () {
       checkFile('''
 
@@ -1010,7 +1086,7 @@
          o = /*severe:STATIC_TYPE_ERROR*/ro;
          o = /*severe:STATIC_TYPE_ERROR*/rn;
          o = oo;
-         o = /*severe:STATIC_TYPE_ERROR*/nn
+         o = /*severe:STATIC_TYPE_ERROR*/nn;
          o = /*severe:STATIC_TYPE_ERROR*/nnn;
 
          n = /*severe:STATIC_TYPE_ERROR*/r;
@@ -1386,7 +1462,7 @@
     checkFile(r'''
         class Animal {
           Animal();
-          factory Animal.cat() => return new Cat();
+          factory Animal.cat() => new Cat();
         }
 
         class Cat extends Animal {}
@@ -1656,21 +1732,22 @@
           /*=T*/ bar/*<T>*/({/*=T*/ x, /*=T*/ y}) => x;
 
           main() {
-            // resolving thses shouldn't crash.
-            foo(1, 2, 3);
-            String x = foo('1', '2', '3');
-            foo(1);
-            String x = foo('1');
-            x = /*severe:STATIC_TYPE_ERROR*/foo(1, 2, 3);
-            x = /*severe:STATIC_TYPE_ERROR*/foo(1);
+            String x;
+            // resolving these shouldn't crash.
+            foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
+            x = foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/('1', '2', '3');
+            foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
+            x = foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/('1');
+            x = /*info:DYNAMIC_CAST*/foo/*warning:EXTRA_POSITIONAL_ARGUMENTS*/(1, 2, 3);
+            x = /*info:DYNAMIC_CAST*/foo/*warning:NOT_ENOUGH_REQUIRED_ARGUMENTS*/(1);
 
             // named arguments
-            bar(y: 1, x: 2, z: 3);
-            String x = bar(z: '1', x: '2', y: '3');
+            bar(y: 1, x: 2, /*warning:UNDEFINED_NAMED_PARAMETER*/z: 3);
+            x = bar(/*warning:UNDEFINED_NAMED_PARAMETER*/z: '1', x: '2', y: '3');
             bar(y: 1);
-            x = bar(x: '1', z: 42);
-            x = /*severe:STATIC_TYPE_ERROR*/bar(y: 1, x: 2, z: 3);
-            x = /*severe:STATIC_TYPE_ERROR*/bar(x: 1);
+            x = bar(x: '1', /*warning:UNDEFINED_NAMED_PARAMETER*/z: 42);
+            x = /*info:DYNAMIC_CAST*/bar(y: 1, x: 2, /*warning:UNDEFINED_NAMED_PARAMETER*/z: 3);
+            x = /*info:DYNAMIC_CAST*/bar(x: 1);
           }
       ''');
   });
@@ -1708,6 +1785,7 @@
       test() {
         A a = new A();
         var c = foo();
+        dynamic d;
 
         ~a;
         (/*info:DYNAMIC_INVOKE*/~d);
@@ -1889,7 +1967,7 @@
             a[/*severe:STATIC_TYPE_ERROR*/z] += d;
             a[b] += /*info:DYNAMIC_CAST*/c;
             a[b] += /*severe:STATIC_TYPE_ERROR*/z;
-            (/*info:DYNAMIC_INVOKE*/(/*info:DYNAMIC_INVOKE*/c[b]) += d);
+            /*info:DYNAMIC_INVOKE,info:DYNAMIC_INVOKE*/c[b] += d;
           }
        ''');
   });
@@ -1948,6 +2026,7 @@
     addFile('''library lib1;''', name: '/lib1.dart');
     checkFile(r'''
         import 'lib1.dart' deferred as lib1;
+        import 'dart:async' show Future;
         main() {
           Future f = lib1.loadLibrary();
         }''');
@@ -1964,11 +2043,11 @@
             }
 
             class T1 extends Base {
-              /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/B get f => null;
+              /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/B get f => null;
             }
 
             class T2 extends Base {
-              /*severe:INVALID_FIELD_OVERRIDE,severe:INVALID_METHOD_OVERRIDE*/set f(B b) => null;
+              /*severe:INVALID_METHOD_OVERRIDE,severe:INVALID_FIELD_OVERRIDE*/set f(B b) => null;
             }
 
             class T3 extends Base {
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 2e7981e..ba964d8 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -261,6 +261,7 @@
         name: '/c.dart');
     addFile(
         '''
+          library e;
           import 'a.dart';
           part 'e2.dart';
 
@@ -281,6 +282,7 @@
         name: '/f.dart');
     addFile(
         '''
+          part of e;
           class F {
             static final f1 = 1;
             final f2 = 1;
@@ -334,17 +336,17 @@
         class B extends A { B(ignore); }
         var a = new A();
         // Note: it doesn't matter that some of these refer to 'x'.
-        var b = new B(x);       // allocations
-        var c1 = [x];           // list literals
+        var b = new B(/*warning:UNDEFINED_IDENTIFIER*/x);  // allocations
+        var c1 = [/*warning:UNDEFINED_IDENTIFIER*/x];      // list literals
         var c2 = const [];
-        var d = {'a': 'b'};     // map literals
+        var d = <dynamic, dynamic>{'a': 'b'};     // map literals
         var e = new A()..x = 3; // cascades
         var f = 2 + 3;          // binary expressions are OK if the left operand
                                 // is from a library in a different strongest
                                 // conected component.
         var g = -3;
         var h = new A() + 3;
-        var i = - new A();
+        var i = /*warning:UNDEFINED_OPERATOR*/- new A();
         var j = null as B;
 
         test1() {
@@ -365,9 +367,9 @@
           g = 1;
           g = /*severe:STATIC_TYPE_ERROR*/false;
           h = /*severe:STATIC_TYPE_ERROR*/false;
-          h = new B();
+          h = new B('b');
           i = false;
-          j = new B();
+          j = new B('b');
           j = /*severe:STATIC_TYPE_ERROR*/false;
           j = /*severe:STATIC_TYPE_ERROR*/[];
         }
@@ -683,12 +685,12 @@
     test('5', () {
       checkFile('''
         abstract class I<E> {
-          String m(a, String f(v, T e));
+          String m(a, String f(v, E e));
         }
 
         abstract class A<E> implements I<E> {
           const A();
-          String m(a, String f(v, T e));
+          String m(a, String f(v, E e));
         }
 
         abstract class M {
@@ -699,7 +701,7 @@
           const B();
           int get y => 0;
 
-          m(a, f(v, T e)) {}
+          m(a, f(v, E e)) {}
         }
 
         foo () {
@@ -728,7 +730,7 @@
         }
         foo () {
           int y = new C().x;
-          String y = /*severe:STATIC_TYPE_ERROR*/new C().x;
+          String z = /*severe:STATIC_TYPE_ERROR*/new C().x;
         }
     ''');
   });
@@ -987,7 +989,7 @@
         const a1 = 3;
         const a2 = 4;
         class A {
-          a3;
+          static const a3 = null;
         }
       ''',
         name: '/a.dart');
@@ -1203,7 +1205,7 @@
 
 abstract class C {
   static AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
-  static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf;
+  static AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf => null;
 
   AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
   AsserterBuilder<List<Asserter<DartType>>, DartType> get assertDOf;
@@ -1230,7 +1232,7 @@
 }
 
 AsserterBuilder<List<Asserter<DartType>>, DartType> assertBOf;
-AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf;
+AsserterBuilder<List<Asserter<DartType>>, DartType> get assertCOf => null;
 
 main() {
   AsserterBuilder<List<Asserter<DartType>>, DartType> assertAOf;
@@ -1255,11 +1257,11 @@
   group('downwards inference on function arguments', () {
     test('infer downwards', () {
       checkFile('''
-      void f0(List<int> a) {};
-      void f1({List<int> a}) {};
-      void f2(Iterable<int> a) {};
-      void f3(Iterable<Iterable<int>> a) {};
-      void f4({Iterable<Iterable<int>> a}) {};
+      void f0(List<int> a) {}
+      void f1({List<int> a}) {}
+      void f2(Iterable<int> a) {}
+      void f3(Iterable<Iterable<int>> a) {}
+      void f4({Iterable<Iterable<int>> a}) {}
       void main() {
         f0(/*info:INFERRED_TYPE_LITERAL*/[]);
         f0(/*info:INFERRED_TYPE_LITERAL*/[3]);
@@ -1294,19 +1296,19 @@
     test('infer downwards', () {
       checkFile('''
       class F0 {
-        F0(List<int> a) {};
+        F0(List<int> a) {}
       }
       class F1 {
-        F1({List<int> a}) {};
+        F1({List<int> a}) {}
       }
       class F2 {
-        F2(Iterable<int> a) {};
+        F2(Iterable<int> a) {}
       }
       class F3 {
-        F3(Iterable<Iterable<int>> a) {};
+        F3(Iterable<Iterable<int>> a) {}
       }
       class F4 {
-        F4({Iterable<Iterable<int>> a}) {};
+        F4({Iterable<Iterable<int>> a}) {}
       }
       void main() {
         new F0(/*info:INFERRED_TYPE_LITERAL*/[]);
@@ -1345,19 +1347,19 @@
     test('infer downwards', () {
       checkFile('''
       class F0<T> {
-        F0(List<T> a) {};
+        F0(List<T> a) {}
       }
       class F1<T> {
-        F1({List<T> a}) {};
+        F1({List<T> a}) {}
       }
       class F2<T> {
-        F2(Iterable<T> a) {};
+        F2(Iterable<T> a) {}
       }
       class F3<T> {
-        F3(Iterable<Iterable<T>> a) {};
+        F3(Iterable<Iterable<T>> a) {}
       }
       class F4<T> {
-        F4({Iterable<Iterable<T>> a}) {};
+        F4({Iterable<Iterable<T>> a}) {}
       }
       void main() {
         new F0<int>(/*info:INFERRED_TYPE_LITERAL*/[]);
@@ -1406,7 +1408,7 @@
     test('infer downwards', () {
       checkFile('''
       void foo([Map<int, String> m1 = /*info:INFERRED_TYPE_LITERAL*/const {1: "hello"},
-        Map<int, String> m1 = /*info:INFERRED_TYPE_LITERAL*/const {(/*severe:STATIC_TYPE_ERROR*/"hello"): "world"}]) {
+        Map<int, String> m2 = /*info:INFERRED_TYPE_LITERAL*/const {(/*severe:STATIC_TYPE_ERROR*/"hello"): "world"}]) {
       }
       void main() {
         {
@@ -1530,7 +1532,7 @@
           x = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => x+1;
           var y = int2String;
           y = /*info:INFERRED_TYPE_CLOSURE, severe:STATIC_TYPE_ERROR*//*<T>*/(x) => x;
-          y = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/x.substring(3);
+          y = /*info:INFERRED_TYPE_CLOSURE, info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => /*info:DYNAMIC_INVOKE, info:DYNAMIC_CAST*/x.substring(3);
           var z = string2String;
           z = /*info:INFERRED_TYPE_CLOSURE*//*<T>*/(x) => x.substring(3);
         }
@@ -1571,28 +1573,30 @@
       void f([List<int> l = /*info:INFERRED_TYPE_LITERAL*/const [1]]) {}
       // We do this inference in an early task but don't preserve the infos.
       Function2<List<int>, String> g = /*pass should be info:INFERRED_TYPE_CLOSURE*/([llll = /*info:INFERRED_TYPE_LITERAL*/const [1]]) => "hello";
-''');
+    ''');
   });
 
   test('downwards inference async/await', () {
     checkFile('''
       import 'dart:async';
       Future<int> test() async {
-        List<int> l0 = /*warning:DOWN_CAST_COMPOSITE should be pass*/await /*pass should be info:INFERRED_TYPE_LITERAL*/[3];
-        List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[3]);
-        ''');
+        dynamic d;
+        List<int> l0 = /*warning:DOWN_CAST_COMPOSITE should be pass*/await /*pass should be info:INFERRED_TYPE_LITERAL*/[d];
+        List<int> l1 = await /*info:INFERRED_TYPE_ALLOCATION*/new Future.value(/*info:INFERRED_TYPE_LITERAL*/[/*info:DYNAMIC_CAST*/d]);
+      }
+    ''');
   });
 
   test('downwards inference foreach', () {
     checkFile('''
       import 'dart:async';
-      void main() {
+      Future main() async {
         for(int x in /*info:INFERRED_TYPE_LITERAL*/[1, 2, 3]) {
         }
         await for(int x in /*info:INFERRED_TYPE_ALLOCATION*/new Stream()) {
         }
       }
-        ''');
+    ''');
   });
 
   test('downwards inference yield/yield*', () {
@@ -1691,7 +1695,7 @@
           Iterable<Future<int>> list = <int>[1, 2, 3].map(make);
           Future<List<int>> results = Future.wait(list);
           Future<String> results2 = results.then((List<int> list)
-            => list.fold('', (String x, int y) => x + y.toString()));
+            => list.fold('', /*info:INFERRED_TYPE_CLOSURE*/(x, y) => x + y.toString()));
         }
     ''');
     });
@@ -1826,7 +1830,7 @@
   /*severe:INVALID_METHOD_OVERRIDE*/m(x) => x;
 }
 main() {
-  int y = /*info:DYNAMIC_CAST*/new D().m/*<int>*/(42);
+  int y = /*info:DYNAMIC_CAST*/new D()./*warning:WRONG_NUMBER_OF_TYPE_ARGUMENTS*/m/*<int>*/(42);
   print(y);
 }
     ''');
@@ -1834,7 +1838,7 @@
 
     test('correctly recognize generic upper bound', () {
       // Regression test for https://github.com/dart-lang/sdk/issues/25740.
-      checkFile('''
+      checkFile(r'''
 class Foo<T extends Pattern> {
   void method/*<U extends T>*/(dynamic/*=U*/ u) {}
 }
@@ -1849,11 +1853,52 @@
 }
       ''');
     });
+
+    test('basic downwards inference', () {
+      checkFile(r'''
+/*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
+main() {
+  String x = f(42);
+  String y = (f)(42);
+}
+      ''');
+    });
+
+    test('downwards inference affects arguments', () {
+      checkFile(r'''
+/*=T*/ f/*<T>*/(List/*<T>*/ s) => null;
+main() {
+  String x = f(/*info:INFERRED_TYPE_LITERAL*/['hi']);
+  String y = f(/*info:INFERRED_TYPE_LITERAL*/[/*severe:STATIC_TYPE_ERROR*/42]);
+}
+      ''');
+    });
+
+    test('downwards inference fold', () {
+      // Regression from https://github.com/dart-lang/sdk/issues/25491
+      // The first example works now, but the latter requires a full solution to
+      // https://github.com/dart-lang/sdk/issues/25490
+      checkFile(r'''
+void main() {
+  List<int> o;
+  int y = o.fold(0, /*info:INFERRED_TYPE_CLOSURE*/(x, y) => x + y);
+  var z = o.fold(0, /*info:INFERRED_TYPE_CLOSURE*/(x, y) => /*info:DYNAMIC_INVOKE*/x + y);
+  y = /*info:DYNAMIC_CAST*/z;
+}
+void functionExpressionInvocation() {
+  List<int> o;
+  int y = (o.fold)(0, /*info:INFERRED_TYPE_CLOSURE*/(x, y) => x + y);
+  var z = (o.fold)(0, /*info:INFERRED_TYPE_CLOSURE*/(x, y) => /*info:DYNAMIC_INVOKE*/x + y);
+  y = /*info:DYNAMIC_CAST*/z;
+}
+      ''');
+    });
+
   });
 
   // Regression test for https://github.com/dart-lang/dev_compiler/issues/47
   test('null literal should not infer as bottom', () {
-    checkFile('''
+    checkFile(r'''
       var h = null;
       void foo(int f(Object _)) {}
 
@@ -1874,4 +1919,45 @@
   ''');
   });
 
+  test('list literals', () {
+    checkFile(r'''
+test1() {
+  var x = [1, 2, 3];
+  x.add(/*severe:STATIC_TYPE_ERROR*/'hi');
+  x.add(/*severe:STATIC_TYPE_ERROR*/4.0);
+  x.add(4);
+  List<num> y = x;
+}
+test2() {
+  var x = [1, 2.0, 3];
+  x.add(/*severe:STATIC_TYPE_ERROR*/'hi');
+  x.add(4.0);
+  List<int> y = /*info:ASSIGNMENT_CAST*/x;
+}
+    ''');
+  });
+
+  test('map literals', () {
+    checkFile(r'''
+test1() {
+  var x = { 1: 'x', 2: 'y' };
+  x[3] = 'z';
+  x[/*severe:STATIC_TYPE_ERROR*/'hi'] = 'w';
+  x[/*severe:STATIC_TYPE_ERROR*/4.0] = 'u';
+  x[3] = /*severe:STATIC_TYPE_ERROR*/42;
+  Map<num, String> y = x;
+}
+
+test2() {
+  var x = { 1: 'x', 2: 'y', 3.0: new RegExp('.') };
+  x[3] = 'z';
+  x[/*severe:STATIC_TYPE_ERROR*/'hi'] = 'w';
+  x[4.0] = 'u';
+  x[3] = /*severe:STATIC_TYPE_ERROR*/42;
+  Pattern p = null;
+  x[2] = p;
+  Map<int, String> y = /*info:ASSIGNMENT_CAST*/x;
+}
+    ''');
+  });
 }
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 e858a37..19ed5b3 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -15,8 +15,6 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/generated/type_system.dart';
-import 'package:analyzer/src/task/strong/checker.dart';
 import 'package:logging/logging.dart';
 import 'package:source_span/source_span.dart';
 import 'package:unittest/unittest.dart';
@@ -64,7 +62,7 @@
   // Enable task model strong mode
   var context = AnalysisEngine.instance.createAnalysisContext();
   context.analysisOptions.strongMode = true;
-  context.analysisOptions.strongModeHints = true;
+  (context.analysisOptions as AnalysisOptionsImpl).strongModeHints = true;
   context.sourceFactory =
       new SourceFactory([new DartUriResolver(new MockSdk()), uriResolver]);
 
@@ -73,13 +71,10 @@
   var initialLibrary = context.resolveCompilationUnit2(mainSource, mainSource);
 
   var collector = new _ErrorCollector();
-  var checker = new CodeChecker(
-      context.typeProvider, new StrongTypeSystemImpl(), collector,
-      hints: true);
 
   // Extract expectations from the comments in the test files, and
   // check that all errors we emit are included in the expected map.
-  var allLibraries = reachableLibraries(initialLibrary.element.library);
+  var allLibraries = _reachableLibraries(initialLibrary.element.library);
   for (var lib in allLibraries) {
     for (var unit in lib.units) {
       var errors = <AnalysisError>[];
@@ -90,9 +85,10 @@
 
       var librarySource = context.getLibrariesContaining(source).single;
       var resolved = context.resolveCompilationUnit2(source, librarySource);
-      errors.addAll(context.getErrors(source).errors.where((error) =>
-          error.errorCode.name.startsWith('STRONG_MODE_INFERRED_TYPE')));
-      checker.visitCompilationUnit(resolved);
+      errors.addAll(context.getErrors(source).errors.where((e) =>
+          e.errorCode != HintCode.UNUSED_LOCAL_VARIABLE &&
+          // TODO(jmesserly): these are usually intentional dynamic calls.
+          e.errorCode.name != 'UNDEFINED_METHOD'));
 
       _expectErrors(resolved, errors);
     }
@@ -105,11 +101,11 @@
   check();
 }
 
-SourceSpanWithContext createSpanHelper(
+SourceSpanWithContext _createSpanHelper(
     LineInfo lineInfo, int start, Source source, String content,
     {int end}) {
-  var startLoc = locationForOffset(lineInfo, source.uri, start);
-  var endLoc = locationForOffset(lineInfo, source.uri, end ?? start);
+  var startLoc = _locationForOffset(lineInfo, source.uri, start);
+  var endLoc = _locationForOffset(lineInfo, source.uri, end ?? start);
 
   var lineStart = startLoc.offset - startLoc.column;
   // Find the end of the line. This is not exposed directly on LineInfo, but
@@ -123,7 +119,7 @@
 
   if (end == null) {
     end = lineEnd;
-    endLoc = locationForOffset(lineInfo, source.uri, lineEnd);
+    endLoc = _locationForOffset(lineInfo, source.uri, lineEnd);
   }
 
   var text = content.substring(start, end);
@@ -131,19 +127,17 @@
   return new SourceSpanWithContext(startLoc, endLoc, text, lineText);
 }
 
-String errorCodeName(ErrorCode errorCode) {
+String _errorCodeName(ErrorCode errorCode) {
   var name = errorCode.name;
   final prefix = 'STRONG_MODE_';
   if (name.startsWith(prefix)) {
     return name.substring(prefix.length);
   } else {
-    // TODO(jmesserly): this is for backwards compat, but not sure it's very
-    // useful to log this.
-    return 'AnalyzerMessage';
+    return name;
   }
 }
 
-initStrongModeTests() {
+void initStrongModeTests() {
   setUp(() {
     AnalysisEngine.instance.processRequiredPlugins();
     files = new MemoryResourceProvider();
@@ -157,15 +151,14 @@
   });
 }
 
-// TODO(jmesserly): can we reuse the same mock SDK as Analyzer tests?
-SourceLocation locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
+SourceLocation _locationForOffset(LineInfo lineInfo, Uri uri, int offset) {
   var loc = lineInfo.getLocation(offset);
   return new SourceLocation(offset,
       sourceUrl: uri, line: loc.lineNumber - 1, column: loc.columnNumber - 1);
 }
 
 /// Returns all libraries transitively imported or exported from [start].
-List<LibraryElement> reachableLibraries(LibraryElement start) {
+List<LibraryElement> _reachableLibraries(LibraryElement start) {
   var results = <LibraryElement>[];
   var seen = new Set();
   void find(LibraryElement lib) {
@@ -190,6 +183,26 @@
 void _expectErrors(CompilationUnit unit, List<AnalysisError> actualErrors) {
   var expectedErrors = _findExpectedErrors(unit.beginToken);
 
+  // Sort both lists: by offset, then level, then name.
+  actualErrors.sort((x, y) {
+    int delta = x.offset.compareTo(y.offset);
+    if (delta != 0) return delta;
+
+    delta = x.errorCode.errorSeverity.compareTo(y.errorCode.errorSeverity);
+    if (delta != 0) return delta;
+
+    return _errorCodeName(x.errorCode).compareTo(_errorCodeName(y.errorCode));
+  });
+  expectedErrors.sort((x, y) {
+    int delta = x.offset.compareTo(y.offset);
+    if (delta != 0) return delta;
+
+    delta = x.level.compareTo(y.level);
+    if (delta != 0) return delta;
+
+    return x.typeName.compareTo(y.typeName);
+  });
+
   // Categorize the differences, if any.
   var unreported = <_ErrorExpectation>[];
   var different = <_ErrorExpectation, AnalysisError>{};
@@ -198,7 +211,7 @@
     AnalysisError actual = expected._removeMatchingActual(actualErrors);
     if (actual != null) {
       if (_actualErrorLevel(actual) != expected.level ||
-          errorCodeName(actual.errorCode) != expected.typeName) {
+          _errorCodeName(actual.errorCode) != expected.typeName) {
         different[expected] = actual;
       }
     } else {
@@ -223,9 +236,11 @@
       if (c.type == TokenType.MULTI_LINE_COMMENT) {
         String value = c.lexeme.substring(2, c.lexeme.length - 2);
         if (value.contains(':')) {
-          var offset = c.end;
-          if (c.next?.type == TokenType.GENERIC_METHOD_TYPE_LIST) {
-            offset += 2;
+          int offset = t.offset;
+          Token previous = t.previous;
+          while (previous != null && previous.offset > c.offset) {
+            offset = previous.offset;
+            previous = previous.previous;
           }
           for (var expectCode in value.split(',')) {
             var expected = _ErrorExpectation.parse(offset, expectCode);
@@ -252,20 +267,20 @@
   String formatActualError(AnalysisError error) {
     int offset = error.offset;
     int length = error.length;
-    var span = createSpanHelper(
+    var span = _createSpanHelper(
         unit.lineInfo, offset, unit.element.source, sourceCode,
         end: offset + length);
     var levelName = _actualErrorLevel(error).name.toLowerCase();
-    return '@$offset $levelName: [${errorCodeName(error.errorCode)}]\n' +
+    return '@$offset $levelName:${_errorCodeName(error.errorCode)}\n' +
         span.message(error.message);
   }
 
   String formatExpectedError(_ErrorExpectation error) {
     int offset = error.offset;
-    var span = createSpanHelper(
+    var span = _createSpanHelper(
         unit.lineInfo, offset, unit.element.source, sourceCode);
     var levelName = error.level.toString().toLowerCase();
-    return '@$offset $levelName: [${error.typeName}]\n' + span.message('');
+    return '@$offset $levelName:${error.typeName}\n' + span.message('');
   }
 
   var message = new StringBuffer();
diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
index 8e6c5fc..176f7c6 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
@@ -1,3 +1,4 @@
+import 'dart:convert';
 import 'dart:io';
 
 import 'package:analyzer/dart/element/element.dart';
@@ -8,6 +9,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:crypto/crypto.dart';
 import 'package:path/path.dart';
 
 main(List<String> args) {
@@ -73,6 +75,7 @@
   final List<LinkedLibraryBuilder> linkedLibraries = <LinkedLibraryBuilder>[];
   final List<String> unlinkedUnitUris = <String>[];
   final List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
+  final List<String> unlinkedUnitHashes = <String>[];
 
   _Builder(this.sdkPath, this.outputDirectoryPath, this.strongMode);
 
@@ -92,20 +95,28 @@
     context.analysisOptions = new AnalysisOptionsImpl()
       ..strongMode = strongMode;
     //
+    // Prepare 'dart:' URIs to serialize.
+    //
+    Set<String> uriSet =
+        sdk.sdkLibraries.map((SdkLibrary library) => library.shortName).toSet();
+    uriSet.add('dart:html/nativewrappers.dart');
+    uriSet.add('dart:html_common/html_common_dart2js.dart');
+    //
     // Serialize each SDK library.
     //
-    for (SdkLibrary lib in sdk.sdkLibraries) {
-      Source libSource = sdk.mapDartUri(lib.shortName);
+    for (String uri in uriSet) {
+      Source libSource = sdk.mapDartUri(uri);
       _serializeLibrary(libSource);
     }
     //
     // Write the whole SDK bundle.
     //
-    SdkBundleBuilder sdkBundle = new SdkBundleBuilder(
+    PackageBundleBuilder sdkBundle = new PackageBundleBuilder(
         linkedLibraryUris: linkedLibraryUris,
         linkedLibraries: linkedLibraries,
         unlinkedUnitUris: unlinkedUnitUris,
-        unlinkedUnits: unlinkedUnits);
+        unlinkedUnits: unlinkedUnits,
+        unlinkedUnitHashes: unlinkedUnitHashes);
     String outputFilePath =
         join(outputDirectoryPath, strongMode ? 'strong.sum' : 'spec.sum');
     File file = new File(outputFilePath);
@@ -117,6 +128,15 @@
   }
 
   /**
+   * Compute a hash of the given file contents.
+   */
+  String _hash(String contents) {
+    MD5 md5 = new MD5();
+    md5.add(UTF8.encode(contents));
+    return CryptoUtils.bytesToHex(md5.close());
+  }
+
+  /**
    * Serialize the library with the given [source] and all its direct or
    * indirect imports and exports.
    */
@@ -141,5 +161,8 @@
     linkedLibraries.add(libraryResult.linked);
     unlinkedUnitUris.addAll(libraryResult.unitUris);
     unlinkedUnits.addAll(libraryResult.unlinkedUnits);
+    for (Source source in libraryResult.unitSources) {
+      unlinkedUnitHashes.add(_hash(source.contents.data));
+    }
   }
 }
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index ba4a49e..9d5fcb6 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -62,6 +62,8 @@
   return codeGenerator._outBuffer.toString();
 });
 
+typedef String _StringToString(String s);
+
 class _CodeGenerator {
   /**
    * Buffer in which generated code is accumulated.
@@ -341,6 +343,7 @@
     out();
     out("import 'flat_buffers.dart' as fb;");
     out("import 'idl.dart' as idl;");
+    out("import 'dart:convert' as convert;");
     out();
     for (idlModel.EnumDeclaration enm in _idl.enums.values) {
       _generateEnumReader(enm);
@@ -631,6 +634,45 @@
     String mixinName = '_${name}Mixin';
     out('abstract class $mixinName implements ${idlPrefix(name)} {');
     indent(() {
+      // Write toJson().
+      out('@override');
+      out('Map<String, Object> toJson() {');
+      indent(() {
+        out('Map<String, Object> _result = <String, Object>{};');
+        for (idlModel.FieldDeclaration field in cls.fields) {
+          String condition;
+          if (field.type.isList) {
+            condition = '${field.name}.isNotEmpty';
+          } else {
+            condition = '${field.name} != ${defaultValue(field.type, false)}';
+          }
+          _StringToString convertItem;
+          if (_idl.classes.containsKey(field.type.typeName)) {
+            convertItem = (String name) => '$name.toJson()';
+          } else if (_idl.enums.containsKey(field.type.typeName)) {
+            // TODO(paulberry): it would be better to generate a const list of
+            // strings so that we don't have to do this kludge.
+            convertItem = (String name) => "$name.toString().split('.')[1]";
+          } else if (field.type.typeName == 'double') {
+            convertItem =
+                (String name) => '$name.isFinite ? $name : $name.toString()';
+          }
+          String convertField;
+          if (convertItem == null) {
+            convertField = field.name;
+          } else if (field.type.isList) {
+            convertField = '${field.name}.map((_value) =>'
+                ' ${convertItem('_value')}).toList()';
+          } else {
+            convertField = convertItem(field.name);
+          }
+          String storeField = '_result[${quoted(field.name)}] = $convertField';
+          out('if ($condition) $storeField;');
+        }
+        out('return _result;');
+      });
+      out('}');
+      out();
       // Write toMap().
       out('@override');
       out('Map<String, Object> toMap() => {');
@@ -641,6 +683,10 @@
         }
       });
       out('};');
+      out();
+      // Write toString().
+      out('@override');
+      out('String toString() => convert.JSON.encode(toJson());');
     });
     out('}');
   }
diff --git a/pkg/analyzer/tool/summary/stats.dart b/pkg/analyzer/tool/summary/stats.dart
index da524a0..b8f5dd7 100644
--- a/pkg/analyzer/tool/summary/stats.dart
+++ b/pkg/analyzer/tool/summary/stats.dart
@@ -24,8 +24,8 @@
   String inputFilePath = args[0];
 
   // Read the input.
-  SdkBundle bundle =
-      new SdkBundle.fromBuffer(new File(inputFilePath).readAsBytesSync());
+  PackageBundle bundle =
+      new PackageBundle.fromBuffer(new File(inputFilePath).readAsBytesSync());
 
   // Compute and output stats.
   Stats stats = new Stats();
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index 1f14eda..d77151b 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -76,8 +76,6 @@
   DART_ERRORS [shape=box]
   DART_SCRIPTS -> ScanDartTask
   DART_SCRIPTS [shape=box]
-  DEFINED_ELEMENTS -> GenerateHintsTask
-  DEFINED_ELEMENTS [shape=box]
   DartErrorsTask -> DART_ERRORS
   EXPLICITLY_IMPORTED_LIBRARIES [shape=box]
   EXPORTED_LIBRARIES -> BuildDirectiveElementsTask
@@ -90,7 +88,6 @@
   EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT11
   EvaluateUnitConstantsTask -> RESOLVED_UNIT11
   GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
-  GatherUsedLocalElementsTask -> DEFINED_ELEMENTS
   GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
   GenerateHintsTask -> HINTS
   GenerateLintsTask -> LINTS
@@ -166,6 +163,7 @@
   LIBRARY_SPECIFIC_UNITS [shape=box]
   LIBRARY_UNIT_ERRORS -> dartErrorsForUnit
   LIBRARY_UNIT_ERRORS [shape=box]
+  LINE_INFO -> DartErrorsTask
   LINE_INFO -> ParseDartTask
   LINE_INFO [shape=box]
   LINTS -> LibraryUnitErrorsTask
@@ -175,6 +173,7 @@
   MODIFICATION_TIME -> ParseDartTask
   MODIFICATION_TIME [shape=box]
   PARSED_UNIT -> BuildCompilationUnitElementTask
+  PARSED_UNIT -> DartErrorsTask
   PARSED_UNIT [shape=box]
   PARSE_ERRORS -> dartErrorsForSource
   PARSE_ERRORS [shape=box]
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index 75cbe52..56eaa2f 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -224,35 +224,8 @@
     formatter.formatErrors(errorInfos);
   }
 
-  /// Check various configuration options to get a desired severity for this
-  /// [error] (or `null` if it's to be suppressed).
-  ProcessedSeverity _processError(AnalysisError error) {
-    ErrorSeverity severity = computeSeverity(error, options, context);
-    bool isOverridden = false;
-
-    // First check for a filter.
-    if (severity == null) {
-      // Null severity means the error has been explicitly ignored.
-      return null;
-    } else {
-      isOverridden = true;
-    }
-
-    // If not overridden, some "natural" severities get globally filtered.
-    if (!isOverridden) {
-      // Check for global hint filtering.
-      if (severity == ErrorSeverity.INFO && options.disableHints) {
-        return null;
-      }
-
-      // Skip TODOs.
-      if (severity == ErrorType.TODO) {
-        return null;
-      }
-    }
-
-    return new ProcessedSeverity(severity, isOverridden);
-  }
+  ProcessedSeverity _processError(AnalysisError error) =>
+      processError(error, options, context);
 
   LibraryElement _resolveLibrary() {
     return _resolveLibraryTag.makeCurrentWhile(() {
@@ -303,6 +276,37 @@
     // Not found.
     return null;
   }
+
+  /// Check various configuration options to get a desired severity for this
+  /// [error] (or `null` if it's to be suppressed).
+  static ProcessedSeverity processError(AnalysisError error,
+      CommandLineOptions options, AnalysisContext context) {
+    ErrorSeverity severity = computeSeverity(error, options, context);
+    bool isOverridden = false;
+
+    // First check for a filter.
+    if (severity == null) {
+      // Null severity means the error has been explicitly ignored.
+      return null;
+    } else {
+      isOverridden = true;
+    }
+
+    // If not overridden, some "natural" severities get globally filtered.
+    if (!isOverridden) {
+      // Check for global hint filtering.
+      if (severity == ErrorSeverity.INFO && options.disableHints) {
+        return null;
+      }
+
+      // Skip TODOs.
+      if (severity == ErrorType.TODO) {
+        return null;
+      }
+    }
+
+    return new ProcessedSeverity(severity, isOverridden);
+  }
 }
 
 /// This [Logger] prints out information comments to [outSink] and error messages
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 3de4b4d..85c53ee 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -34,6 +34,7 @@
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer_cli/src/analyzer_impl.dart';
 import 'package:analyzer_cli/src/options.dart';
+import 'package:analyzer_cli/src/package_analyzer.dart';
 import 'package:analyzer_cli/src/perf_report.dart';
 import 'package:analyzer_cli/starter.dart';
 import 'package:linter/src/plugin/linter_plugin.dart';
@@ -113,7 +114,13 @@
     _setupEnv(options);
 
     // Do analysis.
-    if (_isBatch) {
+    if (options.packageMode) {
+      ErrorSeverity severity = _analyzePackage(options);
+      // In case of error propagate exit code.
+      if (severity == ErrorSeverity.ERROR) {
+        exitCode = severity.ordinal;
+      }
+    } else if (_isBatch) {
       _BatchRunner.runAsBatch(args, (List<String> args) {
         CommandLineOptions options = CommandLineOptions.parse(args);
         return _analyzeAll(options);
@@ -215,6 +222,13 @@
     return allResult;
   }
 
+  /// Perform package analysis according to the given [options].
+  ErrorSeverity _analyzePackage(CommandLineOptions options) {
+    return _analyzeAllTag.makeCurrentWhile(() {
+      return new PackageAnalyzer(options).analyze();
+    });
+  }
+
   /// Determine whether the context created during a previous call to
   /// [_analyzeAll] can be re-used in order to analyze using [options].
   bool _canContextBeReused(CommandLineOptions options) {
@@ -461,6 +475,7 @@
 
     // Create a context.
     AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    _context = context;
 
     // Choose a package resolution policy and a diet parsing policy based on
     // the command-line options.
@@ -471,34 +486,10 @@
 
     context.sourceFactory = sourceFactory;
 
-    Map<String, String> definedVariables = options.definedVariables;
-    if (!definedVariables.isEmpty) {
-      DeclaredVariables declaredVariables = context.declaredVariables;
-      definedVariables.forEach((String variableName, String value) {
-        declaredVariables.define(variableName, value);
-      });
-    }
-
-    if (options.log) {
-      AnalysisEngine.instance.logger = new StdLogger();
-    }
-
-    // Set context options.
-    AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
-    contextOptions.hint = !options.disableHints;
-    contextOptions.enableStrictCallChecks = options.enableStrictCallChecks;
-    contextOptions.enableSuperMixins = options.enableSuperMixins;
-    contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy;
-    contextOptions.generateImplicitErrors = options.showPackageWarnings;
-    contextOptions.generateSdkErrors = options.showSdkWarnings;
-    contextOptions.lint = options.lints;
-    contextOptions.strongMode = options.strongMode;
-    context.analysisOptions = contextOptions;
-    sourceFactory.dartSdk.context.analysisOptions = contextOptions;
-    _context = context;
-
-    // Process analysis options file (and notify all interested parties).
-    _processAnalysisOptions(options, context);
+    setAnalysisContextOptions(_context, options,
+        (AnalysisOptionsImpl contextOptions) {
+      contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy;
+    });
   }
 
   /// Return discovered packagespec, or `null` if none is found.
@@ -515,22 +506,6 @@
     return null;
   }
 
-  fileSystem.File _getOptionsFile(CommandLineOptions options) {
-    fileSystem.File file;
-    String filePath = options.analysisOptionsFile;
-    if (filePath != null) {
-      file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
-      if (!file.exists) {
-        printAndFail('Options file not found: $filePath',
-            exitCode: ErrorSeverity.ERROR.ordinal);
-      }
-    } else {
-      filePath = AnalysisEngine.ANALYSIS_OPTIONS_FILE;
-      file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
-    }
-    return file;
-  }
-
   Map<String, List<fileSystem.Folder>> _getPackageMap(Packages packages) {
     if (packages == null) {
       return null;
@@ -546,34 +521,6 @@
     return folderMap;
   }
 
-  void _processAnalysisOptions(
-      CommandLineOptions options, AnalysisContext context) {
-    fileSystem.File file = _getOptionsFile(options);
-    List<OptionsProcessor> optionsProcessors =
-        AnalysisEngine.instance.optionsPlugin.optionsProcessors;
-    try {
-      AnalysisOptionsProvider analysisOptionsProvider =
-          new AnalysisOptionsProvider();
-      Map<String, YamlNode> optionMap =
-          analysisOptionsProvider.getOptionsFromFile(file);
-      optionsProcessors.forEach(
-          (OptionsProcessor p) => p.optionsProcessed(context, optionMap));
-
-      // Fill in lint rule defaults in case lints are enabled and rules are
-      // not specified in an options file.
-      if (options.lints && !containsLintRuleEntry(optionMap)) {
-        setLints(context, linterPlugin.contributedRules);
-      }
-
-      // Ask engine to further process options.
-      if (optionMap != null) {
-        configureContextOptions(context, optionMap);
-      }
-    } on Exception catch (e) {
-      optionsProcessors.forEach((OptionsProcessor p) => p.onError(e));
-    }
-  }
-
   void _processPlugins() {
     List<Plugin> plugins = <Plugin>[];
     plugins.addAll(AnalysisEngine.instance.requiredPlugins);
@@ -611,6 +558,41 @@
     _isBatch = options.shouldBatch;
   }
 
+  static void setAnalysisContextOptions(
+      AnalysisContext context,
+      CommandLineOptions options,
+      void configureContextOptions(AnalysisOptionsImpl contextOptions)) {
+    Map<String, String> definedVariables = options.definedVariables;
+    if (!definedVariables.isEmpty) {
+      DeclaredVariables declaredVariables = context.declaredVariables;
+      definedVariables.forEach((String variableName, String value) {
+        declaredVariables.define(variableName, value);
+      });
+    }
+
+    if (options.log) {
+      AnalysisEngine.instance.logger = new StdLogger();
+    }
+
+    // Prepare context options.
+    AnalysisOptionsImpl contextOptions = new AnalysisOptionsImpl();
+    contextOptions.hint = !options.disableHints;
+    contextOptions.enableStrictCallChecks = options.enableStrictCallChecks;
+    contextOptions.enableSuperMixins = options.enableSuperMixins;
+    contextOptions.generateImplicitErrors = options.showPackageWarnings;
+    contextOptions.generateSdkErrors = options.showSdkWarnings;
+    contextOptions.lint = options.lints;
+    contextOptions.strongMode = options.strongMode;
+    configureContextOptions(contextOptions);
+
+    // Set context options.
+    context.analysisOptions = contextOptions;
+    context.sourceFactory.dartSdk.context.analysisOptions = contextOptions;
+
+    // Process analysis options file (and notify all interested parties).
+    _processAnalysisOptions(context, options);
+  }
+
   /// Perform a deep comparison of two string maps.
   static bool _equalMaps(Map<String, String> m1, Map<String, String> m2) {
     if (m1.length != m2.length) {
@@ -624,9 +606,53 @@
     return true;
   }
 
+  static fileSystem.File _getOptionsFile(CommandLineOptions options) {
+    fileSystem.File file;
+    String filePath = options.analysisOptionsFile;
+    if (filePath != null) {
+      file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
+      if (!file.exists) {
+        printAndFail('Options file not found: $filePath',
+            exitCode: ErrorSeverity.ERROR.ordinal);
+      }
+    } else {
+      filePath = AnalysisEngine.ANALYSIS_OPTIONS_FILE;
+      file = PhysicalResourceProvider.INSTANCE.getFile(filePath);
+    }
+    return file;
+  }
+
   /// Convert [sourcePath] into an absolute path.
   static String _normalizeSourcePath(String sourcePath) =>
       path.normalize(new File(sourcePath).absolute.path);
+
+  static void _processAnalysisOptions(
+      AnalysisContext context, CommandLineOptions options) {
+    fileSystem.File file = _getOptionsFile(options);
+    List<OptionsProcessor> optionsProcessors =
+        AnalysisEngine.instance.optionsPlugin.optionsProcessors;
+    try {
+      AnalysisOptionsProvider analysisOptionsProvider =
+          new AnalysisOptionsProvider();
+      Map<String, YamlNode> optionMap =
+          analysisOptionsProvider.getOptionsFromFile(file);
+      optionsProcessors.forEach(
+          (OptionsProcessor p) => p.optionsProcessed(context, optionMap));
+
+      // Fill in lint rule defaults in case lints are enabled and rules are
+      // not specified in an options file.
+      if (options.lints && !containsLintRuleEntry(optionMap)) {
+        setLints(context, linterPlugin.contributedRules);
+      }
+
+      // Ask engine to further process options.
+      if (optionMap != null) {
+        configureContextOptions(context, optionMap);
+      }
+    } on Exception catch (e) {
+      optionsProcessors.forEach((OptionsProcessor p) => p.onError(e));
+    }
+  }
 }
 
 /// Provides a framework to read command line options from stdin and feed them
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 2bc48b9..732fc63 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -74,6 +74,21 @@
   /// Whether to use machine format for error display
   final bool machineFormat;
 
+  /// Whether to use the whole package analysis mode.
+  final bool packageMode;
+
+  /// The path of the root folder of the package to analyze.
+  final String packageModePath;
+
+  /// The name of the package being analyzed.
+  final String packageName;
+
+  /// Mapping of package names to package summary file paths.
+  final Map<String, String> packageSummaryInputs;
+
+  /// The path to find the package summary.
+  final String packageSummaryOutput;
+
   /// The path to the package root
   final String packageRootPath;
 
@@ -106,7 +121,7 @@
   CommandLineOptions._fromArgs(
       ArgResults args, Map<String, String> definedVariables)
       : dartSdkPath = args['dart-sdk'],
-        this.definedVariables = definedVariables,
+        definedVariables = definedVariables,
         analysisOptionsFile = args['options'],
         disableHints = args['no-hints'],
         displayVersion = args['version'],
@@ -119,6 +134,11 @@
         lints = args['lints'],
         log = args['log'],
         machineFormat = args['machine'] || args['format'] == 'machine',
+        packageMode = args['package-mode'],
+        packageModePath = args['package-mode-path'],
+        packageName = args['package-name'],
+        packageSummaryInputs = _parsePackageSummaryInputs(args),
+        packageSummaryOutput = args['package-summary-output'],
         packageConfigPath = args['packages'],
         packageRootPath = args['package-root'],
         perfReport = args['x-perf-report'],
@@ -267,6 +287,33 @@
           allowMultiple: true,
           splitCommas: false)
       //
+      // Package analysis mode and summary.
+      //
+      ..addFlag('package-mode',
+          help: 'Enable the whole package analysis mode. '
+              'Exactly one input path must be specified, which must be a path '
+              'to the folder with a Pub package.',
+          defaultsTo: false,
+          negatable: false,
+          hide: true)
+      ..addOption('package-mode-path',
+          help: 'The path of the root folder of the package to analyze.',
+          hide: true)
+      ..addOption('package-name',
+          help: 'The name of the package to analyze, as it is used by clients.',
+          hide: true)
+      ..addOption('package-summary-input',
+          help: '--package-summary-input=packageName,/path/to/package.sum '
+              'specifies the summary file that contains information about '
+              'every library of the specified package.',
+          allowMultiple: true,
+          splitCommas: false,
+          hide: true)
+      ..addOption('package-summary-output',
+          help: 'Specifies the path to the file where the summary information '
+              'about the package should be written to.',
+          hide: true)
+      //
       // Hidden flags.
       //
       ..addFlag('enable-async',
@@ -352,6 +399,27 @@
     }
   }
 
+  /// Parse the `--package-summary-input` arguments into a Map of package
+  /// names to summary paths.
+  static Map<String, String> _parsePackageSummaryInputs(ArgResults args) {
+    Map<String, String> result = <String, String>{};
+    List<String> argList = args['package-summary-input'];
+    for (String arg in argList) {
+      int index = arg.indexOf(',');
+      if (index == -1) {
+        errorSink.writeln(
+            'The syntax is --package-summary-input=packageName,/path/to/pkg.sum');
+        errorSink.writeln('No comma found in: $arg');
+        exitHandler(15);
+        return null; // Only reachable in testing.
+      }
+      String packageName = arg.substring(0, index);
+      String summaryPath = arg.substring(index + 1);
+      result[packageName] = summaryPath;
+    }
+    return result;
+  }
+
   static _showUsage(parser) {
     errorSink
         .writeln('Usage: $_binaryName [options...] <libraries to analyze...>');
@@ -409,7 +477,8 @@
       String defaultsTo,
       void callback(value),
       bool allowMultiple: false,
-      bool splitCommas}) {
+      bool splitCommas,
+      bool hide: false}) {
     _knownFlags.add(name);
     _parser.addOption(name,
         abbr: abbr,
@@ -419,7 +488,8 @@
         defaultsTo: defaultsTo,
         callback: callback,
         allowMultiple: allowMultiple,
-        splitCommas: splitCommas);
+        splitCommas: splitCommas,
+        hide: hide);
   }
 
   /// Generates a string displaying usage information for the defined options.
diff --git a/pkg/analyzer_cli/lib/src/package_analyzer.dart b/pkg/analyzer_cli/lib/src/package_analyzer.dart
new file mode 100644
index 0000000..0bad260
--- /dev/null
+++ b/pkg/analyzer_cli/lib/src/package_analyzer.dart
@@ -0,0 +1,427 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.src.package_analyzer;
+
+import 'dart:convert';
+import 'dart:core' hide Resource;
+import 'dart:io' as io;
+
+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/source/package_map_resolver.dart';
+import 'package:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/resolver.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';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/resynthesize.dart';
+import 'package:analyzer/src/summary/summarize_elements.dart';
+import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:analyzer/task/model.dart';
+import 'package:analyzer_cli/src/analyzer_impl.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/src/error_formatter.dart';
+import 'package:analyzer_cli/src/options.dart';
+import 'package:crypto/crypto.dart';
+import 'package:path/path.dart' as pathos;
+
+/**
+ * If [uri] has the `package` scheme in form of `package:pkg/file.dart`,
+ * return the `pkg` name.  Otherwise return `null`.
+ */
+String getPackageName(Uri uri) {
+  if (uri.scheme != 'package') {
+    return null;
+  }
+  String path = uri.path;
+  int index = path.indexOf('/');
+  if (index == -1) {
+    return null;
+  }
+  return path.substring(0, index);
+}
+
+/**
+ * A concrete resynthesizer that serves summaries from given file paths.
+ */
+class FileBasedSummaryResynthesizer extends SummaryResynthesizer {
+  final Map<String, UnlinkedUnit> unlinkedMap = <String, UnlinkedUnit>{};
+  final Map<String, LinkedLibrary> linkedMap = <String, LinkedLibrary>{};
+
+  FileBasedSummaryResynthesizer(
+      SummaryResynthesizer parent,
+      AnalysisContext context,
+      TypeProvider typeProvider,
+      SourceFactory sourceFactory,
+      bool strongMode,
+      List<String> summaryPaths)
+      : super(parent, context, typeProvider, sourceFactory, strongMode) {
+    summaryPaths.forEach(_fillMaps);
+  }
+
+  @override
+  LinkedLibrary getLinkedSummary(String uri) {
+    return linkedMap[uri];
+  }
+
+  @override
+  UnlinkedUnit getUnlinkedSummary(String uri) {
+    return unlinkedMap[uri];
+  }
+
+  @override
+  bool hasLibrarySummary(String uri) {
+    return linkedMap.containsKey(uri);
+  }
+
+  void _fillMaps(String path) {
+    io.File file = new io.File(path);
+    List<int> buffer = file.readAsBytesSync();
+    PackageBundle bundle = new PackageBundle.fromBuffer(buffer);
+    for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
+      unlinkedMap[bundle.unlinkedUnitUris[i]] = bundle.unlinkedUnits[i];
+    }
+    for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
+      linkedMap[bundle.linkedLibraryUris[i]] = bundle.linkedLibraries[i];
+    }
+  }
+}
+
+/**
+ * The [ResultProvider] that provides results from input package summaries.
+ */
+class InputPackagesResultProvider extends ResultProvider {
+  final InternalAnalysisContext context;
+  final Map<String, String> packageSummaryInputs;
+
+  FileBasedSummaryResynthesizer resynthesizer;
+  SummaryResultProvider sdkProvider;
+
+  InputPackagesResultProvider(this.context, this.packageSummaryInputs) {
+    InternalAnalysisContext sdkContext = context.sourceFactory.dartSdk.context;
+    sdkProvider = sdkContext.resultProvider;
+    // Set the type provider to prevent the context from computing it.
+    context.typeProvider = sdkContext.typeProvider;
+    // Create a chained resynthesizer.
+    resynthesizer = new FileBasedSummaryResynthesizer(
+        sdkProvider.resynthesizer,
+        context,
+        context.typeProvider,
+        context.sourceFactory,
+        context.analysisOptions.strongMode,
+        packageSummaryInputs.values.toList());
+  }
+
+  bool compute(CacheEntry entry, ResultDescriptor result) {
+    if (sdkProvider.compute(entry, result)) {
+      return true;
+    }
+    AnalysisTarget target = entry.target;
+    // Only library results are supported for now.
+    if (target is Source) {
+      Uri uri = target.uri;
+      // We know how to server results to input packages.
+      String sourcePackageName = getPackageName(uri);
+      if (!packageSummaryInputs.containsKey(sourcePackageName)) {
+        return false;
+      }
+      // Provide known results.
+      String uriString = uri.toString();
+      if (result == LIBRARY_ELEMENT1 ||
+          result == LIBRARY_ELEMENT2 ||
+          result == LIBRARY_ELEMENT3 ||
+          result == LIBRARY_ELEMENT4 ||
+          result == LIBRARY_ELEMENT5 ||
+          result == LIBRARY_ELEMENT6 ||
+          result == LIBRARY_ELEMENT7 ||
+          result == LIBRARY_ELEMENT8 ||
+          result == LIBRARY_ELEMENT ||
+          false) {
+        LibraryElement libraryElement =
+            resynthesizer.getLibraryElement(uriString);
+        entry.setValue(result, libraryElement, TargetedResult.EMPTY_LIST);
+        return true;
+      } else if (result == READY_LIBRARY_ELEMENT2 ||
+          result == READY_LIBRARY_ELEMENT5 ||
+          result == READY_LIBRARY_ELEMENT6) {
+        entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+        return true;
+      } else if (result == SOURCE_KIND) {
+        if (resynthesizer.linkedMap.containsKey(uriString)) {
+          entry.setValue(result, SourceKind.LIBRARY, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        if (resynthesizer.unlinkedMap.containsKey(uriString)) {
+          entry.setValue(result, SourceKind.PART, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        return false;
+      }
+    }
+    return false;
+  }
+}
+
+/**
+ * The [UriResolver] that knows about sources that are parts of packages which
+ * are served from their summaries.
+ */
+class InSummaryPackageUriResolver extends UriResolver {
+  final Map<String, String> packageSummaryInputs;
+
+  InSummaryPackageUriResolver(this.packageSummaryInputs);
+
+  @override
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+    actualUri ??= uri;
+    String packageName = getPackageName(actualUri);
+    if (packageSummaryInputs.containsKey(packageName)) {
+      return new InSummarySource(actualUri);
+    }
+    return null;
+  }
+}
+
+/**
+ * A placeholder of a source that is part of a package whose analysis results
+ * are served from its summary.  This source uses its URI as [fullName] and has
+ * empty contents.
+ */
+class InSummarySource extends Source {
+  final Uri uri;
+
+  InSummarySource(this.uri);
+
+  @override
+  TimestampedData<String> get contents => new TimestampedData<String>(0, '');
+
+  @override
+  String get encoding => uri.toString();
+
+  @override
+  String get fullName => encoding;
+
+  @override
+  bool get isInSystemLibrary => false;
+
+  @override
+  int get modificationStamp => 0;
+
+  @override
+  String get shortName => pathos.basename(fullName);
+
+  @override
+  UriKind get uriKind => UriKind.PACKAGE_URI;
+
+  @override
+  bool exists() => true;
+
+  @override
+  Uri resolveRelativeUri(Uri relativeUri) {
+    Uri baseUri = uri;
+    return baseUri.resolveUri(relativeUri);
+  }
+
+  @override
+  String toString() => uri.toString();
+}
+
+/**
+ * The hermetic whole package analyzer.
+ */
+class PackageAnalyzer {
+  final CommandLineOptions options;
+
+  String packagePath;
+  String packageLibPath;
+
+  final ResourceProvider resourceProvider = PhysicalResourceProvider.INSTANCE;
+  InternalAnalysisContext context;
+  final List<Source> explicitSources = <Source>[];
+
+  final List<String> linkedLibraryUris = <String>[];
+  final List<LinkedLibraryBuilder> linkedLibraries = <LinkedLibraryBuilder>[];
+  final List<String> unlinkedUnitUris = <String>[];
+  final List<UnlinkedUnitBuilder> unlinkedUnits = <UnlinkedUnitBuilder>[];
+  final List<String> unlinkedUnitHashes = <String>[];
+
+  PackageAnalyzer(this.options);
+
+  /**
+   * Perform package analysis according to the given [options].
+   */
+  ErrorSeverity analyze() {
+    packagePath = options.packageModePath;
+    packageLibPath = resourceProvider.pathContext.join(packagePath, 'lib');
+    if (packageLibPath == null) {
+      errorSink.writeln('--package-mode-path must be set to the root '
+          'folder of the package to analyze.');
+      io.exitCode = ErrorSeverity.ERROR.ordinal;
+      return ErrorSeverity.ERROR;
+    }
+
+    // Write the progress message.
+    if (!options.machineFormat) {
+      outSink.writeln("Analyzing sources ${options.sourceFiles}...");
+    }
+
+    // Prepare the analysis context.
+    _createContext();
+
+    // Add sources.
+    ChangeSet changeSet = new ChangeSet();
+    for (String path in options.sourceFiles) {
+      if (AnalysisEngine.isDartFileName(path)) {
+        path = resourceProvider.pathContext.absolute(path);
+        File file = resourceProvider.getFile(path);
+        if (!file.exists) {
+          errorSink.writeln('File not found: $path');
+          io.exitCode = ErrorSeverity.ERROR.ordinal;
+          return ErrorSeverity.ERROR;
+        }
+        Source source = _createSourceInContext(file);
+        explicitSources.add(source);
+        changeSet.addedSource(source);
+      }
+    }
+    context.applyChanges(changeSet);
+
+    // Perform full analysis.
+    while (true) {
+      AnalysisResult analysisResult = context.performAnalysisTask();
+      if (!analysisResult.hasMoreWork) {
+        break;
+      }
+    }
+
+    // Write summary for Dart libraries.
+    if (options.packageSummaryOutput != null) {
+      for (Source source in context.librarySources) {
+        if (pathos.isWithin(packageLibPath, source.fullName)) {
+          LibraryElement libraryElement = context.getLibraryElement(source);
+          if (libraryElement != null) {
+            _serializeSingleLibrary(libraryElement);
+          }
+        }
+      }
+      // Write the whole package bundle.
+      PackageBundleBuilder sdkBundle = new PackageBundleBuilder(
+          linkedLibraryUris: linkedLibraryUris,
+          linkedLibraries: linkedLibraries,
+          unlinkedUnitUris: unlinkedUnitUris,
+          unlinkedUnits: unlinkedUnits,
+          unlinkedUnitHashes: unlinkedUnitHashes);
+      io.File file = new io.File(options.packageSummaryOutput);
+      file.writeAsBytesSync(sdkBundle.toBuffer(), mode: io.FileMode.WRITE_ONLY);
+    }
+
+    // Process errors.
+    _printErrors();
+    return _computeMaxSeverity();
+  }
+
+  ErrorSeverity _computeMaxSeverity() {
+    ErrorSeverity maxSeverity = ErrorSeverity.NONE;
+    for (Source source in explicitSources) {
+      AnalysisErrorInfo errorInfo = context.getErrors(source);
+      for (AnalysisError error in errorInfo.errors) {
+        ProcessedSeverity processedSeverity =
+            AnalyzerImpl.processError(error, options, context);
+        if (processedSeverity != null) {
+          maxSeverity = maxSeverity.max(processedSeverity.severity);
+        }
+      }
+    }
+    return maxSeverity;
+  }
+
+  void _createContext() {
+    DirectoryBasedDartSdk sdk = DirectoryBasedDartSdk.defaultSdk;
+    sdk.useSummary = true;
+
+    // Create the context.
+    context = AnalysisEngine.instance.createAnalysisContext();
+    context.typeProvider = sdk.context.typeProvider;
+    context.sourceFactory = new SourceFactory(<UriResolver>[
+      new DartUriResolver(sdk),
+      new InSummaryPackageUriResolver(options.packageSummaryInputs),
+      new PackageMapUriResolver(resourceProvider, <String, List<Folder>>{
+        options.packageName: <Folder>[
+          resourceProvider.getFolder(packageLibPath)
+        ],
+      }),
+      new FileUriResolver()
+    ]);
+
+    // Set context options.
+    Driver.setAnalysisContextOptions(
+        context, options, (AnalysisOptionsImpl contextOptions) {});
+
+    // Set the result provider.
+    context.resultProvider =
+        new InputPackagesResultProvider(context, options.packageSummaryInputs);
+  }
+
+  /**
+   * Create and return a source representing the given [file].
+   */
+  Source _createSourceInContext(File file) {
+    Source source = file.createSource();
+    if (context == null) {
+      return source;
+    }
+    Uri uri = context.sourceFactory.restoreUri(source);
+    return file.createSource(uri);
+  }
+
+  /**
+   * Compute a hash of the given file contents.
+   */
+  String _hash(String contents) {
+    MD5 md5 = new MD5();
+    md5.add(UTF8.encode(contents));
+    return CryptoUtils.bytesToHex(md5.close());
+  }
+
+  /**
+   * Print errors for all explicit sources.
+   */
+  void _printErrors() {
+    StringSink sink = options.machineFormat ? errorSink : outSink;
+    ErrorFormatter formatter = new ErrorFormatter(
+        sink,
+        options,
+        (AnalysisError error) =>
+            AnalyzerImpl.processError(error, options, context));
+    for (Source source in explicitSources) {
+      AnalysisErrorInfo errorInfo = context.getErrors(source);
+      formatter.formatErrors([errorInfo]);
+    }
+  }
+
+  /**
+   * Serialize the library with the given [element].
+   */
+  void _serializeSingleLibrary(LibraryElement element) {
+    String uri = element.source.uri.toString();
+    LibrarySerializationResult libraryResult =
+        serializeLibrary(element, context.typeProvider, options.strongMode);
+    linkedLibraryUris.add(uri);
+    linkedLibraries.add(libraryResult.linked);
+    unlinkedUnitUris.addAll(libraryResult.unitUris);
+    unlinkedUnits.addAll(libraryResult.unlinkedUnits);
+    for (Source source in libraryResult.unitSources) {
+      unlinkedUnitHashes.add(_hash(source.contents.data));
+    }
+  }
+}
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index 0fe04f6..6e59161 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -14,5 +14,6 @@
   plugin: ^0.1.0
   yaml: ^2.1.2
 dev_dependencies:
+  test_reflective_loader: '>=0.0.3 <0.1.0'
   typed_mock: '>=0.0.4 <1.0.0'
   unittest: '>=0.9.0 <0.12.0'
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 900747b..1c6aa76 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -4,8 +4,12 @@
 
 library analyzer_cli.test.options;
 
+import 'dart:io';
+
+import 'package:analyzer_cli/src/driver.dart';
 import 'package:analyzer_cli/src/options.dart';
 import 'package:args/args.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:unittest/unittest.dart';
 
 main() {
@@ -26,7 +30,9 @@
         expect(options.ignoreUnrecognizedFlags, isFalse);
         expect(options.log, isFalse);
         expect(options.machineFormat, isFalse);
+        expect(options.packageMode, isFalse);
         expect(options.packageRootPath, isNull);
+        expect(options.packageSummaryInputs, isEmpty);
         expect(options.shouldBatch, isFalse);
         expect(options.showPackageWarnings, isFalse);
         expect(options.showSdkWarnings, isFalse);
@@ -165,8 +171,8 @@
       });
 
       test('strong mode', () {
-        CommandLineOptions options = CommandLineOptions
-            .parse(['--strong', 'foo.dart']);
+        CommandLineOptions options =
+            CommandLineOptions.parse(['--strong', 'foo.dart']);
         expect(options.strongMode, isTrue);
       });
 
@@ -187,4 +193,85 @@
       });
     });
   });
+  defineReflectiveTests(CommandLineOptionsTest);
+}
+
+@reflectiveTest
+class AbstractStatusTest {
+  int lastExitHandlerCode;
+  StringBuffer outStringBuffer = new StringBuffer();
+  StringBuffer errorStringBuffer = new StringBuffer();
+
+  StringSink savedOutSink, savedErrorSink;
+  int savedExitCode;
+  ExitHandler savedExitHandler;
+
+  setUp() {
+    savedOutSink = outSink;
+    savedErrorSink = errorSink;
+    savedExitHandler = exitHandler;
+    savedExitCode = exitCode;
+    exitHandler = (int code) {
+      lastExitHandlerCode = code;
+    };
+    outSink = outStringBuffer;
+    errorSink = errorStringBuffer;
+  }
+
+  tearDown() {
+    outSink = savedOutSink;
+    errorSink = savedErrorSink;
+    exitCode = savedExitCode;
+    exitHandler = savedExitHandler;
+  }
+}
+
+@reflectiveTest
+class CommandLineOptionsTest extends AbstractStatusTest {
+  CommandLineOptions options;
+
+  test_packageMode() {
+    _parse(['--package-mode', '/path/to/pkg']);
+    expect(options.packageMode, isTrue);
+    print(options.packageSummaryInputs);
+  }
+
+  test_packageSummaryInput() {
+    _parse([
+      '--package-mode',
+      '--package-summary-input=aaa,/path/to/aaa.sum',
+      '--package-summary-input=long.package.bbb,/path/to/bbb.sum',
+      '/path/to/pkg'
+    ]);
+    expect(options.packageMode, isTrue);
+    Map<String, String> map = options.packageSummaryInputs;
+    expect(map, hasLength(2));
+    expect(map, containsPair('aaa', '/path/to/aaa.sum'));
+    expect(map, containsPair('long.package.bbb', '/path/to/bbb.sum'));
+  }
+
+  test_packageSummaryInput_noComma() {
+    _parse([
+      '--package-mode',
+      '--package-summary-input=noCommaInMapping',
+      '/path/to/pkg'
+    ]);
+    expect(lastExitHandlerCode, 15);
+    expect(errorStringBuffer.toString(), contains('--package-summary-input'));
+    expect(errorStringBuffer.toString(), contains('noCommaInMapping'));
+  }
+
+  test_packageSummaryOutput() {
+    _parse([
+      '--package-mode',
+      '--package-summary-output=/path/to/output.sum',
+      '/path/to/pkg'
+    ]);
+    expect(options.packageMode, isTrue);
+    expect(options.packageSummaryOutput, '/path/to/output.sum');
+  }
+
+  void _parse(List<String> args) {
+    options = CommandLineOptions.parse(args);
+  }
 }
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index e6b4f4c..3df2ba4 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1797,9 +1797,8 @@
 
         bool sameToken(Token token, Token sought) {
           if (token == sought) return true;
-          if (token.stringValue == '>>' ||
-              token.stringValue == '>>>') {
-            // `>>` and `>>>` are converted to `>` in the parser when needed.
+          if (token.stringValue == '>>') {
+            // `>>` is converted to `>` in the parser when needed.
             return sought.stringValue == '>' &&
                 token.charOffset <= sought.charOffset &&
                 sought.charOffset < token.charEnd;
diff --git a/pkg/compiler/lib/src/cps_ir/inline.dart b/pkg/compiler/lib/src/cps_ir/inline.dart
index 28ea3d5..d6096af 100644
--- a/pkg/compiler/lib/src/cps_ir/inline.dart
+++ b/pkg/compiler/lib/src/cps_ir/inline.dart
@@ -18,6 +18,7 @@
     FlatTypeMask, ForwardingTypeMask, TypeMask, UnionTypeMask;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector;
+import 'package:js_ast/js_ast.dart' as js;
 
 /// Inlining stack entries.
 ///
@@ -259,8 +260,32 @@
       --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;
 
diff --git a/pkg/compiler/lib/src/cps_ir/optimizers.dart b/pkg/compiler/lib/src/cps_ir/optimizers.dart
index 337ff32..2b248fe 100644
--- a/pkg/compiler/lib/src/cps_ir/optimizers.dart
+++ b/pkg/compiler/lib/src/cps_ir/optimizers.dart
@@ -25,7 +25,7 @@
 export 'inline.dart' show Inliner;
 export 'eagerly_load_statics.dart' show EagerlyLoadStatics;
 export 'loop_invariant_branch.dart' show LoopInvariantBranchMotion;
-export 'duplicate_branch.dart' show PathBasedOptimizer;
+export 'path_based_optimizer.dart' show PathBasedOptimizer;
 export 'use_field_initializers.dart' show UseFieldInitializers;
 export 'parent_visitor.dart' show ParentVisitor;
 
diff --git a/pkg/compiler/lib/src/cps_ir/duplicate_branch.dart b/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart
similarity index 98%
rename from pkg/compiler/lib/src/cps_ir/duplicate_branch.dart
rename to pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart
index 26244a4..6f9fac5 100644
--- a/pkg/compiler/lib/src/cps_ir/duplicate_branch.dart
+++ b/pkg/compiler/lib/src/cps_ir/path_based_optimizer.dart
@@ -1,7 +1,7 @@
 // Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-library dart2js.cps_ir.duplicate_branch; // FIXME: Rename file.
+library dart2js.cps_ir.path_based_optimizer;
 
 import 'cps_ir_nodes.dart';
 import 'optimizers.dart';
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index a9a99fa..00cbfb1 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -44,7 +44,10 @@
   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,
@@ -53,9 +56,11 @@
       anything = new AbstractConstantValue.nonConstant(
           functionCompiler.typeSystem.dynamicType),
       nullValue = new AbstractConstantValue.constantValue(
-          new NullConstantValue(), new TypeMask.empty());
-
-  final AbstractConstantValue nothing = new AbstractConstantValue.nothing();
+          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);
@@ -559,21 +564,41 @@
 
   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);
   }
 
@@ -1245,6 +1270,22 @@
       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.definition,
+          renameToOptimizedSelector(name),
+          node.mask,
+          node.arguments.map((ref) => ref.definition).toList(),
+          sourceInformation: node.sourceInformation,
+          callingConvention: node.callingConvention);
+    }
+
     TypeMask successType =
         typeSystem.receiverTypeFor(node.selector, node.dartReceiver.type);
 
@@ -1301,10 +1342,20 @@
           // Try to insert a shift-right operator. JavaScript's right shift is
           // consistent with Dart's only for left operands in the unsigned
           // 32-bit range.
-          if (opname == '>>' &&
-              lattice.isDefinitelyUint32(left, allowNull: true) &&
-              lattice.isDefinitelyIntInRange(right, min: 0, max: 31)) {
-            return makeBinary(BuiltinOperator.NumShr, guard: checkIsNumber);
+          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.
@@ -3299,6 +3350,17 @@
   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;
diff --git a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
index 2aa258a..13d4c95 100644
--- a/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/generated/shared_messages.dart
@@ -17,18 +17,107 @@
     "Const constructor or factory can't have a body.",
     howToFix: "Remove the 'const' keyword or the body.",
     examples: const [
-      r'''
+      r"""
          class C {
            const C() {}
          }
 
-         main() => new C();''',
-      r'''
+         main() => new C();""",
+      r"""
          class C {
            const factory C() {}
          }
 
-         main() => new C();''',
+         main() => new C();""",
+    ]
+  ),  // Generated. Don't edit.
+  MessageKind.EXTRANEOUS_MODIFIER: const MessageTemplate(
+    MessageKind.EXTRANEOUS_MODIFIER,
+    "Can't have modifier '#{modifier}' here.",
+    howToFix: "Try removing '#{modifier}'.",
+    examples: const [
+      "var String foo; main(){}",
+      "var set foo; main(){}",
+      "var final foo; main(){}",
+      "var var foo; main(){}",
+      "var const foo; main(){}",
+      "var abstract foo; main(){}",
+      "var static foo; main(){}",
+      "var external foo; main(){}",
+      "get var foo; main(){}",
+      "set var foo; main(){}",
+      "final var foo; main(){}",
+      "var var foo; main(){}",
+      "const var foo; main(){}",
+      "abstract var foo; main(){}",
+      "static var foo; main(){}",
+      "external var foo; main(){}",
+    ]
+  ),  // Generated. Don't edit.
+  MessageKind.EXTRANEOUS_MODIFIER_REPLACE: const MessageTemplate(
+    MessageKind.EXTRANEOUS_MODIFIER_REPLACE,
+    "Can't have modifier '#{modifier}' here.",
+    howToFix: "Try replacing modifier '#{modifier}' with 'var', 'final', or a type.",
+    examples: const [
+      "set foo; main(){}",
+      "abstract foo; main(){}",
+      "static foo; main(){}",
+      "external foo; main(){}",
+    ]
+  ),  // Generated. Don't edit.
+  MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE: const MessageTemplate(
+    MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE,
+    "Constructors can't have a return type",
+    howToFix: "Try removing the return type.",
+    examples: const [
+      "class A { int A() {} } main() { new A(); }",
+    ]
+  ),  // Generated. Don't edit.
+  MessageKind.MISSING_EXPRESSION_IN_THROW: const MessageTemplate(
+    MessageKind.MISSING_EXPRESSION_IN_THROW,
+    "Missing expression after 'throw'.",
+    howToFix: "Did you mean 'rethrow'?",
+    examples: const [
+      "main() { throw; }",
+      "main() { try { throw 0; } catch(e) { throw; } }",
+    ]
+  ),  // Generated. Don't edit.
+  MessageKind.RETHROW_OUTSIDE_CATCH: const MessageTemplate(
+    MessageKind.RETHROW_OUTSIDE_CATCH,
+    "Rethrow must be inside of catch clause",
+    howToFix: "Try moving the expression into a catch clause, or using a 'throw' expression.",
+    examples: const [
+      "main() { rethrow; }",
+    ]
+  ),  // Generated. Don't edit.
+  MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR: const MessageTemplate(
+    MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR,
+    "Constructors can't return values.",
+    howToFix: "Try removing the return statement or using a factory constructor.",
+    examples: const [
+      r"""
+        class C {
+          C() {
+            return 1;
+          }
+        }
+
+        main() => new C();""",
+    ]
+  ),  // Generated. Don't edit.
+  MessageKind.RETURN_IN_GENERATOR: const MessageTemplate(
+    MessageKind.RETURN_IN_GENERATOR,
+    "Can't return a value from a generator function (using the '#{modifier}' modifier).",
+    howToFix: "Try removing the value, replacing 'return' with 'yield' or changing the method body modifier",
+    examples: const [
+      r"""
+        foo() async* { return 0; }
+        main() => foo();
+        """,
+      r"""
+        foo() sync* { return 0; }
+        main() => foo();
+        """,
     ]
   ),  // Generated. Don't edit.
 };
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index 2679c75..84e9cc2 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -136,7 +136,7 @@
   CANNOT_RESOLVE_IN_INITIALIZER,
   CANNOT_RESOLVE_SETTER,
   CANNOT_RESOLVE_TYPE,
-  CANNOT_RETURN_FROM_CONSTRUCTOR,
+  RETURN_IN_GENERATIVE_CONSTRUCTOR,
   CLASS_NAME_EXPECTED,
   COMPILER_CRASHED,
   COMPLEX_RETURNING_NSM,
@@ -428,7 +428,7 @@
   THIS_IS_THE_METHOD,
   THIS_IS_THE_PART_OF_TAG,
   THIS_PROPERTY,
-  THROW_WITHOUT_EXPRESSION,
+  RETHROW_OUTSIDE_CATCH,
   TOP_LEVEL_VARIABLE_DECLARED_STATIC,
   TYPE_ARGUMENT_COUNT_MISMATCH,
   TYPE_VARIABLE_IN_CONSTANT,
@@ -453,7 +453,7 @@
   UNSUPPORTED_EQ_EQ_EQ,
   UNSUPPORTED_LITERAL_SYMBOL,
   UNSUPPORTED_PREFIX_PLUS,
-  UNSUPPORTED_THROW_WITHOUT_EXP,
+  MISSING_EXPRESSION_IN_THROW,
   UNTERMINATED_COMMENT,
   UNTERMINATED_STRING,
   UNTERMINATED_TOKEN,
@@ -476,7 +476,7 @@
 // TODO(johnnniwinther): For Infos, consider adding a reference to the
 // error/warning/hint that they belong to.
 class MessageTemplate {
-  final dynamic/*MessageKind | SharedMessageKind*/ kind;
+  final MessageKind kind;
 
   /// Should describe what is wrong and why.
   final String template;
@@ -1149,11 +1149,6 @@
         const MessageTemplate(MessageKind.OPTIONAL_PARAMETER_IN_CATCH,
           "Cannot use optional parameters in catch."),
 
-      MessageKind.THROW_WITHOUT_EXPRESSION:
-        const MessageTemplate(MessageKind.THROW_WITHOUT_EXPRESSION,
-          "Cannot use re-throw outside of catch block "
-          "(expression expected after 'throw')."),
-
       MessageKind.UNBOUND_LABEL:
         const MessageTemplate(MessageKind.UNBOUND_LABEL,
           "Cannot resolve label '#{labelName}'."),
@@ -1847,23 +1842,6 @@
         const MessageTemplate(MessageKind.OPERATOR_NAMED_PARAMETERS,
           "Operator '#{operatorName}' cannot have named parameters."),
 
-      MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE:
-        const MessageTemplate(MessageKind.CONSTRUCTOR_WITH_RETURN_TYPE,
-          "Cannot have return type for constructor."),
-
-      MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR:
-        const MessageTemplate(MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR,
-          "Constructors can't return values.",
-          howToFix: "Remove the return statement or use a factory constructor.",
-          examples: const ["""
-class C {
-  C() {
-    return 1;
-  }
-}
-
-main() => new C();"""]),
-
       MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER:
         const MessageTemplate(MessageKind.ILLEGAL_FINAL_METHOD_MODIFIER,
           "Cannot have final modifier on method."),
@@ -2414,11 +2392,6 @@
               "main() => +2;  // No longer a valid way to write '2'"
           ]),
 
-      MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP:
-        const MessageTemplate(MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP,
-          "No expression after 'throw'. "
-          "Did you mean 'rethrow'?"),
-
       MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX:
         const MessageTemplate(MessageKind.DEPRECATED_TYPEDEF_MIXIN_SYNTAX,
           "'typedef' not allowed here. ",
@@ -2594,42 +2567,6 @@
           // Don't know how to fix since the underlying error is unknown.
           howToFix: DONT_KNOW_HOW_TO_FIX),
 
-      MessageKind.EXTRANEOUS_MODIFIER:
-        const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER,
-          "Can't have modifier '#{modifier}' here.",
-          howToFix: "Try removing '#{modifier}'.",
-          examples: const [
-              "var String foo; main(){}",
-              // "var get foo; main(){}",
-              "var set foo; main(){}",
-              "var final foo; main(){}",
-              "var var foo; main(){}",
-              "var const foo; main(){}",
-              "var abstract foo; main(){}",
-              "var static foo; main(){}",
-              "var external foo; main(){}",
-              "get var foo; main(){}",
-              "set var foo; main(){}",
-              "final var foo; main(){}",
-              "var var foo; main(){}",
-              "const var foo; main(){}",
-              "abstract var foo; main(){}",
-              "static var foo; main(){}",
-              "external var foo; main(){}"]),
-
-      MessageKind.EXTRANEOUS_MODIFIER_REPLACE:
-        const MessageTemplate(MessageKind.EXTRANEOUS_MODIFIER_REPLACE,
-          "Can't have modifier '#{modifier}' here.",
-          howToFix:
-            "Try replacing modifier '#{modifier}' with 'var', 'final', "
-            "or a type.",
-          examples: const [
-              // "get foo; main(){}",
-              "set foo; main(){}",
-              "abstract foo; main(){}",
-              "static foo; main(){}",
-              "external foo; main(){}"]),
-
       MessageKind.ABSTRACT_CLASS_INSTANTIATION:
         const MessageTemplate(MessageKind.ABSTRACT_CLASS_INSTANTIATION,
           "Can't instantiate abstract class.",
@@ -3354,23 +3291,6 @@
  var yield;
 }"""]),
 
-      MessageKind.RETURN_IN_GENERATOR:
-        const MessageTemplate(MessageKind.RETURN_IN_GENERATOR,
-          "'return' with a value is not allowed in a method body using the "
-          "'#{modifier}' modifier.",
-          howToFix: "Try removing the value, replacing 'return' with 'yield' "
-                    "or changing the method body modifier.",
-          examples: const [
-"""
-foo() async* { return 0; }
-main() => foo();
-""",
-
-"""
-foo() sync* { return 0; }
-main() => foo();
-"""]),
-
       MessageKind.NATIVE_NOT_SUPPORTED:
         const MessageTemplate(MessageKind.NATIVE_NOT_SUPPORTED,
           "'native' modifier is not supported.",
@@ -3706,7 +3626,7 @@
     assert(() { computeMessage(); return true; });
   }
 
-  dynamic/*MessageKind | SharedMessageKind*/ get kind => template.kind;
+  MessageKind get kind => template.kind;
 
   String computeMessage() {
     if (message == null) {
diff --git a/pkg/compiler/lib/src/parser/node_listener.dart b/pkg/compiler/lib/src/parser/node_listener.dart
index 3a3e91b..b5f1db2 100644
--- a/pkg/compiler/lib/src/parser/node_listener.dart
+++ b/pkg/compiler/lib/src/parser/node_listener.dart
@@ -450,7 +450,7 @@
     pushNode(new Rethrow(throwToken, endToken));
     if (identical(throwToken.stringValue, 'throw')) {
       reporter.reportErrorMessage(
-          throwToken, MessageKind.UNSUPPORTED_THROW_WITHOUT_EXP);
+          throwToken, MessageKind.MISSING_EXPRESSION_IN_THROW);
     }
   }
 
diff --git a/pkg/compiler/lib/src/parser/parser.dart b/pkg/compiler/lib/src/parser/parser.dart
index f2e0577..42e432b 100644
--- a/pkg/compiler/lib/src/parser/parser.dart
+++ b/pkg/compiler/lib/src/parser/parser.dart
@@ -780,10 +780,6 @@
         token = new SymbolToken(GT_INFO, token.charOffset);
         token.next = new SymbolToken(GT_INFO, token.charOffset + 1);
         token.next.next = next;
-      } else if (identical(token.stringValue, '>>>')) {
-        token = new SymbolToken(GT_INFO, token.charOffset);
-        token.next = new SymbolToken(GT_GT_INFO, token.charOffset + 1);
-        token.next.next = next;
       }
       endStuff(count, begin, token);
       return expect('>', token);
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index da82058..fb5a6f8 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -665,8 +665,7 @@
       if (identical(string, '!') ||
           identical(string, '&&') || identical(string, '||') ||
           identical(string, 'is') || identical(string, 'as') ||
-          identical(string, '?') || identical(string, '??') ||
-          identical(string, '>>>')) {
+          identical(string, '?') || identical(string, '??')) {
         return null;
       }
       String op = source;
@@ -3658,9 +3657,9 @@
   }
 
   ResolutionResult visitRethrow(Rethrow node) {
-    if (!inCatchBlock) {
+    if (!inCatchBlock && node.throwToken.stringValue == 'rethrow') {
       reporter.reportErrorMessage(
-          node, MessageKind.THROW_WITHOUT_EXPRESSION);
+          node, MessageKind.RETHROW_OUTSIDE_CATCH);
     }
     return const NoneResult();
   }
@@ -3674,7 +3673,7 @@
         // Specification 13.12.)
         reporter.reportErrorMessage(
             expression,
-            MessageKind.CANNOT_RETURN_FROM_CONSTRUCTOR);
+            MessageKind.RETURN_IN_GENERATIVE_CONSTRUCTOR);
       } else if (!node.isArrowBody && currentAsyncMarker.isYielding) {
         reporter.reportErrorMessage(
             node,
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 07cf4e6..c31ee4a 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -16,6 +16,7 @@
     show Compiler;
 import '../constants/constructors.dart';
 import '../constants/expressions.dart';
+import '../core_types.dart';
 import '../dart_types.dart';
 import '../elements/elements.dart';
 import '../elements/modelx.dart' show
@@ -853,7 +854,7 @@
   bool get hasLocalScopeMembers => _unsupported('hasLocalScopeMembers');
 
   @override
-  bool implementsFunction(Compiler compiler) {
+  bool implementsFunction(CoreClasses coreClasses) {
     return _unsupported('implementsFunction');
   }
 
@@ -1572,4 +1573,4 @@
   Element lookupLocalMember(String memberName) {
     return _unsupported('lookupLocalMember');
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/dart_messages/bin/publish.dart b/pkg/dart_messages/bin/publish.dart
index 4b497b8..d6e3f87 100644
--- a/pkg/dart_messages/bin/publish.dart
+++ b/pkg/dart_messages/bin/publish.dart
@@ -112,17 +112,25 @@
     }
     if (message.examples != null) {
       out.writeln(",\n    examples: const [");
+
+      String escapeExampleContent(String content) {
+        if (content.contains("\n") || content.contains('"')) {
+          return 'r"""\n$content"""';
+        } else if (content.contains("\\")) {
+          return 'r"$content"';
+        }
+        return '"$content"';
+      }
       for (var example in message.examples) {
         if (example is String) {
-          out.writeln("      r'''");
-          out.write(example);
-          out.write("'''");
+          out.write("      ");
+          out.write(escapeExampleContent(example));
         } else if (example is Map) {
           out.writeln("      const {");
           example.forEach((String fileName, String content) {
-            out.writeln("      '$fileName': r'''");
-            out.write(content);
-            out.writeln("''',");
+            out.writeln("      '$fileName': ");
+            out.write(escapeExampleContent(content));
+            out.writeln(",");
           });
           out.write("      }");
         }
@@ -147,9 +155,12 @@
     }
   }
   int seenHoles = 0;
-  return template.replaceAllMapped(new RegExp(r"#\w+"), (Match match) {
+  return template.replaceAllMapped(new RegExp(r"#\w+|#{\w+}"), (Match match) {
     if (holeMap != null) {
-      String holeName = match[0].substring(1);
+      String matchedString = match[0];
+      String holeName = matchedString.startsWith("#{")
+          ? matchedString.substring(2, matchedString.length - 1)
+          : matchedString.substring(1);
       int index = holeMap[holeName];
       if (index == null) {
         throw "Couldn't find hole-position for $holeName $holeMap";
diff --git a/pkg/dart_messages/lib/generated/shared_messages.json b/pkg/dart_messages/lib/generated/shared_messages.json
index 8b20467..a40bc3f 100644
--- a/pkg/dart_messages/lib/generated/shared_messages.json
+++ b/pkg/dart_messages/lib/generated/shared_messages.json
@@ -1 +1,315 @@
-{"exampleMessage":{"id":"use an Id generated by bin/message_id.dart","subId":0,"category":"AnalysisOptionsError","template":"#use #named #arguments","templateHoleOrder":["arguments","named","use"],"howToFix":"an explanation on how to fix things","options":null,"usedBy":[],"examples":["      Some multiline example;\n      That generates the bug.",{"fileA.dart":"        or a map from file to content.\n        again multiline","fileB.dart":"        with possibly multiple files.\n        muliline too"}]},"CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY":{"id":"LGJGHW","subId":0,"category":"ParserError","template":"Const constructor or factory can't have a body.","templateHoleOrder":null,"howToFix":"Remove the 'const' keyword or the body.","options":null,"usedBy":["Platform.dart2js"],"examples":["         class C {\n           const C() {}\n         }\n\n         main() => new C();","         class C {\n           const factory C() {}\n         }\n\n         main() => new C();"]},"CONST_CONSTRUCTOR_WITH_BODY":{"id":"LGJGHW","subId":1,"category":"ParserError","template":"Const constructor can't have a body.","templateHoleOrder":null,"howToFix":"Try removing the 'const' keyword or the body.","options":null,"usedBy":["Platform.analyzer"],"examples":["         class C {\n           const C() {}\n         }\n\n         main() => new C();"]},"CONST_FACTORY":{"id":"LGJGHW","subId":2,"category":"ParserError","template":"Only redirecting factory constructors can be declared to be 'const'.","templateHoleOrder":null,"howToFix":"Try removing the 'const' keyword or replacing the body with '=' followed by a valid target","options":null,"usedBy":["Platform.analyzer"],"examples":["         class C {\n           const factory C() {}\n         }\n\n         main() => new C();"]}}
\ No newline at end of file
+{
+  "exampleMessage": {
+    "id": "use an Id generated by bin/message_id.dart",
+    "subId": 0,
+    "category": "AnalysisOptionsError",
+    "template": "#use #named #arguments",
+    "templateHoleOrder": [
+      "arguments",
+      "named",
+      "use"
+    ],
+    "howToFix": "an explanation on how to fix things",
+    "options": null,
+    "usedBy": [],
+    "examples": [
+      "      Some multiline example;\n      That generates the bug.",
+      {
+        "fileA.dart": "        or a map from file to content.\n        again multiline",
+        "fileB.dart": "        with possibly multiple files.\n        muliline too"
+      }
+    ]
+  },
+  "CONST_CONSTRUCTOR_OR_FACTORY_WITH_BODY": {
+    "id": "LGJGHW",
+    "subId": 0,
+    "category": "ParserError",
+    "template": "Const constructor or factory can't have a body.",
+    "templateHoleOrder": null,
+    "howToFix": "Remove the 'const' keyword or the body.",
+    "options": null,
+    "usedBy": [
+      "Platform.dart2js"
+    ],
+    "examples": [
+      "         class C {\n           const C() {}\n         }\n\n         main() => new C();",
+      "         class C {\n           const factory C() {}\n         }\n\n         main() => new C();"
+    ]
+  },
+  "CONST_CONSTRUCTOR_WITH_BODY": {
+    "id": "LGJGHW",
+    "subId": 1,
+    "category": "ParserError",
+    "template": "Const constructor can't have a body.",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the 'const' keyword or the body.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "         class C {\n           const C() {}\n         }\n\n         main() => new C();"
+    ]
+  },
+  "CONST_FACTORY": {
+    "id": "LGJGHW",
+    "subId": 2,
+    "category": "ParserError",
+    "template": "Only redirecting factory constructors can be declared to be 'const'.",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the 'const' keyword or replacing the body with '=' followed by a valid target.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "         class C {\n           const factory C() {}\n         }\n\n         main() => new C();"
+    ]
+  },
+  "EXTRANEOUS_MODIFIER": {
+    "id": "GRKIQE",
+    "subId": 0,
+    "category": "ParserError",
+    "template": "Can't have modifier '#{modifier}' here.",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing '#{modifier}'.",
+    "options": null,
+    "usedBy": [
+      "Platform.dart2js"
+    ],
+    "examples": [
+      "var String foo; main(){}",
+      "var set foo; main(){}",
+      "var final foo; main(){}",
+      "var var foo; main(){}",
+      "var const foo; main(){}",
+      "var abstract foo; main(){}",
+      "var static foo; main(){}",
+      "var external foo; main(){}",
+      "get var foo; main(){}",
+      "set var foo; main(){}",
+      "final var foo; main(){}",
+      "var var foo; main(){}",
+      "const var foo; main(){}",
+      "abstract var foo; main(){}",
+      "static var foo; main(){}",
+      "external var foo; main(){}"
+    ]
+  },
+  "EXTRANEOUS_MODIFIER_REPLACE": {
+    "id": "GRKIQE",
+    "subId": 1,
+    "category": "ParserError",
+    "template": "Can't have modifier '#{modifier}' here.",
+    "templateHoleOrder": null,
+    "howToFix": "Try replacing modifier '#{modifier}' with 'var', 'final', or a type.",
+    "options": null,
+    "usedBy": [
+      "Platform.dart2js"
+    ],
+    "examples": [
+      "set foo; main(){}",
+      "abstract foo; main(){}",
+      "static foo; main(){}",
+      "external foo; main(){}"
+    ]
+  },
+  "CONST_CLASS": {
+    "id": "GRKIQE",
+    "subId": 2,
+    "category": "ParserError",
+    "template": "Classes can't be declared to be 'const'",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the 'const' keyword or moving to the class' constructor(s).",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "        const class C {}\n\n        main() => new C();\n        "
+    ]
+  },
+  "CONST_METHOD": {
+    "id": "GRKIQE",
+    "subId": 3,
+    "category": "ParserError",
+    "template": "Getters, setters and methods can't be declared to be 'const'",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the 'const' keyword.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "const int foo() => 499; main() {}",
+      "const int get foo => 499; main() {}",
+      "const set foo(v) => 499; main() {}",
+      "class A { const int foo() => 499; } main() { new A(); }",
+      "class A { const int get foo => 499; } main() { new A(); }",
+      "class A { const set foo(v) => 499; } main() { new A(); }"
+    ]
+  },
+  "CONST_ENUM": {
+    "id": "GRKIQE",
+    "subId": 4,
+    "category": "ParserError",
+    "template": "Enums can't be declared to be 'const'",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the 'const' keyword.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "const enum Foo { x } main() {}"
+    ]
+  },
+  "CONST_TYPEDEF": {
+    "id": "GRKIQE",
+    "subId": 5,
+    "category": "ParserError",
+    "template": "Type aliases can't be declared to be 'const'",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the 'const' keyword.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "const typedef void Foo(); main() {}"
+    ]
+  },
+  "CONST_AND_FINAL": {
+    "id": "GRKIQE",
+    "subId": 6,
+    "category": "ParserError",
+    "template": "Members can't be declared to be both 'const' and 'final'",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing either the 'const' or 'final' keyword.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "final const int x = 499; main() {}",
+      "const final int x = 499; main() {}",
+      "class A { static final const int x = 499; } main() {}",
+      "class A { static const final int x = 499; } main() {}"
+    ]
+  },
+  "CONST_AND_VAR": {
+    "id": "GRKIQE",
+    "subId": 7,
+    "category": "ParserError",
+    "template": "Members can't be declared to be both 'const' and 'var'",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing either the 'const' or 'var' keyword.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "var const x = 499; main() {}",
+      "const var x = 499; main() {}",
+      "class A { var const x = 499; } main() {}",
+      "class A { const var x = 499; } main() {}"
+    ]
+  },
+  "CLASS_IN_CLASS": {
+    "id": "DOTHQH",
+    "subId": 0,
+    "category": "ParserError",
+    "template": "Classes can't be declared inside other classes.",
+    "templateHoleOrder": null,
+    "howToFix": "Try moving the class to the top-level.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer"
+    ],
+    "examples": [
+      "class A { class B {} } main() { new A(); }"
+    ]
+  },
+  "CONSTRUCTOR_WITH_RETURN_TYPE": {
+    "id": "VOJBWY",
+    "subId": 0,
+    "category": "ParserError",
+    "template": "Constructors can't have a return type",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the return type.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer",
+      "Platform.dart2js"
+    ],
+    "examples": [
+      "class A { int A() {} } main() { new A(); }"
+    ]
+  },
+  "MISSING_EXPRESSION_IN_THROW": {
+    "id": "FTGGMJ",
+    "subId": 0,
+    "category": "ParserError",
+    "template": "Missing expression after 'throw'.",
+    "templateHoleOrder": null,
+    "howToFix": "Did you mean 'rethrow'?",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer",
+      "Platform.dart2js"
+    ],
+    "examples": [
+      "main() { throw; }",
+      "main() { try { throw 0; } catch(e) { throw; } }"
+    ]
+  },
+  "RETHROW_OUTSIDE_CATCH": {
+    "id": "MWETLC",
+    "subId": 0,
+    "category": "CompileTimeError",
+    "template": "Rethrow must be inside of catch clause",
+    "templateHoleOrder": null,
+    "howToFix": "Try moving the expression into a catch clause, or using a 'throw' expression.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer",
+      "Platform.dart2js"
+    ],
+    "examples": [
+      "main() { rethrow; }"
+    ]
+  },
+  "RETURN_IN_GENERATIVE_CONSTRUCTOR": {
+    "id": "UOTDQH",
+    "subId": 0,
+    "category": "CompileTimeError",
+    "template": "Constructors can't return values.",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the return statement or using a factory constructor.",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer",
+      "Platform.dart2js"
+    ],
+    "examples": [
+      "        class C {\n          C() {\n            return 1;\n          }\n        }\n\n        main() => new C();"
+    ]
+  },
+  "RETURN_IN_GENERATOR": {
+    "id": "JRUTUQ",
+    "subId": 0,
+    "category": "CompileTimeError",
+    "template": "Can't return a value from a generator function (using the '#{modifier}' modifier).",
+    "templateHoleOrder": null,
+    "howToFix": "Try removing the value, replacing 'return' with 'yield' or changing the method body modifier",
+    "options": null,
+    "usedBy": [
+      "Platform.analyzer",
+      "Platform.dart2js"
+    ],
+    "examples": [
+      "        foo() async* { return 0; }\n        main() => foo();\n        ",
+      "        foo() sync* { return 0; }\n        main() => foo();\n        "
+    ]
+  }
+}
\ No newline at end of file
diff --git a/pkg/dart_messages/lib/shared_messages.dart b/pkg/dart_messages/lib/shared_messages.dart
index 32d7935..ece8895 100644
--- a/pkg/dart_messages/lib/shared_messages.dart
+++ b/pkg/dart_messages/lib/shared_messages.dart
@@ -75,20 +75,40 @@
 
   static final parserError = new Category("ParserError");
 
+  static final compileTimeError = new Category("CompileTimeError");
+
   final String name;
 
   Category(this.name);
 }
 
-enum Platform {
-  dart2js, analyzer,
-}
+enum Platform { dart2js, analyzer, }
 const dart2js = Platform.dart2js;
 const analyzer = Platform.analyzer;
 
 class Message {
+  /// Generic id for this message.
+  ///
+  /// This id should be shared by all errors that fall into the same category.
+  /// In particular, we want errors of the same category to share the same
+  /// explanation page, and want to disable warnings of the same category
+  /// with just one line.
   final String id;
+
+  /// The sub-id of the error.
+  ///
+  /// This id just needs to be unique within the same [id].
   final int subId;
+
+  /// The error sub-id of which this message is a specialization.
+  ///
+  /// For example, "Const is not allowed on getters" may be a specialization of
+  /// "The 'const' keyword is not allowed here".
+  ///
+  /// Examples of the specialized message, should trigger for the more generic
+  /// message, when the platform doesn't support the more specialized message.
+  final int specializationOf;
+
   final Category category;
   final String template;
   // The analyzer fills holes positionally (and not named). The following field
@@ -107,6 +127,7 @@
   Message(
       {this.id,
       this.subId: 0,
+      this.specializationOf: -1,
       this.category,
       this.template,
       this.templateHoleOrder,
@@ -131,7 +152,7 @@
       'examples': message.examples,
     };
   });
-  return JSON.encode(jsonified);
+  return new JsonEncoder.withIndent('  ').convert(jsonified);
 }
 
 final Map<String, Message> MESSAGES = {
@@ -162,7 +183,9 @@
       category: Category.parserError,
       template: "Const constructor or factory can't have a body.",
       howToFix: "Remove the 'const' keyword or the body.",
-      usedBy: [dart2js],
+      usedBy: [
+        dart2js
+      ],
       examples: const [
         r"""
          class C {
@@ -181,10 +204,13 @@
   'CONST_CONSTRUCTOR_WITH_BODY': new Message(
       id: 'LGJGHW',
       subId: 1,
+      specializationOf: 0,
       category: Category.parserError,
       template: "Const constructor can't have a body.",
       howToFix: "Try removing the 'const' keyword or the body.",
-      usedBy: [analyzer],
+      usedBy: [
+        analyzer
+      ],
       examples: const [
         r"""
          class C {
@@ -197,12 +223,15 @@
   'CONST_FACTORY': new Message(
       id: 'LGJGHW',
       subId: 2,
+      specializationOf: 0,
       category: Category.parserError,
       template: "Only redirecting factory constructors can be declared to "
           "be 'const'.",
       howToFix: "Try removing the 'const' keyword or replacing the body with "
-          "'=' followed by a valid target",
-      usedBy: [analyzer],
+          "'=' followed by a valid target.",
+      usedBy: [
+        analyzer
+      ],
       examples: const [
         r"""
          class C {
@@ -211,4 +240,247 @@
 
          main() => new C();"""
       ]),
+
+  'EXTRANEOUS_MODIFIER': new Message(
+      id: 'GRKIQE',
+      subId: 0,
+      category: Category.parserError,
+      template: "Can't have modifier '#{modifier}' here.",
+      howToFix: "Try removing '#{modifier}'.",
+      usedBy: [
+        dart2js
+      ],
+      examples: const [
+        "var String foo; main(){}",
+        // "var get foo; main(){}",
+        "var set foo; main(){}",
+        "var final foo; main(){}",
+        "var var foo; main(){}",
+        "var const foo; main(){}",
+        "var abstract foo; main(){}",
+        "var static foo; main(){}",
+        "var external foo; main(){}",
+        "get var foo; main(){}",
+        "set var foo; main(){}",
+        "final var foo; main(){}",
+        "var var foo; main(){}",
+        "const var foo; main(){}",
+        "abstract var foo; main(){}",
+        "static var foo; main(){}",
+        "external var foo; main(){}"
+      ]),
+
+  'EXTRANEOUS_MODIFIER_REPLACE': new Message(
+      id: 'GRKIQE',
+      subId: 1,
+      category: Category.parserError,
+      template: "Can't have modifier '#{modifier}' here.",
+      howToFix: "Try replacing modifier '#{modifier}' with 'var', 'final', "
+          "or a type.",
+      usedBy: [
+        dart2js
+      ],
+      examples: const [
+        // "get foo; main(){}",
+        "set foo; main(){}",
+        "abstract foo; main(){}",
+        "static foo; main(){}",
+        "external foo; main(){}"
+      ]),
+
+  'CONST_CLASS': new Message(
+      id: 'GRKIQE',
+      subId: 2,
+      // The specialization could also be 1, but the example below triggers 0.
+      specializationOf: 0,
+      category: Category.parserError,
+      template: "Classes can't be declared to be 'const'",
+      howToFix: "Try removing the 'const' keyword or moving to the class'"
+          " constructor(s).",
+      usedBy: [
+        analyzer
+      ],
+      examples: const [
+        r"""
+        const class C {}
+
+        main() => new C();
+        """
+      ]),
+
+  'CONST_METHOD': new Message(
+      id: 'GRKIQE',
+      subId: 3,
+      // The specialization could also be 1, but the example below triggers 0.
+      specializationOf: 0,
+      category: Category.parserError,
+      template: "Getters, setters and methods can't be declared to be 'const'",
+      howToFix: "Try removing the 'const' keyword.",
+      usedBy: [
+        analyzer
+      ],
+      examples: const [
+        "const int foo() => 499; main() {}",
+        "const int get foo => 499; main() {}",
+        "const set foo(v) => 499; main() {}",
+        "class A { const int foo() => 499; } main() { new A(); }",
+        "class A { const int get foo => 499; } main() { new A(); }",
+        "class A { const set foo(v) => 499; } main() { new A(); }",
+      ]),
+
+  'CONST_ENUM': new Message(
+      id: 'GRKIQE',
+      subId: 4,
+      // The specialization could also be 1, but the example below triggers 0.
+      specializationOf: 0,
+      category: Category.parserError,
+      template: "Enums can't be declared to be 'const'",
+      howToFix: "Try removing the 'const' keyword.",
+      usedBy: [analyzer],
+      examples: const ["const enum Foo { x } main() {}",]),
+
+  'CONST_TYPEDEF': new Message(
+      id: 'GRKIQE',
+      subId: 5,
+      // The specialization could also be 1, but the example below triggers 0.
+      specializationOf: 0,
+      category: Category.parserError,
+      template: "Type aliases can't be declared to be 'const'",
+      howToFix: "Try removing the 'const' keyword.",
+      usedBy: [analyzer],
+      examples: const ["const typedef void Foo(); main() {}",]),
+
+  'CONST_AND_FINAL': new Message(
+      id: 'GRKIQE',
+      subId: 6,
+      // The specialization could also be 1, but the example below triggers 0.
+      specializationOf: 0,
+      category: Category.parserError,
+      template: "Members can't be declared to be both 'const' and 'final'",
+      howToFix: "Try removing either the 'const' or 'final' keyword.",
+      usedBy: [
+        analyzer
+      ],
+      examples: const [
+        "final const int x = 499; main() {}",
+        "const final int x = 499; main() {}",
+        "class A { static final const int x = 499; } main() {}",
+        "class A { static const final int x = 499; } main() {}",
+      ]),
+
+  'CONST_AND_VAR': new Message(
+      id: 'GRKIQE',
+      subId: 7,
+      // The specialization could also be 1, but the example below triggers 0.
+      specializationOf: 0,
+      category: Category.parserError,
+      template: "Members can't be declared to be both 'const' and 'var'",
+      howToFix: "Try removing either the 'const' or 'var' keyword.",
+      usedBy: [
+        analyzer
+      ],
+      examples: const [
+        "var const x = 499; main() {}",
+        "const var x = 499; main() {}",
+        "class A { var const x = 499; } main() {}",
+        "class A { const var x = 499; } main() {}",
+      ]),
+
+  'CLASS_IN_CLASS': new Message(
+      // Dart2js currently reports this as an EXTRANEOUS_MODIFIER error.
+      // TODO(floitsch): make dart2js use this error instead.
+      id: 'DOTHQH',
+      category: Category.parserError,
+      template: "Classes can't be declared inside other classes.",
+      howToFix: "Try moving the class to the top-level.",
+      usedBy: [analyzer],
+      examples: const ["class A { class B {} } main() { new A(); }",]),
+
+  'CONSTRUCTOR_WITH_RETURN_TYPE': new Message(
+      id: 'VOJBWY',
+      category: Category.parserError,
+      template: "Constructors can't have a return type",
+      howToFix: "Try removing the return type.",
+      usedBy: [analyzer, dart2js],
+      examples: const ["class A { int A() {} } main() { new A(); }",]),
+
+  'MISSING_EXPRESSION_IN_THROW': new Message(
+      id: 'FTGGMJ',
+      subId: 0,
+      category: Category.parserError,
+      template: "Missing expression after 'throw'.",
+      howToFix: "Did you mean 'rethrow'?",
+      usedBy: [
+        analyzer,
+        dart2js
+      ],
+      examples: const [
+        'main() { throw; }',
+        'main() { try { throw 0; } catch(e) { throw; } }'
+      ]),
+
+  /**
+   * 12.8.1 Rethrow: It is a compile-time error if an expression of the form
+   * <i>rethrow;</i> is not enclosed within a on-catch clause.
+   */
+  'RETHROW_OUTSIDE_CATCH': new Message(
+      id: 'MWETLC',
+      category: Category.compileTimeError,
+      template: 'Rethrow must be inside of catch clause',
+      howToFix: "Try moving the expression into a catch clause, or "
+          "using a 'throw' expression.",
+      usedBy: [analyzer, dart2js],
+      examples: const ["main() { rethrow; }"]),
+
+  /**
+   * 13.12 Return: It is a compile-time error if a return statement of the form
+   * <i>return e;</i> appears in a generative constructor.
+   */
+  'RETURN_IN_GENERATIVE_CONSTRUCTOR': new Message(
+      id: 'UOTDQH',
+      category: Category.compileTimeError,
+      template: "Constructors can't return values.",
+      howToFix:
+          "Try removing the return statement or using a factory constructor.",
+      usedBy: [
+        analyzer,
+        dart2js
+      ],
+      examples: const [
+        """
+        class C {
+          C() {
+            return 1;
+          }
+        }
+
+        main() => new C();"""
+      ]),
+
+  /**
+   * 13.12 Return: It is a compile-time error if a return statement of the form
+   * <i>return e;</i> appears in a generator function.
+   */
+  'RETURN_IN_GENERATOR': new Message(
+      id: 'JRUTUQ',
+      subId: 0,
+      category: Category.compileTimeError,
+      template: "Can't return a value from a generator function "
+          "(using the '#{modifier}' modifier).",
+      howToFix: "Try removing the value, replacing 'return' with 'yield' or"
+          " changing the method body modifier",
+      usedBy: [
+        analyzer,
+        dart2js
+      ],
+      examples: const [
+        """
+        foo() async* { return 0; }
+        main() => foo();
+        """,
+        """
+        foo() sync* { return 0; }
+        main() => foo();
+        """
+      ]),
 };
diff --git a/pkg/meta/CHANGELOG.md b/pkg/meta/CHANGELOG.md
new file mode 100644
index 0000000..6c3009b
--- /dev/null
+++ b/pkg/meta/CHANGELOG.md
@@ -0,0 +1,3 @@
+## 0.9.0
+* Introduce `@protected` annotation for methods that must only be called from
+instance methods of subclasses.
diff --git a/pkg/meta/LICENSE b/pkg/meta/LICENSE
new file mode 100644
index 0000000..82e9b52
--- /dev/null
+++ b/pkg/meta/LICENSE
@@ -0,0 +1,26 @@
+Copyright 2016, the Dart project authors. All rights reserved.
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are
+met:
+
+    * Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above
+      copyright notice, this list of conditions and the following
+      disclaimer in the documentation and/or other materials provided
+      with the distribution.
+    * Neither the name of Google Inc. nor the names of its
+      contributors may be used to endorse or promote products derived
+      from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/pkg/meta/lib/meta.dart b/pkg/meta/lib/meta.dart
new file mode 100644
index 0000000..a914ff6
--- /dev/null
+++ b/pkg/meta/lib/meta.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.
+
+/// Constants for use in metadata annotations such as `@protected`.
+///
+/// See also `@deprecated` and `@override` in the `dart:core` library.
+///
+/// Annotations provide semantic information that tools can use to provide a
+/// better user experience. For example, an IDE might not autocomplete the name
+/// of a function that's been marked `@deprecated`, or it might display the
+/// function's name differently.
+///
+/// For information on installing and importing this library, see the
+/// [meta package on pub.dartlang.org] (http://pub.dartlang.org/packages/meta).
+/// For examples of using annotations, see
+/// [Metadata](https://www.dartlang.org/docs/dart-up-and-running/ch02.html#metadata)
+/// in the language tour.
+library meta;
+
+/// Used to annotate an instance method `m` in a class `C`. Indicates that `m`
+/// should only be invoked from instance methods of `C` or classes that extend
+/// or mix in `C`, either directly or indirectly. Additionally indicates that
+/// `m` should only be invoked on `this`, whether explicitly or implicitly.
+///
+/// Tools, such as the analyzer, can provide feedback if an invocation of a
+/// method marked as being protected is used outside of an instance method
+/// defined on a class that extends or mixes in the class in which the protected
+/// method is defined, or that uses a receiver other than `this`.
+const _Protected protected = const _Protected();
+
+class _Protected {
+  const _Protected();
+}
diff --git a/pkg/meta/pubspec.yaml b/pkg/meta/pubspec.yaml
new file mode 100644
index 0000000..4b20d9c
--- /dev/null
+++ b/pkg/meta/pubspec.yaml
@@ -0,0 +1,10 @@
+name: meta
+version: 0.9.0
+author: Dart Team <misc@dartlang.org>
+homepage: http://www.dartlang.org
+description: >
+ This library contains the definitions of annotations that provide additional
+ semantic information about the program being annotated. These annotations are
+ intended to be used by tools to provide a better user experience.
+environment:
+  sdk: '>=1.12.0 <2.0.0'
diff --git a/pkg/pkg.status b/pkg/pkg.status
index d6170c0..ef18a9b 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -14,7 +14,7 @@
 # Analyzer2dart is not maintained anymore.
 analyzer2dart/test/*: Skip
 
-[ $compiler == none && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 mutation_observer: Skip # Issue 21149
 unittest/*: Skip # Issue 21949
 lookup_map/*: SkipByDesign
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index cb4b63e..5d7b48e 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -752,6 +752,9 @@
         '<(resources_cc_file)',
         '<(observatory_assets_cc_file)',
       ],
+      'defines': [
+        'DART_PRECOMPILED_RUNTIME',
+      ],
       'conditions': [
         ['OS=="win"', {
           'link_settings': {
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 123f56f..51b1d56 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -109,10 +109,10 @@
   V(SecurityContext_Allocate, 1)                                               \
   V(SecurityContext_UsePrivateKeyBytes, 3)                                     \
   V(SecurityContext_SetAlpnProtocols, 3)                                       \
-  V(SecurityContext_SetClientAuthoritiesBytes, 2)                              \
-  V(SecurityContext_SetTrustedCertificatesBytes, 2)                            \
+  V(SecurityContext_SetClientAuthoritiesBytes, 3)                              \
+  V(SecurityContext_SetTrustedCertificatesBytes, 3)                            \
   V(SecurityContext_TrustBuiltinRoots, 1)                                      \
-  V(SecurityContext_UseCertificateChainBytes, 2)                               \
+  V(SecurityContext_UseCertificateChainBytes, 3)                               \
   V(ServerSocket_Accept, 2)                                                    \
   V(ServerSocket_CreateBindListen, 6)                                          \
   V(Socket_CreateConnect, 3)                                                   \
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index e5e60dc..4642486 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -411,8 +411,10 @@
 #ifndef DART_PRODUCT_BINARY
   Log::PrintErr("Full Application snapshots can only be be run with"
                 " dart_product\n");
-#endif
+  return false;
+#else
   return ProcessSnapshotOptionHelper(filename, &run_full_snapshot);
+#endif  // defined(DART_PRODUCT_BINARY)
 }
 
 
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index d7735af..f63d9d0 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -282,7 +282,9 @@
 
 
 static Dart_Handle WrappedX509Certificate(X509* certificate) {
-  if (certificate == NULL) return Dart_Null();
+  if (certificate == NULL) {
+    return Dart_Null();
+  }
   Dart_Handle x509_type =
       DartUtils::GetDartType(DartUtils::kIOLibURL, "X509Certificate");
   if (Dart_IsError(x509_type)) {
@@ -307,7 +309,9 @@
 
 
 int CertificateCallback(int preverify_ok, X509_STORE_CTX* store_ctx) {
-  if (preverify_ok == 1) return 1;
+  if (preverify_ok == 1) {
+    return 1;
+  }
   Dart_Isolate isolate = Dart_CurrentIsolate();
   if (isolate == NULL) {
     FATAL("CertificateCallback called with no current isolate\n");
@@ -319,7 +323,9 @@
   SSLFilter* filter = static_cast<SSLFilter*>(
       SSL_get_ex_data(ssl, SSLFilter::filter_ssl_index));
   Dart_Handle callback = filter->bad_certificate_callback();
-  if (Dart_IsNull(callback)) return 0;
+  if (Dart_IsNull(callback)) {
+    return 0;
+  }
   Dart_Handle args[1];
   args[0] = WrappedX509Certificate(certificate);
   if (Dart_IsError(args[0])) {
@@ -360,12 +366,12 @@
 }
 
 
-void CheckStatus(int status,
-                 const char* type,
-                 const char* message) {
+void CheckStatus(int status, const char* type, const char* message) {
   // TODO(24183): Take appropriate action on failed calls,
   // throw exception that includes all messages from the error stack.
-  if (status == 1) return;
+  if (status == 1) {
+    return;
+  }
   if (SSL_LOG_STATUS) {
     int error = ERR_get_error();
     Log::PrintErr("Failed: %s status %d", message, status);
@@ -556,25 +562,31 @@
 }
 
 
-void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
-    Dart_NativeArguments args) {
-  SSL_CTX* context = GetSecurityContext(args);
-
-  Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 2));
+static const char* GetPasswordArgument(Dart_NativeArguments args,
+                                       intptr_t index) {
+  Dart_Handle password_object =
+      ThrowIfError(Dart_GetNativeArgument(args, index));
   const char* password = NULL;
   if (Dart_IsString(password_object)) {
     ThrowIfError(Dart_StringToCString(password_object, &password));
     if (strlen(password) > PEM_BUFSIZE - 1) {
       Dart_ThrowException(DartUtils::NewDartArgumentError(
-        "SecurityContext.usePrivateKey password length is greater than"
-        " 1023 (PEM_BUFSIZE)"));
+        "Password length is greater than 1023 (PEM_BUFSIZE)"));
     }
   } else if (Dart_IsNull(password_object)) {
     password = "";
   } else {
     Dart_ThrowException(DartUtils::NewDartArgumentError(
-        "SecurityContext.usePrivateKey password is not a String or null"));
+        "Password is not a String or null"));
   }
+  return password;
+}
+
+
+void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
+    Dart_NativeArguments args) {
+  SSL_CTX* context = GetSecurityContext(args);
+  const char* password = GetPasswordArgument(args, 2);
 
   int status;
   {
@@ -590,7 +602,9 @@
 }
 
 
-static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context, BIO* bio) {
+static int SetTrustedCertificatesBytesPKCS12(SSL_CTX* context,
+                                             BIO* bio,
+                                             const char* password) {
   ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
   if (p12.get() == NULL) {
     return NULL;
@@ -599,22 +613,12 @@
   EVP_PKEY* key = NULL;
   X509 *cert = NULL;
   STACK_OF(X509) *ca_certs = NULL;
-  // There should be no private keys in this file, so we hardcode the password
-  // to "".
-  // TODO(zra): Allow passing a password anyway.
-  int status = PKCS12_parse(p12.get(), "", &key, &cert, &ca_certs);
+  int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
   if (status == 0) {
     return status;
   }
 
   ScopedX509Stack cert_stack(ca_certs);
-
-  // There should be no private key.
-  if (key != NULL) {
-    X509_free(cert);
-    return 0;
-  }
-
   X509_STORE* store = SSL_CTX_get_cert_store(context);
   status = X509_STORE_add_cert(store, cert);
   if (status == 0) {
@@ -662,12 +666,14 @@
 }
 
 
-static int SetTrustedCertificatesBytes(SSL_CTX* context, BIO* bio) {
+static int SetTrustedCertificatesBytes(SSL_CTX* context,
+                                       BIO* bio,
+                                       const char* password) {
   int status = SetTrustedCertificatesBytesPEM(context, bio);
   if (TryPKCS12(status != 0)) {
     ERR_clear_error();
     BIO_reset(bio);
-    status = SetTrustedCertificatesBytesPKCS12(context, bio);
+    status = SetTrustedCertificatesBytesPKCS12(context, bio, password);
   } else if (status != 0) {
     // The PEM file was successfully parsed.
     ERR_clear_error();
@@ -679,10 +685,11 @@
 void FUNCTION_NAME(SecurityContext_SetTrustedCertificatesBytes)(
     Dart_NativeArguments args) {
   SSL_CTX* context = GetSecurityContext(args);
+  const char* password = GetPasswordArgument(args, 2);
   int status;
   {
     ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
-    status = SetTrustedCertificatesBytes(context, bio.bio());
+    status = SetTrustedCertificatesBytes(context, bio.bio(), password);
   }
   CheckStatus(status,
               "TlsException",
@@ -708,7 +715,9 @@
 }
 
 
-static int UseChainBytesPKCS12(SSL_CTX* context, BIO* bio) {
+static int UseChainBytesPKCS12(SSL_CTX* context,
+                               BIO* bio,
+                               const char* password) {
   ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
   if (p12.get() == NULL) {
     return NULL;
@@ -717,22 +726,13 @@
   EVP_PKEY* key = NULL;
   X509 *cert = NULL;
   STACK_OF(X509) *ca_certs = NULL;
-  // There should be no private keys in this file, so we hardcode the password
-  // to "".
-  // TODO(zra): Allow passing a password anyway.
-  int status = PKCS12_parse(p12.get(), "", &key, &cert, &ca_certs);
+  int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
   if (status == 0) {
     return status;
   }
 
   ScopedX509 x509(cert);
   ScopedX509Stack certs(ca_certs);
-
-  // There should be no private key.
-  if (key != NULL) {
-    return 0;
-  }
-
   status = SSL_CTX_use_certificate(context, x509.get());
   if (ERR_peek_error() != 0) {
     // Key/certificate mismatch doesn't imply status is 0.
@@ -801,12 +801,12 @@
 }
 
 
-static int UseChainBytes(SSL_CTX* context, BIO* bio) {
+static int UseChainBytes(SSL_CTX* context, BIO* bio, const char* password) {
   int status = UseChainBytesPEM(context, bio);
   if (TryPKCS12(status != 0)) {
     ERR_clear_error();
     BIO_reset(bio);
-    status = UseChainBytesPKCS12(context, bio);
+    status = UseChainBytesPKCS12(context, bio, password);
   } else if (status != 0) {
     // The PEM file was successfully read.
     ERR_clear_error();
@@ -818,10 +818,11 @@
 void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
     Dart_NativeArguments args) {
   SSL_CTX* context = GetSecurityContext(args);
+  const char* password = GetPasswordArgument(args, 2);
   int status;
   {
     ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
-    status = UseChainBytes(context, bio.bio());
+    status = UseChainBytes(context, bio.bio(), password);
   }
   CheckStatus(status,
               "TlsException",
@@ -829,7 +830,8 @@
 }
 
 
-static STACK_OF(X509_NAME)* GetCertificateNamesPKCS12(BIO* bio) {
+static STACK_OF(X509_NAME)* GetCertificateNamesPKCS12(BIO* bio,
+                                                      const char* password) {
   ScopedPKCS12 p12(d2i_PKCS12_bio(bio, NULL));
   if (p12.get() == NULL) {
     return NULL;
@@ -843,22 +845,13 @@
   EVP_PKEY* key = NULL;
   X509 *cert = NULL;
   STACK_OF(X509) *ca_certs = NULL;
-  // There should be no private keys in this file, so we hardcode the password
-  // to "".
-  // TODO(zra): Allow passing a password anyway.
-  int status = PKCS12_parse(p12.get(), "", &key, &cert, &ca_certs);
+  int status = PKCS12_parse(p12.get(), password, &key, &cert, &ca_certs);
   if (status == 0) {
     return NULL;
   }
 
   ScopedX509 x509(cert);
   ScopedX509Stack certs(ca_certs);
-
-  // There should be no private key.
-  if (key != NULL) {
-    return NULL;
-  }
-
   X509_NAME* x509_name = X509_get_subject_name(x509.get());
   if (x509_name == NULL) {
     return NULL;
@@ -935,12 +928,13 @@
 }
 
 
-static STACK_OF(X509_NAME)* GetCertificateNames(BIO* bio) {
+static STACK_OF(X509_NAME)* GetCertificateNames(BIO* bio,
+                                                const char* password) {
   STACK_OF(X509_NAME)* result = GetCertificateNamesPEM(bio);
   if (TryPKCS12(result != NULL)) {
     ERR_clear_error();
     BIO_reset(bio);
-    result = GetCertificateNamesPKCS12(bio);
+    result = GetCertificateNamesPKCS12(bio, password);
   } else if (result != NULL) {
     // The PEM file was successfully parsed.
     ERR_clear_error();
@@ -952,11 +946,12 @@
 void FUNCTION_NAME(SecurityContext_SetClientAuthoritiesBytes)(
     Dart_NativeArguments args) {
   SSL_CTX* context = GetSecurityContext(args);
+  const char* password = GetPasswordArgument(args, 2);
   STACK_OF(X509_NAME)* certificate_names;
 
   {
     ScopedMemBIO bio(ThrowIfError(Dart_GetNativeArgument(args, 1)));
-    certificate_names = GetCertificateNames(bio.bio());
+    certificate_names = GetCertificateNames(bio.bio(), password);
   }
 
   if (certificate_names != NULL) {
diff --git a/runtime/bin/secure_socket_patch.dart b/runtime/bin/secure_socket_patch.dart
index b15d61a..ccfc1c1 100644
--- a/runtime/bin/secure_socket_patch.dart
+++ b/runtime/bin/secure_socket_patch.dart
@@ -147,38 +147,38 @@
   void usePrivateKeyBytes(List<int> keyBytes, {String password})
       native "SecurityContext_UsePrivateKeyBytes";
 
-  void setTrustedCertificates(String file) {
-    setTrustedCertificatesSync(file);
+  void setTrustedCertificates(String file, {String password}) {
+    setTrustedCertificatesSync(file, password: password);
   }
-  void setTrustedCertificatesSync(String file) {
+  void setTrustedCertificatesSync(String file, {String password}) {
     List<int> bytes = (new File(file)).readAsBytesSync();
-    setTrustedCertificatesBytes(bytes);
+    setTrustedCertificatesBytes(bytes, password: password);
   }
-  void setTrustedCertificatesBytes(List<int> certBytes)
+  void setTrustedCertificatesBytes(List<int> certBytes, {String password})
       native "SecurityContext_SetTrustedCertificatesBytes";
 
-  void useCertificateChain({String file, String directory}) {
+  void useCertificateChain({String file, String directory, String password}) {
     if (directory != null) {
       throw new UnsupportedError(
           "The directory argument to useCertificateChain is not supported.");
     }
-    useCertificateChainSync(file);
+    useCertificateChainSync(file, password: password);
   }
-  void useCertificateChainSync(String chainFile) {
+  void useCertificateChainSync(String chainFile, {String password}) {
     List<int> bytes = (new File(chainFile)).readAsBytesSync();
-    useCertificateChainBytes(bytes);
+    useCertificateChainBytes(bytes, password: password);
   }
-  void useCertificateChainBytes(List<int> chainBytes)
+  void useCertificateChainBytes(List<int> chainBytes, {String password})
       native "SecurityContext_UseCertificateChainBytes";
 
-  void setClientAuthorities(String file) {
-    setClientAuthoritiesSync(file);
+  void setClientAuthorities(String file, {String password}) {
+    setClientAuthoritiesSync(file, password: password);
   }
-  void setClientAuthoritiesSync(String file) {
+  void setClientAuthoritiesSync(String file, {String password}) {
     List<int> bytes = (new File(file)).readAsBytesSync();
-    setClientAuthoritiesBytes(bytes);
+    setClientAuthoritiesBytes(bytes, password: password);
   }
-  void setClientAuthoritiesBytes(List<int> authCertBytes)
+  void setClientAuthoritiesBytes(List<int> authCertBytes, {String password})
       native "SecurityContext_SetClientAuthoritiesBytes";
   void setAlpnProtocols(List<String> protocols, bool isServer) {
     Uint8List encodedProtocols =
diff --git a/runtime/bin/vmservice_dartium.cc b/runtime/bin/vmservice_dartium.cc
index 6ff907c..2a9fc8f 100644
--- a/runtime/bin/vmservice_dartium.cc
+++ b/runtime/bin/vmservice_dartium.cc
@@ -62,13 +62,6 @@
   Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
   Builtin::SetNativeResolver(Builtin::kIOLibrary);
 
-  Dart_Handle result;
-
-  // Prepare for script loading by setting up the 'print' and 'timer'
-  // closures and setting up 'package root' for URI resolution.
-  result = DartUtils::PrepareForScriptLoading(true, false);
-  CHECK_RESULT(result);
-
   ASSERT(Dart_IsServiceIsolate(isolate));
   if (!VmService::Setup(DEFAULT_VM_SERVICE_SERVER_IP,
                         DEFAULT_VM_SERVICE_SERVER_PORT,
diff --git a/runtime/dart-runtime.gyp b/runtime/dart-runtime.gyp
index 915b5b4..f976190 100644
--- a/runtime/dart-runtime.gyp
+++ b/runtime/dart-runtime.gyp
@@ -95,7 +95,7 @@
       'target_name': 'libdart_precompiled_runtime',
       'type': 'static_library',
       'dependencies': [
-        'libdart_lib',
+        'libdart_lib_precompiled_runtime',
         'libdart_vm_precompiled_runtime',
         'libdouble_conversion',
         'generate_version_cc_file#host',
diff --git a/runtime/lib/growable_array.dart b/runtime/lib/growable_array.dart
index 39b4522..016a454 100644
--- a/runtime/lib/growable_array.dart
+++ b/runtime/lib/growable_array.dart
@@ -113,13 +113,26 @@
   factory _GrowableList.withData(_List data)
     native "GrowableList_allocate";
 
-  int get length native "GrowableList_getLength";
-
   int get _capacity native "GrowableList_getCapacity";
 
+  int get length native "GrowableList_getLength";
+
   void set length(int new_length) {
-    if (new_length > _capacity) {
-      _grow(new_length);
+    int new_capacity = (new_length == 0) ? _kDefaultCapacity : new_length;
+    if (new_capacity > _capacity) {
+      _grow(new_capacity);
+      _setLength(new_length);
+      return;
+    }
+    // We are shrinking. Pick the method which has fewer writes.
+    // In the shrink-to-fit path, we write |new_capacity + new_length| words
+    // (null init + copy).
+    // In the non-shrink-to-fit path, we write |length - new_length| words
+    // (null overwrite).
+    final bool shouldShrinkToFit =
+        (new_capacity + new_length) < (length - new_length);
+    if (shouldShrinkToFit) {
+      _shrink(new_capacity, new_length);
     } else {
       for (int i = new_length; i < length; i++) {
         this[i] = null;
@@ -217,14 +230,22 @@
     throw IterableElementError.tooMany();;
   }
 
-  void _grow(int new_length) {
-    var new_data = new _List(new_length);
+  void _grow(int new_capacity) {
+    var new_data = new _List(new_capacity);
     for (int i = 0; i < length; i++) {
       new_data[i] = this[i];
     }
     _setData(new_data);
   }
 
+  void _shrink(int new_capacity, int new_length) {
+    var new_data = new _List(new_capacity);
+    for (int i = 0; i < new_length; i++) {
+      new_data[i] = this[i];
+    }
+    _setData(new_data);
+  }
+
   // Iterable interface.
 
   void forEach(f(T element)) {
diff --git a/runtime/lib/identical.cc b/runtime/lib/identical.cc
index 4b24219..bbb47bd 100644
--- a/runtime/lib/identical.cc
+++ b/runtime/lib/identical.cc
@@ -5,7 +5,6 @@
 #include "vm/bootstrap_natives.h"
 
 #include "vm/object.h"
-#include "vm/report.h"
 
 namespace dart {
 
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index e2ded52..10b39ce 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -10,6 +10,7 @@
 #include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/exceptions.h"
+#include "vm/flags.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
 #include "vm/port.h"
@@ -18,7 +19,7 @@
 
 namespace dart {
 
-DECLARE_FLAG(bool, lazy_dispatchers);
+#ifndef PRODUCT
 
 #define PROPAGATE_IF_MALFORMED(type)                                           \
   if (type.IsMalformed()) {                                                    \
@@ -2089,5 +2090,6 @@
   return Bool::Get(a.IsSubtypeOf(b, NULL, NULL, Heap::kNew)).raw();
 }
 
+#endif  // !PRODUCT
 
 }  // namespace dart
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 95f2661..c34552d 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -10,7 +10,6 @@
 #include "vm/heap.h"
 #include "vm/native_entry.h"
 #include "vm/object.h"
-#include "vm/report.h"
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 
diff --git a/runtime/observatory/lib/src/elements/debugger.dart b/runtime/observatory/lib/src/elements/debugger.dart
index 3692d6a..3bf25b5 100644
--- a/runtime/observatory/lib/src/elements/debugger.dart
+++ b/runtime/observatory/lib/src/elements/debugger.dart
@@ -1810,7 +1810,7 @@
   Future smartNext() async {
     if (isolatePaused()) {
       var event = isolate.pauseEvent;
-      if (event.atAsyncJump) {
+      if (event.atAsyncSuspension) {
         return asyncNext();
       } else {
         return syncNext();
@@ -1823,11 +1823,10 @@
   Future asyncNext() async {
     if (isolatePaused()) {
       var event = isolate.pauseEvent;
-      if (event.asyncContinuation == null) {
+      if (!event.atAsyncSuspension) {
         console.print("No async continuation at this location");
       } else {
-        List<Future> asyncStepFutures = await isolate.asyncStepOver();
-        return asyncStepFutures[Isolate.kFirstResume];
+        return isolate.stepOverAsyncSuspension();
       }
     } else {
       console.print('The program is already running');
diff --git a/runtime/observatory/lib/src/elements/heap_profile.dart b/runtime/observatory/lib/src/elements/heap_profile.dart
index 731ff48..9e5b142 100644
--- a/runtime/observatory/lib/src/elements/heap_profile.dart
+++ b/runtime/observatory/lib/src/elements/heap_profile.dart
@@ -156,7 +156,6 @@
   static const _FREE_INDEX = 1;
   static const _EXTERNAL_INDEX = 2;
 
-  static const _LABEL_INDEX = 0;
   static const _VALUE_INDEX = 1;
 
   void _initPieChartData(List rows) {
diff --git a/runtime/observatory/lib/src/elements/timeline_page.dart b/runtime/observatory/lib/src/elements/timeline_page.dart
index b7a5462..fbecb10 100644
--- a/runtime/observatory/lib/src/elements/timeline_page.dart
+++ b/runtime/observatory/lib/src/elements/timeline_page.dart
@@ -8,7 +8,6 @@
 import 'dart:convert';
 import 'dart:html';
 import 'observatory_element.dart';
-import 'package:observatory/app.dart';
 import 'package:observatory/service_html.dart';
 import 'package:polymer/polymer.dart';
 
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index bd76e67..78b6765 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -1577,92 +1577,12 @@
     return invokeRpc('resume', {'step': 'Over'});
   }
 
-  Future stepOut() {
-    return invokeRpc('resume', {'step': 'Out'});
+  Future stepOverAsyncSuspension() {
+    return invokeRpc('resume', {'step': 'OverAsyncSuspension'});
   }
 
-
-  static const int kFirstResume = 0;
-  static const int kSecondResume = 1;
-  /// result[kFirstResume] completes after the inital resume. The UI should
-  /// wait on this future because some other breakpoint may be hit before the
-  /// async continuation.
-  /// result[kSecondResume] completes after the second resume. Tests should
-  /// wait on this future to avoid confusing the pause event at the
-  /// state-machine switch with the pause event after the state-machine switch.
-  Future<List<Future>> asyncStepOver() async {
-    final Completer firstResume = new Completer();
-    final Completer secondResume = new Completer();
-    final List<Future> result = [firstResume.future, secondResume.future];
-    StreamSubscription subscription;
-
-    // Inner error handling function.
-    handleError(error) {
-      if (subscription != null) {
-        subscription.cancel();
-        subscription = null;
-      }
-      firstResume.completeError(error);
-      secondResume.completeError(error);
-    }
-
-    if ((pauseEvent == null) ||
-        (pauseEvent.kind != ServiceEvent.kPauseBreakpoint) ||
-        (pauseEvent.asyncContinuation == null)) {
-      handleError(new Exception("No async continuation available"));
-    } else {
-      Instance continuation = pauseEvent.asyncContinuation;
-      assert(continuation.isClosure);
-
-      // Add breakpoint at continuation.
-      Breakpoint continuationBpt;
-      try {
-        continuationBpt = await addBreakOnActivation(continuation);
-      } catch (e) {
-        handleError(e);
-        return result;
-      }
-
-      // Subscribe to the debugger event stream.
-      Stream stream;
-      try {
-        stream = await vm.getEventStream(VM.kDebugStream);
-      } catch (e) {
-        handleError(e);
-        return result;
-      }
-
-      Completer onResume = firstResume;
-      subscription = stream.listen((ServiceEvent event) async {
-        if ((event.kind == ServiceEvent.kPauseBreakpoint) &&
-            (event.breakpoint == continuationBpt)) {
-          // We are stopped before state-machine dispatch:
-          // 1) Remove the continuation breakpoint.
-          // 2) step over.
-          // reach user code.
-          await removeBreakpoint(continuationBpt);
-          onResume = secondResume;
-          stepOver().catchError(handleError);
-        } else if (event.kind == ServiceEvent.kResume) {
-          // We've resumed.
-          if (onResume == secondResume) {
-            // This is our second resume, cancel our subscription to the debug
-            // stream.
-            subscription.cancel();
-            subscription = null;
-          }
-          // Complete onResume and clear it.
-          if (onResume != null) {
-            onResume.complete(this);
-            onResume = null;
-          }
-        }
-      });
-
-      // Call resume, which will eventually cause us to hit continuationBpt.
-      resume().catchError(handleError);
-    }
-    return result;
+  Future stepOut() {
+    return invokeRpc('resume', {'step': 'Out'});
   }
 
   Future setName(String newName) {
@@ -1914,8 +1834,7 @@
   @observable Frame topFrame;
   @observable String extensionRPC;
   @observable Instance exception;
-  @observable Instance asyncContinuation;
-  @observable bool atAsyncJump;
+  @observable bool atAsyncSuspension;
   @observable ServiceObject inspectee;
   @observable ByteData data;
   @observable int count;
@@ -1964,12 +1883,7 @@
     if (map['exception'] != null) {
       exception = map['exception'];
     }
-    if (map['_asyncContinuation'] != null) {
-      asyncContinuation = map['_asyncContinuation'];
-      atAsyncJump = map['_atAsyncJump'];
-    } else {
-      atAsyncJump = false;
-    }
+    atAsyncSuspension = map['atAsyncSuspension'] != null;
     if (map['inspectee'] != null) {
       inspectee = map['inspectee'];
     }
@@ -2040,6 +1954,10 @@
   // The breakpoint has been assigned to a final source location.
   @observable bool resolved;
 
+  // The breakpoint was synthetically created as part of an
+  // 'OverAsyncContinuation' resume request.
+  @observable bool isSyntheticAsyncContinuation;
+
   void _update(ObservableMap map, bool mapIsRef) {
     _loaded = true;
     _upgradeCollection(map, owner);
@@ -2066,6 +1984,8 @@
       newScript._addBreakpoint(this);
     }
 
+    isSyntheticAsyncContinuation = map['isSyntheticAsyncContinuation'] != null;
+
     assert(resolved || location is UnresolvedSourceLocation);
   }
 
@@ -2081,7 +2001,11 @@
 
   String toString() {
     if (number != null) {
-      return 'Breakpoint ${number} at ${location})';
+      if (isSyntheticAsyncContinuation) {
+        return 'Synthetic Async Continuation Breakpoint ${number}';
+      } else {
+        return 'Breakpoint ${number} at ${location}';
+      }
     } else {
       return 'Uninitialized breakpoint';
     }
diff --git a/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart b/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart
index a51a2b3..b735254 100644
--- a/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart
+++ b/runtime/observatory/tests/service/add_breakpoint_rpc_test.dart
@@ -5,10 +5,14 @@
 
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 import 'deferred_library.dart' deferred as deferredLib;
 import 'dart:async';
 
+const int LINE_A = 24;
+const int LINE_B = 26;
+
 int value = 0;
 
 int incValue(int amount) {
@@ -17,9 +21,9 @@
 }
 
 Future testMain() async {
-  incValue(incValue(1));  // line 20
+  incValue(incValue(1));  // line A.
 
-  incValue(incValue(1));  // line 22
+  incValue(incValue(1));  // line B.
 
   await deferredLib.loadLibrary();
   deferredLib.deferredTest();
@@ -35,17 +39,17 @@
     var script = rootLib.scripts[0];
 
     // Future breakpoint.
-    var futureBpt1 = await isolate.addBreakpoint(script, 20);
+    var futureBpt1 = await isolate.addBreakpoint(script, LINE_A);
     expect(futureBpt1.number, equals(1));
     expect(futureBpt1.resolved, isFalse);
-    expect(await futureBpt1.location.getLine(), equals(20));
+    expect(await futureBpt1.location.getLine(), equals(LINE_A));
     expect(await futureBpt1.location.getColumn(), equals(null));
 
     // Future breakpoint with specific column.
-    var futureBpt2 = await isolate.addBreakpoint(script, 20, 3);
+    var futureBpt2 = await isolate.addBreakpoint(script, LINE_A, 3);
     expect(futureBpt2.number, equals(2));
     expect(futureBpt2.resolved, isFalse);
-    expect(await futureBpt2.location.getLine(), equals(20));
+    expect(await futureBpt2.location.getLine(), equals(LINE_A));
     expect(await futureBpt2.location.getColumn(), equals(3));
 
     var stream = await isolate.vm.getEventStream(VM.kDebugStream);
@@ -67,10 +71,10 @@
     // After resolution the breakpoints have assigned line & column.
     expect(resolvedCount, equals(2));
     expect(futureBpt1.resolved, isTrue);
-    expect(await futureBpt1.location.getLine(), equals(20));
+    expect(await futureBpt1.location.getLine(), equals(LINE_A));
     expect(await futureBpt1.location.getColumn(), equals(12));
     expect(futureBpt2.resolved, isTrue);
-    expect(await futureBpt2.location.getLine(), equals(20));
+    expect(await futureBpt2.location.getLine(), equals(LINE_A));
     expect(await futureBpt2.location.getColumn(), equals(3));
 
     // The first breakpoint hits before value is modified.
@@ -176,19 +180,19 @@
     var script = isolate.rootLibrary.scripts[0];
     // Try all columns, including some columns that are too big.
     for (int col = 1; col <= 50; col++) {
-      var bpt = await isolate.addBreakpoint(script, 20, col);
+      var bpt = await isolate.addBreakpoint(script, LINE_A, col);
       expect(bpt.resolved, isTrue);
       int resolvedLine = await bpt.location.getLine();
       int resolvedCol = await bpt.location.getColumn();
       print('20:${col} -> ${resolvedLine}:${resolvedCol}');
       if (col <= 10) {
-        expect(resolvedLine, equals(20));
+        expect(resolvedLine, equals(LINE_A));
         expect(resolvedCol, equals(3));
       } else if (col <= 19) {
-        expect(resolvedLine, equals(20));
+        expect(resolvedLine, equals(LINE_A));
         expect(resolvedCol, equals(12));
       } else {
-        expect(resolvedLine, equals(22));
+        expect(resolvedLine, equals(LINE_B));
         expect(resolvedCol, equals(12));
       }
       expect((await isolate.removeBreakpoint(bpt)).type, equals('Success'));
diff --git a/runtime/observatory/tests/service/async_continuation_test.dart b/runtime/observatory/tests/service/async_continuation_test.dart
deleted file mode 100644
index dfbad2d..0000000
--- a/runtime/observatory/tests/service/async_continuation_test.dart
+++ /dev/null
@@ -1,95 +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.
-// VMOptions=--error_on_bad_type --error_on_bad_override --verbose-debug
-
-import 'dart:async';
-import 'dart:developer';
-import 'package:observatory/service_io.dart';
-import 'package:unittest/unittest.dart';
-import 'test_helper.dart';
-
-foo() {}
-
-doSync() {
-  foo();  // Line 15
-}
-
-doAsync() async {
-  foo();  // Line 19
-  await null;
-}
-
-doAsyncStar() async* {
-  foo();  // Line 24
-  yield null;
-}
-
-testeeDo() {
-  debugger();
-
-  doSync();
-
-  doAsync();
-
-  doAsyncStar().listen((_) => null);
-}
-
-test(Isolate isolate) async {
-  await isolate.rootLibrary.load();
-  var script = isolate.rootLibrary.scripts[0];
-
-  var bp1 = await isolate.addBreakpoint(script, 15);
-  expect(bp1, isNotNull);
-  expect(bp1 is Breakpoint, isTrue);
-
-  var bp2 = await isolate.addBreakpoint(script, 19);
-  expect(bp2, isNotNull);
-  expect(bp2 is Breakpoint, isTrue);
-
-  var bp3 = await isolate.addBreakpoint(script, 24);
-  expect(bp3, isNotNull);
-  expect(bp3 is Breakpoint, isTrue);
-
-  isolate.resume();
-
-  var bp1_hit = new Completer();
-  var bp2_hit = new Completer();
-  var bp3_hit = new Completer();
-
-  var stream = await isolate.vm.getEventStream(VM.kDebugStream);
-  stream.listen((ServiceEvent event) async {
-    print("Event: $event");
-    if (event.kind == ServiceEvent.kPauseBreakpoint) {
-      var bp = event.breakpoint;
-      print('Hit $bp');
-      if (bp == bp1) {
-        await stoppedAtLine(15)(isolate);
-        print(event.asyncContinuation);
-        expect(event.asyncContinuation, equals(null));
-        isolate.resume();
-        bp1_hit.complete(null);
-      }
-      if (bp == bp2) {
-        await stoppedAtLine(19)(isolate);
-        print(event.asyncContinuation);
-        expect(event.asyncContinuation.isClosure, isTrue);
-        isolate.resume();
-        bp2_hit.complete(null);
-      }
-      if (bp == bp3) {
-        await stoppedAtLine(24)(isolate);
-        print(event.asyncContinuation);
-        expect(event.asyncContinuation.isClosure, isTrue);
-        isolate.resume();
-        bp3_hit.complete(null);
-      }
-    }
-  });
-
-  await bp1_hit.future;
-  await bp2_hit.future;
-  await bp3_hit.future;
-}
-
-main(args) => runIsolateTests(args, [test], testeeConcurrent: testeeDo);
diff --git a/runtime/observatory/tests/service/async_next_test.dart b/runtime/observatory/tests/service/async_next_test.dart
index dbdc19b..4fefcca 100644
--- a/runtime/observatory/tests/service/async_next_test.dart
+++ b/runtime/observatory/tests/service/async_next_test.dart
@@ -4,16 +4,21 @@
 // VMOptions=--error_on_bad_type --error_on_bad_override  --verbose_debug
 
 import 'package:observatory/service_io.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 import 'dart:developer';
 
+const int LINE_A = 19;
+const int LINE_B = 20;
+const int LINE_C = 21;
+
 foo() async { }
 
 doAsync(stop) async {
   if (stop) debugger();
-  await foo(); // Line 14.
-  await foo(); // Line 15.
-  await foo(); // Line 16.
+  await foo(); // Line A.
+  await foo(); // Line B.
+  await foo(); // Line C.
   return null;
 }
 
@@ -26,19 +31,20 @@
 
 asyncNext(Isolate isolate) async {
   print('asyncNext');
-  List asyncStepFutures = await isolate.asyncStepOver();
-  return asyncStepFutures[Isolate.kSecondResume];
+  return asyncStepOver(isolate);
 }
 
 var tests = [
   hasStoppedAtBreakpoint,
-  stoppedAtLine(14),
+  stoppedAtLine(LINE_A),
+  stepOver, // foo()
   asyncNext,
   hasStoppedAtBreakpoint,
-  stoppedAtLine(15),
+  stoppedAtLine(LINE_B),
+  stepOver, // foo()
   asyncNext,
   hasStoppedAtBreakpoint,
-  stoppedAtLine(16),
+  stoppedAtLine(LINE_C),
   resumeIsolate,
 ];
 
diff --git a/runtime/observatory/tests/service/async_scope_test.dart b/runtime/observatory/tests/service/async_scope_test.dart
index a3f97cc..170a638 100644
--- a/runtime/observatory/tests/service/async_scope_test.dart
+++ b/runtime/observatory/tests/service/async_scope_test.dart
@@ -6,19 +6,23 @@
 import 'dart:developer';
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
+const int LINE_A = 19;
+const int LINE_B = 25;
+
 foo() {}
 
 doAsync(param1) async {
   var local1 = param1 + 1;
-  foo(); // Line 15
+  foo(); // Line A.
   await local1;
 }
 
 doAsyncStar(param2) async* {
   var local2 = param2 + 1;
-  foo(); // Line 21
+  foo(); // Line B.
   yield local2;
 }
 
@@ -53,17 +57,17 @@
 
 var tests = [
   hasStoppedAtBreakpoint, // debugger()
-  setBreakpointAtLine(15),
-  setBreakpointAtLine(21),
+  setBreakpointAtLine(LINE_A),
+  setBreakpointAtLine(LINE_B),
   resumeIsolate,
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(15),
+  stoppedAtLine(LINE_A),
   checkAsyncVarDescriptors,
   resumeIsolate,
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(21),
+  stoppedAtLine(LINE_B),
   checkAsyncStarVarDescriptors,
   resumeIsolate,
 ];
diff --git a/runtime/observatory/tests/service/break_on_function_test.dart b/runtime/observatory/tests/service/break_on_function_test.dart
index 1a0e0ee..e428b25 100644
--- a/runtime/observatory/tests/service/break_on_function_test.dart
+++ b/runtime/observatory/tests/service/break_on_function_test.dart
@@ -5,10 +5,13 @@
 
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 import 'dart:developer';
 
-testFunction(flag) {  // Line 11
+const int LINE_A = 14;
+
+testFunction(flag) {  // Line A.
   if (flag) {
     print("Yes");
   } else {
@@ -40,11 +43,11 @@
 resumeIsolate,
 
 hasStoppedAtBreakpoint,
-stoppedAtLine(11),
+stoppedAtLine(LINE_A),
 resumeIsolate,
 
 hasStoppedAtBreakpoint,
-stoppedAtLine(11),
+stoppedAtLine(LINE_A),
 resumeIsolate,
 
 ];
diff --git a/runtime/observatory/tests/service/capture_stdio_test.dart b/runtime/observatory/tests/service/capture_stdio_test.dart
index 56a1451..279d055 100644
--- a/runtime/observatory/tests/service/capture_stdio_test.dart
+++ b/runtime/observatory/tests/service/capture_stdio_test.dart
@@ -8,6 +8,7 @@
 import 'dart:io';
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 void test() {
diff --git a/runtime/observatory/tests/service/coverage_test.dart b/runtime/observatory/tests/service/coverage_test.dart
index 7a8ee93..1266500 100644
--- a/runtime/observatory/tests/service/coverage_test.dart
+++ b/runtime/observatory/tests/service/coverage_test.dart
@@ -6,13 +6,18 @@
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
+import 'service_test_common.dart';
 import 'dart:developer';
 
+const int LINE_A = 20;
+const int LINE_B = 38;
+const int LINE_C = 136;
+
 int globalVar = 100;
 
 class MyClass {
   static void myFunction(int value) {
-    if (value < 0) {
+    if (value < 0) {  // Line A.
       print("negative");
     } else {
       print("positive");
@@ -30,7 +35,7 @@
 }
 
 void testFunction() {
-  MyClass.otherFunction(-100);
+  MyClass.otherFunction(-100);  // Line B.
   MyClass.myFunction(10000);
 }
 
@@ -60,7 +65,10 @@
   expect(coverage['type'], equals('CodeCoverage'));
   expect(coverage['coverage'].length, equals(1));
   expect(coverage['coverage'][0]['hits'],
-         equals([15, 1, 16, 0, 18, 1, 20, 1]));
+         equals([LINE_A, 1,
+                 LINE_A + 1, 0,
+                 LINE_A + 3, 1,
+                 LINE_A + 5, 1]));
 
   // Class
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage',
@@ -68,8 +76,14 @@
   expect(coverage['type'], equals('CodeCoverage'));
   expect(coverage['coverage'].length, equals(1));
   expect(coverage['coverage'][0]['hits'],
-         equals([15, 1, 16, 0, 18, 1, 20, 1,
-                 24, 1, 25, 1, 27, 0, 13, 0]));
+         equals([LINE_A, 1,
+                 LINE_A + 1, 0,
+                 LINE_A + 3, 1,
+                 LINE_A + 5, 1,
+                 LINE_A + 9, 1,
+                 LINE_A + 10, 1,
+                 LINE_A + 12, 0,
+                 LINE_A - 2, 0]));
 
   // Library
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage',
@@ -77,10 +91,18 @@
   expect(coverage['type'], equals('CodeCoverage'));
   expect(coverage['coverage'].length, equals(4));
   expect(coverage['coverage'][0]['hits'],
-         equals([15, 1, 16, 0, 18, 1, 20, 1,
-                 24, 1, 25, 1, 27, 0, 13, 0]));
+         equals([LINE_A, 1,
+                 LINE_A + 1, 0,
+                 LINE_A + 3, 1,
+                 LINE_A + 5, 1,
+                 LINE_A + 9, 1,
+                 LINE_A + 10, 1,
+                 LINE_A + 12, 0,
+                 LINE_A - 2, 0]));
   expect(coverage['coverage'][1]['hits'],
-         equals([33, 1, 34, 1, 106, 2]));
+         equals([LINE_B, 1,
+                 LINE_B + 1, 1,
+                 LINE_C, 2]));
 
   // Script
   await cls.load();
@@ -89,10 +111,18 @@
   expect(coverage['type'], equals('CodeCoverage'));
   expect(coverage['coverage'].length, equals(4));
   expect(coverage['coverage'][0]['hits'],
-         equals([15, 1, 16, 0, 18, 1, 20, 1,
-                 24, 1, 25, 1, 27, 0, 13, 0]));
+         equals([LINE_A, 1,
+                 LINE_A + 1, 0,
+                 LINE_A + 3, 1,
+                 LINE_A + 5, 1,
+                 LINE_A + 9, 1,
+                 LINE_A + 10, 1,
+                 LINE_A + 12, 0,
+                 LINE_A - 2, 0]));
   expect(coverage['coverage'][1]['hits'],
-         equals([33, 1, 34, 1, 106, 2]));
+         equals([LINE_B, 1,
+                 LINE_B + 1, 1,
+                 LINE_C, 2]));
 
   // Isolate
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage', {});
@@ -103,6 +133,6 @@
 
 ];
 
-main(args) => runIsolateTests(args, tests,
+main(args) => runIsolateTests(args, tests,    // Line C.
                               testeeConcurrent: testFunction,
                               trace_service: true);
diff --git a/runtime/observatory/tests/service/debugger_location_test.dart b/runtime/observatory/tests/service/debugger_location_test.dart
index ab50f4d..53ed4fb 100644
--- a/runtime/observatory/tests/service/debugger_location_test.dart
+++ b/runtime/observatory/tests/service/debugger_location_test.dart
@@ -6,15 +6,20 @@
 import 'package:observatory/service_io.dart';
 import 'package:observatory/debugger.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 import 'dart:async';
 import 'dart:developer';
 
+const int LINE_A = 22;
+const int LINE_B = 112;
+const int LINE_C = 12;
+
 void testFunction() {
   int i = 0;
   while (i == 0) {
     debugger();
-    print('loop');
+    print('loop');  // Line A.
     print('loop');
   }
 }
@@ -59,7 +64,7 @@
   var debugger = await initDebugger(isolate);
   var loc = await DebuggerLocation.parse(debugger, '');
   expect(loc.valid, isTrue);
-  expect(loc.toString(), equals('debugger_location_test.dart:17:5'));
+  expect(loc.toString(), equals('debugger_location_test.dart:$LINE_A:5'));
 },
 
 // Parse line
@@ -236,22 +241,18 @@
       await DebuggerLocation.complete(debugger,
                                       'debugger_location_test.dart:11');
   expect(completions.toString(), equals(
-      '[debugger_location_test.dart:110 ,'
-      ' debugger_location_test.dart:110:,'
-      ' debugger_location_test.dart:111 ,'
-      ' debugger_location_test.dart:111:,'
-      ' debugger_location_test.dart:112 ,'
-      ' debugger_location_test.dart:112:,'
-      ' debugger_location_test.dart:115 ,'
-      ' debugger_location_test.dart:115:,'
-      ' debugger_location_test.dart:116 ,'
-      ' debugger_location_test.dart:116:,'
-      ' debugger_location_test.dart:117 ,'
-      ' debugger_location_test.dart:117:,'
-      ' debugger_location_test.dart:118 ,'
-      ' debugger_location_test.dart:118:,'
-      ' debugger_location_test.dart:119 ,'
-      ' debugger_location_test.dart:119:]'));
+      '[debugger_location_test.dart:${LINE_B + 0} ,'
+      ' debugger_location_test.dart:${LINE_B + 0}:,'
+      ' debugger_location_test.dart:${LINE_B + 1} ,'
+      ' debugger_location_test.dart:${LINE_B + 1}:,'
+      ' debugger_location_test.dart:${LINE_B + 2} ,'
+      ' debugger_location_test.dart:${LINE_B + 2}:,'
+      ' debugger_location_test.dart:${LINE_B + 3} ,'
+      ' debugger_location_test.dart:${LINE_B + 3}:,'
+      ' debugger_location_test.dart:${LINE_B + 4} ,'
+      ' debugger_location_test.dart:${LINE_B + 4}:,'
+      ' debugger_location_test.dart:${LINE_B + 5} ,'
+      ' debugger_location_test.dart:${LINE_B + 5}:]'));
 },
 
 // Complete script:line:col
@@ -259,27 +260,27 @@
   var debugger = await initDebugger(isolate);
   var completions =
       await DebuggerLocation.complete(debugger,
-                                      'debugger_location_test.dart:11:2');
+                                      'debugger_location_test.dart:$LINE_C:2');
   expect(completions.toString(), equals(
-      '[debugger_location_test.dart:11:2 ,'
-      ' debugger_location_test.dart:11:20 ,'
-      ' debugger_location_test.dart:11:21 ,'
-      ' debugger_location_test.dart:11:22 ,'
-      ' debugger_location_test.dart:11:23 ,'
-      ' debugger_location_test.dart:11:24 ]'));
+      '[debugger_location_test.dart:$LINE_C:2 ,'
+      ' debugger_location_test.dart:$LINE_C:20 ,'
+      ' debugger_location_test.dart:$LINE_C:21 ,'
+      ' debugger_location_test.dart:$LINE_C:22 ,'
+      ' debugger_location_test.dart:$LINE_C:23 ,'
+      ' debugger_location_test.dart:$LINE_C:24 ]'));
 },
 
 // Complete without the script name.
 (Isolate isolate) async {
   var debugger = await initDebugger(isolate);
-  var completions = await DebuggerLocation.complete(debugger, '11:2');
+  var completions = await DebuggerLocation.complete(debugger, '$LINE_C:2');
   expect(completions.toString(), equals(
-      '[debugger_location_test.dart:11:2 ,'
-      ' debugger_location_test.dart:11:20 ,'
-      ' debugger_location_test.dart:11:21 ,'
-      ' debugger_location_test.dart:11:22 ,'
-      ' debugger_location_test.dart:11:23 ,'
-      ' debugger_location_test.dart:11:24 ]'));
+      '[debugger_location_test.dart:$LINE_C:2 ,'
+      ' debugger_location_test.dart:$LINE_C:20 ,'
+      ' debugger_location_test.dart:$LINE_C:21 ,'
+      ' debugger_location_test.dart:$LINE_C:22 ,'
+      ' debugger_location_test.dart:$LINE_C:23 ,'
+      ' debugger_location_test.dart:$LINE_C:24 ]'));
 },
 
 ];
diff --git a/runtime/observatory/tests/service/debugging_inlined_finally_test.dart b/runtime/observatory/tests/service/debugging_inlined_finally_test.dart
index 91ca4b2..7f867a2 100644
--- a/runtime/observatory/tests/service/debugging_inlined_finally_test.dart
+++ b/runtime/observatory/tests/service/debugging_inlined_finally_test.dart
@@ -5,9 +5,14 @@
 
 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 = 24;
+const int LINE_B = 27;
+const int LINE_C = 30;
+
 testFunction() {
   debugger();
   var a;
@@ -16,13 +21,13 @@
     try {
       for (int i = 0; i < 10; i++) {
         var x = () => i + a + b;
-        return x;  // line 19
+        return x;  // LINE_A
       }
     } finally {
-      b = 10;  // line 22
+      b = 10;  // LINE_B
     }
   } finally {
-    a = 1;  // line 25
+    a = 1;  // LINE_C
   }
 }
 
@@ -44,32 +49,35 @@
 
   // Add 3 breakpoints.
   {
-    var result = await isolate.addBreakpoint(script, 19);
+    var result = await isolate.addBreakpoint(script, LINE_A);
     expect(result is Breakpoint, isTrue);
     Breakpoint bpt = result;
     expect(bpt.type, equals('Breakpoint'));
     expect(bpt.location.script.id, equals(script.id));
-    expect(bpt.location.script.tokenToLine(bpt.location.tokenPos), equals(19));
+    expect(bpt.location.script.tokenToLine(bpt.location.tokenPos),
+           equals(LINE_A));
     expect(isolate.breakpoints.length, equals(1));
   }
 
   {
-    var result = await isolate.addBreakpoint(script, 22);
+    var result = await isolate.addBreakpoint(script, LINE_B);
     expect(result is Breakpoint, isTrue);
     Breakpoint bpt = result;
     expect(bpt.type, equals('Breakpoint'));
     expect(bpt.location.script.id, equals(script.id));
-    expect(bpt.location.script.tokenToLine(bpt.location.tokenPos), equals(22));
+    expect(bpt.location.script.tokenToLine(bpt.location.tokenPos),
+           equals(LINE_B));
     expect(isolate.breakpoints.length, equals(2));
   }
 
   {
-    var result = await isolate.addBreakpoint(script, 25);
+    var result = await isolate.addBreakpoint(script, LINE_C);
     expect(result is Breakpoint, isTrue);
     Breakpoint bpt = result;
     expect(bpt.type, equals('Breakpoint'));
     expect(bpt.location.script.id, equals(script.id));
-    expect(bpt.location.script.tokenToLine(bpt.location.tokenPos), equals(25));
+    expect(bpt.location.script.tokenToLine(bpt.location.tokenPos),
+           equals(LINE_C));
     expect(isolate.breakpoints.length, equals(3));
   }
 
@@ -80,42 +88,45 @@
 
 hasStoppedAtBreakpoint,
 
-// We are at the breakpoint on line 19.
+// We are at the breakpoint on line LINE_A.
 (Isolate isolate) async {
   ServiceMap stack = await isolate.getStack();
   expect(stack.type, equals('Stack'));
   expect(stack['frames'].length, greaterThanOrEqualTo(1));
 
   Script script = stack['frames'][0].location.script;
-  expect(script.tokenToLine(stack['frames'][0].location.tokenPos), equals(19));
+  expect(script.tokenToLine(stack['frames'][0].location.tokenPos),
+         equals(LINE_A));
 },
 
 resumeIsolate,
 
 hasStoppedAtBreakpoint,
 
-// We are at the breakpoint on line 22.
+// We are at the breakpoint on line LINE_B.
 (Isolate isolate) async {
   ServiceMap stack = await isolate.getStack();
   expect(stack.type, equals('Stack'));
   expect(stack['frames'].length, greaterThanOrEqualTo(1));
 
   Script script = stack['frames'][0].location.script;
-  expect(script.tokenToLine(stack['frames'][0].location.tokenPos), equals(22));
+  expect(script.tokenToLine(stack['frames'][0].location.tokenPos),
+         equals(LINE_B));
 },
 
 resumeIsolate,
 
 hasStoppedAtBreakpoint,
 
-// We are at the breakpoint on line 25.
+// We are at the breakpoint on line LINE_C.
 (Isolate isolate) async {
   ServiceMap stack = await isolate.getStack();
   expect(stack.type, equals('Stack'));
   expect(stack['frames'].length, greaterThanOrEqualTo(1));
 
   Script script = stack['frames'][0].location.script;
-  expect(script.tokenToLine(stack['frames'][0].location.tokenPos), equals(25));
+  expect(script.tokenToLine(stack['frames'][0].location.tokenPos),
+         equals(LINE_C));
 },
 
 resumeIsolate,
diff --git a/runtime/observatory/tests/service/developer_extension_test.dart b/runtime/observatory/tests/service/developer_extension_test.dart
index b4bafac..f8cd30f 100644
--- a/runtime/observatory/tests/service/developer_extension_test.dart
+++ b/runtime/observatory/tests/service/developer_extension_test.dart
@@ -9,7 +9,7 @@
 import 'package:observatory/service_io.dart';
 import 'package:observatory/cpu_profile.dart';
 import 'package:unittest/unittest.dart';
-
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 Future<ServiceExtensionResponse> Handler(String method,
diff --git a/runtime/observatory/tests/service/eval_test.dart b/runtime/observatory/tests/service/eval_test.dart
index 99dfe8f..d41a70b 100644
--- a/runtime/observatory/tests/service/eval_test.dart
+++ b/runtime/observatory/tests/service/eval_test.dart
@@ -7,6 +7,7 @@
 import 'dart:developer';
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 int globalVar = 100;
diff --git a/runtime/observatory/tests/service/evaluate_in_frame_rpc_test.dart b/runtime/observatory/tests/service/evaluate_in_frame_rpc_test.dart
index 053fd15..2c73fe6 100644
--- a/runtime/observatory/tests/service/evaluate_in_frame_rpc_test.dart
+++ b/runtime/observatory/tests/service/evaluate_in_frame_rpc_test.dart
@@ -3,10 +3,10 @@
 // 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:developer';
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 void method(int value, _) {
diff --git a/runtime/observatory/tests/service/get_allocation_samples_test.dart b/runtime/observatory/tests/service/get_allocation_samples_test.dart
index 19d8a86..87615c9 100644
--- a/runtime/observatory/tests/service/get_allocation_samples_test.dart
+++ b/runtime/observatory/tests/service/get_allocation_samples_test.dart
@@ -7,7 +7,7 @@
 import 'package:observatory/service_io.dart';
 import 'package:observatory/cpu_profile.dart';
 import 'package:unittest/unittest.dart';
-
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 class Foo {
@@ -67,8 +67,7 @@
     var tree = cpuProfile.loadCodeTree('exclusive');
     var node = tree.root;
     var expected =
-        ['Root', 'test', 'test', '_Closure.call',
-         'runIsolateTests.<runIsolateTests_async_body>'];
+        ['Root', 'test', 'test', '_Closure.call'];
     for (var i = 0; i < expected.length; i++) {
       expect(node.profileCode.code.name, equals(expected[i]));
       // Depth first traversal.
diff --git a/runtime/observatory/tests/service/get_source_report_test.dart b/runtime/observatory/tests/service/get_source_report_test.dart
index d306bca..006ef5b 100644
--- a/runtime/observatory/tests/service/get_source_report_test.dart
+++ b/runtime/observatory/tests/service/get_source_report_test.dart
@@ -6,6 +6,7 @@
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
+import 'service_test_common.dart';
 import 'dart:developer';
 
 int globalVar = 100;
@@ -62,10 +63,10 @@
 
   var expectedRange = {
     'scriptIndex': 0,
-    'startPos': 33,
-    'endPos': 82,
+    'startPos': 38,
+    'endPos': 87,
     'compiled': true,
-    'coverage': {'hits': [48, 66, 76], 'misses': [54]}
+    'coverage': {'hits': [53, 71, 81], 'misses': [59]}
   };
 
   // Full script
diff --git a/runtime/observatory/tests/service/get_stack_rpc_test.dart b/runtime/observatory/tests/service/get_stack_rpc_test.dart
index 7757819..7efc7e7 100644
--- a/runtime/observatory/tests/service/get_stack_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_stack_rpc_test.dart
@@ -5,13 +5,14 @@
 
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 import 'dart:async';
 import 'dart:isolate' as isolate;
 import 'dart:developer' as developer;
 
 int counter = 0;
-const stoppedAtLine = 23;
+const stoppedAtLine = 24;
 var port = new isolate.RawReceivePort(msgHandler);
 
 // This name is used in a test below.
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 779c690..d4c4913 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -13,7 +13,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(2));
+    expect(result['minor'], equals(3));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/isolate_lifecycle_test.dart b/runtime/observatory/tests/service/isolate_lifecycle_test.dart
index f88b123..992b100 100644
--- a/runtime/observatory/tests/service/isolate_lifecycle_test.dart
+++ b/runtime/observatory/tests/service/isolate_lifecycle_test.dart
@@ -9,7 +9,7 @@
 
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
-
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 final spawnCount = 4;
@@ -131,7 +131,7 @@
   },
 
   (VM vm) async {
-    expect(numPaused(vm), spawnCount + 1 - resumeCount); 
+    expect(numPaused(vm), spawnCount + 1 - resumeCount);
   },
 ];
 
diff --git a/runtime/observatory/tests/service/issue_25465_test.dart b/runtime/observatory/tests/service/issue_25465_test.dart
index 3a739f0..21f91bd 100644
--- a/runtime/observatory/tests/service/issue_25465_test.dart
+++ b/runtime/observatory/tests/service/issue_25465_test.dart
@@ -6,11 +6,15 @@
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
+import 'service_test_common.dart';
 import 'dart:async';
 
+const int LINE_A = 16;
+const int LINE_B = 17;
+
 testMain() {
-  var foo;      // line 11
-  foo = 42;     // line 12
+  var foo;      // line A
+  foo = 42;     // line B
   print(foo);
 }
 
@@ -23,10 +27,10 @@
     await rootLib.load();
     var script = rootLib.scripts[0];
 
-    var bpt1 = await isolate.addBreakpoint(script, 11);
-    var bpt2 = await isolate.addBreakpoint(script, 12);
-    expect(await bpt1.location.getLine(), equals(11));
-    expect(await bpt2.location.getLine(), equals(12));
+    var bpt1 = await isolate.addBreakpoint(script, LINE_A);
+    var bpt2 = await isolate.addBreakpoint(script, LINE_B);
+    expect(await bpt1.location.getLine(), equals(LINE_A));
+    expect(await bpt2.location.getLine(), equals(LINE_B));
 
     var stream = await isolate.vm.getEventStream(VM.kDebugStream);
     Completer completer = new Completer();
@@ -52,9 +56,9 @@
           // No breakpoint.
           expect(event.breakpoint, isNull);
 
-          // We expect the next step to take us to line 12.
+          // We expect the next step to take us to line B.
           var stack = await isolate.getStack();
-          expect(await stack['frames'][0].location.getLine(), equals(12));
+          expect(await stack['frames'][0].location.getLine(), equals(LINE_B));
 
           subscription.cancel();
           completer.complete(null);
diff --git a/runtime/observatory/tests/service/logging_test.dart b/runtime/observatory/tests/service/logging_test.dart
index b8839f1..777412f 100644
--- a/runtime/observatory/tests/service/logging_test.dart
+++ b/runtime/observatory/tests/service/logging_test.dart
@@ -6,7 +6,7 @@
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
 import 'package:logging/logging.dart';
-
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 void init() {
diff --git a/runtime/observatory/tests/service/parameters_in_scope_at_entry_test.dart b/runtime/observatory/tests/service/parameters_in_scope_at_entry_test.dart
index 0e4209a..7f90eec 100644
--- a/runtime/observatory/tests/service/parameters_in_scope_at_entry_test.dart
+++ b/runtime/observatory/tests/service/parameters_in_scope_at_entry_test.dart
@@ -8,6 +8,11 @@
 import 'dart:developer';
 import 'package:unittest/unittest.dart';
 
+import 'service_test_common.dart';
+
+const int LINE_A = 29;
+const int LINE_B = 33;
+
 foo(param) {
   return param;
 }
@@ -21,16 +26,16 @@
 
 testMain() {
   debugger();
-  foo("in-scope");  // Line 24
+  foo("in-scope");  // Line A.
 
   var f = fooClosure();
   debugger();
-  f("in-scope");  // Line 28
+  f("in-scope");  // Line B.
 }
 
 var tests = [
   hasStoppedAtBreakpoint,
-  stoppedAtLine(24),
+  stoppedAtLine(LINE_A),
   (isolate) => isolate.stepInto(),
   hasStoppedAtBreakpoint,
   (isolate) async {
@@ -47,7 +52,7 @@
   resumeIsolate,
 
   hasStoppedAtBreakpoint,
-  stoppedAtLine(28),
+  stoppedAtLine(LINE_B),
   (isolate) => isolate.stepInto(),
   hasStoppedAtBreakpoint,
   (isolate) async {
diff --git a/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart b/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart
index e9f233b..2e09acc 100644
--- a/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart
+++ b/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart
@@ -6,7 +6,7 @@
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
-import 'dart:async';
+import 'service_test_common.dart';
 
 doThrow() {
   throw "TheException"; // Line 13.
diff --git a/runtime/observatory/tests/service/reachable_size_test.dart b/runtime/observatory/tests/service/reachable_size_test.dart
index 5c346e3..ae6827e 100644
--- a/runtime/observatory/tests/service/reachable_size_test.dart
+++ b/runtime/observatory/tests/service/reachable_size_test.dart
@@ -6,6 +6,7 @@
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
 import 'test_helper.dart';
+import 'service_test_common.dart';
 
 class Pair {
   var x, y;
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index e990d12..0e3d8fd 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -30,3 +30,7 @@
 # Service protocol is not supported in product mode.
 [ $mode == product ]
 *: SkipByDesign
+
+# Service protocol is not supported when running a full application snapshot.
+[ ($runtime == dart_product) ]
+*: SkipByDesign
diff --git a/runtime/observatory/tests/service/service_test_common.dart b/runtime/observatory/tests/service/service_test_common.dart
new file mode 100644
index 0000000..7435ee5
--- /dev/null
+++ b/runtime/observatory/tests/service/service_test_common.dart
@@ -0,0 +1,236 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library service_test_common;
+
+import 'dart:async';
+import 'package:observatory/service_common.dart';
+import 'package:unittest/unittest.dart';
+
+typedef Future IsolateTest(Isolate isolate);
+typedef Future VMTest(VM vm);
+
+Future asyncStepOver(Isolate isolate) async {
+  final Completer pausedAtSyntheticBreakpoint = new Completer();
+  StreamSubscription subscription;
+
+  // Cancel the subscription.
+  cancelSubscription() {
+    if (subscription != null) {
+      subscription.cancel();
+      subscription = null;
+    }
+  }
+
+  // Complete futures with with error.
+  completeError(error) {
+    if (!pausedAtSyntheticBreakpoint.isCompleted) {
+      pausedAtSyntheticBreakpoint.completeError(error);
+    }
+  }
+
+  // Subscribe to the debugger event stream.
+  Stream stream;
+  try {
+    stream = await isolate.vm.getEventStream(VM.kDebugStream);
+  } catch (e) {
+    completeError(e);
+    return pausedAtSyntheticBreakpoint.future;
+  }
+
+  Breakpoint syntheticBreakpoint;
+
+  subscription = stream.listen((ServiceEvent event) async {
+    // Synthetic breakpoint add event. This is the first event we will
+    // receive.
+    bool isAdd = (event.kind == ServiceEvent.kBreakpointAdded) &&
+                 (event.breakpoint.isSyntheticAsyncContinuation) &&
+                 (event.owner == isolate);
+    // Resume after synthetic breakpoint added. This is the second event
+    // we will recieve.
+    bool isResume = (event.kind == ServiceEvent.kResume) &&
+                    (syntheticBreakpoint != null) &&
+                    (event.owner == isolate);
+    // Paused at synthetic breakpoint. This is the third event we will
+    // receive.
+    bool isPaused = (event.kind == ServiceEvent.kPauseBreakpoint) &&
+                    (syntheticBreakpoint != null) &&
+                    (event.breakpoint == syntheticBreakpoint);
+    if (isAdd) {
+      syntheticBreakpoint = event.breakpoint;
+    } else if (isResume) {
+    } else if (isPaused) {
+      pausedAtSyntheticBreakpoint.complete(isolate);
+      syntheticBreakpoint = null;
+      cancelSubscription();
+    }
+  });
+
+  // Issue the step OverAwait command.
+  try {
+    await isolate.stepOverAsyncSuspension();
+  } catch (e) {
+    // This can fail when another client issued the same resume command
+    // or another client has moved the isolate forward.
+    cancelSubscription();
+    completeError(e);
+  }
+
+  return pausedAtSyntheticBreakpoint.future;
+}
+
+
+Future<Isolate> hasPausedFor(Isolate isolate, String kind) {
+  // Set up a listener to wait for breakpoint events.
+  Completer completer = new Completer();
+  isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
+    var subscription;
+    subscription = stream.listen((ServiceEvent event) {
+        if (event.kind == kind) {
+          print('Paused with $kind');
+          subscription.cancel();
+          if (completer != null) {
+            // Reload to update isolate.pauseEvent.
+            completer.complete(isolate.reload());
+            completer = null;
+          }
+        }
+    });
+
+    // Pause may have happened before we subscribed.
+    isolate.reload().then((_) {
+      if ((isolate.pauseEvent != null) &&
+         (isolate.pauseEvent.kind == kind)) {
+        // Already waiting at a breakpoint.
+        print('Paused with $kind');
+        subscription.cancel();
+        if (completer != null) {
+          completer.complete(isolate);
+          completer = null;
+        }
+      }
+    });
+  });
+
+  return completer.future;  // Will complete when breakpoint hit.
+}
+
+Future<Isolate> hasStoppedAtBreakpoint(Isolate isolate) {
+  return hasPausedFor(isolate, ServiceEvent.kPauseBreakpoint);
+}
+
+Future<Isolate> hasStoppedWithUnhandledException(Isolate isolate) {
+  return hasPausedFor(isolate, ServiceEvent.kPauseException);
+}
+
+Future<Isolate> hasPausedAtStart(Isolate isolate) {
+  return hasPausedFor(isolate, ServiceEvent.kPauseStart);
+}
+
+// Currying is your friend.
+IsolateTest setBreakpointAtLine(int line) {
+  return (Isolate isolate) async {
+    print("Setting breakpoint for line $line");
+    Library lib = await isolate.rootLibrary.load();
+    Script script = lib.scripts.single;
+
+    Breakpoint bpt = await isolate.addBreakpoint(script, line);
+    print("Breakpoint is $bpt");
+    expect(bpt, isNotNull);
+    expect(bpt is Breakpoint, isTrue);
+  };
+}
+
+IsolateTest stoppedAtLine(int line) {
+  return (Isolate isolate) async {
+    print("Checking we are at line $line");
+
+    ServiceMap stack = await isolate.getStack();
+    expect(stack.type, equals('Stack'));
+
+    List<Frame> frames = stack['frames'];
+    expect(frames.length, greaterThanOrEqualTo(1));
+
+    Frame top = frames[0];
+    Script script = await top.location.script.load();
+    int actualLine = script.tokenToLine(top.location.tokenPos);
+    if (actualLine != line) {
+      var sb = new StringBuffer();
+      sb.write("Expected to be at line $line but actually at line $actualLine");
+      sb.write("\nFull stack trace:\n");
+      for (Frame f in stack['frames']) {
+        sb.write(" $f [${await f.location.getLine()}]\n");
+      }
+      throw sb.toString();
+    }
+  };
+}
+
+
+Future<Isolate> resumeIsolate(Isolate isolate) {
+  Completer completer = new Completer();
+  isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
+    var subscription;
+    subscription = stream.listen((ServiceEvent event) {
+      if (event.kind == ServiceEvent.kResume) {
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+  });
+  isolate.resume();
+  return completer.future;
+}
+
+
+Future resumeAndAwaitEvent(Isolate isolate, stream, onEvent) async {
+  Completer completer = new Completer();
+  var sub;
+  sub = await isolate.vm.listenEventStream(
+    stream,
+    (ServiceEvent event) {
+      var r = onEvent(event);
+      if (r is! Future) {
+        r = new Future.value(r);
+      }
+      r.then((x) => sub.cancel().then((_) {
+        completer.complete();
+      }));
+    });
+  await isolate.resume();
+  return completer.future;
+}
+
+IsolateTest resumeIsolateAndAwaitEvent(stream, onEvent) {
+  return (Isolate isolate) async =>
+      resumeAndAwaitEvent(isolate, stream, onEvent);
+}
+
+
+Future<Isolate> stepOver(Isolate isolate) async {
+  await isolate.stepOver();
+  return hasStoppedAtBreakpoint(isolate);
+}
+
+Future<Class> getClassFromRootLib(Isolate isolate, String className) async {
+  Library rootLib = await isolate.rootLibrary.load();
+  for (var i = 0; i < rootLib.classes.length; i++) {
+    Class cls = rootLib.classes[i];
+    if (cls.name == className) {
+      return cls;
+    }
+  }
+  return null;
+}
+
+
+Future<Instance> rootLibraryFieldValue(Isolate isolate,
+                                       String fieldName) async {
+  Library rootLib = await isolate.rootLibrary.load();
+  Field field = rootLib.variables.singleWhere((v) => v.name == fieldName);
+  await field.load();
+  Instance value = field.staticValue;
+  await value.load();
+  return value;
+}
diff --git a/runtime/observatory/tests/service/smart_next_test.dart b/runtime/observatory/tests/service/smart_next_test.dart
index 34bac34..e0576a7 100644
--- a/runtime/observatory/tests/service/smart_next_test.dart
+++ b/runtime/observatory/tests/service/smart_next_test.dart
@@ -7,18 +7,21 @@
 import 'test_helper.dart';
 import 'dart:async';
 import 'dart:developer';
+import 'service_test_common.dart';
+
+const int LINE_A = 19;
 
 foo() async { }
 bar() { }
 
 doAsync(stop) async {
   if (stop) debugger();
-  await foo(); // Line 16.
-  bar();       // Line 17.
-  bar();       // Line 18.
-  await foo(); // Line 19.
-  await foo(); // Line 20.
-  bar();       // Line 21.
+  await foo(); // Line A.
+  bar();       // Line A + 1.
+  bar();       // Line A + 2.
+  await foo(); // Line A + 3.
+  await foo(); // Line A + 4.
+  bar();       // Line A + 5.
   return null;
 }
 
@@ -45,10 +48,9 @@
 }
 
 smartNext(Isolate isolate) async {
-  if (isolate.pauseEvent.atAsyncJump) {
+  if (isolate.pauseEvent.atAsyncSuspension) {
     print("next-async");
-    List asyncStepFutures = await isolate.asyncStepOver();
-    return asyncStepFutures[Isolate.kSecondResume];
+    return asyncStepOver(isolate);
   } else {
     print("next-sync");
     return stepOverAwaitingResume(isolate);
@@ -56,15 +58,15 @@
 }
 
 var tests = [
-             hasStoppedAtBreakpoint, stoppedAtLine(16), // foo()
-  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(16), // await
-  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(17), // bar()
-  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(18), // bar()
-  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(19), // foo()
-  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(19), // await
-  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(20), // foo()
-  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(20), // await
-  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(21), // bar()
+             hasStoppedAtBreakpoint, stoppedAtLine(LINE_A), // foo()
+  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(LINE_A), // await
+  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(LINE_A + 1), // bar()
+  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(LINE_A + 2), // bar()
+  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(LINE_A + 3), // foo()
+  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(LINE_A + 3), // await
+  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(LINE_A + 4), // foo()
+  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(LINE_A + 4), // await
+  smartNext, hasStoppedAtBreakpoint, stoppedAtLine(LINE_A + 5), // bar()
   resumeIsolate,
 ];
 
diff --git a/runtime/observatory/tests/service/step_into_async_no_await_test.dart b/runtime/observatory/tests/service/step_into_async_no_await_test.dart
index f9dddd5..fcae338 100644
--- a/runtime/observatory/tests/service/step_into_async_no_await_test.dart
+++ b/runtime/observatory/tests/service/step_into_async_no_await_test.dart
@@ -5,6 +5,9 @@
 
 import 'test_helper.dart';
 import 'dart:developer';
+import 'service_test_common.dart';
+
+const int LINE_A = 20;
 
 // :async_op will not be captured in this function because it never needs to
 // reschedule it.
@@ -14,12 +17,12 @@
 
 testMain() {
   debugger();
-  asyncWithoutAwait();  // Line 17
+  asyncWithoutAwait();  // Line A.
 }
 
 var tests = [
   hasStoppedAtBreakpoint,
-  stoppedAtLine(17),
+  stoppedAtLine(LINE_A),
   (isolate) => isolate.stepInto(),
   hasStoppedAtBreakpoint,
   (isolate) => isolate.getStack(),  // Should not crash.
diff --git a/runtime/observatory/tests/service/step_over_await_test.dart b/runtime/observatory/tests/service/step_over_await_test.dart
new file mode 100644
index 0000000..4f57a52
--- /dev/null
+++ b/runtime/observatory/tests/service/step_over_await_test.dart
@@ -0,0 +1,176 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for 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 --trace_service
+
+import 'dart:async';
+import 'dart:developer';
+
+import 'test_helper.dart';
+import 'service_test_common.dart';
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+
+const int LINE_A = 24;
+const int LINE_B = 26;
+const int LINE_C = 28;
+const int LINE_D = 29;
+
+// This tests the low level synthetic breakpoint added / paused / removed
+// machinery triggered by the step OverAwait command.
+asyncWithoutAwait() async {
+  debugger();
+  print('a');  // LINE_A
+  await new Future.delayed(new Duration(seconds: 2));
+  print('b');  // LINE_B
+  debugger();  // LINE_C
+  debugger();  // LINE_D
+}
+
+testMain() {
+  asyncWithoutAwait();
+}
+
+Breakpoint syntheticBreakpoint;
+
+Future<Isolate> testLowLevelAwaitOver(
+    Isolate isolate) {
+  assert(isolate.pauseEvent.atAsyncSuspension);
+
+  int state = 0;
+  bool firstResume = true;
+  handleBreakpointAdded(ServiceEvent event) {
+    expect(syntheticBreakpoint, isNull);
+    expect(state, 0);
+    if (!event.breakpoint.isSyntheticAsyncContinuation) {
+      // Not a synthetic async breakpoint.
+      return;
+    }
+    if (event.owner != isolate) {
+      // Wrong isolate.
+      return;
+    }
+    syntheticBreakpoint = event.breakpoint;
+    print('!!!! Synthetic async breakpoint added ${syntheticBreakpoint}');
+    state = 1;
+  }
+
+  handleResume(ServiceEvent event) {
+    if (firstResume) {
+      expect(state, 1);
+      if (event.owner != isolate) {
+        // Wrong isolate.
+        return;
+      }
+      print('!!!! Got first resume.');
+      state = 2;
+      firstResume = false;
+    } else {
+      expect(state, 3);
+      if (event.owner != isolate) {
+        // Wrong isolate.
+        return;
+      }
+      print('!!!! Got second resume.');
+      state = 4;
+    }
+
+  }
+
+  handlePauseBreakpoint(ServiceEvent event) {
+    expect(syntheticBreakpoint, isNotNull);
+    expect(state, 2);
+    if (!event.breakpoint.isSyntheticAsyncContinuation) {
+      // Not a synthetic async breakpoint.
+      return;
+    }
+    if (event.owner != isolate) {
+      // Wrong isolate.
+      return;
+    }
+    expect(event.breakpoint, equals(syntheticBreakpoint));
+    print('!!!! Paused at synthetic async breakpoint ${syntheticBreakpoint}');
+    state = 3;
+  }
+
+  handleBreakpointRemoved(ServiceEvent event) {
+    expect(syntheticBreakpoint, isNotNull);
+    expect(state, 4);
+    if (!event.breakpoint.isSyntheticAsyncContinuation) {
+      // Not a synthetic async breakpoint.
+      return;
+    }
+    if (event.owner != isolate) {
+      // Wrong isolate.
+      return;
+    }
+    expect(event.breakpoint, equals(syntheticBreakpoint));
+    print('!!!! Synthetic async breakpoint removed ${syntheticBreakpoint}');
+    state = 5;
+    syntheticBreakpoint = null;
+  }
+
+  // Set up a listener to wait for debugger events.
+  Completer completer = new Completer();
+  isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
+    var subscription;
+    subscription = stream.listen((ServiceEvent event) async {
+      if (event.kind == ServiceEvent.kBreakpointAdded) {
+        handleBreakpointAdded(event);
+        expect(state, 1);
+      } else if (event.kind == ServiceEvent.kResume) {
+        if (firstResume) {
+          handleResume(event);
+          expect(state, 2);
+        } else {
+          handleResume(event);
+          expect(state, 4);
+        }
+      } else if (event.kind == ServiceEvent.kPauseBreakpoint) {
+        handlePauseBreakpoint(event);
+        expect(state, 3);
+        // Check that we are paused after the await statement.
+        await (stoppedAtLine(LINE_B)(isolate));
+        // Resume the isolate so that we trigger the breakpoint removal.
+        print('!!!! Triggering synthetic breakpoint removal.');
+        isolate.resume();
+      } else if (event.kind == ServiceEvent.kBreakpointRemoved) {
+        handleBreakpointRemoved(event);
+        expect(state, 5);
+        subscription.cancel();
+        if (completer != null) {
+          // Reload to update isolate.pauseEvent.
+          completer.complete(isolate.reload());
+          completer = null;
+        }
+      }
+    });
+  });
+
+  isolate.stepOverAsyncSuspension();
+
+  return completer.future;  // Will complete when breakpoint added.
+}
+
+
+var tests = [
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_A),
+  stepOver,
+  stepOver,
+  stepOver,
+  (Isolate isolate) async {
+    expect(isolate.pauseEvent.atAsyncSuspension, isTrue);
+    expect(syntheticBreakpoint, isNull);
+  },
+  testLowLevelAwaitOver,
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_C),
+  resumeIsolate,
+  hasStoppedAtBreakpoint,
+  stoppedAtLine(LINE_D),
+  resumeIsolate,
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testMain);
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 1920369..91cb11e 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -8,29 +8,88 @@
 import 'dart:convert';
 import 'dart:io';
 import 'package:observatory/service_io.dart';
-import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+
+/// Will be set to the http address of the VM's service protocol before
+/// any tests are invoked.
+String serviceHttpAddress;
+String serviceWebsocketAddress;
 
 bool _isWebSocketDisconnect(e) {
   return e is NetworkRpcException;
 }
 
-// This invocation should set up the state being tested.
-const String _TESTEE_MODE_FLAG = "--testee-mode";
+const String _TESTEE_ENV_KEY = 'SERVICE_TEST_TESTEE';
+const Map<String, String> _TESTEE_SPAWN_ENV = const {
+  _TESTEE_ENV_KEY: 'true'
+};
+bool _isTestee() {
+  return Platform.environment.containsKey(_TESTEE_ENV_KEY);
+}
 
-class _TestLauncher {
+class _SerivceTesteeRunner {
+  Future run({testeeBefore(): null,
+              testeeConcurrent(): null,
+              bool pause_on_start: false,
+              bool pause_on_exit: false}) async {
+    if (!pause_on_start) {
+      if (testeeBefore != null) {
+        var result = testeeBefore();
+        if (result is Future) {
+          await result;
+        }
+      }
+      print(''); // Print blank line to signal that testeeBefore has run.
+    }
+    if (testeeConcurrent != null) {
+      var result = testeeConcurrent();
+      if (result is Future) {
+        await result;
+      }
+    }
+    if (!pause_on_exit) {
+      // Wait around for the process to be killed.
+      stdin.first.then((_) => exit(0));
+    }
+  }
+
+  void runSync({void testeeBeforeSync(): null,
+                void testeeConcurrentSync(): null,
+                bool pause_on_start: false,
+                bool pause_on_exit: false}) {
+    if (!pause_on_start) {
+      if (testeeBeforeSync != null) {
+        testeeBeforeSync();
+      }
+      print(''); // Print blank line to signal that testeeBefore has run.
+    }
+    if (testeeConcurrentSync != null) {
+      testeeConcurrentSync();
+    }
+    if (!pause_on_exit) {
+      // Wait around for the process to be killed.
+      stdin.first.then((_) => exit(0));
+    }
+  }
+}
+
+class _ServiceTesteeLauncher {
   Process process;
   final List<String> args;
   bool killedByTester = false;
 
-  _TestLauncher() : args = ['--enable-vm-service:0',
-                            Platform.script.toFilePath(),
-                            _TESTEE_MODE_FLAG] {}
+  _ServiceTesteeLauncher() :
+      args = ['--enable-vm-service:0',
+              Platform.script.toFilePath()] {}
 
-  Future<int> launch(bool pause_on_start,
-                     bool pause_on_exit,
-                     bool pause_on_unhandled_exceptions,
-                     bool trace_service,
-                     bool trace_compiler) {
+  String get executablePath => Platform.executable;
+
+  // Spawn the testee process.
+  Future<Process> _spawnProcess(bool pause_on_start,
+                                bool pause_on_exit,
+                                bool pause_on_unhandled_exceptions,
+                                bool trace_service,
+                                bool trace_compiler) {
     assert(pause_on_start != null);
     assert(pause_on_exit != null);
     assert(trace_service != null);
@@ -58,8 +117,21 @@
     fullArgs.addAll(Platform.executableArguments);
     fullArgs.addAll(args);
     print('** Launching $dartExecutable ${fullArgs.join(' ')}');
-    return Process.start(dartExecutable, fullArgs).then((p) {
+    return Process.start(dartExecutable,
+                         fullArgs,
+                         environment: _TESTEE_SPAWN_ENV);
+  }
 
+  Future<int> launch(bool pause_on_start,
+                     bool pause_on_exit,
+                     bool pause_on_unhandled_exceptions,
+                     bool trace_service,
+                     bool trace_compiler) {
+    return _spawnProcess(pause_on_start,
+                  pause_on_exit,
+                  pause_on_unhandled_exceptions,
+                  trace_service,
+                  trace_compiler).then((p) {
       Completer completer = new Completer();
       process = p;
       var portNumber;
@@ -106,67 +178,57 @@
   }
 }
 
-typedef Future IsolateTest(Isolate isolate);
-typedef Future VMTest(VM vm);
-
-/// Will be set to the http address of the VM's service protocol before
-/// any tests are invoked.
-String serviceHttpAddress;
-
-/// Runs [tests] in sequence, each of which should take an [Isolate] and
-/// return a [Future]. Code for setting up state can run before and/or
-/// concurrently with the tests. Uses [mainArgs] to determine whether
-/// to run tests or testee in this invokation of the script.
-Future runIsolateTests(List<String> mainArgs,
-                       List<IsolateTest> tests,
-                       {testeeBefore(),
-                        void testeeConcurrent(),
-                        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}) async {
-  assert(!pause_on_start || testeeBefore == null);
-  if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
-    if (!pause_on_start) {
-      if (testeeBefore != null) {
-        var result = testeeBefore();
-        if (result is Future) {
-          await result;
-        }
-      }
-      print(''); // Print blank line to signal that we are ready.
-    }
-    if (testeeConcurrent != null) {
-      testeeConcurrent();
-    }
-    if (!pause_on_exit) {
-      // Wait around for the process to be killed.
-      stdin.first.then((_) => exit(0));
-    }
-  } else {
-    var process = new _TestLauncher();
+class _ServiceTesterRunner {
+  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 process = new _ServiceTesteeLauncher();
     process.launch(pause_on_start, pause_on_exit,
                    pause_on_unhandled_exceptions,
-                   trace_service, trace_compiler).then((port) {
+                   trace_service, trace_compiler).then((port) async {
       if (mainArgs.contains("--gdb")) {
         port = 8181;
       }
-      String addr = 'ws://localhost:$port/ws';
+      serviceWebsocketAddress = 'ws://localhost:$port/ws';
       serviceHttpAddress = 'http://localhost:$port';
-      var testIndex = 1;
-      var totalTests = tests.length;
       var name = Platform.script.pathSegments.last;
       runZoned(() {
-        new WebSocketVM(new WebSocketVMTarget(addr)).load()
-            .then((VM vm) => vm.isolates.first.load())
-            .then((Isolate isolate) => Future.forEach(tests, (test) {
-              isolate.vm.verbose = verbose_vm;
-              print('Running $name [$testIndex/$totalTests]');
-              testIndex++;
-              return test(isolate);
-            })).then((_) => process.requestExit());
+        new WebSocketVM(new WebSocketVMTarget(serviceWebsocketAddress)).load()
+            .then((VM vm) async {
+
+              // 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);
+                }
+              }
+
+              await process.requestExit();
+            });
       }, onError: (e, st) {
         process.requestExit();
         if (!_isWebSocketDisconnect(e)) {
@@ -182,14 +244,44 @@
 /// return a [Future]. Code for setting up state can run before and/or
 /// concurrently with the tests. Uses [mainArgs] to determine whether
 /// to run tests or testee in this invokation of the script.
+Future runIsolateTests(List<String> mainArgs,
+                       List<IsolateTest> tests,
+                       {testeeBefore(),
+                        testeeConcurrent(),
+                        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}) async {
+  assert(!pause_on_start || testeeBefore == null);
+  if (_isTestee()) {
+    new _SerivceTesteeRunner().run(testeeBefore: testeeBefore,
+                                   testeeConcurrent: testeeConcurrent,
+                                   pause_on_start: pause_on_start,
+                                   pause_on_exit: pause_on_exit);
+  } else {
+    new _ServiceTesterRunner().run(
+        mainArgs: mainArgs,
+        isolateTests: tests,
+        pause_on_start: pause_on_start,
+        pause_on_exit: pause_on_exit,
+        trace_service: trace_service,
+        trace_compiler: trace_compiler,
+        verbose_vm: verbose_vm,
+        pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
+  }
+}
+
+/// Runs [tests] in sequence, each of which should take an [Isolate] and
+/// return a [Future]. Code for setting up state can run before and/or
+/// concurrently with the tests. Uses [mainArgs] to determine whether
+/// to run tests or testee in this invokation of the script.
 ///
 /// This is a special version of this test harness specifically for the
 /// pause_on_unhandled_exceptions_test, which cannot properly function
 /// in an async context (because exceptions are *always* handled in async
 /// functions).
-///
-/// TODO(johnmccutchan): Don't use the shared harness for the
-/// pause_on_unhandled_exceptions_test.
 void runIsolateTestsSynchronous(List<String> mainArgs,
                                 List<IsolateTest> tests,
                                 {void testeeBefore(),
@@ -201,202 +293,24 @@
                                  bool verbose_vm: false,
                                  bool pause_on_unhandled_exceptions: false}) {
   assert(!pause_on_start || testeeBefore == null);
-  if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
-    if (!pause_on_start) {
-      if (testeeBefore != null) {
-        testeeBefore();
-      }
-      print(''); // Print blank line to signal that we are ready.
-    }
-    if (testeeConcurrent != null) {
-      testeeConcurrent();
-    }
-    if (!pause_on_exit) {
-      // Wait around for the process to be killed.
-      stdin.first.then((_) => exit(0));
-    }
+  if (_isTestee()) {
+    new _SerivceTesteeRunner().runSync(testeeBeforeSync: testeeBefore,
+                                       testeeConcurrentSync: testeeConcurrent,
+                                       pause_on_start: pause_on_start,
+                                       pause_on_exit: pause_on_exit);
   } else {
-    var process = new _TestLauncher();
-    process.launch(pause_on_start, pause_on_exit,
-                   pause_on_unhandled_exceptions,
-                   trace_service, trace_compiler).then((port) {
-      if (mainArgs.contains("--gdb")) {
-        port = 8181;
-      }
-      String addr = 'ws://localhost:$port/ws';
-      serviceHttpAddress = 'http://localhost:$port';
-      var testIndex = 1;
-      var totalTests = tests.length;
-      var name = Platform.script.pathSegments.last;
-      runZoned(() {
-        new WebSocketVM(new WebSocketVMTarget(addr)).load()
-            .then((VM vm) => vm.isolates.first.load())
-            .then((Isolate isolate) => Future.forEach(tests, (test) {
-              isolate.vm.verbose = verbose_vm;
-              print('Running $name [$testIndex/$totalTests]');
-              testIndex++;
-              return test(isolate);
-            })).then((_) => process.requestExit());
-      }, onError: (e, st) {
-        process.requestExit();
-        if (!_isWebSocketDisconnect(e)) {
-          print('Unexpected exception in service tests: $e $st');
-          throw e;
-        }
-      });
-    });
+    new _ServiceTesterRunner().run(
+        mainArgs: mainArgs,
+        isolateTests: tests,
+        pause_on_start: pause_on_start,
+        pause_on_exit: pause_on_exit,
+        trace_service: trace_service,
+        trace_compiler: trace_compiler,
+        verbose_vm: verbose_vm,
+        pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
   }
 }
 
-Future<Isolate> hasPausedFor(Isolate isolate, String kind) {
-  // Set up a listener to wait for breakpoint events.
-  Completer completer = new Completer();
-  isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
-    var subscription;
-    subscription = stream.listen((ServiceEvent event) {
-        if (event.kind == kind) {
-          print('Paused with $kind');
-          subscription.cancel();
-          if (completer != null) {
-            // Reload to update isolate.pauseEvent.
-            completer.complete(isolate.reload());
-            completer = null;
-          }
-        }
-    });
-
-    // Pause may have happened before we subscribed.
-    isolate.reload().then((_) {
-      if ((isolate.pauseEvent != null) &&
-         (isolate.pauseEvent.kind == kind)) {
-        // Already waiting at a breakpoint.
-        print('Paused with $kind');
-        subscription.cancel();
-        if (completer != null) {
-          completer.complete(isolate);
-          completer = null;
-        }
-      }
-    });
-  });
-
-  return completer.future;  // Will complete when breakpoint hit.
-}
-
-Future<Isolate> hasStoppedAtBreakpoint(Isolate isolate) {
-  return hasPausedFor(isolate, ServiceEvent.kPauseBreakpoint);
-}
-
-Future<Isolate> hasStoppedWithUnhandledException(Isolate isolate) {
-  return hasPausedFor(isolate, ServiceEvent.kPauseException);
-}
-
-Future<Isolate> hasPausedAtStart(Isolate isolate) {
-  return hasPausedFor(isolate, ServiceEvent.kPauseStart);
-}
-
-// Currying is your friend.
-IsolateTest setBreakpointAtLine(int line) {
-  return (Isolate isolate) async {
-    print("Setting breakpoint for line $line");
-    Library lib = await isolate.rootLibrary.load();
-    Script script = lib.scripts.single;
-
-    Breakpoint bpt = await isolate.addBreakpoint(script, line);
-    print("Breakpoint is $bpt");
-    expect(bpt, isNotNull);
-    expect(bpt is Breakpoint, isTrue);
-  };
-}
-
-IsolateTest stoppedAtLine(int line) {
-  return (Isolate isolate) async {
-    print("Checking we are at line $line");
-
-    ServiceMap stack = await isolate.getStack();
-    expect(stack.type, equals('Stack'));
-
-    List<Frame> frames = stack['frames'];
-    expect(frames.length, greaterThanOrEqualTo(1));
-
-    Frame top = frames[0];
-    Script script = await top.location.script.load();
-    int actualLine = script.tokenToLine(top.location.tokenPos);
-    if (actualLine != line) {
-      var sb = new StringBuffer();
-      sb.write("Expected to be at line $line but actually at line $actualLine");
-      sb.write("\nFull stack trace:\n");
-      for (Frame f in stack['frames']) {
-        sb.write(" $f [${await f.location.getLine()}]\n");
-      }
-      throw sb.toString();
-    }
-  };
-}
-
-
-Future<Isolate> resumeIsolate(Isolate isolate) {
-  Completer completer = new Completer();
-  isolate.vm.getEventStream(VM.kDebugStream).then((stream) {
-    var subscription;
-    subscription = stream.listen((ServiceEvent event) {
-      if (event.kind == ServiceEvent.kResume) {
-        subscription.cancel();
-        completer.complete();
-      }
-    });
-  });
-  isolate.resume();
-  return completer.future;
-}
-
-
-Future resumeAndAwaitEvent(Isolate isolate, stream, onEvent) async {
-  Completer completer = new Completer();
-  var sub;
-  sub = await isolate.vm.listenEventStream(
-    stream,
-    (ServiceEvent event) {
-      var r = onEvent(event);
-      if (r is! Future) {
-        r = new Future.value(r);
-      }
-      r.then((x) => sub.cancel().then((_) {
-        completer.complete();
-      }));
-    });
-  await isolate.resume();
-  return completer.future;
-}
-
-IsolateTest resumeIsolateAndAwaitEvent(stream, onEvent) {
-  return (Isolate isolate) async =>
-      resumeAndAwaitEvent(isolate, stream, onEvent);
-}
-
-
-Future<Class> getClassFromRootLib(Isolate isolate, String className) async {
-  Library rootLib = await isolate.rootLibrary.load();
-  for (var i = 0; i < rootLib.classes.length; i++) {
-    Class cls = rootLib.classes[i];
-    if (cls.name == className) {
-      return cls;
-    }
-  }
-  return null;
-}
-
-
-Future<Instance> rootLibraryFieldValue(Isolate isolate,
-                                       String fieldName) async {
-  Library rootLib = await isolate.rootLibrary.load();
-  Field field = rootLib.variables.singleWhere((v) => v.name == fieldName);
-  await field.load();
-  Instance value = field.staticValue;
-  await value.load();
-  return value;
-}
-
 
 /// Runs [tests] in sequence, each of which should take an [Isolate] and
 /// return a [Future]. Code for setting up state can run before and/or
@@ -404,57 +318,28 @@
 /// to run tests or testee in this invokation of the script.
 Future runVMTests(List<String> mainArgs,
                   List<VMTest> tests,
-                  {Future testeeBefore(),
-                   Future testeeConcurrent(),
+                  {testeeBefore(),
+                   testeeConcurrent(),
                    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}) async {
-  if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
-    if (!pause_on_start) {
-      if (testeeBefore != null) {
-        await testeeBefore();
-      }
-      print(''); // Print blank line to signal that we are ready.
-    }
-    if (testeeConcurrent != null) {
-      await testeeConcurrent();
-    }
-    if (!pause_on_exit) {
-      // Wait around for the process to be killed.
-      stdin.first.then((_) => exit(0));
-    }
+  if (_isTestee()) {
+    new _SerivceTesteeRunner().run(testeeBefore: testeeBefore,
+                                   testeeConcurrent: testeeConcurrent,
+                                   pause_on_start: pause_on_start,
+                                   pause_on_exit: pause_on_exit);
   } else {
-    var process = new _TestLauncher();
-    process.launch(pause_on_start,
-                   pause_on_exit,
-                   pause_on_unhandled_exceptions,
-                   trace_service, trace_compiler).then((port) async {
-      if (mainArgs.contains("--gdb")) {
-        port = 8181;
-      }
-      String addr = 'ws://localhost:$port/ws';
-      serviceHttpAddress = 'http://localhost:$port';
-      var testIndex = 1;
-      var totalTests = tests.length;
-      var name = Platform.script.pathSegments.last;
-      runZoned(() {
-        new WebSocketVM(new WebSocketVMTarget(addr)).load()
-            .then((VM vm) => Future.forEach(tests, (test) {
-              vm.verbose = verbose_vm;
-              print('Running $name [$testIndex/$totalTests]');
-              testIndex++;
-              return test(vm);
-            })).then((_) => process.requestExit());
-      }, onError: (e, st) {
-        process.requestExit();
-        if (!_isWebSocketDisconnect(e)) {
-          print('Unexpected exception in service tests: $e $st');
-          throw e;
-        }
-      });
-    });
+    new _ServiceTesterRunner().run(
+        mainArgs: mainArgs,
+        vmTests: tests,
+        pause_on_start: pause_on_start,
+        pause_on_exit: pause_on_exit,
+        trace_service: trace_service,
+        trace_compiler: trace_compiler,
+        verbose_vm: verbose_vm,
+        pause_on_unhandled_exceptions: pause_on_unhandled_exceptions);
   }
 }
diff --git a/runtime/observatory/tests/service/vm_restart_test.dart b/runtime/observatory/tests/service/vm_restart_test.dart
index 8f5da2e..605e7bf 100644
--- a/runtime/observatory/tests/service/vm_restart_test.dart
+++ b/runtime/observatory/tests/service/vm_restart_test.dart
@@ -7,6 +7,7 @@
 import 'dart:developer';
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 int count = 0;
@@ -69,7 +70,7 @@
         }
       }
     });
-    
+
     Completer restartCompleter = new Completer();
     var isolateStream = await isolate.vm.getEventStream(VM.kIsolateStream);
     var isolateSub;
@@ -101,5 +102,5 @@
   },
 ];
 
-  
+
 main(args) => runIsolateTests(args, tests, testeeConcurrent: test);
diff --git a/runtime/observatory/tests/service/vm_timeline_flags_test.dart b/runtime/observatory/tests/service/vm_timeline_flags_test.dart
index 6e8994e..6943874 100644
--- a/runtime/observatory/tests/service/vm_timeline_flags_test.dart
+++ b/runtime/observatory/tests/service/vm_timeline_flags_test.dart
@@ -6,7 +6,7 @@
 import 'dart:developer';
 import 'package:observatory/service_io.dart';
 import 'package:unittest/unittest.dart';
-
+import 'service_test_common.dart';
 import 'test_helper.dart';
 
 primeDartTimeline() {
@@ -60,6 +60,7 @@
     // Confirm that only Dart is being recorded.
     expect(flags['recordedStreams'].length, equals(1));
     expect(flags['recordedStreams'].contains('Dart'), isTrue);
+    print(flags);
   },
   resumeIsolate,
   (Isolate isolate) async {
@@ -67,6 +68,7 @@
     Map result = await isolate.vm.invokeRpcNoUpgrade('_getVMTimeline', {});
     expect(result['type'], equals('_Timeline'));
     expect(result['traceEvents'], new isInstanceOf<List>());
+    print(result['traceEvents']);
     // Confirm that Dart events are added.
     expect(filterEvents(result['traceEvents'], isDart).length, greaterThan(0));
     // Confirm that zero non-Dart events are added.
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 8d3a155..d1c6ef6 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -57,7 +57,7 @@
 #include <inttypes.h>
 #include <stdint.h>
 #include <unistd.h>
-#endif
+#endif  // !defined(_WIN32)
 
 #include <float.h>
 #include <limits.h>
@@ -72,23 +72,30 @@
 #include "platform/c99_support_win.h"
 #include "platform/inttypes_support_win.h"
 #include "platform/floating_point_win.h"
-#endif
+#endif  // defined(_WIN32)
 
 #include "platform/math.h"
 
 #if !defined(_WIN32)
 #include "platform/floating_point.h"
-#endif
+#endif  // !defined(_WIN32)
 
 // Target OS detection.
 // for more information on predefined macros:
 //   - http://msdn.microsoft.com/en-us/library/b0084kay.aspx
 //   - with gcc, run: "echo | gcc -E -dM -"
 #if defined(__ANDROID__)
+
+// Check for Android first, to determine its difference from Linux.
 #define TARGET_OS_ANDROID 1
+
 #elif defined(__linux__) || defined(__FreeBSD__)
+
+// Generic Linux.
 #define TARGET_OS_LINUX 1
+
 #elif defined(__APPLE__)
+
 // Define the flavor of Mac OS we are running on.
 #include <TargetConditionals.h>
 // TODO(iposva): Rename TARGET_OS_MACOS to TARGET_OS_MAC to inherit
@@ -99,11 +106,33 @@
 #endif
 
 #elif defined(_WIN32)
+
+// Windows, both 32- and 64-bit, regardless of the check for _WIN32.
 #define TARGET_OS_WINDOWS 1
+
 #else
 #error Automatic target os detection failed.
 #endif
 
+
+// Setup product, release or debug build related macros.
+#if defined(PRODUCT) && defined(DEBUG)
+#error Both PRODUCT and DEBUG defined.
+#endif  // defined(PRODUCT) && defined(DEBUG)
+
+#if defined(PRODUCT)
+#define NOT_IN_PRODUCT(code)
+#define DEBUG_ONLY(code)
+#else  // defined(PRODUCT)
+#define NOT_IN_PRODUCT(code) code
+#if defined(DEBUG)
+#define DEBUG_ONLY(code) code
+#else  // defined(DEBUG)
+#define DEBUG_ONLY(code)
+#endif  // defined(DEBUG)
+#endif  // defined(PRODUCT)
+
+
 namespace dart {
 
 struct simd128_value_t {
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index ade646c..3032412 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -85,6 +85,17 @@
 dart/redirection_type_shuffling_test: CompileTimeError # Imports dart:mirrors
 dart/optimized_stacktrace_test: RuntimeError # Expects line and column numbers
 
+[ $compiler == dart2app ]
+dart/optimized_stacktrace_test: RuntimeError # Expects line and column numbers
+
+[ $runtime == dart_product ]
+dart/data_uri_spawn_test: Skip # Isolate.spawnUri
+
 [ $runtime == dart_precompiled ]
 dart/inline_stack_frame_test: Fail  # Issue 24783 - inlined frames missing
 dart/data_uri_spawn_test: RuntimeError # Isolate.spawnUri
+
+[ $runtime == vm && $mode == product ]
+cc/IsolateSetCheckedMode: Fail,OK  # Expects exact type name.
+cc/LibraryGetClassNames: Fail,OK  # Expects exact type name.
+cc/StackTraceFormat: Fail,OK  # Expects exact type name.
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
new file mode 100644
index 0000000..63c13f5
--- /dev/null
+++ b/runtime/vm/aot_optimizer.cc
@@ -0,0 +1,2853 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "vm/aot_optimizer.h"
+
+#include "vm/bit_vector.h"
+#include "vm/branch_optimizer.h"
+#include "vm/cha.h"
+#include "vm/compiler.h"
+#include "vm/cpu.h"
+#include "vm/dart_entry.h"
+#include "vm/exceptions.h"
+#include "vm/flow_graph_builder.h"
+#include "vm/flow_graph_compiler.h"
+#include "vm/flow_graph_inliner.h"
+#include "vm/flow_graph_range_analysis.h"
+#include "vm/hash_map.h"
+#include "vm/il_printer.h"
+#include "vm/intermediate_language.h"
+#include "vm/object.h"
+#include "vm/object_store.h"
+#include "vm/parser.h"
+#include "vm/precompiler.h"
+#include "vm/resolver.h"
+#include "vm/scopes.h"
+#include "vm/stack_frame.h"
+#include "vm/symbols.h"
+
+namespace dart {
+
+DECLARE_FLAG(bool, precompilation);
+
+// Quick access to the current isolate and zone.
+#define I (isolate())
+#define Z (zone())
+
+static bool ShouldInlineSimd() {
+  return FlowGraphCompiler::SupportsUnboxedSimd128();
+}
+
+
+static bool CanUnboxDouble() {
+  return FlowGraphCompiler::SupportsUnboxedDoubles();
+}
+
+
+static bool CanConvertUnboxedMintToDouble() {
+  return FlowGraphCompiler::CanConvertUnboxedMintToDouble();
+}
+
+
+// Optimize instance calls using ICData.
+void AotOptimizer::ApplyICData() {
+  VisitBlocks();
+}
+
+
+void AotOptimizer::PopulateWithICData() {
+  ASSERT(current_iterator_ == NULL);
+  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
+       !block_it.Done();
+       block_it.Advance()) {
+    ForwardInstructionIterator it(block_it.Current());
+    for (; !it.Done(); it.Advance()) {
+      Instruction* instr = it.Current();
+      if (instr->IsInstanceCall()) {
+        InstanceCallInstr* call = instr->AsInstanceCall();
+        if (!call->HasICData()) {
+          const Array& arguments_descriptor =
+              Array::Handle(zone(),
+                  ArgumentsDescriptor::New(call->ArgumentCount(),
+                                           call->argument_names()));
+          const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New(
+              function(), call->function_name(),
+              arguments_descriptor, call->deopt_id(),
+              call->checked_argument_count()));
+          call->set_ic_data(&ic_data);
+        }
+      }
+    }
+    current_iterator_ = NULL;
+  }
+}
+
+
+// Optimize instance calls using cid.  This is called after optimizer
+// converted instance calls to instructions. Any remaining
+// instance calls are either megamorphic calls, cannot be optimized or
+// have no runtime type feedback collected.
+// Attempts to convert an instance call (IC call) using propagated class-ids,
+// e.g., receiver class id, guarded-cid, or by guessing cid-s.
+void AotOptimizer::ApplyClassIds() {
+  ASSERT(current_iterator_ == NULL);
+  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()) {
+      Instruction* instr = it.Current();
+      if (instr->IsInstanceCall()) {
+        InstanceCallInstr* call = instr->AsInstanceCall();
+        if (call->HasICData()) {
+          if (TryCreateICData(call)) {
+            VisitInstanceCall(call);
+          }
+        }
+      } else if (instr->IsPolymorphicInstanceCall()) {
+        SpecializePolymorphicInstanceCall(instr->AsPolymorphicInstanceCall());
+      }
+    }
+    current_iterator_ = NULL;
+  }
+}
+
+
+// TODO(srdjan): Test/support other number types as well.
+static bool IsNumberCid(intptr_t cid) {
+  return (cid == kSmiCid) || (cid == kDoubleCid);
+}
+
+
+static void GetUniqueDynamicTarget(Isolate* isolate,
+                                   const String& fname,
+                                   Object* function) {
+  UniqueFunctionsSet functions_set(
+      isolate->object_store()->unique_dynamic_targets());
+  ASSERT(fname.IsSymbol());
+  *function = functions_set.GetOrNull(fname);
+  ASSERT(functions_set.Release().raw() ==
+      isolate->object_store()->unique_dynamic_targets());
+}
+
+
+bool AotOptimizer::TryCreateICData(InstanceCallInstr* call) {
+  ASSERT(call->HasICData());
+  if (call->ic_data()->NumberOfUsedChecks() > 0) {
+    // This occurs when an instance call has too many checks, will be converted
+    // to megamorphic call.
+    return false;
+  }
+  GrowableArray<intptr_t> class_ids(call->ic_data()->NumArgsTested());
+  ASSERT(call->ic_data()->NumArgsTested() <= call->ArgumentCount());
+  for (intptr_t i = 0; i < call->ic_data()->NumArgsTested(); i++) {
+    class_ids.Add(call->PushArgumentAt(i)->value()->Type()->ToCid());
+  }
+
+  const Token::Kind op_kind = call->token_kind();
+  if (Token::IsRelationalOperator(op_kind) ||
+      Token::IsEqualityOperator(op_kind) ||
+      Token::IsBinaryOperator(op_kind)) {
+    // Guess cid: if one of the inputs is a number assume that the other
+    // is a number of same type.
+    if (FLAG_guess_icdata_cid) {
+      const intptr_t cid_0 = class_ids[0];
+      const intptr_t cid_1 = class_ids[1];
+      if ((cid_0 == kDynamicCid) && (IsNumberCid(cid_1))) {
+        class_ids[0] = cid_1;
+      } else if (IsNumberCid(cid_0) && (cid_1 == kDynamicCid)) {
+        class_ids[1] = cid_0;
+      }
+    }
+  }
+
+  bool all_cids_known = true;
+  for (intptr_t i = 0; i < class_ids.length(); i++) {
+    if (class_ids[i] == kDynamicCid) {
+      // Not all cid-s known.
+      all_cids_known = false;
+      break;
+    }
+  }
+
+  if (all_cids_known) {
+    const Class& receiver_class = Class::Handle(Z,
+        isolate()->class_table()->At(class_ids[0]));
+    if (!receiver_class.is_finalized()) {
+      // Do not eagerly finalize classes. ResolveDynamicForReceiverClass can
+      // cause class finalization, since callee's receiver class may not be
+      // finalized yet.
+      return false;
+    }
+    const Array& args_desc_array = Array::Handle(Z,
+        ArgumentsDescriptor::New(call->ArgumentCount(),
+                                 call->argument_names()));
+    ArgumentsDescriptor args_desc(args_desc_array);
+    const Function& function = Function::Handle(Z,
+        Resolver::ResolveDynamicForReceiverClass(
+            receiver_class,
+            call->function_name(),
+            args_desc));
+    if (function.IsNull()) {
+      return false;
+    }
+
+    // Create new ICData, do not modify the one attached to the instruction
+    // since it is attached to the assembly instruction itself.
+    // TODO(srdjan): Prevent modification of ICData object that is
+    // referenced in assembly code.
+    const ICData& ic_data = ICData::ZoneHandle(Z,
+        ICData::NewFrom(*call->ic_data(), class_ids.length()));
+    if (class_ids.length() > 1) {
+      ic_data.AddCheck(class_ids, function);
+    } else {
+      ASSERT(class_ids.length() == 1);
+      ic_data.AddReceiverCheck(class_ids[0], function);
+    }
+    call->set_ic_data(&ic_data);
+    return true;
+  }
+
+  if (isolate()->object_store()->unique_dynamic_targets() != Array::null()) {
+    // Check if the target is unique.
+    Function& target_function = Function::Handle(Z);
+    GetUniqueDynamicTarget(isolate(), call->function_name(), &target_function);
+    // Calls with named arguments must be resolved/checked at runtime.
+    String& error_message = String::Handle(Z);
+    if (!target_function.IsNull() &&
+        !target_function.HasOptionalNamedParameters() &&
+        target_function.AreValidArgumentCounts(call->ArgumentCount(), 0,
+                                               &error_message)) {
+      const intptr_t cid = Class::Handle(Z, target_function.Owner()).id();
+      const ICData& ic_data = ICData::ZoneHandle(Z,
+          ICData::NewFrom(*call->ic_data(), 1));
+      ic_data.AddReceiverCheck(cid, target_function);
+      call->set_ic_data(&ic_data);
+      return true;
+    }
+  }
+
+  // Check if getter or setter in function's class and class is currently leaf.
+  if (FLAG_guess_icdata_cid &&
+      ((call->token_kind() == Token::kGET) ||
+          (call->token_kind() == Token::kSET))) {
+    const Class& owner_class = Class::Handle(Z, function().Owner());
+    if (!owner_class.is_abstract() &&
+        !CHA::HasSubclasses(owner_class) &&
+        !CHA::IsImplemented(owner_class)) {
+      const Array& args_desc_array = Array::Handle(Z,
+          ArgumentsDescriptor::New(call->ArgumentCount(),
+                                   call->argument_names()));
+      ArgumentsDescriptor args_desc(args_desc_array);
+      const Function& function = Function::Handle(Z,
+          Resolver::ResolveDynamicForReceiverClass(owner_class,
+                                                   call->function_name(),
+                                                   args_desc));
+      if (!function.IsNull()) {
+        const ICData& ic_data = ICData::ZoneHandle(Z,
+            ICData::NewFrom(*call->ic_data(), class_ids.length()));
+        ic_data.AddReceiverCheck(owner_class.id(), function);
+        call->set_ic_data(&ic_data);
+        return true;
+      }
+    }
+  }
+
+  return false;
+}
+
+
+const ICData& AotOptimizer::TrySpecializeICData(const ICData& ic_data,
+                                                      intptr_t cid) {
+  ASSERT(ic_data.NumArgsTested() == 1);
+
+  if ((ic_data.NumberOfUsedChecks() == 1) && ic_data.HasReceiverClassId(cid)) {
+    return ic_data;  // Nothing to do
+  }
+
+  const Function& function =
+      Function::Handle(Z, ic_data.GetTargetForReceiverClassId(cid));
+  // TODO(fschneider): Try looking up the function on the class if it is
+  // not found in the ICData.
+  if (!function.IsNull()) {
+    const ICData& new_ic_data = ICData::ZoneHandle(Z, ICData::New(
+        Function::Handle(Z, ic_data.Owner()),
+        String::Handle(Z, ic_data.target_name()),
+        Object::empty_array(),  // Dummy argument descriptor.
+        ic_data.deopt_id(),
+        ic_data.NumArgsTested()));
+    new_ic_data.SetDeoptReasons(ic_data.DeoptReasons());
+    new_ic_data.AddReceiverCheck(cid, function);
+    return new_ic_data;
+  }
+
+  return ic_data;
+}
+
+
+void AotOptimizer::SpecializePolymorphicInstanceCall(
+    PolymorphicInstanceCallInstr* call) {
+  if (!FLAG_polymorphic_with_deopt) {
+    // Specialization adds receiver checks which can lead to deoptimization.
+    return;
+  }
+  if (!call->with_checks()) {
+    return;  // Already specialized.
+  }
+
+  const intptr_t receiver_cid =
+      call->PushArgumentAt(0)->value()->Type()->ToCid();
+  if (receiver_cid == kDynamicCid) {
+    return;  // No information about receiver was infered.
+  }
+
+  const ICData& ic_data = TrySpecializeICData(call->ic_data(), receiver_cid);
+  if (ic_data.raw() == call->ic_data().raw()) {
+    // No specialization.
+    return;
+  }
+
+  const bool with_checks = false;
+  PolymorphicInstanceCallInstr* specialized =
+      new(Z) PolymorphicInstanceCallInstr(call->instance_call(),
+                                          ic_data,
+                                          with_checks);
+  call->ReplaceWith(specialized, current_iterator());
+}
+
+
+static BinarySmiOpInstr* AsSmiShiftLeftInstruction(Definition* d) {
+  BinarySmiOpInstr* instr = d->AsBinarySmiOp();
+  if ((instr != NULL) && (instr->op_kind() == Token::kSHL)) {
+    return instr;
+  }
+  return NULL;
+}
+
+
+static bool IsPositiveOrZeroSmiConst(Definition* d) {
+  ConstantInstr* const_instr = d->AsConstant();
+  if ((const_instr != NULL) && (const_instr->value().IsSmi())) {
+    return Smi::Cast(const_instr->value()).Value() >= 0;
+  }
+  return false;
+}
+
+
+void AotOptimizer::OptimizeLeftShiftBitAndSmiOp(
+    Definition* bit_and_instr,
+    Definition* left_instr,
+    Definition* right_instr) {
+  ASSERT(bit_and_instr != NULL);
+  ASSERT((left_instr != NULL) && (right_instr != NULL));
+
+  // Check for pattern, smi_shift_left must be single-use.
+  bool is_positive_or_zero = IsPositiveOrZeroSmiConst(left_instr);
+  if (!is_positive_or_zero) {
+    is_positive_or_zero = IsPositiveOrZeroSmiConst(right_instr);
+  }
+  if (!is_positive_or_zero) return;
+
+  BinarySmiOpInstr* smi_shift_left = NULL;
+  if (bit_and_instr->InputAt(0)->IsSingleUse()) {
+    smi_shift_left = AsSmiShiftLeftInstruction(left_instr);
+  }
+  if ((smi_shift_left == NULL) && (bit_and_instr->InputAt(1)->IsSingleUse())) {
+    smi_shift_left = AsSmiShiftLeftInstruction(right_instr);
+  }
+  if (smi_shift_left == NULL) return;
+
+  // Pattern recognized.
+  smi_shift_left->mark_truncating();
+  ASSERT(bit_and_instr->IsBinarySmiOp() || bit_and_instr->IsBinaryMintOp());
+  if (bit_and_instr->IsBinaryMintOp()) {
+    // Replace Mint op with Smi op.
+    BinarySmiOpInstr* smi_op = new(Z) BinarySmiOpInstr(
+        Token::kBIT_AND,
+        new(Z) Value(left_instr),
+        new(Z) Value(right_instr),
+        Thread::kNoDeoptId);  // BIT_AND cannot deoptimize.
+    bit_and_instr->ReplaceWith(smi_op, current_iterator());
+  }
+}
+
+
+void AotOptimizer::AppendExtractNthOutputForMerged(Definition* instr,
+                                                         intptr_t index,
+                                                         Representation rep,
+                                                         intptr_t cid) {
+  ExtractNthOutputInstr* extract =
+      new(Z) ExtractNthOutputInstr(new(Z) Value(instr), index, rep, cid);
+  instr->ReplaceUsesWith(extract);
+  flow_graph()->InsertAfter(instr, extract, NULL, FlowGraph::kValue);
+}
+
+
+// Dart:
+//  var x = d % 10;
+//  var y = d ~/ 10;
+//  var z = x + y;
+//
+// IL:
+//  v4 <- %(v2, v3)
+//  v5 <- ~/(v2, v3)
+//  v6 <- +(v4, v5)
+//
+// IL optimized:
+//  v4 <- DIVMOD(v2, v3);
+//  v5 <- LoadIndexed(v4, 0); // ~/ result
+//  v6 <- LoadIndexed(v4, 1); // % result
+//  v7 <- +(v5, v6)
+// Because of the environment it is important that merged instruction replaces
+// first original instruction encountered.
+void AotOptimizer::TryMergeTruncDivMod(
+    GrowableArray<BinarySmiOpInstr*>* merge_candidates) {
+  if (merge_candidates->length() < 2) {
+    // Need at least a TRUNCDIV and a MOD.
+    return;
+  }
+  for (intptr_t i = 0; i < merge_candidates->length(); i++) {
+    BinarySmiOpInstr* curr_instr = (*merge_candidates)[i];
+    if (curr_instr == NULL) {
+      // Instruction was merged already.
+      continue;
+    }
+    ASSERT((curr_instr->op_kind() == Token::kTRUNCDIV) ||
+           (curr_instr->op_kind() == Token::kMOD));
+    // Check if there is kMOD/kTRUNDIV binop with same inputs.
+    const intptr_t other_kind = (curr_instr->op_kind() == Token::kTRUNCDIV) ?
+        Token::kMOD : Token::kTRUNCDIV;
+    Definition* left_def = curr_instr->left()->definition();
+    Definition* right_def = curr_instr->right()->definition();
+    for (intptr_t k = i + 1; k < merge_candidates->length(); k++) {
+      BinarySmiOpInstr* other_binop = (*merge_candidates)[k];
+      // 'other_binop' can be NULL if it was already merged.
+      if ((other_binop != NULL) &&
+          (other_binop->op_kind() == other_kind) &&
+          (other_binop->left()->definition() == left_def) &&
+          (other_binop->right()->definition() == right_def)) {
+        (*merge_candidates)[k] = NULL;  // Clear it.
+        ASSERT(curr_instr->HasUses());
+        AppendExtractNthOutputForMerged(
+            curr_instr,
+            MergedMathInstr::OutputIndexOf(curr_instr->op_kind()),
+            kTagged, kSmiCid);
+        ASSERT(other_binop->HasUses());
+        AppendExtractNthOutputForMerged(
+            other_binop,
+            MergedMathInstr::OutputIndexOf(other_binop->op_kind()),
+            kTagged, kSmiCid);
+
+        ZoneGrowableArray<Value*>* args = new(Z) ZoneGrowableArray<Value*>(2);
+        args->Add(new(Z) Value(curr_instr->left()->definition()));
+        args->Add(new(Z) Value(curr_instr->right()->definition()));
+
+        // Replace with TruncDivMod.
+        MergedMathInstr* div_mod = new(Z) MergedMathInstr(
+            args,
+            curr_instr->deopt_id(),
+            MergedMathInstr::kTruncDivMod);
+        curr_instr->ReplaceWith(div_mod, current_iterator());
+        other_binop->ReplaceUsesWith(div_mod);
+        other_binop->RemoveFromGraph();
+        // Only one merge possible. Because canonicalization happens later,
+        // more candidates are possible.
+        // TODO(srdjan): Allow merging of trunc-div/mod into truncDivMod.
+        break;
+      }
+    }
+  }
+}
+
+
+// Tries to merge MathUnary operations, in this case sinus and cosinus.
+void AotOptimizer::TryMergeMathUnary(
+    GrowableArray<MathUnaryInstr*>* merge_candidates) {
+  if (!FlowGraphCompiler::SupportsSinCos() || !CanUnboxDouble() ||
+      !FLAG_merge_sin_cos) {
+    return;
+  }
+  if (merge_candidates->length() < 2) {
+    // Need at least a SIN and a COS.
+    return;
+  }
+  for (intptr_t i = 0; i < merge_candidates->length(); i++) {
+    MathUnaryInstr* curr_instr = (*merge_candidates)[i];
+    if (curr_instr == NULL) {
+      // Instruction was merged already.
+      continue;
+    }
+    const intptr_t kind = curr_instr->kind();
+    ASSERT((kind == MathUnaryInstr::kSin) ||
+           (kind == MathUnaryInstr::kCos));
+    // Check if there is sin/cos binop with same inputs.
+    const intptr_t other_kind = (kind == MathUnaryInstr::kSin) ?
+        MathUnaryInstr::kCos : MathUnaryInstr::kSin;
+    Definition* def = curr_instr->value()->definition();
+    for (intptr_t k = i + 1; k < merge_candidates->length(); k++) {
+      MathUnaryInstr* other_op = (*merge_candidates)[k];
+      // 'other_op' can be NULL if it was already merged.
+      if ((other_op != NULL) && (other_op->kind() == other_kind) &&
+          (other_op->value()->definition() == def)) {
+        (*merge_candidates)[k] = NULL;  // Clear it.
+        ASSERT(curr_instr->HasUses());
+        AppendExtractNthOutputForMerged(curr_instr,
+                                        MergedMathInstr::OutputIndexOf(kind),
+                                        kUnboxedDouble, kDoubleCid);
+        ASSERT(other_op->HasUses());
+        AppendExtractNthOutputForMerged(
+            other_op,
+            MergedMathInstr::OutputIndexOf(other_kind),
+            kUnboxedDouble, kDoubleCid);
+        ZoneGrowableArray<Value*>* args = new(Z) ZoneGrowableArray<Value*>(1);
+        args->Add(new(Z) Value(curr_instr->value()->definition()));
+        // Replace with SinCos.
+        MergedMathInstr* sin_cos =
+            new(Z) MergedMathInstr(args,
+                                   curr_instr->DeoptimizationTarget(),
+                                   MergedMathInstr::kSinCos);
+        curr_instr->ReplaceWith(sin_cos, current_iterator());
+        other_op->ReplaceUsesWith(sin_cos);
+        other_op->RemoveFromGraph();
+        // Only one merge possible. Because canonicalization happens later,
+        // more candidates are possible.
+        // TODO(srdjan): Allow merging of sin/cos into sincos.
+        break;
+      }
+    }
+  }
+}
+
+
+// Optimize (a << b) & c pattern: if c is a positive Smi or zero, then the
+// shift can be a truncating Smi shift-left and result is always Smi.
+// Merging occurs only per basic-block.
+void AotOptimizer::TryOptimizePatterns() {
+  if (!FLAG_truncating_left_shift) return;
+  ASSERT(current_iterator_ == NULL);
+  GrowableArray<BinarySmiOpInstr*> div_mod_merge;
+  GrowableArray<MathUnaryInstr*> sin_cos_merge;
+  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
+       !block_it.Done();
+       block_it.Advance()) {
+    // Merging only per basic-block.
+    div_mod_merge.Clear();
+    sin_cos_merge.Clear();
+    ForwardInstructionIterator it(block_it.Current());
+    current_iterator_ = &it;
+    for (; !it.Done(); it.Advance()) {
+      if (it.Current()->IsBinarySmiOp()) {
+        BinarySmiOpInstr* binop = it.Current()->AsBinarySmiOp();
+        if (binop->op_kind() == Token::kBIT_AND) {
+          OptimizeLeftShiftBitAndSmiOp(binop,
+                                       binop->left()->definition(),
+                                       binop->right()->definition());
+        } else if ((binop->op_kind() == Token::kTRUNCDIV) ||
+                   (binop->op_kind() == Token::kMOD)) {
+          if (binop->HasUses()) {
+            div_mod_merge.Add(binop);
+          }
+        }
+      } else if (it.Current()->IsBinaryMintOp()) {
+        BinaryMintOpInstr* mintop = it.Current()->AsBinaryMintOp();
+        if (mintop->op_kind() == Token::kBIT_AND) {
+          OptimizeLeftShiftBitAndSmiOp(mintop,
+                                       mintop->left()->definition(),
+                                       mintop->right()->definition());
+        }
+      } else if (it.Current()->IsMathUnary()) {
+        MathUnaryInstr* math_unary = it.Current()->AsMathUnary();
+        if ((math_unary->kind() == MathUnaryInstr::kSin) ||
+            (math_unary->kind() == MathUnaryInstr::kCos)) {
+          if (math_unary->HasUses()) {
+            sin_cos_merge.Add(math_unary);
+          }
+        }
+      }
+    }
+    TryMergeTruncDivMod(&div_mod_merge);
+    TryMergeMathUnary(&sin_cos_merge);
+    current_iterator_ = NULL;
+  }
+}
+
+
+static bool ClassIdIsOneOf(intptr_t class_id,
+                           const GrowableArray<intptr_t>& class_ids) {
+  for (intptr_t i = 0; i < class_ids.length(); i++) {
+    ASSERT(class_ids[i] != kIllegalCid);
+    if (class_ids[i] == class_id) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+// Returns true if ICData tests two arguments and all ICData cids are in the
+// required sets 'receiver_class_ids' or 'argument_class_ids', respectively.
+static bool ICDataHasOnlyReceiverArgumentClassIds(
+    const ICData& ic_data,
+    const GrowableArray<intptr_t>& receiver_class_ids,
+    const GrowableArray<intptr_t>& argument_class_ids) {
+  if (ic_data.NumArgsTested() != 2) {
+    return false;
+  }
+  const intptr_t len = ic_data.NumberOfChecks();
+  GrowableArray<intptr_t> class_ids;
+  for (intptr_t i = 0; i < len; i++) {
+    if (ic_data.IsUsedAt(i)) {
+      ic_data.GetClassIdsAt(i, &class_ids);
+      ASSERT(class_ids.length() == 2);
+      if (!ClassIdIsOneOf(class_ids[0], receiver_class_ids) ||
+          !ClassIdIsOneOf(class_ids[1], argument_class_ids)) {
+        return false;
+      }
+    }
+  }
+  return true;
+}
+
+
+static bool ICDataHasReceiverArgumentClassIds(const ICData& ic_data,
+                                              intptr_t receiver_class_id,
+                                              intptr_t argument_class_id) {
+  if (ic_data.NumArgsTested() != 2) {
+    return false;
+  }
+  const intptr_t len = ic_data.NumberOfChecks();
+  for (intptr_t i = 0; i < len; i++) {
+    if (ic_data.IsUsedAt(i)) {
+      GrowableArray<intptr_t> class_ids;
+      ic_data.GetClassIdsAt(i, &class_ids);
+      ASSERT(class_ids.length() == 2);
+      if ((class_ids[0] == receiver_class_id) &&
+          (class_ids[1] == argument_class_id)) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+
+static bool HasOnlyOneSmi(const ICData& ic_data) {
+  return (ic_data.NumberOfUsedChecks() == 1)
+      && ic_data.HasReceiverClassId(kSmiCid);
+}
+
+
+static bool HasOnlySmiOrMint(const ICData& ic_data) {
+  if (ic_data.NumberOfUsedChecks() == 1) {
+    return ic_data.HasReceiverClassId(kSmiCid)
+        || ic_data.HasReceiverClassId(kMintCid);
+  }
+  return (ic_data.NumberOfUsedChecks() == 2)
+      && ic_data.HasReceiverClassId(kSmiCid)
+      && ic_data.HasReceiverClassId(kMintCid);
+}
+
+
+static bool HasOnlyTwoOf(const ICData& ic_data, intptr_t cid) {
+  if (ic_data.NumberOfUsedChecks() != 1) {
+    return false;
+  }
+  GrowableArray<intptr_t> first;
+  GrowableArray<intptr_t> second;
+  ic_data.GetUsedCidsForTwoArgs(&first, &second);
+  return (first[0] == cid) && (second[0] == cid);
+}
+
+// Returns false if the ICData contains anything other than the 4 combinations
+// of Mint and Smi for the receiver and argument classes.
+static bool HasTwoMintOrSmi(const ICData& ic_data) {
+  GrowableArray<intptr_t> first;
+  GrowableArray<intptr_t> second;
+  ic_data.GetUsedCidsForTwoArgs(&first, &second);
+  for (intptr_t i = 0; i < first.length(); i++) {
+    if ((first[i] != kSmiCid) && (first[i] != kMintCid)) {
+      return false;
+    }
+    if ((second[i] != kSmiCid) && (second[i] != kMintCid)) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+// Returns false if the ICData contains anything other than the 4 combinations
+// of Double and Smi for the receiver and argument classes.
+static bool HasTwoDoubleOrSmi(const ICData& ic_data) {
+  GrowableArray<intptr_t> class_ids(2);
+  class_ids.Add(kSmiCid);
+  class_ids.Add(kDoubleCid);
+  return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids);
+}
+
+
+static bool HasOnlyOneDouble(const ICData& ic_data) {
+  return (ic_data.NumberOfUsedChecks() == 1)
+      && ic_data.HasReceiverClassId(kDoubleCid);
+}
+
+
+static bool ShouldSpecializeForDouble(const ICData& ic_data) {
+  // Don't specialize for double if we can't unbox them.
+  if (!CanUnboxDouble()) {
+    return false;
+  }
+
+  // Unboxed double operation can't handle case of two smis.
+  if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
+    return false;
+  }
+
+  // Check that it have seen only smis and doubles.
+  return HasTwoDoubleOrSmi(ic_data);
+}
+
+
+void AotOptimizer::ReplaceCall(Definition* call,
+                                     Definition* replacement) {
+  // Remove the original push arguments.
+  for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+    PushArgumentInstr* push = call->PushArgumentAt(i);
+    push->ReplaceUsesWith(push->value()->definition());
+    push->RemoveFromGraph();
+  }
+  call->ReplaceWith(replacement, current_iterator());
+}
+
+
+void AotOptimizer::AddCheckSmi(Definition* to_check,
+                                     intptr_t deopt_id,
+                                     Environment* deopt_environment,
+                                     Instruction* insert_before) {
+  if (to_check->Type()->ToCid() != kSmiCid) {
+    InsertBefore(insert_before,
+                 new(Z) CheckSmiInstr(new(Z) Value(to_check),
+                                      deopt_id,
+                                      insert_before->token_pos()),
+                 deopt_environment,
+                 FlowGraph::kEffect);
+  }
+}
+
+
+Instruction* AotOptimizer::GetCheckClass(Definition* to_check,
+                                               const ICData& unary_checks,
+                                               intptr_t deopt_id,
+                                               TokenPosition token_pos) {
+  if ((unary_checks.NumberOfUsedChecks() == 1) &&
+      unary_checks.HasReceiverClassId(kSmiCid)) {
+    return new(Z) CheckSmiInstr(new(Z) Value(to_check),
+                                deopt_id,
+                                token_pos);
+  }
+  return new(Z) CheckClassInstr(
+      new(Z) Value(to_check), deopt_id, unary_checks, token_pos);
+}
+
+
+void AotOptimizer::AddCheckClass(Definition* to_check,
+                                       const ICData& unary_checks,
+                                       intptr_t deopt_id,
+                                       Environment* deopt_environment,
+                                       Instruction* insert_before) {
+  // Type propagation has not run yet, we cannot eliminate the check.
+  Instruction* check = GetCheckClass(
+      to_check, unary_checks, deopt_id, insert_before->token_pos());
+  InsertBefore(insert_before, check, deopt_environment, FlowGraph::kEffect);
+}
+
+
+void AotOptimizer::AddReceiverCheck(InstanceCallInstr* call) {
+  AddCheckClass(call->ArgumentAt(0),
+                ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks()),
+                call->deopt_id(),
+                call->env(),
+                call);
+}
+
+
+static bool ArgIsAlways(intptr_t cid,
+                        const ICData& ic_data,
+                        intptr_t arg_number) {
+  ASSERT(ic_data.NumArgsTested() > arg_number);
+  if (ic_data.NumberOfUsedChecks() == 0) {
+    return false;
+  }
+  const intptr_t num_checks = ic_data.NumberOfChecks();
+  for (intptr_t i = 0; i < num_checks; i++) {
+    if (ic_data.IsUsedAt(i) && ic_data.GetClassIdAt(i, arg_number) != cid) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+bool AotOptimizer::TryReplaceWithIndexedOp(InstanceCallInstr* call) {
+  // Check for monomorphic IC data.
+  if (!call->HasICData()) return false;
+  const ICData& ic_data =
+      ICData::Handle(Z, call->ic_data()->AsUnaryClassChecks());
+  if (ic_data.NumberOfChecks() != 1) {
+    return false;
+  }
+  return TryReplaceInstanceCallWithInline(call);
+}
+
+
+// Return true if d is a string of length one (a constant or result from
+// from string-from-char-code instruction.
+static bool IsLengthOneString(Definition* d) {
+  if (d->IsConstant()) {
+    const Object& obj = d->AsConstant()->value();
+    if (obj.IsString()) {
+      return String::Cast(obj).Length() == 1;
+    } else {
+      return false;
+    }
+  } else {
+    return d->IsStringFromCharCode();
+  }
+}
+
+
+// Returns true if the string comparison was converted into char-code
+// comparison. Conversion is only possible for strings of length one.
+// E.g., detect str[x] == "x"; and use an integer comparison of char-codes.
+// TODO(srdjan): Expand for two-byte and external strings.
+bool AotOptimizer::TryStringLengthOneEquality(InstanceCallInstr* call,
+                                                    Token::Kind op_kind) {
+  ASSERT(HasOnlyTwoOf(*call->ic_data(), kOneByteStringCid));
+  // Check that left and right are length one strings (either string constants
+  // or results of string-from-char-code.
+  Definition* left = call->ArgumentAt(0);
+  Definition* right = call->ArgumentAt(1);
+  Value* left_val = NULL;
+  Definition* to_remove_left = NULL;
+  if (IsLengthOneString(right)) {
+    // Swap, since we know that both arguments are strings
+    Definition* temp = left;
+    left = right;
+    right = temp;
+  }
+  if (IsLengthOneString(left)) {
+    // Optimize if left is a string with length one (either constant or
+    // result of string-from-char-code.
+    if (left->IsConstant()) {
+      ConstantInstr* left_const = left->AsConstant();
+      const String& str = String::Cast(left_const->value());
+      ASSERT(str.Length() == 1);
+      ConstantInstr* char_code_left = flow_graph()->GetConstant(
+          Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0)))));
+      left_val = new(Z) Value(char_code_left);
+    } else if (left->IsStringFromCharCode()) {
+      // Use input of string-from-charcode as left value.
+      StringFromCharCodeInstr* instr = left->AsStringFromCharCode();
+      left_val = new(Z) Value(instr->char_code()->definition());
+      to_remove_left = instr;
+    } else {
+      // IsLengthOneString(left) should have been false.
+      UNREACHABLE();
+    }
+
+    Definition* to_remove_right = NULL;
+    Value* right_val = NULL;
+    if (right->IsStringFromCharCode()) {
+      // Skip string-from-char-code, and use its input as right value.
+      StringFromCharCodeInstr* right_instr = right->AsStringFromCharCode();
+      right_val = new(Z) Value(right_instr->char_code()->definition());
+      to_remove_right = right_instr;
+    } else {
+      const ICData& unary_checks_1 =
+          ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1));
+      AddCheckClass(right,
+                    unary_checks_1,
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      // String-to-char-code instructions returns -1 (illegal charcode) if
+      // string is not of length one.
+      StringToCharCodeInstr* char_code_right =
+          new(Z) StringToCharCodeInstr(new(Z) Value(right), kOneByteStringCid);
+      InsertBefore(call, char_code_right, call->env(), FlowGraph::kValue);
+      right_val = new(Z) Value(char_code_right);
+    }
+
+    // Comparing char-codes instead of strings.
+    EqualityCompareInstr* comp =
+        new(Z) EqualityCompareInstr(call->token_pos(),
+                                    op_kind,
+                                    left_val,
+                                    right_val,
+                                    kSmiCid,
+                                    call->deopt_id());
+    ReplaceCall(call, comp);
+
+    // Remove dead instructions.
+    if ((to_remove_left != NULL) &&
+        (to_remove_left->input_use_list() == NULL)) {
+      to_remove_left->ReplaceUsesWith(flow_graph()->constant_null());
+      to_remove_left->RemoveFromGraph();
+    }
+    if ((to_remove_right != NULL) &&
+        (to_remove_right->input_use_list() == NULL)) {
+      to_remove_right->ReplaceUsesWith(flow_graph()->constant_null());
+      to_remove_right->RemoveFromGraph();
+    }
+    return true;
+  }
+  return false;
+}
+
+
+static bool SmiFitsInDouble() { return kSmiBits < 53; }
+
+bool AotOptimizer::TryReplaceWithEqualityOp(InstanceCallInstr* call,
+                                                  Token::Kind op_kind) {
+  const ICData& ic_data = *call->ic_data();
+  ASSERT(ic_data.NumArgsTested() == 2);
+
+  ASSERT(call->ArgumentCount() == 2);
+  Definition* left = call->ArgumentAt(0);
+  Definition* right = call->ArgumentAt(1);
+
+  intptr_t cid = kIllegalCid;
+  if (HasOnlyTwoOf(ic_data, kOneByteStringCid)) {
+    if (TryStringLengthOneEquality(call, op_kind)) {
+      return true;
+    } else {
+      return false;
+    }
+  } else if (HasOnlyTwoOf(ic_data, kSmiCid)) {
+    InsertBefore(call,
+                 new(Z) CheckSmiInstr(new(Z) Value(left),
+                                      call->deopt_id(),
+                                      call->token_pos()),
+                 call->env(),
+                 FlowGraph::kEffect);
+    InsertBefore(call,
+                 new(Z) CheckSmiInstr(new(Z) Value(right),
+                                      call->deopt_id(),
+                                      call->token_pos()),
+                 call->env(),
+                 FlowGraph::kEffect);
+    cid = kSmiCid;
+  } else if (HasTwoMintOrSmi(ic_data) &&
+             FlowGraphCompiler::SupportsUnboxedMints()) {
+    cid = kMintCid;
+  } else if (HasTwoDoubleOrSmi(ic_data) && CanUnboxDouble()) {
+    // Use double comparison.
+    if (SmiFitsInDouble()) {
+      cid = kDoubleCid;
+    } else {
+      if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
+        // We cannot use double comparison on two smis. Need polymorphic
+        // call.
+        return false;
+      } else {
+        InsertBefore(call,
+                     new(Z) CheckEitherNonSmiInstr(
+                         new(Z) Value(left),
+                         new(Z) Value(right),
+                         call->deopt_id()),
+                     call->env(),
+                     FlowGraph::kEffect);
+        cid = kDoubleCid;
+      }
+    }
+  } else {
+    // Check if ICDData contains checks with Smi/Null combinations. In that case
+    // we can still emit the optimized Smi equality operation but need to add
+    // checks for null or Smi.
+    GrowableArray<intptr_t> smi_or_null(2);
+    smi_or_null.Add(kSmiCid);
+    smi_or_null.Add(kNullCid);
+    if (ICDataHasOnlyReceiverArgumentClassIds(ic_data,
+                                              smi_or_null,
+                                              smi_or_null)) {
+      const ICData& unary_checks_0 =
+          ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks());
+      AddCheckClass(left,
+                    unary_checks_0,
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+
+      const ICData& unary_checks_1 =
+          ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecksForArgNr(1));
+      AddCheckClass(right,
+                    unary_checks_1,
+                    call->deopt_id(),
+                    call->env(),
+                    call);
+      cid = kSmiCid;
+    } else {
+      // Shortcut for equality with null.
+      ConstantInstr* right_const = right->AsConstant();
+      ConstantInstr* left_const = left->AsConstant();
+      if ((right_const != NULL && right_const->value().IsNull()) ||
+          (left_const != NULL && left_const->value().IsNull())) {
+        StrictCompareInstr* comp =
+            new(Z) StrictCompareInstr(call->token_pos(),
+                                      Token::kEQ_STRICT,
+                                      new(Z) Value(left),
+                                      new(Z) Value(right),
+                                      false);  // No number check.
+        ReplaceCall(call, comp);
+        return true;
+      }
+      return false;
+    }
+  }
+  ASSERT(cid != kIllegalCid);
+  EqualityCompareInstr* comp = new(Z) EqualityCompareInstr(call->token_pos(),
+                                                           op_kind,
+                                                           new(Z) Value(left),
+                                                           new(Z) Value(right),
+                                                           cid,
+                                                           call->deopt_id());
+  ReplaceCall(call, comp);
+  return true;
+}
+
+
+bool AotOptimizer::TryReplaceWithRelationalOp(InstanceCallInstr* call,
+                                                    Token::Kind op_kind) {
+  const ICData& ic_data = *call->ic_data();
+  ASSERT(ic_data.NumArgsTested() == 2);
+
+  ASSERT(call->ArgumentCount() == 2);
+  Definition* left = call->ArgumentAt(0);
+  Definition* right = call->ArgumentAt(1);
+
+  intptr_t cid = kIllegalCid;
+  if (HasOnlyTwoOf(ic_data, kSmiCid)) {
+    InsertBefore(call,
+                 new(Z) CheckSmiInstr(new(Z) Value(left),
+                                      call->deopt_id(),
+                                      call->token_pos()),
+                 call->env(),
+                 FlowGraph::kEffect);
+    InsertBefore(call,
+                 new(Z) CheckSmiInstr(new(Z) Value(right),
+                                      call->deopt_id(),
+                                      call->token_pos()),
+                 call->env(),
+                 FlowGraph::kEffect);
+    cid = kSmiCid;
+  } else if (HasTwoMintOrSmi(ic_data) &&
+             FlowGraphCompiler::SupportsUnboxedMints()) {
+    cid = kMintCid;
+  } else if (HasTwoDoubleOrSmi(ic_data) && CanUnboxDouble()) {
+    // Use double comparison.
+    if (SmiFitsInDouble()) {
+      cid = kDoubleCid;
+    } else {
+      if (ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid)) {
+        // We cannot use double comparison on two smis. Need polymorphic
+        // call.
+        return false;
+      } else {
+        InsertBefore(call,
+                     new(Z) CheckEitherNonSmiInstr(
+                         new(Z) Value(left),
+                         new(Z) Value(right),
+                         call->deopt_id()),
+                     call->env(),
+                     FlowGraph::kEffect);
+        cid = kDoubleCid;
+      }
+    }
+  } else {
+    return false;
+  }
+  ASSERT(cid != kIllegalCid);
+  RelationalOpInstr* comp = new(Z) RelationalOpInstr(call->token_pos(),
+                                                     op_kind,
+                                                     new(Z) Value(left),
+                                                     new(Z) Value(right),
+                                                     cid,
+                                                     call->deopt_id());
+  ReplaceCall(call, comp);
+  return true;
+}
+
+
+bool AotOptimizer::TryReplaceWithBinaryOp(InstanceCallInstr* call,
+                                                Token::Kind op_kind) {
+  intptr_t operands_type = kIllegalCid;
+  ASSERT(call->HasICData());
+  const ICData& ic_data = *call->ic_data();
+  switch (op_kind) {
+    case Token::kADD:
+    case Token::kSUB:
+    case Token::kMUL:
+      if (HasOnlyTwoOf(ic_data, kSmiCid)) {
+        // Don't generate smi code if the IC data is marked because
+        // of an overflow.
+        operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp)
+            ? kMintCid
+            : kSmiCid;
+      } else if (HasTwoMintOrSmi(ic_data) &&
+                 FlowGraphCompiler::SupportsUnboxedMints()) {
+        // Don't generate mint code if the IC data is marked because of an
+        // overflow.
+        if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) return false;
+        operands_type = kMintCid;
+      } else if (ShouldSpecializeForDouble(ic_data)) {
+        operands_type = kDoubleCid;
+      } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) {
+        operands_type = kFloat32x4Cid;
+      } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) {
+        ASSERT(op_kind != Token::kMUL);  // Int32x4 doesn't have a multiply op.
+        operands_type = kInt32x4Cid;
+      } else if (HasOnlyTwoOf(ic_data, kFloat64x2Cid)) {
+        operands_type = kFloat64x2Cid;
+      } else {
+        return false;
+      }
+      break;
+    case Token::kDIV:
+      if (!FlowGraphCompiler::SupportsHardwareDivision()) return false;
+      if (ShouldSpecializeForDouble(ic_data) ||
+          HasOnlyTwoOf(ic_data, kSmiCid)) {
+        operands_type = kDoubleCid;
+      } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) {
+        operands_type = kFloat32x4Cid;
+      } else if (HasOnlyTwoOf(ic_data, kFloat64x2Cid)) {
+        operands_type = kFloat64x2Cid;
+      } else {
+        return false;
+      }
+      break;
+    case Token::kBIT_AND:
+    case Token::kBIT_OR:
+    case Token::kBIT_XOR:
+      if (HasOnlyTwoOf(ic_data, kSmiCid)) {
+        operands_type = kSmiCid;
+      } else if (HasTwoMintOrSmi(ic_data)) {
+        operands_type = kMintCid;
+      } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) {
+        operands_type = kInt32x4Cid;
+      } else {
+        return false;
+      }
+      break;
+    case Token::kSHR:
+    case Token::kSHL:
+      if (HasOnlyTwoOf(ic_data, kSmiCid)) {
+        // Left shift may overflow from smi into mint or big ints.
+        // Don't generate smi code if the IC data is marked because
+        // of an overflow.
+        if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) {
+          return false;
+        }
+        operands_type = ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp)
+            ? kMintCid
+            : kSmiCid;
+      } else if (HasTwoMintOrSmi(ic_data) &&
+                 HasOnlyOneSmi(ICData::Handle(Z,
+                     ic_data.AsUnaryClassChecksForArgNr(1)))) {
+        // Don't generate mint code if the IC data is marked because of an
+        // overflow.
+        if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) {
+          return false;
+        }
+        // Check for smi/mint << smi or smi/mint >> smi.
+        operands_type = kMintCid;
+      } else {
+        return false;
+      }
+      break;
+    case Token::kMOD:
+    case Token::kTRUNCDIV:
+      if (!FlowGraphCompiler::SupportsHardwareDivision()) return false;
+      if (HasOnlyTwoOf(ic_data, kSmiCid)) {
+        if (ic_data.HasDeoptReason(ICData::kDeoptBinarySmiOp)) {
+          return false;
+        }
+        operands_type = kSmiCid;
+      } else {
+        return false;
+      }
+      break;
+    default:
+      UNREACHABLE();
+  }
+
+  ASSERT(call->ArgumentCount() == 2);
+  Definition* left = call->ArgumentAt(0);
+  Definition* right = call->ArgumentAt(1);
+  if (operands_type == kDoubleCid) {
+    if (!CanUnboxDouble()) {
+      return false;
+    }
+    // Check that either left or right are not a smi.  Result of a
+    // binary operation with two smis is a smi not a double, except '/' which
+    // returns a double for two smis.
+    if (op_kind != Token::kDIV) {
+      InsertBefore(call,
+                   new(Z) CheckEitherNonSmiInstr(
+                       new(Z) Value(left),
+                       new(Z) Value(right),
+                       call->deopt_id()),
+                   call->env(),
+                   FlowGraph::kEffect);
+    }
+
+    BinaryDoubleOpInstr* double_bin_op =
+        new(Z) BinaryDoubleOpInstr(op_kind,
+                                   new(Z) Value(left),
+                                   new(Z) Value(right),
+                                   call->deopt_id(), call->token_pos());
+    ReplaceCall(call, double_bin_op);
+  } else if (operands_type == kMintCid) {
+    if (!FlowGraphCompiler::SupportsUnboxedMints()) return false;
+    if ((op_kind == Token::kSHR) || (op_kind == Token::kSHL)) {
+      ShiftMintOpInstr* shift_op =
+          new(Z) ShiftMintOpInstr(
+              op_kind, new(Z) Value(left), new(Z) Value(right),
+              call->deopt_id());
+      ReplaceCall(call, shift_op);
+    } else {
+      BinaryMintOpInstr* bin_op =
+          new(Z) BinaryMintOpInstr(
+              op_kind, new(Z) Value(left), new(Z) Value(right),
+              call->deopt_id());
+      ReplaceCall(call, bin_op);
+    }
+  } else if (operands_type == kFloat32x4Cid) {
+    return InlineFloat32x4BinaryOp(call, op_kind);
+  } else if (operands_type == kInt32x4Cid) {
+    return InlineInt32x4BinaryOp(call, op_kind);
+  } else if (operands_type == kFloat64x2Cid) {
+    return InlineFloat64x2BinaryOp(call, op_kind);
+  } else if (op_kind == Token::kMOD) {
+    ASSERT(operands_type == kSmiCid);
+    if (right->IsConstant()) {
+      const Object& obj = right->AsConstant()->value();
+      if (obj.IsSmi() && Utils::IsPowerOfTwo(Smi::Cast(obj).Value())) {
+        // Insert smi check and attach a copy of the original environment
+        // because the smi operation can still deoptimize.
+        InsertBefore(call,
+                     new(Z) CheckSmiInstr(new(Z) Value(left),
+                                          call->deopt_id(),
+                                          call->token_pos()),
+                     call->env(),
+                     FlowGraph::kEffect);
+        ConstantInstr* constant =
+            flow_graph()->GetConstant(Smi::Handle(Z,
+                Smi::New(Smi::Cast(obj).Value() - 1)));
+        BinarySmiOpInstr* bin_op =
+            new(Z) BinarySmiOpInstr(Token::kBIT_AND,
+                                    new(Z) Value(left),
+                                    new(Z) Value(constant),
+                                    call->deopt_id());
+        ReplaceCall(call, bin_op);
+        return true;
+      }
+    }
+    // Insert two smi checks and attach a copy of the original
+    // environment because the smi operation can still deoptimize.
+    AddCheckSmi(left, call->deopt_id(), call->env(), call);
+    AddCheckSmi(right, call->deopt_id(), call->env(), call);
+    BinarySmiOpInstr* bin_op =
+        new(Z) BinarySmiOpInstr(op_kind,
+                                new(Z) Value(left),
+                                new(Z) Value(right),
+                                call->deopt_id());
+    ReplaceCall(call, bin_op);
+  } else {
+    ASSERT(operands_type == kSmiCid);
+    // Insert two smi checks and attach a copy of the original
+    // environment because the smi operation can still deoptimize.
+    AddCheckSmi(left, call->deopt_id(), call->env(), call);
+    AddCheckSmi(right, call->deopt_id(), call->env(), call);
+    if (left->IsConstant() &&
+        ((op_kind == Token::kADD) || (op_kind == Token::kMUL))) {
+      // Constant should be on the right side.
+      Definition* temp = left;
+      left = right;
+      right = temp;
+    }
+    BinarySmiOpInstr* bin_op =
+        new(Z) BinarySmiOpInstr(
+            op_kind,
+            new(Z) Value(left),
+            new(Z) Value(right),
+            call->deopt_id());
+    ReplaceCall(call, bin_op);
+  }
+  return true;
+}
+
+
+bool AotOptimizer::TryReplaceWithUnaryOp(InstanceCallInstr* call,
+                                               Token::Kind op_kind) {
+  ASSERT(call->ArgumentCount() == 1);
+  Definition* input = call->ArgumentAt(0);
+  Definition* unary_op = NULL;
+  if (HasOnlyOneSmi(*call->ic_data())) {
+    InsertBefore(call,
+                 new(Z) CheckSmiInstr(new(Z) Value(input),
+                                      call->deopt_id(),
+                                      call->token_pos()),
+                 call->env(),
+                 FlowGraph::kEffect);
+    unary_op = new(Z) UnarySmiOpInstr(
+        op_kind, new(Z) Value(input), call->deopt_id());
+  } else if ((op_kind == Token::kBIT_NOT) &&
+             HasOnlySmiOrMint(*call->ic_data()) &&
+             FlowGraphCompiler::SupportsUnboxedMints()) {
+    unary_op = new(Z) UnaryMintOpInstr(
+        op_kind, new(Z) Value(input), call->deopt_id());
+  } else if (HasOnlyOneDouble(*call->ic_data()) &&
+             (op_kind == Token::kNEGATE) &&
+             CanUnboxDouble()) {
+    AddReceiverCheck(call);
+    unary_op = new(Z) UnaryDoubleOpInstr(
+        Token::kNEGATE, new(Z) Value(input), call->deopt_id());
+  } else {
+    return false;
+  }
+  ASSERT(unary_op != NULL);
+  ReplaceCall(call, unary_op);
+  return true;
+}
+
+
+// Using field class
+RawField* AotOptimizer::GetField(intptr_t class_id,
+                                       const String& field_name) {
+  Class& cls = Class::Handle(Z, isolate()->class_table()->At(class_id));
+  Field& field = Field::Handle(Z);
+  while (!cls.IsNull()) {
+    field = cls.LookupInstanceField(field_name);
+    if (!field.IsNull()) {
+      return field.raw();
+    }
+    cls = cls.SuperClass();
+  }
+  return Field::null();
+}
+
+
+// Use CHA to determine if the call needs a class check: if the callee's
+// receiver is the same as the caller's receiver and there are no overriden
+// callee functions, then no class check is needed.
+bool AotOptimizer::InstanceCallNeedsClassCheck(
+    InstanceCallInstr* call, RawFunction::Kind kind) const {
+  if (!FLAG_use_cha_deopt && !isolate()->all_classes_finalized()) {
+    // Even if class or function are private, lazy class finalization
+    // may later add overriding methods.
+    return true;
+  }
+  Definition* callee_receiver = call->ArgumentAt(0);
+  ASSERT(callee_receiver != NULL);
+  const Function& function = flow_graph_->function();
+  if (function.IsDynamicFunction() &&
+      callee_receiver->IsParameter() &&
+      (callee_receiver->AsParameter()->index() == 0)) {
+    const String& name = (kind == RawFunction::kMethodExtractor)
+        ? String::Handle(Z, Field::NameFromGetter(call->function_name()))
+        : call->function_name();
+    const Class& cls = Class::Handle(Z, function.Owner());
+    if (!thread()->cha()->HasOverride(cls, name)) {
+      if (FLAG_trace_cha) {
+        THR_Print("  **(CHA) Instance call needs no check, "
+            "no overrides of '%s' '%s'\n",
+            name.ToCString(), cls.ToCString());
+      }
+      thread()->cha()->AddToLeafClasses(cls);
+      return false;
+    }
+  }
+  return true;
+}
+
+
+bool AotOptimizer::InlineImplicitInstanceGetter(InstanceCallInstr* call,
+                                                      bool allow_check) {
+  ASSERT(call->HasICData());
+  const ICData& ic_data = *call->ic_data();
+  ASSERT(ic_data.HasOneTarget());
+  GrowableArray<intptr_t> class_ids;
+  ic_data.GetClassIdsAt(0, &class_ids);
+  ASSERT(class_ids.length() == 1);
+  // Inline implicit instance getter.
+  const String& field_name =
+      String::Handle(Z, Field::NameFromGetter(call->function_name()));
+  const Field& field =
+      Field::ZoneHandle(Z, GetField(class_ids[0], field_name));
+  ASSERT(!field.IsNull());
+
+  if (InstanceCallNeedsClassCheck(call, RawFunction::kImplicitGetter)) {
+    if (!allow_check) {
+      return false;
+    }
+    AddReceiverCheck(call);
+  }
+  LoadFieldInstr* load = new(Z) LoadFieldInstr(
+      new(Z) Value(call->ArgumentAt(0)),
+      &field,
+      AbstractType::ZoneHandle(Z, field.type()),
+      call->token_pos());
+  load->set_is_immutable(field.is_final());
+
+  // Discard the environment from the original instruction because the load
+  // can't deoptimize.
+  call->RemoveEnvironment();
+  ReplaceCall(call, load);
+
+  if (load->result_cid() != kDynamicCid) {
+    // Reset value types if guarded_cid was used.
+    for (Value::Iterator it(load->input_use_list());
+         !it.Done();
+         it.Advance()) {
+      it.Current()->SetReachingType(NULL);
+    }
+  }
+  return true;
+}
+
+
+bool AotOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
+                                               MethodRecognizer::Kind getter) {
+  if (!ShouldInlineSimd()) {
+    return false;
+  }
+  AddCheckClass(call->ArgumentAt(0),
+                ICData::ZoneHandle(
+                    Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  intptr_t mask = 0;
+  if ((getter == MethodRecognizer::kFloat32x4Shuffle) ||
+      (getter == MethodRecognizer::kFloat32x4ShuffleMix)) {
+    // Extract shuffle mask.
+    Definition* mask_definition = NULL;
+    if (getter == MethodRecognizer::kFloat32x4Shuffle) {
+      ASSERT(call->ArgumentCount() == 2);
+      mask_definition = call->ArgumentAt(1);
+    } else {
+      ASSERT(getter == MethodRecognizer::kFloat32x4ShuffleMix);
+      ASSERT(call->ArgumentCount() == 3);
+      mask_definition = call->ArgumentAt(2);
+    }
+    if (!mask_definition->IsConstant()) {
+      return false;
+    }
+    ASSERT(mask_definition->IsConstant());
+    ConstantInstr* constant_instruction = mask_definition->AsConstant();
+    const Object& constant_mask = constant_instruction->value();
+    if (!constant_mask.IsSmi()) {
+      return false;
+    }
+    ASSERT(constant_mask.IsSmi());
+    mask = Smi::Cast(constant_mask).Value();
+    if ((mask < 0) || (mask > 255)) {
+      // Not a valid mask.
+      return false;
+    }
+  }
+  if (getter == MethodRecognizer::kFloat32x4GetSignMask) {
+    Simd32x4GetSignMaskInstr* instr = new(Z) Simd32x4GetSignMaskInstr(
+        getter,
+        new(Z) Value(call->ArgumentAt(0)),
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  } else if (getter == MethodRecognizer::kFloat32x4ShuffleMix) {
+    Simd32x4ShuffleMixInstr* instr = new(Z) Simd32x4ShuffleMixInstr(
+        getter,
+        new(Z) Value(call->ArgumentAt(0)),
+        new(Z) Value(call->ArgumentAt(1)),
+        mask,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  } else {
+    ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle)  ||
+           (getter == MethodRecognizer::kFloat32x4ShuffleX) ||
+           (getter == MethodRecognizer::kFloat32x4ShuffleY) ||
+           (getter == MethodRecognizer::kFloat32x4ShuffleZ) ||
+           (getter == MethodRecognizer::kFloat32x4ShuffleW));
+    Simd32x4ShuffleInstr* instr = new(Z) Simd32x4ShuffleInstr(
+        getter,
+        new(Z) Value(call->ArgumentAt(0)),
+        mask,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
+bool AotOptimizer::InlineFloat64x2Getter(InstanceCallInstr* call,
+                                               MethodRecognizer::Kind getter) {
+  if (!ShouldInlineSimd()) {
+    return false;
+  }
+  AddCheckClass(call->ArgumentAt(0),
+                ICData::ZoneHandle(
+                    Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  if ((getter == MethodRecognizer::kFloat64x2GetX) ||
+      (getter == MethodRecognizer::kFloat64x2GetY)) {
+    Simd64x2ShuffleInstr* instr = new(Z) Simd64x2ShuffleInstr(
+        getter,
+        new(Z) Value(call->ArgumentAt(0)),
+        0,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  }
+  UNREACHABLE();
+  return false;
+}
+
+
+bool AotOptimizer::InlineInt32x4Getter(InstanceCallInstr* call,
+                                              MethodRecognizer::Kind getter) {
+  if (!ShouldInlineSimd()) {
+    return false;
+  }
+  AddCheckClass(call->ArgumentAt(0),
+                ICData::ZoneHandle(
+                    Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  intptr_t mask = 0;
+  if ((getter == MethodRecognizer::kInt32x4Shuffle) ||
+      (getter == MethodRecognizer::kInt32x4ShuffleMix)) {
+    // Extract shuffle mask.
+    Definition* mask_definition = NULL;
+    if (getter == MethodRecognizer::kInt32x4Shuffle) {
+      ASSERT(call->ArgumentCount() == 2);
+      mask_definition = call->ArgumentAt(1);
+    } else {
+      ASSERT(getter == MethodRecognizer::kInt32x4ShuffleMix);
+      ASSERT(call->ArgumentCount() == 3);
+      mask_definition = call->ArgumentAt(2);
+    }
+    if (!mask_definition->IsConstant()) {
+      return false;
+    }
+    ASSERT(mask_definition->IsConstant());
+    ConstantInstr* constant_instruction = mask_definition->AsConstant();
+    const Object& constant_mask = constant_instruction->value();
+    if (!constant_mask.IsSmi()) {
+      return false;
+    }
+    ASSERT(constant_mask.IsSmi());
+    mask = Smi::Cast(constant_mask).Value();
+    if ((mask < 0) || (mask > 255)) {
+      // Not a valid mask.
+      return false;
+    }
+  }
+  if (getter == MethodRecognizer::kInt32x4GetSignMask) {
+    Simd32x4GetSignMaskInstr* instr = new(Z) Simd32x4GetSignMaskInstr(
+        getter,
+        new(Z) Value(call->ArgumentAt(0)),
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  } else if (getter == MethodRecognizer::kInt32x4ShuffleMix) {
+    Simd32x4ShuffleMixInstr* instr = new(Z) Simd32x4ShuffleMixInstr(
+        getter,
+        new(Z) Value(call->ArgumentAt(0)),
+        new(Z) Value(call->ArgumentAt(1)),
+        mask,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  } else if (getter == MethodRecognizer::kInt32x4Shuffle) {
+    Simd32x4ShuffleInstr* instr = new(Z) Simd32x4ShuffleInstr(
+        getter,
+        new(Z) Value(call->ArgumentAt(0)),
+        mask,
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  } else {
+    Int32x4GetFlagInstr* instr = new(Z) Int32x4GetFlagInstr(
+        getter,
+        new(Z) Value(call->ArgumentAt(0)),
+        call->deopt_id());
+    ReplaceCall(call, instr);
+    return true;
+  }
+}
+
+
+bool AotOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call,
+                                                 Token::Kind op_kind) {
+  if (!ShouldInlineSimd()) {
+    return false;
+  }
+  ASSERT(call->ArgumentCount() == 2);
+  Definition* left = call->ArgumentAt(0);
+  Definition* right = call->ArgumentAt(1);
+  // Type check left.
+  AddCheckClass(left,
+                ICData::ZoneHandle(
+                    Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  // Type check right.
+  AddCheckClass(right,
+                ICData::ZoneHandle(
+                    Z, call->ic_data()->AsUnaryClassChecksForArgNr(1)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  // Replace call.
+  BinaryFloat32x4OpInstr* float32x4_bin_op =
+      new(Z) BinaryFloat32x4OpInstr(
+          op_kind, new(Z) Value(left), new(Z) Value(right),
+          call->deopt_id());
+  ReplaceCall(call, float32x4_bin_op);
+
+  return true;
+}
+
+
+bool AotOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call,
+                                                Token::Kind op_kind) {
+  if (!ShouldInlineSimd()) {
+    return false;
+  }
+  ASSERT(call->ArgumentCount() == 2);
+  Definition* left = call->ArgumentAt(0);
+  Definition* right = call->ArgumentAt(1);
+  // Type check left.
+  AddCheckClass(left,
+                ICData::ZoneHandle(
+                    Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  // Type check right.
+  AddCheckClass(right,
+                ICData::ZoneHandle(Z,
+                    call->ic_data()->AsUnaryClassChecksForArgNr(1)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  // Replace call.
+  BinaryInt32x4OpInstr* int32x4_bin_op =
+      new(Z) BinaryInt32x4OpInstr(
+          op_kind, new(Z) Value(left), new(Z) Value(right),
+          call->deopt_id());
+  ReplaceCall(call, int32x4_bin_op);
+  return true;
+}
+
+
+bool AotOptimizer::InlineFloat64x2BinaryOp(InstanceCallInstr* call,
+                                                 Token::Kind op_kind) {
+  if (!ShouldInlineSimd()) {
+    return false;
+  }
+  ASSERT(call->ArgumentCount() == 2);
+  Definition* left = call->ArgumentAt(0);
+  Definition* right = call->ArgumentAt(1);
+  // Type check left.
+  AddCheckClass(left,
+                ICData::ZoneHandle(
+                    call->ic_data()->AsUnaryClassChecksForArgNr(0)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  // Type check right.
+  AddCheckClass(right,
+                ICData::ZoneHandle(
+                    call->ic_data()->AsUnaryClassChecksForArgNr(1)),
+                call->deopt_id(),
+                call->env(),
+                call);
+  // Replace call.
+  BinaryFloat64x2OpInstr* float64x2_bin_op =
+      new(Z) BinaryFloat64x2OpInstr(
+          op_kind, new(Z) Value(left), new(Z) Value(right),
+          call->deopt_id());
+  ReplaceCall(call, float64x2_bin_op);
+  return true;
+}
+
+
+// Only unique implicit instance getters can be currently handled.
+// Returns false if 'allow_check' is false and a check is needed.
+bool AotOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call,
+                                                 bool allow_check) {
+  ASSERT(call->HasICData());
+  const ICData& ic_data = *call->ic_data();
+  if (ic_data.NumberOfUsedChecks() == 0) {
+    // No type feedback collected.
+    return false;
+  }
+
+  if (!ic_data.HasOneTarget()) {
+    // Polymorphic sites are inlined like normal methods by conventional
+    // inlining in FlowGraphInliner.
+    return false;
+  }
+
+  const Function& target = Function::Handle(Z, ic_data.GetTargetAt(0));
+  if (target.kind() != RawFunction::kImplicitGetter) {
+    // Non-implicit getters are inlined like normal methods by conventional
+    // inlining in FlowGraphInliner.
+    return false;
+  }
+  return InlineImplicitInstanceGetter(call, allow_check);
+}
+
+
+bool AotOptimizer::TryReplaceInstanceCallWithInline(
+    InstanceCallInstr* call) {
+  Function& target = Function::Handle(Z);
+  GrowableArray<intptr_t> class_ids;
+  call->ic_data()->GetCheckAt(0, &class_ids, &target);
+  const intptr_t receiver_cid = class_ids[0];
+
+  TargetEntryInstr* entry;
+  Definition* last;
+  if (!FlowGraphInliner::TryInlineRecognizedMethod(flow_graph_,
+                                                   receiver_cid,
+                                                   target,
+                                                   call,
+                                                   call->ArgumentAt(0),
+                                                   call->token_pos(),
+                                                   *call->ic_data(),
+                                                   &entry, &last)) {
+    return false;
+  }
+
+  // Insert receiver class check.
+  AddReceiverCheck(call);
+  // Remove the original push arguments.
+  for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+    PushArgumentInstr* push = call->PushArgumentAt(i);
+    push->ReplaceUsesWith(push->value()->definition());
+    push->RemoveFromGraph();
+  }
+  // Replace all uses of this definition with the result.
+  call->ReplaceUsesWith(last);
+  // Finally insert the sequence other definition in place of this one in the
+  // graph.
+  call->previous()->LinkTo(entry->next());
+  entry->UnuseAllInputs();  // Entry block is not in the graph.
+  last->LinkTo(call);
+  // Remove through the iterator.
+  ASSERT(current_iterator()->Current() == call);
+  current_iterator()->RemoveCurrentFromGraph();
+  call->set_previous(NULL);
+  call->set_next(NULL);
+  return true;
+}
+
+
+void AotOptimizer::ReplaceWithMathCFunction(
+    InstanceCallInstr* call,
+    MethodRecognizer::Kind recognized_kind) {
+  AddReceiverCheck(call);
+  ZoneGrowableArray<Value*>* args =
+      new(Z) ZoneGrowableArray<Value*>(call->ArgumentCount());
+  for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
+    args->Add(new(Z) Value(call->ArgumentAt(i)));
+  }
+  InvokeMathCFunctionInstr* invoke =
+      new(Z) InvokeMathCFunctionInstr(args,
+                                      call->deopt_id(),
+                                      recognized_kind,
+                                      call->token_pos());
+  ReplaceCall(call, invoke);
+}
+
+
+static bool IsSupportedByteArrayViewCid(intptr_t cid) {
+  switch (cid) {
+    case kTypedDataInt8ArrayCid:
+    case kTypedDataUint8ArrayCid:
+    case kExternalTypedDataUint8ArrayCid:
+    case kTypedDataUint8ClampedArrayCid:
+    case kExternalTypedDataUint8ClampedArrayCid:
+    case kTypedDataInt16ArrayCid:
+    case kTypedDataUint16ArrayCid:
+    case kTypedDataInt32ArrayCid:
+    case kTypedDataUint32ArrayCid:
+    case kTypedDataFloat32ArrayCid:
+    case kTypedDataFloat64ArrayCid:
+    case kTypedDataFloat32x4ArrayCid:
+    case kTypedDataInt32x4ArrayCid:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
+// Inline only simple, frequently called core library methods.
+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.
+    return false;
+  }
+
+  Function& target = Function::Handle(Z);
+  GrowableArray<intptr_t> class_ids;
+  ic_data.GetCheckAt(0, &class_ids, &target);
+  MethodRecognizer::Kind recognized_kind =
+      MethodRecognizer::RecognizeKind(target);
+
+  if ((recognized_kind == MethodRecognizer::kGrowableArraySetData) &&
+      (ic_data.NumberOfChecks() == 1) &&
+      (class_ids[0] == kGrowableObjectArrayCid)) {
+    // This is an internal method, no need to check argument types.
+    Definition* array = call->ArgumentAt(0);
+    Definition* value = call->ArgumentAt(1);
+    StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
+        GrowableObjectArray::data_offset(),
+        new(Z) Value(array),
+        new(Z) Value(value),
+        kEmitStoreBarrier,
+        call->token_pos());
+    ReplaceCall(call, store);
+    return true;
+  }
+
+  if ((recognized_kind == MethodRecognizer::kGrowableArraySetLength) &&
+      (ic_data.NumberOfChecks() == 1) &&
+      (class_ids[0] == kGrowableObjectArrayCid)) {
+    // This is an internal method, no need to check argument types nor
+    // range.
+    Definition* array = call->ArgumentAt(0);
+    Definition* value = call->ArgumentAt(1);
+    StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
+        GrowableObjectArray::length_offset(),
+        new(Z) Value(array),
+        new(Z) Value(value),
+        kNoStoreBarrier,
+        call->token_pos());
+    ReplaceCall(call, store);
+    return true;
+  }
+
+  if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
+       (recognized_kind == MethodRecognizer::kStringBaseCharAt)) &&
+      (ic_data.NumberOfChecks() == 1) &&
+      ((class_ids[0] == kOneByteStringCid) ||
+       (class_ids[0] == kTwoByteStringCid))) {
+    return TryReplaceInstanceCallWithInline(call);
+  }
+
+  if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) {
+    if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) {
+      // This is an internal method, no need to check argument types nor
+      // range.
+      Definition* str = call->ArgumentAt(0);
+      Definition* index = call->ArgumentAt(1);
+      Definition* value = call->ArgumentAt(2);
+      StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr(
+          new(Z) Value(str),
+          new(Z) Value(index),
+          new(Z) Value(value),
+          kNoStoreBarrier,
+          1,  // Index scale
+          kOneByteStringCid,
+          call->deopt_id(),
+          call->token_pos());
+      ReplaceCall(call, store_op);
+      return true;
+    }
+    return false;
+  }
+
+  if (CanUnboxDouble() &&
+      (recognized_kind == MethodRecognizer::kIntegerToDouble) &&
+      (ic_data.NumberOfChecks() == 1)) {
+    if (class_ids[0] == kSmiCid) {
+      AddReceiverCheck(call);
+      ReplaceCall(call,
+                  new(Z) SmiToDoubleInstr(
+                      new(Z) Value(call->ArgumentAt(0)),
+                      call->token_pos()));
+      return true;
+    } else if ((class_ids[0] == kMintCid) && CanConvertUnboxedMintToDouble()) {
+      AddReceiverCheck(call);
+      ReplaceCall(call,
+                  new(Z) MintToDoubleInstr(new(Z) Value(call->ArgumentAt(0)),
+                                           call->deopt_id()));
+      return true;
+    }
+  }
+
+  if (class_ids[0] == kDoubleCid) {
+    if (!CanUnboxDouble()) {
+      return false;
+    }
+    switch (recognized_kind) {
+      case MethodRecognizer::kDoubleToInteger: {
+        AddReceiverCheck(call);
+        ASSERT(call->HasICData());
+        const ICData& ic_data = *call->ic_data();
+        Definition* input = call->ArgumentAt(0);
+        Definition* d2i_instr = NULL;
+        if (ic_data.HasDeoptReason(ICData::kDeoptDoubleToSmi)) {
+          // Do not repeatedly deoptimize because result didn't fit into Smi.
+          d2i_instr =  new(Z) DoubleToIntegerInstr(
+              new(Z) Value(input), call);
+        } else {
+          // Optimistically assume result fits into Smi.
+          d2i_instr = new(Z) DoubleToSmiInstr(
+              new(Z) Value(input), call->deopt_id());
+        }
+        ReplaceCall(call, d2i_instr);
+        return true;
+      }
+      case MethodRecognizer::kDoubleMod:
+      case MethodRecognizer::kDoubleRound:
+        ReplaceWithMathCFunction(call, recognized_kind);
+        return true;
+      case MethodRecognizer::kDoubleTruncate:
+      case MethodRecognizer::kDoubleFloor:
+      case MethodRecognizer::kDoubleCeil:
+        if (!TargetCPUFeatures::double_truncate_round_supported()) {
+          ReplaceWithMathCFunction(call, recognized_kind);
+        } else {
+          AddReceiverCheck(call);
+          DoubleToDoubleInstr* d2d_instr =
+              new(Z) DoubleToDoubleInstr(new(Z) Value(call->ArgumentAt(0)),
+                                         recognized_kind, call->deopt_id());
+          ReplaceCall(call, d2d_instr);
+        }
+        return true;
+      case MethodRecognizer::kDoubleAdd:
+      case MethodRecognizer::kDoubleSub:
+      case MethodRecognizer::kDoubleMul:
+      case MethodRecognizer::kDoubleDiv:
+        return TryReplaceInstanceCallWithInline(call);
+      default:
+        // Unsupported method.
+        return false;
+    }
+  }
+
+  if (IsSupportedByteArrayViewCid(class_ids[0]) &&
+      (ic_data.NumberOfChecks() == 1)) {
+    return TryReplaceInstanceCallWithInline(call);
+  }
+
+  if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
+    return TryInlineFloat32x4Method(call, recognized_kind);
+  }
+
+  if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
+    return TryInlineInt32x4Method(call, recognized_kind);
+  }
+
+  if ((class_ids[0] == kFloat64x2Cid) && (ic_data.NumberOfChecks() == 1)) {
+    return TryInlineFloat64x2Method(call, recognized_kind);
+  }
+
+  if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) {
+    ASSERT(call->ArgumentCount() == 3);
+    ASSERT(ic_data.NumArgsTested() == 2);
+    Definition* value = call->ArgumentAt(0);
+    Definition* count = call->ArgumentAt(1);
+    Definition* int32_mask = call->ArgumentAt(2);
+    if (HasOnlyTwoOf(ic_data, kSmiCid)) {
+      if (ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) {
+        return false;
+      }
+      // We cannot overflow. The input value must be a Smi
+      AddCheckSmi(value, call->deopt_id(), call->env(), call);
+      AddCheckSmi(count, call->deopt_id(), call->env(), call);
+      ASSERT(int32_mask->IsConstant());
+      const Integer& mask_literal = Integer::Cast(
+          int32_mask->AsConstant()->value());
+      const int64_t mask_value = mask_literal.AsInt64Value();
+      ASSERT(mask_value >= 0);
+      if (mask_value > Smi::kMaxValue) {
+        // The result will not be Smi.
+        return false;
+      }
+      BinarySmiOpInstr* left_shift =
+          new(Z) BinarySmiOpInstr(Token::kSHL,
+                                  new(Z) Value(value),
+                                  new(Z) Value(count),
+                                  call->deopt_id());
+      left_shift->mark_truncating();
+      if ((kBitsPerWord == 32) && (mask_value == 0xffffffffLL)) {
+        // No BIT_AND operation needed.
+        ReplaceCall(call, left_shift);
+      } else {
+        InsertBefore(call, left_shift, call->env(), FlowGraph::kValue);
+        BinarySmiOpInstr* bit_and =
+            new(Z) BinarySmiOpInstr(Token::kBIT_AND,
+                                    new(Z) Value(left_shift),
+                                    new(Z) Value(int32_mask),
+                                    call->deopt_id());
+        ReplaceCall(call, bit_and);
+      }
+      return true;
+    }
+
+    if (HasTwoMintOrSmi(ic_data) &&
+        HasOnlyOneSmi(ICData::Handle(Z,
+                                     ic_data.AsUnaryClassChecksForArgNr(1)))) {
+      if (!FlowGraphCompiler::SupportsUnboxedMints() ||
+          ic_data.HasDeoptReason(ICData::kDeoptBinaryMintOp)) {
+        return false;
+      }
+      ShiftMintOpInstr* left_shift =
+          new(Z) ShiftMintOpInstr(Token::kSHL,
+                                  new(Z) Value(value),
+                                  new(Z) Value(count),
+                                  call->deopt_id());
+      InsertBefore(call, left_shift, call->env(), FlowGraph::kValue);
+      BinaryMintOpInstr* bit_and =
+          new(Z) BinaryMintOpInstr(Token::kBIT_AND,
+                                   new(Z) Value(left_shift),
+                                   new(Z) Value(int32_mask),
+                                   call->deopt_id());
+      ReplaceCall(call, bit_and);
+      return true;
+    }
+  }
+  return false;
+}
+
+
+bool AotOptimizer::TryInlineFloat32x4Constructor(
+    StaticCallInstr* call,
+    MethodRecognizer::Kind recognized_kind) {
+  // Cannot handle unboxed instructions.
+  ASSERT(FLAG_precompilation);
+  return false;
+}
+
+
+bool AotOptimizer::TryInlineFloat64x2Constructor(
+    StaticCallInstr* call,
+    MethodRecognizer::Kind recognized_kind) {
+  // Cannot handle unboxed instructions.
+  ASSERT(FLAG_precompilation);
+  return false;
+}
+
+
+bool AotOptimizer::TryInlineInt32x4Constructor(
+    StaticCallInstr* call,
+    MethodRecognizer::Kind recognized_kind) {
+  // Cannot handle unboxed instructions.
+  ASSERT(FLAG_precompilation);
+  return false;
+}
+
+
+bool AotOptimizer::TryInlineFloat32x4Method(
+    InstanceCallInstr* call,
+    MethodRecognizer::Kind recognized_kind) {
+  // Cannot handle unboxed instructions.
+  return false;
+}
+
+
+bool AotOptimizer::TryInlineFloat64x2Method(
+    InstanceCallInstr* call,
+    MethodRecognizer::Kind recognized_kind) {
+  // Cannot handle unboxed instructions.
+  return false;
+}
+
+
+bool AotOptimizer::TryInlineInt32x4Method(
+    InstanceCallInstr* call,
+    MethodRecognizer::Kind recognized_kind) {
+  // Cannot handle unboxed instructions.
+  return false;
+}
+
+
+// If type tests specified by 'ic_data' do not depend on type arguments,
+// return mapping cid->result in 'results' (i : cid; i + 1: result).
+// If all tests yield the same result, return it otherwise return Bool::null.
+// If no mapping is possible, 'results' is empty.
+// An instance-of test returning all same results can be converted to a class
+// check.
+RawBool* AotOptimizer::InstanceOfAsBool(
+    const ICData& ic_data,
+    const AbstractType& type,
+    ZoneGrowableArray<intptr_t>* results) const {
+  ASSERT(results->is_empty());
+  ASSERT(ic_data.NumArgsTested() == 1);  // Unary checks only.
+  if (type.IsFunctionType() || type.IsDartFunctionType() ||
+      !type.IsInstantiated() || type.IsMalformedOrMalbounded()) {
+    return Bool::null();
+  }
+  const Class& type_class = Class::Handle(Z, type.type_class());
+  const intptr_t num_type_args = type_class.NumTypeArguments();
+  if (num_type_args > 0) {
+    // Only raw types can be directly compared, thus disregarding type
+    // arguments.
+    const intptr_t num_type_params = type_class.NumTypeParameters();
+    const intptr_t from_index = num_type_args - num_type_params;
+    const TypeArguments& type_arguments =
+        TypeArguments::Handle(Z, type.arguments());
+    const bool is_raw_type = type_arguments.IsNull() ||
+        type_arguments.IsRaw(from_index, num_type_params);
+    if (!is_raw_type) {
+      // Unknown result.
+      return Bool::null();
+    }
+  }
+
+  const ClassTable& class_table = *isolate()->class_table();
+  Bool& prev = Bool::Handle(Z);
+  Class& cls = Class::Handle(Z);
+
+  bool results_differ = false;
+  for (int i = 0; i < ic_data.NumberOfChecks(); i++) {
+    cls = class_table.At(ic_data.GetReceiverClassIdAt(i));
+    if (cls.NumTypeArguments() > 0) {
+      return Bool::null();
+    }
+    const bool is_subtype = cls.IsSubtypeOf(
+        TypeArguments::Handle(Z),
+        type_class,
+        TypeArguments::Handle(Z),
+        NULL,
+        NULL,
+        Heap::kOld);
+    results->Add(cls.id());
+    results->Add(is_subtype);
+    if (prev.IsNull()) {
+      prev = Bool::Get(is_subtype).raw();
+    } else {
+      if (is_subtype != prev.value()) {
+        results_differ = true;
+      }
+    }
+  }
+  return results_differ ?  Bool::null() : prev.raw();
+}
+
+
+// Returns true if checking against this type is a direct class id comparison.
+bool AotOptimizer::TypeCheckAsClassEquality(const AbstractType& type) {
+  ASSERT(type.IsFinalized() && !type.IsMalformedOrMalbounded());
+  // Requires CHA.
+  if (!type.IsInstantiated()) return false;
+  // Function types have different type checking rules.
+  if (type.IsFunctionType()) return false;
+  const Class& type_class = Class::Handle(type.type_class());
+  // Could be an interface check?
+  if (CHA::IsImplemented(type_class)) return false;
+  // Check if there are subclasses.
+  if (CHA::HasSubclasses(type_class)) {
+    return false;
+  }
+
+  // Private classes cannot be subclassed by later loaded libs.
+  if (!type_class.IsPrivate()) {
+    if (FLAG_use_cha_deopt || isolate()->all_classes_finalized()) {
+      if (FLAG_trace_cha) {
+        THR_Print("  **(CHA) Typecheck as class equality since no "
+            "subclasses: %s\n",
+            type_class.ToCString());
+      }
+      if (FLAG_use_cha_deopt) {
+        thread()->cha()->AddToLeafClasses(type_class);
+      }
+    } else {
+      return false;
+    }
+  }
+  const intptr_t num_type_args = type_class.NumTypeArguments();
+  if (num_type_args > 0) {
+    // Only raw types can be directly compared, thus disregarding type
+    // arguments.
+    const intptr_t num_type_params = type_class.NumTypeParameters();
+    const intptr_t from_index = num_type_args - num_type_params;
+    const TypeArguments& type_arguments =
+        TypeArguments::Handle(type.arguments());
+    const bool is_raw_type = type_arguments.IsNull() ||
+        type_arguments.IsRaw(from_index, num_type_params);
+    return is_raw_type;
+  }
+  return true;
+}
+
+
+static bool CidTestResultsContains(const ZoneGrowableArray<intptr_t>& results,
+                                   intptr_t test_cid) {
+  for (intptr_t i = 0; i < results.length(); i += 2) {
+    if (results[i] == test_cid) return true;
+  }
+  return false;
+}
+
+
+static void TryAddTest(ZoneGrowableArray<intptr_t>* results,
+                       intptr_t test_cid,
+                       bool result) {
+  if (!CidTestResultsContains(*results, test_cid)) {
+    results->Add(test_cid);
+    results->Add(result);
+  }
+}
+
+
+// Tries to add cid tests to 'results' so that no deoptimization is
+// necessary.
+// TODO(srdjan): Do also for other than 'int' type.
+static bool TryExpandTestCidsResult(ZoneGrowableArray<intptr_t>* results,
+                                    const AbstractType& type) {
+  ASSERT(results->length() >= 2);  // At least on eentry.
+  const ClassTable& class_table = *Isolate::Current()->class_table();
+  if ((*results)[0] != kSmiCid) {
+    const Class& cls = Class::Handle(class_table.At(kSmiCid));
+    const Class& type_class = Class::Handle(type.type_class());
+    const bool smi_is_subtype = cls.IsSubtypeOf(TypeArguments::Handle(),
+                                                type_class,
+                                                TypeArguments::Handle(),
+                                                NULL,
+                                                NULL,
+                                                Heap::kOld);
+    results->Add((*results)[results->length() - 2]);
+    results->Add((*results)[results->length() - 2]);
+    for (intptr_t i = results->length() - 3; i > 1; --i) {
+      (*results)[i] = (*results)[i - 2];
+    }
+    (*results)[0] = kSmiCid;
+    (*results)[1] = smi_is_subtype;
+  }
+
+  ASSERT(type.IsInstantiated() && !type.IsMalformedOrMalbounded());
+  ASSERT(results->length() >= 2);
+  if (type.IsIntType()) {
+    ASSERT((*results)[0] == kSmiCid);
+    TryAddTest(results, kMintCid, true);
+    TryAddTest(results, kBigintCid, true);
+    // Cannot deoptimize since all tests returning true have been added.
+    return false;
+  }
+
+  return true;  // May deoptimize since we have not identified all 'true' tests.
+}
+
+
+// TODO(srdjan): Use ICData to check if always true or false.
+void AotOptimizer::ReplaceWithInstanceOf(InstanceCallInstr* call) {
+  ASSERT(Token::IsTypeTestOperator(call->token_kind()));
+  Definition* left = call->ArgumentAt(0);
+  Definition* type_args = NULL;
+  AbstractType& type = AbstractType::ZoneHandle(Z);
+  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();
+    } else {
+      UNIMPLEMENTED();
+    }
+    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();
+    negate = Bool::Cast(call->ArgumentAt(3)->OriginalDefinition()
+        ->AsConstant()->value()).value();
+  }
+  const ICData& unary_checks =
+      ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks());
+  if ((unary_checks.NumberOfChecks() > 0) &&
+      (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) {
+    ZoneGrowableArray<intptr_t>* results =
+        new(Z) ZoneGrowableArray<intptr_t>(unary_checks.NumberOfChecks() * 2);
+    Bool& as_bool =
+        Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results));
+    if (as_bool.IsNull()) {
+      if (results->length() == unary_checks.NumberOfChecks() * 2) {
+        const bool can_deopt = TryExpandTestCidsResult(results, type);
+        TestCidsInstr* test_cids = new(Z) TestCidsInstr(
+            call->token_pos(),
+            negate ? Token::kISNOT : Token::kIS,
+            new(Z) Value(left),
+            *results,
+            can_deopt ? call->deopt_id() : Thread::kNoDeoptId);
+        // Remove type.
+        ReplaceCall(call, test_cids);
+        return;
+      }
+    } else {
+      // TODO(srdjan): Use TestCidsInstr also for this case.
+      // One result only.
+      AddReceiverCheck(call);
+      if (negate) {
+        as_bool = Bool::Get(!as_bool.value()).raw();
+      }
+      ConstantInstr* bool_const = flow_graph()->GetConstant(as_bool);
+      for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+        PushArgumentInstr* push = call->PushArgumentAt(i);
+        push->ReplaceUsesWith(push->value()->definition());
+        push->RemoveFromGraph();
+      }
+      call->ReplaceUsesWith(bool_const);
+      ASSERT(current_iterator()->Current() == call);
+      current_iterator()->RemoveCurrentFromGraph();
+      return;
+    }
+  }
+
+  if (TypeCheckAsClassEquality(type)) {
+    LoadClassIdInstr* left_cid = new(Z) LoadClassIdInstr(new(Z) Value(left));
+    InsertBefore(call,
+                 left_cid,
+                 NULL,
+                 FlowGraph::kValue);
+    const intptr_t type_cid = Class::Handle(Z, type.type_class()).id();
+    ConstantInstr* cid =
+        flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(type_cid)));
+
+    StrictCompareInstr* check_cid =
+        new(Z) StrictCompareInstr(
+            call->token_pos(),
+            negate ? Token::kNE_STRICT : Token::kEQ_STRICT,
+            new(Z) Value(left_cid),
+            new(Z) Value(cid),
+            false);  // No number check.
+    ReplaceCall(call, check_cid);
+    return;
+  }
+
+  InstanceOfInstr* instance_of =
+      new(Z) InstanceOfInstr(call->token_pos(),
+                             new(Z) Value(left),
+                             new(Z) Value(type_args),
+                             type,
+                             negate,
+                             call->deopt_id());
+  ReplaceCall(call, instance_of);
+}
+
+
+// TODO(srdjan): Apply optimizations as in ReplaceWithInstanceOf (TestCids).
+void AotOptimizer::ReplaceWithTypeCast(InstanceCallInstr* call) {
+  ASSERT(Token::IsTypeCastOperator(call->token_kind()));
+  Definition* left = call->ArgumentAt(0);
+  Definition* type_args = call->ArgumentAt(1);
+  const AbstractType& type =
+      AbstractType::Cast(call->ArgumentAt(2)->AsConstant()->value());
+  ASSERT(!type.IsMalformedOrMalbounded());
+  const ICData& unary_checks =
+      ICData::ZoneHandle(Z, call->ic_data()->AsUnaryClassChecks());
+  if ((unary_checks.NumberOfChecks() > 0) &&
+      (unary_checks.NumberOfChecks() <= FLAG_max_polymorphic_checks)) {
+    ZoneGrowableArray<intptr_t>* results =
+        new(Z) ZoneGrowableArray<intptr_t>(unary_checks.NumberOfChecks() * 2);
+    const Bool& as_bool = Bool::ZoneHandle(Z,
+        InstanceOfAsBool(unary_checks, type, results));
+    if (as_bool.raw() == Bool::True().raw()) {
+      AddReceiverCheck(call);
+      // Remove the original push arguments.
+      for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+        PushArgumentInstr* push = call->PushArgumentAt(i);
+        push->ReplaceUsesWith(push->value()->definition());
+        push->RemoveFromGraph();
+      }
+      // Remove call, replace it with 'left'.
+      call->ReplaceUsesWith(left);
+      ASSERT(current_iterator()->Current() == call);
+      current_iterator()->RemoveCurrentFromGraph();
+      return;
+    }
+  }
+  const String& dst_name = String::ZoneHandle(Z,
+      Symbols::New(Exceptions::kCastErrorDstName));
+  AssertAssignableInstr* assert_as =
+      new(Z) AssertAssignableInstr(call->token_pos(),
+                                   new(Z) Value(left),
+                                   new(Z) Value(type_args),
+                                   type,
+                                   dst_name,
+                                   call->deopt_id());
+  ReplaceCall(call, assert_as);
+}
+
+
+bool AotOptimizer::IsBlackListedForInlining(intptr_t call_deopt_id) {
+  for (intptr_t i = 0; i < inlining_black_list_->length(); ++i) {
+    if ((*inlining_black_list_)[i] == call_deopt_id) return true;
+  }
+  return false;
+}
+
+// Special optimizations when running in --noopt mode.
+void AotOptimizer::InstanceCallNoopt(InstanceCallInstr* instr) {
+  // TODO(srdjan): Investigate other attempts, as they are not allowed to
+  // deoptimize.
+
+  // Type test is special as it always gets converted into inlined code.
+  const Token::Kind op_kind = instr->token_kind();
+  if (Token::IsTypeTestOperator(op_kind)) {
+    ReplaceWithInstanceOf(instr);
+    return;
+  }
+  if (Token::IsTypeCastOperator(op_kind)) {
+    ReplaceWithTypeCast(instr);
+    return;
+  }
+
+  if ((op_kind == Token::kGET) &&
+      TryInlineInstanceGetter(instr, false /* no checks allowed */)) {
+    return;
+  }
+  const ICData& unary_checks =
+      ICData::ZoneHandle(Z, instr->ic_data()->AsUnaryClassChecks());
+  if ((unary_checks.NumberOfChecks() > 0) &&
+      (op_kind == Token::kSET) &&
+      TryInlineInstanceSetter(instr, unary_checks, false /* no checks */)) {
+    return;
+  }
+
+  if (use_speculative_inlining_ &&
+      !IsBlackListedForInlining(instr->deopt_id()) &&
+      (unary_checks.NumberOfChecks() > 0)) {
+    if ((op_kind == Token::kINDEX) && TryReplaceWithIndexedOp(instr)) {
+      return;
+    }
+    if ((op_kind == Token::kASSIGN_INDEX) && TryReplaceWithIndexedOp(instr)) {
+      return;
+    }
+    if ((op_kind == Token::kEQ) && TryReplaceWithEqualityOp(instr, op_kind)) {
+      return;
+    }
+
+    if (Token::IsRelationalOperator(op_kind) &&
+        TryReplaceWithRelationalOp(instr, op_kind)) {
+      return;
+    }
+
+    if (Token::IsBinaryOperator(op_kind) &&
+        TryReplaceWithBinaryOp(instr, op_kind)) {
+      return;
+    }
+    if (Token::IsUnaryOperator(op_kind) &&
+        TryReplaceWithUnaryOp(instr, op_kind)) {
+      return;
+    }
+  }
+
+  bool has_one_target =
+      (unary_checks.NumberOfChecks() > 0) && unary_checks.HasOneTarget();
+  if (has_one_target) {
+    // Check if the single target is a polymorphic target, if it is,
+    // we don't have one target.
+    const Function& target =
+        Function::Handle(Z, unary_checks.GetTargetAt(0));
+    const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target);
+    has_one_target = !polymorphic_target;
+  }
+
+  if (has_one_target) {
+    RawFunction::Kind function_kind =
+        Function::Handle(Z, unary_checks.GetTargetAt(0)).kind();
+    if (!InstanceCallNeedsClassCheck(instr, function_kind)) {
+      PolymorphicInstanceCallInstr* call =
+          new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
+                                              /* with_checks = */ false);
+      instr->ReplaceWith(call, current_iterator());
+      return;
+    }
+  }
+
+  // More than one targets. Generate generic polymorphic call without
+  // deoptimization.
+  if (instr->ic_data()->NumberOfUsedChecks() > 0) {
+    ASSERT(!FLAG_polymorphic_with_deopt);
+    // OK to use checks with PolymorphicInstanceCallInstr since no
+    // deoptimization is allowed.
+    PolymorphicInstanceCallInstr* call =
+        new(Z) PolymorphicInstanceCallInstr(instr, unary_checks,
+                                            /* with_checks = */ true);
+    instr->ReplaceWith(call, current_iterator());
+    return;
+  }
+
+  // No IC data checks. Try resolve target using the propagated type.
+  // If the propagated type has a method with the target name and there are
+  // no overrides with that name according to CHA, call the method directly.
+  const intptr_t receiver_cid =
+      instr->PushArgumentAt(0)->value()->Type()->ToCid();
+  if (receiver_cid == kDynamicCid) return;
+  const Class& receiver_class = Class::Handle(Z,
+      isolate()->class_table()->At(receiver_cid));
+
+  const Array& args_desc_array = Array::Handle(Z,
+      ArgumentsDescriptor::New(instr->ArgumentCount(),
+                               instr->argument_names()));
+  ArgumentsDescriptor args_desc(args_desc_array);
+  const Function& function = Function::Handle(Z,
+      Resolver::ResolveDynamicForReceiverClass(
+          receiver_class,
+          instr->function_name(),
+          args_desc));
+  if (function.IsNull()) {
+    return;
+  }
+  if (!thread()->cha()->HasOverride(receiver_class, instr->function_name())) {
+    if (FLAG_trace_cha) {
+      THR_Print("  **(CHA) Instance call needs no check, "
+          "no overrides of '%s' '%s'\n",
+          instr->function_name().ToCString(), receiver_class.ToCString());
+    }
+    thread()->cha()->AddToLeafClasses(receiver_class);
+
+    // Create fake IC data with the resolved target.
+    const ICData& ic_data = ICData::Handle(
+        ICData::New(flow_graph_->function(),
+                    instr->function_name(),
+                    args_desc_array,
+                    Thread::kNoDeoptId,
+                    /* args_tested = */ 1));
+    ic_data.AddReceiverCheck(receiver_class.id(), function);
+    PolymorphicInstanceCallInstr* call =
+        new(Z) PolymorphicInstanceCallInstr(instr, ic_data,
+                                            /* with_checks = */ false);
+    instr->ReplaceWith(call, current_iterator());
+    return;
+  }
+}
+
+
+// Tries to optimize instance call by replacing it with a faster instruction
+// (e.g, binary op, field load, ..).
+void AotOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
+  ASSERT(FLAG_precompilation);
+  InstanceCallNoopt(instr);
+}
+
+
+void AotOptimizer::VisitStaticCall(StaticCallInstr* call) {
+  if (!CanUnboxDouble()) {
+    return;
+  }
+  MethodRecognizer::Kind recognized_kind =
+      MethodRecognizer::RecognizeKind(call->function());
+  MathUnaryInstr::MathUnaryKind unary_kind;
+  switch (recognized_kind) {
+    case MethodRecognizer::kMathSqrt:
+      unary_kind = MathUnaryInstr::kSqrt;
+      break;
+    case MethodRecognizer::kMathSin:
+      unary_kind = MathUnaryInstr::kSin;
+      break;
+    case MethodRecognizer::kMathCos:
+      unary_kind = MathUnaryInstr::kCos;
+      break;
+    default:
+      unary_kind = MathUnaryInstr::kIllegal;
+      break;
+  }
+  if (unary_kind != MathUnaryInstr::kIllegal) {
+    ASSERT(FLAG_precompilation);
+    // TODO(srdjan): Adapt MathUnaryInstr to allow tagged inputs as well.
+    return;
+  }
+
+  switch (recognized_kind) {
+    case MethodRecognizer::kFloat32x4Zero:
+    case MethodRecognizer::kFloat32x4Splat:
+    case MethodRecognizer::kFloat32x4Constructor:
+    case MethodRecognizer::kFloat32x4FromFloat64x2:
+      TryInlineFloat32x4Constructor(call, recognized_kind);
+      break;
+    case MethodRecognizer::kFloat64x2Constructor:
+    case MethodRecognizer::kFloat64x2Zero:
+    case MethodRecognizer::kFloat64x2Splat:
+    case MethodRecognizer::kFloat64x2FromFloat32x4:
+      TryInlineFloat64x2Constructor(call, recognized_kind);
+      break;
+    case MethodRecognizer::kInt32x4BoolConstructor:
+    case MethodRecognizer::kInt32x4Constructor:
+      TryInlineInt32x4Constructor(call, recognized_kind);
+      break;
+    case MethodRecognizer::kObjectConstructor: {
+      // Remove the original push arguments.
+      for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
+        PushArgumentInstr* push = call->PushArgumentAt(i);
+        push->ReplaceUsesWith(push->value()->definition());
+        push->RemoveFromGraph();
+      }
+      // Manually replace call with global null constant. ReplaceCall can't
+      // be used for definitions that are already in the graph.
+      call->ReplaceUsesWith(flow_graph_->constant_null());
+      ASSERT(current_iterator()->Current() == call);
+      current_iterator()->RemoveCurrentFromGraph();
+      break;
+    }
+    case MethodRecognizer::kMathMin:
+    case MethodRecognizer::kMathMax: {
+      // We can handle only monomorphic min/max call sites with both arguments
+      // being either doubles or smis.
+      if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) {
+        const ICData& ic_data = *call->ic_data();
+        intptr_t result_cid = kIllegalCid;
+        if (ICDataHasReceiverArgumentClassIds(ic_data,
+                                              kDoubleCid, kDoubleCid)) {
+          result_cid = kDoubleCid;
+        } else if (ICDataHasReceiverArgumentClassIds(ic_data,
+                                                     kSmiCid, kSmiCid)) {
+          result_cid = kSmiCid;
+        }
+        if (result_cid != kIllegalCid) {
+          MathMinMaxInstr* min_max = new(Z) MathMinMaxInstr(
+              recognized_kind,
+              new(Z) Value(call->ArgumentAt(0)),
+              new(Z) Value(call->ArgumentAt(1)),
+              call->deopt_id(),
+              result_cid);
+          const ICData& unary_checks =
+              ICData::ZoneHandle(Z, ic_data.AsUnaryClassChecks());
+          AddCheckClass(min_max->left()->definition(),
+                        unary_checks,
+                        call->deopt_id(),
+                        call->env(),
+                        call);
+          AddCheckClass(min_max->right()->definition(),
+                        unary_checks,
+                        call->deopt_id(),
+                        call->env(),
+                        call);
+          ReplaceCall(call, min_max);
+        }
+      }
+      break;
+    }
+    case MethodRecognizer::kMathDoublePow:
+    case MethodRecognizer::kMathTan:
+    case MethodRecognizer::kMathAsin:
+    case MethodRecognizer::kMathAcos:
+    case MethodRecognizer::kMathAtan:
+    case MethodRecognizer::kMathAtan2: {
+      ASSERT(FLAG_precompilation);
+      // No UnboxDouble instructions allowed.
+      return;
+    }
+    case MethodRecognizer::kDoubleFromInteger: {
+      if (call->HasICData() && (call->ic_data()->NumberOfChecks() == 1)) {
+        const ICData& ic_data = *call->ic_data();
+        if (CanUnboxDouble()) {
+          if (ArgIsAlways(kSmiCid, ic_data, 1)) {
+            Definition* arg = call->ArgumentAt(1);
+            AddCheckSmi(arg, call->deopt_id(), call->env(), call);
+            ReplaceCall(call,
+                        new(Z) SmiToDoubleInstr(new(Z) Value(arg),
+                                                call->token_pos()));
+          } else if (ArgIsAlways(kMintCid, ic_data, 1) &&
+                     CanConvertUnboxedMintToDouble()) {
+            Definition* arg = call->ArgumentAt(1);
+            ReplaceCall(call,
+                        new(Z) MintToDoubleInstr(new(Z) Value(arg),
+                                                 call->deopt_id()));
+          }
+        }
+      }
+      break;
+    }
+    default: {
+      if (call->function().IsFactory()) {
+        const Class& function_class =
+            Class::Handle(Z, call->function().Owner());
+        if ((function_class.library() == Library::CoreLibrary()) ||
+            (function_class.library() == Library::TypedDataLibrary())) {
+          intptr_t cid = FactoryRecognizer::ResultCid(call->function());
+          switch (cid) {
+            case kArrayCid: {
+              Value* type = new(Z) Value(call->ArgumentAt(0));
+              Value* num_elements = new(Z) Value(call->ArgumentAt(1));
+              if (num_elements->BindsToConstant() &&
+                  num_elements->BoundConstant().IsSmi()) {
+                intptr_t length =
+                    Smi::Cast(num_elements->BoundConstant()).Value();
+                if (length >= 0 && length <= Array::kMaxElements) {
+                  CreateArrayInstr* create_array =
+                      new(Z) CreateArrayInstr(
+                          call->token_pos(), type, num_elements);
+                  ReplaceCall(call, create_array);
+                }
+              }
+            }
+            default:
+              break;
+          }
+        }
+      }
+    }
+  }
+}
+
+
+void AotOptimizer::VisitAllocateContext(AllocateContextInstr* instr) {
+  // Replace generic allocation with a sequence of inlined allocation and
+  // explicit initalizing stores.
+  AllocateUninitializedContextInstr* replacement =
+      new AllocateUninitializedContextInstr(instr->token_pos(),
+                                            instr->num_context_variables());
+  instr->ReplaceWith(replacement, current_iterator());
+
+  StoreInstanceFieldInstr* store =
+      new(Z) StoreInstanceFieldInstr(Context::parent_offset(),
+                                     new Value(replacement),
+                                     new Value(flow_graph_->constant_null()),
+                                     kNoStoreBarrier,
+                                     instr->token_pos());
+  // Storing into uninitialized memory; remember to prevent dead store
+  // elimination and ensure proper GC barrier.
+  store->set_is_object_reference_initialization(true);
+  flow_graph_->InsertAfter(replacement, store, NULL, FlowGraph::kEffect);
+  Definition* cursor = store;
+  for (intptr_t i = 0; i < instr->num_context_variables(); ++i) {
+    store =
+        new(Z) StoreInstanceFieldInstr(Context::variable_offset(i),
+                                       new Value(replacement),
+                                       new Value(flow_graph_->constant_null()),
+                                       kNoStoreBarrier,
+                                       instr->token_pos());
+    // Storing into uninitialized memory; remember to prevent dead store
+    // elimination and ensure proper GC barrier.
+    store->set_is_object_reference_initialization(true);
+    flow_graph_->InsertAfter(cursor, store, NULL, FlowGraph::kEffect);
+    cursor = store;
+  }
+}
+
+
+void AotOptimizer::VisitLoadCodeUnits(LoadCodeUnitsInstr* instr) {
+  // TODO(zerny): Use kUnboxedUint32 once it is fully supported/optimized.
+#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_ARM)
+  if (!instr->can_pack_into_smi())
+    instr->set_representation(kUnboxedMint);
+#endif
+}
+
+
+bool AotOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
+                                                 const ICData& unary_ic_data,
+                                                 bool allow_checks) {
+  ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
+      (unary_ic_data.NumArgsTested() == 1));
+  if (I->flags().type_checks()) {
+    // Checked mode setters are inlined like normal methods by conventional
+    // inlining.
+    return false;
+  }
+
+  ASSERT(instr->HasICData());
+  if (unary_ic_data.NumberOfChecks() == 0) {
+    // No type feedback collected.
+    return false;
+  }
+  if (!unary_ic_data.HasOneTarget()) {
+    // Polymorphic sites are inlined like normal method calls by conventional
+    // inlining.
+    return false;
+  }
+  Function& target = Function::Handle(Z);
+  intptr_t class_id;
+  unary_ic_data.GetOneClassCheckAt(0, &class_id, &target);
+  if (target.kind() != RawFunction::kImplicitSetter) {
+    // Non-implicit setter are inlined like normal method calls.
+    return false;
+  }
+  // Inline implicit instance setter.
+  const String& field_name =
+      String::Handle(Z, Field::NameFromSetter(instr->function_name()));
+  const Field& field =
+      Field::ZoneHandle(Z, GetField(class_id, field_name));
+  ASSERT(!field.IsNull());
+
+  if (InstanceCallNeedsClassCheck(instr, RawFunction::kImplicitSetter)) {
+    if (!allow_checks) {
+      return false;
+    }
+    AddReceiverCheck(instr);
+  }
+  if (field.guarded_cid() != kDynamicCid) {
+    if (!allow_checks) {
+      return false;
+    }
+    InsertBefore(instr,
+                 new(Z) GuardFieldClassInstr(
+                     new(Z) Value(instr->ArgumentAt(1)),
+                      field,
+                      instr->deopt_id()),
+                 instr->env(),
+                 FlowGraph::kEffect);
+  }
+
+  if (field.needs_length_check()) {
+    if (!allow_checks) {
+      return false;
+    }
+    InsertBefore(instr,
+                 new(Z) GuardFieldLengthInstr(
+                     new(Z) Value(instr->ArgumentAt(1)),
+                      field,
+                      instr->deopt_id()),
+                 instr->env(),
+                 FlowGraph::kEffect);
+  }
+
+  // Field guard was detached.
+  StoreInstanceFieldInstr* store = new(Z) StoreInstanceFieldInstr(
+      field,
+      new(Z) Value(instr->ArgumentAt(0)),
+      new(Z) Value(instr->ArgumentAt(1)),
+      kEmitStoreBarrier,
+      instr->token_pos());
+
+  // No unboxed stores in precompiled code.
+  ASSERT(!store->IsUnboxedStore());
+
+  // Discard the environment from the original instruction because the store
+  // can't deoptimize.
+  instr->RemoveEnvironment();
+  ReplaceCall(instr, store);
+  return true;
+}
+
+
+}  // namespace dart
diff --git a/runtime/vm/aot_optimizer.h b/runtime/vm/aot_optimizer.h
new file mode 100644
index 0000000..e770ffe
--- /dev/null
+++ b/runtime/vm/aot_optimizer.h
@@ -0,0 +1,188 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef VM_AOT_OPTIMIZER_H_
+#define VM_AOT_OPTIMIZER_H_
+
+#include "vm/intermediate_language.h"
+#include "vm/flow_graph.h"
+
+namespace dart {
+
+class CSEInstructionMap;
+template <typename T> class GrowableArray;
+class ParsedFunction;
+class RawBool;
+
+class AotOptimizer : public FlowGraphVisitor {
+ public:
+  AotOptimizer(
+      FlowGraph* flow_graph,
+      bool use_speculative_inlining,
+      GrowableArray<intptr_t>* inlining_black_list)
+      : FlowGraphVisitor(flow_graph->reverse_postorder()),
+        flow_graph_(flow_graph),
+        use_speculative_inlining_(use_speculative_inlining),
+        inlining_black_list_(inlining_black_list) {
+    ASSERT(!use_speculative_inlining || (inlining_black_list != NULL));
+  }
+  virtual ~AotOptimizer() {}
+
+  FlowGraph* flow_graph() const { return flow_graph_; }
+
+  // Add ICData to InstanceCalls, so that optimizations can be run on them.
+  // TODO(srdjan): StaticCals as well?
+  void PopulateWithICData();
+
+  // Use ICData to optimize, replace or eliminate instructions.
+  void ApplyICData();
+
+  // Use propagated class ids to optimize, replace or eliminate instructions.
+  void ApplyClassIds();
+
+  // Optimize (a << b) & c pattern: if c is a positive Smi or zero, then the
+  // shift can be a truncating Smi shift-left and result is always Smi.
+  // Merge instructions (only per basic-block).
+  void TryOptimizePatterns();
+
+  virtual void VisitStaticCall(StaticCallInstr* instr);
+  virtual void VisitInstanceCall(InstanceCallInstr* instr);
+  virtual void VisitAllocateContext(AllocateContextInstr* instr);
+  virtual void VisitLoadCodeUnits(LoadCodeUnitsInstr* instr);
+
+  void InsertBefore(Instruction* next,
+                    Instruction* instr,
+                    Environment* env,
+                    FlowGraph::UseKind use_kind) {
+    flow_graph_->InsertBefore(next, instr, env, use_kind);
+  }
+
+ private:
+  // Attempt to build ICData for call using propagated class-ids.
+  bool TryCreateICData(InstanceCallInstr* call);
+  const ICData& TrySpecializeICData(const ICData& ic_data, intptr_t cid);
+
+  void SpecializePolymorphicInstanceCall(PolymorphicInstanceCallInstr* call);
+
+  bool TryReplaceWithIndexedOp(InstanceCallInstr* call);
+
+
+  bool TryReplaceWithBinaryOp(InstanceCallInstr* call, Token::Kind op_kind);
+  bool TryReplaceWithUnaryOp(InstanceCallInstr* call, Token::Kind op_kind);
+
+  bool TryReplaceWithEqualityOp(InstanceCallInstr* call, Token::Kind op_kind);
+  bool TryReplaceWithRelationalOp(InstanceCallInstr* call, Token::Kind op_kind);
+
+  bool TryInlineInstanceGetter(InstanceCallInstr* call,
+                               bool allow_check = true);
+  bool TryInlineInstanceSetter(InstanceCallInstr* call,
+                               const ICData& unary_ic_data,
+                               bool allow_check = true);
+
+  bool TryInlineInstanceMethod(InstanceCallInstr* call);
+  bool TryInlineFloat32x4Constructor(StaticCallInstr* call,
+                                     MethodRecognizer::Kind recognized_kind);
+  bool TryInlineFloat64x2Constructor(StaticCallInstr* call,
+                                     MethodRecognizer::Kind recognized_kind);
+  bool TryInlineInt32x4Constructor(StaticCallInstr* call,
+                                    MethodRecognizer::Kind recognized_kind);
+  bool TryInlineFloat32x4Method(InstanceCallInstr* call,
+                                MethodRecognizer::Kind recognized_kind);
+  bool TryInlineFloat64x2Method(InstanceCallInstr* call,
+                                MethodRecognizer::Kind recognized_kind);
+  bool TryInlineInt32x4Method(InstanceCallInstr* call,
+                               MethodRecognizer::Kind recognized_kind);
+  void ReplaceWithInstanceOf(InstanceCallInstr* instr);
+  bool TypeCheckAsClassEquality(const AbstractType& type);
+  void ReplaceWithTypeCast(InstanceCallInstr* instr);
+
+  bool TryReplaceInstanceCallWithInline(InstanceCallInstr* call);
+
+  // Insert a check of 'to_check' determined by 'unary_checks'.  If the
+  // check fails it will deoptimize to 'deopt_id' using the deoptimization
+  // environment 'deopt_environment'.  The check is inserted immediately
+  // before 'insert_before'.
+  void AddCheckClass(Definition* to_check,
+                     const ICData& unary_checks,
+                     intptr_t deopt_id,
+                     Environment* deopt_environment,
+                     Instruction* insert_before);
+  Instruction* GetCheckClass(Definition* to_check,
+                             const ICData& unary_checks,
+                             intptr_t deopt_id,
+                             TokenPosition token_pos);
+
+  // Insert a Smi check if needed.
+  void AddCheckSmi(Definition* to_check,
+                   intptr_t deopt_id,
+                   Environment* deopt_environment,
+                   Instruction* insert_before);
+
+  // Add a class check for a call's first argument immediately before the
+  // call, using the call's IC data to determine the check, and the call's
+  // deopt ID and deoptimization environment if the check fails.
+  void AddReceiverCheck(InstanceCallInstr* call);
+
+  void ReplaceCall(Definition* call, Definition* replacement);
+
+
+  bool InstanceCallNeedsClassCheck(InstanceCallInstr* call,
+                                   RawFunction::Kind kind) const;
+
+  bool InlineFloat32x4Getter(InstanceCallInstr* call,
+                             MethodRecognizer::Kind getter);
+  bool InlineFloat64x2Getter(InstanceCallInstr* call,
+                             MethodRecognizer::Kind getter);
+  bool InlineInt32x4Getter(InstanceCallInstr* call,
+                            MethodRecognizer::Kind getter);
+  bool InlineFloat32x4BinaryOp(InstanceCallInstr* call,
+                               Token::Kind op_kind);
+  bool InlineInt32x4BinaryOp(InstanceCallInstr* call,
+                              Token::Kind op_kind);
+  bool InlineFloat64x2BinaryOp(InstanceCallInstr* call,
+                               Token::Kind op_kind);
+  bool InlineImplicitInstanceGetter(InstanceCallInstr* call, bool allow_check);
+
+  RawBool* InstanceOfAsBool(const ICData& ic_data,
+                            const AbstractType& type,
+                            ZoneGrowableArray<intptr_t>* results) const;
+
+  void ReplaceWithMathCFunction(InstanceCallInstr* call,
+                                MethodRecognizer::Kind recognized_kind);
+
+  void OptimizeLeftShiftBitAndSmiOp(Definition* bit_and_instr,
+                                    Definition* left_instr,
+                                    Definition* right_instr);
+  void TryMergeTruncDivMod(GrowableArray<BinarySmiOpInstr*>* merge_candidates);
+  void TryMergeMathUnary(GrowableArray<MathUnaryInstr*>* merge_candidates);
+
+  void AppendExtractNthOutputForMerged(Definition* instr, intptr_t ix,
+                                       Representation rep, intptr_t cid);
+  bool TryStringLengthOneEquality(InstanceCallInstr* call, Token::Kind op_kind);
+
+  void InstanceCallNoopt(InstanceCallInstr* instr);
+
+  RawField* GetField(intptr_t class_id, const String& field_name);
+
+  Thread* thread() const { return flow_graph_->thread(); }
+  Isolate* isolate() const { return flow_graph_->isolate(); }
+  Zone* zone() const { return flow_graph_->zone(); }
+
+  const Function& function() const { return flow_graph_->function(); }
+
+  bool IsBlackListedForInlining(intptr_t deopt_id);
+
+  FlowGraph* flow_graph_;
+
+  const bool use_speculative_inlining_;
+
+  GrowableArray<intptr_t>* inlining_black_list_;
+
+  DISALLOW_COPY_AND_ASSIGN(AotOptimizer);
+};
+
+
+}  // namespace dart
+
+#endif  // VM_AOT_OPTIMIZER_H_
diff --git a/runtime/vm/ast_printer.cc b/runtime/vm/ast_printer.cc
index bd45331..3732c3a 100644
--- a/runtime/vm/ast_printer.cc
+++ b/runtime/vm/ast_printer.cc
@@ -10,9 +10,9 @@
 #include "vm/os.h"
 #include "vm/parser.h"
 
-namespace dart {
+#if !defined(PRODUCT)
 
-#ifndef PRODUCT
+namespace dart {
 
 AstPrinter::AstPrinter() : indent_(0) { }
 
@@ -576,6 +576,6 @@
   THR_Print("}\n");
 }
 
-#endif  // !PRODUCT
-
 }  // namespace dart
+
+#endif  // !defined(PRODUCT)
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index e8a5074..488a2d9 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -26,6 +26,73 @@
 Benchmark* Benchmark::tail_ = NULL;
 const char* Benchmark::executable_ = NULL;
 
+
+//
+// Measure compile of all dart2js(compiler) functions.
+//
+static char* ComputeDart2JSPath(const char* arg) {
+  char buffer[2048];
+  char* dart2js_path = strdup(File::GetCanonicalPath(arg));
+  const char* compiler_path =
+      "%s%spkg%scompiler%slib%scompiler.dart";
+  const char* path_separator = File::PathSeparator();
+  ASSERT(path_separator != NULL && strlen(path_separator) == 1);
+  char* ptr = strrchr(dart2js_path, *path_separator);
+  while (ptr != NULL) {
+    *ptr = '\0';
+    OS::SNPrint(buffer, 2048, compiler_path,
+                dart2js_path,
+                path_separator,
+                path_separator,
+                path_separator,
+                path_separator,
+                path_separator);
+    if (File::Exists(buffer)) {
+      break;
+    }
+    ptr = strrchr(dart2js_path, *path_separator);
+  }
+  if (ptr == NULL) {
+    free(dart2js_path);
+    dart2js_path = NULL;
+  }
+  return dart2js_path;
+}
+
+
+static void func(Dart_NativeArguments args) {
+}
+
+
+static Dart_NativeFunction NativeResolver(Dart_Handle name,
+                                          int arg_count,
+                                          bool* auto_setup_scope) {
+  ASSERT(auto_setup_scope != NULL);
+  *auto_setup_scope = false;
+  return &func;
+}
+
+
+static void SetupDart2JSPackagePath() {
+  bool worked = bin::DartUtils::SetOriginalWorkingDirectory();
+  EXPECT(worked);
+
+  Dart_Handle result = bin::DartUtils::PrepareForScriptLoading(false, false);
+  DART_CHECK_VALID(result);
+
+  // Setup package root.
+  char buffer[2048];
+  char* executable_path =
+      strdup(File::GetCanonicalPath(Benchmark::Executable()));
+  const char* packages_path = "%s%s..%spackages";
+  const char* path_separator = File::PathSeparator();
+  OS::SNPrint(buffer, 2048, packages_path,
+              executable_path, path_separator, path_separator);
+  result = bin::DartUtils::SetupPackageRoot(buffer, NULL);
+  DART_CHECK_VALID(result);
+}
+
+
 void Benchmark::RunAll(const char* executable) {
   SetExecutable(executable);
   Benchmark* benchmark = first_;
@@ -66,6 +133,9 @@
 }
 
 
+#ifndef PRODUCT
+
+
 BENCHMARK(CorelibCompilerStats) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
@@ -86,6 +156,47 @@
 }
 
 
+BENCHMARK(Dart2JSCompilerStats) {
+  bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
+  bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+  SetupDart2JSPackagePath();
+  char* dart_root = ComputeDart2JSPath(Benchmark::Executable());
+  char* script = NULL;
+  if (dart_root != NULL) {
+    HANDLESCOPE(thread);
+    script = OS::SCreate(NULL,
+        "import '%s/pkg/compiler/lib/compiler.dart';", dart_root);
+    Dart_Handle lib = TestCase::LoadTestScript(
+        script,
+        reinterpret_cast<Dart_NativeEntryResolver>(NativeResolver));
+    EXPECT_VALID(lib);
+  } else {
+    Dart_Handle lib = TestCase::LoadTestScript(
+        "import 'pkg/compiler/lib/compiler.dart';",
+        reinterpret_cast<Dart_NativeEntryResolver>(NativeResolver));
+    EXPECT_VALID(lib);
+  }
+  CompilerStats* stats = thread->isolate()->compiler_stats();
+  ASSERT(stats != NULL);
+  stats->EnableBenchmark();
+  Timer timer(true, "Compile all of dart2js benchmark");
+  timer.Start();
+  const bool old_flag = FLAG_background_compilation;
+  FLAG_background_compilation = false;
+  Dart_Handle result = Dart_CompileAll();
+  FLAG_background_compilation = old_flag;
+  EXPECT_VALID(result);
+  timer.Stop();
+  int64_t elapsed_time = timer.TotalElapsedTime();
+  benchmark->set_score(elapsed_time);
+  free(dart_root);
+  free(script);
+}
+
+
+#endif  // !PRODUCT
+
+
 //
 // Measure creation of core isolate from a snapshot.
 //
@@ -254,70 +365,6 @@
 }
 
 
-//
-// Measure compile of all dart2js(compiler) functions.
-//
-static char* ComputeDart2JSPath(const char* arg) {
-  char buffer[2048];
-  char* dart2js_path = strdup(File::GetCanonicalPath(arg));
-  const char* compiler_path =
-      "%s%spkg%scompiler%slib%scompiler.dart";
-  const char* path_separator = File::PathSeparator();
-  ASSERT(path_separator != NULL && strlen(path_separator) == 1);
-  char* ptr = strrchr(dart2js_path, *path_separator);
-  while (ptr != NULL) {
-    *ptr = '\0';
-    OS::SNPrint(buffer, 2048, compiler_path,
-                dart2js_path,
-                path_separator,
-                path_separator,
-                path_separator,
-                path_separator,
-                path_separator);
-    if (File::Exists(buffer)) {
-      break;
-    }
-    ptr = strrchr(dart2js_path, *path_separator);
-  }
-  if (ptr == NULL) {
-    free(dart2js_path);
-    dart2js_path = NULL;
-  }
-  return dart2js_path;
-}
-
-
-static void func(Dart_NativeArguments args) {
-}
-
-
-static Dart_NativeFunction NativeResolver(Dart_Handle name,
-                                          int arg_count,
-                                          bool* auto_setup_scope) {
-  ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
-  return &func;
-}
-
-static void SetupDart2JSPackagePath() {
-  bool worked = bin::DartUtils::SetOriginalWorkingDirectory();
-  EXPECT(worked);
-
-  Dart_Handle result = bin::DartUtils::PrepareForScriptLoading(false, false);
-  DART_CHECK_VALID(result);
-
-  // Setup package root.
-  char buffer[2048];
-  char* executable_path =
-      strdup(File::GetCanonicalPath(Benchmark::Executable()));
-  const char* packages_path = "%s%s..%spackages";
-  const char* path_separator = File::PathSeparator();
-  OS::SNPrint(buffer, 2048, packages_path,
-              executable_path, path_separator, path_separator);
-  result = bin::DartUtils::SetupPackageRoot(buffer, NULL);
-  DART_CHECK_VALID(result);
-}
-
 BENCHMARK(Dart2JSCompileAll) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
@@ -353,44 +400,6 @@
 }
 
 
-BENCHMARK(Dart2JSCompilerStats) {
-  bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
-  bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
-  SetupDart2JSPackagePath();
-  char* dart_root = ComputeDart2JSPath(Benchmark::Executable());
-  char* script = NULL;
-  if (dart_root != NULL) {
-    HANDLESCOPE(thread);
-    script = OS::SCreate(NULL,
-        "import '%s/pkg/compiler/lib/compiler.dart';", dart_root);
-    Dart_Handle lib = TestCase::LoadTestScript(
-        script,
-        reinterpret_cast<Dart_NativeEntryResolver>(NativeResolver));
-    EXPECT_VALID(lib);
-  } else {
-    Dart_Handle lib = TestCase::LoadTestScript(
-        "import 'pkg/compiler/lib/compiler.dart';",
-        reinterpret_cast<Dart_NativeEntryResolver>(NativeResolver));
-    EXPECT_VALID(lib);
-  }
-  CompilerStats* stats = thread->isolate()->compiler_stats();
-  ASSERT(stats != NULL);
-  stats->EnableBenchmark();
-  Timer timer(true, "Compile all of dart2js benchmark");
-  timer.Start();
-  const bool old_flag = FLAG_background_compilation;
-  FLAG_background_compilation = false;
-  Dart_Handle result = Dart_CompileAll();
-  FLAG_background_compilation = old_flag;
-  EXPECT_VALID(result);
-  timer.Stop();
-  int64_t elapsed_time = timer.TotalElapsedTime();
-  benchmark->set_score(elapsed_time);
-  free(dart_root);
-  free(script);
-}
-
-
 //
 // Measure frame lookup during stack traversal.
 //
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 1868f07..8cb5d77 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -295,6 +295,11 @@
   for (intptr_t i = 0;
        bootstrap_libraries[i].index_ != ObjectStore::kNone;
        ++i) {
+#ifdef PRODUCT
+    if (bootstrap_libraries[i].index_ == ObjectStore::kMirrors) {
+      continue;
+    }
+#endif  // !PRODUCT
     uri = Symbols::New(bootstrap_libraries[i].uri_);
     lib = Library::LookupLibrary(uri);
     if (lib.IsNull()) {
@@ -310,6 +315,11 @@
   for (intptr_t i = 0;
        bootstrap_libraries[i].index_ != ObjectStore::kNone;
        ++i) {
+#ifdef PRODUCT
+    if (bootstrap_libraries[i].index_ == ObjectStore::kMirrors) {
+      continue;
+    }
+#endif  // PRODUCT
     uri = Symbols::New(bootstrap_libraries[i].uri_);
     lib = Library::LookupLibrary(uri);
     ASSERT(!lib.IsNull());
diff --git a/runtime/vm/bootstrap_natives.cc b/runtime/vm/bootstrap_natives.cc
index d0bef86..7e1ea34 100644
--- a/runtime/vm/bootstrap_natives.cc
+++ b/runtime/vm/bootstrap_natives.cc
@@ -28,6 +28,9 @@
   int argument_count_;
 } BootStrapEntries[] = {
   BOOTSTRAP_NATIVE_LIST(REGISTER_NATIVE_ENTRY)
+#ifndef PRODUCT
+  MIRRORS_BOOTSTRAP_NATIVE_LIST(REGISTER_NATIVE_ENTRY)
+#endif  // !PRODUCT
 };
 
 
@@ -116,10 +119,11 @@
   library.set_native_entry_resolver(resolver);
   library.set_native_entry_symbol_resolver(symbol_resolver);
 
+NOT_IN_PRODUCT(
   library = Library::MirrorsLibrary();
   ASSERT(!library.IsNull());
   library.set_native_entry_resolver(resolver);
-  library.set_native_entry_symbol_resolver(symbol_resolver);
+  library.set_native_entry_symbol_resolver(symbol_resolver));
 
   library = Library::ProfilerLibrary();
   ASSERT(!library.IsNull());
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 00fa958..02b1e3c 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -316,6 +316,55 @@
   V(Isolate_getPortAndCapabilitiesOfCurrentIsolate, 0)                         \
   V(Isolate_getCurrentRootUriStr, 0)                                           \
   V(Isolate_sendOOB, 2)                                                        \
+  V(GrowableList_allocate, 2)                                                  \
+  V(GrowableList_getIndexed, 2)                                                \
+  V(GrowableList_setIndexed, 3)                                                \
+  V(GrowableList_getLength, 1)                                                 \
+  V(GrowableList_getCapacity, 1)                                               \
+  V(GrowableList_setLength, 2)                                                 \
+  V(GrowableList_setData, 2)                                                   \
+  V(Internal_makeListFixedLength, 1)                                           \
+  V(Internal_makeFixedListUnmodifiable, 1)                                     \
+  V(Internal_inquireIs64Bit, 0)                                                \
+  V(LinkedHashMap_allocate, 1)                                                 \
+  V(LinkedHashMap_getIndex, 1)                                                 \
+  V(LinkedHashMap_setIndex, 2)                                                 \
+  V(LinkedHashMap_getData, 1)                                                  \
+  V(LinkedHashMap_setData, 2)                                                  \
+  V(LinkedHashMap_getHashMask, 1)                                              \
+  V(LinkedHashMap_setHashMask, 2)                                              \
+  V(LinkedHashMap_getUsedData, 1)                                              \
+  V(LinkedHashMap_setUsedData, 2)                                              \
+  V(LinkedHashMap_getDeletedKeys, 1)                                           \
+  V(LinkedHashMap_setDeletedKeys, 2)                                           \
+  V(WeakProperty_new, 2)                                                       \
+  V(WeakProperty_getKey, 1)                                                    \
+  V(WeakProperty_getValue, 1)                                                  \
+  V(WeakProperty_setValue, 2)                                                  \
+  V(Uri_isWindowsPlatform, 0)                                                  \
+  V(LibraryPrefix_load, 1)                                                     \
+  V(LibraryPrefix_invalidateDependentCode, 1)                                  \
+  V(LibraryPrefix_loadError, 1)                                                \
+  V(LibraryPrefix_isLoaded, 1)                                                 \
+  V(UserTag_new, 2)                                                            \
+  V(UserTag_label, 1)                                                          \
+  V(UserTag_defaultTag, 0)                                                     \
+  V(UserTag_makeCurrent, 1)                                                    \
+  V(Profiler_getCurrentTag, 0)                                                 \
+  V(ClassID_getID, 1)                                                          \
+  V(Num_toString, 1)                                                           \
+  V(VMService_SendIsolateServiceMessage, 2)                                    \
+  V(VMService_SendRootServiceMessage, 1)                                       \
+  V(VMService_OnStart, 0)                                                      \
+  V(VMService_OnExit, 0)                                                       \
+  V(VMService_OnServerAddressChange, 1)                                        \
+  V(VMService_ListenStream, 1)                                                 \
+  V(VMService_CancelStream, 1)                                                 \
+  V(VMService_RequestAssets, 0)                                                \
+  V(VMService_DecodeAssets, 1)                                                 \
+
+// List of bootstrap native entry points used in the dart:mirror library.
+#define MIRRORS_BOOTSTRAP_NATIVE_LIST(V)                                       \
   V(Mirrors_evalInLibraryWithPrivateKey, 2)                                    \
   V(Mirrors_makeLocalClassMirror, 1)                                           \
   V(Mirrors_makeLocalTypeMirror, 1)                                            \
@@ -365,52 +414,6 @@
   V(TypedefMirror_referent, 1)                                                 \
   V(TypedefMirror_declaration, 1)                                              \
   V(VariableMirror_type, 2)                                                    \
-  V(GrowableList_allocate, 2)                                                  \
-  V(GrowableList_getIndexed, 2)                                                \
-  V(GrowableList_setIndexed, 3)                                                \
-  V(GrowableList_getLength, 1)                                                 \
-  V(GrowableList_getCapacity, 1)                                               \
-  V(GrowableList_setLength, 2)                                                 \
-  V(GrowableList_setData, 2)                                                   \
-  V(Internal_makeListFixedLength, 1)                                           \
-  V(Internal_makeFixedListUnmodifiable, 1)                                     \
-  V(Internal_inquireIs64Bit, 0)                                                \
-  V(LinkedHashMap_allocate, 1)                                                 \
-  V(LinkedHashMap_getIndex, 1)                                                 \
-  V(LinkedHashMap_setIndex, 2)                                                 \
-  V(LinkedHashMap_getData, 1)                                                  \
-  V(LinkedHashMap_setData, 2)                                                  \
-  V(LinkedHashMap_getHashMask, 1)                                              \
-  V(LinkedHashMap_setHashMask, 2)                                              \
-  V(LinkedHashMap_getUsedData, 1)                                              \
-  V(LinkedHashMap_setUsedData, 2)                                              \
-  V(LinkedHashMap_getDeletedKeys, 1)                                           \
-  V(LinkedHashMap_setDeletedKeys, 2)                                           \
-  V(WeakProperty_new, 2)                                                       \
-  V(WeakProperty_getKey, 1)                                                    \
-  V(WeakProperty_getValue, 1)                                                  \
-  V(WeakProperty_setValue, 2)                                                  \
-  V(Uri_isWindowsPlatform, 0)                                                  \
-  V(LibraryPrefix_load, 1)                                                     \
-  V(LibraryPrefix_invalidateDependentCode, 1)                                  \
-  V(LibraryPrefix_loadError, 1)                                                \
-  V(LibraryPrefix_isLoaded, 1)                                                 \
-  V(UserTag_new, 2)                                                            \
-  V(UserTag_label, 1)                                                          \
-  V(UserTag_defaultTag, 0)                                                     \
-  V(UserTag_makeCurrent, 1)                                                    \
-  V(Profiler_getCurrentTag, 0)                                                 \
-  V(ClassID_getID, 1)                                                          \
-  V(Num_toString, 1)                                                           \
-  V(VMService_SendIsolateServiceMessage, 2)                                    \
-  V(VMService_SendRootServiceMessage, 1)                                       \
-  V(VMService_OnStart, 0)                                                      \
-  V(VMService_OnExit, 0)                                                       \
-  V(VMService_OnServerAddressChange, 1)                                        \
-  V(VMService_ListenStream, 1)                                                 \
-  V(VMService_CancelStream, 1)                                                 \
-  V(VMService_RequestAssets, 0)                                                \
-  V(VMService_DecodeAssets, 1)                                                 \
 
 class BootstrapNatives : public AllStatic {
  public:
@@ -424,6 +427,9 @@
   static void DN_##name(Dart_NativeArguments args);
 
   BOOTSTRAP_NATIVE_LIST(DECLARE_BOOTSTRAP_NATIVE)
+#ifndef PRODUCT
+  MIRRORS_BOOTSTRAP_NATIVE_LIST(DECLARE_BOOTSTRAP_NATIVE)
+#endif
 
 #undef DECLARE_BOOTSTRAP_NATIVE
 };
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index f2c7b12..74304da 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -11,7 +11,6 @@
 #include "vm/longjump.h"
 #include "vm/log.h"
 #include "vm/object_store.h"
-#include "vm/report.h"
 #include "vm/symbols.h"
 
 namespace dart {
@@ -19,7 +18,6 @@
 DEFINE_FLAG(bool, print_classes, false, "Prints details about loaded classes.");
 DEFINE_FLAG(bool, trace_class_finalization, false, "Trace class finalization.");
 DEFINE_FLAG(bool, trace_type_finalization, false, "Trace type finalization.");
-DECLARE_FLAG(bool, use_cha_deopt);
 
 
 bool ClassFinalizer::AllClassesFinalized() {
@@ -2252,17 +2250,15 @@
   const intptr_t num_functions = functions.Length();
   for (intptr_t i = 0; i < num_functions; i++) {
     func ^= functions.At(i);
-    if (func.IsFactory() || func.IsGenerativeConstructor()) {
+    if (func.IsGenerativeConstructor()) {
       // A mixin class must not have explicit constructors.
       if (!func.IsImplicitConstructor()) {
-        const char* ctr_kind = func.IsFactory() ? "factory" : "constructor";
         const Script& script = Script::Handle(cls.script());
         const Error& error = Error::Handle(
             LanguageError::NewFormatted(Error::Handle(),
                 script, func.token_pos(), Report::AtLocation,
                 Report::kError, Heap::kNew,
-                "%s '%s' is illegal in mixin class %s",
-                ctr_kind,
+                "constructor '%s' is illegal in mixin class %s",
                 String::Handle(func.PrettyName()).ToCString(),
                 String::Handle(zone, mixin_cls.Name()).ToCString()));
 
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index 3296bcc..7129cf8 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -180,6 +180,13 @@
 }
 
 
+#if defined(DEBUG)
+void ClassTable::Unregister(intptr_t index) {
+  table_[index] = 0;
+}
+#endif
+
+
 void ClassTable::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(visitor != NULL);
   visitor->VisitPointers(reinterpret_cast<RawObject**>(&table_[0]), top_);
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index aa8c366..97e475a 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -171,6 +171,10 @@
 
   void RegisterAt(intptr_t index, const Class& cls);
 
+#if defined(DEBUG)
+  void Unregister(intptr_t index);
+#endif
+
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
   void Validate();
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 4f5b2a1..4e23a6d 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -18,7 +18,6 @@
 #include "vm/message.h"
 #include "vm/message_handler.h"
 #include "vm/parser.h"
-#include "vm/report.h"
 #include "vm/resolver.h"
 #include "vm/runtime_entry.h"
 #include "vm/stack_frame.h"
@@ -65,8 +64,6 @@
 DECLARE_FLAG(int, max_deoptimization_counter_threshold);
 DECLARE_FLAG(bool, enable_inlining_annotations);
 DECLARE_FLAG(bool, trace_compiler);
-DECLARE_FLAG(bool, trace_field_guards);
-DECLARE_FLAG(bool, trace_optimization);
 DECLARE_FLAG(bool, trace_optimizing_compiler);
 DECLARE_FLAG(int, max_polymorphic_checks);
 DECLARE_FLAG(bool, precompilation);
@@ -82,7 +79,6 @@
             "Deoptimize on every N stack overflow checks");
 DEFINE_FLAG(charp, deoptimize_filter, NULL,
             "Deoptimize in named function on stack overflow checks");
-DEFINE_FLAG(bool, lazy_dispatchers, true, "Lazily generate dispatchers");
 
 #ifdef DEBUG
 DEFINE_FLAG(charp, gc_at_instance_allocation, NULL,
diff --git a/runtime/vm/code_observers.cc b/runtime/vm/code_observers.cc
index 331a4be..ec47c8f 100644
--- a/runtime/vm/code_observers.cc
+++ b/runtime/vm/code_observers.cc
@@ -10,6 +10,8 @@
 
 namespace dart {
 
+#ifndef PRODUCT
+
 Mutex* CodeObservers::mutex_ = NULL;
 intptr_t CodeObservers::observers_length_ = 0;
 CodeObserver** CodeObservers::observers_ = NULL;
@@ -66,4 +68,6 @@
 }
 
 
+#endif  // !PRODUCT
+
 }  // namespace dart
diff --git a/runtime/vm/code_observers.h b/runtime/vm/code_observers.h
index 2e857f7..1ce8135 100644
--- a/runtime/vm/code_observers.h
+++ b/runtime/vm/code_observers.h
@@ -10,6 +10,8 @@
 
 namespace dart {
 
+#ifndef PRODUCT
+
 class Mutex;
 
 // Object observing code creation events. Used by external profilers and
@@ -65,6 +67,7 @@
   static CodeObserver** observers_;
 };
 
+#endif  // !PRODUCT
 
 }  // namespace dart
 
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 4d88bae..39c8846 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -275,7 +275,7 @@
 
   Thread* const thread = Thread::Current();
   StackZone zone(thread);
-#ifndef PRODUCT
+NOT_IN_PRODUCT(
   VMTagScope tagScope(thread, VMTag::kCompileClassTagId);
   TimelineDurationScope tds(thread,
                             thread->isolate()->GetCompilerStream(),
@@ -284,7 +284,7 @@
     tds.SetNumArguments(1);
     tds.CopyArgument(0, "class", cls.ToCString());
   }
-#endif  // !PRODUCT
+)  // !PRODUCT
 
   // We remember all the classes that are being compiled in these lists. This
   // also allows us to reset the marked_for_parsing state in case we see an
@@ -489,7 +489,7 @@
           }
         }
       }
-      if (!flow_graph->guarded_fields()->is_empty()) {
+      if (!flow_graph->parsed_function().guarded_fields()->is_empty()) {
         if (field_invalidation_gen_at_start() !=
             isolate()->field_invalidation_gen()) {
           code_is_valid = false;
@@ -526,10 +526,10 @@
          ++i) {
       thread()->cha()->leaf_classes()[i]->RegisterCHACode(code);
     }
-    for (intptr_t i = 0;
-         i < flow_graph->guarded_fields()->length();
-         i++) {
-      const Field* field = (*flow_graph->guarded_fields())[i];
+    const ZoneGrowableArray<const Field*>& guarded_fields =
+        *flow_graph->parsed_function().guarded_fields();
+    for (intptr_t i = 0; i < guarded_fields.length(); i++) {
+      const Field* field = guarded_fields[i];
       field->RegisterDependentCode(code);
     }
   } else {  // not optimized.
@@ -563,9 +563,8 @@
   }
   bool is_compiled = false;
   Zone* const zone = thread()->zone();
-#ifndef PRODUCT
-  TimelineStream* compiler_timeline = isolate()->GetCompilerStream();
-#endif
+  NOT_IN_PRODUCT(
+      TimelineStream* compiler_timeline = isolate()->GetCompilerStream());
   CSTAT_TIMER_SCOPE(thread(), codegen_timer);
   HANDLESCOPE(thread());
 
@@ -601,8 +600,12 @@
         if (optimized()) {
           // Extract type feedback before the graph is built, as the graph
           // builder uses it to attach it to nodes.
-          ASSERT(function.deoptimization_counter() <
-                 FLAG_max_deoptimization_counter_threshold);
+
+          // In background compilation the deoptimization counter may have
+          // already reached the limit.
+          ASSERT(Compiler::IsBackgroundCompilation() ||
+                 (function.deoptimization_counter() <
+                     FLAG_max_deoptimization_counter_threshold));
 
           // 'Freeze' ICData in background compilation so that it does not
           // change while compiling.
@@ -623,11 +626,9 @@
           }
         }
 
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(),
-                                  compiler_timeline,
-                                  "BuildFlowGraph");
-#endif  // !PRODUCT
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
+                                                 compiler_timeline,
+                                                 "BuildFlowGraph");)
         flow_graph = pipeline->BuildFlowGraph(zone,
                                               parsed_function(),
                                               *ic_data_array,
@@ -651,20 +652,15 @@
       const bool reorder_blocks =
           FlowGraph::ShouldReorderBlocks(function, optimized());
       if (reorder_blocks) {
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(),
-                                  compiler_timeline,
-                                  "BlockScheduler::AssignEdgeWeights");
-#endif  // !PRODUCT
+        NOT_IN_PRODUCT(TimelineDurationScope tds(
+            thread(), compiler_timeline, "BlockScheduler::AssignEdgeWeights"));
         block_scheduler.AssignEdgeWeights();
       }
 
       if (optimized()) {
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(),
-                                  compiler_timeline,
-                                  "ComputeSSA");
-#endif  // !PRODUCT
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
+                                                 compiler_timeline,
+                                                 "ComputeSSA"));
         CSTAT_TIMER_SCOPE(thread(), ssa_timer);
         // Transform to SSA (virtual register 0 and no inlining arguments).
         flow_graph->ComputeSSA(0, NULL);
@@ -683,11 +679,9 @@
       // have non-generic type feedback attached to them that can
       // potentially affect optimizations.
       if (optimized()) {
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(),
-                                  compiler_timeline,
-                                  "OptimizationPasses");
-#endif  // !PRODUCT
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
+                                                 compiler_timeline,
+                                                 "OptimizationPasses"));
         inline_id_to_function.Add(&function);
         // Top scope function has no caller (-1).
         caller_inline_id.Add(-1);
@@ -708,11 +702,9 @@
 
         // Inlining (mutates the flow graph)
         if (FLAG_use_inlining) {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "Inlining");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "Inlining"));
           CSTAT_TIMER_SCOPE(thread(), graphinliner_timer);
           // Propagate types to create more inlining opportunities.
           FlowGraphTypePropagator::Propagate(flow_graph);
@@ -737,11 +729,9 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "ApplyClassIds");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "ApplyClassIds"));
           // Use propagated class-ids to optimize further.
           optimizer.ApplyClassIds();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
@@ -753,19 +743,17 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         // Do optimizations that depend on the propagated type information.
-        if (optimizer.Canonicalize()) {
+        if (flow_graph->Canonicalize()) {
           // Invoke Canonicalize twice in order to fully canonicalize patterns
           // like "if (a & const == 0) { }".
-          optimizer.Canonicalize();
+          flow_graph->Canonicalize();
         }
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "BranchSimplifier");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "BranchSimplifier"));
           BranchSimplifier::Simplify(flow_graph);
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
@@ -774,15 +762,13 @@
         }
 
         if (FLAG_constant_propagation) {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "ConstantPropagation");
-#endif  // !PRODUCT
-          ConstantPropagator::Optimize(flow_graph);
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "ConstantPropagation");
+          ConstantPropagator::Optimize(flow_graph));
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
           // A canonicalization pass to remove e.g. smi checks on smi constants.
-          optimizer.Canonicalize();
+          flow_graph->Canonicalize();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
           // Canonicalization introduced more opportunities for constant
           // propagation.
@@ -805,28 +791,23 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "SelectRepresentations");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "SelectRepresentations"));
           // Where beneficial convert Smi operations into Int32 operations.
           // Only meanigful for 32bit platforms right now.
-          optimizer.WidenSmiToInt32();
+          flow_graph->WidenSmiToInt32();
 
           // Unbox doubles. Performed after constant propagation to minimize
           // interference from phis merging double values and tagged
           // values coming from dead paths.
-          optimizer.SelectRepresentations();
+          flow_graph->SelectRepresentations();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "CommonSubexpressionElinination");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(
+              thread(), compiler_timeline, "CommonSubexpressionElinination"));
           if (FLAG_common_subexpression_elimination ||
               FLAG_loop_invariant_code_motion) {
             flow_graph->ComputeBlockEffects();
@@ -835,12 +816,12 @@
           if (FLAG_common_subexpression_elimination) {
             if (DominatorBasedCSE::Optimize(flow_graph)) {
               DEBUG_ASSERT(flow_graph->VerifyUseLists());
-              optimizer.Canonicalize();
+              flow_graph->Canonicalize();
               // Do another round of CSE to take secondary effects into account:
               // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
               // TODO(fschneider): Change to a one-pass optimization pass.
               if (DominatorBasedCSE::Optimize(flow_graph)) {
-                optimizer.Canonicalize();
+                flow_graph->Canonicalize();
               }
               DEBUG_ASSERT(flow_graph->VerifyUseLists());
             }
@@ -864,20 +845,16 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "DeadStoreElimination");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "DeadStoreElimination"));
           DeadStoreElimination::Optimize(flow_graph);
         }
 
         if (FLAG_range_analysis) {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "RangeAnalysis");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "RangeAnalysis"));
           // Propagate types after store-load-forwarding. Some phis may have
           // become smi phis that can be processed by range analysis.
           FlowGraphTypePropagator::Propagate(flow_graph);
@@ -892,11 +869,9 @@
         }
 
         if (FLAG_constant_propagation) {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "ConstantPropagator::OptimizeBranches");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(
+              thread(), compiler_timeline,
+              "ConstantPropagator::OptimizeBranches"));
           // Constant propagation can use information from range analysis to
           // find unreachable branch targets and eliminate branches that have
           // the same true- and false-target.
@@ -910,11 +885,8 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "TryCatchAnalyzer::Optimize");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(
+              thread(), compiler_timeline, "TryCatchAnalyzer::Optimize"));
           // Optimize try-blocks.
           TryCatchAnalyzer::Optimize(flow_graph);
         }
@@ -922,20 +894,18 @@
         // Detach environments from the instructions that can't deoptimize.
         // Do it before we attempt to perform allocation sinking to minimize
         // amount of materializations it has to perform.
-        optimizer.EliminateEnvironments();
+        flow_graph->EliminateEnvironments();
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "EliminateDeadPhis");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "EliminateDeadPhis"));
           DeadCodeElimination::EliminateDeadPhis(flow_graph);
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
 
-        if (optimizer.Canonicalize()) {
-          optimizer.Canonicalize();
+        if (flow_graph->Canonicalize()) {
+          flow_graph->Canonicalize();
         }
 
         // Attempt to sink allocations of temporary non-escaping objects to
@@ -943,11 +913,8 @@
         AllocationSinking* sinking = NULL;
         if (FLAG_allocation_sinking &&
             (flow_graph->graph_entry()->SuccessorCount()  == 1)) {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "AllocationSinking::Optimize");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(
+              thread(), compiler_timeline, "AllocationSinking::Optimize"));
           // TODO(fschneider): Support allocation sinking with try-catch.
           sinking = new AllocationSinking(flow_graph);
           sinking->Optimize();
@@ -961,33 +928,28 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "SelectRepresentations");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "SelectRepresentations"));
           // Ensure that all phis inserted by optimization passes have
           // consistent representations.
-          optimizer.SelectRepresentations();
+          flow_graph->SelectRepresentations();
         }
 
-        if (optimizer.Canonicalize()) {
+        if (flow_graph->Canonicalize()) {
           // To fully remove redundant boxing (e.g. BoxDouble used only in
           // environments and UnboxDouble instructions) instruction we
           // first need to replace all their uses and then fold them away.
           // For now we just repeat Canonicalize twice to do that.
           // TODO(vegorov): implement a separate representation folding pass.
-          optimizer.Canonicalize();
+          flow_graph->Canonicalize();
         }
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         if (sinking != NULL) {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(
-              thread(),
-              compiler_timeline,
-              "AllocationSinking::DetachMaterializations");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(
+              thread(), compiler_timeline,
+              "AllocationSinking::DetachMaterializations"));
           // Remove all MaterializeObject instructions inserted by allocation
           // sinking from the flow graph and let them float on the side
           // referenced only from environments. Register allocator will consider
@@ -1000,22 +962,17 @@
         FlowGraphInliner::CollectGraphInfo(flow_graph, true);
 
         {
-#ifndef PRODUCT
-          TimelineDurationScope tds2(thread(),
-                                     compiler_timeline,
-                                     "AllocateRegisters");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds2(thread(),
+                                                    compiler_timeline,
+                                                    "AllocateRegisters"));
           // Perform register allocation on the SSA graph.
           FlowGraphAllocator allocator(*flow_graph);
           allocator.AllocateRegisters();
         }
 
         if (reorder_blocks) {
-#ifndef PRODUCT
-          TimelineDurationScope tds(thread(),
-                                    compiler_timeline,
-                                    "BlockScheduler::ReorderBlocks");
-#endif  // !PRODUCT
+          NOT_IN_PRODUCT(TimelineDurationScope tds(
+              thread(), compiler_timeline, "BlockScheduler::ReorderBlocks"));
           block_scheduler.ReorderBlocks();
         }
 
@@ -1032,20 +989,16 @@
                                        caller_inline_id);
       {
         CSTAT_TIMER_SCOPE(thread(), graphcompiler_timer);
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(),
-                                  compiler_timeline,
-                                  "CompileGraph");
-#endif  // !PRODUCT
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
+                                                 compiler_timeline,
+                                                 "CompileGraph"));
         graph_compiler.CompileGraph();
         pipeline->FinalizeCompilation();
       }
       {
-#ifndef PRODUCT
-        TimelineDurationScope tds(thread(),
-                                  compiler_timeline,
-                                  "FinalizeCompilation");
-#endif  // !PRODUCT
+        NOT_IN_PRODUCT(TimelineDurationScope tds(thread(),
+                                                 compiler_timeline,
+                                                 "FinalizeCompilation"));
         if (thread()->IsMutatorThread()) {
           FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
         } else {
@@ -1110,7 +1063,7 @@
 }
 
 
-#if defined(DEBUG)
+DEBUG_ONLY(
 // Verifies that the inliner is always in the list of inlined functions.
 // If this fails run with --trace-inlining-intervals to get more information.
 static void CheckInliningIntervals(const Function& function) {
@@ -1128,8 +1081,7 @@
            function.raw());
   }
 }
-#endif
-
+)
 
 static RawError* CompileFunctionHelper(CompilationPipeline* pipeline,
                                        const Function& function,
@@ -1153,9 +1105,10 @@
     if (trace_compiler) {
       const intptr_t token_size = function.end_token_pos().Pos() -
                                   function.token_pos().Pos();
-      THR_Print("Compiling %s%sfunction: '%s' @ token %s, size %" Pd "\n",
+      THR_Print("Compiling %s%sfunction %s: '%s' @ token %s, size %" Pd "\n",
                 (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "),
                 (optimized ? "optimized " : ""),
+                (Compiler::IsBackgroundCompilation() ? "(background)" : ""),
                 function.ToFullyQualifiedCString(),
                 function.token_pos().ToCString(),
                 token_size);
@@ -1224,9 +1177,7 @@
       Disassembler::DisassembleCode(function, true);
       THR_Print("*** END CODE\n");
     }
-#if defined(DEBUG)
-    CheckInliningIntervals(function);
-#endif
+    DEBUG_ONLY(CheckInliningIntervals(function));
     return Error::null();
   } else {
     Thread* const thread = Thread::Current();
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index d120682..7905ed8 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -89,6 +89,8 @@
 }
 
 
+#ifndef PRODUCT
+
 // This function is used as a callback in the log object to which the
 // compiler stats are printed. It will be called only once, to print
 // the accumulated text when all of the compiler stats values are
@@ -286,4 +288,6 @@
   return stats_text;
 }
 
+#endif  // !PRODUCT
+
 }  // namespace dart
diff --git a/runtime/vm/compiler_stats.h b/runtime/vm/compiler_stats.h
index 296b2a4..9b9e67b 100644
--- a/runtime/vm/compiler_stats.h
+++ b/runtime/vm/compiler_stats.h
@@ -72,20 +72,22 @@
 };
 
 #define INC_STAT(thread, counter, incr)                                        \
-  if (FLAG_compiler_stats) {                                                   \
+  if (FLAG_support_compiler_stats && FLAG_compiler_stats) {                    \
     MutexLocker ml((thread)->isolate()->mutex());                              \
     (thread)->isolate()->compiler_stats()->counter += (incr);                  \
   }
 
 #define STAT_VALUE(thread, counter)                                            \
-  ((FLAG_compiler_stats != false) ?                                            \
+  ((FLAG_support_compiler_stats && FLAG_compiler_stats) ?                      \
       (thread)->isolate()->compiler_stats()->counter : 0)
 
 #define CSTAT_TIMER_SCOPE(thr, t)                                              \
-  TimerScope timer(FLAG_compiler_stats,                                        \
-      FLAG_compiler_stats ? &((thr)->isolate()->compiler_stats()->t) : NULL,   \
+  TimerScope timer(FLAG_support_compiler_stats && FLAG_compiler_stats,         \
+      (FLAG_support_compiler_stats && FLAG_compiler_stats) ?                   \
+      &((thr)->isolate()->compiler_stats()->t) : NULL,                         \
       thr);
 
+
 }  // namespace dart
 
 #endif  // VM_COMPILER_STATS_H_
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 5e563eb..895d6b1 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -99,15 +99,13 @@
   if (FLAG_support_timeline) {
     Timeline::InitOnce();
   }
-#ifndef PRODUCT
-  TimelineDurationScope tds(Timeline::GetVMStream(),
-                            "Dart::InitOnce");
-#endif
+  NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(),
+                                           "Dart::InitOnce"));
   Isolate::InitOnce();
   PortMap::InitOnce();
   FreeListElement::InitOnce();
   Api::InitOnce();
-  CodeObservers::InitOnce();
+  NOT_IN_PRODUCT(CodeObservers::InitOnce());
   if (FLAG_profiler) {
     ThreadInterrupter::InitOnce();
     Profiler::InitOnce();
@@ -365,7 +363,7 @@
     OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting code observers\n",
                  timestamp());
   }
-  CodeObservers::DeleteAll();
+  NOT_IN_PRODUCT(CodeObservers::DeleteAll());
   if (FLAG_support_timeline) {
     if (FLAG_trace_shutdown) {
       OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Shutting down timeline\n",
@@ -393,18 +391,17 @@
   // Initialize the new isolate.
   Thread* T = Thread::Current();
   Isolate* I = T->isolate();
-#ifndef PRODUCT
-  TimelineDurationScope tds(T, I->GetIsolateStream(), "InitializeIsolate");
-  tds.SetNumArguments(1);
-  tds.CopyArgument(0, "isolateName", I->name());
-#endif  // !PRODUCT
+  NOT_IN_PRODUCT(
+    TimelineDurationScope tds(T, I->GetIsolateStream(), "InitializeIsolate");
+    tds.SetNumArguments(1);
+    tds.CopyArgument(0, "isolateName", I->name());
+  )
   ASSERT(I != NULL);
   StackZone zone(T);
   HandleScope handle_scope(T);
   {
-#ifndef PRODUCT
-    TimelineDurationScope tds(T, I->GetIsolateStream(), "ObjectStore::Init");
-#endif  // !PRODUCT
+    NOT_IN_PRODUCT(TimelineDurationScope tds(T,
+        I->GetIsolateStream(), "ObjectStore::Init"));
     ObjectStore::Init(I);
   }
 
@@ -414,10 +411,8 @@
   }
   if (snapshot_buffer != NULL) {
     // Read the snapshot and setup the initial state.
-#ifndef PRODUCT
-    TimelineDurationScope tds(
-        T, I->GetIsolateStream(), "IsolateSnapshotReader");
-#endif  // !PRODUCT
+    NOT_IN_PRODUCT(TimelineDurationScope tds(T,
+        I->GetIsolateStream(), "IsolateSnapshotReader"));
     // TODO(turnidge): Remove once length is not part of the snapshot.
     const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_buffer);
     if (snapshot == NULL) {
@@ -451,14 +446,11 @@
   }
 
   Object::VerifyBuiltinVtables();
-#if defined(DEBUG)
-  I->heap()->Verify(kForbidMarked);
-#endif
+  DEBUG_ONLY(I->heap()->Verify(kForbidMarked));
 
   {
-#ifndef PRODUCT
-    TimelineDurationScope tds(T, I->GetIsolateStream(), "StubCode::Init");
-#endif  // !PRODUCT
+    NOT_IN_PRODUCT(TimelineDurationScope tds(T,
+        I->GetIsolateStream(), "StubCode::Init"));
     StubCode::Init(I);
   }
 
@@ -472,8 +464,9 @@
   I->set_ic_miss_code(miss_code);
 
   if (snapshot_buffer == NULL) {
-    if (!I->object_store()->PreallocateObjects()) {
-      return T->sticky_error();
+    const Error& error = Error::Handle(I->object_store()->PreallocateObjects());
+    if (!error.IsNull()) {
+      return error.raw();
     }
   }
 
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index dad463e..4c27091 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -16,7 +16,6 @@
 #include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
-#include "vm/debuginfo.h"
 #include "vm/exceptions.h"
 #include "vm/flags.h"
 #include "vm/growable_array.h"
@@ -52,7 +51,6 @@
 #define Z (T->zone())
 
 
-DECLARE_FLAG(bool, enable_mirrors);
 DECLARE_FLAG(bool, load_deferred_eagerly);
 DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, print_class_table);
@@ -5717,9 +5715,9 @@
                                                   const char* event_kind,
                                                   const uint8_t* bytes,
                                                   intptr_t bytes_length) {
-#ifdef PRODUCT
+#if defined(PRODUCT)
   return Api::Success();
-#else
+#else  // defined(PRODUCT)
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   if (stream_id == NULL) {
@@ -5738,7 +5736,7 @@
   Service::SendEmbedderEvent(I, stream_id, event_kind,
                              bytes, bytes_length);
   return Api::Success();
-#endif  // PRODUCT
+#endif  // defined(PRODUCT)
 }
 
 
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 615976f..3845949 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -17,8 +17,6 @@
 
 namespace dart {
 
-DECLARE_FLAG(bool, lazy_dispatchers);
-
 // A cache of VM heap allocated arguments descriptors.
 RawArray* ArgumentsDescriptor::cached_args_descriptors_[kCachedDescriptorCount];
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 82511db..06e7880 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -218,6 +218,9 @@
 
   jsobj.AddFixedServiceId("breakpoints/%" Pd "", id());
   jsobj.AddProperty("breakpointNumber", id());
+  if (is_synthetic_async()) {
+    jsobj.AddProperty("isSyntheticAsyncContinuation", is_synthetic_async());
+  }
   jsobj.AddProperty("resolved", bpt_location_->IsResolved());
   if (bpt_location_->IsResolved()) {
     jsobj.AddLocation(bpt_location_);
@@ -430,7 +433,8 @@
 
 
 Breakpoint* BreakpointLocation::AddPerClosure(Debugger* dbg,
-                                              const Instance& closure) {
+                                              const Instance& closure,
+                                              bool for_over_await) {
   Breakpoint* bpt = breakpoints();
   while (bpt != NULL) {
     if (bpt->IsPerClosure() && bpt->closure() == closure.raw()) break;
@@ -439,6 +443,7 @@
   if (bpt == NULL) {
     bpt = new Breakpoint(dbg->nextId(), this);
     bpt->SetIsPerClosure(closure);
+    bpt->set_is_synthetic_async(for_over_await);
     AddBreakpoint(bpt, dbg);
   }
   return bpt;
@@ -1268,6 +1273,7 @@
       stack_trace_(NULL),
       stepping_fp_(0),
       skip_next_step_(false),
+      synthetic_async_breakpoint_(NULL),
       exc_pause_info_(kNoPauseOnExceptions) {
 }
 
@@ -1280,6 +1286,7 @@
   ASSERT(code_breakpoints_ == NULL);
   ASSERT(stack_trace_ == NULL);
   ASSERT(obj_cache_ == NULL);
+  ASSERT(synthetic_async_breakpoint_ == NULL);
 }
 
 
@@ -1326,6 +1333,25 @@
 }
 
 
+bool Debugger::SetupStepOverAsyncSuspension() {
+  ActivationFrame* top_frame = TopDartFrame();
+  if (!IsAtAsyncJump(top_frame)) {
+    // Not at an async operation.
+    return false;
+  }
+  Object& closure = Object::Handle(top_frame->GetAsyncOperation());
+  ASSERT(!closure.IsNull());
+  ASSERT(closure.IsInstance());
+  ASSERT(Instance::Cast(closure).IsClosure());
+  Breakpoint* bpt = SetBreakpointAtActivation(Instance::Cast(closure), true);
+  if (bpt == NULL) {
+    // Unable to set the breakpoint.
+    return false;
+  }
+  return true;
+}
+
+
 void Debugger::SetSingleStep() {
   resume_action_ = kSingleStep;
 }
@@ -2155,7 +2181,8 @@
 }
 
 
-Breakpoint* Debugger::SetBreakpointAtActivation(const Instance& closure) {
+Breakpoint* Debugger::SetBreakpointAtActivation(
+    const Instance& closure, bool for_over_await) {
   if (!closure.IsClosure()) {
     return NULL;
   }
@@ -2165,7 +2192,7 @@
                                                    func.token_pos(),
                                                    func.end_token_pos(),
                                                    -1, -1 /* no line/col */);
-  return bpt_location->AddPerClosure(this, closure);
+  return bpt_location->AddPerClosure(this, closure, for_over_await);
 }
 
 
@@ -2617,24 +2644,28 @@
   DebuggerEvent event(isolate_, DebuggerEvent::kBreakpointReached);
   event.set_top_frame(top_frame);
   event.set_breakpoint(bpt);
+  event.set_at_async_jump(IsAtAsyncJump(top_frame));
+  Pause(&event);
+}
+
+
+bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) {
   Object& closure_or_null = Object::Handle(top_frame->GetAsyncOperation());
   if (!closure_or_null.IsNull()) {
     ASSERT(closure_or_null.IsInstance());
     ASSERT(Instance::Cast(closure_or_null).IsClosure());
-    event.set_async_continuation(&closure_or_null);
     const Script& script = Script::Handle(top_frame->SourceScript());
     const TokenStream& tokens = TokenStream::Handle(script.tokens());
     TokenStream::Iterator iter(tokens, top_frame->TokenPos());
     if ((iter.CurrentTokenKind() == Token::kIDENT) &&
         ((iter.CurrentLiteral() == Symbols::Await().raw()) ||
          (iter.CurrentLiteral() == Symbols::YieldKw().raw()))) {
-      event.set_at_async_jump(true);
+      return true;
     }
   }
-  Pause(&event);
+  return false;
 }
 
-
 RawError* Debugger::DebuggerStepCallback() {
   ASSERT(isolate_->single_step());
   // Don't pause recursively.
@@ -2691,7 +2722,14 @@
 
   ASSERT(stack_trace_ == NULL);
   stack_trace_ = CollectStackTrace();
-  SignalPausedEvent(frame, NULL);
+  // If this step callback is part of stepping over an await statement,
+  // we saved the synthetic async breakpoint in SignalBpReached. We report
+  // that we are paused at that breakpoint and then delete it after continuing.
+  SignalPausedEvent(frame, synthetic_async_breakpoint_);
+  if (synthetic_async_breakpoint_ != NULL) {
+    RemoveBreakpoint(synthetic_async_breakpoint_->id());
+    synthetic_async_breakpoint_ = NULL;
+  }
   HandleSteppingRequest(stack_trace_);
   stack_trace_ = NULL;
 
@@ -2764,6 +2802,36 @@
     return Error::null();
   }
 
+  if (bpt_hit->is_synthetic_async()) {
+    DebuggerStackTrace* stack_trace = CollectStackTrace();
+    ASSERT(stack_trace->Length() > 0);
+    ASSERT(stack_trace_ == NULL);
+    stack_trace_ = stack_trace;
+
+    // Hit a synthetic async breakpoint.
+    if (FLAG_verbose_debug) {
+      OS::Print(">>> hit synthetic breakpoint at %s:%" Pd " "
+                "(token %s) (address %#" Px ")\n",
+                String::Handle(cbpt->SourceUrl()).ToCString(),
+                cbpt->LineNumber(),
+                cbpt->token_pos().ToCString(),
+                top_frame->pc());
+    }
+
+    ASSERT(synthetic_async_breakpoint_ == NULL);
+    synthetic_async_breakpoint_ = bpt_hit;
+    bpt_hit = NULL;
+
+    // We are at the entry of an async function.
+    // We issue a step over to resume at the point after the await statement.
+    SetStepOver();
+    // When we single step from a user breakpoint, our next stepping
+    // point will be at the exact same pc.  Skip it.
+    HandleSteppingRequest(stack_trace_, true /* skip next step */);
+    stack_trace_ = NULL;
+    return Error::null();
+  }
+
   if (FLAG_verbose_debug) {
     OS::Print(">>> hit %s breakpoint at %s:%" Pd " "
               "(token %s) (address %#" Px ")\n",
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index d6904d5..4d00a34 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -30,7 +30,8 @@
       kind_(Breakpoint::kNone),
       next_(NULL),
       closure_(Instance::null()),
-      bpt_location_(bpt_location) {}
+      bpt_location_(bpt_location),
+      is_synthetic_async_(false) {}
 
   intptr_t id() const { return id_; }
   Breakpoint* next() const { return next_; }
@@ -60,6 +61,14 @@
     closure_ = closure.raw();
   }
 
+  // Mark that this breakpoint is a result of a step OverAwait request.
+  void set_is_synthetic_async(bool is_synthetic_async) {
+    is_synthetic_async_ = is_synthetic_async;
+  }
+  bool is_synthetic_async() const {
+    return is_synthetic_async_;
+  }
+
   void PrintJSON(JSONStream* stream);
 
  private:
@@ -77,6 +86,7 @@
   Breakpoint* next_;
   RawInstance* closure_;
   BreakpointLocation* bpt_location_;
+  bool is_synthetic_async_;
 
   friend class BreakpointLocation;
   DISALLOW_COPY_AND_ASSIGN(Breakpoint);
@@ -128,7 +138,9 @@
 
   Breakpoint* AddRepeated(Debugger* dbg);
   Breakpoint* AddSingleShot(Debugger* dbg);
-  Breakpoint* AddPerClosure(Debugger* dbg, const Instance& closure);
+  Breakpoint* AddPerClosure(Debugger* dbg,
+                            const Instance& closure,
+                            bool for_over_await);
 
   bool AnyEnabled() const;
   bool IsResolved() const { return is_resolved_; }
@@ -467,7 +479,8 @@
   // Set breakpoint at closest location to function entry.
   Breakpoint* SetBreakpointAtEntry(const Function& target_function,
                                    bool single_shot);
-  Breakpoint* SetBreakpointAtActivation(const Instance& closure);
+  Breakpoint* SetBreakpointAtActivation(const Instance& closure,
+                                        bool for_over_await);
   Breakpoint* BreakpointAtActivation(const Instance& closure);
 
   // TODO(turnidge): script_url may no longer be specific enough.
@@ -486,6 +499,8 @@
   void RemoveBreakpoint(intptr_t bp_id);
   Breakpoint* GetBreakpointById(intptr_t id);
 
+  // Will return false if we are not at an await.
+  bool SetupStepOverAsyncSuspension();
   void SetStepOver();
   void SetSingleStep();
   void SetStepOut();
@@ -587,7 +602,7 @@
   static bool HasAnyEventHandler();
   static bool HasDebugEventHandler();
   void InvokeEventHandler(DebuggerEvent* event);
-
+  bool IsAtAsyncJump(ActivationFrame* top_frame);
   void FindCompiledFunctions(const Script& script,
                              TokenPosition start_pos,
                              TokenPosition end_pos,
@@ -696,6 +711,11 @@
   // breakpoint.
   bool skip_next_step_;
 
+  // We keep this breakpoint alive until after the debugger does the step over
+  // async continuation machinery so that we can report that we've stopped
+  // at the breakpoint.
+  Breakpoint* synthetic_async_breakpoint_;
+
   Dart_ExceptionPauseInfo exc_pause_info_;
 
   static EventHandler* event_handler_;
diff --git a/runtime/vm/debuginfo.h b/runtime/vm/debuginfo.h
deleted file mode 100644
index fd94268..0000000
--- a/runtime/vm/debuginfo.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef VM_DEBUGINFO_H_
-#define VM_DEBUGINFO_H_
-
-#include "platform/assert.h"
-#include "platform/utils.h"
-#include "vm/globals.h"
-
-namespace dart {
-
-// DebugInfo is used to generate minimal debug information containing code,
-// symbols, and line numbers for generated code in the dart VM. This information
-// can be used in two ways:
-// - for debugging using a debugger
-// - for generating information to be read by pprof to analyze Dart programs.
-class DebugInfo {
- public:
-  // A basic ByteBuffer which is growable and uses malloc/free.
-  class ByteBuffer {
-   public:
-    ByteBuffer() : size_(0), capacity_(0), data_(NULL) { }
-    ~ByteBuffer() {
-      free(data_);
-      size_ = 0;
-      capacity_ = 0;
-      data_ = NULL;
-    }
-
-    uint8_t at(int index) const {
-      ASSERT(0 <= index);
-      ASSERT(index < size_);
-      ASSERT(size_ <= capacity_);
-      return data_[index];
-    }
-
-    uint8_t* data() const { return data_; }
-    void set_data(uint8_t* value) { data_ = value; }
-    int size() const { return size_; }
-
-    // Append an element.
-    void Add(const uint8_t value) {
-      Resize(size() + 1);
-      data_[size() - 1] = value;
-    }
-
-   private:
-    void Resize(int new_size) {
-      if (new_size > capacity_) {
-        int new_capacity = Utils::RoundUpToPowerOfTwo(new_size);
-        uint8_t* new_data =
-            reinterpret_cast<uint8_t*>(realloc(data_, new_capacity));
-        ASSERT(new_data != NULL);
-        data_ = new_data;
-        capacity_ = new_capacity;
-      }
-      size_ = new_size;
-    }
-
-    int size_;
-    int capacity_;
-    uint8_t* data_;
-
-    // Disallow assignment
-    DISALLOW_COPY_AND_ASSIGN(ByteBuffer);
-  };
-
-  ~DebugInfo();
-
-  // Add the code starting at pc.
-  void AddCode(uword pc, intptr_t size);
-
-  // Add symbol information for a region (includes the start and end symbol),
-  // does not add the actual code.
-  void AddCodeRegion(const char* name, uword pc, intptr_t size);
-
-  // Write out all the debug information info the memory region.
-  bool WriteToMemory(ByteBuffer* region);
-
-  // Create a new debug information generator.
-  static DebugInfo* NewGenerator();
-
-  // Register this generated section with debuggger using the JIT interface.
-  static void RegisterSection(const char* name,
-                              uword entry_point,
-                              intptr_t size);
-
-  // Unregister all generated section from debuggger.
-  static void UnregisterAllSections();
-
- private:
-  void* handle_;
-  DebugInfo();
-
-  DISALLOW_COPY_AND_ASSIGN(DebugInfo);
-};
-
-}  // namespace dart
-
-#endif  // VM_DEBUGINFO_H_
diff --git a/runtime/vm/debuginfo_android.cc b/runtime/vm/debuginfo_android.cc
deleted file mode 100644
index ee4015c..0000000
--- a/runtime/vm/debuginfo_android.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/globals.h"
-#if defined(TARGET_OS_ANDROID)
-
-#include "vm/debuginfo.h"
-
-#include "vm/elfgen.h"
-#include "vm/gdbjit_android.h"
-
-namespace dart {
-
-DebugInfo::DebugInfo() {
-  handle_ = reinterpret_cast<void*>(new ElfGen());
-  ASSERT(handle_ != NULL);
-}
-
-
-DebugInfo::~DebugInfo() {
-  ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
-  delete elf_gen;
-}
-
-
-void DebugInfo::AddCode(uword pc, intptr_t size) {
-  ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
-  elf_gen->AddCode(pc, size);
-}
-
-
-void DebugInfo::AddCodeRegion(const char* name, uword pc, intptr_t size) {
-  ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
-  elf_gen->AddCodeRegion(name, pc, size);
-}
-
-
-bool DebugInfo::WriteToMemory(ByteBuffer* region) {
-  ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
-  return elf_gen->WriteToMemory(region);
-}
-
-
-DebugInfo* DebugInfo::NewGenerator() {
-  return new DebugInfo();
-}
-
-
-void DebugInfo::RegisterSection(const char* name,
-                                uword entry_point,
-                                intptr_t size) {
-  ElfGen* elf_section = new ElfGen();
-  ASSERT(elf_section != NULL);
-  elf_section->AddCode(entry_point, size);
-  elf_section->AddCodeRegion(name, entry_point, size);
-
-  ByteBuffer* dynamic_region = new ByteBuffer();
-  ASSERT(dynamic_region != NULL);
-
-  elf_section->WriteToMemory(dynamic_region);
-
-  ::addDynamicSection(reinterpret_cast<const char*>(dynamic_region->data()),
-                      dynamic_region->size());
-  dynamic_region->set_data(NULL);
-  delete dynamic_region;
-  delete elf_section;
-}
-
-
-void DebugInfo::UnregisterAllSections() {
-  ::deleteDynamicSections();
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/vm/debuginfo_linux.cc b/runtime/vm/debuginfo_linux.cc
deleted file mode 100644
index 9e73553..0000000
--- a/runtime/vm/debuginfo_linux.cc
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/globals.h"
-#if defined(TARGET_OS_LINUX)
-
-#include "vm/debuginfo.h"
-
-#include "vm/elfgen.h"
-#include "vm/gdbjit_linux.h"
-
-namespace dart {
-
-DebugInfo::DebugInfo() {
-  handle_ = reinterpret_cast<void*>(new ElfGen());
-  ASSERT(handle_ != NULL);
-}
-
-
-DebugInfo::~DebugInfo() {
-  ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
-  delete elf_gen;
-}
-
-
-void DebugInfo::AddCode(uword pc, intptr_t size) {
-  ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
-  elf_gen->AddCode(pc, size);
-}
-
-
-void DebugInfo::AddCodeRegion(const char* name, uword pc, intptr_t size) {
-  ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
-  elf_gen->AddCodeRegion(name, pc, size);
-}
-
-
-bool DebugInfo::WriteToMemory(ByteBuffer* region) {
-  ElfGen* elf_gen = reinterpret_cast<ElfGen*>(handle_);
-  return elf_gen->WriteToMemory(region);
-}
-
-
-DebugInfo* DebugInfo::NewGenerator() {
-  return new DebugInfo();
-}
-
-
-void DebugInfo::RegisterSection(const char* name,
-                                uword entry_point,
-                                intptr_t size) {
-  ElfGen* elf_section = new ElfGen();
-  ASSERT(elf_section != NULL);
-  elf_section->AddCode(entry_point, size);
-  elf_section->AddCodeRegion(name, entry_point, size);
-
-  ByteBuffer* dynamic_region = new ByteBuffer();
-  ASSERT(dynamic_region != NULL);
-
-  elf_section->WriteToMemory(dynamic_region);
-
-  ::addDynamicSection(reinterpret_cast<const char*>(dynamic_region->data()),
-                      dynamic_region->size());
-  dynamic_region->set_data(NULL);
-  delete dynamic_region;
-  delete elf_section;
-}
-
-
-void DebugInfo::UnregisterAllSections() {
-  ::deleteDynamicSections();
-}
-
-}  // namespace dart
-
-#endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/vm/elfgen.h b/runtime/vm/elfgen.h
deleted file mode 100644
index f3fcd70..0000000
--- a/runtime/vm/elfgen.h
+++ /dev/null
@@ -1,509 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef VM_ELFGEN_H_
-#define VM_ELFGEN_H_
-
-#include "vm/lockers.h"
-#include "vm/os_thread.h"
-
-namespace dart {
-
-// -----------------------------------------------------------------------------
-// Implementation of ElfGen
-//
-// Specification documents:
-//   http://refspecs.freestandards.org
-//
-//   ELF generic ABI:
-//     http://refspecs.freestandards.org/elf/gabi4+/contents.html
-//   ELF processor-specific supplement for X86_64:
-//     http://refspecs.freestandards.org/elf/x86_64-SysV-psABI.pdf
-//   DWARF 2.0:
-//     http://refspecs.freestandards.org/dwarf/dwarf-2.0.0.pdf
-
-// Forward declarations.
-class File;
-
-// ElfGen is used to generate minimal ELF information containing code, symbols,
-// and line numbers for generated code in the dart VM. This information is
-// used in two ways:
-// - it is used to generate in-memory ELF information which is then
-//   registered with gdb using the JIT interface.
-// - it is also used to generate a file with the ELF information. This file
-//   is not executed, but read by pprof to analyze Dart programs.
-
-class ElfGen {
- public:
-  ElfGen();
-  ~ElfGen();
-
-  // Add the code starting at pc.
-  void AddCode(uword pc, intptr_t size);
-
-  // Add symbol information for a region (includes the start and end symbol),
-  // does not add the actual code.
-  void AddCodeRegion(const char* name, uword pc, intptr_t size);
-
-  // Add specified symbol information, does not add the actual code.
-  int AddFunction(const char* name, uword pc, intptr_t size);
-
-  // Write out all the Elf information using the specified handle.
-  bool WriteToFile(File* handle);
-  bool WriteToMemory(DebugInfo::ByteBuffer* region);
-
-  // Register this generated section with GDB using the JIT interface.
-  static void RegisterSectionWithGDB(const char* name,
-                                     uword entry_point,
-                                     intptr_t size);
-
-  // Unregister all generated section from GDB.
-  static void UnregisterAllSectionsWithGDB();
-
- private:
-  // ELF helpers
-  typedef int (*OutputWriter)(void* handle,
-                              const DebugInfo::ByteBuffer& section);
-  typedef void (*OutputPadder)(void* handle, int padding_size);
-
-  int AddString(DebugInfo::ByteBuffer* buf, const char* str);
-  int AddSectionName(const char* str);
-  int AddName(const char* str);
-  void AddELFHeader(int shoff);
-  void AddSectionHeader(int section, int offset);
-  int PadSection(DebugInfo::ByteBuffer* section, int offset, int alignment);
-  bool WriteOutput(void* handle, OutputWriter writer, OutputPadder padder);
-
-  uword text_vma_;  // text section vma
-  intptr_t text_size_;  // text section size
-  int text_padding_;  // padding preceding text section
-
-  static const int kNumSections = 5;  // we generate 5 sections
-  int section_name_[kNumSections];  // array of section name indices
-  DebugInfo::ByteBuffer section_buf_[kNumSections];  // array of section buffers
-  DebugInfo::ByteBuffer header_;  // ELF header buffer
-  DebugInfo::ByteBuffer sheaders_;  // section header table buffer
-  DebugInfo::ByteBuffer lineprog_;  // line statement program, part of
-                                    // '.debug_line' section
-
-  // current state of the DWARF line info generator
-  uintptr_t cur_addr_;  // current pc
-  int map_offset_;
-  uword map_begin_;
-  uword map_end_;
-
-  Mutex lock_;
-};
-
-
-enum {
-  // Various constant sizes for ELF files.
-  kAddrSize = sizeof(uword),
-  kPageSize = 4*1024,  // Memory mapping page size.
-  kTextAlign = 16,
-  kELFHeaderSize = 40 + 3*kAddrSize,
-  kProgramHeaderEntrySize = 8 + 6*kAddrSize,
-  kSectionHeaderEntrySize = 16 + 6*kAddrSize,
-  kSymbolSize = 8 + 2*kAddrSize,
-
-  // Our own layout of sections.
-  kUndef = 0,   // Undefined section.
-  kText,        // Text section.
-  kShStrtab,    // Section header string table.
-  kStrtab,      // String table.
-  kSymtab,      // Symbol table.
-  kNumSections,  // Num of section header entries in section header table.
-
-  // Various ELF constants.
-  kELFCLASS32 = 1,
-  kELFCLASS64 = 2,
-  kELFDATA2LSB = 1,
-  kELFDATA2MSB = 2,
-  kEM_386 = 3,
-  kEM_MIPS = 8,
-  kEM_ARM = 40,
-  kEM_X86_64 = 62,
-  kEV_CURRENT = 1,
-  kET_EXEC = 2,  // not used
-  kET_DYN = 3,
-  kSHT_PROGBITS = 1,
-  kSHT_SYMTAB = 2,
-  kSHT_STRTAB = 3,
-  kSHF_WRITE = 1,  // not used
-  kSHF_ALLOC = 2,
-  kSHF_EXECINSTR = 4,
-  kSTB_LOCAL = 0,
-  kSTB_EXPORTED = 1,
-  kSTT_FUNC = 2,
-};
-
-
-// ELF and DWARF constants.
-static const char* kEI_MAG0_MAG3 = "\177ELF";
-static const uint8_t kSpecialOpcodeLengths[] = { 0, 1, 1, 1, 1, 0, 0, 0, 1 };
-
-
-// Section attributes.
-// The field names correspond to the field names of Elf32_Shdr and Elf64_Shdr.
-static const struct {
-  // Section header index (only used to check correct section order).
-  int shndx;
-  const char* name;  // sh_name will be the index of name inserted in shstrtab.
-  int sh_type;
-  int sh_flags;
-  int sh_link;
-  int sh_addralign;
-  int sh_entsize;
-} section_attr[kNumSections + 1] = {
-  { kUndef,      "",               0,             0,
-    0,       0,           0           },
-  { kText,       ".text",          kSHT_PROGBITS, kSHF_ALLOC|kSHF_EXECINSTR,
-    0,       kTextAlign,  0           },
-  { kShStrtab,   ".shstrtab",      kSHT_STRTAB,   0,
-    0,       1,           0           },
-  { kStrtab,     ".strtab",        kSHT_STRTAB,   0,
-    0,       1,           0           },
-  { kSymtab,     ".symtab",        kSHT_SYMTAB,   0,
-    kStrtab, kAddrSize,   kSymbolSize },
-  // Sentinel to pad the last section
-  // for proper alignment of section header table.
-  { 0,          "",               0,             0,
-    0,       kAddrSize,   0           }
-};
-
-
-// Convenience function aligning an integer.
-static inline uintptr_t Align(uintptr_t x, intptr_t size) {
-  // size is a power of 2
-  ASSERT((size & (size-1)) == 0);
-  return (x + (size-1)) & ~(size-1);
-}
-
-
-// Convenience function writing a single byte to a ByteBuffer.
-static inline void WriteByte(DebugInfo::ByteBuffer* buf, uint8_t byte) {
-  buf->Add(byte);
-}
-
-
-// Convenience function writing an unsigned native word to a ByteBuffer.
-// The word is 32-bit wide in 32-bit mode and 64-bit wide in 64-bit mode.
-static inline void WriteWord(DebugInfo::ByteBuffer* buf, uword word) {
-  uint8_t* p = reinterpret_cast<uint8_t*>(&word);
-  for (size_t i = 0; i < sizeof(word); i++) {
-    buf->Add(p[i]);
-  }
-}
-
-static inline void WriteInt(DebugInfo::ByteBuffer* buf, int word) {
-  uint8_t* p = reinterpret_cast<uint8_t*>(&word);
-  for (size_t i = 0; i < sizeof(word); i++) {
-    buf->Add(p[i]);
-  }
-}
-
-static inline void WriteShort(DebugInfo::ByteBuffer* buf, uint16_t word) {
-  uint8_t* p = reinterpret_cast<uint8_t*>(&word);
-  for (size_t i = 0; i < sizeof(word); i++) {
-    buf->Add(p[i]);
-  }
-}
-
-static inline void WriteString(DebugInfo::ByteBuffer* buf, const char* str) {
-  for (size_t i = 0; i < strlen(str); i++) {
-    buf->Add(static_cast<uint8_t>(str[i]));
-  }
-}
-
-static inline void Write(DebugInfo::ByteBuffer* buf,
-                         const void* mem,
-                         int length) {
-  const uint8_t* p = reinterpret_cast<const uint8_t*>(mem);
-  for (int i = 0; i < length; i++) {
-    buf->Add(p[i]);
-  }
-}
-
-
-// Write given section to file and return written size.
-static int WriteSectionToFile(void* handle,
-                              const DebugInfo::ByteBuffer& section) {
-#if 0
-  File* fp = reinterpret_cast<File*>(handle);
-  int size = section.size();
-  fp->WriteFully(section.data(), size);
-  return size;
-#else
-  return 0;
-#endif
-}
-
-
-// Pad output file to specified padding size.
-static void PadFile(void* handle, int padding_size) {
-#if 0
-  File* fp = reinterpret_cast<File*>(handle);
-  for (int i = 0; i < padding_size; i++) {
-    fp->WriteFully("", 1);
-  }
-#endif
-}
-
-
-// Write given section to specified memory region and return written size.
-static int WriteSectionToMemory(void* handle,
-                                const DebugInfo::ByteBuffer& section) {
-  DebugInfo::ByteBuffer* buffer =
-      reinterpret_cast<DebugInfo::ByteBuffer*>(handle);
-  int size = section.size();
-  for (int i = 0; i < size; i++) {
-    buffer->Add(static_cast<uint8_t>(section.data()[i]));
-  }
-  return size;
-}
-
-
-// Pad memory to specified padding size.
-static void PadMemory(void* handle, int padding_size) {
-  DebugInfo::ByteBuffer* buffer =
-      reinterpret_cast<DebugInfo::ByteBuffer*>(handle);
-  for (int i = 0; i < padding_size; i++) {
-    buffer->Add(static_cast<uint8_t>(0));
-  }
-}
-
-
-// Constructor
-ElfGen::ElfGen()
-    : text_vma_(0), text_size_(0), text_padding_(0), map_offset_(0), lock_() {
-  for (int i = 0; i < kNumSections; i++) {
-    ASSERT(section_attr[i].shndx == i);  // Verify layout of sections.
-    section_name_[i] = AddSectionName(section_attr[i].name);
-  }
-  // Section header string table always starts with an empty string, which is
-  // the name of the kUndef section.
-  ASSERT((section_attr[0].name[0] == '\0') && (section_name_[0] == 0));
-
-  // String table always starts with an empty string.
-  AddName("");
-  ASSERT(section_buf_[kStrtab].size() == 1);
-
-  // Symbol at index 0 in symtab is always STN_UNDEF (all zero):
-  DebugInfo::ByteBuffer* symtab = &section_buf_[kSymtab];
-  while (symtab->size() < kSymbolSize) {
-    WriteInt(symtab, 0);
-  }
-  ASSERT(symtab->size() == kSymbolSize);
-}
-
-
-// Destructor
-ElfGen::~ElfGen() {
-}
-
-
-void ElfGen::AddCode(uword pc, intptr_t size) {
-  MutexLocker ml(&lock_);
-  text_vma_ = pc;
-  text_size_ = size;
-  // We pad the text section in the file to align absolute code addresses with
-  // corresponding file offsets as if the code had been loaded by memory
-  // mapping.
-  if (text_vma_ % kPageSize < kELFHeaderSize) {
-    text_padding_ = text_vma_ % kPageSize + kPageSize - kELFHeaderSize;
-  } else {
-    text_padding_ = text_vma_ % kPageSize - kELFHeaderSize;
-  }
-
-  Write(&section_buf_[kText], reinterpret_cast<void*>(pc), size);
-  // map_offset is the file offset of the first mapped page.
-  map_offset_ = (kELFHeaderSize + text_padding_)/kPageSize*kPageSize;
-  map_begin_ = Align(text_vma_ - kPageSize + 1, kPageSize);
-  map_end_ = Align(text_vma_ + size, kPageSize);
-}
-
-
-void ElfGen::AddCodeRegion(const char* name, uword pc, intptr_t size) {
-  MutexLocker ml(&lock_);
-  AddFunction(name, pc, size);
-  char end_name[256];
-  OS::SNPrint(end_name, sizeof(end_name), "%s_end", name);
-  AddFunction(end_name, pc + size, 0);
-}
-
-
-int ElfGen::AddFunction(const char* name, uword pc, intptr_t size) {
-  ASSERT(text_vma_ != 0);  // code must have been added
-  DebugInfo::ByteBuffer* symtab = &section_buf_[kSymtab];
-  const int beg = symtab->size();
-  WriteInt(symtab, AddName(name));  // st_name
-#if defined(ARCH_IS_64_BIT)
-  WriteShort(symtab, (kSTB_LOCAL << 4) + kSTT_FUNC);  // st_info + (st_other<<8)
-  WriteShort(symtab, kText);  // st_shndx
-#endif
-  WriteWord(symtab, pc);  // st_value
-  WriteWord(symtab, size);  // st_size
-#if defined(ARCH_IS_32_BIT)
-  // st_info + (st_other<<8)
-  WriteShort(symtab, (kSTB_EXPORTED << 4) + kSTT_FUNC);
-  WriteShort(symtab, kText);  // st_shndx
-#endif
-  ASSERT(symtab->size() - beg == kSymbolSize);
-  return beg / kSymbolSize;  // symbol index in symtab
-}
-
-
-bool ElfGen::WriteToFile(File* handle) {
-  return WriteOutput(handle, WriteSectionToFile, PadFile);
-}
-
-
-bool ElfGen::WriteToMemory(DebugInfo::ByteBuffer* region) {
-  return WriteOutput(region, WriteSectionToMemory, PadMemory);
-}
-
-
-int ElfGen::AddString(DebugInfo::ByteBuffer* buf, const char* str) {
-  const int str_index = buf->size();
-  WriteString(buf, str);
-  WriteByte(buf, 0);  // terminating '\0'
-  return str_index;
-}
-
-
-int ElfGen::AddSectionName(const char* str) {
-  return AddString(&section_buf_[kShStrtab], str);
-}
-
-
-int ElfGen::AddName(const char* str) {
-  return AddString(&section_buf_[kStrtab], str);
-}
-
-
-void ElfGen::AddELFHeader(int shoff) {
-  ASSERT(text_vma_ != 0);  // Code must have been added.
-  Write(&header_, kEI_MAG0_MAG3, 4);  // EI_MAG0..EI_MAG3
-#if defined(ARCH_IS_32_BIT)
-  WriteByte(&header_, kELFCLASS32);  // EI_CLASS
-#elif defined(ARCH_IS_64_BIT)
-  WriteByte(&header_, kELFCLASS64);  // EI_CLASS
-#else
-#error Unknown architecture.
-#endif
-  WriteByte(&header_, kELFDATA2LSB);  // EI_DATA
-  WriteByte(&header_, kEV_CURRENT);  // EI_VERSION
-  WriteByte(&header_, 0);  // EI_PAD
-  WriteInt(&header_, 0);  // EI_PAD
-  WriteInt(&header_, 0);  // EI_PAD
-  WriteShort(&header_, kET_DYN);  // e_type, fake a shared object.
-#if defined(TARGET_ARCH_IA32)
-  WriteShort(&header_, kEM_386);  // e_machine
-#elif defined(TARGET_ARCH_X64)
-  WriteShort(&header_, kEM_X86_64);  // e_machine
-#elif defined(TARGET_ARCH_ARM)
-  WriteShort(&header_, kEM_ARM);  // e_machine
-#elif defined(TARGET_ARCH_ARM64)
-  // TODO(zra): Find the right ARM64 constant.
-  WriteShort(&header_, kEM_ARM);  // e_machine
-#elif defined(TARGET_ARCH_MIPS)
-  WriteShort(&header_, kEM_MIPS);  // e_machine
-#else
-#error Unknown architecture.
-#endif
-  WriteInt(&header_, kEV_CURRENT);  // e_version
-  WriteWord(&header_, 0);  // e_entry: none
-  WriteWord(&header_, 0);  // e_phoff: no program header table.
-  WriteWord(&header_, shoff);  // e_shoff: section header table offset.
-  WriteInt(&header_, 0);  // e_flags: no flags.
-  WriteShort(&header_, kELFHeaderSize);  // e_ehsize: header size.
-  WriteShort(&header_, kProgramHeaderEntrySize);  // e_phentsize
-  WriteShort(&header_, 0);  // e_phnum: no entries program header table.
-  WriteShort(&header_, kSectionHeaderEntrySize);  // e_shentsize
-  // e_shnum: number of section header entries.
-  WriteShort(&header_, kNumSections);
-  WriteShort(&header_, kShStrtab);  // e_shstrndx: index of shstrtab.
-  ASSERT(header_.size() == kELFHeaderSize);
-}
-
-
-void ElfGen::AddSectionHeader(int section, int offset) {
-  WriteInt(&sheaders_, section_name_[section]);
-  WriteInt(&sheaders_, section_attr[section].sh_type);
-  WriteWord(&sheaders_, section_attr[section].sh_flags);
-  // sh_addr: abs addr
-  WriteWord(&sheaders_, (section == kText) ? text_vma_ : 0);
-  WriteWord(&sheaders_, offset);  // sh_offset: section file offset.
-  WriteWord(&sheaders_, section_buf_[section].size());
-  WriteInt(&sheaders_, section_attr[section].sh_link);
-  WriteInt(&sheaders_, 0);
-  WriteWord(&sheaders_, section_attr[section].sh_addralign);
-  WriteWord(&sheaders_, section_attr[section].sh_entsize);
-  ASSERT(sheaders_.size() == kSectionHeaderEntrySize * (section + 1));
-}
-
-
-// Pads the given section with zero bytes for the given aligment, assuming the
-// section starts at given file offset; returns file offset after padded
-// section.
-int ElfGen::PadSection(DebugInfo::ByteBuffer* section,
-                       int offset,
-                       int alignment) {
-  offset += section->size();
-  int aligned_offset = Align(offset, alignment);
-  while (offset++ < aligned_offset) {
-    WriteByte(section, 0);  // one byte padding.
-  }
-  return aligned_offset;
-}
-
-
-bool ElfGen::WriteOutput(void* handle,
-                         OutputWriter writer,
-                         OutputPadder padder) {
-  if (handle == NULL || writer == NULL || padder == NULL) {
-    return false;
-  }
-
-  // Align all sections before writing the ELF header in order to calculate the
-  // file offset of the section header table, which is needed in the ELF header.
-  // Pad each section as required by the aligment constraint of the immediately
-  // following section, except the ELF header section, which requires special
-  // padding (text_padding_) to align the text_ section.
-  int offset = kELFHeaderSize + text_padding_;
-  for (int i = kText; i < kNumSections; i++) {
-    offset = PadSection(&section_buf_[i],
-                        offset,
-                        section_attr[i+1].sh_addralign);
-  }
-
-  const int shoff = offset;  // Section header table offset.
-
-  // Write elf header.
-  AddELFHeader(shoff);
-  offset = (*writer)(handle, header_);
-
-  // Pad file before writing text section in order to align vma with file
-  // offset.
-  (*padder)(handle, text_padding_);
-
-  offset += text_padding_;
-  ASSERT((text_vma_ - offset) % kPageSize == 0);
-
-  // Section header at index 0 in section header table is always SHN_UNDEF:
-  for (int i = 0; i < kNumSections; i++) {
-    AddSectionHeader(i, offset);
-    offset += (*writer)(handle, section_buf_[i]);
-  }
-  // Write section header table.
-  ASSERT(offset == shoff);
-  offset += (*writer)(handle, sheaders_);
-  ASSERT(offset == shoff + kNumSections * kSectionHeaderEntrySize);
-
-  return true;
-}
-
-}  // namespace dart
-
-#endif  // VM_ELFGEN_H_
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 259d09b..4fdfb7b 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -12,8 +12,15 @@
 // * D ebug flags: Can only be set in debug VMs, which also have assertions
 //   enabled.
 // * R elease flags: Generally available flags except when building product.
-
-#define FLAG_LIST(P, R, D)                                                     \
+// * pre C ompile flags: Generally available flags except when building product
+//   or precompiled runtime.
+//
+// Usage:
+//   P(name, type, default_value, comment)
+//   D(name, type, default_value, comment)
+//   R(name, product_value, type, default_value, comment)
+//   C(name, precompiled_value, product_value, type, default_value, comment)
+#define FLAG_LIST(P, R, D, C)                                                  \
 R(dedup_instructions, true, bool, false,                                       \
   "Canonicalize instructions when precompiling.")                              \
 R(disable_alloc_stubs_after_gc, false, bool, false,                            \
@@ -24,10 +31,26 @@
   "Disassemble optimized code.")                                               \
 R(dump_symbol_stats, false, bool, false,                                       \
   "Dump symbol table statistics")                                              \
+R(enable_mirrors, false, bool, true,                                           \
+  "Disable to make importing dart:mirrors an error.")                          \
 R(gc_at_alloc, false, bool, false,                                             \
   "GC at every allocation.")                                                   \
+P(getter_setter_ratio, int, 13,                                                \
+  "Ratio of getter/setter usage used for double field unboxing heuristics")    \
+P(guess_icdata_cid, bool, true,                                                \
+  "Artificially create type feedback for arithmetic etc. operations")          \
+C(lazy_dispatchers, false, true, bool, true,                                   \
+  "Generate dispatchers lazily")                                               \
+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,")              \
+P(merge_sin_cos, bool, false,                                                  \
+  "Merge sin/cos into sincos")                                                 \
 P(new_gen_ext_limit, int, 64,                                                  \
   "maximum total external size (MB) in new gen before triggering GC")          \
+C(polymorphic_with_deopt, false, true, bool, true,                             \
+    "Polymorphic calls with deoptimization / megamorphic call")                \
 R(pretenure_all, false, bool, false,                                           \
   "Global pretenuring (for testing).")                                         \
 P(pretenure_interval, int, 10,                                                 \
@@ -38,6 +61,8 @@
   "Enable the profiler.")                                                      \
 R(support_ast_printer, false, bool, true,                                      \
   "Support the AST printer.")                                                  \
+R(support_compiler_stats, false, bool, true,                                   \
+  "Support compiler stats.")                                                   \
 R(support_debugger, false, bool, true,                                         \
   "Support the debugger.")                                                     \
 R(support_disassembler, false, bool, true,                                     \
@@ -50,10 +75,20 @@
   "Support code coverage.")                                                    \
 R(support_timeline, false, bool, true,                                         \
   "Support timeline.")                                                         \
+D(trace_cha, bool, false,                                                      \
+  "Trace CHA operations")                                                      \
+D(trace_field_guards, bool, false,                                             \
+  "Trace changes in field's cids.")                                            \
 D(trace_handles, bool, false,                                                  \
   "Traces allocation of handles.")                                             \
+D(trace_optimization, bool, false,                                             \
+  "Print optimization details.");                                              \
 D(trace_zones, bool, false,                                                    \
   "Traces allocation sizes in the zone.")                                      \
+P(truncating_left_shift, bool, true,                                           \
+  "Optimize left shift to truncate if possible")                               \
+C(use_cha_deopt, false, true, bool, true,                                      \
+  "Use class hierarchy analysis even if it can cause deoptimization.")         \
 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 a2a63f7..ee7d702 100644
--- a/runtime/vm/flags.cc
+++ b/runtime/vm/flags.cc
@@ -30,24 +30,55 @@
 #define DEBUG_FLAG_MARCO(name, type, default_value, comment)
 #endif  // defined(DEBUG)
 
-#if defined(PRODUCT)
+#if defined(PRODUCT) && defined(DART_PRECOMPILED_RUNTIME)
 // Nothing to be done for the product flag definitions.
 #define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)
-#else  // defined(PRODUCT)
+// Nothing to be done for the precompilation flag definitions.
+#define PRECOMPILE_FLAG_MARCO(name, pre_value, product_value, type,            \
+                              default_value, comment)
+
+#elif defined(PRODUCT)  // !PRECOMPILED
+// Nothing to be done for the product flag definitions.
+#define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)
+// Nothing to be done for the precompilation flag definitions.
+#define PRECOMPILE_FLAG_MARCO(name, pre_value, product_value, type,            \
+                              default_value, comment)
+
+#elif defined(DART_PRECOMPILED_RUNTIME)  // !PRODUCT
 #define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)  \
   type FLAG_##name = Flags::Register_##type(&FLAG_##name,                      \
                                             #name,                             \
                                             default_value,                     \
                                             comment);
-#endif  // defined(PRODUCT)
+// Nothing to be done for the precompilation flag definitions.
+#define PRECOMPILE_FLAG_MARCO(name, pre_value, product_value, type,            \
+                              default_value, comment)
+
+#else  // !PRODUCT && !PRECOMPILED
+#define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)  \
+  type FLAG_##name = Flags::Register_##type(&FLAG_##name,                      \
+                                            #name,                             \
+                                            default_value,                     \
+                                            comment);
+#define PRECOMPILE_FLAG_MARCO(name, pre_value, product_value, type,            \
+                              default_value, comment)                          \
+  type FLAG_##name = Flags::Register_##type(&FLAG_##name,                      \
+                                            #name,                             \
+                                            default_value,                     \
+                                            comment);
+#endif
+
 
 // Define all of the non-product flags here.
-FLAG_LIST(PRODUCT_FLAG_MARCO, RELEASE_FLAG_MARCO, DEBUG_FLAG_MARCO)
+FLAG_LIST(PRODUCT_FLAG_MARCO,
+          RELEASE_FLAG_MARCO,
+          DEBUG_FLAG_MARCO,
+          PRECOMPILE_FLAG_MARCO)
 
 #undef RELEASE_FLAG_MARCO
 #undef DEBUG_FLAG_MARCO
 #undef PRODUCT_FLAG_MARCO
-
+#undef PRECOMPILE_FLAG_MARCO
 
 bool Flags::initialized_ = false;
 
diff --git a/runtime/vm/flags.h b/runtime/vm/flags.h
index d3e4869..81f594e 100644
--- a/runtime/vm/flags.h
+++ b/runtime/vm/flags.h
@@ -110,23 +110,46 @@
   const type FLAG_##name = default_value;
 #endif  // defined(DEBUG)
 
-#if defined(PRODUCT)
+#if defined(PRODUCT) && defined(DART_PRECOMPILED_RUNTIME)
 #define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)  \
   const type FLAG_##name = product_value;
+#define PRECOMPILE_FLAG_MARCO(name, precompiled_value, product_value, type,    \
+                              default_value, comment)                          \
+  const type FLAG_##name = precompiled_value;
 
-#else  // defined(PRODUCT)
+#elif defined(PRODUCT)  // !PRECOMPILED
+#define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)  \
+  const type FLAG_##name = product_value;
+#define PRECOMPILE_FLAG_MARCO(name, precompiled_value, product_value, type,    \
+                              default_value, comment)                          \
+  const type FLAG_##name = product_value;
 
+#elif defined(DART_PRECOMPILED_RUNTIME)  // !PRODUCT
 #define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)  \
   extern type FLAG_##name;
+#define PRECOMPILE_FLAG_MARCO(name, precompiled_value, product_value, type,    \
+                              default_value, comment)                          \
+  const type FLAG_##name = precompiled_value;
 
-#endif  // defined(PRODUCT)
+#else  // !PRODUCT && !PRECOMPILED
+#define RELEASE_FLAG_MARCO(name, product_value, type, default_value, comment)  \
+  extern type FLAG_##name;
+#define PRECOMPILE_FLAG_MARCO(name, precompiled_value, product_value, type,    \
+                              default_value, comment)                          \
+  extern type FLAG_##name;
+
+#endif
 
 // Now declare all flags here.
-FLAG_LIST(PRODUCT_FLAG_MARCO, RELEASE_FLAG_MARCO, DEBUG_FLAG_MARCO)
+FLAG_LIST(PRODUCT_FLAG_MARCO,
+          RELEASE_FLAG_MARCO,
+          DEBUG_FLAG_MARCO,
+          PRECOMPILE_FLAG_MARCO)
 
 #undef RELEASE_FLAG_MARCO
 #undef DEBUG_FLAG_MARCO
 #undef PRODUCT_FLAG_MARCO
+#undef PRECOMPILE_FLAG_MARCO
 
 }  // namespace dart
 
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 1f97a72..b7b59cd 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -6,18 +6,21 @@
 
 #include "vm/bit_vector.h"
 #include "vm/flow_graph_builder.h"
+#include "vm/flow_graph_compiler.h"
+#include "vm/flow_graph_range_analysis.h"
 #include "vm/il_printer.h"
 #include "vm/intermediate_language.h"
 #include "vm/growable_array.h"
 #include "vm/object_store.h"
-#include "vm/report.h"
 
 namespace dart {
 
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32)
+DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass.");
+#endif
 DEFINE_FLAG(bool, prune_dead_locals, true, "optimize dead locals away");
 DECLARE_FLAG(bool, emit_edge_counters);
 DECLARE_FLAG(bool, reorder_basic_blocks);
-DECLARE_FLAG(bool, trace_optimization);
 DECLARE_FLAG(bool, verify_compiler);
 
 
@@ -43,7 +46,6 @@
     licm_allowed_(true),
     loop_headers_(NULL),
     loop_invariant_loads_(NULL),
-    guarded_fields_(parsed_function.guarded_fields()),
     deferred_prefixes_(parsed_function.deferred_prefixes()),
     captured_parameters_(new(zone()) BitVector(zone(), variable_count())),
     inlining_id_(-1) {
@@ -87,23 +89,6 @@
 }
 
 
-
-void FlowGraph::AddToGuardedFields(
-    ZoneGrowableArray<const Field*>* array,
-    const Field* field) {
-  if ((field->guarded_cid() == kDynamicCid) ||
-      (field->guarded_cid() == kIllegalCid)) {
-    return;
-  }
-  for (intptr_t j = 0; j < array->length(); j++) {
-    if ((*array)[j]->raw() == field->raw()) {
-      return;
-    }
-  }
-  array->Add(field);
-}
-
-
 void FlowGraph::AddToDeferredPrefixes(
     ZoneGrowableArray<const LibraryPrefix*>* from) {
   ZoneGrowableArray<const LibraryPrefix*>* to = deferred_prefixes();
@@ -1433,4 +1418,566 @@
       from->postorder_number());
 }
 
+
+// Quick access to the current zone.
+#define Z (zone())
+
+
+void FlowGraph::ConvertUse(Value* use, Representation from_rep) {
+  const Representation to_rep =
+      use->instruction()->RequiredInputRepresentation(use->use_index());
+  if (from_rep == to_rep || to_rep == kNoRepresentation) {
+    return;
+  }
+  InsertConversion(from_rep, to_rep, use, /*is_environment_use=*/ false);
+}
+
+
+static bool IsUnboxedInteger(Representation rep) {
+  return (rep == kUnboxedInt32) ||
+         (rep == kUnboxedUint32) ||
+         (rep == kUnboxedMint);
+}
+
+
+static bool ShouldInlineSimd() {
+  return FlowGraphCompiler::SupportsUnboxedSimd128();
+}
+
+
+static bool CanUnboxDouble() {
+  return FlowGraphCompiler::SupportsUnboxedDoubles();
+}
+
+
+static bool CanConvertUnboxedMintToDouble() {
+  return FlowGraphCompiler::CanConvertUnboxedMintToDouble();
+}
+
+
+void FlowGraph::InsertConversion(Representation from,
+                                 Representation to,
+                                 Value* use,
+                                 bool is_environment_use) {
+  Instruction* insert_before;
+  Instruction* deopt_target;
+  PhiInstr* phi = use->instruction()->AsPhi();
+  if (phi != NULL) {
+    ASSERT(phi->is_alive());
+    // For phis conversions have to be inserted in the predecessor.
+    insert_before =
+        phi->block()->PredecessorAt(use->use_index())->last_instruction();
+    deopt_target = NULL;
+  } else {
+    deopt_target = insert_before = use->instruction();
+  }
+
+  Definition* converted = NULL;
+  if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) {
+    const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != NULL) ?
+      deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+    converted = new(Z) UnboxedIntConverterInstr(from,
+                                                to,
+                                                use->CopyWithType(),
+                                                deopt_id);
+  } else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) {
+    converted = new Int32ToDoubleInstr(use->CopyWithType());
+  } else if ((from == kUnboxedMint) &&
+             (to == kUnboxedDouble) &&
+             CanConvertUnboxedMintToDouble()) {
+    const intptr_t deopt_id = (deopt_target != NULL) ?
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+    ASSERT(CanUnboxDouble());
+    converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id);
+  } else if ((from == kTagged) && Boxing::Supports(to)) {
+    const intptr_t deopt_id = (deopt_target != NULL) ?
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+    converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id);
+  } else if ((to == kTagged) && Boxing::Supports(from)) {
+    converted = BoxInstr::Create(from, use->CopyWithType());
+  } else {
+    // We have failed to find a suitable conversion instruction.
+    // Insert two "dummy" conversion instructions with the correct
+    // "from" and "to" representation. The inserted instructions will
+    // trigger a deoptimization if executed. See #12417 for a discussion.
+    const intptr_t deopt_id = (deopt_target != NULL) ?
+        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
+    ASSERT(Boxing::Supports(from));
+    ASSERT(Boxing::Supports(to));
+    Definition* boxed = BoxInstr::Create(from, use->CopyWithType());
+    use->BindTo(boxed);
+    InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
+    converted = UnboxInstr::Create(to, new(Z) Value(boxed), deopt_id);
+  }
+  ASSERT(converted != NULL);
+  InsertBefore(insert_before, converted, use->instruction()->env(),
+               FlowGraph::kValue);
+  if (is_environment_use) {
+    use->BindToEnvironment(converted);
+  } else {
+    use->BindTo(converted);
+  }
+
+  if ((to == kUnboxedInt32) && (phi != NULL)) {
+    // Int32 phis are unboxed optimistically. Ensure that unboxing
+    // has deoptimization target attached from the goto instruction.
+    CopyDeoptTarget(converted, insert_before);
+  }
+}
+
+
+void FlowGraph::ConvertEnvironmentUse(Value* use, Representation from_rep) {
+  const Representation to_rep = kTagged;
+  if (from_rep == to_rep) {
+    return;
+  }
+  InsertConversion(from_rep, to_rep, use, /*is_environment_use=*/ true);
+}
+
+
+void FlowGraph::InsertConversionsFor(Definition* def) {
+  const Representation from_rep = def->representation();
+
+  for (Value::Iterator it(def->input_use_list());
+       !it.Done();
+       it.Advance()) {
+    ConvertUse(it.Current(), from_rep);
+  }
+
+  if (graph_entry()->SuccessorCount() > 1) {
+    for (Value::Iterator it(def->env_use_list());
+         !it.Done();
+         it.Advance()) {
+      Value* use = it.Current();
+      if (use->instruction()->MayThrow() &&
+          use->instruction()->GetBlock()->InsideTryBlock()) {
+        // Environment uses at calls inside try-blocks must be converted to
+        // tagged representation.
+        ConvertEnvironmentUse(it.Current(), from_rep);
+      }
+    }
+  }
+}
+
+
+static void UnboxPhi(PhiInstr* phi) {
+  Representation unboxed = phi->representation();
+
+  switch (phi->Type()->ToCid()) {
+    case kDoubleCid:
+      if (CanUnboxDouble()) {
+        unboxed = kUnboxedDouble;
+      }
+      break;
+    case kFloat32x4Cid:
+      if (ShouldInlineSimd()) {
+        unboxed = kUnboxedFloat32x4;
+      }
+      break;
+    case kInt32x4Cid:
+      if (ShouldInlineSimd()) {
+        unboxed = kUnboxedInt32x4;
+      }
+      break;
+    case kFloat64x2Cid:
+      if (ShouldInlineSimd()) {
+        unboxed = kUnboxedFloat64x2;
+      }
+      break;
+  }
+
+  if ((kSmiBits < 32) &&
+      (unboxed == kTagged) &&
+      phi->Type()->IsInt() &&
+      RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt64)) {
+    // On 32-bit platforms conservatively unbox phis that:
+    //   - are proven to be of type Int;
+    //   - fit into 64bits range;
+    //   - have either constants or Box() operations as inputs;
+    //   - have at least one Box() operation as an input;
+    //   - are used in at least 1 Unbox() operation.
+    bool should_unbox = false;
+    for (intptr_t i = 0; i < phi->InputCount(); i++) {
+      Definition* input = phi->InputAt(i)->definition();
+      if (input->IsBox() &&
+          RangeUtils::Fits(input->range(),
+                           RangeBoundary::kRangeBoundaryInt64)) {
+        should_unbox = true;
+      } else if (!input->IsConstant()) {
+        should_unbox = false;
+        break;
+      }
+    }
+
+    if (should_unbox) {
+      // We checked inputs. Check if phi is used in at least one unbox
+      // operation.
+      bool has_unboxed_use = false;
+      for (Value* use = phi->input_use_list();
+           use != NULL;
+           use = use->next_use()) {
+        Instruction* instr = use->instruction();
+        if (instr->IsUnbox()) {
+          has_unboxed_use = true;
+          break;
+        } else if (IsUnboxedInteger(
+            instr->RequiredInputRepresentation(use->use_index()))) {
+          has_unboxed_use = true;
+          break;
+        }
+      }
+
+      if (!has_unboxed_use) {
+        should_unbox = false;
+      }
+    }
+
+    if (should_unbox) {
+      unboxed =
+          RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt32)
+          ? kUnboxedInt32 : kUnboxedMint;
+    }
+  }
+
+  phi->set_representation(unboxed);
+}
+
+
+void FlowGraph::SelectRepresentations() {
+  // Conservatively unbox all phis that were proven to be of Double,
+  // Float32x4, or Int32x4 type.
+  for (BlockIterator block_it = reverse_postorder_iterator();
+       !block_it.Done();
+       block_it.Advance()) {
+    JoinEntryInstr* join_entry = block_it.Current()->AsJoinEntry();
+    if (join_entry != NULL) {
+      for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
+        PhiInstr* phi = it.Current();
+        UnboxPhi(phi);
+      }
+    }
+  }
+
+  // Process all instructions and insert conversions where needed.
+  // Visit incoming parameters and constants.
+  for (intptr_t i = 0;
+       i < graph_entry()->initial_definitions()->length();
+       i++) {
+    InsertConversionsFor((*graph_entry()->initial_definitions())[i]);
+  }
+
+  for (BlockIterator block_it = reverse_postorder_iterator();
+       !block_it.Done();
+       block_it.Advance()) {
+    BlockEntryInstr* entry = block_it.Current();
+    JoinEntryInstr* join_entry = entry->AsJoinEntry();
+    if (join_entry != NULL) {
+      for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
+        PhiInstr* phi = it.Current();
+        ASSERT(phi != NULL);
+        ASSERT(phi->is_alive());
+        InsertConversionsFor(phi);
+      }
+    }
+    CatchBlockEntryInstr* catch_entry = entry->AsCatchBlockEntry();
+    if (catch_entry != NULL) {
+      for (intptr_t i = 0;
+           i < catch_entry->initial_definitions()->length();
+           i++) {
+        InsertConversionsFor((*catch_entry->initial_definitions())[i]);
+      }
+    }
+    for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
+      Definition* def = it.Current()->AsDefinition();
+      if (def != NULL) {
+        InsertConversionsFor(def);
+      }
+    }
+  }
+}
+
+
+#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32)
+// Smi widening pass is only meaningful on platforms where Smi
+// is smaller than 32bit. For now only support it on ARM and ia32.
+static bool CanBeWidened(BinarySmiOpInstr* smi_op) {
+  return BinaryInt32OpInstr::IsSupported(smi_op->op_kind(),
+                                         smi_op->left(),
+                                         smi_op->right());
+}
+
+
+static bool BenefitsFromWidening(BinarySmiOpInstr* smi_op) {
+  // TODO(vegorov): when shifts with non-constants shift count are supported
+  // add them here as we save untagging for the count.
+  switch (smi_op->op_kind()) {
+    case Token::kMUL:
+    case Token::kSHR:
+      // For kMUL we save untagging of the argument for kSHR
+      // we save tagging of the result.
+      return true;
+
+    default:
+      return false;
+  }
+}
+
+
+void FlowGraph::WidenSmiToInt32() {
+  GrowableArray<BinarySmiOpInstr*> candidates;
+
+  // Step 1. Collect all instructions that potentially benefit from widening of
+  // their operands (or their result) into int32 range.
+  for (BlockIterator block_it = reverse_postorder_iterator();
+       !block_it.Done();
+       block_it.Advance()) {
+    for (ForwardInstructionIterator instr_it(block_it.Current());
+         !instr_it.Done();
+         instr_it.Advance()) {
+      BinarySmiOpInstr* smi_op = instr_it.Current()->AsBinarySmiOp();
+      if ((smi_op != NULL) &&
+          smi_op->HasSSATemp() &&
+          BenefitsFromWidening(smi_op) &&
+          CanBeWidened(smi_op)) {
+        candidates.Add(smi_op);
+      }
+    }
+  }
+
+  if (candidates.is_empty()) {
+    return;
+  }
+
+  // Step 2. For each block in the graph compute which loop it belongs to.
+  // We will use this information later during computation of the widening's
+  // gain: we are going to assume that only conversion occuring inside the
+  // same loop should be counted against the gain, all other conversions
+  // can be hoisted and thus cost nothing compared to the loop cost itself.
+  const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = LoopHeaders();
+
+  GrowableArray<intptr_t> loops(preorder().length());
+  for (intptr_t i = 0; i < preorder().length(); i++) {
+    loops.Add(-1);
+  }
+
+  for (intptr_t loop_id = 0; loop_id < loop_headers.length(); ++loop_id) {
+    for (BitVector::Iterator loop_it(loop_headers[loop_id]->loop_info());
+         !loop_it.Done();
+         loop_it.Advance()) {
+      loops[loop_it.Current()] = loop_id;
+    }
+  }
+
+  // Step 3. For each candidate transitively collect all other BinarySmiOpInstr
+  // and PhiInstr that depend on it and that it depends on and count amount of
+  // untagging operations that we save in assumption that this whole graph of
+  // values is using kUnboxedInt32 representation instead of kTagged.
+  // Convert those graphs that have positive gain to kUnboxedInt32.
+
+  // BitVector containing SSA indexes of all processed definitions. Used to skip
+  // those candidates that belong to dependency graph of another candidate.
+  BitVector* processed =
+      new(Z) BitVector(Z, current_ssa_temp_index());
+
+  // Worklist used to collect dependency graph.
+  DefinitionWorklist worklist(this, candidates.length());
+  for (intptr_t i = 0; i < candidates.length(); i++) {
+    BinarySmiOpInstr* op = candidates[i];
+    if (op->WasEliminated() || processed->Contains(op->ssa_temp_index())) {
+      continue;
+    }
+
+    if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+      THR_Print("analysing candidate: %s\n", op->ToCString());
+    }
+    worklist.Clear();
+    worklist.Add(op);
+
+    // Collect dependency graph. Note: more items are added to worklist
+    // inside this loop.
+    intptr_t gain = 0;
+    for (intptr_t j = 0; j < worklist.definitions().length(); j++) {
+      Definition* defn = worklist.definitions()[j];
+
+      if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+        THR_Print("> %s\n", defn->ToCString());
+      }
+
+      if (defn->IsBinarySmiOp() &&
+          BenefitsFromWidening(defn->AsBinarySmiOp())) {
+        gain++;
+        if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+          THR_Print("^ [%" Pd "] (o) %s\n", gain, defn->ToCString());
+        }
+      }
+
+      const intptr_t defn_loop = loops[defn->GetBlock()->preorder_number()];
+
+      // Process all inputs.
+      for (intptr_t k = 0; k < defn->InputCount(); k++) {
+        Definition* input = defn->InputAt(k)->definition();
+        if (input->IsBinarySmiOp() &&
+            CanBeWidened(input->AsBinarySmiOp())) {
+          worklist.Add(input);
+        } else if (input->IsPhi() && (input->Type()->ToCid() == kSmiCid)) {
+          worklist.Add(input);
+        } else if (input->IsBinaryMintOp()) {
+          // Mint operation produces untagged result. We avoid tagging.
+          gain++;
+          if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+            THR_Print("^ [%" Pd "] (i) %s\n", gain, input->ToCString());
+          }
+        } else if (defn_loop == loops[input->GetBlock()->preorder_number()] &&
+                   (input->Type()->ToCid() == kSmiCid)) {
+          // Input comes from the same loop, is known to be smi and requires
+          // untagging.
+          // TODO(vegorov) this heuristic assumes that values that are not
+          // known to be smi have to be checked and this check can be
+          // coalesced with untagging. Start coalescing them.
+          gain--;
+          if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+            THR_Print("v [%" Pd "] (i) %s\n", gain, input->ToCString());
+          }
+        }
+      }
+
+      // Process all uses.
+      for (Value* use = defn->input_use_list();
+           use != NULL;
+           use = use->next_use()) {
+        Instruction* instr = use->instruction();
+        Definition* use_defn = instr->AsDefinition();
+        if (use_defn == NULL) {
+          // We assume that tagging before returning or pushing argument costs
+          // very little compared to the cost of the return/call itself.
+          if (!instr->IsReturn() && !instr->IsPushArgument()) {
+            gain--;
+            if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+              THR_Print("v [%" Pd "] (u) %s\n",
+                        gain,
+                        use->instruction()->ToCString());
+            }
+          }
+          continue;
+        } else if (use_defn->IsBinarySmiOp() &&
+                   CanBeWidened(use_defn->AsBinarySmiOp())) {
+          worklist.Add(use_defn);
+        } else if (use_defn->IsPhi() &&
+                   use_defn->AsPhi()->Type()->ToCid() == kSmiCid) {
+          worklist.Add(use_defn);
+        } else if (use_defn->IsBinaryMintOp()) {
+          // BinaryMintOp requires untagging of its inputs.
+          // Converting kUnboxedInt32 to kUnboxedMint is essentially zero cost
+          // sign extension operation.
+          gain++;
+          if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+            THR_Print("^ [%" Pd "] (u) %s\n",
+                      gain,
+                      use->instruction()->ToCString());
+          }
+        } else if (defn_loop == loops[instr->GetBlock()->preorder_number()]) {
+          gain--;
+          if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+            THR_Print("v [%" Pd "] (u) %s\n",
+                      gain,
+                      use->instruction()->ToCString());
+          }
+        }
+      }
+    }
+
+    processed->AddAll(worklist.contains_vector());
+
+    if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
+      THR_Print("~ %s gain %" Pd "\n", op->ToCString(), gain);
+    }
+
+    if (gain > 0) {
+      // We have positive gain from widening. Convert all BinarySmiOpInstr into
+      // BinaryInt32OpInstr and set representation of all phis to kUnboxedInt32.
+      for (intptr_t j = 0; j < worklist.definitions().length(); j++) {
+        Definition* defn = worklist.definitions()[j];
+        ASSERT(defn->IsPhi() || defn->IsBinarySmiOp());
+
+        if (defn->IsBinarySmiOp()) {
+          BinarySmiOpInstr* smi_op = defn->AsBinarySmiOp();
+          BinaryInt32OpInstr* int32_op = new(Z) BinaryInt32OpInstr(
+            smi_op->op_kind(),
+            smi_op->left()->CopyWithType(),
+            smi_op->right()->CopyWithType(),
+            smi_op->DeoptimizationTarget());
+
+          smi_op->ReplaceWith(int32_op, NULL);
+        } else if (defn->IsPhi()) {
+          defn->AsPhi()->set_representation(kUnboxedInt32);
+          ASSERT(defn->Type()->IsInt());
+        }
+      }
+    }
+  }
+}
+#else
+void FlowGraph::WidenSmiToInt32() {
+  // TODO(vegorov) ideally on 64-bit platforms we would like to narrow smi
+  // operations to 32-bit where it saves tagging and untagging and allows
+  // to use shorted (and faster) instructions. But we currently don't
+  // save enough range information in the ICData to drive this decision.
+}
+#endif
+
+
+void FlowGraph::EliminateEnvironments() {
+  // After this pass we can no longer perform LICM and hoist instructions
+  // that can deoptimize.
+
+  disallow_licm();
+  for (BlockIterator block_it = reverse_postorder_iterator();
+       !block_it.Done();
+       block_it.Advance()) {
+    BlockEntryInstr* block = block_it.Current();
+    block->RemoveEnvironment();
+    for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
+      Instruction* current = it.Current();
+      if (!current->CanDeoptimize()) {
+        // TODO(srdjan): --source-lines needs deopt environments to get at
+        // the code for this instruction, however, leaving the environment
+        // changes code.
+        current->RemoveEnvironment();
+      }
+    }
+  }
+}
+
+
+bool FlowGraph::Canonicalize() {
+  bool changed = false;
+
+  for (BlockIterator block_it = reverse_postorder_iterator();
+       !block_it.Done();
+       block_it.Advance()) {
+    for (ForwardInstructionIterator it(block_it.Current());
+         !it.Done();
+         it.Advance()) {
+      Instruction* current = it.Current();
+      if (current->HasUnmatchedInputRepresentations()) {
+        // Can't canonicalize this instruction until all conversions for its
+        // inputs are inserted.
+        continue;
+      }
+
+      Instruction* replacement = current->Canonicalize(this);
+
+      if (replacement != current) {
+        // For non-definitions Canonicalize should return either NULL or
+        // this.
+        ASSERT((replacement == NULL) || current->IsDefinition());
+        ReplaceCurrentInstruction(&it, current, replacement);
+        changed = true;
+      }
+    }
+  }
+  return changed;
+}
+
+
 }  // namespace dart
diff --git a/runtime/vm/flow_graph.h b/runtime/vm/flow_graph.h
index 9841716..d4d9d2f 100644
--- a/runtime/vm/flow_graph.h
+++ b/runtime/vm/flow_graph.h
@@ -277,14 +277,8 @@
 
   bool IsCompiledForOsr() const { return graph_entry()->IsCompiledForOsr(); }
 
-  static void AddToGuardedFields(ZoneGrowableArray<const Field*>* array,
-                                 const Field* field);
   void AddToDeferredPrefixes(ZoneGrowableArray<const LibraryPrefix*>* from);
 
-  ZoneGrowableArray<const Field*>* guarded_fields() const {
-    return guarded_fields_;
-  }
-
   ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes() const {
     return deferred_prefixes_;
   }
@@ -296,6 +290,16 @@
   intptr_t inlining_id() const { return inlining_id_; }
   void set_inlining_id(intptr_t value) { inlining_id_ = value; }
 
+  // Returns true if any instructions were canonicalized away.
+  bool Canonicalize();
+
+  void SelectRepresentations();
+
+  void WidenSmiToInt32();
+
+  // Remove environments from the instructions which do not deoptimize.
+  void EliminateEnvironments();
+
  private:
   friend class IfConverter;
   friend class BranchSimplifier;
@@ -340,6 +344,14 @@
   // indicates membership in the loop.
   BitVector* FindLoop(BlockEntryInstr* m, BlockEntryInstr* n) const;
 
+  void InsertConversionsFor(Definition* def);
+  void ConvertUse(Value* use, Representation from);
+  void ConvertEnvironmentUse(Value* use, Representation from);
+  void InsertConversion(Representation from,
+                        Representation to,
+                        Value* use,
+                        bool is_environment_use);
+
   Thread* thread_;
 
   // DiscoverBlocks computes parent_ and assigned_vars_ which are then used
@@ -368,7 +380,6 @@
 
   ZoneGrowableArray<BlockEntryInstr*>* loop_headers_;
   ZoneGrowableArray<BitVector*>* loop_invariant_loads_;
-  ZoneGrowableArray<const Field*>* guarded_fields_;
   ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes_;
   DirectChainedHashMap<ConstantPoolTrait> constant_instr_pool_;
   BitVector* captured_parameters_;
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 458557d..736efc6 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -3672,7 +3672,7 @@
         (node->field().guarded_cid() == kNullCid)) {
       load->set_result_cid(node->field().guarded_cid());
     }
-    FlowGraph::AddToGuardedFields(owner()->guarded_fields(), &node->field());
+    owner()->parsed_function().AddToGuardedFields(&node->field());
   }
   ReturnDefinition(load);
 }
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 27062d6..474bc4f 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -153,10 +153,6 @@
   bool IsInlining() const { return (exit_collector_ != NULL); }
   InlineExitCollector* exit_collector() const { return exit_collector_; }
 
-  ZoneGrowableArray<const Field*>* guarded_fields() const {
-    return parsed_function_.guarded_fields();
-  }
-
   ZoneGrowableArray<const LibraryPrefix*>* deferred_prefixes() const {
     return parsed_function_.deferred_prefixes();
   }
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index ef109ac..d646909 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -13,6 +13,7 @@
 #include "vm/debugger.h"
 #include "vm/deopt_instructions.h"
 #include "vm/exceptions.h"
+#include "vm/flags.h"
 #include "vm/flow_graph_allocator.h"
 #include "vm/il_printer.h"
 #include "vm/intrinsifier.h"
@@ -39,9 +40,6 @@
     "The minimum invocation count for a function.");
 DEFINE_FLAG(int, optimization_counter_scale, 2000,
     "The scale of invocation count, by size of the function.");
-DEFINE_FLAG(bool, polymorphic_with_deopt, true,
-    "Polymorphic calls can be generated so that failure either causes "
-    "deoptimization or falls through to a megamorphic call");
 DEFINE_FLAG(bool, source_lines, false, "Emit source line as assembly comment.");
 DEFINE_FLAG(bool, trace_inlining_intervals, false,
     "Inlining interval diagnostics");
@@ -65,12 +63,9 @@
 DECLARE_FLAG(int, stacktrace_every);
 DECLARE_FLAG(charp, stacktrace_filter);
 DECLARE_FLAG(bool, use_field_guards);
-DECLARE_FLAG(bool, use_cha_deopt);
 DECLARE_FLAG(bool, use_osr);
 DECLARE_FLAG(bool, print_stop_message);
-DECLARE_FLAG(bool, lazy_dispatchers);
 DECLARE_FLAG(bool, interpret_irregexp);
-DECLARE_FLAG(bool, enable_mirrors);
 DECLARE_FLAG(bool, link_natives_lazily);
 DECLARE_FLAG(bool, trace_compiler);
 DECLARE_FLAG(int, inlining_hotness);
@@ -91,29 +86,26 @@
     FLAG_precompilation = true;
 
     FLAG_always_megamorphic_calls = true;
-    FLAG_polymorphic_with_deopt = false;
     FLAG_optimization_counter_threshold = -1;
     FLAG_use_field_guards = false;
     FLAG_use_osr = false;
     FLAG_emit_edge_counters = false;
 #ifndef PRODUCT
     FLAG_support_debugger = false;
-#endif
+#endif  // !PRODUCT
     FLAG_ic_range_profiling = false;
     FLAG_collect_code = false;
     FLAG_load_deferred_eagerly = true;
     FLAG_deoptimize_alot = false;  // Used in some tests.
     FLAG_deoptimize_every = 0;     // Used in some tests.
-    // Precompilation finalizes all classes and thus allows CHA optimizations.
-    // Do not require CHA triggered deoptimization.
-    FLAG_use_cha_deopt = false;
     // Calling the PrintStopMessage stub is not supported in precompiled code
     // since it is done at places where no pool pointer is loaded.
     FLAG_print_stop_message = false;
 
-    FLAG_lazy_dispatchers = false;
     FLAG_interpret_irregexp = true;
+#ifndef PRODUCT
     FLAG_enable_mirrors = false;
+#endif  // !PRODUCT
     FLAG_link_natives_lazily = true;
     FLAG_fields_may_be_reset = true;
     FLAG_allow_absolute_addresses = false;
@@ -136,6 +128,23 @@
     // while precompilation has only one.
     FLAG_background_compilation = false;
     FLAG_collect_dynamic_function_names = true;
+#if !defined(DART_PRECOMPILED_RUNTIME) && !defined(PRODUCT)
+    FLAG_lazy_dispatchers = false;
+    FLAG_polymorphic_with_deopt = false;
+    // Precompilation finalizes all classes and thus allows CHA optimizations.
+    // Do not require CHA triggered deoptimization.
+    FLAG_use_cha_deopt = false;
+#elif defined(DART_PRECOMPILED_RUNTIME)
+    // Precompiled product and release mode.
+    COMPILE_ASSERT(!FLAG_lazy_dispatchers);
+    COMPILE_ASSERT(!FLAG_polymorphic_with_deopt);
+    COMPILE_ASSERT(!FLAG_use_cha_deopt);
+#elif defined(PRODUCT)
+    // Jit product and release mode.
+    COMPILE_ASSERT(FLAG_lazy_dispatchers);
+    COMPILE_ASSERT(FLAG_polymorphic_with_deopt);
+    COMPILE_ASSERT(FLAG_use_cha_deopt);
+#endif
   }
 }
 
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index 57bff29..7a1e156 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -311,6 +311,7 @@
   static bool SupportsSinCos();
   static bool SupportsUnboxedSimd128();
   static bool SupportsHardwareDivision();
+  static bool CanConvertUnboxedMintToDouble();
 
   static bool IsUnboxedField(const Field& field);
   static bool IsPotentialUnboxedField(const Field& field);
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 4eb7f3f..2b14545 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -78,6 +78,13 @@
 }
 
 
+bool FlowGraphCompiler::CanConvertUnboxedMintToDouble() {
+  // ARM does not have a short instruction sequence for converting int64 to
+  // double.
+  return false;
+}
+
+
 void FlowGraphCompiler::EnterIntrinsicMode() {
   ASSERT(!intrinsic_mode());
   intrinsic_mode_ = true;
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 2a237d9..30e4211 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -70,6 +70,13 @@
 }
 
 
+bool FlowGraphCompiler::CanConvertUnboxedMintToDouble() {
+  // ARM does not have a short instruction sequence for converting int64 to
+  // double.
+  return false;
+}
+
+
 bool FlowGraphCompiler::SupportsHardwareDivision() {
   return true;
 }
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 0476344..3ae8998 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -81,6 +81,11 @@
 }
 
 
+bool FlowGraphCompiler::CanConvertUnboxedMintToDouble() {
+  return true;
+}
+
+
 void FlowGraphCompiler::EnterIntrinsicMode() {
   ASSERT(!intrinsic_mode());
   intrinsic_mode_ = true;
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index f9777c0..273a0e0 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -73,6 +73,13 @@
 }
 
 
+bool FlowGraphCompiler::CanConvertUnboxedMintToDouble() {
+  // TODO(johnmccutchan): Investigate possibility on MIPS once
+  // mints are implemented there.
+  return false;
+}
+
+
 void FlowGraphCompiler::EnterIntrinsicMode() {
   ASSERT(!intrinsic_mode());
   intrinsic_mode_ = true;
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index b922bb8..49aeed8 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -77,6 +77,11 @@
 }
 
 
+bool FlowGraphCompiler::CanConvertUnboxedMintToDouble() {
+  return false;
+}
+
+
 void FlowGraphCompiler::EnterIntrinsicMode() {
   ASSERT(!intrinsic_mode());
   intrinsic_mode_ = true;
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index f2fd49d..9956af3 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -4,6 +4,7 @@
 
 #include "vm/flow_graph_inliner.h"
 
+#include "vm/aot_optimizer.h"
 #include "vm/block_scheduler.h"
 #include "vm/branch_optimizer.h"
 #include "vm/compiler.h"
@@ -61,7 +62,6 @@
 
 DECLARE_FLAG(bool, compiler_stats);
 DECLARE_FLAG(int, max_deoptimization_counter_threshold);
-DECLARE_FLAG(bool, polymorphic_with_deopt);
 DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(bool, print_flow_graph_optimized);
@@ -790,10 +790,10 @@
           CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer);
           // TODO(fschneider): Improve suppression of speculative inlining.
           // Deopt-ids overlap between caller and callee.
-          FlowGraphOptimizer optimizer(callee_graph,
-                                       inliner_->use_speculative_inlining_,
-                                       inliner_->inlining_black_list_);
           if (FLAG_precompilation) {
+            AotOptimizer optimizer(callee_graph,
+                                   inliner_->use_speculative_inlining_,
+                                   inliner_->inlining_black_list_);
             optimizer.PopulateWithICData();
 
             optimizer.ApplyClassIds();
@@ -801,14 +801,26 @@
 
             FlowGraphTypePropagator::Propagate(callee_graph);
             DEBUG_ASSERT(callee_graph->VerifyUseLists());
-          }
-          optimizer.ApplyICData();
-          DEBUG_ASSERT(callee_graph->VerifyUseLists());
 
-          // Optimize (a << b) & c patterns, merge instructions. Must occur
-          // before 'SelectRepresentations' which inserts conversion nodes.
-          optimizer.TryOptimizePatterns();
-          DEBUG_ASSERT(callee_graph->VerifyUseLists());
+            optimizer.ApplyICData();
+            DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
+            // Optimize (a << b) & c patterns, merge instructions. Must occur
+            // before 'SelectRepresentations' which inserts conversion nodes.
+            optimizer.TryOptimizePatterns();
+            DEBUG_ASSERT(callee_graph->VerifyUseLists());
+          } else {
+            FlowGraphOptimizer optimizer(callee_graph,
+                                         inliner_->use_speculative_inlining_,
+                                         inliner_->inlining_black_list_);
+            optimizer.ApplyICData();
+            DEBUG_ASSERT(callee_graph->VerifyUseLists());
+
+            // Optimize (a << b) & c patterns, merge instructions. Must occur
+            // before 'SelectRepresentations' which inserts conversion nodes.
+            optimizer.TryOptimizePatterns();
+            DEBUG_ASSERT(callee_graph->VerifyUseLists());
+          }
         }
 
         if (FLAG_support_il_printer && FLAG_trace_inlining &&
@@ -881,11 +893,11 @@
 
         // When inlined, we add the guarded fields of the callee to the caller's
         // list of guarded fields.
-        for (intptr_t i = 0;
-             i < callee_graph->guarded_fields()->length();
-             ++i) {
-          FlowGraph::AddToGuardedFields(caller_graph_->guarded_fields(),
-                                        (*callee_graph->guarded_fields())[i]);
+        const ZoneGrowableArray<const Field*>& callee_guarded_fields =
+            *callee_graph->parsed_function().guarded_fields();
+        for (intptr_t i = 0; i < callee_guarded_fields.length(); ++i) {
+          caller_graph()->
+              parsed_function().AddToGuardedFields(callee_guarded_fields[i]);
         }
         // When inlined, we add the deferred prefixes of the callee to the
         // caller's list of deferred prefixes.
@@ -1508,9 +1520,6 @@
 
 bool PolymorphicInliner::TryInlineRecognizedMethod(intptr_t receiver_cid,
                                                    const Function& target) {
-  FlowGraphOptimizer optimizer(owner_->caller_graph(),
-                               false,  // Speculative inlining not applicable.
-                               NULL);
   TargetEntryInstr* entry;
   Definition* last;
   // Replace the receiver argument with a redefinition to prevent code from
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index b4c3a2a..fa5649f 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -20,7 +20,6 @@
 #include "vm/intermediate_language.h"
 #include "vm/object_store.h"
 #include "vm/parser.h"
-#include "vm/precompiler.h"
 #include "vm/resolver.h"
 #include "vm/scopes.h"
 #include "vm/stack_frame.h"
@@ -28,31 +27,6 @@
 
 namespace dart {
 
-DEFINE_FLAG(int, getter_setter_ratio, 13,
-    "Ratio of getter/setter usage used for double field unboxing heuristics");
-DEFINE_FLAG(bool, guess_icdata_cid, true,
-    "Artificially create type feedback for arithmetic etc. operations"
-    " by guessing the other unknown argument cid");
-DEFINE_FLAG(int, max_polymorphic_checks, 4,
-    "Maximum number of polymorphic check, otherwise it is megamorphic.");
-DEFINE_FLAG(int, max_equality_polymorphic_checks, 32,
-    "Maximum number of polymorphic checks in equality operator,"
-    " otherwise use megamorphic dispatch.");
-DEFINE_FLAG(bool, merge_sin_cos, false, "Merge sin/cos into sincos");
-DEFINE_FLAG(bool, trace_optimization, false, "Print optimization details.");
-DEFINE_FLAG(bool, truncating_left_shift, true,
-    "Optimize left shift to truncate if possible");
-DEFINE_FLAG(bool, use_cha_deopt, true,
-    "Use class hierarchy analysis even if it can cause deoptimization.");
-#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32)
-DEFINE_FLAG(bool, trace_smi_widening, false, "Trace Smi->Int32 widening pass.");
-#endif
-
-DECLARE_FLAG(bool, precompilation);
-DECLARE_FLAG(bool, polymorphic_with_deopt);
-DECLARE_FLAG(bool, trace_cha);
-DECLARE_FLAG(bool, trace_field_guards);
-
 // Quick access to the current isolate and zone.
 #define I (isolate())
 #define Z (zone())
@@ -68,15 +42,7 @@
 
 
 static bool CanConvertUnboxedMintToDouble() {
-#if defined(TARGET_ARCH_IA32)
-  return true;
-#else
-  // ARM does not have a short instruction sequence for converting int64 to
-  // double.
-  // TODO(johnmccutchan): Investigate possibility on MIPS once
-  // mints are implemented there.
-  return false;
-#endif
+  return FlowGraphCompiler::CanConvertUnboxedMintToDouble();
 }
 
 
@@ -86,34 +52,6 @@
 }
 
 
-void FlowGraphOptimizer::PopulateWithICData() {
-  ASSERT(current_iterator_ == NULL);
-  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
-       !block_it.Done();
-       block_it.Advance()) {
-    ForwardInstructionIterator it(block_it.Current());
-    for (; !it.Done(); it.Advance()) {
-      Instruction* instr = it.Current();
-      if (instr->IsInstanceCall()) {
-        InstanceCallInstr* call = instr->AsInstanceCall();
-        if (!call->HasICData()) {
-          const Array& arguments_descriptor =
-              Array::Handle(zone(),
-                  ArgumentsDescriptor::New(call->ArgumentCount(),
-                                           call->argument_names()));
-          const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New(
-              function(), call->function_name(),
-              arguments_descriptor, call->deopt_id(),
-              call->checked_argument_count()));
-          call->set_ic_data(&ic_data);
-        }
-      }
-    }
-    current_iterator_ = NULL;
-  }
-}
-
-
 // Optimize instance calls using cid.  This is called after optimizer
 // converted instance calls to instructions. Any remaining
 // instance calls are either megamorphic calls, cannot be optimized or
@@ -138,13 +76,6 @@
         }
       } else if (instr->IsPolymorphicInstanceCall()) {
         SpecializePolymorphicInstanceCall(instr->AsPolymorphicInstanceCall());
-      } else if (instr->IsStrictCompare()) {
-        VisitStrictCompare(instr->AsStrictCompare());
-      } else if (instr->IsBranch()) {
-        ComparisonInstr* compare = instr->AsBranch()->comparison();
-        if (compare->IsStrictCompare()) {
-          VisitStrictCompare(compare->AsStrictCompare());
-        }
       }
     }
     current_iterator_ = NULL;
@@ -214,7 +145,8 @@
         Resolver::ResolveDynamicForReceiverClass(
             receiver_class,
             call->function_name(),
-            args_desc));
+            args_desc,
+            false /* allow add */));
     if (function.IsNull()) {
       return false;
     }
@@ -235,29 +167,6 @@
     return true;
   }
 
-#ifdef DART_PRECOMPILER
-  if (FLAG_precompilation &&
-      (isolate()->object_store()->unique_dynamic_targets() != Array::null())) {
-    // Check if the target is unique.
-    Function& target_function = Function::Handle(Z);
-    Precompiler::GetUniqueDynamicTarget(
-        isolate(), call->function_name(), &target_function);
-    // Calls with named arguments must be resolved/checked at runtime.
-    String& error_message = String::Handle(Z);
-    if (!target_function.IsNull() &&
-        !target_function.HasOptionalNamedParameters() &&
-        target_function.AreValidArgumentCounts(call->ArgumentCount(), 0,
-                                               &error_message)) {
-      const intptr_t cid = Class::Handle(Z, target_function.Owner()).id();
-      const ICData& ic_data = ICData::ZoneHandle(Z,
-          ICData::NewFrom(*call->ic_data(), 1));
-      ic_data.AddReceiverCheck(cid, target_function);
-      call->set_ic_data(&ic_data);
-      return true;
-    }
-  }
-#endif
-
   // Check if getter or setter in function's class and class is currently leaf.
   if (FLAG_guess_icdata_cid &&
       ((call->token_kind() == Token::kGET) ||
@@ -273,7 +182,8 @@
       const Function& function = Function::Handle(Z,
           Resolver::ResolveDynamicForReceiverClass(owner_class,
                                                    call->function_name(),
-                                                   args_desc));
+                                                   args_desc,
+                                                   false /* allow_add */));
       if (!function.IsNull()) {
         const ICData& ic_data = ICData::ZoneHandle(Z,
             ICData::NewFrom(*call->ic_data(), class_ids.length()));
@@ -603,297 +513,6 @@
 }
 
 
-bool FlowGraphOptimizer::Canonicalize() {
-  bool changed = false;
-
-  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
-       !block_it.Done();
-       block_it.Advance()) {
-    for (ForwardInstructionIterator it(block_it.Current());
-         !it.Done();
-         it.Advance()) {
-      Instruction* current = it.Current();
-      if (current->HasUnmatchedInputRepresentations()) {
-        // Can't canonicalize this instruction until all conversions for its
-        // inputs are inserted.
-        continue;
-      }
-
-      Instruction* replacement = current->Canonicalize(flow_graph());
-
-      if (replacement != current) {
-        // For non-definitions Canonicalize should return either NULL or
-        // this.
-        ASSERT((replacement == NULL) || current->IsDefinition());
-        flow_graph_->ReplaceCurrentInstruction(&it, current, replacement);
-        changed = true;
-      }
-    }
-  }
-  return changed;
-}
-
-
-static bool IsUnboxedInteger(Representation rep) {
-  return (rep == kUnboxedInt32) ||
-         (rep == kUnboxedUint32) ||
-         (rep == kUnboxedMint);
-}
-
-
-void FlowGraphOptimizer::InsertConversion(Representation from,
-                                          Representation to,
-                                          Value* use,
-                                          bool is_environment_use) {
-  Instruction* insert_before;
-  Instruction* deopt_target;
-  PhiInstr* phi = use->instruction()->AsPhi();
-  if (phi != NULL) {
-    ASSERT(phi->is_alive());
-    // For phis conversions have to be inserted in the predecessor.
-    insert_before =
-        phi->block()->PredecessorAt(use->use_index())->last_instruction();
-    deopt_target = NULL;
-  } else {
-    deopt_target = insert_before = use->instruction();
-  }
-
-  Definition* converted = NULL;
-  if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) {
-    const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != NULL) ?
-      deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
-    converted = new(Z) UnboxedIntConverterInstr(from,
-                                                to,
-                                                use->CopyWithType(),
-                                                deopt_id);
-  } else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) {
-    converted = new Int32ToDoubleInstr(use->CopyWithType());
-  } else if ((from == kUnboxedMint) &&
-             (to == kUnboxedDouble) &&
-             CanConvertUnboxedMintToDouble()) {
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
-    ASSERT(CanUnboxDouble());
-    converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id);
-  } else if ((from == kTagged) && Boxing::Supports(to)) {
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
-    converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id);
-  } else if ((to == kTagged) && Boxing::Supports(from)) {
-    converted = BoxInstr::Create(from, use->CopyWithType());
-  } else {
-    // We have failed to find a suitable conversion instruction.
-    // Insert two "dummy" conversion instructions with the correct
-    // "from" and "to" representation. The inserted instructions will
-    // trigger a deoptimization if executed. See #12417 for a discussion.
-    const intptr_t deopt_id = (deopt_target != NULL) ?
-        deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId;
-    ASSERT(Boxing::Supports(from));
-    ASSERT(Boxing::Supports(to));
-    Definition* boxed = BoxInstr::Create(from, use->CopyWithType());
-    use->BindTo(boxed);
-    InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue);
-    converted = UnboxInstr::Create(to, new(Z) Value(boxed), deopt_id);
-  }
-  ASSERT(converted != NULL);
-  InsertBefore(insert_before, converted, use->instruction()->env(),
-               FlowGraph::kValue);
-  if (is_environment_use) {
-    use->BindToEnvironment(converted);
-  } else {
-    use->BindTo(converted);
-  }
-
-  if ((to == kUnboxedInt32) && (phi != NULL)) {
-    // Int32 phis are unboxed optimistically. Ensure that unboxing
-    // has deoptimization target attached from the goto instruction.
-    flow_graph_->CopyDeoptTarget(converted, insert_before);
-  }
-}
-
-
-void FlowGraphOptimizer::ConvertUse(Value* use, Representation from_rep) {
-  const Representation to_rep =
-      use->instruction()->RequiredInputRepresentation(use->use_index());
-  if (from_rep == to_rep || to_rep == kNoRepresentation) {
-    return;
-  }
-  InsertConversion(from_rep, to_rep, use, /*is_environment_use=*/ false);
-}
-
-
-void FlowGraphOptimizer::ConvertEnvironmentUse(Value* use,
-                                               Representation from_rep) {
-  const Representation to_rep = kTagged;
-  if (from_rep == to_rep) {
-    return;
-  }
-  InsertConversion(from_rep, to_rep, use, /*is_environment_use=*/ true);
-}
-
-
-void FlowGraphOptimizer::InsertConversionsFor(Definition* def) {
-  const Representation from_rep = def->representation();
-
-  for (Value::Iterator it(def->input_use_list());
-       !it.Done();
-       it.Advance()) {
-    ConvertUse(it.Current(), from_rep);
-  }
-
-  if (flow_graph()->graph_entry()->SuccessorCount() > 1) {
-    for (Value::Iterator it(def->env_use_list());
-         !it.Done();
-         it.Advance()) {
-      Value* use = it.Current();
-      if (use->instruction()->MayThrow() &&
-          use->instruction()->GetBlock()->InsideTryBlock()) {
-        // Environment uses at calls inside try-blocks must be converted to
-        // tagged representation.
-        ConvertEnvironmentUse(it.Current(), from_rep);
-      }
-    }
-  }
-}
-
-
-static void UnboxPhi(PhiInstr* phi) {
-  Representation unboxed = phi->representation();
-
-  switch (phi->Type()->ToCid()) {
-    case kDoubleCid:
-      if (CanUnboxDouble()) {
-        unboxed = kUnboxedDouble;
-      }
-      break;
-    case kFloat32x4Cid:
-      if (ShouldInlineSimd()) {
-        unboxed = kUnboxedFloat32x4;
-      }
-      break;
-    case kInt32x4Cid:
-      if (ShouldInlineSimd()) {
-        unboxed = kUnboxedInt32x4;
-      }
-      break;
-    case kFloat64x2Cid:
-      if (ShouldInlineSimd()) {
-        unboxed = kUnboxedFloat64x2;
-      }
-      break;
-  }
-
-  if ((kSmiBits < 32) &&
-      (unboxed == kTagged) &&
-      phi->Type()->IsInt() &&
-      RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt64)) {
-    // On 32-bit platforms conservatively unbox phis that:
-    //   - are proven to be of type Int;
-    //   - fit into 64bits range;
-    //   - have either constants or Box() operations as inputs;
-    //   - have at least one Box() operation as an input;
-    //   - are used in at least 1 Unbox() operation.
-    bool should_unbox = false;
-    for (intptr_t i = 0; i < phi->InputCount(); i++) {
-      Definition* input = phi->InputAt(i)->definition();
-      if (input->IsBox() &&
-          RangeUtils::Fits(input->range(),
-                           RangeBoundary::kRangeBoundaryInt64)) {
-        should_unbox = true;
-      } else if (!input->IsConstant()) {
-        should_unbox = false;
-        break;
-      }
-    }
-
-    if (should_unbox) {
-      // We checked inputs. Check if phi is used in at least one unbox
-      // operation.
-      bool has_unboxed_use = false;
-      for (Value* use = phi->input_use_list();
-           use != NULL;
-           use = use->next_use()) {
-        Instruction* instr = use->instruction();
-        if (instr->IsUnbox()) {
-          has_unboxed_use = true;
-          break;
-        } else if (IsUnboxedInteger(
-            instr->RequiredInputRepresentation(use->use_index()))) {
-          has_unboxed_use = true;
-          break;
-        }
-      }
-
-      if (!has_unboxed_use) {
-        should_unbox = false;
-      }
-    }
-
-    if (should_unbox) {
-      unboxed =
-          RangeUtils::Fits(phi->range(), RangeBoundary::kRangeBoundaryInt32)
-          ? kUnboxedInt32 : kUnboxedMint;
-    }
-  }
-
-  phi->set_representation(unboxed);
-}
-
-
-void FlowGraphOptimizer::SelectRepresentations() {
-  // Conservatively unbox all phis that were proven to be of Double,
-  // Float32x4, or Int32x4 type.
-  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
-       !block_it.Done();
-       block_it.Advance()) {
-    JoinEntryInstr* join_entry = block_it.Current()->AsJoinEntry();
-    if (join_entry != NULL) {
-      for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
-        PhiInstr* phi = it.Current();
-        UnboxPhi(phi);
-      }
-    }
-  }
-
-  // Process all instructions and insert conversions where needed.
-  GraphEntryInstr* graph_entry = flow_graph_->graph_entry();
-
-  // Visit incoming parameters and constants.
-  for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) {
-    InsertConversionsFor((*graph_entry->initial_definitions())[i]);
-  }
-
-  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
-       !block_it.Done();
-       block_it.Advance()) {
-    BlockEntryInstr* entry = block_it.Current();
-    JoinEntryInstr* join_entry = entry->AsJoinEntry();
-    if (join_entry != NULL) {
-      for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
-        PhiInstr* phi = it.Current();
-        ASSERT(phi != NULL);
-        ASSERT(phi->is_alive());
-        InsertConversionsFor(phi);
-      }
-    }
-    CatchBlockEntryInstr* catch_entry = entry->AsCatchBlockEntry();
-    if (catch_entry != NULL) {
-      for (intptr_t i = 0;
-           i < catch_entry->initial_definitions()->length();
-           i++) {
-        InsertConversionsFor((*catch_entry->initial_definitions())[i]);
-      }
-    }
-    for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
-      Definition* def = it.Current()->AsDefinition();
-      if (def != NULL) {
-        InsertConversionsFor(def);
-      }
-    }
-  }
-}
-
-
 static bool ClassIdIsOneOf(intptr_t class_id,
                            const GrowableArray<intptr_t>& class_ids) {
   for (intptr_t i = 0; i < class_ids.length(); i++) {
@@ -1724,7 +1343,7 @@
     if (!field.is_nullable() || (field.guarded_cid() == kNullCid)) {
       load->set_result_cid(field.guarded_cid());
     }
-    FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
+    flow_graph()->parsed_function().AddToGuardedFields(&field);
   }
 
   // Discard the environment from the original instruction because the load
@@ -2365,10 +1984,6 @@
 bool FlowGraphOptimizer::TryInlineFloat32x4Constructor(
     StaticCallInstr* call,
     MethodRecognizer::Kind recognized_kind) {
-  if (FLAG_precompilation) {
-    // Cannot handle unboxed instructions.
-    return false;
-  }
   if (!ShouldInlineSimd()) {
     return false;
   }
@@ -2412,10 +2027,6 @@
 bool FlowGraphOptimizer::TryInlineFloat64x2Constructor(
     StaticCallInstr* call,
     MethodRecognizer::Kind recognized_kind) {
-  if (FLAG_precompilation) {
-    // Cannot handle unboxed instructions.
-    return false;
-  }
   if (!ShouldInlineSimd()) {
     return false;
   }
@@ -2451,10 +2062,6 @@
 bool FlowGraphOptimizer::TryInlineInt32x4Constructor(
     StaticCallInstr* call,
     MethodRecognizer::Kind recognized_kind) {
-  if (FLAG_precompilation) {
-    // Cannot handle unboxed instructions.
-    return false;
-  }
   if (!ShouldInlineSimd()) {
     return false;
   }
@@ -3245,11 +2852,6 @@
 // Tries to optimize instance call by replacing it with a faster instruction
 // (e.g, binary op, field load, ..).
 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
-  if (FLAG_precompilation) {
-    InstanceCallNoopt(instr);
-    return;
-  }
-
   if (!instr->HasICData() || (instr->ic_data()->NumberOfUsedChecks() == 0)) {
     return;
   }
@@ -3377,10 +2979,6 @@
       break;
   }
   if (unary_kind != MathUnaryInstr::kIllegal) {
-    if (FLAG_precompilation) {
-      // TODO(srdjan): Adapt MathUnaryInstr to allow tagged inputs as well.
-      return;
-    }
     MathUnaryInstr* math_unary =
         new(Z) MathUnaryInstr(unary_kind,
                               new(Z) Value(call->ArgumentAt(0)),
@@ -3463,10 +3061,6 @@
     case MethodRecognizer::kMathAcos:
     case MethodRecognizer::kMathAtan:
     case MethodRecognizer::kMathAtan2: {
-      if (FLAG_precompilation) {
-        // No UnboxDouble instructons allowed.
-        return;
-      }
       // InvokeMathCFunctionInstr requires unboxed doubles. UnboxDouble
       // instructions contain type checks and conversions to double.
       ZoneGrowableArray<Value*>* args =
@@ -3584,7 +3178,7 @@
       field.set_is_unboxing_candidate(false);
       field.DeoptimizeDependentCode();
     } else {
-      FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
+      flow_graph()->parsed_function().AddToGuardedFields(&field);
     }
   }
 }
@@ -3710,7 +3304,7 @@
       instr->token_pos());
 
   if (store->IsUnboxedStore()) {
-    FlowGraph::AddToGuardedFields(flow_graph_->guarded_fields(), &field);
+    flow_graph()->parsed_function().AddToGuardedFields(&field);
   }
 
   // Discard the environment from the original instruction because the store
@@ -3721,257 +3315,4 @@
 }
 
 
-#if defined(TARGET_ARCH_ARM) || defined(TARGET_ARCH_IA32)
-// Smi widening pass is only meaningful on platforms where Smi
-// is smaller than 32bit. For now only support it on ARM and ia32.
-static bool CanBeWidened(BinarySmiOpInstr* smi_op) {
-  return BinaryInt32OpInstr::IsSupported(smi_op->op_kind(),
-                                         smi_op->left(),
-                                         smi_op->right());
-}
-
-
-static bool BenefitsFromWidening(BinarySmiOpInstr* smi_op) {
-  // TODO(vegorov): when shifts with non-constants shift count are supported
-  // add them here as we save untagging for the count.
-  switch (smi_op->op_kind()) {
-    case Token::kMUL:
-    case Token::kSHR:
-      // For kMUL we save untagging of the argument for kSHR
-      // we save tagging of the result.
-      return true;
-
-    default:
-      return false;
-  }
-}
-
-
-void FlowGraphOptimizer::WidenSmiToInt32() {
-  GrowableArray<BinarySmiOpInstr*> candidates;
-
-  // Step 1. Collect all instructions that potentially benefit from widening of
-  // their operands (or their result) into int32 range.
-  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
-       !block_it.Done();
-       block_it.Advance()) {
-    for (ForwardInstructionIterator instr_it(block_it.Current());
-         !instr_it.Done();
-         instr_it.Advance()) {
-      BinarySmiOpInstr* smi_op = instr_it.Current()->AsBinarySmiOp();
-      if ((smi_op != NULL) &&
-          smi_op->HasSSATemp() &&
-          BenefitsFromWidening(smi_op) &&
-          CanBeWidened(smi_op)) {
-        candidates.Add(smi_op);
-      }
-    }
-  }
-
-  if (candidates.is_empty()) {
-    return;
-  }
-
-  // Step 2. For each block in the graph compute which loop it belongs to.
-  // We will use this information later during computation of the widening's
-  // gain: we are going to assume that only conversion occuring inside the
-  // same loop should be counted against the gain, all other conversions
-  // can be hoisted and thus cost nothing compared to the loop cost itself.
-  const ZoneGrowableArray<BlockEntryInstr*>& loop_headers =
-      flow_graph()->LoopHeaders();
-
-  GrowableArray<intptr_t> loops(flow_graph_->preorder().length());
-  for (intptr_t i = 0; i < flow_graph_->preorder().length(); i++) {
-    loops.Add(-1);
-  }
-
-  for (intptr_t loop_id = 0; loop_id < loop_headers.length(); ++loop_id) {
-    for (BitVector::Iterator loop_it(loop_headers[loop_id]->loop_info());
-         !loop_it.Done();
-         loop_it.Advance()) {
-      loops[loop_it.Current()] = loop_id;
-    }
-  }
-
-  // Step 3. For each candidate transitively collect all other BinarySmiOpInstr
-  // and PhiInstr that depend on it and that it depends on and count amount of
-  // untagging operations that we save in assumption that this whole graph of
-  // values is using kUnboxedInt32 representation instead of kTagged.
-  // Convert those graphs that have positive gain to kUnboxedInt32.
-
-  // BitVector containing SSA indexes of all processed definitions. Used to skip
-  // those candidates that belong to dependency graph of another candidate.
-  BitVector* processed =
-      new(Z) BitVector(Z, flow_graph_->current_ssa_temp_index());
-
-  // Worklist used to collect dependency graph.
-  DefinitionWorklist worklist(flow_graph_, candidates.length());
-  for (intptr_t i = 0; i < candidates.length(); i++) {
-    BinarySmiOpInstr* op = candidates[i];
-    if (op->WasEliminated() || processed->Contains(op->ssa_temp_index())) {
-      continue;
-    }
-
-    if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-      THR_Print("analysing candidate: %s\n", op->ToCString());
-    }
-    worklist.Clear();
-    worklist.Add(op);
-
-    // Collect dependency graph. Note: more items are added to worklist
-    // inside this loop.
-    intptr_t gain = 0;
-    for (intptr_t j = 0; j < worklist.definitions().length(); j++) {
-      Definition* defn = worklist.definitions()[j];
-
-      if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-        THR_Print("> %s\n", defn->ToCString());
-      }
-
-      if (defn->IsBinarySmiOp() &&
-          BenefitsFromWidening(defn->AsBinarySmiOp())) {
-        gain++;
-        if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-          THR_Print("^ [%" Pd "] (o) %s\n", gain, defn->ToCString());
-        }
-      }
-
-      const intptr_t defn_loop = loops[defn->GetBlock()->preorder_number()];
-
-      // Process all inputs.
-      for (intptr_t k = 0; k < defn->InputCount(); k++) {
-        Definition* input = defn->InputAt(k)->definition();
-        if (input->IsBinarySmiOp() &&
-            CanBeWidened(input->AsBinarySmiOp())) {
-          worklist.Add(input);
-        } else if (input->IsPhi() && (input->Type()->ToCid() == kSmiCid)) {
-          worklist.Add(input);
-        } else if (input->IsBinaryMintOp()) {
-          // Mint operation produces untagged result. We avoid tagging.
-          gain++;
-          if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-            THR_Print("^ [%" Pd "] (i) %s\n", gain, input->ToCString());
-          }
-        } else if (defn_loop == loops[input->GetBlock()->preorder_number()] &&
-                   (input->Type()->ToCid() == kSmiCid)) {
-          // Input comes from the same loop, is known to be smi and requires
-          // untagging.
-          // TODO(vegorov) this heuristic assumes that values that are not
-          // known to be smi have to be checked and this check can be
-          // coalesced with untagging. Start coalescing them.
-          gain--;
-          if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-            THR_Print("v [%" Pd "] (i) %s\n", gain, input->ToCString());
-          }
-        }
-      }
-
-      // Process all uses.
-      for (Value* use = defn->input_use_list();
-           use != NULL;
-           use = use->next_use()) {
-        Instruction* instr = use->instruction();
-        Definition* use_defn = instr->AsDefinition();
-        if (use_defn == NULL) {
-          // We assume that tagging before returning or pushing argument costs
-          // very little compared to the cost of the return/call itself.
-          if (!instr->IsReturn() && !instr->IsPushArgument()) {
-            gain--;
-            if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-              THR_Print("v [%" Pd "] (u) %s\n",
-                        gain,
-                        use->instruction()->ToCString());
-            }
-          }
-          continue;
-        } else if (use_defn->IsBinarySmiOp() &&
-                   CanBeWidened(use_defn->AsBinarySmiOp())) {
-          worklist.Add(use_defn);
-        } else if (use_defn->IsPhi() &&
-                   use_defn->AsPhi()->Type()->ToCid() == kSmiCid) {
-          worklist.Add(use_defn);
-        } else if (use_defn->IsBinaryMintOp()) {
-          // BinaryMintOp requires untagging of its inputs.
-          // Converting kUnboxedInt32 to kUnboxedMint is essentially zero cost
-          // sign extension operation.
-          gain++;
-          if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-            THR_Print("^ [%" Pd "] (u) %s\n",
-                      gain,
-                      use->instruction()->ToCString());
-          }
-        } else if (defn_loop == loops[instr->GetBlock()->preorder_number()]) {
-          gain--;
-          if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-            THR_Print("v [%" Pd "] (u) %s\n",
-                      gain,
-                      use->instruction()->ToCString());
-          }
-        }
-      }
-    }
-
-    processed->AddAll(worklist.contains_vector());
-
-    if (FLAG_support_il_printer && FLAG_trace_smi_widening) {
-      THR_Print("~ %s gain %" Pd "\n", op->ToCString(), gain);
-    }
-
-    if (gain > 0) {
-      // We have positive gain from widening. Convert all BinarySmiOpInstr into
-      // BinaryInt32OpInstr and set representation of all phis to kUnboxedInt32.
-      for (intptr_t j = 0; j < worklist.definitions().length(); j++) {
-        Definition* defn = worklist.definitions()[j];
-        ASSERT(defn->IsPhi() || defn->IsBinarySmiOp());
-
-        if (defn->IsBinarySmiOp()) {
-          BinarySmiOpInstr* smi_op = defn->AsBinarySmiOp();
-          BinaryInt32OpInstr* int32_op = new(Z) BinaryInt32OpInstr(
-            smi_op->op_kind(),
-            smi_op->left()->CopyWithType(),
-            smi_op->right()->CopyWithType(),
-            smi_op->DeoptimizationTarget());
-
-          smi_op->ReplaceWith(int32_op, NULL);
-        } else if (defn->IsPhi()) {
-          defn->AsPhi()->set_representation(kUnboxedInt32);
-          ASSERT(defn->Type()->IsInt());
-        }
-      }
-    }
-  }
-}
-#else
-void FlowGraphOptimizer::WidenSmiToInt32() {
-  // TODO(vegorov) ideally on 64-bit platforms we would like to narrow smi
-  // operations to 32-bit where it saves tagging and untagging and allows
-  // to use shorted (and faster) instructions. But we currently don't
-  // save enough range information in the ICData to drive this decision.
-}
-#endif
-
-
-void FlowGraphOptimizer::EliminateEnvironments() {
-  // After this pass we can no longer perform LICM and hoist instructions
-  // that can deoptimize.
-
-  flow_graph_->disallow_licm();
-  for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
-       !block_it.Done();
-       block_it.Advance()) {
-    BlockEntryInstr* block = block_it.Current();
-    block->RemoveEnvironment();
-    for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
-      Instruction* current = it.Current();
-      if (!current->CanDeoptimize()) {
-        // TODO(srdjan): --source-lines needs deopt environments to get at
-        // the code for this instruction, however, leaving the environment
-        // changes code.
-        current->RemoveEnvironment();
-      }
-    }
-  }
-}
-
-
 }  // namespace dart
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 79abf12..544d7de 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -30,10 +30,6 @@
 
   FlowGraph* flow_graph() const { return flow_graph_; }
 
-  // Add ICData to InstanceCalls, so that optimizations can be run on them.
-  // TODO(srdjan): StaticCals as well?
-  void PopulateWithICData();
-
   // Use ICData to optimize, replace or eliminate instructions.
   void ApplyICData();
 
@@ -45,18 +41,6 @@
   // Merge instructions (only per basic-block).
   void TryOptimizePatterns();
 
-  // Returns true if any instructions were canonicalized away.
-  bool Canonicalize();
-
-  void EliminateDeadPhis();
-
-  void SelectRepresentations();
-
-  void WidenSmiToInt32();
-
-  // Remove environments from the instructions which do not deoptimize.
-  void EliminateEnvironments();
-
   virtual void VisitStaticCall(StaticCallInstr* instr);
   virtual void VisitInstanceCall(InstanceCallInstr* instr);
   virtual void VisitStoreInstanceField(StoreInstanceFieldInstr* instr);
@@ -138,15 +122,6 @@
 
   void ReplaceCall(Definition* call, Definition* replacement);
 
-  void InsertConversionsFor(Definition* def);
-
-  void ConvertUse(Value* use, Representation from);
-  void ConvertEnvironmentUse(Value* use, Representation from);
-
-  void InsertConversion(Representation from,
-                        Representation to,
-                        Value* use,
-                        bool is_environment_use);
 
   bool InstanceCallNeedsClassCheck(InstanceCallInstr* call,
                                    RawFunction::Kind kind) const;
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index 93e06b7..9807bcf 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -15,8 +15,6 @@
             "Trace flow graph type propagation");
 
 DECLARE_FLAG(bool, propagate_types);
-DECLARE_FLAG(bool, trace_cha);
-DECLARE_FLAG(bool, use_cha_deopt);
 DECLARE_FLAG(bool, fields_may_be_reset);
 
 
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index 6fcc90c..c9ac9fa 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -713,7 +713,9 @@
       // All marking done; detach code, etc.
       FinalizeResultsFrom(&mark);
     } else {
-      ThreadBarrier barrier(num_tasks + 1);
+      ThreadBarrier barrier(num_tasks + 1,
+                            heap_->barrier(),
+                            heap_->barrier_done());
       // Used to coordinate draining among tasks; all start out as 'busy'.
       uintptr_t num_busy = num_tasks;
       // Phase 1: Iterate over roots and drain marking stack in tasks.
diff --git a/runtime/vm/gdbjit_android.cc b/runtime/vm/gdbjit_android.cc
deleted file mode 100644
index 1141fbf..0000000
--- a/runtime/vm/gdbjit_android.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/globals.h"
-#if defined(TARGET_OS_ANDROID)
-
-#include <stdint.h>  // NOLINT
-#include <stdio.h>  // NOLINT
-#include <stdlib.h>  // NOLINT
-
-#include "vm/gdbjit_android.h"
-
-extern "C" {
-  typedef enum {
-    JIT_NOACTION = 0,
-    JIT_REGISTER_FN,
-    JIT_UNREGISTER_FN
-  } jit_actions_t;
-
-  struct jit_code_entry {
-    struct jit_code_entry* next_entry;
-    struct jit_code_entry* prev_entry;
-    const char* symfile_addr;
-    uint64_t symfile_size;
-  };
-
-  struct jit_descriptor {
-    uint32_t version;
-    /* This type should be jit_actions_t, but we use uint32_t
-       to be explicit about the bitwidth.  */
-    uint32_t action_flag;
-    struct jit_code_entry* relevant_entry;
-    struct jit_code_entry* first_entry;
-  };
-
-#ifndef GDB_JIT_SYMBOLS
-  /* GDB puts a breakpoint in this function.  */
-  void __attribute__((noinline)) __jit_debug_register_code() { }
-
-  /* Make sure to specify the version statically, because the
-     debugger may check the version before we can set it.  */
-  struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
-#endif
-
-  static struct jit_code_entry* first_dynamic_region = NULL;
-  static struct jit_code_entry* last_dynamic_region = NULL;
-
-  void addDynamicSection(const char* symfile_addr, uint64_t symfile_size) {
-    jit_code_entry* new_entry = reinterpret_cast<jit_code_entry*>(
-        malloc(sizeof(jit_code_entry)));
-    if (new_entry != NULL) {
-      new_entry->symfile_addr = symfile_addr;
-      new_entry->symfile_size = symfile_size;
-      new_entry->next_entry = NULL;
-      new_entry->prev_entry = last_dynamic_region;
-      if (first_dynamic_region == NULL) {
-        first_dynamic_region = new_entry;
-      } else {
-        last_dynamic_region->next_entry = new_entry;
-      }
-      last_dynamic_region = new_entry;
-    }
-    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
-    __jit_debug_descriptor.relevant_entry = new_entry;
-    __jit_debug_descriptor.first_entry = first_dynamic_region;
-    __jit_debug_register_code();
-  }
-
-  void deleteDynamicSections() {
-    struct jit_code_entry* iterator = last_dynamic_region;
-    while (iterator != NULL) {
-      __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
-      __jit_debug_descriptor.relevant_entry = iterator;
-      __jit_debug_descriptor.first_entry = first_dynamic_region;
-      __jit_debug_register_code();
-      iterator = iterator->prev_entry;
-    }
-    first_dynamic_region = NULL;
-    last_dynamic_region = NULL;
-  }
-};
-
-#endif  // defined(TARGET_OS_ANDROID)
diff --git a/runtime/vm/gdbjit_android.h b/runtime/vm/gdbjit_android.h
deleted file mode 100644
index f2cd1ba..0000000
--- a/runtime/vm/gdbjit_android.h
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef VM_GDBJIT_ANDROID_H_
-#define VM_GDBJIT_ANDROID_H_
-
-#include <stdint.h>
-
-extern "C" {
-  void addDynamicSection(const char* symfile_addr, uint64_t symfile_size);
-  void deleteDynamicSections();
-};
-
-#endif  // VM_GDBJIT_ANDROID_H_
diff --git a/runtime/vm/gdbjit_linux.cc b/runtime/vm/gdbjit_linux.cc
deleted file mode 100644
index 9e06b85..0000000
--- a/runtime/vm/gdbjit_linux.cc
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/globals.h"
-#if defined(TARGET_OS_LINUX)
-
-#include <stdint.h>  // NOLINT
-#include <stdio.h>  // NOLINT
-#include <stdlib.h>  // NOLINT
-
-#include "vm/gdbjit_linux.h"
-
-extern "C" {
-  typedef enum {
-    JIT_NOACTION = 0,
-    JIT_REGISTER_FN,
-    JIT_UNREGISTER_FN
-  } jit_actions_t;
-
-  struct jit_code_entry {
-    struct jit_code_entry* next_entry;
-    struct jit_code_entry* prev_entry;
-    const char* symfile_addr;
-    uint64_t symfile_size;
-  };
-
-  struct jit_descriptor {
-    uint32_t version;
-    /* This type should be jit_actions_t, but we use uint32_t
-       to be explicit about the bitwidth.  */
-    uint32_t action_flag;
-    struct jit_code_entry* relevant_entry;
-    struct jit_code_entry* first_entry;
-  };
-
-#ifndef GDB_JIT_SYMBOLS
-  /* GDB puts a breakpoint in this function.  */
-  void __attribute__((noinline)) __jit_debug_register_code() { }
-
-  /* Make sure to specify the version statically, because the
-     debugger may check the version before we can set it.  */
-  struct jit_descriptor __jit_debug_descriptor = { 1, 0, 0, 0 };
-#endif
-
-  static struct jit_code_entry* first_dynamic_region = NULL;
-  static struct jit_code_entry* last_dynamic_region = NULL;
-
-  void addDynamicSection(const char* symfile_addr, uint64_t symfile_size) {
-    jit_code_entry* new_entry = reinterpret_cast<jit_code_entry*>(
-        malloc(sizeof(jit_code_entry)));
-    if (new_entry != NULL) {
-      new_entry->symfile_addr = symfile_addr;
-      new_entry->symfile_size = symfile_size;
-      new_entry->next_entry = NULL;
-      new_entry->prev_entry = last_dynamic_region;
-      if (first_dynamic_region == NULL) {
-        first_dynamic_region = new_entry;
-      } else {
-        last_dynamic_region->next_entry = new_entry;
-      }
-      last_dynamic_region = new_entry;
-    }
-    __jit_debug_descriptor.action_flag = JIT_REGISTER_FN;
-    __jit_debug_descriptor.relevant_entry = new_entry;
-    __jit_debug_descriptor.first_entry = first_dynamic_region;
-    __jit_debug_register_code();
-  }
-
-  void deleteDynamicSections() {
-    struct jit_code_entry* iterator = last_dynamic_region;
-    while (iterator != NULL) {
-      __jit_debug_descriptor.action_flag = JIT_UNREGISTER_FN;
-      __jit_debug_descriptor.relevant_entry = iterator;
-      __jit_debug_descriptor.first_entry = first_dynamic_region;
-      __jit_debug_register_code();
-      iterator = iterator->prev_entry;
-    }
-    first_dynamic_region = NULL;
-    last_dynamic_region = NULL;
-  }
-};
-
-#endif  // defined(TARGET_OS_LINUX)
diff --git a/runtime/vm/gdbjit_linux.h b/runtime/vm/gdbjit_linux.h
deleted file mode 100644
index cf259f6..0000000
--- a/runtime/vm/gdbjit_linux.h
+++ /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.
-
-#ifndef VM_GDBJIT_LINUX_H_
-#define VM_GDBJIT_LINUX_H_
-
-#include <stdint.h>
-
-extern "C" {
-  void addDynamicSection(const char* symfile_addr, uint64_t symfile_size);
-  void deleteDynamicSections();
-};
-
-#endif  // VM_GDBJIT_LINUX_H_
diff --git a/runtime/vm/globals.h b/runtime/vm/globals.h
index 9b1e89c..9fd69e2 100644
--- a/runtime/vm/globals.h
+++ b/runtime/vm/globals.h
@@ -15,7 +15,7 @@
 #undef PARITY_EVEN
 #undef PARITY_ODD
 #undef near
-#endif
+#endif  // defined(_WIN32)
 
 // The following #defines are invalidated.
 #undef OVERFLOW  // From math.h conflicts in constants_ia32.h
diff --git a/runtime/vm/hash_table.h b/runtime/vm/hash_table.h
index 2334bbc..c162232 100644
--- a/runtime/vm/hash_table.h
+++ b/runtime/vm/hash_table.h
@@ -99,7 +99,9 @@
         key_handle_(Object::Handle(zone_)),
         smi_handle_(Smi::Handle(zone_)),
         data_(&Array::Handle(zone_, data)),
-        released_data_(NULL) {}
+        released_data_(NULL) {
+    ASSERT(!data_->IsNull());
+  }
 
   // Returns the final table. The handle is cleared when this HashTable is
   // destroyed.
@@ -296,6 +298,7 @@
   }
 
   intptr_t GetSmiValueAt(intptr_t index) const {
+    ASSERT(!data_->IsNull());
     ASSERT(Object::Handle(zone(), data_->At(index)).IsSmi());
     return Smi::Value(Smi::RawCast(data_->At(index)));
   }
@@ -689,7 +692,9 @@
 class UnorderedHashSet : public HashSet<UnorderedHashTable<KeyTraits, 0> > {
  public:
   typedef HashSet<UnorderedHashTable<KeyTraits, 0> > BaseSet;
-  explicit UnorderedHashSet(RawArray* data) : BaseSet(data) {}
+  explicit UnorderedHashSet(RawArray* data) : BaseSet(data) {
+    ASSERT(data != Array::null());
+  }
   UnorderedHashSet(Zone* zone, RawArray* data) : BaseSet(zone, data) {}
 };
 
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index d7846a7..8950958 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -31,6 +31,8 @@
            intptr_t max_old_gen_words,
            intptr_t max_external_words)
     : isolate_(isolate),
+      barrier_(new Monitor()),
+      barrier_done_(new Monitor()),
       new_space_(this, max_new_gen_semi_words, kNewObjectAlignmentOffset),
       old_space_(this, max_old_gen_words, max_external_words),
       read_only_(false),
@@ -48,6 +50,9 @@
 
 
 Heap::~Heap() {
+  delete barrier_;
+  delete barrier_done_;
+
   for (int sel = 0;
        sel < kNumWeakSelectors;
        sel++) {
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index cfc1b54..f116af55 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -244,6 +244,9 @@
 
   Isolate* isolate() const { return isolate_; }
 
+  Monitor* barrier() const { return barrier_; }
+  Monitor* barrier_done() const { return barrier_done_; }
+
   bool ShouldPretenure(intptr_t class_id) const;
 
   void SetupExternalPage(void* pointer, uword size, bool is_executable) {
@@ -329,6 +332,8 @@
   void GetMergedAddressRange(uword* start, uword* end) const;
 
   Isolate* isolate_;
+  Monitor* barrier_;
+  Monitor* barrier_done_;
 
   // The different spaces used for allocation.
   Scavenger new_space_;
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 20b1e09..b2b4df6 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -42,7 +42,6 @@
 DEFINE_FLAG(bool, fields_may_be_reset, false,
             "Don't optimize away static field initialization");
 DECLARE_FLAG(bool, eliminate_type_checks);
-DECLARE_FLAG(bool, trace_optimization);
 
 Definition::Definition(intptr_t deopt_id)
     : Instruction(deopt_id),
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 32b50e8..3758c21 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -18,6 +18,7 @@
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
 #include "vm/deopt_instructions.h"
+#include "vm/flags.h"
 #include "vm/heap.h"
 #include "vm/lockers.h"
 #include "vm/log.h"
@@ -801,6 +802,7 @@
       random_(),
       simulator_(NULL),
       mutex_(new Mutex()),
+      symbols_mutex_(new Mutex()),
       saved_stack_limit_(0),
       deferred_interrupts_mask_(0),
       deferred_interrupts_(0),
@@ -820,7 +822,6 @@
       last_allocationprofile_accumulator_reset_timestamp_(0),
       last_allocationprofile_gc_timestamp_(0),
       object_id_ring_(NULL),
-      trace_buffer_(NULL),
       tag_table_(GrowableObjectArray::null()),
       deoptimized_code_array_(GrowableObjectArray::null()),
       background_compiler_(NULL),
@@ -863,6 +864,8 @@
 #endif
   delete mutex_;
   mutex_ = NULL;  // Fail fast if interrupts are scheduled on a dead isolate.
+  delete symbols_mutex_;
+  symbols_mutex_ = NULL;
   delete message_handler_;
   message_handler_ = NULL;  // Fail fast if we send messages to a dead isolate.
   ASSERT(deopt_context_ == NULL);  // No deopt in progress when isolate deleted.
@@ -959,9 +962,11 @@
     }
   }
 
-  result->compiler_stats_ = new CompilerStats(result);
-  if (FLAG_compiler_benchmark) {
-    result->compiler_stats_->EnableBenchmark();
+  if (FLAG_support_compiler_stats) {
+    result->compiler_stats_ = new CompilerStats(result);
+    if (FLAG_compiler_benchmark) {
+      result->compiler_stats_->EnableBenchmark();
+    }
   }
 
   if (FLAG_support_service) {
@@ -1773,7 +1778,7 @@
     }
 
     // Write compiler stats data if enabled.
-    if (FLAG_compiler_stats
+    if (FLAG_support_compiler_stats && FLAG_compiler_stats
         && !ServiceIsolate::IsServiceIsolateDescendant(this)
         && (this != Dart::vm_isolate())) {
       OS::Print("%s", compiler_stats()->PrintToZone());
@@ -1951,30 +1956,32 @@
   jsobj.AddProperty("livePorts", message_handler()->live_ports());
   jsobj.AddProperty("pauseOnExit", message_handler()->should_pause_on_exit());
 
-  if (message_handler()->is_paused_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_) {
-    ServiceEvent pause_event(debugger()->PauseEvent());
-    jsobj.AddProperty("pauseEvent", &pause_event);
-  } else {
-    ServiceEvent pause_event(this, ServiceEvent::kResume);
+  if (debugger() != NULL) {
+    if (message_handler()->is_paused_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_) {
+      ServiceEvent pause_event(debugger()->PauseEvent());
+      jsobj.AddProperty("pauseEvent", &pause_event);
+    } else {
+      ServiceEvent pause_event(this, ServiceEvent::kResume);
 
-    // 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));
+      // 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("pauseEvent", &pause_event);
-  }
 
-  jsobj.AddProperty("exceptionPauseMode",
-      ExceptionPauseInfoToServiceEnum(debugger()->GetExceptionPauseInfo()));
+    jsobj.AddProperty("exceptionPauseMode",
+        ExceptionPauseInfoToServiceEnum(debugger()->GetExceptionPauseInfo()));
+  }
 
   const Library& lib =
       Library::Handle(object_store()->root_library());
@@ -2005,14 +2012,17 @@
       lib_array.AddValue(lib);
     }
   }
-  {
-    JSONArray breakpoints(&jsobj, "breakpoints");
-    debugger()->PrintBreakpointsToJSONArray(&breakpoints);
-  }
 
-  {
-    JSONObject jssettings(&jsobj, "_debuggerSettings");
-    debugger()->PrintSettingsToJSONObject(&jssettings);
+  if (debugger() != NULL) {
+    {
+      JSONArray breakpoints(&jsobj, "breakpoints");
+      debugger()->PrintBreakpointsToJSONArray(&breakpoints);
+    }
+
+    {
+      JSONObject jssettings(&jsobj, "_debuggerSettings");
+      debugger()->PrintSettingsToJSONObject(&jssettings);
+    }
   }
 
   {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 15c2562..e9c255b 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -19,7 +19,7 @@
 #include "vm/os_thread.h"
 #include "vm/timeline.h"
 #include "vm/timer.h"
-#include "vm/trace_buffer.h"
+#include "vm/token_position.h"
 
 namespace dart {
 
@@ -318,6 +318,7 @@
   void set_spawn_state(IsolateSpawnState* value) { spawn_state_ = value; }
 
   Mutex* mutex() const { return mutex_; }
+  Mutex* symbols_mutex() const { return symbols_mutex_; }
 
   Debugger* debugger() const {
     if (!FLAG_support_debugger) {
@@ -493,13 +494,6 @@
     return object_id_ring_;
   }
 
-  void set_trace_buffer(TraceBuffer* buffer) {
-    trace_buffer_ = buffer;
-  }
-  TraceBuffer* trace_buffer() {
-    return trace_buffer_;
-  }
-
   DeoptContext* deopt_context() const { return deopt_context_; }
   void set_deopt_context(DeoptContext* value) {
     ASSERT(value == NULL || deopt_context_ == NULL);
@@ -779,6 +773,7 @@
   Random random_;
   Simulator* simulator_;
   Mutex* mutex_;  // protects stack_limit_, saved_stack_limit_, compiler stats.
+  Mutex* symbols_mutex_;  // Protects concurrent access to teh symbol table.
   uword saved_stack_limit_;
   uword deferred_interrupts_mask_;
   uword deferred_interrupts_;
@@ -807,9 +802,6 @@
   // Ring buffer of objects assigned an id.
   ObjectIdRing* object_id_ring_;
 
-  // Trace buffer support.
-  TraceBuffer* trace_buffer_;
-
   VMTagCounters vm_tag_counters_;
   RawGrowableObjectArray* tag_table_;
 
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index ef3ba53..6491c41 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -131,7 +131,9 @@
 // round update *before* the interrupt is set.
 TEST_CASE(StackLimitInterrupts) {
   Isolate* isolate = Thread::Current()->isolate();
-  ThreadBarrier barrier(InterruptChecker::kTaskCount + 1);
+  ThreadBarrier barrier(InterruptChecker::kTaskCount + 1,
+                        isolate->heap()->barrier(),
+                        isolate->heap()->barrier_done());
   // Start all tasks. They will busy-wait until interrupted in the first round.
   for (intptr_t task = 0; task < InterruptChecker::kTaskCount; task++) {
     Dart::thread_pool()->Run(new InterruptChecker(isolate, &barrier));
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
index 1c95381..839d40c 100644
--- a/runtime/vm/lockers.cc
+++ b/runtime/vm/lockers.cc
@@ -34,4 +34,29 @@
 }
 
 
+SafepointMutexLocker::SafepointMutexLocker(Mutex* mutex) : mutex_(mutex) {
+  ASSERT(mutex != NULL);
+  if (!mutex_->TryLock()) {
+    // We did not get the lock and could potentially block, so transition
+    // accordingly.
+    Thread* thread = Thread::Current();
+    thread->set_execution_state(Thread::kThreadInBlockedState);
+    thread->EnterSafepoint();
+    mutex->Lock();
+    // First try a fast update of the thread state to indicate it is not at a
+    // safepoint anymore.
+    uword old_state = Thread::SetAtSafepoint(true, 0);
+    uword addr =
+        reinterpret_cast<uword>(thread) + Thread::safepoint_state_offset();
+    if (AtomicOperations::CompareAndSwapWord(
+            reinterpret_cast<uword*>(addr), old_state, 0) != old_state) {
+      // Fast update failed which means we could potentially be in the middle
+      // of a safepoint operation and need to block for it.
+      SafepointHandler* handler = thread->isolate()->safepoint_handler();
+      handler->ExitSafepointUsingLock(thread);
+    }
+    thread->set_execution_state(Thread::kThreadInVM);
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index 42b0984..fd324f4 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -71,6 +71,25 @@
   DISALLOW_COPY_AND_ASSIGN(MonitorLocker);
 };
 
+
+// SafepointMutexLocker objects are used in code where the locks are
+// more coarse grained and a safepoint operation could be potentially
+// triggered while holding this lock. This ensures that other threads
+// which try to acquire the same lock will be marked as being at a
+// safepoint when they are blocked.
+class SafepointMutexLocker : public ValueObject {
+ public:
+  explicit SafepointMutexLocker(Mutex* mutex);
+  virtual ~SafepointMutexLocker() {
+    mutex_->Unlock();
+  }
+
+ private:
+  Mutex* const mutex_;
+
+  DISALLOW_COPY_AND_ASSIGN(SafepointMutexLocker);
+};
+
 }  // namespace dart
 
 
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index ded8b85..1763c8c 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -62,11 +62,15 @@
 
 #endif
 
+#ifndef PRODUCT
 #define TRACE_NATIVE_CALL(format, name)                                        \
   if (FLAG_trace_natives) {                                                    \
     OS::Print("Calling native: " format "\n", name);                           \
   }
-
+#else
+#define TRACE_NATIVE_CALL(format, name)                                        \
+  do { } while (0)
+#endif
 
 // Class NativeArguments is used to access arguments passed in from
 // generated dart code to a runtime function or a dart library native
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index 34ea4bf..a28a779 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -24,6 +24,13 @@
             "Trace invocation of natives (debug mode only)");
 
 
+void DartNativeThrowArgumentException(const Instance& instance) {
+  const Array& __args__ = Array::Handle(Array::New(1));
+  __args__.SetAt(0, instance);
+  Exceptions::ThrowByType(Exceptions::kArgument, __args__);
+}
+
+
 NativeFunction NativeEntry::ResolveNative(const Library& library,
                                           const String& function_name,
                                           int number_of_arguments,
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index c5578f9..2e90ffc 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -71,15 +71,16 @@
                                     NativeArguments* arguments)
 
 
+// Helper that throws an argument exception.
+void DartNativeThrowArgumentException(const Instance& instance);
+
 // Natives should throw an exception if an illegal argument or null is passed.
 // type name = value.
 #define GET_NON_NULL_NATIVE_ARGUMENT(type, name, value)                        \
   const Instance& __##name##_instance__ =                                      \
       Instance::CheckedHandle(zone, value);                                    \
   if (!__##name##_instance__.Is##type()) {                                     \
-    const Array& __args__ = Array::Handle(Array::New(1));                      \
-    __args__.SetAt(0, __##name##_instance__);                                  \
-    Exceptions::ThrowByType(Exceptions::kArgument, __args__);                  \
+    DartNativeThrowArgumentException(__##name##_instance__);                   \
   }                                                                            \
   const type& name = type::Cast(__##name##_instance__);
 
@@ -92,9 +93,7 @@
   type& name = type::Handle(zone);                                             \
   if (!__##name##_instance__.IsNull()) {                                       \
     if (!__##name##_instance__.Is##type()) {                                   \
-      const Array& __args__ = Array::Handle(Array::New(1));                    \
-      __args__.SetAt(0, __##name##_instance__);                                \
-      Exceptions::ThrowByType(Exceptions::kArgument, __args__);                \
+      DartNativeThrowArgumentException(__##name##_instance__);                 \
     }                                                                          \
   }                                                                            \
   name ^= value;
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index c85afa2..aea7d1f 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -31,7 +31,6 @@
 #include "vm/parser.h"
 #include "vm/precompiler.h"
 #include "vm/profiler.h"
-#include "vm/report.h"
 #include "vm/reusable_handles.h"
 #include "vm/runtime_entry.h"
 #include "vm/scopes.h"
@@ -56,10 +55,8 @@
 DEFINE_FLAG(bool, show_internal_names, false,
     "Show names of internal classes (e.g. \"OneByteString\") in error messages "
     "instead of showing the corresponding interface names (e.g. \"String\")");
-DEFINE_FLAG(bool, trace_cha, false, "Trace CHA operations");
 DEFINE_FLAG(bool, use_field_guards, true, "Guard field cids.");
 DEFINE_FLAG(bool, use_lib_cache, true, "Use library name cache");
-DEFINE_FLAG(bool, trace_field_guards, false, "Trace changes in field's cids.");
 DEFINE_FLAG(bool, ignore_patch_signature_mismatch, false,
             "Ignore patch file member signature mismatch.");
 
@@ -1366,6 +1363,7 @@
 
   // Pre-register the mirrors library so we can place the vm class
   // MirrorReference there rather than the core library.
+NOT_IN_PRODUCT(
   lib = Library::LookupLibrary(Symbols::DartMirrors());
   if (lib.IsNull()) {
     lib = Library::NewLibraryHelper(Symbols::DartMirrors(), true);
@@ -1377,7 +1375,7 @@
   ASSERT(lib.raw() == Library::MirrorsLibrary());
 
   cls = Class::New<MirrorReference>();
-  RegisterPrivateClass(cls, Symbols::_MirrorReference(), lib);
+  RegisterPrivateClass(cls, Symbols::_MirrorReference(), lib));
 
   // Pre-register the collection library so we can place the vm class
   // LinkedHashMap there rather than the core library.
@@ -1737,6 +1735,17 @@
 }
 
 
+#if defined(DEBUG)
+bool Object:: InVMHeap() const {
+  if (FLAG_verify_handles && raw()->IsVMHeapObject()) {
+    Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
+    ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw())));
+  }
+  return raw()->IsVMHeapObject();
+}
+#endif  // DEBUG
+
+
 void Object::Print() const {
   THR_Print("%s\n", ToCString());
 }
@@ -1914,8 +1923,12 @@
 
 
 RawString* Class::UserVisibleName() const {
+#if defined(PRODUCT)
+  return raw_ptr()->name_;
+#else  // defined(PRODUCT)
   ASSERT(raw_ptr()->user_name_ != String::null());
   return raw_ptr()->user_name_;
+#endif  // defined(PRODUCT)
 }
 
 
@@ -2110,6 +2123,7 @@
 
 
 void Class::SetFunctions(const Array& value) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(!value.IsNull());
   StorePointer(&raw_ptr()->functions_, value.raw());
   const intptr_t len = value.Length();
@@ -2130,6 +2144,7 @@
 
 
 void Class::AddFunction(const Function& function) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   const Array& arr = Array::Handle(functions());
   const Array& new_arr =
       Array::Handle(Array::Grow(arr, arr.Length() + 1, Heap::kOld));
@@ -2149,6 +2164,7 @@
 
 
 void Class::RemoveFunction(const Function& function) const {
+  ASSERT(Thread::Current()->IsMutatorThread());
   const Array& arr = Array::Handle(functions());
   StorePointer(&raw_ptr()->functions_, Object::empty_array().raw());
   StorePointer(&raw_ptr()->functions_hash_table_, Array::null());
@@ -3147,6 +3163,7 @@
 void Class::set_name(const String& value) const {
   ASSERT(value.IsSymbol());
   StorePointer(&raw_ptr()->name_, value.raw());
+NOT_IN_PRODUCT(
   if (raw_ptr()->user_name_ == String::null()) {
     // TODO(johnmccutchan): Eagerly set user name for VM isolate classes,
     // lazily set user name for the other classes.
@@ -3154,12 +3171,15 @@
     const String& user_name = String::Handle(GenerateUserVisibleName());
     set_user_name(user_name);
   }
+)
 }
 
 
+NOT_IN_PRODUCT(
 void Class::set_user_name(const String& value) const {
   StorePointer(&raw_ptr()->user_name_, value.raw());
 }
+)
 
 
 RawString* Class::GeneratePrettyName() const {
@@ -3486,6 +3506,11 @@
 }
 
 
+void Class::ClearDirectSubclasses() const {
+  StorePointer(&raw_ptr()->direct_subclasses_, GrowableObjectArray::null());
+}
+
+
 RawArray* Class::constants() const {
   return raw_ptr()->constants_;
 }
@@ -3935,13 +3960,18 @@
   const intptr_t len = funcs.Length();
   Function& function = thread->FunctionHandle();
   if (len >= kFunctionLookupHashTreshold) {
-    ClassFunctionsSet set(raw_ptr()->functions_hash_table_);
-    REUSABLE_STRING_HANDLESCOPE(thread);
-    function ^= set.GetOrNull(FunctionName(name, &(thread->StringHandle())));
-    // No mutations.
-    ASSERT(set.Release().raw() == raw_ptr()->functions_hash_table_);
-    return function.IsNull() ? Function::null()
-                             : CheckFunctionType(function, kind);
+    // Cache functions hash table to allow multi threaded access.
+    const Array& hash_table = Array::Handle(thread->zone(),
+                                            raw_ptr()->functions_hash_table_);
+    if (!hash_table.IsNull()) {
+      ClassFunctionsSet set(hash_table.raw());
+      REUSABLE_STRING_HANDLESCOPE(thread);
+      function ^= set.GetOrNull(FunctionName(name, &(thread->StringHandle())));
+      // No mutations.
+      ASSERT(set.Release().raw() == hash_table.raw());
+      return function.IsNull() ? Function::null()
+                               : CheckFunctionType(function, kind);
+    }
   }
   if (name.IsSymbol()) {
     // Quick Symbol compare.
@@ -9694,6 +9724,12 @@
 }
 
 
+void Library::DropDependencies() const {
+  StorePointer(&raw_ptr()->imports_, Array::null());
+  StorePointer(&raw_ptr()->exports_, Array::null());
+}
+
+
 void Library::AddImport(const Namespace& ns) const {
   Array& imports = Array::Handle(this->imports());
   intptr_t capacity = imports.Length();
@@ -12821,11 +12857,13 @@
   CPU::FlushICache(instrs.EntryPoint(), instrs.size());
 
   code.set_compile_timestamp(OS::GetCurrentMonotonicMicros());
+#ifndef PRODUCT
   CodeObservers::NotifyAll(name,
                            instrs.EntryPoint(),
                            assembler->prologue_offset(),
                            instrs.size(),
                            optimized);
+#endif
   {
     NoSafepointScope no_safepoint;
     const ZoneGrowableArray<intptr_t>& pointer_offsets =
@@ -12882,13 +12920,14 @@
                             bool optimized) {
   // Calling ToLibNamePrefixedQualifiedCString is very expensive,
   // try to avoid it.
+#ifndef PRODUCT
   if (CodeObservers::AreActive()) {
     return FinalizeCode(function.ToLibNamePrefixedQualifiedCString(),
                         assembler,
                         optimized);
-  } else {
-    return FinalizeCode("", assembler, optimized);
   }
+#endif  // !PRODUCT
+  return FinalizeCode("", assembler, optimized);
 }
 
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index ebd93ae..ee8782a 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -314,15 +314,11 @@
 
   bool IsNew() const { return raw()->IsNewObject(); }
   bool IsOld() const { return raw()->IsOldObject(); }
-  bool InVMHeap() const {
 #if defined(DEBUG)
-    if (raw()->IsVMHeapObject()) {
-      Heap* vm_isolate_heap = Dart::vm_isolate()->heap();
-      ASSERT(vm_isolate_heap->Contains(RawObject::ToAddr(raw())));
-    }
-#endif
-    return raw()->IsVMHeapObject();
-  }
+  bool InVMHeap() const;
+#else
+  bool InVMHeap() const { return raw()->IsVMHeapObject(); }
+#endif  // DEBUG
 
   // Print the object on stdout for debugging.
   void Print() const;
@@ -1094,6 +1090,7 @@
     return raw_ptr()->direct_subclasses_;
   }
   void AddDirectSubclass(const Class& subclass) const;
+  void ClearDirectSubclasses() const;
 
   // Check if this class represents the class of null.
   bool IsNullClass() const { return id() == kNullCid; }
@@ -3518,6 +3515,8 @@
   RawLibrary* ImportLibraryAt(intptr_t index) const;
   bool ImportsCorelib() const;
 
+  void DropDependencies() const;
+
   // Resolving native methods for script loaded in the library.
   Dart_NativeEntryResolver native_entry_resolver() const {
     return raw_ptr()->native_entry_resolver_;
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index a3bfae9..a0feb38 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -118,7 +118,7 @@
 }
 
 
-bool ObjectStore::PreallocateObjects() {
+RawError* ObjectStore::PreallocateObjects() {
   Thread* thread = Thread::Current();
   Isolate* isolate = thread->isolate();
   Zone* zone = thread->zone();
@@ -126,7 +126,7 @@
   if (this->stack_overflow() != Instance::null()) {
     ASSERT(this->out_of_memory() != Instance::null());
     ASSERT(this->preallocated_stack_trace() != Stacktrace::null());
-    return true;
+    return Error::null();
   }
   ASSERT(this->stack_overflow() == Instance::null());
   ASSERT(this->out_of_memory() == Instance::null());
@@ -147,7 +147,7 @@
                                             Symbols::Dot(),
                                             Object::empty_array());
   if (result.IsError()) {
-    return false;
+    return Error::Cast(result).raw();
   }
   set_stack_overflow(Instance::Cast(result));
 
@@ -156,7 +156,7 @@
                                             Symbols::Dot(),
                                             Object::empty_array());
   if (result.IsError()) {
-    return false;
+    return Error::Cast(result).raw();
   }
   set_out_of_memory(Instance::Cast(result));
 
@@ -178,7 +178,7 @@
   stack_trace.set_expand_inlined(false);
   set_preallocated_stack_trace(stack_trace);
 
-  return true;
+  return Error::null();
 }
 
 
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 2cab02b..92be955 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -478,9 +478,9 @@
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
   // Called to initialize objects required by the vm but which invoke
-  // dart code.  If an error occurs then false is returned and error
-  // information is stored in Thread::sticky_error().
-  bool PreallocateObjects();
+  // dart code.  If an error occurs the error object is returned otherwise
+  // a null object is returned.
+  RawError* PreallocateObjects();
 
   void InitKnownObjects();
 
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 9dcd09e..5975735 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -21,9 +21,7 @@
 #include "platform/utils.h"
 #include "vm/code_observers.h"
 #include "vm/dart.h"
-#include "vm/debuginfo.h"
 #include "vm/isolate.h"
-#include "vm/vtune.h"
 #include "vm/zone.h"
 
 
@@ -31,12 +29,11 @@
 
 // Android CodeObservers.
 
-DEFINE_FLAG(bool, generate_gdb_symbols, false,
-    "Generate symbols of generated dart functions for debugging with GDB");
+#ifndef PRODUCT
+
 DEFINE_FLAG(bool, generate_perf_events_symbols, false,
     "Generate events symbols for profiling with perf");
 
-
 class PerfCodeObserver : public CodeObserver {
  public:
   PerfCodeObserver() : out_file_(NULL) {
@@ -83,41 +80,7 @@
   DISALLOW_COPY_AND_ASSIGN(PerfCodeObserver);
 };
 
-
-class GdbCodeObserver : public CodeObserver {
- public:
-  GdbCodeObserver() { }
-
-  virtual bool IsActive() const {
-    return FLAG_generate_gdb_symbols;
-  }
-
-  virtual void Notify(const char* name,
-                      uword base,
-                      uword prologue_offset,
-                      uword size,
-                      bool optimized) {
-    if (prologue_offset > 0) {
-      // In order to ensure that gdb sees the first instruction of a function
-      // as the prologue sequence we register two symbols for the cases when
-      // the prologue sequence is not the first instruction:
-      // <name>_entry is used for code preceding the prologue sequence.
-      // <name> for rest of the code (first instruction is prologue sequence).
-      char* pname = OS::SCreate(Thread::Current()->zone(),
-          "%s_%s", name, "entry");
-      DebugInfo::RegisterSection(pname, base, size);
-      DebugInfo::RegisterSection(name,
-                                 (base + prologue_offset),
-                                 (size - prologue_offset));
-    } else {
-      DebugInfo::RegisterSection(name, base, size);
-    }
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GdbCodeObserver);
-};
-
+#endif  // !PRODUCT
 
 const char* OS::Name() {
   return "android";
@@ -427,15 +390,11 @@
 
 
 void OS::RegisterCodeObservers() {
+#ifndef PRODUCT
   if (FLAG_generate_perf_events_symbols) {
     CodeObservers::Register(new PerfCodeObserver);
   }
-  if (FLAG_generate_gdb_symbols) {
-    CodeObservers::Register(new GdbCodeObserver);
-  }
-#if defined(DART_VTUNE_SUPPORT)
-  CodeObservers::Register(new VTuneCodeObserver);
-#endif
+#endif  // !PRODUCT
 }
 
 
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 244e9b7..d97a3a7 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -22,26 +22,21 @@
 #include "platform/utils.h"
 #include "vm/code_observers.h"
 #include "vm/dart.h"
-#include "vm/debuginfo.h"
+#include "vm/flags.h"
 #include "vm/isolate.h"
 #include "vm/lockers.h"
 #include "vm/os_thread.h"
-#include "vm/vtune.h"
 #include "vm/zone.h"
 
 
 namespace dart {
 
-// Linux CodeObservers.
+#ifndef PRODUCT
 
-DEFINE_FLAG(bool, generate_gdb_symbols, false,
-    "Generate symbols of generated dart functions for debugging with GDB");
 DEFINE_FLAG(bool, generate_perf_events_symbols, false,
     "Generate events symbols for profiling with perf");
-DEFINE_FLAG(bool, generate_perf_jitdump, false,
-    "Writes jitdump data for profiling with perf annotate");
 
-
+// Linux CodeObservers.
 class PerfCodeObserver : public CodeObserver {
  public:
   PerfCodeObserver() : out_file_(NULL) {
@@ -92,249 +87,7 @@
 };
 
 
-class GdbCodeObserver : public CodeObserver {
- public:
-  GdbCodeObserver() { }
-
-  virtual bool IsActive() const {
-    return FLAG_generate_gdb_symbols;
-  }
-
-  virtual void Notify(const char* name,
-                      uword base,
-                      uword prologue_offset,
-                      uword size,
-                      bool optimized) {
-    if (prologue_offset > 0) {
-      // In order to ensure that gdb sees the first instruction of a function
-      // as the prologue sequence we register two symbols for the cases when
-      // the prologue sequence is not the first instruction:
-      // <name>_entry is used for code preceding the prologue sequence.
-      // <name> for rest of the code (first instruction is prologue sequence).
-      char* pname = OS::SCreate(Thread::Current()->zone(),
-          "%s_%s", name, "entry");
-      DebugInfo::RegisterSection(pname, base, size);
-      DebugInfo::RegisterSection(name,
-                                 (base + prologue_offset),
-                                 (size - prologue_offset));
-    } else {
-      DebugInfo::RegisterSection(name, base, size);
-    }
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(GdbCodeObserver);
-};
-
-
-#define CLOCKFD 3
-#define FD_TO_CLOCKID(fd)       ((~(clockid_t) (fd) << 3) | CLOCKFD)  // NOLINT
-
-class JitdumpCodeObserver : public CodeObserver {
- public:
-  JitdumpCodeObserver() {
-    ASSERT(FLAG_generate_perf_jitdump);
-    out_file_ = NULL;
-    clock_fd_ = -1;
-    clock_id_ = kInvalidClockId;
-    code_sequence_ = 0;
-    Dart_FileOpenCallback file_open = Isolate::file_open_callback();
-    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
-    Dart_FileCloseCallback file_close = Isolate::file_close_callback();
-    if ((file_open == NULL) || (file_write == NULL) || (file_close == NULL)) {
-      return;
-    }
-    // The Jitdump code observer writes all jitted code into the file
-    // 'perf.jitdump' in the current working directory. We open the file once
-    // on initialization and close it when the VM is going down.
-    {
-      // Open the file.
-      const char* filename = "perf.jitdump";
-      out_file_ = (*file_open)(filename, true);
-      ASSERT(out_file_ != NULL);
-      // Write the jit dump header.
-      WriteHeader();
-    }
-    // perf uses an internal clock and because our output is merged with data
-    // collected by perf our timestamps must be consistent. Using
-    // the posix-clock-module (/dev/trace_clock) as our time source ensures
-    // we are consistent with the perf timestamps.
-    clock_id_ = kInvalidClockId;
-    clock_fd_ = open("/dev/trace_clock", O_RDONLY);
-    if (clock_fd_ >= 0) {
-      clock_id_ = FD_TO_CLOCKID(clock_fd_);
-    }
-  }
-
-  ~JitdumpCodeObserver() {
-    Dart_FileCloseCallback file_close = Isolate::file_close_callback();
-    if (file_close == NULL) {
-      return;
-    }
-    ASSERT(out_file_ != NULL);
-    (*file_close)(out_file_);
-    if (clock_fd_ >= 0) {
-      close(clock_fd_);
-    }
-  }
-
-  virtual bool IsActive() const {
-    return FLAG_generate_perf_jitdump && (out_file_ != NULL);
-  }
-
-  virtual void Notify(const char* name,
-                      uword base,
-                      uword prologue_offset,
-                      uword size,
-                      bool optimized) {
-    WriteCodeLoad(name, base, prologue_offset, size, optimized);
-  }
-
- private:
-  static const uint32_t kJitHeaderMagic = 0x4A695444;
-  static const uint32_t kJitHeaderMagicSw = 0x4454694A;
-  static const uint32_t kJitHeaderVersion = 0x1;
-  static const uint32_t kElfMachIA32 = 3;
-  static const uint32_t kElfMachX64 = 62;
-  static const uint32_t kElfMachARM = 40;
-  // TODO(zra): Find the right ARM64 constant.
-  static const uint32_t kElfMachARM64 = 40;
-  static const uint32_t kElfMachMIPS = 10;
-  static const int kInvalidClockId = -1;
-
-  struct jitheader {
-    uint32_t magic;   /* characters "jItD" */
-    uint32_t version; /* header version */
-    uint32_t total_size;  /* total size of header */
-    uint32_t elf_mach;  /* elf mach target */
-    uint32_t pad1;    /* reserved */
-    uint32_t pid;   /* JIT process id */
-    uint64_t timestamp; /* timestamp */
-  };
-
-  /* record prefix (mandatory in each record) */
-  struct jr_prefix {
-    uint32_t id;
-    uint32_t total_size;
-    uint64_t timestamp;
-  };
-
-  enum jit_record_type {
-    JIT_CODE_LOAD = 0,
-    /* JIT_CODE_MOVE = 1, */
-    /* JIT_CODE_DEBUG_INFO = 2, */
-    /* JIT_CODE_CLOSE = 3, */
-    JIT_CODE_MAX = 4,
-  };
-
-  struct jr_code_load {
-    struct jr_prefix prefix;
-    uint32_t pid;
-    uint32_t tid;
-    uint64_t vma;
-    uint64_t code_addr;
-    uint64_t code_size;
-    uint64_t code_index;
-  };
-
-  const char* GenerateCodeName(const char* name, bool optimized) {
-    const char* marker = optimized ? "*" : "";
-    return OS::SCreate(Thread::Current()->zone(), "%s%s", marker, name);
-  }
-
-  uint32_t GetElfMach() {
-#if defined(TARGET_ARCH_IA32)
-    return kElfMachIA32;
-#elif defined(TARGET_ARCH_X64)
-    return kElfMachX64;
-#elif defined(TARGET_ARCH_ARM)
-    return kElfMachARM;
-#elif defined(TARGET_ARCH_ARM64)
-    return kElfMachARM64;
-#elif defined(TARGET_ARCH_MIPS)
-    return kElfMachMIPS;
-#else
-#error Unknown architecture.
-#endif
-  }
-
-  pid_t gettid() {
-    // libc doesn't wrap the Linux-specific gettid system call.
-    // Note that this thread id is not the same as the posix thread id.
-    return syscall(SYS_gettid);
-  }
-
-  uint64_t GetKernelTimeNanos() {
-    if (clock_id_ != kInvalidClockId) {
-      struct timespec ts;
-      int r = clock_gettime(clock_id_, &ts);
-      ASSERT(r == 0);
-      uint64_t nanos = static_cast<uint64_t>(ts.tv_sec) *
-                       static_cast<uint64_t>(kNanosecondsPerSecond);
-      nanos += static_cast<uint64_t>(ts.tv_nsec);
-      return nanos;
-    } else {
-      return OS::GetCurrentTimeMicros() * kNanosecondsPerMicrosecond;
-    }
-  }
-
-  void WriteHeader() {
-    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
-    ASSERT(file_write != NULL);
-    ASSERT(out_file_ != NULL);
-    jitheader header;
-    header.magic = kJitHeaderMagic;
-    header.version = kJitHeaderVersion;
-    header.total_size = sizeof(jitheader);
-    header.pad1 = 0x0;
-    header.elf_mach = GetElfMach();
-    header.pid = getpid();
-    header.timestamp = GetKernelTimeNanos();
-    {
-      MutexLocker ml(CodeObservers::mutex());
-      (*file_write)(&header, sizeof(header), out_file_);
-    }
-  }
-
-  void WriteCodeLoad(const char* name, uword base, uword prologue_offset,
-                     uword code_size, bool optimized) {
-    Dart_FileWriteCallback file_write = Isolate::file_write_callback();
-    ASSERT(file_write != NULL);
-    ASSERT(out_file_ != NULL);
-
-    const char* code_name = GenerateCodeName(name, optimized);
-    const intptr_t code_name_size = strlen(code_name) + 1;
-    uint8_t* code_pointer = reinterpret_cast<uint8_t*>(base);
-
-    jr_code_load code_load;
-    code_load.prefix.id = JIT_CODE_LOAD;
-    code_load.prefix.total_size =
-        sizeof(code_load) + code_name_size + code_size;
-    code_load.prefix.timestamp = GetKernelTimeNanos();
-    code_load.pid = getpid();
-    code_load.tid = gettid();
-    code_load.vma = 0x0;  //  Our addresses are absolute.
-    code_load.code_addr = base;
-    code_load.code_size = code_size;
-
-    {
-      MutexLocker ml(CodeObservers::mutex());
-      // Set this field under the index.
-      code_load.code_index = code_sequence_++;
-      // Write structures.
-      (*file_write)(&code_load, sizeof(code_load), out_file_);
-      (*file_write)(code_name, code_name_size, out_file_);
-      (*file_write)(code_pointer, code_size, out_file_);
-    }
-  }
-
-  void* out_file_;
-  int clock_fd_;
-  int clock_id_;
-  uint64_t code_sequence_;
-  DISALLOW_COPY_AND_ASSIGN(JitdumpCodeObserver);
-};
-
+#endif  // !PRODUCT
 
 const char* OS::Name() {
   return "linux";
@@ -617,18 +370,11 @@
 
 
 void OS::RegisterCodeObservers() {
+#ifndef PRODUCT
   if (FLAG_generate_perf_events_symbols) {
     CodeObservers::Register(new PerfCodeObserver);
   }
-  if (FLAG_generate_gdb_symbols) {
-    CodeObservers::Register(new GdbCodeObserver);
-  }
-  if (FLAG_generate_perf_jitdump) {
-    CodeObservers::Register(new JitdumpCodeObserver);
-  }
-#if defined(DART_VTUNE_SUPPORT)
-  CodeObservers::Register(new VTuneCodeObserver);
-#endif
+#endif  // !PRODUCT
 }
 
 
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 603ade6..2548a4c 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -14,7 +14,6 @@
 #include "platform/utils.h"
 #include "platform/assert.h"
 #include "vm/os_thread.h"
-#include "vm/vtune.h"
 #include "vm/zone.h"
 
 namespace dart {
@@ -365,9 +364,6 @@
 
 
 void OS::RegisterCodeObservers() {
-#if defined(DART_VTUNE_SUPPORT)
-  CodeObservers::Register(new VTuneCodeObserver);
-#endif
 }
 
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 048c184..9571669 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -28,7 +28,6 @@
 #include "vm/object_store.h"
 #include "vm/os.h"
 #include "vm/regexp_assembler.h"
-#include "vm/report.h"
 #include "vm/resolver.h"
 #include "vm/safepoint.h"
 #include "vm/scanner.h"
@@ -42,8 +41,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, enable_debug_break, false, "Allow use of break \"message\".");
-DEFINE_FLAG(bool, enable_mirrors, true,
-    "Disable to make importing dart:mirrors an error.");
 DEFINE_FLAG(bool, load_deferred_eagerly, false,
     "Load deferred libraries eagerly.");
 DEFINE_FLAG(bool, trace_parser, false, "Trace parser operations.");
@@ -56,7 +53,6 @@
 DEFINE_FLAG(bool, await_is_keyword, false,
     "await and yield are treated as proper keywords in synchronous code.");
 
-DECLARE_FLAG(bool, lazy_dispatchers);
 DECLARE_FLAG(bool, load_deferred_eagerly);
 DECLARE_FLAG(bool, profile_vm);
 
@@ -160,6 +156,20 @@
 }
 
 
+void ParsedFunction::AddToGuardedFields(const Field* field) const {
+  if ((field->guarded_cid() == kDynamicCid) ||
+      (field->guarded_cid() == kIllegalCid)) {
+    return;
+  }
+  for (intptr_t j = 0; j < guarded_fields_->length(); j++) {
+    if ((*guarded_fields_)[j]->raw() == field->raw()) {
+      return;
+    }
+  }
+  guarded_fields_->Add(field);
+}
+
+
 LocalVariable* ParsedFunction::EnsureExpressionTemp() {
   if (!has_expression_temp_var()) {
     LocalVariable* temp =
@@ -14335,12 +14345,16 @@
 
 namespace dart {
 
-DEFINE_FLAG(bool, enable_mirrors, true,
-    "Disable to make importing dart:mirrors an error.");
 DEFINE_FLAG(bool, load_deferred_eagerly, false,
     "Load deferred libraries eagerly.");
 DEFINE_FLAG(bool, link_natives_lazily, false, "Link native calls lazily");
 
+
+void ParsedFunction::AddToGuardedFields(const Field* field) const {
+  UNREACHABLE();
+}
+
+
 LocalVariable* ParsedFunction::EnsureExpressionTemp() {
   UNREACHABLE();
   return NULL;
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index ebf38d3..dcd03a6 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -166,6 +166,10 @@
   Isolate* isolate() const { return thread_->isolate(); }
   Zone* zone() const { return thread_->zone(); }
 
+  // Adds only relevant fields: field must be unique and its guarded_cid()
+  // relevant.
+  void AddToGuardedFields(const Field* field) const;
+
  private:
   Thread* thread_;
   const Function& function_;
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 65b6166..ce5ca5e 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -4,6 +4,7 @@
 
 #include "vm/precompiler.h"
 
+#include "vm/aot_optimizer.h"
 #include "vm/assembler.h"
 #include "vm/ast_printer.h"
 #include "vm/branch_optimizer.h"
@@ -21,7 +22,6 @@
 #include "vm/flow_graph_builder.h"
 #include "vm/flow_graph_compiler.h"
 #include "vm/flow_graph_inliner.h"
-#include "vm/flow_graph_optimizer.h"
 #include "vm/flow_graph_range_analysis.h"
 #include "vm/flow_graph_type_propagator.h"
 #include "vm/hash_table.h"
@@ -140,12 +140,19 @@
     selector_count_(0),
     dropped_function_count_(0),
     dropped_field_count_(0),
+    dropped_class_count_(0),
+    dropped_typearg_count_(0),
+    dropped_type_count_(0),
+    dropped_library_count_(0),
     libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())),
     pending_functions_(
         GrowableObjectArray::Handle(GrowableObjectArray::New())),
     sent_selectors_(),
     enqueued_functions_(),
     fields_to_retain_(),
+    classes_to_retain_(),
+    typeargs_to_retain_(),
+    types_to_retain_(),
     error_(Error::Handle()) {
 }
 
@@ -166,7 +173,7 @@
     const intptr_t kPrecompilerRounds = 1;
     for (intptr_t round = 0; round < kPrecompilerRounds; round++) {
       if (FLAG_trace_precompiler) {
-        OS::Print("Precompiler round %" Pd "\n", round);
+        THR_Print("Precompiler round %" Pd "\n", round);
       }
 
       if (round > 0) {
@@ -197,8 +204,11 @@
 
     DropFunctions();
     DropFields();
-
-    // TODO(rmacnak): DropEmptyClasses();
+    TraceTypesFromRetainedClasses();
+    DropTypes();
+    DropTypeArguments();
+    DropClasses();
+    DropLibraries();
 
     BindStaticCalls();
 
@@ -219,15 +229,17 @@
   intptr_t dropped_symbols_count = Symbols::Compact(I);
 
   if (FLAG_trace_precompiler) {
-    THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types,"
-              " %" Pd " dynamic selectors.\n Dropped %" Pd " functions, %" Pd
-              " fields, %" Pd " symbols.\n",
-              function_count_,
-              class_count_,
-              selector_count_,
-              dropped_function_count_,
-              dropped_field_count_,
-              dropped_symbols_count);
+    THR_Print("Precompiled %" Pd " functions,", function_count_);
+    THR_Print(" %" Pd " dynamic types,", class_count_);
+    THR_Print(" %" Pd " dynamic selectors.\n", selector_count_);
+
+    THR_Print("Dropped %" Pd " functions,", dropped_function_count_);
+    THR_Print(" %" Pd " fields,", dropped_field_count_);
+    THR_Print(" %" Pd " symbols,", dropped_symbols_count);
+    THR_Print(" %" Pd " types,", dropped_type_count_);
+    THR_Print(" %" Pd " type arguments,", dropped_typearg_count_);
+    THR_Print(" %" Pd " classes,", dropped_class_count_);
+    THR_Print(" %" Pd " libraries.\n", dropped_library_count_);
   }
 }
 
@@ -236,6 +248,7 @@
   class ClearCodeFunctionVisitor : public FunctionVisitor {
     void VisitFunction(const Function& function) {
       function.ClearCode();
+      function.ClearICDataArray();
     }
   };
   ClearCodeFunctionVisitor visitor;
@@ -252,84 +265,25 @@
   AddSelector(Symbols::Call());  // For speed, not correctness.
 
   // Allocated from C++.
-  static const intptr_t kExternallyAllocatedCids[] = {
-    kBoolCid,
-    kNullCid,
-    kClosureCid,
-
-    kSmiCid,
-    kMintCid,
-    kBigintCid,
-    kDoubleCid,
-
-    kOneByteStringCid,
-    kTwoByteStringCid,
-    kExternalOneByteStringCid,
-    kExternalTwoByteStringCid,
-
-    kArrayCid,
-    kImmutableArrayCid,
-    kGrowableObjectArrayCid,
-    kLinkedHashMapCid,
-
-    kTypedDataUint8ClampedArrayCid,
-    kTypedDataUint8ArrayCid,
-    kTypedDataUint16ArrayCid,
-    kTypedDataUint32ArrayCid,
-    kTypedDataUint64ArrayCid,
-    kTypedDataInt8ArrayCid,
-    kTypedDataInt16ArrayCid,
-    kTypedDataInt32ArrayCid,
-    kTypedDataInt64ArrayCid,
-
-    kExternalTypedDataUint8ArrayCid,
-    kExternalTypedDataUint16ArrayCid,
-    kExternalTypedDataUint32ArrayCid,
-    kExternalTypedDataUint64ArrayCid,
-    kExternalTypedDataInt8ArrayCid,
-    kExternalTypedDataInt16ArrayCid,
-    kExternalTypedDataInt32ArrayCid,
-    kExternalTypedDataInt64ArrayCid,
-
-    kTypedDataFloat32ArrayCid,
-    kTypedDataFloat64ArrayCid,
-
-    kTypedDataFloat32x4ArrayCid,
-    kTypedDataInt32x4ArrayCid,
-    kTypedDataFloat64x2ArrayCid,
-
-    kInt32x4Cid,
-    kFloat32x4Cid,
-    kFloat64x2Cid,
-
-    kTypeCid,
-    kFunctionTypeCid,
-    kTypeRefCid,
-    kTypeParameterCid,
-    kBoundedTypeCid,
-    kLibraryPrefixCid,
-
-    kJSRegExpCid,
-    kUserTagCid,
-    kStacktraceCid,
-    kWeakPropertyCid,
-    kCapabilityCid,
-    ReceivePort::kClassId,
-    SendPort::kClassId,
-
-    kIllegalCid
-  };
-
   Class& cls = Class::Handle(Z);
-  for (intptr_t i = 0; kExternallyAllocatedCids[i] != kIllegalCid; i++) {
-    cls = isolate()->class_table()->At(kExternallyAllocatedCids[i]);
+  for (intptr_t cid = kInstanceCid; cid < kNumPredefinedCids; cid++) {
+    ASSERT(isolate()->class_table()->IsValidIndex(cid));
+    if (!isolate()->class_table()->HasValidClassAt(cid)) {
+      continue;
+    }
+    if ((cid == kDynamicCid) ||
+        (cid == kVoidCid) ||
+        (cid == kFreeListElement)) {
+      continue;
+    }
+    cls = isolate()->class_table()->At(cid);
     AddInstantiatedClass(cls);
   }
 
   Dart_QualifiedFunctionName vm_entry_points[] = {
     // Functions
     { "dart:async", "::", "_setScheduleImmediateClosure" },
-    { "dart:core", "::", "_completeDeferredLoads"},
+    { "dart:core", "::", "_completeDeferredLoads" },
     { "dart:core", "AbstractClassInstantiationError",
                    "AbstractClassInstantiationError._create" },
     { "dart:core", "ArgumentError", "ArgumentError." },
@@ -483,6 +437,8 @@
     if (!error_.IsNull()) {
       Jump(error_);
     }
+    // Used in the JIT to save type-feedback across compilations.
+    function.ClearICDataArray();
   } else {
     if (FLAG_trace_precompiler) {
       // This function was compiled from somewhere other than Precompiler,
@@ -510,7 +466,7 @@
   for (intptr_t i = 0; i < table.Length(); i++) {
     entry = table.At(i);
     if (entry.IsFunction()) {
-      target ^= table.At(i);
+      target ^= entry.raw();
       AddFunction(target);
     }
   }
@@ -532,9 +488,8 @@
       entry = pool.ObjectAt(i);
       if (entry.IsICData()) {
         call_site ^= entry.raw();
-        if (call_site.NumberOfChecks() == 1) {
-          // Probably a static call.
-          target = call_site.GetTargetAt(0);
+        for (intptr_t j = 0; j < call_site.NumberOfChecks(); j++) {
+          target = call_site.GetTargetAt(j);
           AddFunction(target);
           if (!target.is_static()) {
             // Super call (should not enqueue selector) or dynamic call with a
@@ -542,7 +497,8 @@
             selector = call_site.target_name();
             AddSelector(selector);
           }
-        } else {
+        }
+        if (call_site.NumberOfChecks() == 0) {
           // A dynamic call.
           selector = call_site.target_name();
           AddSelector(selector);
@@ -563,7 +519,11 @@
       } else if (entry.IsInstance()) {
         // Const object, literal or args descriptor.
         instance ^= entry.raw();
-        AddConstObject(instance);
+        if (entry.IsAbstractType()) {
+          AddType(AbstractType::Cast(entry));
+        } else {
+          AddConstObject(instance);
+        }
       } else if (entry.IsFunction()) {
         // Local closure function.
         target ^= entry.raw();
@@ -574,12 +534,99 @@
           cls ^= target_code.owner();
           AddInstantiatedClass(cls);
         }
+      } else if (entry.IsTypeArguments()) {
+        AddTypeArguments(TypeArguments::Cast(entry));
       }
     }
   }
 }
 
 
+void Precompiler::AddTypesOf(const Class& cls) {
+  if (cls.IsNull()) return;
+  if (classes_to_retain_.Lookup(&cls) != NULL) return;
+  classes_to_retain_.Insert(&Class::ZoneHandle(Z, cls.raw()));
+
+  Array& interfaces = Array::Handle(Z, cls.interfaces());
+  AbstractType& type = AbstractType::Handle(Z);
+  for (intptr_t i = 0; i < interfaces.Length(); i++) {
+    type ^= interfaces.At(i);
+    AddType(type);
+  }
+
+  AddTypeArguments(TypeArguments::Handle(Z, cls.type_parameters()));
+
+  type = cls.super_type();
+  AddType(type);
+
+  type = cls.mixin();
+  AddType(type);
+
+  if (cls.IsTypedefClass()) {
+    AddTypesOf(Function::Handle(Z, cls.signature_function()));
+  }
+}
+
+
+void Precompiler::AddTypesOf(const Function& function) {
+  AbstractType& type = AbstractType::Handle(Z);
+  type = function.result_type();
+  AddType(type);
+  for (intptr_t i = 0; i < function.NumParameters(); i++) {
+    type = function.ParameterTypeAt(i);
+    AddType(type);
+  }
+}
+
+
+void Precompiler::AddType(const AbstractType& abstype) {
+  if (abstype.IsNull()) return;
+
+  if (types_to_retain_.Lookup(&abstype) != NULL) return;
+  types_to_retain_.Insert(&AbstractType::ZoneHandle(Z, abstype.raw()));
+
+  if (abstype.IsType()) {
+    const Type& type = Type::Cast(abstype);
+    const Class& cls = Class::Handle(Z, type.type_class());
+    AddTypesOf(cls);
+    const TypeArguments& vector = TypeArguments::Handle(Z, abstype.arguments());
+    AddTypeArguments(vector);
+  } else if (abstype.IsFunctionType()) {
+    const FunctionType& func_type = FunctionType::Cast(abstype);
+    const Class& cls = Class::Handle(Z, func_type.scope_class());
+    AddTypesOf(cls);
+    const Function& func = Function::Handle(Z, func_type.signature());
+    AddTypesOf(func);
+    const TypeArguments& vector = TypeArguments::Handle(Z, abstype.arguments());
+    AddTypeArguments(vector);
+  } else if (abstype.IsBoundedType()) {
+    AbstractType& type = AbstractType::Handle(Z);
+    type = BoundedType::Cast(abstype).type();
+    AddType(type);
+    type = BoundedType::Cast(abstype).bound();
+    AddType(type);
+  } else if (abstype.IsTypeRef()) {
+    AbstractType& type = AbstractType::Handle(Z);
+    type = TypeRef::Cast(abstype).type();
+    AddType(type);
+  }
+}
+
+
+void Precompiler::AddTypeArguments(const TypeArguments& args) {
+  if (args.IsNull()) return;
+
+  if (typeargs_to_retain_.Lookup(&args) != NULL) return;
+  typeargs_to_retain_.Insert(&TypeArguments::ZoneHandle(Z, args.raw()));
+
+  AbstractType& arg = AbstractType::Handle(Z);
+  for (intptr_t i = 0; i < args.Length(); i++) {
+    arg = args.TypeAt(i);
+    AddType(arg);
+  }
+}
+
+
 void Precompiler::AddConstObject(const Instance& instance) {
   const Class& cls = Class::Handle(Z, instance.clazz());
   AddInstantiatedClass(cls);
@@ -590,6 +637,7 @@
         Function::Handle(Z, Closure::Cast(instance).function());
     ASSERT(func.is_static());
     AddFunction(func);
+    AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments()));
     return;
   }
 
@@ -600,6 +648,10 @@
   // argument descriptors.
   if (!instance.IsCanonical()) return;
 
+  if (cls.NumTypeArguments() > 0) {
+    AddTypeArguments(TypeArguments::Handle(Z, instance.GetTypeArguments()));
+  }
+
   class ConstObjectVisitor : public ObjectPointerVisitor {
    public:
     ConstObjectVisitor(Precompiler* precompiler, Isolate* isolate) :
@@ -682,7 +734,7 @@
   ASSERT(field.is_static());
   if (field.HasPrecompiledInitializer()) {
     // TODO(rmacnak): Investigate why this happens for _enum_names.
-    OS::Print("Warning: Ignoring repeated request for initializer for %s\n",
+    THR_Print("Warning: Ignoring repeated request for initializer for %s\n",
               field.ToCString());
     return Function::null();
   }
@@ -975,33 +1027,6 @@
 typedef UnorderedHashMap<NameFunctionsTraits> Table;
 
 
-class FunctionsTraits {
- public:
-  static bool IsMatch(const Object& a, const Object& b) {
-    Zone* zone = Thread::Current()->zone();
-    String& a_s = String::Handle(zone);
-    String& b_s = String::Handle(zone);
-    a_s = a.IsFunction() ? Function::Cast(a).name() : String::Cast(a).raw();
-    b_s = b.IsFunction() ? Function::Cast(b).name() : String::Cast(b).raw();
-    ASSERT(a_s.IsSymbol() && b_s.IsSymbol());
-    return a_s.raw() == b_s.raw();
-  }
-  static uword Hash(const Object& obj) {
-    if (obj.IsFunction()) {
-      return String::Handle(Function::Cast(obj).name()).Hash();
-    } else {
-      ASSERT(String::Cast(obj).IsSymbol());
-      return String::Cast(obj).Hash();
-    }
-  }
-  static RawObject* NewKey(const Function& function) {
-    return function.raw();
-  }
-};
-
-typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet;
-
-
 static void AddNameToFunctionsTable(Zone* zone,
                                     Table* table,
                                     const String& fname,
@@ -1142,6 +1167,7 @@
         if (retain) {
           retained_functions.Add(function);
           function.DropUncompiledImplicitClosureFunction();
+          AddTypesOf(function);
         } else {
           bool top_level = cls.IsTopLevel();
           if (top_level &&
@@ -1173,8 +1199,10 @@
   retained_functions = GrowableObjectArray::New();
   for (intptr_t j = 0; j < closures.Length(); j++) {
     function ^= closures.At(j);
-    if (function.HasCode()) {
+    bool retain = function.HasCode();
+    if (retain) {
       retained_functions.Add(function);
+      AddTypesOf(function);
     } else {
       dropped_function_count_++;
       if (FLAG_trace_precompiler) {
@@ -1194,6 +1222,7 @@
   Field& field = Field::Handle(Z);
   GrowableObjectArray& retained_fields = GrowableObjectArray::Handle(Z);
   String& name = String::Handle(Z);
+  AbstractType& type = AbstractType::Handle(Z);
 
   for (intptr_t i = 0; i < libraries_.Length(); i++) {
     lib ^= libraries_.At(i);
@@ -1211,6 +1240,8 @@
         bool retain = fields_to_retain_.Lookup(&field) != NULL;
         if (retain) {
           retained_fields.Add(field);
+          type = field.type();
+          AddType(type);
         } else {
           bool top_level = cls.IsTopLevel();
           if (top_level) {
@@ -1237,6 +1268,249 @@
 }
 
 
+void Precompiler::DropTypes() {
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+  Object& obj = Object::Handle(Z);
+  Array& arr = Array::Handle(Z);
+  GrowableObjectArray& retained_types = GrowableObjectArray::Handle(Z);
+  AbstractType& type = AbstractType::Handle(Z);
+
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+      obj = cls.canonical_types();
+      if (!obj.IsArray()) {
+        // Class only has one type, keep it.
+      } else {
+        // Class has many types.
+        arr ^= obj.raw();
+        retained_types = GrowableObjectArray::New();
+
+        // Always keep the first one.
+        ASSERT(arr.Length() >= 1);
+        obj = arr.At(0);
+        retained_types.Add(obj);
+
+        for (intptr_t i = 1; i < arr.Length(); i++) {
+          obj = arr.At(i);
+          if (obj.IsNull()) {
+            continue;
+          }
+          type ^= obj.raw();
+          bool retain = types_to_retain_.Lookup(&type) != NULL;
+          if (retain) {
+            retained_types.Add(type);
+          } else {
+            dropped_type_count_++;
+          }
+        }
+        arr = Array::MakeArray(retained_types);
+        cls.set_canonical_types(arr);
+      }
+    }
+  }
+}
+
+
+void Precompiler::DropTypeArguments() {
+  const Array& typeargs_table =
+      Array::Handle(Z, I->object_store()->canonical_type_arguments());
+  GrowableObjectArray& retained_typeargs =
+      GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+  TypeArguments& typeargs = TypeArguments::Handle(Z);
+  for (intptr_t i = 0; i < (typeargs_table.Length() - 1); i++) {
+    typeargs ^= typeargs_table.At(i);
+    bool retain = typeargs_to_retain_.Lookup(&typeargs) != NULL;
+    if (retain) {
+      retained_typeargs.Add(typeargs);
+    } else {
+      dropped_typearg_count_++;
+    }
+  }
+
+  const intptr_t dict_size =
+      Utils::RoundUpToPowerOfTwo(retained_typeargs.Length() * 4 / 3);
+  const Array& new_table = Array::Handle(Z, Array::New(dict_size + 1));
+
+  Object& element = Object::Handle(Z);
+  for (intptr_t i = 0; i < retained_typeargs.Length(); i++) {
+    typeargs ^= retained_typeargs.At(i);
+    intptr_t hash = typeargs.Hash();
+    intptr_t index = hash & (dict_size - 1);
+    element = new_table.At(index);
+    while (!element.IsNull()) {
+      index = (index + 1) & (dict_size - 1);
+      element = new_table.At(index);
+    }
+    new_table.SetAt(index, typeargs);
+  }
+
+  const Smi& used = Smi::Handle(Z, Smi::New(retained_typeargs.Length()));
+  new_table.SetAt(dict_size, used);
+
+  I->object_store()->set_canonical_type_arguments(new_table);
+}
+
+
+void Precompiler::TraceTypesFromRetainedClasses() {
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+  Array& members = Array::Handle(Z);
+
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+
+      // The subclasses array is only needed for CHA.
+      cls.ClearDirectSubclasses();
+
+      bool retain = false;
+      members = cls.fields();
+      if (members.Length() > 0) {
+        retain = true;
+      }
+      members = cls.functions();
+      if (members.Length() > 0) {
+        retain = true;
+      }
+      if (cls.is_allocated()) {
+        retain = true;
+      }
+      if (cls.is_enum_class()) {
+        // Enum classes have live instances, so we cannot unregister
+        // them.
+        retain = true;
+      }
+      members = cls.constants();
+      if (members.Length() > 0) {
+        // --compile_all?
+        retain = true;
+      }
+
+      if (retain) {
+        AddTypesOf(cls);
+      }
+    }
+  }
+}
+
+
+void Precompiler::DropClasses() {
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+  Array& members = Array::Handle(Z);
+  String& name = String::Handle(Z);
+
+#if defined(DEBUG)
+  {
+    // Force GC for allocation stats.
+    I->heap()->CollectAllGarbage();
+  }
+#endif
+
+  ClassTable* class_table = I->class_table();
+  intptr_t num_cids = class_table->NumCids();
+
+  for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
+    if (!class_table->IsValidIndex(cid)) continue;
+    if (!class_table->HasValidClassAt(cid)) continue;
+
+    cls = class_table->At(cid);
+    ASSERT(!cls.IsNull());
+
+    if (cls.IsTopLevel()) {
+      // Top-level classes are referenced directly from their library. They
+      // will only be removed as a consequence of an entire library being
+      // removed.
+      continue;
+    }
+    if (cls.is_enum_class()) {
+      // Enum classes have live instances, so we cannot unregister
+      // them.
+      continue;
+    }
+    members = cls.constants();
+    if (members.Length() > 0) {
+      // --compile_all?
+      continue;
+    }
+
+    bool retain = classes_to_retain_.Lookup(&cls) != NULL;
+    if (retain) {
+      continue;
+    }
+
+#if defined(DEBUG)
+    intptr_t instances =
+        class_table->StatsWithUpdatedSize(cid)->post_gc.new_count +
+        class_table->StatsWithUpdatedSize(cid)->post_gc.old_count;
+    if (instances != 0) {
+      FATAL2("Want to drop class %s, but it has %" Pd " instances\n",
+             cls.ToCString(),
+             instances);
+    }
+#endif
+
+    dropped_class_count_++;
+    if (FLAG_trace_precompiler) {
+      THR_Print("Precompilation dropping %" Pd " %s\n", cid, cls.ToCString());
+    }
+
+#if defined(DEBUG)
+    class_table->Unregister(cid);
+#endif
+    cls.set_id(kIllegalCid);  // We check this when serializing.
+
+    lib = cls.library();
+    name = cls.DictionaryName();
+    lib.RemoveObject(cls, name);
+  }
+}
+
+
+void Precompiler::DropLibraries() {
+  const GrowableObjectArray& retained_libraries =
+      GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+  Library& lib = Library::Handle(Z);
+
+  for (intptr_t i = 0; i < libraries_.Length(); i++) {
+    lib ^= libraries_.At(i);
+    lib.DropDependencies();
+    intptr_t entries = 0;
+    DictionaryIterator it(lib);
+    while (it.HasNext()) {
+      it.GetNext();
+      entries++;
+    }
+    bool retain = (entries > 0) || lib.is_dart_scheme();
+    if (retain) {
+      lib.set_index(retained_libraries.Length());
+      retained_libraries.Add(lib);
+    } else {
+      dropped_library_count_++;
+      lib.set_index(-1);
+      if (FLAG_trace_precompiler) {
+        THR_Print("Precompilation dropping %s\n", lib.ToCString());
+      }
+    }
+  }
+
+  I->object_store()->set_libraries(retained_libraries);
+  libraries_ = retained_libraries.raw();
+}
+
+
 void Precompiler::BindStaticCalls() {
   class BindStaticCallsVisitor : public FunctionVisitor {
    public:
@@ -1713,9 +1987,9 @@
         caller_inline_id.Add(-1);
         CSTAT_TIMER_SCOPE(thread(), graphoptimizer_timer);
 
-        FlowGraphOptimizer optimizer(flow_graph,
-                                     use_speculative_inlining,
-                                     &inlining_black_list);
+        AotOptimizer optimizer(flow_graph,
+                               use_speculative_inlining,
+                               &inlining_black_list);
         optimizer.PopulateWithICData();
 
         optimizer.ApplyClassIds();
@@ -1781,10 +2055,10 @@
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
         // Do optimizations that depend on the propagated type information.
-        if (optimizer.Canonicalize()) {
+        if (flow_graph->Canonicalize()) {
           // Invoke Canonicalize twice in order to fully canonicalize patterns
           // like "if (a & const == 0) { }".
-          optimizer.Canonicalize();
+          flow_graph->Canonicalize();
         }
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
@@ -1810,7 +2084,7 @@
           ConstantPropagator::Optimize(flow_graph);
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
           // A canonicalization pass to remove e.g. smi checks on smi constants.
-          optimizer.Canonicalize();
+          flow_graph->Canonicalize();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
           // Canonicalization introduced more opportunities for constant
           // propagation.
@@ -1840,12 +2114,12 @@
 #endif  // !PRODUCT
           // Where beneficial convert Smi operations into Int32 operations.
           // Only meanigful for 32bit platforms right now.
-          optimizer.WidenSmiToInt32();
+          flow_graph->WidenSmiToInt32();
 
           // Unbox doubles. Performed after constant propagation to minimize
           // interference from phis merging double values and tagged
           // values coming from dead paths.
-          optimizer.SelectRepresentations();
+          flow_graph->SelectRepresentations();
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
 
@@ -1863,12 +2137,12 @@
           if (FLAG_common_subexpression_elimination) {
             if (DominatorBasedCSE::Optimize(flow_graph)) {
               DEBUG_ASSERT(flow_graph->VerifyUseLists());
-              optimizer.Canonicalize();
+              flow_graph->Canonicalize();
               // Do another round of CSE to take secondary effects into account:
               // e.g. when eliminating dependent loads (a.x[0] + a.x[0])
               // TODO(fschneider): Change to a one-pass optimization pass.
               if (DominatorBasedCSE::Optimize(flow_graph)) {
-                optimizer.Canonicalize();
+                flow_graph->Canonicalize();
               }
               DEBUG_ASSERT(flow_graph->VerifyUseLists());
             }
@@ -1950,7 +2224,7 @@
         // Detach environments from the instructions that can't deoptimize.
         // Do it before we attempt to perform allocation sinking to minimize
         // amount of materializations it has to perform.
-        optimizer.EliminateEnvironments();
+        flow_graph->EliminateEnvironments();
 
         {
 #ifndef PRODUCT
@@ -1962,8 +2236,8 @@
           DEBUG_ASSERT(flow_graph->VerifyUseLists());
         }
 
-        if (optimizer.Canonicalize()) {
-          optimizer.Canonicalize();
+        if (flow_graph->Canonicalize()) {
+          flow_graph->Canonicalize();
         }
 
         // Attempt to sink allocations of temporary non-escaping objects to
@@ -1996,16 +2270,16 @@
 #endif  // !PRODUCT
           // Ensure that all phis inserted by optimization passes have
           // consistent representations.
-          optimizer.SelectRepresentations();
+          flow_graph->SelectRepresentations();
         }
 
-        if (optimizer.Canonicalize()) {
+        if (flow_graph->Canonicalize()) {
           // To fully remove redundant boxing (e.g. BoxDouble used only in
           // environments and UnboxDouble instructions) instruction we
           // first need to replace all their uses and then fold them away.
           // For now we just repeat Canonicalize twice to do that.
           // TODO(vegorov): implement a separate representation folding pass.
-          optimizer.Canonicalize();
+          flow_graph->Canonicalize();
         }
         DEBUG_ASSERT(flow_graph->VerifyUseLists());
 
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index c32a955..43b7b96 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -7,6 +7,7 @@
 
 #include "vm/allocation.h"
 #include "vm/hash_map.h"
+#include "vm/hash_table.h"
 #include "vm/object.h"
 
 namespace dart {
@@ -166,6 +167,75 @@
 typedef DirectChainedHashMap<FieldKeyValueTrait> FieldSet;
 
 
+class ClassKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef const Class* Key;
+  typedef const Class* Value;
+  typedef const Class* Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) {
+    return key->token_pos().value();
+  }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    return pair->raw() == key->raw();
+  }
+};
+
+typedef DirectChainedHashMap<ClassKeyValueTrait> ClassSet;
+
+
+class AbstractTypeKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef const AbstractType* Key;
+  typedef const AbstractType* Value;
+  typedef const AbstractType* Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) {
+    return key->Hash();
+  }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    return pair->raw() == key->raw();
+  }
+};
+
+typedef DirectChainedHashMap<AbstractTypeKeyValueTrait> AbstractTypeSet;
+
+
+class TypeArgumentsKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef const TypeArguments* Key;
+  typedef const TypeArguments* Value;
+  typedef const TypeArguments* Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) {
+    return key->Hash();
+  }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    return pair->raw() == key->raw();
+  }
+};
+
+typedef DirectChainedHashMap<TypeArgumentsKeyValueTrait> TypeArgumentsSet;
+
+
 class Precompiler : public ValueObject {
  public:
   static RawError* CompileAll(
@@ -199,6 +269,10 @@
   void AddEntryPoints(Dart_QualifiedFunctionName entry_points[]);
   void Iterate();
 
+  void AddType(const AbstractType& type);
+  void AddTypesOf(const Class& cls);
+  void AddTypesOf(const Function& function);
+  void AddTypeArguments(const TypeArguments& args);
   void AddCalleesOf(const Function& function);
   void AddConstObject(const Instance& instance);
   void AddClosureCall(const ICData& call_site);
@@ -213,6 +287,12 @@
 
   void DropFunctions();
   void DropFields();
+  void TraceTypesFromRetainedClasses();
+  void DropTypes();
+  void DropTypeArguments();
+  void DropClasses();
+  void DropLibraries();
+
   void BindStaticCalls();
   void DedupStackmaps();
   void DedupStackmapLists();
@@ -247,15 +327,50 @@
   intptr_t selector_count_;
   intptr_t dropped_function_count_;
   intptr_t dropped_field_count_;
+  intptr_t dropped_class_count_;
+  intptr_t dropped_typearg_count_;
+  intptr_t dropped_type_count_;
+  intptr_t dropped_library_count_;
 
-  const GrowableObjectArray& libraries_;
+  GrowableObjectArray& libraries_;
   const GrowableObjectArray& pending_functions_;
   SymbolSet sent_selectors_;
   FunctionSet enqueued_functions_;
   FieldSet fields_to_retain_;
+  ClassSet classes_to_retain_;
+  TypeArgumentsSet typeargs_to_retain_;
+  AbstractTypeSet types_to_retain_;
   Error& error_;
 };
 
+
+class FunctionsTraits {
+ public:
+  static bool IsMatch(const Object& a, const Object& b) {
+    Zone* zone = Thread::Current()->zone();
+    String& a_s = String::Handle(zone);
+    String& b_s = String::Handle(zone);
+    a_s = a.IsFunction() ? Function::Cast(a).name() : String::Cast(a).raw();
+    b_s = b.IsFunction() ? Function::Cast(b).name() : String::Cast(b).raw();
+    ASSERT(a_s.IsSymbol() && b_s.IsSymbol());
+    return a_s.raw() == b_s.raw();
+  }
+  static uword Hash(const Object& obj) {
+    if (obj.IsFunction()) {
+      return String::Handle(Function::Cast(obj).name()).Hash();
+    } else {
+      ASSERT(String::Cast(obj).IsSymbol());
+      return String::Cast(obj).Hash();
+    }
+  }
+  static RawObject* NewKey(const Function& function) {
+    return function.raw();
+  }
+};
+
+typedef UnorderedHashSet<FunctionsTraits> UniqueFunctionsSet;
+
+
 }  // namespace dart
 
 #endif  // VM_PRECOMPILER_H_
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index a262edf..76d49ed 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -666,13 +666,12 @@
 
   RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->name_); }
   RawString* name_;
-  RawString* user_name_;
+  NOT_IN_PRODUCT(RawString* user_name_);
   RawArray* functions_;
   RawArray* functions_hash_table_;
   RawArray* fields_;
   RawArray* offset_in_words_to_field_;
   RawArray* interfaces_;  // Array of AbstractType.
-  RawGrowableObjectArray* direct_subclasses_;  // Array of Class.
   RawScript* script_;
   RawLibrary* library_;
   RawTypeArguments* type_parameters_;  // Array of TypeParameter.
@@ -683,10 +682,11 @@
   RawObject* canonical_types_;  // An array of canonicalized types of this class
                                 // or the canonical type.
   RawArray* invocation_dispatcher_cache_;  // Cache for dispatcher functions.
-  RawArray* cha_codes_;  // CHA optimized codes.
   RawCode* allocation_stub_;  // Stub code for allocation of instances.
+  RawGrowableObjectArray* direct_subclasses_;  // Array of Class.
+  RawArray* cha_codes_;  // CHA optimized codes.
   RawObject** to() {
-    return reinterpret_cast<RawObject**>(&ptr()->allocation_stub_);
+    return reinterpret_cast<RawObject**>(&ptr()->cha_codes_);
   }
 
   cpp_vtable handle_vtable_;
@@ -1555,8 +1555,11 @@
 
   RawObject** from() { return reinterpret_cast<RawObject**>(&ptr()->name_); }
   RawString* name_;               // Library prefix name.
-  RawArray* imports_;             // Libraries imported with this prefix.
   RawLibrary* importer_;          // Library which declares this prefix.
+  RawObject** to_precompiled_snapshot() {
+    return reinterpret_cast<RawObject**>(&ptr()->importer_);
+  }
+  RawArray* imports_;             // Libraries imported with this prefix.
   RawArray* dependent_code_;      // Code that refers to deferred, unloaded
                                   // library prefix.
   RawObject** to() {
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 405c2e4..6b9d728 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -115,6 +115,7 @@
     // Write out all the non object pointer fields.
     // NOTE: cpp_vtable_ is not written.
     classid_t class_id = ptr()->id_;
+    ASSERT(class_id != kIllegalCid);
     writer->Write<classid_t>(class_id);
     if (!RawObject::IsInternalVMdefinedClassId(class_id)) {
       // We don't write the instance size of VM defined classes as they
@@ -643,6 +644,10 @@
                      closure.raw()->from(), closure.raw()->to(),
                      kAsReference);
 
+  // Set the canonical bit.
+  if (RawObject::IsCanonical(tags)) {
+    closure.SetCanonical();
+  }
   return closure.raw();
 }
 
@@ -1290,6 +1295,7 @@
   } else {
     ASSERT((kind == Snapshot::kFull) || !ptr()->is_in_fullsnapshot_);
     // Write out all non object fields.
+    ASSERT(ptr()->index_ != static_cast<classid_t>(-1));
     writer->WriteClassIDValue(ptr()->index_);
     writer->Write<uint16_t>(ptr()->num_imports_);
     writer->Write<int8_t>(ptr()->load_state_);
@@ -1330,9 +1336,18 @@
   prefix.StoreNonPointer(&prefix.raw_ptr()->is_loaded_, reader->Read<bool>());
 
   // Set all the object fields.
+  RawObject** toobj = reader->snapshot_code()
+      ? prefix.raw()->to_precompiled_snapshot()
+      : prefix.raw()->to();
   READ_OBJECT_FIELDS(prefix,
-                     prefix.raw()->from(), prefix.raw()->to(),
+                     prefix.raw()->from(), toobj,
                      kAsReference);
+  if (reader->snapshot_code()) {
+    prefix.StorePointer(&prefix.raw_ptr()->imports_,
+                        Array::null());
+    prefix.StorePointer(&prefix.raw_ptr()->dependent_code_,
+                        Array::null());
+  }
 
   return prefix.raw();
 }
@@ -1359,7 +1374,9 @@
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
-  visitor.VisitPointers(from(), to());
+  RawObject** toobj = writer->snapshot_code() ? to_precompiled_snapshot()
+                                              : to();
+  visitor.VisitPointers(from(), toobj);
 }
 
 
@@ -2003,6 +2020,9 @@
   READ_OBJECT_FIELDS(result,
                      result.raw()->from(), toobj,
                      kAsReference);
+  if (reader->snapshot_code()) {
+    result.set_owner(Function::Handle(reader->zone()));
+  }
 
   return result.raw();
 }
@@ -3251,6 +3271,21 @@
     default:
       UNREACHABLE();
   }
+  // If it is a canonical constant make it one.
+  // When reading a full snapshot we don't need to canonicalize the object
+  // as it would already be a canonical object.
+  // When reading a script snapshot or a message snapshot we always have
+  // to canonicalize the object.
+  if (RawObject::IsCanonical(tags)) {
+    if (kind == Snapshot::kFull) {
+      // Set the canonical bit.
+      result.SetCanonical();
+    } else {
+      result ^= result.CheckAndCanonicalize(NULL);
+      ASSERT(!result.IsNull());
+      ASSERT(result.IsCanonical());
+    }
+  }
   return result.raw();
 }
 #undef TYPED_DATA_READ
diff --git a/runtime/vm/redundancy_elimination.cc b/runtime/vm/redundancy_elimination.cc
index effe15e..266abdf 100644
--- a/runtime/vm/redundancy_elimination.cc
+++ b/runtime/vm/redundancy_elimination.cc
@@ -21,7 +21,6 @@
 
 DECLARE_FLAG(bool, fields_may_be_reset);
 DECLARE_FLAG(bool, precompilation);
-DECLARE_FLAG(bool, trace_optimization);
 
 // Quick access to the current zone.
 #define Z (zone())
diff --git a/runtime/vm/resolver.cc b/runtime/vm/resolver.cc
index b0ae79b..caaf556 100644
--- a/runtime/vm/resolver.cc
+++ b/runtime/vm/resolver.cc
@@ -7,6 +7,7 @@
 #include "vm/dart_entry.h"
 #include "vm/flags.h"
 #include "vm/isolate.h"
+#include "vm/log.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
 #include "vm/symbols.h"
@@ -14,7 +15,6 @@
 namespace dart {
 
 DEFINE_FLAG(bool, trace_resolving, false, "Trace resolving.");
-DECLARE_FLAG(bool, lazy_dispatchers);
 
 // The actual names of named arguments are not checked by the dynamic resolver,
 // but by the method entry code. It is important that the dynamic resolver
@@ -34,22 +34,24 @@
 RawFunction* Resolver::ResolveDynamicForReceiverClass(
     const Class& receiver_class,
     const String& function_name,
-    const ArgumentsDescriptor& args_desc) {
+    const ArgumentsDescriptor& args_desc,
+    bool allow_add) {
 
-  Function& function =
-      Function::Handle(ResolveDynamicAnyArgs(receiver_class, function_name));
+  Function& function = Function::Handle(
+      ResolveDynamicAnyArgs(receiver_class, function_name, allow_add));
 
   if (function.IsNull() ||
       !function.AreValidArguments(args_desc, NULL)) {
     // Return a null function to signal to the upper levels to dispatch to
     // "noSuchMethod" function.
     if (FLAG_trace_resolving) {
-      String& error_message = String::Handle(String::New("function not found"));
+      String& error_message =
+          String::Handle(Symbols::New("function not found"));
       if (!function.IsNull()) {
         // Obtain more detailed error message.
         function.AreValidArguments(args_desc, &error_message);
       }
-      OS::Print("ResolveDynamic error '%s': %s.\n",
+      THR_Print("ResolveDynamic error '%s': %s.\n",
                 function_name.ToCString(),
                 error_message.ToCString());
     }
@@ -61,10 +63,11 @@
 
 RawFunction* Resolver::ResolveDynamicAnyArgs(
     const Class& receiver_class,
-    const String& function_name) {
+    const String& function_name,
+    bool allow_add) {
   Class& cls = Class::Handle(receiver_class.raw());
   if (FLAG_trace_resolving) {
-    OS::Print("ResolveDynamic '%s' for class %s\n",
+    THR_Print("ResolveDynamic '%s' for class %s\n",
               function_name.ToCString(),
               String::Handle(cls.Name()).ToCString());
   }
@@ -124,7 +127,7 @@
     if (FLAG_lazy_dispatchers) {
       if (is_getter && function.IsNull()) {
         function ^= cls.LookupDynamicFunction(field_name);
-        if (!function.IsNull()) {
+        if (!function.IsNull() && allow_add) {
           // We were looking for the getter but found a method with the same
           // name. Create a method extractor and return it.
           // The extractor does not exist yet, so using GetMethodExtractor is
@@ -159,7 +162,7 @@
           function.AreValidArguments(num_arguments,
                                      argument_names,
                                      &error_message);
-          OS::Print("ResolveStatic error '%s': %s.\n",
+          THR_Print("ResolveStatic error '%s': %s.\n",
                     function_name.ToCString(),
                     error_message.ToCString());
         }
@@ -167,7 +170,7 @@
       }
     } else {
       if (FLAG_trace_resolving) {
-        OS::Print("ResolveStatic error: function '%s' not found.\n",
+        THR_Print("ResolveStatic error: function '%s' not found.\n",
                   function_name.ToCString());
       }
     }
@@ -183,7 +186,7 @@
                                argument_names);
     }
     if (FLAG_trace_resolving && function.IsNull()) {
-      OS::Print("ResolveStatic error: function '%s.%s' not found.\n",
+      THR_Print("ResolveStatic error: function '%s.%s' not found.\n",
                 class_name.ToCString(),
                 function_name.ToCString());
     }
@@ -198,7 +201,7 @@
                                      const Array& argument_names) {
   ASSERT(!cls.IsNull());
   if (FLAG_trace_resolving) {
-    OS::Print("ResolveStatic '%s'\n", function_name.ToCString());
+    THR_Print("ResolveStatic '%s'\n", function_name.ToCString());
   }
   const Function& function =
       Function::Handle(cls.LookupStaticFunction(function_name));
@@ -214,7 +217,7 @@
                                    argument_names,
                                    &error_message);
       }
-      OS::Print("ResolveStatic error '%s': %s.\n",
+      THR_Print("ResolveStatic error '%s': %s.\n",
                 function_name.ToCString(),
                 error_message.ToCString());
     }
@@ -230,7 +233,7 @@
                                                  const Array& argument_names) {
   ASSERT(!cls.IsNull());
   if (FLAG_trace_resolving) {
-    OS::Print("ResolveStaticAllowPrivate '%s'\n", function_name.ToCString());
+    THR_Print("ResolveStaticAllowPrivate '%s'\n", function_name.ToCString());
   }
   const Function& function =
       Function::Handle(cls.LookupStaticFunctionAllowPrivate(function_name));
@@ -246,7 +249,7 @@
                                    argument_names,
                                    &error_message);
       }
-      OS::Print("ResolveStaticAllowPrivate error '%s': %s.\n",
+      THR_Print("ResolveStaticAllowPrivate error '%s': %s.\n",
                 function_name.ToCString(),
                 error_message.ToCString());
     }
diff --git a/runtime/vm/resolver.h b/runtime/vm/resolver.h
index 1ea883e..32629aa 100644
--- a/runtime/vm/resolver.h
+++ b/runtime/vm/resolver.h
@@ -28,14 +28,18 @@
                                      const String& function_name,
                                      const ArgumentsDescriptor& args_desc);
 
+  // If 'allow_add' is true we may add a function to the class during lookup.
   static RawFunction* ResolveDynamicForReceiverClass(
       const Class& receiver_class,
       const String& function_name,
-      const ArgumentsDescriptor& args_desc);
+      const ArgumentsDescriptor& args_desc,
+      bool allow_add = true);
 
+  // If 'allow_add' is true we may add a function to the class during lookup.
   static RawFunction* ResolveDynamicAnyArgs(
       const Class& receiver_class,
-      const String& function_name);
+      const String& function_name,
+      bool allow_add = true);
 
   // Resolve specified dart static function. If library.IsNull, use
   // either application library or core library if no application library
diff --git a/runtime/vm/reusable_handles.h b/runtime/vm/reusable_handles.h
index 8f057ea..beae36b 100644
--- a/runtime/vm/reusable_handles.h
+++ b/runtime/vm/reusable_handles.h
@@ -11,9 +11,9 @@
 
 namespace dart {
 
-// Classes registered in REUSABLE_HANDLE_LIST have an isolate specific reusable
+// Classes registered in REUSABLE_HANDLE_LIST have an thread specific reusable
 // handle. A guard class (Reusable*ClassName*HandleScope) should be used in
-// regions of the virtual machine where the isolate specific reusable handle
+// regions of the virtual machine where the thread specific reusable handle
 // of that type is used. The class asserts that we do not add code that will
 // result in recursive uses of the class's reusable handle.
 //
@@ -21,7 +21,7 @@
 // REUSABLE_*CLASSNAME*_HANDLESCOPE macro:
 //
 // {
-//   REUSABLE_ARRAY_HANDLESCOPE(isolate);
+//   REUSABLE_ARRAY_HANDLESCOPE(thread);
 //   ....
 //   ....
 //   Array& funcs = reused_array_handle.Handle();
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index d3f8428..c52b6b5 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -76,6 +76,15 @@
   DISALLOW_COPY_AND_ASSIGN(RuntimeEntry);
 };
 
+#ifndef PRODUCT
+#define TRACE_RUNTIME_CALL(format, name)                                       \
+  if (FLAG_trace_runtime_calls) {                                              \
+    OS::Print("Runtime call: " format "\n", name);                             \
+  }
+#else
+#define TRACE_RUNTIME_CALL(format, name)                                       \
+  do { } while (0)
+#endif
 
 // Helper macros for declaring and defining runtime entries.
 
@@ -91,7 +100,7 @@
     CHECK_STACK_ALIGNMENT;                                                     \
     VERIFY_ON_TRANSITION;                                                      \
     ASSERT(arguments.ArgCount() == argument_count);                            \
-    if (FLAG_trace_runtime_calls) OS::Print("Runtime call: %s\n", ""#name);    \
+    TRACE_RUNTIME_CALL("%s", ""#name);                                         \
     {                                                                          \
       Thread* thread = arguments.thread();                                     \
       ASSERT(thread == Thread::Current());                                     \
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index c8912eb..f75291d 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -2419,6 +2419,11 @@
 
 
 static bool GetSourceReport(Thread* thread, JSONStream* js) {
+  if (!thread->isolate()->compilation_allowed()) {
+    js->PrintError(kFeatureDisabled,
+        "Cannot get source report when running a precompiled program.");
+    return true;
+  }
   const char* reports_str = js->LookupParam("reports");
   const EnumListParameter* reports_parameter =
       static_cast<const EnumListParameter*>(get_source_report_params[1]);
@@ -2629,7 +2634,7 @@
   }
   const Instance& closure = Instance::Cast(obj);
   Breakpoint* bpt =
-      thread->isolate()->debugger()->SetBreakpointAtActivation(closure);
+      thread->isolate()->debugger()->SetBreakpointAtActivation(closure, false);
   if (bpt == NULL) {
     js->PrintError(kCannotAddBreakpoint,
                    "%s: Cannot add breakpoint at activation",
@@ -3020,6 +3025,12 @@
         isolate->debugger()->SetStepOver();
       } else if (strcmp(step_param, "Out") == 0) {
         isolate->debugger()->SetStepOut();
+      } else if (strcmp(step_param, "OverAsyncSuspension") == 0) {
+        if (!isolate->debugger()->SetupStepOverAsyncSuspension()) {
+          js->PrintError(kInvalidParams,
+                         "Isolate must be paused at an async suspension point");
+          return true;
+        }
       } else {
         PrintInvalidParamError(js, "step");
         return true;
@@ -3605,7 +3616,7 @@
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "Version");
   jsobj.AddProperty("major", static_cast<intptr_t>(3));
-  jsobj.AddProperty("minor", static_cast<intptr_t>(2));
+  jsobj.AddProperty("minor", static_cast<intptr_t>(3));
   jsobj.AddProperty("_privateMajor", static_cast<intptr_t>(0));
   jsobj.AddProperty("_privateMinor", static_cast<intptr_t>(0));
   return true;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 0ab4ee2..3153563 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.2
+# Dart VM Service Protocol 3.3
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.2_ of the Dart VM Service Protocol. This
+This document describes of _version 3.3_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -919,6 +919,10 @@
   // Has this breakpoint been assigned to a specific program location?
   bool resolved;
 
+  // Is this a breakpoint that was added synthetically as part of a step
+  // OverAsyncSuspension resume command?
+  bool isSyntheticAsyncContinuation [optional];
+
   // SourceLocation when breakpoint is resolved, UnresolvedSourceLocation
   // when a breakpoint is not resolved.
   SourceLocation|UnresolvedSourceLocation location;
@@ -1208,6 +1212,13 @@
   //
   // This is provided for the Extension event.
   ExtensionData extensionData [optional];
+
+  // Is the isolate paused at an await, yield, or yield* statement?
+  //
+  // This is provided for the event kinds:
+  //   PauseBreakpoint
+  //   PauseInterrupted
+  bool atAsyncSuspension [optional];
 }
 ```
 
@@ -1913,8 +1924,9 @@
   // The current pause on exception mode for this isolate.
   ExceptionPauseMode exceptionPauseMode;
 
-  // The list of service extension RPCs that are registered for this isolate.
-  string[] extensionRPCs;
+  // The list of service extension RPCs that are registered for this isolate,
+  // if any.
+  string[] extensionRPCs [optional];
 }
 ```
 
@@ -2333,6 +2345,7 @@
 enum StepOption {
   Into,
   Over,
+  OverAsyncSuspension,
   Out
 }
 ```
@@ -2475,6 +2488,6 @@
 3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.  Add offset and count parameters to getObject() and offset and count fields to Instance. Added ServiceExtensionAdded event.
 3.1 | Add the getSourceReport RPC.  The getObject RPC now accepts offset and count for string objects.  String objects now contain length, offset, and count properties.
 3.2 | Isolate objects now include the runnable bit and many debugger related RPCs will return an error if executed on an isolate before it is runnable.
-
+3.3 | Pause event now indicates if the isolate is paused at an await, yield, or yield* suspension point via the 'atAsyncSuspension' field. Resume command now supports the step parameter 'OverAsyncSuspension'. A Breakpoint added synthetically by an 'OverAsyncSuspension' resume command identifies itself as such via the 'isSyntheticAsyncContinuation' field.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.cc b/runtime/vm/service_event.cc
index 314d635..2e64c66 100644
--- a/runtime/vm/service_event.cc
+++ b/runtime/vm/service_event.cc
@@ -44,7 +44,6 @@
       top_frame_(NULL),
       extension_rpc_(NULL),
       exception_(NULL),
-      async_continuation_(NULL),
       at_async_jump_(false),
       inspectee_(NULL),
       gc_stats_(NULL),
@@ -67,7 +66,7 @@
       top_frame_(NULL),
       extension_rpc_(NULL),
       exception_(NULL),
-      async_continuation_(NULL),
+      at_async_jump_(false),
       inspectee_(NULL),
       gc_stats_(NULL),
       bytes_(NULL),
@@ -76,7 +75,6 @@
   DebuggerEvent::EventType type = debugger_event->type();
   if (type == DebuggerEvent::kBreakpointReached) {
     set_breakpoint(debugger_event->breakpoint());
-    set_async_continuation(debugger_event->async_continuation());
     set_at_async_jump(debugger_event->at_async_jump());
   }
   if (type == DebuggerEvent::kExceptionThrown) {
@@ -222,9 +220,8 @@
   if (exception() != NULL) {
     jsobj.AddProperty("exception", *(exception()));
   }
-  if (async_continuation() != NULL && !async_continuation()->IsNull()) {
-    jsobj.AddProperty("_asyncContinuation", *(async_continuation()));
-    jsobj.AddProperty("_atAsyncJump", at_async_jump());
+  if (at_async_jump()) {
+    jsobj.AddProperty("atAsyncSuspension", true);
   }
   if (inspectee() != NULL) {
     jsobj.AddProperty("inspectee", *(inspectee()));
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index 45ebb71..e5afb6d 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -134,14 +134,6 @@
     exception_ = exception;
   }
 
-  const Object* async_continuation() const {
-    return async_continuation_;
-  }
-  void set_async_continuation(const Object* closure) {
-    ASSERT(kind_ == kPauseBreakpoint);
-    async_continuation_ = closure;
-  }
-
   bool at_async_jump() const {
     return at_async_jump_;
   }
@@ -203,7 +195,6 @@
   ActivationFrame* top_frame_;
   const String* extension_rpc_;
   const Object* exception_;
-  const Object* async_continuation_;
   bool at_async_jump_;
   const Object* inspectee_;
   const Heap::GCStats* gc_stats_;
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 340351a..bf02cba 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -683,8 +683,10 @@
                 kMessageBufferSize,
                 "No full snapshot version found, expected '%s'",
                 Version::SnapshotString());
-    const String& msg = String::Handle(String::New(message_buffer));
-    return ApiError::New(msg);
+    // This can also fail while bringing up the VM isolate, so make sure to
+    // allocate the error message in old space.
+    const String& msg = String::Handle(String::New(message_buffer, Heap::kOld));
+    return ApiError::New(msg, Heap::kOld);
   }
 
   const char* version = reinterpret_cast<const char*>(CurrentBufferAddress());
@@ -2163,8 +2165,7 @@
     return true;
   }
 
-  // Now check if it is an object from the VM isolate (NOTE: premarked objects
-  // are considered to be objects in the VM isolate). These objects are shared
+  // Now check if it is an object from the VM isolate. These objects are shared
   // by all isolates.
   if (rawobj->IsVMHeapObject() && HandleVMIsolateObject(rawobj)) {
     return true;
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index 533eb93..0a7644b 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -16,8 +16,6 @@
 
 namespace dart {
 
-DECLARE_FLAG(bool, lazy_dispatchers);
-
 // Unit test for empty stack frame iteration.
 VM_TEST_CASE(EmptyStackFrameIteration) {
   StackFrameIterator iterator(StackFrameIterator::kValidateFrames);
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index d06b125..6738a25 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -10,6 +10,7 @@
 #include "vm/disassembler.h"
 #include "vm/flags.h"
 #include "vm/object_store.h"
+#include "vm/safepoint.h"
 #include "vm/snapshot.h"
 #include "vm/virtual_memory.h"
 #include "vm/visitor.h"
@@ -120,9 +121,41 @@
     Assembler assembler;
     const char* name = cls.ToCString();
     StubCode::GenerateAllocationStubForClass(&assembler, cls);
-    stub ^= Code::FinalizeCode(name, &assembler, false /* optimized */);
-    stub.set_owner(cls);
-    cls.set_allocation_stub(stub);
+
+    if (thread->IsMutatorThread()) {
+      stub ^= Code::FinalizeCode(name, &assembler, false /* optimized */);
+      // Check if background compilation thread has not already added the stub.
+      if (cls.allocation_stub() == Code::null()) {
+        stub.set_owner(cls);
+        cls.set_allocation_stub(stub);
+      }
+    } else {
+      // This part of stub code generation must be at a safepoint.
+      // Stop mutator thread before creating the instruction object and
+      // installing code.
+      // Mutator thread may not run code while we are creating the
+      // instruction object, since the creation of instruction object
+      // changes code page access permissions (makes them temporary not
+      // executable).
+      {
+        SafepointOperationScope safepoint_scope(thread);
+        stub = cls.allocation_stub();
+        // Check if stub was already generated.
+        if (!stub.IsNull()) {
+          return stub.raw();
+        }
+        // Do not Garbage collect during this stage and instead allow the
+        // heap to grow.
+        NoHeapGrowthControlScope no_growth_control;
+        stub ^= Code::FinalizeCode(name, &assembler, false /* optimized */);
+        stub.set_owner(cls);
+        cls.set_allocation_stub(stub);
+      }
+      Isolate* isolate = thread->isolate();
+      if (isolate->heap()->NeedsGarbageCollection()) {
+        isolate->heap()->CollectAllGarbage();
+      }
+    }
     if (FLAG_support_disassembler && FLAG_disassemble_stubs) {
       LogBlock lb;
       THR_Print("Code for allocation stub '%s': {\n", name);
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index 82fc0fb..77b6685 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -27,7 +27,6 @@
     "Set to true for debugging & verifying the slow paths.");
 DECLARE_FLAG(bool, trace_optimized_ic_calls);
 DECLARE_FLAG(int, optimization_counter_threshold);
-DECLARE_FLAG(bool, lazy_dispatchers);
 
 // Input parameters:
 //   LR : return address.
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index ec83c5d..c0648d4 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -26,7 +26,6 @@
     "Set to true for debugging & verifying the slow paths.");
 DECLARE_FLAG(bool, trace_optimized_ic_calls);
 DECLARE_FLAG(int, optimization_counter_threshold);
-DECLARE_FLAG(bool, lazy_dispatchers);
 
 // Input parameters:
 //   LR : return address.
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 270e0f6..e79efba 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -28,7 +28,6 @@
     "Set to true for debugging & verifying the slow paths.");
 DECLARE_FLAG(bool, trace_optimized_ic_calls);
 DECLARE_FLAG(int, optimization_counter_threshold);
-DECLARE_FLAG(bool, lazy_dispatchers);
 
 #define INT32_SIZEOF(x) static_cast<int32_t>(sizeof(x))
 
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index ff81507..8d1b252 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -26,7 +26,6 @@
     "Set to true for debugging & verifying the slow paths.");
 DECLARE_FLAG(bool, trace_optimized_ic_calls);
 DECLARE_FLAG(int, optimization_counter_threshold);
-DECLARE_FLAG(bool, lazy_dispatchers);
 
 // Input parameters:
 //   RA : return address.
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 3931825..ace6744 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -27,7 +27,6 @@
     "Set to true for debugging & verifying the slow paths.");
 DECLARE_FLAG(bool, trace_optimized_ic_calls);
 DECLARE_FLAG(int, optimization_counter_threshold);
-DECLARE_FLAG(bool, lazy_dispatchers);
 
 // Input parameters:
 //   RSP : points to return address.
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index f6735c2..d35dc6d 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -564,6 +564,7 @@
     table.Release();
   }
   if (symbol.IsNull()) {
+    SafepointMutexLocker ml(isolate->symbols_mutex());
     SymbolTable table(zone, isolate->object_store()->symbol_table());
     symbol ^= table.InsertNewOrGet(str);
     isolate->object_store()->set_symbol_table(table.Release());
@@ -587,6 +588,7 @@
     table.Release();
   }
   if (symbol.IsNull()) {
+    SafepointMutexLocker ml(isolate->symbols_mutex());
     SymbolTable table(zone, isolate->object_store()->symbol_table());
     symbol ^= table.GetOrNull(str);
     table.Release();
diff --git a/runtime/vm/thread_barrier.h b/runtime/vm/thread_barrier.h
index 9cc1d97..39c56a8 100644
--- a/runtime/vm/thread_barrier.h
+++ b/runtime/vm/thread_barrier.h
@@ -46,16 +46,20 @@
 //
 class ThreadBarrier {
  public:
-  explicit ThreadBarrier(intptr_t num_threads)
+  explicit ThreadBarrier(intptr_t num_threads,
+                         Monitor* monitor,
+                         Monitor* done_monitor)
     : num_threads_(num_threads),
+      monitor_(monitor),
       remaining_(num_threads),
       parity_(false),
+      done_monitor_(done_monitor),
       done_(false) {
     ASSERT(remaining_ > 0);
   }
 
   void Sync() {
-    MonitorLocker ml(&monitor_);
+    MonitorLocker ml(monitor_);
     ASSERT(remaining_ > 0);
     if (--remaining_ > 0) {
       // I'm not last to arrive; wait until next round.
@@ -75,13 +79,13 @@
   void Exit() {
     bool last = false;
     {
-      MonitorLocker ml(&monitor_);
+      MonitorLocker ml(monitor_);
       ASSERT(remaining_ > 0);
       last = (--remaining_ == 0);
     }
     if (last) {
       // Last one to exit sets done_.
-      MonitorLocker ml(&done_monitor_);
+      MonitorLocker ml(done_monitor_);
       ASSERT(!done_);
       done_ = true;
       // Tell the destructor in case it's already waiting.
@@ -90,7 +94,7 @@
   }
 
   ~ThreadBarrier() {
-    MonitorLocker ml(&done_monitor_);
+    MonitorLocker ml(done_monitor_);
     // Wait for everyone to exit before destroying the monitors.
     while (!done_) {
       ml.Wait();
@@ -101,11 +105,11 @@
  private:
   const intptr_t num_threads_;
 
-  Monitor monitor_;
+  Monitor* monitor_;
   intptr_t remaining_;
   bool parity_;
 
-  Monitor done_monitor_;  // TODO(koda): Try to optimize this away.
+  Monitor* done_monitor_;  // TODO(koda): Try to optimize this away.
   bool done_;
 
   DISALLOW_COPY_AND_ASSIGN(ThreadBarrier);
diff --git a/runtime/vm/thread_barrier_test.cc b/runtime/vm/thread_barrier_test.cc
index 4517e18..7ca11c6 100644
--- a/runtime/vm/thread_barrier_test.cc
+++ b/runtime/vm/thread_barrier_test.cc
@@ -46,14 +46,21 @@
   static const intptr_t kNumTasks = 5;
   static const intptr_t kNumRounds = 500;
 
-  ThreadBarrier barrier(kNumTasks + 1);
-  for (intptr_t i = 0; i < kNumTasks; ++i) {
-    Dart::thread_pool()->Run(new FuzzTask(kNumRounds, &barrier, i + 1));
+  Monitor* monitor = new Monitor();
+  Monitor* monitor_done = new Monitor();
+  {
+    ThreadBarrier barrier(kNumTasks + 1, monitor, monitor_done);
+    for (intptr_t i = 0; i < kNumTasks; ++i) {
+      Dart::thread_pool()->Run(new FuzzTask(kNumRounds, &barrier, i + 1));
+    }
+    for (intptr_t i = 0; i < kNumRounds; ++i) {
+      barrier.Sync();
+    }
+    barrier.Exit();
   }
-  for (intptr_t i = 0; i < kNumRounds; ++i) {
-    barrier.Sync();
-  }
-  barrier.Exit();
+
+  delete monitor_done;
+  delete monitor;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index f44fb53..6dfc8d2 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -362,8 +362,7 @@
         function.ToLibNamePrefixedQualifiedCString());                         \
   }
 #else
-#define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, suffix, function)       \
-  do { } while (false);
+#define TIMELINE_FUNCTION_COMPILATION_DURATION(thread, suffix, function)
 #endif  // !PRODUCT
 
 // See |TimelineDurationScope| and |TimelineBeginEndScope|.
diff --git a/runtime/vm/timer.h b/runtime/vm/timer.h
index e4ee890..f3b15fa 100644
--- a/runtime/vm/timer.h
+++ b/runtime/vm/timer.h
@@ -12,8 +12,6 @@
 
 namespace dart {
 
-class JSONObject;
-
 // Timer class allows timing of specific operations in the VM.
 class Timer : public ValueObject {
  public:
diff --git a/runtime/vm/trace_buffer.cc b/runtime/vm/trace_buffer.cc
deleted file mode 100644
index 2022e49..0000000
--- a/runtime/vm/trace_buffer.cc
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/isolate.h"
-#include "vm/json_stream.h"
-#include "vm/object.h"
-#include "vm/os.h"
-#include "vm/trace_buffer.h"
-
-namespace dart {
-
-TraceBuffer::TraceBuffer(Isolate* isolate, intptr_t capacity)
-    : isolate_(isolate), ring_capacity_(capacity) {
-  ring_cursor_ = 0;
-  ring_ = reinterpret_cast<TraceBufferEntry*>(
-      calloc(ring_capacity_, sizeof(TraceBufferEntry)));  // NOLINT
-}
-
-
-TraceBuffer::~TraceBuffer() {
-  ASSERT(ring_ != NULL);
-  Clear();
-  free(ring_);
-  if (isolate_ != NULL) {
-    isolate_->set_trace_buffer(NULL);
-    isolate_ = NULL;
-  }
-}
-
-
-void TraceBuffer::Init(Isolate* isolate, intptr_t capacity) {
-  TraceBuffer* trace_buffer = new TraceBuffer(isolate, capacity);
-  isolate->set_trace_buffer(trace_buffer);
-}
-
-
-void TraceBuffer::Clear() {
-  for (intptr_t i = 0; i < ring_capacity_; i++) {
-    TraceBufferEntry& entry = ring_[i];
-    entry.micros = 0;
-    free(entry.message);
-    entry.message = NULL;
-    entry.message_is_escaped = false;
-  }
-  ring_cursor_ = 0;
-}
-
-
-void TraceBuffer::Fill(TraceBufferEntry* entry, int64_t micros,
-                       char* msg, bool msg_is_escaped) {
-  if (entry->message != NULL) {
-    // Recycle TraceBufferEntry.
-    free(entry->message);
-  }
-  entry->message = msg;
-  entry->message_is_escaped = msg_is_escaped;
-  entry->micros = micros;
-}
-
-
-void TraceBuffer::AppendTrace(int64_t micros, char* msg, bool msg_is_escaped) {
-  const intptr_t index = ring_cursor_;
-  TraceBufferEntry* trace_entry = &ring_[index];
-  Fill(trace_entry, micros, msg, msg_is_escaped);
-  ring_cursor_ = RingIndex(ring_cursor_ + 1);
-}
-
-
-void TraceBuffer::Trace(int64_t micros, const char* msg, bool msg_is_escaped) {
-  ASSERT(msg != NULL);
-  char* message_copy = strdup(msg);
-  AppendTrace(micros, message_copy, msg_is_escaped);
-}
-
-
-void TraceBuffer::Trace(const char* msg, bool msg_is_escaped) {
-  Trace(OS::GetCurrentTimeMicros(), msg, msg_is_escaped);
-}
-
-
-void TraceBuffer::TraceF(const char* format, ...) {
-  const int64_t micros = OS::GetCurrentTimeMicros();
-  va_list args;
-  va_start(args, format);
-  const intptr_t len = OS::VSNPrint(NULL, 0, format, args);
-  va_end(args);
-  char* p = reinterpret_cast<char*>(malloc(len+1));
-  va_start(args, format);
-  const intptr_t len2 = OS::VSNPrint(p, len+1, format, args);
-  va_end(args);
-  ASSERT(len == len2);
-  AppendTrace(micros, p);
-}
-
-
-void TraceBuffer::PrintToJSONStream(JSONStream* stream) const {
-  JSONObject json_trace_buffer(stream);
-  json_trace_buffer.AddProperty("type", "TraceBuffer");
-  // TODO(johnmccutchan): Send cursor position in response.
-  JSONArray json_trace_buffer_array(&json_trace_buffer, "members");
-  // Scan forward until we find the first entry which isn't empty.
-  // TODO(johnmccutchan): Accept cursor start position as input.
-  intptr_t start = -1;
-  for (intptr_t i = 0; i < ring_capacity_; i++) {
-    intptr_t index = RingIndex(i + ring_cursor_);
-    if (!ring_[index].empty()) {
-      start = index;
-      break;
-    }
-  }
-  // No messages in trace buffer.
-  if (start == -1) {
-    return;
-  }
-  for (intptr_t i = 0; i < ring_capacity_; i++) {
-    intptr_t index = RingIndex(start + i);
-    const TraceBufferEntry& entry = ring_[index];
-    if (entry.empty()) {
-      // Empty entry, stop.
-      break;
-    }
-    JSONObject trace_entry(&json_trace_buffer_array);
-    trace_entry.AddProperty("type", "TraceBufferEntry");
-    double seconds = static_cast<double>(entry.micros) /
-                     static_cast<double>(kMicrosecondsPerSecond);
-    trace_entry.AddProperty("time", seconds);
-    if (entry.message_is_escaped) {
-      trace_entry.AddPropertyNoEscape("message", entry.message);
-    } else {
-      trace_entry.AddProperty("message", entry.message);
-    }
-  }
-}
-
-}  // namespace dart
diff --git a/runtime/vm/trace_buffer.h b/runtime/vm/trace_buffer.h
deleted file mode 100644
index 4c3c74c..0000000
--- a/runtime/vm/trace_buffer.h
+++ /dev/null
@@ -1,70 +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.
-
-#ifndef VM_TRACE_BUFFER_H_
-#define VM_TRACE_BUFFER_H_
-
-#include "platform/assert.h"
-#include "platform/globals.h"
-#include "vm/json_stream.h"
-
-namespace dart {
-
-class JSONStream;
-class Script;
-
-struct TraceBufferEntry {
-  int64_t micros;
-  char* message;
-  bool message_is_escaped;
-  bool empty() const {
-    return message == NULL;
-  }
-};
-
-class TraceBuffer {
- public:
-  static const intptr_t kDefaultCapacity = 1024;
-
-  static void Init(Isolate* isolate, intptr_t capacity = kDefaultCapacity);
-
-  ~TraceBuffer();
-
-  void Clear();
-
-  // Internally message is copied.
-  void Trace(int64_t micros, const char* msg, bool msg_is_escaped = false);
-  // Internally message is copied.
-  void Trace(const char* msg, bool msg_is_escaped = false);
-  void TraceF(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
-
-  void PrintToJSONStream(JSONStream* stream) const;
-
-  // Accessors for testing.
-  TraceBufferEntry* At(intptr_t i) const { return &ring_[RingIndex(i)]; }
-  intptr_t Length() const { return ring_cursor_; }
-
- private:
-  TraceBuffer(Isolate* isolate, intptr_t capacity);
-  void Cleanup();
-  void Fill(TraceBufferEntry* entry, int64_t micros,
-            char* msg, bool msg_is_escaped = false);
-  void AppendTrace(int64_t micros, char* msg, bool msg_is_escaped = false);
-
-  Isolate* isolate_;
-  TraceBufferEntry* ring_;
-  const intptr_t ring_capacity_;
-  intptr_t ring_cursor_;
-
-  intptr_t RingIndex(intptr_t i) const {
-    return i % ring_capacity_;
-  }
-
-  DISALLOW_COPY_AND_ASSIGN(TraceBuffer);
-};
-
-
-}  // namespace dart
-
-#endif  // VM_TRACE_BUFFER_H_
diff --git a/runtime/vm/trace_buffer_test.cc b/runtime/vm/trace_buffer_test.cc
deleted file mode 100644
index 1ac6452..0000000
--- a/runtime/vm/trace_buffer_test.cc
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "platform/assert.h"
-#include "vm/globals.h"
-#include "vm/json_stream.h"
-#include "vm/trace_buffer.h"
-#include "vm/unit_test.h"
-
-namespace dart {
-
-#ifndef PRODUCT
-
-TEST_CASE(TraceBufferEmpty) {
-  Isolate* isolate = Isolate::Current();
-  TraceBuffer::Init(isolate, 3);
-  TraceBuffer* trace_buffer = isolate->trace_buffer();
-  {
-    JSONStream js;
-    trace_buffer->PrintToJSONStream(&js);
-    EXPECT_STREQ("{\"type\":\"TraceBuffer\",\"members\":[]}", js.ToCString());
-  }
-  delete trace_buffer;
-}
-
-
-TEST_CASE(TraceBufferClear) {
-  Isolate* isolate = Isolate::Current();
-  TraceBuffer::Init(isolate, 3);
-  TraceBuffer* trace_buffer = isolate->trace_buffer();
-  trace_buffer->Trace(kMicrosecondsPerSecond * 1, "abc");
-  trace_buffer->Clear();
-  {
-    JSONStream js;
-    trace_buffer->PrintToJSONStream(&js);
-    EXPECT_STREQ("{\"type\":\"TraceBuffer\",\"members\":[]}", js.ToCString());
-  }
-  delete trace_buffer;
-}
-
-
-TEST_CASE(TraceBufferTrace) {
-  Isolate* isolate = Isolate::Current();
-  TraceBuffer::Init(isolate, 3);
-  TraceBuffer* trace_buffer = isolate->trace_buffer();
-
-  trace_buffer->Trace(kMicrosecondsPerSecond * 1, "abc");
-  {
-    JSONStream js;
-    trace_buffer->PrintToJSONStream(&js);
-    EXPECT_STREQ("{\"type\":\"TraceBuffer\",\"members\":["
-                 "{\"type\":\"TraceBufferEntry\",\"time\":1.000000,"
-                 "\"message\":\"abc\"}]}", js.ToCString());
-  }
-  trace_buffer->Trace(kMicrosecondsPerSecond * 2, "def");
-  {
-    JSONStream js;
-    trace_buffer->PrintToJSONStream(&js);
-    EXPECT_STREQ("{\"type\":\"TraceBuffer\",\"members\":["
-                 "{\"type\":\"TraceBufferEntry\",\"time\":1.000000,"
-                 "\"message\":\"abc\"},"
-                 "{\"type\":\"TraceBufferEntry\",\"time\":2.000000,"
-                 "\"message\":\"def\"}]}", js.ToCString());
-  }
-  trace_buffer->Trace(kMicrosecondsPerSecond * 3, "ghi");
-  {
-    JSONStream js;
-    trace_buffer->PrintToJSONStream(&js);
-    EXPECT_STREQ("{\"type\":\"TraceBuffer\",\"members\":["
-                 "{\"type\":\"TraceBufferEntry\",\"time\":1.000000,"
-                 "\"message\":\"abc\"},"
-                 "{\"type\":\"TraceBufferEntry\",\"time\":2.000000,"
-                 "\"message\":\"def\"},"
-                 "{\"type\":\"TraceBufferEntry\",\"time\":3.000000,"
-                 "\"message\":\"ghi\"}]}", js.ToCString());
-  }
-  // This will overwrite the first Trace.
-  trace_buffer->Trace(kMicrosecondsPerSecond * 4, "jkl");
-  {
-    JSONStream js;
-    trace_buffer->PrintToJSONStream(&js);
-    EXPECT_STREQ("{\"type\":\"TraceBuffer\",\"members\":["
-                 "{\"type\":\"TraceBufferEntry\",\"time\":2.000000,"
-                 "\"message\":\"def\"},"
-                 "{\"type\":\"TraceBufferEntry\",\"time\":3.000000,"
-                 "\"message\":\"ghi\"},"
-                 "{\"type\":\"TraceBufferEntry\",\"time\":4.000000,"
-                 "\"message\":\"jkl\"}]}", js.ToCString());
-  }
-  delete trace_buffer;
-}
-
-
-TEST_CASE(TraceBufferTraceF) {
-  Isolate* isolate = Isolate::Current();
-  TraceBuffer::Init(isolate, 3);
-  TraceBuffer* trace_buffer = isolate->trace_buffer();
-  trace_buffer->TraceF("foo %d %s", 99, "bar");
-  {
-    JSONStream js;
-    trace_buffer->PrintToJSONStream(&js);
-    EXPECT_SUBSTRING("foo 99 bar", js.ToCString());
-  }
-  delete trace_buffer;
-}
-
-#endif  // !PRODUCT
-
-}  // namespace dart
diff --git a/runtime/vm/virtual_memory_android.cc b/runtime/vm/virtual_memory_android.cc
index 0e0c1b2..16aa834 100644
--- a/runtime/vm/virtual_memory_android.cc
+++ b/runtime/vm/virtual_memory_android.cc
@@ -13,6 +13,8 @@
 #include "platform/assert.h"
 #include "platform/utils.h"
 
+#include "vm/isolate.h"
+
 namespace dart {
 
 // standard MAP_FAILED causes "error: use of old-style cast" as it
@@ -80,6 +82,8 @@
 
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
+  ASSERT(Thread::Current()->IsMutatorThread() ||
+         Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
   uword page_address = Utils::RoundDown(start_address, PageSize());
diff --git a/runtime/vm/virtual_memory_linux.cc b/runtime/vm/virtual_memory_linux.cc
index 275c0c6..0228f68 100644
--- a/runtime/vm/virtual_memory_linux.cc
+++ b/runtime/vm/virtual_memory_linux.cc
@@ -13,6 +13,8 @@
 #include "platform/assert.h"
 #include "platform/utils.h"
 
+#include "vm/isolate.h"
+
 namespace dart {
 
 // standard MAP_FAILED causes "error: use of old-style cast" as it
@@ -79,6 +81,8 @@
 
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
+  ASSERT(Thread::Current()->IsMutatorThread() ||
+         Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
   uword page_address = Utils::RoundDown(start_address, PageSize());
diff --git a/runtime/vm/virtual_memory_macos.cc b/runtime/vm/virtual_memory_macos.cc
index f28da35..484ad78 100644
--- a/runtime/vm/virtual_memory_macos.cc
+++ b/runtime/vm/virtual_memory_macos.cc
@@ -13,6 +13,8 @@
 #include "platform/assert.h"
 #include "platform/utils.h"
 
+#include "vm/isolate.h"
+
 namespace dart {
 
 // standard MAP_FAILED causes "error: use of old-style cast" as it
@@ -80,6 +82,8 @@
 
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
+  ASSERT(Thread::Current()->IsMutatorThread() ||
+         Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
   uword page_address = Utils::RoundDown(start_address, PageSize());
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index dd154ac..2584613 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -10,6 +10,8 @@
 #include "platform/assert.h"
 #include "vm/os.h"
 
+#include "vm/isolate.h"
+
 namespace dart {
 
 uword VirtualMemory::page_size_ = 0;
@@ -63,6 +65,8 @@
 
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
+  ASSERT(Thread::Current()->IsMutatorThread() ||
+         Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
   uword page_address = Utils::RoundDown(start_address, PageSize());
diff --git a/runtime/vm/vm.gypi b/runtime/vm/vm.gypi
index a733877..0f857b3 100644
--- a/runtime/vm/vm.gypi
+++ b/runtime/vm/vm.gypi
@@ -74,26 +74,7 @@
           'sources/' : [
             ['exclude', 'gdbjit.cc'],
           ],
-       }],
-       ['dart_vtune_support==0', {
-          'sources/' : [
-            ['exclude', 'vtune\\.(cc|h)$'],
-          ],
-       }],
-       ['dart_vtune_support==1', {
-          'include_dirs': ['<(dart_vtune_root)/include'],
-          'defines': ['DART_VTUNE_SUPPORT'],
-          'link_settings': {
-            'conditions': [
-              ['OS=="linux"', {
-                 'libraries': ['-ljitprofiling'],
-              }],
-              ['OS=="win"', {
-                 'libraries': ['-ljitprofiling.lib'],
-              }],
-            ],
-          },
-        }]],
+       }]],
     },
     {
       'target_name': 'libdart_vm_precompiled_runtime',
@@ -137,26 +118,7 @@
           'sources/' : [
             ['exclude', 'gdbjit.cc'],
           ],
-       }],
-       ['dart_vtune_support==0', {
-          'sources/' : [
-            ['exclude', 'vtune\\.(cc|h)$'],
-          ],
-       }],
-       ['dart_vtune_support==1', {
-          'include_dirs': ['<(dart_vtune_root)/include'],
-          'defines': ['DART_VTUNE_SUPPORT'],
-          'link_settings': {
-            'conditions': [
-              ['OS=="linux"', {
-                 'libraries': ['-ljitprofiling'],
-              }],
-              ['OS=="win"', {
-                 'libraries': ['-ljitprofiling.lib'],
-              }],
-            ],
-          },
-        }]],
+       }]],
     },
     {
       'target_name': 'libdart_vm_noopt',
@@ -200,26 +162,7 @@
           'sources/' : [
             ['exclude', 'gdbjit.cc'],
           ],
-       }],
-       ['dart_vtune_support==0', {
-          'sources/' : [
-            ['exclude', 'vtune\\.(cc|h)$'],
-          ],
-       }],
-       ['dart_vtune_support==1', {
-          'include_dirs': ['<(dart_vtune_root)/include'],
-          'defines': ['DART_VTUNE_SUPPORT'],
-          'link_settings': {
-            'conditions': [
-              ['OS=="linux"', {
-                 'libraries': ['-ljitprofiling'],
-              }],
-              ['OS=="win"', {
-                 'libraries': ['-ljitprofiling.lib'],
-              }],
-            ],
-          },
-        }]],
+       }]],
     },
     {
       'target_name': 'libdart_vm_nosnapshot',
@@ -264,26 +207,7 @@
           'sources/' : [
             ['exclude', 'gdbjit.cc'],
           ],
-       }],
-       ['dart_vtune_support==0', {
-          'sources/' : [
-            ['exclude', 'vtune\\.(cc|h)$'],
-          ],
-       }],
-       ['dart_vtune_support==1', {
-          'include_dirs': ['<(dart_vtune_root)/include'],
-          'defines': ['DART_VTUNE_SUPPORT'],
-          'link_settings': {
-            'conditions': [
-              ['OS=="linux"', {
-                 'libraries': ['-ljitprofiling'],
-              }],
-              ['OS=="win"', {
-                 'libraries': ['-ljitprofiling.lib'],
-              }],
-            ],
-          },
-        }]],
+       }]],
     },
     {
       'target_name': 'libdart_lib_nosnapshot',
@@ -381,6 +305,32 @@
       ],
     },
     {
+      'target_name': 'libdart_lib_precompiled_runtime',
+      'type': 'static_library',
+      'toolsets':['host', 'target'],
+      'includes': [
+        '../lib/async_sources.gypi',
+        '../lib/collection_sources.gypi',
+        '../lib/core_sources.gypi',
+        '../lib/developer_sources.gypi',
+        '../lib/internal_sources.gypi',
+        '../lib/isolate_sources.gypi',
+        '../lib/math_sources.gypi',
+        '../lib/mirrors_sources.gypi',
+        '../lib/typed_data_sources.gypi',
+        '../lib/vmservice_sources.gypi',
+      ],
+      'sources': [
+        'bootstrap_nocore.cc',
+      ],
+      'defines': [
+        'DART_PRECOMPILED_RUNTIME',
+      ],
+      'include_dirs': [
+        '..',
+      ],
+    },
+    {
       'target_name': 'generate_async_cc_file',
       'type': 'none',
       'toolsets':['host'],
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index a3d0536..f21951b 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -9,6 +9,8 @@
     'allocation.cc',
     'allocation.h',
     'allocation_test.cc',
+    'aot_optimizer.cc',
+    'aot_optimizer.h',
     'assembler.cc',
     'assembler.h',
     'assembler_arm.cc',
@@ -144,9 +146,6 @@
     'debugger_ia32.cc',
     'debugger_mips.cc',
     'debugger_x64.cc',
-    'debuginfo.h',
-    'debuginfo_android.cc',
-    'debuginfo_linux.cc',
     'deferred_objects.cc',
     'deferred_objects.h',
     'deopt_instructions.cc',
@@ -162,7 +161,6 @@
     'double_conversion.cc',
     'double_conversion.h',
     'double_internals.h',
-    'elfgen.h',
     'exceptions.cc',
     'exceptions.h',
     'exceptions_test.cc',
@@ -201,10 +199,6 @@
     'gc_marker.h',
     'gc_sweeper.cc',
     'gc_sweeper.h',
-    'gdbjit_android.cc',
-    'gdbjit_android.h',
-    'gdbjit_linux.cc',
-    'gdbjit_linux.h',
     'globals.h',
     'growable_array.h',
     'growable_array_test.cc',
@@ -482,9 +476,6 @@
     'token.h',
     'token_position.cc',
     'token_position.h',
-    'trace_buffer.cc',
-    'trace_buffer.h',
-    'trace_buffer_test.cc',
     'unibrow.cc',
     'unibrow.h',
     'unibrow-inl.h',
@@ -508,8 +499,6 @@
     'virtual_memory_test.cc',
     'virtual_memory_win.cc',
     'visitor.h',
-    'vtune.cc',
-    'vtune.h',
     'weak_code.cc',
     'weak_code.h',
     'weak_table.cc',
diff --git a/runtime/vm/vtune.cc b/runtime/vm/vtune.cc
deleted file mode 100644
index 57e065a..0000000
--- a/runtime/vm/vtune.cc
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#include "vm/vtune.h"
-
-#include <jitprofiling.h>
-
-#include "platform/assert.h"
-
-namespace dart {
-
-bool VTuneCodeObserver::IsActive() const {
-  return (iJIT_IsProfilingActive() == iJIT_SAMPLING_ON);
-}
-
-
-void VTuneCodeObserver::Notify(const char* name,
-                               uword base,
-                               uword prologue_offset,
-                               uword size,
-                               bool optimized) {
-  ASSERT(IsActive());
-  iJIT_Method_Load jmethod;
-  memset(&jmethod, 0, sizeof(jmethod));
-  jmethod.method_id = iJIT_GetNewMethodID();
-  jmethod.method_name = const_cast<char*>(name);
-  jmethod.method_load_address = reinterpret_cast<void*>(base);
-  jmethod.method_size = size;
-  iJIT_NotifyEvent(iJVM_EVENT_TYPE_METHOD_LOAD_FINISHED, &jmethod);
-}
-
-}  // namespace dart
diff --git a/runtime/vm/vtune.h b/runtime/vm/vtune.h
deleted file mode 100644
index 4f62aff..0000000
--- a/runtime/vm/vtune.h
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-#ifndef VM_VTUNE_H_
-#define VM_VTUNE_H_
-
-#include "vm/code_observers.h"
-
-namespace dart {
-
-#if defined(DART_VTUNE_SUPPORT)
-class VTuneCodeObserver : public CodeObserver {
- public:
-  virtual bool IsActive() const;
-
-  virtual void Notify(const char* name,
-                      uword base,
-                      uword prologue_offset,
-                      uword size,
-                      bool optimized);
-};
-#endif
-
-
-}  // namespace dart
-
-#endif  // VM_VTUNE_H_
diff --git a/samples/samples.status b/samples/samples.status
index f1398d9..d9739f4 100644
--- a/samples/samples.status
+++ b/samples/samples.status
@@ -24,5 +24,5 @@
 [ $arch == simarm64 ]
 *: Skip
 
-[ $noopt || $runtime == dart_precompiled ]
+[ $noopt || $runtime == dart_precompiled || $runtime == dart_product ]
 sample_extension: RuntimeError # Platform.executable
diff --git a/sdk/lib/html/html_common/conversions.dart b/sdk/lib/html/html_common/conversions.dart
index 0dca4d3..de0d423 100644
--- a/sdk/lib/html/html_common/conversions.dart
+++ b/sdk/lib/html/html_common/conversions.dart
@@ -266,7 +266,7 @@
 // Conversions for ContextAttributes.
 //
 // On Firefox, the returned ContextAttributes is a plain object.
-class _TypedContextAttributes implements gl.ContextAttributes {
+class ContextAttributes {
   bool alpha;
   bool antialias;
   bool depth;
@@ -275,21 +275,16 @@
   bool stencil;
   bool failIfMajorPerformanceCaveat;
 
-  _TypedContextAttributes(this.alpha, this.antialias, this.depth,
+  ContextAttributes(this.alpha, this.antialias, this.depth,
       this.failIfMajorPerformanceCaveat, this.premultipliedAlpha,
       this.preserveDrawingBuffer, this.stencil);
 }
 
-gl.ContextAttributes convertNativeToDart_ContextAttributes(
-    nativeContextAttributes) {
-  if (nativeContextAttributes is gl.ContextAttributes) {
-    return nativeContextAttributes;
-  }
-
+convertNativeToDart_ContextAttributes(nativeContextAttributes) {
   // On Firefox the above test fails because ContextAttributes is a plain
   // object so we create a _TypedContextAttributes.
 
-  return new _TypedContextAttributes(
+  return new ContextAttributes(
       JS('var', '#.alpha', nativeContextAttributes),
       JS('var', '#.antialias', nativeContextAttributes),
       JS('var', '#.depth', nativeContextAttributes),
diff --git a/sdk/lib/html/html_common/conversions_dartium.dart b/sdk/lib/html/html_common/conversions_dartium.dart
index 3e3e5c1..3c35817 100644
--- a/sdk/lib/html/html_common/conversions_dartium.dart
+++ b/sdk/lib/html/html_common/conversions_dartium.dart
@@ -97,6 +97,31 @@
   return jsObject;
 }
 
+// Creates a Dart class to allow members of the Map to be fetched (as if getters exist).
+// TODO(terry): Need to use package:js but that's a problem in dart:html. Talk to
+//              Jacob about how to do this properly using dart:js.
+class _ReturnedDictionary {
+  Map _values;
+
+  noSuchMethod(InvocationMirror invocation) {
+    var key = MirrorSystem.getName(invocation.memberName);
+    if (invocation.isGetter) {
+      return _values[key];
+    } else if (invocation.isSetter && key.endsWith('=')) {
+      key = key.substring(0, key.length-1);
+      _values[key] = invocation.positionalArguments[0];
+    }
+  }
+
+  Map get toMap => _values;
+
+  _ReturnedDictionary(Map value): _values = value;
+}
+
+// Helper function to wrapped a returned dictionary from blink to a Dart looking
+// class.
+convertNativeDictionaryToDartDictionary(Map values) => new _ReturnedDictionary(values);
+
 // Conversion function place holder (currently not used in dart2js or dartium).
 List convertDartToNative_StringArray(List<String> input) => input;
 
diff --git a/sdk/lib/html/html_common/html_common.dart b/sdk/lib/html/html_common/html_common.dart
index c2e1644..0509f6f 100644
--- a/sdk/lib/html/html_common/html_common.dart
+++ b/sdk/lib/html/html_common/html_common.dart
@@ -9,6 +9,7 @@
 import 'dart:html';
 import 'dart:js' as js;
 import 'dart:_internal' show WhereIterable;
+import 'dart:mirrors';
 import 'dart:nativewrappers';
 import 'dart:typed_data';
 import 'dart:web_gl' as gl;
diff --git a/sdk/lib/io/security_context.dart b/sdk/lib/io/security_context.dart
index 7fc7287..fc9defd 100644
--- a/sdk/lib/io/security_context.dart
+++ b/sdk/lib/io/security_context.dart
@@ -12,12 +12,8 @@
  * The [SecureSocket]  and [SecureServer] classes take a SecurityContext
  * as an argument to their connect and bind methods.
  *
- * Certificates and keys can be added to a SecurityContext from PEM files
- * on the disk.  A PEM file contains one or more base-64 encoded DER-serialized
- * ASN1 objects, surrounded with delimiter strings like
- * "-----BEGIN CERTIFICATE -----" and "-----END CERTIFICATE-----".
- * Distinguished encoding rules (DER) is a canonical binary serialization
- * of ASN1 objects into an octet string.
+ * Certificates and keys can be added to a SecurityContext from either PEM
+ * or PKCS12 containers.
  *
  * [usePrivateKey], [setTrustedCertificates], [useCertificateChain], and
  * [setClientAuthorities] are deprecated. They have been renamed
@@ -46,7 +42,7 @@
    *
    * A secure connection using this SecurityContext will use this key with
    * the server or client certificate to sign and decrypt messages.
-   * [keyFile] is a PEM or PKCS12 file containing an encrypted
+   * [keyFile] is the path to a PEM or PKCS12 file containing an encrypted
    * private key, encrypted with [password].  An unencrypted file can be
    * used, but this is not usual.
    */
@@ -71,18 +67,18 @@
    * client connections, when connecting to a secure server.
    *
    * [file] is the path to a PEM or PKCS12 file containing X509 certificates,
-   * usually root certificates from certificate authorities. When using a
-   * PKCS12 file, it should not contain a private key, and the password should
-   * be the empty string.
+   * usually root certificates from certificate authorities. For PKCS12 files,
+   * [password] is the password for the file. For PEM files, [password] is
+   * ignored.
    */
-  void setTrustedCertificatesSync(String file);
+  void setTrustedCertificatesSync(String file, {String password});
 
   /**
    * [setTrustedCertificates] is deprecated. Use [setTrustedCertificatesSync]
    * or [setTrustedCertificatesBytes].
    */
   @deprecated
-  void setTrustedCertificates(String file);
+  void setTrustedCertificates(String file, {String password});
 
   /**
    * Sets the set of trusted X509 certificates used by [SecureSocket]
@@ -90,7 +86,7 @@
    *
    * Like [setTrustedCertificatesSync] but takes the contents of the file.
    */
-  void setTrustedCertificatesBytes(List<int> certBytes);
+  void setTrustedCertificatesBytes(List<int> certBytes,{String password});
 
   /**
    * Sets the chain of X509 certificates served by [SecureServer]
@@ -99,18 +95,18 @@
    * [file] is a PEM or PKCS12 file containing X509 certificates, starting with
    * the root authority and intermediate authorities forming the signed
    * chain to the server certificate, and ending with the server certificate.
-   * The private key for the server certificate is set by [usePrivateKey]. When
-   * using a PKCS12 file, it should not contain a private key, and the password
-   * should be the empty string.
+   * The private key for the server certificate is set by [usePrivateKey]. For
+   * PKCS12 files, [password] is the password for the file. For PEM files,
+   * [password] is ignored.
    */
-  void useCertificateChainSync(String file);
+  void useCertificateChainSync(String file, {String password});
 
   /**
    * [useCertificateChain] is deprecated. Use [useCertificateChainSync]
    * or [useCertificateChainBytes].
    */
   @deprecated
-  void useCertificateChain({String file, String directory});
+  void useCertificateChain({String file, String directory, String password});
 
   /**
    * Sets the chain of X509 certificates served by [SecureServer]
@@ -118,7 +114,7 @@
    *
    * Like [useCertificateChainSync] but takes the contents of the file.
    */
-  void useCertificateChainBytes(List<int> chainBytes);
+  void useCertificateChainBytes(List<int> chainBytes, {String password});
 
   /**
    * Sets the list of authority names that a [SecureServer] will advertise
@@ -127,17 +123,17 @@
    *
    * [file] is a PEM or PKCS12 file containing the accepted signing
    * authority certificates - the authority names are extracted from the
-   * certificates. When using a PKCS12 file, it should not contain a private
-   * key, and the password should be the empty string.
+   * certificates. For PKCS12 files, [password] is the password for the file.
+   * For PEM files, [password] is ignored.
    */
-  void setClientAuthoritiesSync(String file);
+  void setClientAuthoritiesSync(String file, {String password});
 
   /**
    * [setClientAuthorities] is deprecated. Use [setClientAuthoritiesSync]
    * or [setClientAuthoritiesBytes].
    */
   @deprecated
-  void setClientAuthorities(String file);
+  void setClientAuthorities(String file, {String password});
 
   /**
    * Sets the list of authority names that a [SecureServer] will advertise
@@ -146,7 +142,7 @@
    *
    * Like [setClientAuthoritySync] but takes the contents of the file.
    */
-  void setClientAuthoritiesBytes(List<int> authCertBytes);
+  void setClientAuthoritiesBytes(List<int> authCertBytes, {String password});
 
   /**
    * Sets the list of application-level protocols supported by a client
diff --git a/tests/benchmark_smoke/benchmark_smoke.status b/tests/benchmark_smoke/benchmark_smoke.status
index a83fd89..46f821f 100644
--- a/tests/benchmark_smoke/benchmark_smoke.status
+++ b/tests/benchmark_smoke/benchmark_smoke.status
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 *: Skip
 
 [ $compiler == dart2js && $runtime == none ]
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 603365c..4ea29a4 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -66,8 +66,6 @@
 
 
 Language/Expressions/Method_Invocation/Cascaded_Invocations/syntax_t19: MissingStaticWarning
-Language/Statements/For/For_Loop/execution_t07: MissingStaticWarning
-Language/Statements/For/For_Loop/execution_t08: MissingStaticWarning
 Language/Statements/Switch/last_statement_t03: MissingStaticWarning
 Language/Statements/Assert/type_t04: MissingStaticWarning
 
diff --git a/tests/co19/co19-co19.status b/tests/co19/co19-co19.status
index 81419e9..f6e0f6d 100644
--- a/tests/co19/co19-co19.status
+++ b/tests/co19/co19-co19.status
@@ -46,11 +46,11 @@
 LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: Fail # co19 issue 687
 LibTest/async/Stream/asBroadcastStream_A02_t01: Fail # co19 issue 687
 
-LibTest/core/Symbol/Symbol_A01_t04: RuntimeError # co19-roll r607: Please triage this failure
+LibTest/core/Symbol/Symbol_A01_t04: RuntimeError # Issue 25804
 
-Language/Classes/same_name_type_variable_t01: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
-Language/Classes/same_name_type_variable_t04: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
-Language/Classes/same_name_type_variable_t07: Pass, MissingCompileTimeError, Fail # co19-roll r623: Please triage this failure
+Language/Classes/same_name_type_variable_t01: Pass, MissingCompileTimeError, Fail # Issue 14513
+Language/Classes/same_name_type_variable_t04: Pass, MissingCompileTimeError, Fail # Issue 14513
+Language/Classes/same_name_type_variable_t07: Pass, MissingCompileTimeError, Fail # Issue 14513
 
 LibTest/math/acos_A01_t01: PASS, FAIL, OK # co19 issue 44
 LibTest/math/asin_A01_t01: PASS, FAIL, OK # co19 issue 44
@@ -100,6 +100,6 @@
 ### CHECKED MODE FAILURES ###
 
 [ $compiler != dart2analyzer && $checked ]
-LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19-roll r607: Please triage this failure
-LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19-roll r623: Please triage this failure
+LibTest/collection/DoubleLinkedQueue/removeFirst_A01_t01: RuntimeError # co19 issue 22
+LibTest/collection/LinkedList/LinkedList_A01_t01: RuntimeError # co19 issue 23
 LibTest/collection/LinkedList/lastWhere_A02_t01: RuntimeError # co19 issue 737
diff --git a/tests/co19/co19-dartium.status b/tests/co19/co19-dartium.status
index eb8f2c5..e8e6c56 100644
--- a/tests/co19/co19-dartium.status
+++ b/tests/co19/co19-dartium.status
@@ -6,35 +6,113 @@
 *: Skip # running co19 tests on content_shell would make our dartium cycle-times very long
 
 [ $compiler == none && $runtime == dartium && $system == macos ]
-LayoutTests/fast/writing-mode/broken-ideographic-font_t01: Skip # Timing out on the bots. Please triage this failure.
 LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Skip # Depends on animation timing, commented as known to be flaky in test.  Will not fix.
-LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
+LayoutTests/fast/writing-mode/broken-ideographic-font_t01: Skip # Timing out on the bots. Please triage this failure.
 LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: Pass, RuntimeError # Issue 21605
+LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
 
 [ $compiler == none && $runtime == dartium && $system == windows ]
 LayoutTests/fast/writing-mode/vertical-inline-block-hittest_t01: Pass, RuntimeError # Issue 21605
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: RuntimeError # Please triage this failure.
 
-[ $compiler == none && $runtime == dartium ]
-LayoutTests/fast/dom/custom/document-register-basic_t01: RuntimeError # Bad test can't register HtmlElement.
-LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/xpath/attr-namespace_t01: RuntimeError # Dartium JsInterop failure
-LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
-LayoutTests/fast/xpath/py-dom-xpath/axes_t01: RuntimeError # Dartium JSInterop failure
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Pass, RuntimeError # Flaky with Dartium JsInterop. Seems like timing issues in the test.
-LibTest/html/IFrameElement/IFrameElement.created_A01_t01: RuntimeError # Issue 24568
-LibTest/html/Window/requestFileSystem_A02_t01: Skip # Issue 24585.
-LibTest/html/Window/document_A01_t01: Skip # accesses window.document from a cross-frame window
-WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: Skip # accesses window.document from a cross-frame window
-WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Pass, Fail # https://github.com/dart-lang/co19/issues/12
+[ $compiler == none && $runtime == dartium && $system != windows ]
+LayoutTests/fast/css/font-face-unicode-range-monospace_t01: RuntimeError # co19-roll r761: Please triage this failure.
+
+[ $compiler == none && $runtime == dartium && $mode == debug ]
+WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: Skip # Issue 19495.
+WebPlatformTest/html/semantics/forms/the-datalist-element/datalistoptions_t01: Skip # Issue 20540.
 
 [ $compiler == none && $runtime == dartium && $checked ]
+Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure.
+Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure.
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-column-flex-items_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-flex-items_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/multicol_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css/box-sizing-border-box-dynamic-padding-border-update_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/display-inline-block-scrollbar_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/style-scoped/style-scoped-scoping-nodes-different-order_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LayoutTests/fast/dom/custom/type-extensions_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-abort_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-copy_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-get-entry_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-get-metadata_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-get-parent_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-move_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-read-directory_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-remove_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-restricted-chars_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-restricted-names_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/filesystem/op-restricted-unicode_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/flexbox/flexing-overflow-scroll-item_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/html/article-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/html/aside-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/innerHTML/innerHTML-svg-read_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
+LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/css-table-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/fixed-table-layout-width-change_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/html-table-width-max-width-constrained_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/margins-flipped-text-direction_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/min-max-width-preferred-size_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/nested-tables-with-div-offset_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/table/table-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/trivial-segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/url/trivial_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # https://github.com/dart-lang/co19/issues/21
+LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # co19-roll r722: Issue 18251
+WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
 
-[ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ $compiler == none && $runtime == dartium ]
+Language/Classes/Constructors/Generative_Constructors/execution_t03: Fail, OK
 Language/Classes/Constructors/Generative_Constructors/final_variables_t01: Pass, Fail #: Please triage this failure.
 Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure.
 Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure.
@@ -74,8 +152,12 @@
 Language/Classes/deсlarations_t34: Skip # Times out. Please triage this failure.
 Language/Expressions/Instance_Creation/Const/abstract_class_t01: Fail # Issue 22007
 Language/Expressions/Instance_Creation/Const/abstract_class_t03: Fail # Issue 22007
+Language/Expressions/Instance_Creation/New/execution_t04: Fail, OK
+Language/Expressions/Instance_Creation/New/execution_t06: Fail, OK
 Language/Expressions/Property_Extraction/Named_Constructor_Extraction/not_class_t01: RuntimeError # Please triage this failure.
 Language/Expressions/Spawning_an_Isolate/new_isolate_t01: RuntimeError, OK  # Uses Isolate.spawn.
+Language/Libraries_and_Scripts/Exports/reexport_t01: fail # Dart issue 12916
+Language/Libraries_and_Scripts/Exports/reexport_t02: fail # Dart issue 12916
 Language/Libraries_and_Scripts/Imports/namespace_changes_t10: RuntimeError # Please triage this failure.
 Language/Libraries_and_Scripts/Parts/compilation_t02: Skip # Please triage this failure.
 Language/Libraries_and_Scripts/Parts/syntax_t05: Skip # Times out flakily. Issue 20881
@@ -90,6 +172,12 @@
 Language/Metadata/before_variable_t01: RuntimeError # Please triage this failure.
 Language/Mixins/not_object_superclass_t01: Fail # Please triage this failure.
 Language/Mixins/reference_to_super_t01: Fail # Please triage this failure.
+Language/Statements/Assert/execution_t02: skip # co19 issue 734
+Language/Statements/Assert/execution_t03: skip # co19 issue 734
+Language/Statements/Assert/type_t02: skip # co19 issue 734
+Language/Statements/Assert/type_t05: skip # co19 issue 734
+Language/Statements/Labels/syntax_t03: fail # Dart issue 2238
+Language/Statements/Switch/syntax_t02: fail # Dart issue 12908
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -101,32 +189,163 @@
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.negative_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.veryLarge_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.verySmall_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/alpha_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: Skip # Times out. co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is behind a flag in Chrome
 LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/canvas-getImageData-invalid_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/canvas-large-dimensions_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/canvas-large-fills_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/canvas-lineDash-input-sequence_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/canvas/canvas-lose-restore-googol-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/canvas-lose-restore-max-int-size_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/drawImage-with-broken-image_t01: Timeout, Pass # co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: Pass, RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: RuntimeError # Issue 25653
 LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: Skip # Causes following tests to fail. co19-roll r761: Please triage this failure.
 LayoutTests/fast/canvas/webgl/canvas-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/canvas/webgl/canvas-test_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/canvas-zero-size_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/compressed-tex-image_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/context-lost_t01: RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/draw-arrays-out-of-bounds_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/draw-elements-out-of-bounds_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Issue 22026
 LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/error-reporting_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-test_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/get-active-test_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/gl-enable-enum-test_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-enum-tests_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-get-calls_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-getstring_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError #  Pass, Issue 20, 22026
+LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-vertex-attrib-zero-issues_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-vertex-attrib_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/gl-vertexattribpointer_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: Pass, RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/index-validation-copies-indices_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/index-validation-crash-with-buffer-sub-data_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/index-validation-with-resized-buffer_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/index-validation_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/invalid-UTF-16_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Issue 22026
 LayoutTests/fast/canvas/webgl/is-object_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: Pass, RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/null-uniform-location_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Issue 25653
 LayoutTests/fast/canvas/webgl/premultiplyalpha-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/program-test_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # Issue 25653
 LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/shader-precision-format_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: Skip # Issue 20540
+LayoutTests/fast/canvas/webgl/tex-image-and-uniform-binding-bugs_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: Pass, RuntimeError # Issue 20, 22026
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/texture-active-bind_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-color-profile_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-complete_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-npot_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Issue 22026
 LayoutTests/fast/canvas/webgl/triangle_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/uniform-location-length-limits_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/viewport-unchanged-upon-resize_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/canvas/webgl/webgl-exceptions_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-specific_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: RuntimeError # Issue 25653
+LayoutTests/fast/canvas/webgl/webgl-unprefixed-context-id_t01: Pass, RuntimeError # Issue 22026
+LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: Pass, RuntimeError # Issue 22026
 LayoutTests/fast/css-generated-content/bug91547_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Skip # co19 issue 732.
 LayoutTests/fast/css-generated-content/malformed-url_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -176,18 +395,35 @@
 LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Timeout # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/MarqueeLayoutTest_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/aspect-ratio-inheritance_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: Skip # co19 issue 732.
 LayoutTests/fast/css/computed-offset-with-zoom_t01: Skip # co19 issue 732.
+LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/content-language-mapped-to-webkit-locale_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/content-language-multiple_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/content-language-no-content_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/content/content-none_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/content/content-normal_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/counters/complex-before_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/counters/counter-cssText_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/csstext-of-content-string_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: Pass, RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/ex-unit-with-no-x-height_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/focus-display-block-inline_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/font-face-cache-bug_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -195,9 +431,17 @@
 LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css/font-face-unicode-range-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/font-face-unicode-range-overlap-load_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/fontfaceset-events_t01: Pass, RuntimeError # Issue 23433
 LayoutTests/fast/css/fontfaceset-loadingdone_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/getPropertyValue-columns_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/html-attr-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/id-or-class-before-stylesheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/image-set-setting_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/important-js-override_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/inherit-initial-shorthand-values_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/invalid-predefined-color_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/link-alternate-stylesheet-1_t01: RuntimeError # co19-roll r761: Please triage this failure.
@@ -206,24 +450,32 @@
 LayoutTests/fast/css/link-alternate-stylesheet-4_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/link-alternate-stylesheet-5_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/media-query-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/nested-at-rules_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/parse-color-int-or-percent-crash_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/parsing-at-rule-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/css/parsing-css-nth-child_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/parsing-page-rule_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/parsing-selector-error-recovery_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/parsing-text-rendering_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/pseudo-any_t01: RuntimeError, Pass # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/pseudo-target-indirect-sibling-001_t01: Skip # Times out. co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/pseudo-target-indirect-sibling-002_t01: Skip # Times out. co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/pseudo-valid-unapplied_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/readonly-pseudoclass-opera-001_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/readonly-pseudoclass-opera-002_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/readonly-pseudoclass-opera-003_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/readonly-pseudoclass-opera-004_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/readonly-pseudoclass-opera-005_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/sticky/parsing-position-sticky_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/string-quote-binary_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/style-element-process-crash_t01: Skip # Times out. co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/style-scoped/style-scoped-nested_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css/style-scoped/style-scoped-with-dom-operation_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css/style-scoped/style-scoped-with-important-rule_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/css/transform-origin-parsing_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last-inherited_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/css3-text/css3-text-align-last/getComputedStyle/getComputedStyle-text-align-last_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -295,31 +547,41 @@
 LayoutTests/fast/dom/Range/bug-19527_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/Range/range-created-during-remove-children_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
 LayoutTests/fast/dom/Range/range-detached-exceptions_t01: RuntimeError # Please triage this failure.
+LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/dom/StyleSheet/discarded-sheet-owner-null_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/Window/window-resize-contents_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/Window/window-resize_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/Window/window-scroll-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/anchor-without-content_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/attribute-namespaces-get-set_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/background-shorthand-csstext_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/dom/blur-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/css-cached-import-rule_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/css-innerHTML_t01: RuntimeError # Test is incorrect.
+LayoutTests/fast/dom/css-selectorText_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/dom/cssTarget-crash_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/dom/custom/document-register-basic_t01: RuntimeError # Bad test can't register HtmlElement.
 LayoutTests/fast/dom/custom/document-register-svg-extends_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/custom/element-names_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/dom/dataset-xhtml_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/dataset_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/document-importNode-arguments_t01: RuntimeError # Please triage this failure.
 LayoutTests/fast/dom/empty-hash-and-search_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/focus-contenteditable_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/fragment-activation-focuses-target_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/dom/getElementsByClassName/011_t01: RuntimeError # Chrome 39 roll. Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/dom/option-properties_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/content-reprojection-fallback-crash_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/dom/shadow/form-in-shadow_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/dom/shadow/no-renderers-for-light-children_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/shadow/pseudoclass-update-checked-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
@@ -328,7 +590,9 @@
 LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-optgroup_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/shadow/pseudoclass-update-enabled-option_t01: RuntimeError # co19-roll r738: Please triage this failure.
 LayoutTests/fast/dom/shadow/shadow-content-crash_t01: RuntimeError # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-disable_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/dom/shadow/shadow-removechild-and-blur-event_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
+LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/dynamic/crash-generated-counter_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/dynamic/crash-generated-image_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/dynamic/crash-generated-quote_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -336,9 +600,12 @@
 LayoutTests/fast/dynamic/insertAdjacentElement_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
 LayoutTests/fast/dynamic/insertAdjacentHTML_t01: Pass, RuntimeError # co19 issue 11.
 LayoutTests/fast/dynamic/recursive-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/encoding/css-charset-dom_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/events/add-event-without-document_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Timeout # Dartium 45 roll. Issue 25754
 LayoutTests/fast/events/clipboard-clearData_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/clipboard-dataTransferItemList-remove_t01: RuntimeError # Issue 22532
 LayoutTests/fast/events/clipboard-dataTransferItemList_t01: Skip # Timeout. co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/div-focus_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/document-elementFromPoint_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -353,13 +620,17 @@
 LayoutTests/fast/events/mutation-during-replace-child-2_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/mutation-during-replace-child_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/nested-event-remove-node-crash_t01: Skip # Flaky timeout. co19-roll r786: Please triage this failure.
+LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/events/scoped/editing-commands_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/scroll-event-does-not-bubble_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/events/tabindex-removal-from-focused-element_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/exclusions/parsing/parsing-wrap-flow_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/exclusions/parsing/parsing-wrap-through_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/files/blob-close-read_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/files/blob-close-revoke_t01: RuntimeError # Experimental feature not exposed anywhere yet
 LayoutTests/fast/files/blob-close_t01: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/files/blob-constructor_t01: RuntimeError # Dartium 45 roll. Issue 25754
+LayoutTests/fast/files/file-reader-fffd_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/files/xhr-response-blob_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/async-operations_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/filesystem/directory-entry-to-uri_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -374,6 +645,7 @@
 LayoutTests/fast/filesystem/read-directory-many_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/filesystem/simple-readonly_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/HTMLOptionElement_selected2_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/ValidityState-customError_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/forms/autofocus-focus-only-once_t01: Skip # Times out. co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Skip # Times out. co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/autofocus-opera-007_t01: Skip # Times out. co19-roll r801: Please triage this failure.
@@ -385,6 +657,7 @@
 LayoutTests/fast/forms/date-multiple-fields/date-multiple-fields-onblur-setvalue-onfocusremoved_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/datetimelocal-multiple-fields/datetimelocal-multiple-fields-change-layout-by-value_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/datetimelocal/datetimelocal-interactive-validation-required_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Experimental feature not exposed in Chrome yet
 LayoutTests/fast/forms/focus-style-pending_t01: Skip # Times out. co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/form-submission-create-crash_t01: Skip # Test reloads itself. Issue 18558.
@@ -395,6 +668,8 @@
 LayoutTests/fast/forms/formmethod-attribute-input-html_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/input-appearance-elementFromPoint_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/input-hit-test-border_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/input-inputmode_t01: RuntimeError # Experimental feature not exposed in Chrome yet
+LayoutTests/fast/forms/input-value-sanitization_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/forms/input-width-height-attributes-without-renderer-loaded-image_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/listbox-select-all_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/listbox-selection-2_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -416,9 +691,11 @@
 LayoutTests/fast/forms/submit-form-with-dirname-attribute_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/submit-nil-value-field-assert_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/submit-nil-value-field-assert_t01: Skip # Test reloads itself. Issue 18558.
+LayoutTests/fast/forms/textarea-paste-newline_t01: Pass, RuntimeError # Issue 23433
 LayoutTests/fast/forms/textarea-scrollbar-height_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/forms/textarea-submit-crash_t01: Skip # Test reloads itself. Issue 18558.
 LayoutTests/fast/forms/textfield-focus-out_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/forms/validationMessage_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/html/adjacent-html-context-element_t01:RuntimeError # co19 issue 11.
 LayoutTests/fast/html/hidden-attr_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LayoutTests/fast/html/imports/import-element-removed-flag_t01: RuntimeError # co19-roll r706.  Please triage this failure.
@@ -439,6 +716,7 @@
 LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/inline/reattach-inlines-in-anonymous-blocks-with-out-of-flow-siblings_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/innerHTML/innerHTML-special-elements_t01: RuntimeError # co19 issue 11.
+LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
@@ -451,6 +729,7 @@
 LayoutTests/fast/loader/hashchange-event-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/loader/loadInProgress_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/loader/onhashchange-attribute-listeners_t01: Skip # Times out. co19-roll r801: Please triage this failure.
+LayoutTests/fast/loader/onload-policy-ignore-for-frame_t01: Timeout # Dartium 45 roll. Issue 25754
 LayoutTests/fast/loader/scroll-position-restored-on-back_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: Skip # Times out. co19-roll r801: Please triage this failure.
 LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -467,6 +746,7 @@
 LayoutTests/fast/multicol/break-after-always-bottom-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/break-properties_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/column-width-zero_t01: Pass, RuntimeError # co19 issue 11.
+LayoutTests/fast/multicol/columns-shorthand-parsing_t02: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/multicol/cssom-view_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/multicol/flipped-blocks-hit-test_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
@@ -527,9 +807,12 @@
 LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
 LayoutTests/fast/replaced/container-width-zero_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError # Dartium 45 roll. Issue 25754
 LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError, Pass # Spurious intermittent pass. # co19 issue 11.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Timeout # Dartium 45 roll. Issue 25754
 LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: RuntimeError, Pass # Spurious intermittent pass # co19 issue 11.
+LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: Timeout # Dartium 45 roll. Issue 25754
 LayoutTests/fast/replaced/preferred-widths_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
 LayoutTests/fast/replaced/table-percent-height-text-controls_t01: RuntimeError # co19 issue 11.
 LayoutTests/fast/replaced/table-percent-height_t01: RuntimeError # co19-roll r801: Please triage this failure.
@@ -695,13 +978,17 @@
 LayoutTests/fast/xpath/4XPath/Core/test_core_functions_t02: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/xpath/4XPath/Core/test_node_test_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/xpath/4XPath/Core/test_node_test_t02: RuntimeError # co19-roll r786: Please triage this failure.
+LayoutTests/fast/xpath/4XPath/Core/test_parser_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/ambiguous-operators_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/attr-namespace_t01: RuntimeError # Dartium JsInterop failure
 LayoutTests/fast/xpath/attr-namespace_t02: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/xpath/ensure-null-namespace_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/xpath/implicit-node-args_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/xpath/node-name-case-sensitivity_t01: RuntimeError # co19-roll r761: Please triage this failure.
 LayoutTests/fast/xpath/node-name-case-sensitivity_t02: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/xpath/position_t01: RuntimeError # co19-roll r761: Please triage this failure.
+LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
+LayoutTests/fast/xpath/py-dom-xpath/axes_t01: RuntimeError # Dartium JSInterop failure
 LayoutTests/fast/xpath/py-dom-xpath/data_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/xpath/py-dom-xpath/expressions_t01: RuntimeError # co19-roll r786: Please triage this failure.
 LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # co19-roll r786: Please triage this failure.
@@ -713,7 +1000,15 @@
 LibTest/collection/ListBase/ListBase_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
 LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip # co19-roll r722: Please triage this failure.
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19-roll r722: Please triage this failure.
+LibTest/core/DateTime/parse_A01_t02: Skip # Times out. Please triage this failure.
+LibTest/core/DateTime/parse_A03_t01: fail # Issue 12514
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: Fail # Issue 22200
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: Fail # Issue 22200
+LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: Fail # Issue 22200
+LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Issue 13596
+LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Issue 13596
 LibTest/core/int/operator_left_shift_A01_t02: Pass, Fail # Please triage this failure.
+LibTest/core/int/toRadixString_A01_t01: Fail # co19 issue 492
 LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t03: RuntimeError # co19-roll r722: Please triage this failure.
 LibTest/html/CanvasRenderingContext2D/addEventListener_A01_t06: RuntimeError # co19-roll r722: Please triage this failure.
 LibTest/html/Document/childNodes_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
@@ -743,6 +1038,7 @@
 LibTest/html/HttpRequestUpload/onLoadEnd_A01_t01: Skip # co19-roll r706.  Please triage this failure.
 LibTest/html/HttpRequestUpload/onLoadStart_A01_t01: Skip # co19-roll r706.  Please triage this failure.
 LibTest/html/HttpRequestUpload/onLoad_A01_t01: Skip # co19-roll r706.  Please triage this failure.
+LibTest/html/IFrameElement/IFrameElement.created_A01_t01: RuntimeError # Issue 24568
 LibTest/html/IFrameElement/appendHtml_A01_t01: Pass, RuntimeError # Issue 23462
 LibTest/html/IFrameElement/appendHtml_A01_t01: RuntimeError # Issue 23462
 LibTest/html/IFrameElement/appendHtml_A01_t02: Pass, RuntimeError # Issue 23462
@@ -774,6 +1070,7 @@
 LibTest/html/Node/nodes_A01_t02: RuntimeError # co19-roll r722: Please triage this failure.
 LibTest/html/Node/parent_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
 LibTest/html/Node/previousNode_A01_t01: RuntimeError # co19-roll r722: Please triage this failure.
+LibTest/html/Window/document_A01_t01: Skip # accesses window.document from a cross-frame window
 LibTest/html/Window/find_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/html/Window/find_A03_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/html/Window/find_A06_t01: RuntimeError # co19-roll r706.  Please triage this failure.
@@ -781,6 +1078,7 @@
 LibTest/html/Window/moveTo_A02_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/html/Window/postMessage_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/html/Window/requestFileSystem_A01_t02: RuntimeError,Pass # co19-roll r722: Please triage this failure.
+LibTest/html/Window/requestFileSystem_A02_t01: Skip # Issue 24585.
 LibTest/html/Window/resizeBy_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/html/Window/resizeTo_A01_t01: RuntimeError # co19-roll r706.  Please triage this failure.
 LibTest/isolate/Isolate/spawnUri_A01_t01: RuntimeError # Dart issue 15974
@@ -789,12 +1087,15 @@
 LibTest/isolate/Isolate/spawnUri_A01_t04: RuntimeError # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A01_t05: RuntimeError # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A02_t01: RuntimeError # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A02_t02: Skip # Dart issue 15974
+LibTest/isolate/Isolate/spawnUri_A02_t03: Skip # Dart issue 15974
 LibTest/isolate/Isolate/spawnUri_A02_t04: Skip # Dart issue 15974
 LibTest/isolate/Isolate/spawn_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/Isolate/spawn_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/Isolate/spawn_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/Isolate/spawn_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A01_t05: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/Isolate/spawn_A02_t02: RuntimeError # Dart issue 15617
 LibTest/isolate/RawReceivePort/RawReceivePort_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/RawReceivePort/RawReceivePort_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/RawReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
@@ -803,11 +1104,18 @@
 LibTest/isolate/ReceivePort/any_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/any_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/asBroadcastStream_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A01_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
 LibTest/isolate/ReceivePort/asBroadcastStream_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/asBroadcastStream_A01_t04: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: RuntimeError # Issue 13921
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t03: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
 LibTest/isolate/ReceivePort/asBroadcastStream_A04_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/asBroadcastStream_A04_t02: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/asBroadcastStream_A04_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
+LibTest/isolate/ReceivePort/close_A02_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
 LibTest/isolate/ReceivePort/contains_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/distinct_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/distinct_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
@@ -840,6 +1148,7 @@
 LibTest/isolate/ReceivePort/reduce_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/reduce_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/reduce_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
+LibTest/isolate/ReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
 LibTest/isolate/ReceivePort/singleWhere_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/singleWhere_A02_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/single_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
@@ -856,14 +1165,6 @@
 LibTest/isolate/ReceivePort/transform_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/where_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/ReceivePort/where_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
-LibTest/isolate/ReceivePort/close_A01_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A01_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A02_t01: RuntimeError # Issue 13921
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t02: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/asBroadcastStream_A03_t03: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/close_A02_t01: Pass, RuntimeError # Issue 13921, co19 issue for false pass https://github.com/dart-lang/co19/issues/13
-LibTest/isolate/ReceivePort/sendPort_A01_t01: RuntimeError # Issue 13921
 LibTest/isolate/SendPort/send_A01_t01: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/SendPort/send_A01_t02: RuntimeError, OK  # Uses Isolate.spawn.
 LibTest/isolate/SendPort/send_A01_t03: RuntimeError, OK  # Uses Isolate.spawn.
@@ -920,6 +1221,7 @@
 WebPlatformTest/html-templates/parsing-html-templates/creating-an-element-for-the-token/template-owner-document_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-image_t01: RuntimeError # co19-roll r738: Please triage this failure.
 WebPlatformTest/html/browsers/browsing-the-web/read-media/pageload-video_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/browsers/browsing-the-web/read-text/load-text-plain_t01: Skip # accesses window.document from a cross-frame window
 WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-getter_t01: RuntimeError # co19-roll r738: Please triage this failure.
 WebPlatformTest/html/dom/documents/dom-tree-accessors/document.body-setter_t01: RuntimeError # co19-roll r738: Please triage this failure.
 WebPlatformTest/html/dom/documents/dom-tree-accessors/document.getElementsByName-case_t01: RuntimeError # co19 issue 11.
@@ -945,6 +1247,7 @@
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # co19-roll r738: Please triage this failure.
 WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formAction_document_address_t01: RuntimeError # co19-roll r738: Please triage this failure.
 WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # co19-roll r738: Please triage this failure.
+WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Dartium 45 roll. Issue 25754
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # co19-roll r738: Please triage this failure.
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.  Pass on macos.
 WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # co19-roll r738: Please triage this failure.
@@ -1013,8 +1316,11 @@
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: RuntimeError # Dartium 45 roll. Issue 25754
 WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-005_t01: RuntimeError # Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-006_t01: RuntimeError # Please triage this failure.
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-002_t01: RuntimeError # Dartium 45 roll. Issue 25754
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-005_t01: RuntimeError # Dartium 45 roll. Issue 25754
 WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: RuntimeError # Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: RuntimeError # Please triage this failure.
 WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: RuntimeError # co19-roll r722: Please triage this failure.
@@ -1027,9 +1333,11 @@
 WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: RuntimeError # Not clear that any of this works. Also suppressed in dart2js
 WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Pass, RuntimeError # Flaky with Dartium JsInterop. Seems like timing issues in the test.
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Skip # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Skip # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Skip # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Pass, Fail # https://github.com/dart-lang/co19/issues/12
 WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: RuntimeError, Pass # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
@@ -1039,359 +1347,10 @@
 WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # co19-roll r722: Please triage this failure.
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: RuntimeError # Dartium 45 roll. Issue 25754
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # co19-roll r722: Please triage this failure.
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure.
 WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # co19-roll r761: Please triage this failure.
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
 WebPlatformTest/webstorage/storage_session_setitem_quotaexceedederr_t01: Skip # Times out flakily. co19-roll r761: Please triage this failure.
-
-[ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid ) && $checked ]
-Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure.
-Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure.
-Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure.
-Language/Errors_and_Warnings/static_warning_t04: RuntimeError # Please triage this failure.
-Language/Errors_and_Warnings/static_warning_t05: RuntimeError # Please triage this failure.
-Language/Errors_and_Warnings/static_warning_t06: RuntimeError # Please triage this failure.
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-blocks_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-column-flex-items_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-flex-items_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/multicol_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/width-shrinks-avoid-floats_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/css/box-sizing-border-box-dynamic-padding-border-update_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/display-inline-block-scrollbar_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/fixed-width-intrinsic-width-excludes-scrollbars_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-relative_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/HTMLDialogElement/top-layer-position-static_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/HTMLLabelElement/form/test1_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/HTMLTableElement/insert-row_t01: RuntimeError # co19-roll r722: Please triage this failure.
-LayoutTests/fast/dom/custom/type-extensions_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/dom/shadow/shadowhost-keyframes_t01: RuntimeError, Pass # co19-roll r738: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-abort_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-events_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-copy_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-get-entry_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-get-metadata_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-get-parent_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-move_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-read-directory_t01: Pass, RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-remove_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-restricted-chars_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-restricted-names_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/filesystem/op-restricted-unicode_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/flexbox/flexing-overflow-scroll-item_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/flexbox/intrinsic-min-width-applies-with-fixed-width_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/select-list-box-mouse-focus_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/html/article-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/html/aside-element_t01: RuntimeError # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/inline/empty-inline-before-collapsed-space_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/innerHTML/innerHTML-svg-read_t01: RuntimeError, Pass # co19-roll r706.  Please triage this failure.
-LayoutTests/fast/lists/list-style-position-inside_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/lists/marker-preferred-margins_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/fixed-column-percent-logical-height-orthogonal-writing-mode_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/multicol/vertical-lr/image-inside-nested-blocks-with-border_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/available-height-for-content_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor-vertical-lr_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/replaced/computed-image-width-with-percent-height-inside-table-cell-and-fixed-ancestor_t01: Pass, RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-image-threshold_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-margin_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/shapes/parsing/parsing-shape-outside_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/table/absolute-table-percent-lengths_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/css-table-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/fixed-table-layout-width-change_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/html-table-width-max-width-constrained_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/margins-flipped-text-direction_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/min-max-width-preferred-size_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/nested-tables-with-div-offset_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/table/switch-table-layout-dynamic-cells_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/switch-table-layout-multiple-section_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # co19 issue 11.
-LayoutTests/fast/table/switch-table-layout_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/table/table-width-exceeding-max-width_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/text/line-break-after-inline-latin1_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/trivial-segments_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/url/trivial_t01: RuntimeError # co19-roll r786: Please triage this failure.
-LayoutTests/fast/xpath/invalid-resolver_t01: RuntimeError # https://github.com/dart-lang/co19/issues/21
-LayoutTests/fast/xpath/xpath-result-eventlistener-crash_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LibTest/html/Node/ownerDocument_A01_t01: RuntimeError # co19-roll r722: Issue 18251
-WebPlatformTest/DOMEvents/approved/Propagation.path.target.removed_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-body-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html-templates/parsing-html-templates/clearing-the-stack-back-to-a-given-context/clearing-stack-back-to-a-table-row-context_t01: RuntimeError # co19-roll r722: Please triage this failure.
-WebPlatformTest/html/dom/elements/global-attributes/dataset-enumeration_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # co19-roll r738: Please triage this failure.
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: RuntimeError # co19-roll r722: Please triage this failure.
-
-[ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $mode == debug ]
-WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: Skip # Issue 19495.
-WebPlatformTest/html/semantics/forms/the-datalist-element/datalistoptions_t01: Skip # Issue 20540.
-
-[ $compiler == none && $runtime == ContentShellOnAndroid ]
-LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError #  Please triage this failure.
-LayoutTests/fast/canvas/canvas-scale-drawImage-shadow_t01: RuntimeError, Pass #  Please triage this failure.
-LayoutTests/fast/canvas/canvas-scale-fillPath-shadow_t01: RuntimeError, Pass #  Please triage this failure.
-LayoutTests/fast/canvas/canvas-scale-fillRect-shadow_t01: Skip # Times out.  Please triage this failure.
-LayoutTests/fast/canvas/canvas-scale-shadowBlur_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-scale-strokePath-shadow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-strokePath-alpha-shadow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-strokePath-gradient-shadow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-strokeRect-alpha-shadow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-strokeRect-gradient-shadow_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/canvas-transforms-fillRect-shadow_t01: RuntimeError, Pass #  Please triage this failure.
-LayoutTests/fast/canvas/webgl/canvas-test_t01: RuntimeError, Pass #  Please triage this failure.
-LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: Skip # Times out flakily.  Please triage this failure.
-LayoutTests/fast/css-generated-content/bug-106384_t01: Skip # Times out.  Please triage this failure.
-LayoutTests/fast/css-generated-content/empty-first-letter-with-columns-crash_t01: Skip # Times out.  Please triage this failure.
-LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: RuntimeError #  Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: RuntimeError #  Please triage this failure.
-LayoutTests/fast/css-intrinsic-dimensions/tables_t01: RuntimeError #  Please triage this failure.
-LayoutTests/fast/css/getComputedStyle/computed-style-select-overflow_t01: RuntimeError #  Please triage this failure.
-LayoutTests/fast/css/vertical-align-length-copy-bug_t01: RuntimeError #  Please triage this failure.
-LayoutTests/fast/dom/HTMLElement/innerHTML-selection-crash_t01: Skip # Times out.  Please triage this failure.
-LayoutTests/fast/dom/HTMLLinkElement/prefetch-beforeload_t01: Pass, RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/jsDevicePixelRatio_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/partial-layout-non-overlay-scrollbars_t01: Pass, RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: Pass, RuntimeError # Please triage this failure.
-LayoutTests/fast/dom/shadow/shadowdom-for-input-type-change_t01: RuntimeError # Please triage this failure.
-LayoutTests/fast/filesystem/file-writer-abort-continue_t01: Skip # Times out.  Please triage this failure.
-LayoutTests/fast/forms/activate-and-disabled-elements_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/forms/plaintext-mode-1_t01: RuntimeError # co19-roll r801: Please triage this failure.
-LayoutTests/fast/forms/selection-direction_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/forms/text-set-value-crash_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/forms/textarea-paste-newline_t01: RuntimeError # co19-roll r801 : Please triage this failure.
-LayoutTests/fast/inline/continuation-inlines-inserted-in-reverse-after-block_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-inline-parent_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent-relative-ancestor_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/inline/fixed-pos-moves-with-abspos-parent_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/inline/inline-relative-offset-boundingbox_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/layers/negative-scroll-positions_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/loader/loadInProgress_t01: Skip # Times out. Please triage this failure.
-LayoutTests/fast/table/table-rowspan-height-distribution-in-rows_t02: Skip # Times out. Please triage this failure.
-LayoutTests/fast/text-autosizing/text-removal_t01: RuntimeError #  Please triage this failure.
-LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError #  Please triage this failure.
-LayoutTests/fast/transforms/scrollIntoView-transformed_t01: RuntimeError #  Please triage this failure.
-LibTest/collection/ListBase/ListBase_class_A01_t02: Skip # Times out flakily. Issue 20956
-LibTest/core/DateTime/parse_A01_t02: Skip # Times out. Please triage this failure.
-LibTest/core/List/List_class_A01_t02: Skip # Times out flakily. Issue 20956
-LibTest/html/Element/getBoundingClientRect_A01_t02: RuntimeError # Issue 19127.
-LibTest/html/Window/animationFrame_A01_t01: Skip # Times out.  Please triage this failure.
-LibTest/math/log_A01_t01: Pass, Fail # co19 issue 44.
-
-[ $compiler == none && $runtime == dartium ]
-LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # co19-roll r761: Please triage this failure.
-LayoutTests/fast/css/fontfaceset-events_t01: Pass, RuntimeError # Issue 23433
-LayoutTests/fast/events/clipboard-dataTransferItemList-remove_t01: RuntimeError # Issue 22532
-LayoutTests/fast/forms/textarea-paste-newline_t01: Pass, RuntimeError # Issue 23433
-LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is behind a flag in Chrome
-LayoutTests/fast/files/blob-close-revoke_t01: RuntimeError # Experimental feature not exposed anywhere yet
-LayoutTests/fast/forms/file/file-input-capture_t01: RuntimeError # Experimental feature not exposed in Chrome yet
-LayoutTests/fast/forms/input-inputmode_t01: RuntimeError # Experimental feature not exposed in Chrome yet
-
-[ $compiler == none && $runtime == dartium ]
-LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/oes-vertex-array-object_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/point-size_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/read-pixels-pack-alignment_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/read-pixels-test_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-active-bind_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-color-profile_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-complete_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/texture-npot_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/webgl-texture-binding-preserved_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/viewport-unchanged-upon-resize_t01: RuntimeError # Issue 25653
-LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
-
-LayoutTests/fast/canvas/webgl/WebGLContextEvent_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/canvas-test_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/canvas-zero-size_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/compressed-tex-image_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/draw-arrays-out-of-bounds_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/draw-elements-out-of-bounds_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/error-reporting_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/framebuffer-test_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/get-active-test_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-enable-enum-test_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-enum-tests_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-get-calls_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-getstring_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-vertex-attrib-zero-issues_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-vertex-attrib_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-vertexattribpointer_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/index-validation-copies-indices_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/index-validation-crash-with-buffer-sub-data_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/index-validation-verifies-too-many-indices_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/index-validation-with-resized-buffer_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/index-validation_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/invalid-UTF-16_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/null-uniform-location_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/program-test_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/shader-precision-format_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-image-and-uniform-binding-bugs_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/uniform-location-length-limits_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-composite-modes-repaint_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-composite-modes_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-exceptions_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-specific_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-unprefixed-context-id_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/webgl-viewport-parameters-preserved_t01: Pass, RuntimeError # Issue 22026
-LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError #  Pass, Issue 20, 22026
-LayoutTests/fast/canvas/webgl/incorrect-context-object-behaviour_t01: Pass, RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/null-object-behaviour_t01: Pass, RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: Pass, RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/context-lost_t01: RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Issue 20, 22026
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: Pass, RuntimeError # Issue 20, 22026
-
-LayoutTests/fast/canvas/alpha_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/canvas/canvas-lineDash-input-sequence_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/MarqueeLayoutTest_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/aspect-ratio-inheritance_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/aspect-ratio-parsing-tests_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/content-language-mapped-to-webkit-locale_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/content-language-multiple_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/content-language-no-content_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/counters/counter-cssText_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/csstext-of-content-string_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/ex-unit-with-no-x-height_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/font-shorthand-from-longhands_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/getComputedStyle/computed-style-font_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/getComputedStyle/computed-style-properties_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/getComputedStyle/counterIncrement-without-counter_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/getPropertyValue-columns_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/image-set-setting_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/important-js-override_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/nested-at-rules_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/parse-color-int-or-percent-crash_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/parsing-css-allowed-string-characters_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/parsing-css-nth-child_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/parsing-text-rendering_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/pseudo-valid-unapplied_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/string-quote-binary_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css/transform-origin-parsing_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/dom/background-shorthand-csstext_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/dom/css-selectorText_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/dom/custom/element-names_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/dom/fragment-activation-focuses-target_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/dom/shadow/content-reprojection-fallback-crash_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/dom/shadow/event-path_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/dom/shadow/shadow-disable_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/dom/shadow/shadow-root-js-api_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/encoding/css-charset-dom_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/events/overflowchanged-event-raf-timing_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/files/blob-constructor_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/files/file-reader-fffd_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/forms/ValidityState-customError_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/forms/input-value-sanitization_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/forms/validationMessage_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/multicol/columns-shorthand-parsing_t02: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: RuntimeError # Dartium 45 roll. Issue 25754
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Dartium 45 roll. Issue 25754
-WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: RuntimeError # Dartium 45 roll. Issue 25754
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-002_t01: RuntimeError # Dartium 45 roll. Issue 25754
-WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-005_t01: RuntimeError # Dartium 45 roll. Issue 25754
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: RuntimeError # Dartium 45 roll. Issue 25754
-LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-replaced-absolutes_t01: Timeout # Dartium 45 roll. Issue 25754
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-anonymous-table-cell_t01: Timeout # Dartium 45 roll. Issue 25754
-LayoutTests/fast/replaced/iframe-with-percentage-height-within-table-with-table-cell-ignore-height_t01: Timeout # Dartium 45 roll. Issue 25754
-LayoutTests/fast/events/change-overflow-on-overflow-change_t01: Timeout # Dartium 45 roll. Issue 25754
-LayoutTests/fast/loader/onload-policy-ignore-for-frame_t01: Timeout # Dartium 45 roll. Issue 25754
-
-[ $compiler == none && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $system != windows ]
-LayoutTests/fast/css/font-face-unicode-range-monospace_t01: RuntimeError # co19-roll r761: Please triage this failure.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 322d664..01a850a 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -3,7 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 
-[ ($compiler == none || $compiler == precompiler) && (($runtime == vm || $runtime == dart_precompiled) || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 
 # Failures ok in tests below. VM moves super initializer to end of list.
 Language/Classes/Constructors/Generative_Constructors/execution_t03: Fail, OK
@@ -43,7 +43,7 @@
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Issue 13596
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Issue 13596
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 LibTest/typed_data/Float32x4/reciprocalSqrt_A01_t01: Pass, Fail # co19 issue 599
 LibTest/typed_data/Float32x4/reciprocal_A01_t01: Pass, Fail # co19 issue 599
 Language/Expressions/Instance_Creation/Const/abstract_class_t01: MissingCompileTimeError # Issue 22007
@@ -52,17 +52,15 @@
 Language/Libraries_and_Scripts/Imports/invalid_uri_t02: Fail
 Language/Libraries_and_Scripts/Exports/invalid_uri_t02: Fail
 Language/Libraries_and_Scripts/Parts/syntax_t06: Fail
-
-[ ($runtime == vm || $runtime == dart_precompiled) ]
 LibTest/math/MutableRectangle/MutableRectangle.fromPoints_A01_t01: Pass, RuntimeError # co19-roll r607: Please triage this failure
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $mode == debug ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $mode == debug ]
 LibTest/core/List/List_class_A01_t02: Pass, Slow
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch != x64 && $arch != simarm64 && $arch != arm64) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && ($arch != x64 && $arch != simarm64 && $arch != arm64) ]
 LibTest/core/int/operator_left_shift_A01_t02: Fail # co19 issue 129
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch == mips) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $arch == mips ]
 LibTest/core/double/toInt_A01_t01: Fail
 
 [ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch == mips || $arch == arm64) ]
@@ -72,34 +70,34 @@
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip # co19 issue 673
 LibTest/collection/ListBase/ListBase_class_A01_t02: Skip # co19 issue 673
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $mode == debug ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $arch == mips && $mode == debug ]
 LibTest/isolate/Isolate/spawnUri_A01_t04: Crash, Pass # Issue 17440
 LibTest/isolate/Isolate/spawn_A01_t04: Crash, Pass # Issue 17440
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ($arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simmips || $arch == simarm64) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && ($arch == simarm || $arch == simarmv6 || $arch == simarmv5te || $arch == simmips || $arch == simarm64) ]
 LibTest/core/Uri/Uri_A06_t03: Skip  # Timeout
 LibTest/collection/ListMixin/ListMixin_class_A01_t01: Skip  # Timeout
 LibTest/collection/ListBase/ListBase_class_A01_t01: Skip  # Timeout
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Skip  # Timeout
 LibTest/collection/ListBase/ListBase_class_A01_t02: Skip  # Timeout
 
-[ ($compiler == none || $compiler == precompiler) && $system == windows ]
+[ $system == windows ]
 LibTest/collection/ListMixin/ListMixin_class_A01_t02: Pass, Slow
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Slow
 
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 LibTest/isolate/Isolate/spawn_A02_t01: Skip # co19 issue 667
 LibTest/html/*: SkipByDesign # dart:html not supported on VM.
 LayoutTests/fast/*: SkipByDesign # DOM not supported on VM.
 WebPlatformTest/*: SkipByDesign # dart:html not supported on VM.
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $mode == debug && $builder_tag == asan ]
 Language/Types/Interface_Types/subtype_t27: Skip  # Issue 21174.
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $arch == arm ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $arch == arm ]
 LibTest/typed_data/Float32x4/operator_multiplication_A01_t01: Fail # Dart issue 24416
 
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 # co19 update Sep 29, 2015 (3ed795ea02e022ef19c77cf1b6095b7c8f5584d0)
 Language/Classes/Getters/type_object_t01: RuntimeError # Please triage this failure
 Language/Classes/Getters/type_object_t02: RuntimeError # Please triage this failure
@@ -137,7 +135,7 @@
 Language/Mixins/not_object_superclass_t01: MissingCompileTimeError # Please triage this failure
 Language/Mixins/reference_to_super_t01: MissingCompileTimeError # Please triage this failure
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $checked ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $checked ]
 Language/Errors_and_Warnings/static_warning_t01: RuntimeError # Please triage this failure
 Language/Errors_and_Warnings/static_warning_t02: RuntimeError # Please triage this failure
 Language/Errors_and_Warnings/static_warning_t03: RuntimeError # Please triage this failure
@@ -158,3 +156,20 @@
 
 [ $runtime == dart_precompiled ]
 LibTest/isolate/Isolate/spawnUri*: RuntimeError # Isolate.spawnUri
+
+[ $runtime == dart_product ]
+LibTest/isolate/Isolate/spawnUri*: Skip # Isolate.spawnUri
+
+[ $runtime == vm && $mode == product ]
+LibTest/typed_data/Float32List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Float32x4List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Float64List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Int16List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Int32List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Int64List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Int8List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Uint16List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Uint32List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Uint64List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Uint8ClampedList/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
+LibTest/typed_data/Uint8List/runtimeType_A01_t01: Fail,OK  # Expects exact type name.
diff --git a/tests/compiler/dart2js/cps_ir/runner.dart b/tests/compiler/dart2js/cps_ir/runner.dart
index af77384..9f76482 100644
--- a/tests/compiler/dart2js/cps_ir/runner.dart
+++ b/tests/compiler/dart2js/cps_ir/runner.dart
@@ -28,8 +28,13 @@
       .readAsStringSync();
   var expectedFile =
       new File.fromUri(Platform.script.resolve('expected/$outputname'));
-  String expected = expectedFile.existsSync()
-    ? expectedFile.readAsStringSync() : '';
+  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);
 
@@ -58,14 +63,9 @@
       Expect.isTrue(result.isSuccess);
       CompilerImpl compiler = result.compiler;
       if (expected != null) {
-        String output = elementName == null
+        found = elementName == null
             ? _getCodeForMain(compiler)
             : _getCodeForMethod(compiler, elementName);
-        // Include the input in a comment of the expected file to make it easier
-        // to see the relation between input and output in code reviews.
-        found = '// Expectation for test: \n'
-            '// ${source.trim().replaceAll('\n', '\n// ')}\n\n'
-            '$output\n';
       }
     } catch (e, st) {
       print(e);
@@ -81,12 +81,16 @@
     }
     if (expected != found) {
       if (update) {
-        expectedFile.writeAsStringSync(found);
+        // 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'
+            'Expected:\n  ${expected.replaceAll('\n', '\n  ')}\n\n'
             'but found:\n  ${found?.replaceAll('\n', '\n  ')}\n'
             '$regenerateCommand');
       }
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index d3f5ad8..888e95f 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -49,8 +49,8 @@
 
 # Source information is not correct due to inlining.
 js_backend_cps_ir_source_information_test: Fail
-sourcemaps/source_mapping_operators_test: Fail # Issue 25304 for checked mode, was: Pass, Slow
-sourcemaps/source_mapping_invokes_test: Fail # Issue 25304 for checked mode, was: Pass, Slow
+sourcemaps/source_mapping_operators_test: Fail, Slow # Issue 25304 for checked mode, was: Pass, Slow
+sourcemaps/source_mapping_invokes_test: Fail, Slow # Issue 25304 for checked mode, was: Pass, Slow
 
 check_elements_invariants_test: Slow, Pass, Timeout # Slow due to inlining in the CPS backend
 
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 586d145..3d4c849 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 bool_from_environment2_test: Skip
 bool_from_environment_test: Skip
 from_environment_const_type_test: Skip
@@ -14,20 +14,42 @@
 string_from_environment3_test: Skip
 string_from_environment_test: Skip
 
-[ ($compiler == none || $compiler == precompiler) ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) ]
 unicode_test: Fail        # Bug 6706
 compare_to2_test: Fail    # Bug 4018
 
 symbol_test/01: Fail, Pass # bug 11669
 
+# With the exception of 'void', new Symbol() should not accept reserved words.
+symbol_reserved_word_test/06: RuntimeError # bug 11669
+symbol_reserved_word_test/09: RuntimeError # bug 11669
+symbol_reserved_word_test/12: RuntimeError # bug 11669
+
+symbol_test/none: Fail # bug 11669
+symbol_operator_test/03: Fail # bug 11669
+string_case_test/01: Fail # Bug 18061
+
+iterable_return_type_test/01: RuntimeError # Issue 13646
+iterable_return_type_test/02: RuntimeError # Issue 13646
+
 # #void should be a valid symbol.
-[ ($compiler == none || $compiler == precompiler) || $compiler == dart2js ]
+[ $compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2js ]
 symbol_reserved_word_test/02: CompileTimeError # bug 20191
 symbol_reserved_word_test/05: CompileTimeError # bug 20191
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+# With the exception of 'void', const Symbol() should not accept reserved
+# words.
+symbol_reserved_word_test/04: MissingCompileTimeError # bug 11669, 19972
+symbol_reserved_word_test/07: MissingCompileTimeError # bug 11669, 19972
+symbol_reserved_word_test/10: MissingCompileTimeError # bug 11669, 19972
+
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 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
+symbol_reserved_word_test/07: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
+symbol_reserved_word_test/10: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
+main_test: Fail  # Dartium needs to check for both main() and main(args).
 
 [ $compiler == dart2js ]
 symbol_reserved_word_test/03: RuntimeError # bug 19972, new Symbol('void') should be allowed.
@@ -38,43 +60,10 @@
 int_modulo_arith_test/bignum: RuntimeError # No bigints.
 int_modulo_arith_test/modPow: RuntimeError # No bigints.
 
-
-# With the exception of 'void', const Symbol() should not accept reserved
-# words.
-[ ($compiler == none || $compiler == precompiler) || $compiler == dart2js ]
-symbol_reserved_word_test/04: MissingCompileTimeError # bug 11669, 19972
-symbol_reserved_word_test/07: MissingCompileTimeError # bug 11669, 19972
-symbol_reserved_word_test/10: MissingCompileTimeError # bug 11669, 19972
-
-[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
-symbol_reserved_word_test/04: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
-symbol_reserved_word_test/07: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
-symbol_reserved_word_test/10: Fail # bug 11669, 19972 / dartium/drt cannot detect CompileTimeErrors
-
-# With the exception of 'void', new Symbol() should not accept reserved words.
-[ ($compiler == none || $compiler == precompiler) ]
-symbol_reserved_word_test/06: RuntimeError # bug 11669
-symbol_reserved_word_test/09: RuntimeError # bug 11669
-symbol_reserved_word_test/12: RuntimeError # bug 11669
-
-[ ($compiler == none || $compiler == precompiler) && $runtime != dartium && $runtime != drt && $runtime != ContentShellOnAndroid ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && $runtime != dartium && $runtime != drt ]
 symbol_test/02: MissingCompileTimeError # bug 11669
 symbol_test/03: MissingCompileTimeError # bug 11669
 
-[ ($compiler == none || $compiler == precompiler) ]
-symbol_test/none: Fail # bug 11669
-symbol_operator_test/03: Fail # bug 11669
-string_case_test/01: Fail # Bug 18061
-
-iterable_return_type_test/01: RuntimeError # Issue 13646
-iterable_return_type_test/02: RuntimeError # Issue 13646
-
-[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
-main_test: Fail  # Dartium needs to check for both main() and main(args).
-
-[ ($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
-core_runtime_types_test: Pass, Fail # Issue 20525
-
 [ $runtime == ff || $runtime == jsshell ]
 unicode_test: Fail
 # Firefox takes advantage of the ECMAScript number parsing cop-out clause
@@ -123,7 +112,7 @@
 [ $compiler == dart2js && ($runtime == safari || $runtime == safarimobilesim) ]
 string_split_test: RuntimeError # Issue 21431
 
-[ $compiler == dart2js && (($runtime == safari && $builder_tag == mac10_7) || $runtime == safarimobilesim) ]
+[ $compiler == dart2js && $runtime == safarimobilesim ]
 list_test/01: Fail # Safari bug: Array(-2) seen as dead code.
 string_trimlr_test/none: Fail
 
@@ -169,26 +158,28 @@
 # The regexp tests are not verified to work on non d8/vm platforms yet.
 regexp/*: Skip
 
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 regexp/global_test: Skip # Timeout. Issue 21709 and 21708
 
 [ $runtime != vm && $compiler != dart2analyzer]
-package_resource_test: RuntimeError # Issue 23825 (not implemented yet).
 data_resource_test: RuntimeError # Issue 23825 (not implemented yet).
 file_resource_test: Skip, OK # VM specific test, uses dart:io.
 http_resource_test: Skip, OK # VM specific test, uses dart:io.
 
+[ $runtime != vm && $compiler != dart2analyzer && $cps_ir == false ]
+package_resource_test: RuntimeError # Issue 23825 (not implemented yet).
+
 [ $mode == debug ]
 regexp/pcre_test: Pass, Slow # Timeout. Issue 22008
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $arch == simarmv5te ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $arch == simarmv5te ]
 int_parse_radix_test/*: Pass, Slow
 big_integer_parsed_mul_div_vm_test: Pass, Slow
 
 [ $compiler == dart2js && $cps_ir ]
-data_resource_test: Crash # (await for(var byteSlice in resource.openRead()){streamBytes.addAll(byteSlice);}): await for
-package_resource_test: Crash # (await for(var byteSlice in resource.openRead()){streamBytes.addAll(byteSlice);}): await for
+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.
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 regexp/pcre_test: Crash # Stack Overflow
@@ -199,3 +190,7 @@
 big_integer_huge_mul_vm_test: Pass, Timeout # --no_intrinsify
 big_integer_parsed_mul_div_vm_test: Pass, Timeout # --no_intrinsify
 int_parse_radix_test: Pass, Timeout # --no_intrinsify
+
+[ ($runtime == dart_product) ]
+data_resource_test: Skip # Resolve URI not supported yet in product mode.
+package_resource_test: Skip # Resolve URI not supported yet in product mode.
diff --git a/tests/html/html.status b/tests/html/html.status
index eaf77bd..cf55429 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -20,7 +20,6 @@
 
 blob_constructor_test: RuntimeError # Dartium 45 roll. Issue 25754
 crypto_test/functional: RuntimeError # Dartium 45 roll. Issue 25754
-svgelement_test/constructors: RuntimeError # Dartium 45 roll. Issue 25754
 url_test: RuntimeError # Dartium 45 roll. Issue 25754
 
 [ $compiler == none && ($runtime == drt || $runtime == dartium ) ]
@@ -125,7 +124,7 @@
 transition_event_test/functional: Skip # Times out. Issue 22167
 request_animation_frame_test: Skip # Times out. Issue 22167
 
-[$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid || $runtime == ContentShellOnAndroid ]
+[$runtime == drt || $runtime == dartium || $runtime == chrome || $runtime == chromeOnAndroid ]
 webgl_1_test: Pass, Fail # Issue 8219
 element_animate_test/omit_timing: RuntimeError # Dartium 45 roll. Issue 25786
 element_animate_test/simple_timing: RuntimeError # Dartium 45 roll. Issue 25786
@@ -381,7 +380,7 @@
 
 # 'html' tests import the HTML library, so they only make sense in
 # a browser environment.
-[ $runtime == vm || $runtime == dart_precompiled ]
+[ $runtime == vm || $runtime == dart_precompiled || $runtime == dart_product ]
 *: Skip
 
 [ $compiler == dart2js && ($runtime == drt || $runtime == ff) ]
diff --git a/tests/html/svgelement_test.dart b/tests/html/svgelement_test.dart
index 5527dcd..1fa7259 100644
--- a/tests/html/svgelement_test.dart
+++ b/tests/html/svgelement_test.dart
@@ -70,12 +70,6 @@
   });
 
   // Unfortunately, because the filtering mechanism in unitttest is a regex done
-  group('supported_altGlyph', () {
-    test('supported', () {
-      expect(svg.AltGlyphElement.supported, true);
-    });
-  });
-
   group('supported_animate', () {
     test('supported', () {
       expect(svg.AnimateElement.supported, true);
@@ -277,8 +271,6 @@
       testConstructor('use', (e) => e is svg.UseElement);
       testConstructor('view', (e) => e is svg.ViewElement);
       // TODO(alanknight): Issue 23144
-      testConstructor('altGlyph', (e) => e is svg.AltGlyphElement,
-          svg.AltGlyphElement.supported, false);
       testConstructor('animate', (e) => e is svg.AnimateElement,
           svg.AnimateElement.supported);
       testConstructor('animateMotion', (e) => e is svg.AnimateMotionElement,
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index 7e51060..4149d7d 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -2,17 +2,17 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 browser/*: SkipByDesign  # Browser specific tests
 isolate_stress_test: Fail # Issue 12588: This should be able to pass when we have wrapper-less tests.
 
 [ $runtime != vm ]
 checked_test: Skip # Unsupported.
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $mode == debug ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $arch == mips && $mode == debug ]
 mandel_isolate_test: Skip # Uses 600 MB Ram on our 1 GB test device.
 
-[ ($compiler == none || $compiler == precompiler) ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) ]
 compile_time_error_test/01: Skip # Issue 12587
 ping_test: Skip           # Resolve test issues
 ping_pause_test: Skip     # Resolve test issues
@@ -20,9 +20,6 @@
 
 message3_test/int32x4: Crash, Timeout # Issue 21818
 
-[ ($compiler == none) && $runtime == ContentShellOnAndroid ]
-*: Skip # Isolate tests are timing out flakily on Android content_shell.  Issue 19795
-
 [ $compiler == dart2js && $runtime == safarimobilesim ]
 compile_time_error_test/none: Pass, Slow
 
@@ -78,22 +75,14 @@
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 unresolved_ports_test: Pass, Timeout # Issue 15610
 
-[ ($compiler == none) && $runtime == drt ]
-spawn_uri_nested_vm_test: Skip # Issue 14463
-
 [ $jscl ]
 spawn_uri_multi_test/none: RuntimeError # Issue 13544
 
-[ ($compiler == none) && $runtime == ContentShellOnAndroid ]
-nested_spawn2_test: Skip # Issue 19127: This test is timing out.
-
-[ ($compiler == none) && ($runtime == dartium || $runtime == ContentShellOnAndroid) ]
-spawn_uri_nested_vm_test: Skip # Issue 14479: This test is timing out.
-
 [ ($compiler == none) && $runtime == dartium && $arch == x64 ]
 isolate/spawn_uri_multi_test/01: Skip # Times out. Issue 24795
 
-[ ($compiler == none) && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none) && ( $runtime == dartium || $runtime == drt) ]
+spawn_uri_nested_vm_test: Skip # Issue 14479: This test is timing out. Issue 14463
 typed_message_test: Skip # Issue 13921, 14400
 isolate_stress_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
 object_leak_test: Skip # Issue 13921 Dom isolates don't support spawnFunction
@@ -172,7 +161,7 @@
 static_function_test: CompileTimeError
 unresolved_ports_test: CompileTimeError
 
-[ $runtime == dart_precompiled ]
+[ $runtime == dart_precompiled || $runtime == dart_product ]
 deferred_in_isolate_test: Skip # Isolate.spawnUri
 deferred_in_isolate2_test: Skip # Isolate.spawnUri
 exit_at_spawnuri_test: Skip # Isolate.spawnUri
@@ -187,3 +176,7 @@
 spawn_uri_vm_test: Skip # Isolate.spawnUri
 issue_21398_parent_isolate_test: Skip # Isolate.spawnUri
 error_at_spawnuri_test: Skip # Isolate.spawnUri
+
+[ $runtime == dart_product ]
+spawn_uri_missing_from_isolate_test: Skip # SpawnUri in product mode
+spawn_uri_missing_test: Skip # SpawnUri in product mode
diff --git a/tests/language/language.status b/tests/language/language.status
index 2d38d62..b2409a5 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -5,7 +5,7 @@
 # This directory contains tests that are intended to show the
 # current state of the language.
 
-[ ($compiler == none || $compiler == precompiler) ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) ]
 tearoff_constructor_basic_test: Skip # Crashes in checked mode -- hausner investigating
 
 # These tests are skipped in the VM because it has "--supermixin"
@@ -26,6 +26,9 @@
 constructor3_test: Fail, OK
 constructor2_test: Fail, OK
 
+dynamic_prefix_core_test/01: RuntimeError # Issue 12478
+multiline_strings_test: Fail # Issue 23020
+
 # Regular bugs which should be fixed.
 duplicate_export_negative_test: Fail # Issue 6134
 
@@ -49,7 +52,7 @@
 accessor_conflict_import_prefixed2_test: RuntimeError # Issue 25625
 accessor_conflict_import_prefixed_test: RuntimeError # Issue 25625
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 unicode_bom_test: Fail # Issue 16067
@@ -59,15 +62,11 @@
 [ ($compiler == none || $compiler == precompiler) && $checked ]
 type_variable_bounds4_test/01: Fail # Issue 14006
 
-[ ($compiler == none || $compiler == precompiler) ]
-dynamic_prefix_core_test/01: RuntimeError # Issue 12478
-multiline_strings_test: Fail # Issue 23020
-
-[ ($compiler == none || $compiler == precompiler) && (($runtime == vm || $runtime == dart_precompiled) || $runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && (($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) || $runtime == drt || $runtime == dartium) ]
 dynamic_prefix_core_test/none: Fail # Issue 12478
 export_ambiguous_main_negative_test: Fail # Issue 14763
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $unchecked ]
+[ $compiler == none && $runtime == dartium && $unchecked ]
 assertion_test: Fail # Issue 14651.
 generic_test: Fail # Issue 14651.
 list_literal4_test: Fail # Issue 14651.
@@ -80,7 +79,7 @@
 type_checks_in_factory_method_test: Fail # Issue 14651.
 vm/type_vm_test: Fail # Issue 14651.
 
-[ ($compiler == none || $compiler == precompiler) && ( $runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) ]
+[ $compiler == none && ($runtime == dartium || $runtime == drt) ]
 issue13474_test: Pass, Fail # Issue 14651.
 config_import_test: Fail # Issue 14651.
 vm/optimized_guarded_field_isolates_test: RuntimeError, OK  # Uses Isolate.spawn.
@@ -93,39 +92,37 @@
 mirror_in_static_init_test: Fail # Issue 22071
 vm/debug_break_enabled_vm_test/*: Skip # Issue 14651.
 
-[ ($compiler == none || $compiler == precompiler) && $runtime == dartium && $system == linux && $arch != x64 ]
+[ $compiler == none && $runtime == dartium && $system == linux && $arch != x64 ]
 issue_22780_test/01 : Pass, Timeout # Issue 24473
 
-[ ($compiler == none || $compiler == precompiler) && $runtime == drt ]
+[ $compiler == none && $runtime == drt ]
 disassemble_test: Pass, Fail # Issue 18122
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $checked ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $arch == mips && $checked ]
 generic_instanceof3_test: Pass, Crash # Issue 17440.
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && $arch == mips && $mode == debug ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $arch == mips && $mode == debug ]
 stack_overflow_test: Skip # Crashes. Issue 17440.
 stack_overflow_stacktrace_test: Skip # Crashes. Issue 17440.
 large_class_declaration_test: SkipSlow # Times out. Issue 20352
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == drt || $runtime == ContentShellOnAndroid) && $mode == debug ]
+[ $compiler == none && ($runtime == dartium || $runtime == drt) && $mode == debug ]
 large_class_declaration_test: SkipSlow # Times out. Issue 20352
 
-[ ($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
-gc_test: SkipSlow # Times out flakily. Issue 20956
-
-[ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) && ( $arch == simarm || $arch == arm || $arch == simarmv6 || $arch == armv6 || $arch == simarmv5te || $arch == armv5te || $arch == simarm64 || $arch == arm64 || $arch == simmips || $arch == mips) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && ( $arch == simarm || $arch == arm || $arch == simarmv6 || $arch == armv6 || $arch == simarmv5te || $arch == armv5te || $arch == simarm64 || $arch == arm64 || $arch == simmips || $arch == mips) ]
 vm/load_to_load_unaligned_forwarding_vm_test: Pass, Crash # Unaligned offset. Issue 22151
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == drt) ]
+[ $compiler == none && ($runtime == dartium || $runtime == drt) ]
 issue23244_test: Fail # Issue 23244
 
-[ ($compiler == none || $compiler == precompiler) && (($runtime == vm || $runtime == dart_precompiled) || $runtime == drt || $runtime == dartium) && $arch == ia32 ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && (($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) || $runtime == drt || $runtime == dartium) && $arch == ia32 ]
 vm/regress_24517_test: Pass, Fail # Issue 24517.
 
 [ ($noopt || $compiler == precompiler) ]
 # Imports dart:mirrors
 const_evaluation_test: CompileTimeError
-deferred_constraints_constants_test: CompileTimeError
+deferred_constraints_constants_test/none: CompileTimeError
+deferred_constraints_constants_test/reference_after_load: CompileTimeError
 enum_mirror_test: CompileTimeError
 field_increment_bailout_test: CompileTimeError
 instance_creation_in_function_annotation_test: CompileTimeError
@@ -137,28 +134,40 @@
 no_such_method_test: CompileTimeError
 null_test/none: CompileTimeError
 overridden_no_such_method_test: CompileTimeError
+redirecting_factory_reflection_test: CompileTimeError
 regress_13462_0_test: CompileTimeError
 regress_13462_1_test: CompileTimeError
 regress_18535_test: CompileTimeError
 super_call4_test: CompileTimeError
 super_getter_setter_test: CompileTimeError
 vm/reflect_core_vm_test: CompileTimeError
-redirecting_factory_reflection_test: CompileTimeError
-deferred_constraints_constants_test: Skip # multitest gets confused
-vm/type_vm_test: RuntimeError # Expects line and column numbers
 
+deferred_global_test: RuntimeError # Issue 25845
+
+[ ($noopt || $compiler == precompiler || $compiler == dart2app) ]
 # Deferred loading happens eagerly
 regress_23408_test: RuntimeError
-deferred_global_test: RuntimeError
 deferred_inheritance_constraints_test: Skip
 deferred_load_constants_test: Skip # multitest gets confused
-
-deopt_inlined_function_lazy_test: Pass, Crash # Incompatible flag: --deoptimize-alot
 tearoff_basic_test: RuntimeError, Crash # Conflicting flag.
+
+vm/type_vm_test: RuntimeError # Expects line and column numbers
 vm/type_cast_vm_test: RuntimeError # Line number mismatch.
 
 [ $runtime == dart_precompiled ]
+deferred_global_test: RuntimeError # Tries to produce a stack trace.
 ct_const2_test: Pass, Crash # Incompatible flag --compile_all
 hello_dart_test: Pass, Crash # Incompatible flag --compile_all
 
 implicit_closure_test: Pass, Crash # --use_slow_path
+
+deopt_inlined_function_lazy_test: Pass, Crash # Incompatible flag: --deoptimize-alot
+
+[ $runtime == dart_product ]
+# Deferred loading happens eagerly (not sure why this works on precompiled code).
+deferred_static_seperate_test: Skip
+deferred_constraints_type_annotation_test/new_before_load: Skip
+regress_22443_test: Skip
+
+[ $runtime == vm && $mode == product ]
+vm/type_vm_test: Fail,OK  # Expects exact type name.
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 5f20fea..5e0c4af 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -13,9 +13,6 @@
 enum_syntax_test/05: Fail # 21649
 enum_syntax_test/06: Fail # 21649
 
-mixin_illegal_constructor_test/20: MissingCompileTimeError # 25588
-mixin_illegal_constructor_test/21: MissingCompileTimeError # 25588
-
 tearoff_basic_test: Skip # Tear-off not supported
 tearoff_constructor_basic_test: Skip # Tear-off not supported
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 060a61d..90527a4 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -14,9 +14,6 @@
 try_catch_on_syntax_test/10: Fail # Issue 19823
 try_catch_on_syntax_test/11: Fail # Issue 19823
 
-mixin_illegal_constructor_test/20: MissingCompileTimeError # 25587
-mixin_illegal_constructor_test/21: MissingCompileTimeError # 25587
-
 deep_nesting1_negative_test: Crash # Issue 25557
 deep_nesting2_negative_test: Crash # Issue 25557
 
diff --git a/tests/language/mixin_illegal_constructor_test.dart b/tests/language/mixin_illegal_constructor_test.dart
index 8884084..d0a59fb 100644
--- a/tests/language/mixin_illegal_constructor_test.dart
+++ b/tests/language/mixin_illegal_constructor_test.dart
@@ -15,7 +15,7 @@
   M2.named();
 }
 
-class C0 = Object with M0;      /// 20: compile-time error
+class C0 = Object with M0;
 class C1 = Object with M1;      /// 01: compile-time error
 class C2 = Object with M2;      /// 02: compile-time error
 class C3 = Object with M0, M1;  /// 03: compile-time error
@@ -23,7 +23,7 @@
 class C5 = Object with M0, M2;  /// 05: compile-time error
 class C6 = Object with M2, M0;  /// 06: compile-time error
 
-class D0 extends Object with M0 { }      /// 21: compile-time error
+class D0 extends Object with M0 { }
 class D1 extends Object with M1 { }      /// 07: compile-time error
 class D2 extends Object with M2 { }      /// 08: compile-time error
 class D3 extends Object with M0, M1 { }  /// 09: compile-time error
@@ -32,7 +32,7 @@
 class D6 extends Object with M2, M0 { }  /// 12: compile-time error
 
 main() {
-  new C0();  /// 20: continued
+  new C0();
   new C1();  /// 01: continued
   new C2();  /// 02: continued
   new C3();  /// 03: continued
@@ -40,11 +40,16 @@
   new C5();  /// 05: continued
   new C6();  /// 06: continued
 
-  new D0();  /// 21: continued
+  new D0();
   new D1();  /// 07: continued
   new D2();  /// 08: continued
   new D3();  /// 09: continued
   new D4();  /// 10: continued
   new D5();  /// 11: continued
   new D6();  /// 12: continued
+
+  new C0(1,2,3);   /// 13: static type warning, runtime error
+  new C0.named();  /// 14: static type warning, runtime error
+  new D0(1,2,3);   /// 15: static type warning, runtime error
+  new D0.named();  /// 16: static type warning, runtime error
 }
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 3bd73ed..4a43727 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -185,7 +185,7 @@
 
 # 'js' tests import the dart:js library, so they only make sense in
 # a browser environment.
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 js/*: Skip
 
 # 'js' tests import the dart:js library, so they only make sense in
@@ -208,7 +208,7 @@
 async/slow_consumer_test: Pass, Timeout # Issue 22696
 async/catch_errors11_test: Pass, Timeout # Issue 22696
 
-[ $runtime == chrome || $runtime == ff || $runtime == ContentShellOnAndroid ]
+[ $runtime == chrome || $runtime == ff ]
 convert/streamed_conversion_utf8_encode_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_utf8_decode_test: SkipSlow # Times out. Issue 22050
 convert/streamed_conversion_json_utf8_encode_test: SkipSlow # Times out. Issue 22050
@@ -228,19 +228,19 @@
 # TODO(efortuna): Investigate.
 async/timer_test: Fail, Pass
 
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 async/timer_not_available_test: Fail, OK
 mirrors/native_class_test: Fail, OK # This test is meant to run in a browser.
 mirrors/deferred_type_test: CompileTimeError, OK # Don't have a multitest marker for dynamic compile time errors.
 
-[ ($compiler == none || $compiler == precompiler) ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) ]
 async/timer_not_available_test: SkipByDesign # only meant to test when there is no way to implement timer (currently only in d8)
 
 mirrors/symbol_validation_test: RuntimeError # Issue 13596
 
 mirrors/mirrors_used*: SkipByDesign # Invalid tests. MirrorsUsed does not have a specification, and dart:mirrors is not required to hide declarations that are not covered by any MirrorsUsed annotation.
 
-[ ($compiler == none || $compiler == precompiler) && ( $runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 async/schedule_microtask6_test: Fail # Issue 10910
 async/timer_test: Fail, Pass # Issue 15487
 async/multiple_timer_test: Fail, Pass # Issue 15487
@@ -253,22 +253,13 @@
 mirrors/local_isolate_test: RuntimeError # Issue 12188
 mirrors/deferred_type_test: RuntimeError, OK # Should be CompileTimeError. Issue 22072
 
-[ ($compiler == none || $compiler == precompiler) && $runtime == drt && $system == windows ]
+[ $compiler == none && $runtime == drt && $system == windows ]
 async/multiple_timer_test: Fail, Pass # See Issue 10982
 async/timer_test: Fail, Pass # See Issue 10982
 
-[ ($compiler == none || $compiler == precompiler) && $runtime == drt && $checked ]
+[ $compiler == none && $runtime == drt && $checked ]
 async/slow_consumer_test: Fail, Pass # Dartium JsInterop failure, dartbug.com/24460
 
-[($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
-async/stream_timeout_test: RuntimeError, Pass # Issue 19127
-async/slow_consumer3_test: SkipSlow # Times out flakily. Issue 20956
-async/slow_consumer2_test: SkipSlow # Times out flakily. Issue 20956
-convert/streamed_conversion_utf8_encode_test: SkipSlow # Times out or passes. Issue 19127
-convert/streamed_conversion_utf8_decode_test: SkipSlow # Times out or passes. Issue 19127
-mirrors/lazy_static_test: SkipSlow # Times out. Issue 19127
-mirrors/mirrors_reader_test: SkipSlow # Times out. Issue 19127
-
 [ $compiler == dart2js && $runtime == safarimobilesim ]
 mirrors/mirrors_reader_test: SkipSlow # Times out. Issue 20806.
 
@@ -307,7 +298,7 @@
 [ $compiler == dart2js && $mode == debug ]
 mirrors/native_class_test: Pass, Slow
 
-[ ($compiler == none || $compiler == precompiler) && $arch == mips ]
+[ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && $arch == mips ]
 async/timer_regress22626_test: Pass, RuntimeError # Issue 22626
 
 [ $arch == simarm || $arch == simarmv6 || $arch == simarmv5te ]
@@ -327,16 +318,16 @@
 [ $mode == debug && $arch == ia32 && $system == windows ]
 convert/streamed_conversion_json_utf8_decode_test: Skip  # Verification OOM.
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $arch == x64 && $system == windows ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $mode == debug && $arch == x64 && $system == windows ]
 convert/streamed_conversion_json_utf8_decode_test: Pass, Slow
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $mode == release && $arch == ia32 && $system == windows ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $mode == release && $arch == ia32 && $system == windows ]
 convert/json_test: RuntimeError # Issue 24908
 
 [ $mode == debug && $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv6 && $arch != simarmv5te ]
 convert/streamed_conversion_json_utf8_decode_test: Skip  # Verification not yet implemented.
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $mode == debug && $builder_tag == asan ]
 mirrors/immutable_collections_test: SkipSlow  # Timeout.
 convert/streamed_conversion_json_utf8_decode_test: Skip  # Timeout.
 
@@ -361,3 +352,7 @@
 mirrors/*: SkipByDesign
 convert/chunked_conversion_utf88_test: Pass, Timeout
 convert/utf85_test: Pass, Timeout
+
+[ $runtime == vm && $mode == product ]
+mirrors/mirrors_reader_test: Fail,OK  # Expects exact type name.
+
diff --git a/tests/standalone/io/certificates/README b/tests/standalone/io/certificates/README
index 1268432..6ecd518 100644
--- a/tests/standalone/io/certificates/README
+++ b/tests/standalone/io/certificates/README
@@ -8,6 +8,8 @@
 in a bash or sh shell, with the openssl tools installed.  Run the script
 twice to create the untrusted_* files.
 
+PEM files:
+
 server_chain.pem:
   Contains the chain of certificates, from the self-signed
 test certificate authority, through the intermediate CA, to the server
@@ -29,6 +31,40 @@
 to fail because the client does not accept this certificate authority
 
 untrusted_server_key.pem:
-  Contains the private key for the untrusted server certificate 
+  Contains the private key for the untrusted server certificate
 in untrusted_server_chain.pem
 
+*_malformed.pem:
+  Truncated PEM formatted certificates used to test error handling.
+
+PKCS12 files:
+
+server_key.12:
+  Created with:
+  $ openssl pkcs12 -export -inkey server_key.pem -out server_key.p12 -nocerts
+  with password 'dartdart'
+
+server_chain.p12:
+  Created with:
+  $ openssl pkcs12 -export -in server_chain.pem -out server_chain.p12 -nokeys
+  with password 'dartdart'
+
+client1_key.p12:
+  Created with:
+  $ openssl pkcs12 -export -inkey client1_key.pem -out client1_key.p12 -nocerts
+  with password 'dartdart'
+
+client1.p12:
+  Created with:
+  $ openssl pkcs12 -export -in client1.pem -out client1.p12 -nokeys
+  with password 'dartdart'
+
+trusted_certs.p12:
+  Created with:
+  $ openssl pkcs12 -export -in trusted_certs.pem -out trusted_certs.p12 -nokeys
+  with password 'dartdart'
+
+client_authority.p12:
+  Created with:
+  $ openssl pkcs12 -export -in client_authority.pem -out client_authority.p12 -nokeys
+  with password 'dartdart'
diff --git a/tests/standalone/io/certificates/client1.p12 b/tests/standalone/io/certificates/client1.p12
index 0b51218..8d19d04 100644
--- a/tests/standalone/io/certificates/client1.p12
+++ b/tests/standalone/io/certificates/client1.p12
Binary files differ
diff --git a/tests/standalone/io/certificates/client1_key.p12 b/tests/standalone/io/certificates/client1_key.p12
index a65c398..d9cf05b 100644
--- a/tests/standalone/io/certificates/client1_key.p12
+++ b/tests/standalone/io/certificates/client1_key.p12
Binary files differ
diff --git a/tests/standalone/io/certificates/client_authority.p12 b/tests/standalone/io/certificates/client_authority.p12
index a873b2a..545282e 100644
--- a/tests/standalone/io/certificates/client_authority.p12
+++ b/tests/standalone/io/certificates/client_authority.p12
Binary files differ
diff --git a/tests/standalone/io/certificates/server_chain.p12 b/tests/standalone/io/certificates/server_chain.p12
index c9416eb..1e8c66d 100644
--- a/tests/standalone/io/certificates/server_chain.p12
+++ b/tests/standalone/io/certificates/server_chain.p12
Binary files differ
diff --git a/tests/standalone/io/certificates/server_key.p12 b/tests/standalone/io/certificates/server_key.p12
index 8b59c9b..2434fb7 100644
--- a/tests/standalone/io/certificates/server_key.p12
+++ b/tests/standalone/io/certificates/server_key.p12
Binary files differ
diff --git a/tests/standalone/io/certificates/trusted_certs.p12 b/tests/standalone/io/certificates/trusted_certs.p12
index 71ffe1b..167f2e8 100644
--- a/tests/standalone/io/certificates/trusted_certs.p12
+++ b/tests/standalone/io/certificates/trusted_certs.p12
Binary files differ
diff --git a/tests/standalone/io/secure_server_client_certificate_test.dart b/tests/standalone/io/secure_server_client_certificate_test.dart
index 97bbc4f..e1cf015 100644
--- a/tests/standalone/io/secure_server_client_certificate_test.dart
+++ b/tests/standalone/io/secure_server_client_certificate_test.dart
@@ -12,32 +12,40 @@
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
 
-SecurityContext serverContext(String certType) => new SecurityContext()
-  ..useCertificateChainSync(localFile('certificates/server_chain.$certType'))
-  ..usePrivateKeySync(localFile('certificates/server_key.$certType'),
-                      password: 'dartdart')
+SecurityContext serverContext(String certType, String password) =>
+  new SecurityContext()
+  ..useCertificateChainSync(
+      localFile('certificates/server_chain.$certType'), password: password)
+  ..usePrivateKeySync(
+      localFile('certificates/server_key.$certType'), password: password)
   ..setTrustedCertificatesSync(localFile(
-      'certificates/client_authority.$certType'))
+      'certificates/client_authority.$certType'), password: password)
   ..setClientAuthoritiesSync(localFile(
-      'certificates/client_authority.$certType'));
+      'certificates/client_authority.$certType'), password: password);
 
-SecurityContext clientCertContext(String certType) => new SecurityContext()
-  ..setTrustedCertificatesSync(localFile(
-      'certificates/trusted_certs.$certType'))
-  ..useCertificateChainSync(localFile('certificates/client1.$certType'))
-  ..usePrivateKeySync(localFile('certificates/client1_key.$certType'),
-                                password: 'dartdart');
+SecurityContext clientCertContext(String certType, String password) =>
+  new SecurityContext()
+  ..setTrustedCertificatesSync(
+      localFile('certificates/trusted_certs.$certType'), password: password)
+  ..useCertificateChainSync(
+      localFile('certificates/client1.$certType'), password: password)
+  ..usePrivateKeySync(
+      localFile('certificates/client1_key.$certType'), password: password);
 
-SecurityContext clientNoCertContext(String certType) => new SecurityContext()
+SecurityContext clientNoCertContext(String certType, String password) =>
+  new SecurityContext()
   ..setTrustedCertificatesSync(localFile(
-      'certificates/trusted_certs.$certType'));
+      'certificates/trusted_certs.$certType'), password: password);
 
 Future testClientCertificate(
-    {bool required, bool sendCert, String certType}) async {
-  var server = await SecureServerSocket.bind(HOST, 0, serverContext(certType),
-      requestClientCertificate: true, requireClientCertificate: required);
-  var clientContext =
-      sendCert ? clientCertContext(certType) : clientNoCertContext(certType);
+    {bool required, bool sendCert, String certType, String password}) async {
+  var server = await SecureServerSocket.bind(HOST, 0,
+      serverContext(certType, password),
+      requestClientCertificate: true,
+      requireClientCertificate: required);
+  var clientContext = sendCert ?
+      clientCertContext(certType, password) :
+      clientNoCertContext(certType, password);
   var clientEndFuture =
       SecureSocket.connect(HOST, server.port, context: clientContext);
   if (required && !sendCert) {
@@ -74,16 +82,22 @@
 main() async {
   asyncStart();
   HOST = (await InternetAddress.lookup("localhost")).first;
-  await testClientCertificate(required: false, sendCert: true, certType: 'pem');
-  await testClientCertificate(required: true, sendCert: true, certType: 'pem');
   await testClientCertificate(
-      required: false, sendCert: false, certType: 'pem');
-  await testClientCertificate(required: true, sendCert: false, certType: 'pem');
+      required: false, sendCert: true, certType: 'pem', password: 'dartdart');
+  await testClientCertificate(
+      required: true, sendCert: true, certType: 'pem', password: 'dartdart');
+  await testClientCertificate(
+      required: false, sendCert: false, certType: 'pem', password: 'dartdart');
+  await testClientCertificate(
+      required: true, sendCert: false, certType: 'pem', password: 'dartdart');
 
-  await testClientCertificate(required: false, sendCert: true, certType: 'p12');
-  await testClientCertificate(required: true, sendCert: true, certType: 'p12');
   await testClientCertificate(
-      required: false, sendCert: false, certType: 'p12');
-  await testClientCertificate(required: true, sendCert: false, certType: 'p12');
+      required: false, sendCert: true, certType: 'p12', password: 'dartdart');
+  await testClientCertificate(
+      required: true, sendCert: true, certType: 'p12', password: 'dartdart');
+  await testClientCertificate(
+      required: false, sendCert: false, certType: 'p12', password: 'dartdart');
+  await testClientCertificate(
+      required: true, sendCert: false, certType: 'p12', password: 'dartdart');
   asyncEnd();
 }
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index dbd7271..c24fc5f 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -15,20 +15,23 @@
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
 
-SecurityContext serverContext(String certType) => new SecurityContext()
-  ..useCertificateChainSync(localFile('certificates/server_chain.$certType'))
-  ..usePrivateKeySync(localFile('certificates/server_key.$certType'),
-                      password: 'dartdart');
+SecurityContext serverContext(String certType, String password) =>
+    new SecurityContext()
+    ..useCertificateChainSync(localFile('certificates/server_chain.$certType'),
+                              password: password)
+    ..usePrivateKeySync(localFile('certificates/server_key.$certType'),
+                        password: password);
 
-SecurityContext clientContext(String certType) => new SecurityContext()
-  ..setTrustedCertificatesSync(localFile(
-      'certificates/trusted_certs.$certType'));
+SecurityContext clientContext(String certType, String password) =>
+    new SecurityContext()
+    ..setTrustedCertificatesSync(localFile(
+        'certificates/trusted_certs.$certType'), password: password);
 
-Future<HttpServer> startServer(String certType) {
+Future<HttpServer> startServer(String certType, String password) {
   return HttpServer.bindSecure(
       "localhost",
       0,
-      serverContext(certType),
+      serverContext(certType, password),
       backlog: 5).then((server) {
     server.listen((HttpRequest request) {
       request.listen(
@@ -45,11 +48,11 @@
   });
 }
 
-Future test(String certType) {
+Future test(String certType, String password) {
   List<int> body = <int>[];
-  startServer(certType).then((server) {
+  startServer(certType, password).then((server) {
     SecureSocket.connect(
-        "localhost", server.port, context: clientContext(certType))
+        "localhost", server.port, context: clientContext(certType, password))
     .then((socket) {
       socket.write("GET / HTTP/1.0\r\nHost: localhost\r\n\r\n");
       socket.close();
@@ -74,7 +77,7 @@
 
 main() async {
   asyncStart();
-  await test('pem');
-  await test('p12');
+  await test('pem', 'dartdart');
+  await test('p12', 'dartdart');
   asyncEnd();
 }
diff --git a/tests/standalone/io/security_context_argument_test.dart b/tests/standalone/io/security_context_argument_test.dart
index 91de8dc..6d5e1e2 100644
--- a/tests/standalone/io/security_context_argument_test.dart
+++ b/tests/standalone/io/security_context_argument_test.dart
@@ -16,9 +16,8 @@
 void testUsePrivateKeyArguments() {
     var c = new SecurityContext();
     c.useCertificateChainSync(localFile('certificates/server_chain.pem'));
-    Expect.throws(() => c.usePrivateKeySync(
-        localFile('certificates/server_key.pem'), password: "dart" * 1000),
-        argumentError);
+
+    // Wrong password.
     Expect.throws(() => c.usePrivateKeySync(
         localFile('certificates/server_key.pem')),
         tlsException);
@@ -26,12 +25,70 @@
           localFile('certificates/server_key.pem'), password: "iHackSites"),
         tlsException);
     Expect.throws(() => c.usePrivateKeySync(
+        localFile('certificates/server_key.p12')),
+        tlsException);
+    Expect.throws(() => c.usePrivateKeySync(
+          localFile('certificates/server_key.p12'), password: "iHackSites"),
+        tlsException);
+    Expect.throws(() => c.setTrustedCertificatesSync(
+        localFile('certificates/server_key.p12')),
+        tlsException);
+    Expect.throws(() => c.setTrustedCertificatesSync(
+          localFile('certificates/server_key.p12'), password: "iHackSites"),
+        tlsException);
+    Expect.throws(() => c.useCertificateChainSync(
+        localFile('certificates/server_key.p12')),
+        tlsException);
+    Expect.throws(() => c.useCertificateChainSync(
+          localFile('certificates/server_key.p12'), password: "iHackSites"),
+        tlsException);
+    Expect.throws(() => c.setClientAuthoritiesSync(
+        localFile('certificates/server_key.p12')),
+        argumentError);
+    Expect.throws(() => c.setClientAuthoritiesSync(
+          localFile('certificates/server_key.p12'), password: "iHackSites"),
+        argumentError);
+
+    // File does not exist
+    Expect.throws(() => c.usePrivateKeySync(
         localFile('certificates/server_key_oops.pem'),
                   password: "dartdart"),
         fileSystemException);
+
+    // Wrong type for file name or data
     Expect.throws(() => c.usePrivateKeySync(1), argumentOrTypeError);
     Expect.throws(() => c.usePrivateKeySync(null), argumentError);
+    Expect.throws(() => c.usePrivateKeyBytes(1), argumentOrTypeError);
+    Expect.throws(() => c.usePrivateKeyBytes(null), argumentError);
+
+    // Too-long passwords.
     Expect.throws(() => c.usePrivateKeySync(
+        localFile('certificates/server_key.pem'), password: "dart" * 1000),
+        argumentError);
+    Expect.throws(() => c.usePrivateKeySync(
+        localFile('certificates/server_key.p12'), password: "dart" * 1000),
+        argumentOrTypeError);
+    Expect.throws(() => c.setTrustedCertificatesSync(
+        localFile('certificates/server_key.p12'), password: "dart" * 1000),
+        argumentOrTypeError);
+    Expect.throws(() => c.useCertificateChainSync(
+        localFile('certificates/server_key.p12'), password: "dart" * 1000),
+        argumentOrTypeError);
+    Expect.throws(() => c.setClientAuthoritiesSync(
+        localFile('certificates/server_key.p12'), password: "dart" * 1000),
+        argumentOrTypeError);
+
+    // Bad password type.
+    Expect.throws(() => c.usePrivateKeySync(
+        localFile('certificates/server_key.pem'), password: 3),
+        argumentOrTypeError);
+    Expect.throws(() => c.setTrustedCertificatesBytes(
+        localFile('certificates/server_key.pem'), password: 3),
+        argumentOrTypeError);
+    Expect.throws(() => c.useCertificateChainBytes(
+        localFile('certificates/server_key.pem'), password: 3),
+        argumentOrTypeError);
+    Expect.throws(() => c.setClientAuthoritiesBytes(
         localFile('certificates/server_key.pem'), password: 3),
         argumentOrTypeError);
 
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 43cd0bc..6b9e9e9 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -18,15 +18,15 @@
 
 issue14236_test: Pass # Do not remove this line. It serves as a marker for Issue 14516 comment #4.
 
-[ ($runtime != vm && $runtime != dart_precompiled) && ($runtime != drt || $compiler != none)) ]
+[ ($runtime != vm && $runtime != dart_precompiled && $runtime != dart_product) && ($runtime != drt || $compiler != none)) ]
 no_assert_test: Fail, OK # This is testing a vm flag.
 
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 package/package_isolate_test: Fail # Issue 12474
 io/observatory_test: Fail
 package/scenarios/invalid/same_package_twice_test: Pass # Issue 24119
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $checked ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $checked ]
 # These tests have type errors on purpose.
 io/process_invalid_arguments_test: Fail, OK
 io/directory_invalid_arguments_test: Fail, OK
@@ -39,7 +39,7 @@
 io/file_fuzz_test: Skip
 io/directory_fuzz_test: Skip
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $system == macos ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $system == macos ]
 # This test fails with "Too many open files" on the Mac OS buildbot.
 # This is expected as MacOS by default runs with a very low number
 # of allowed open files ('ulimit -n' says something like 256).
@@ -53,7 +53,7 @@
 io/secure_builtin_roots_test: Skip
 
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
+[ $compiler == none && ($runtime == drt || $runtime == dartium) ]
 typed_array_test: RuntimeError, OK  # Uses Isolate.spawn
 typed_array_int64_uint64_test: RuntimeError, OK  # Uses Isolate.spawn
 typed_data_isolate_test: SkipByDesign # This test uses dart:io
@@ -111,19 +111,19 @@
 noopt_test: Skip # Standalone only test.
 regress_25335_test: Skip # Int64List not supported.
 
-[ $runtime == vm && $mode == debug ]
+[ ($runtime == vm || $runtime == dart_product) && $mode == debug ]
 precompilation_dart2js_test: Pass, Slow
 
-[ $runtime == vm && $arch == ia32 ]
+[ ($runtime == vm || $runtime == dart_product) && $arch == ia32 ]
 precompilation_test: Skip # Not expected to pass on ia32.
 precompilation_dart2js_test: Skip # Not expected to pass on ia32.
 noopt_test: Skip # Not expected to pass on ia32.
 
-[ $runtime == vm && $arch == arm ]
+[ ($runtime == vm || $runtime == dart_product) && $arch == arm ]
 precompilation_test: Skip # Issue 24427
 precompilation_dart2js_test: Skip # Issue 24427
 
-[ $runtime == vm && $arch == mips ]
+[ ($runtime == vm || $runtime == dart_product) && $arch == mips ]
 precompilation_dart2js_test: SkipSlow
 
 [ $compiler == dart2js && $jscl ]
@@ -158,7 +158,7 @@
 full_coverage_test: SkipSlow # Times out. Issue 20352
 io/http_client_stays_alive_test: Skip # Timing dependent test, MIPS machine too slow.
 
-[ ($compiler == none || $compiler == precompiler) && ($runtime == dartium || $runtime == ContentShellOnAndroid) && $unchecked ]
+[ $compiler == none && $runtime == dartium && $unchecked ]
 assert_test: Fail # Issue 14651.
 
 [ $compiler == none && $runtime == drt ]
@@ -201,13 +201,13 @@
 [ $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv5te && $mode == debug ]
 verified_mem_test: Skip  # Not yet implemented.
 
-[ ($runtime == vm || $runtime == dart_precompiled) && $mode == debug && $builder_tag == asan ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $mode == debug && $builder_tag == asan ]
 full_coverage_test: Skip  # Timeout.
 io/file_lock_test: Skip  # Timeout.
 io/test_runner_test: Skip  # Timeout.
 io/http_client_stays_alive_test: Skip  # Timeout.
 
-[ ($runtime == vm || $runtime == dart_precompiled) ]
+[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 # Failures in secure networking while NSS is replaced with BoringSSL
 io/https_client_certificate_test: RuntimeError # Issue 24070
 io/secure_socket_renegotiate_test: RuntimeError
@@ -230,47 +230,52 @@
 full_coverage_test: Skip # Platform.executable
 
 [ $runtime == dart_precompiled ]
+io/compile_all_test: Crash # Incompatible flag --compile_all
+
+[ $runtime == dart_product ]
+io/stdout_bad_argument_test: Skip # Test exits and so can't generate snapshot.
+
+[ $runtime == dart_precompiled || $runtime == dart_product ]
 debugger/*: Skip
 noopt_test: Skip
+precompilation_test: Skip # Platform.executable
 precompilation_dart2js_test: Skip # Platform.executable
-
-full_coverage_test: RuntimeError # Platform.executable
-http_launch_test: RuntimeError # Platform.executable
-io/addlatexhash_test: RuntimeError # Platform.executable
-io/compile_all_test: Crash # Incompatible flag --compile_all
-io/file_read_special_device_test: RuntimeError # Platform.executable
-io/file_stream_test: RuntimeError # Platform.executable
-io/file_test: RuntimeError # Platform.executable
-io/http_cross_process_test: RuntimeError # Platform.executable
-io/https_unauthorized_test: RuntimeError # Platform.executable
-io/platform_resolved_executable_test: RuntimeError # Platform.resolvedExecutable
-io/skipping_dart2js_compilations_test: RuntimeError # Platform.executable
-io/snapshot_fail_test: RuntimeError # Platform.executable
-io/stdin_sync_test: RuntimeError # Platform.executable
-io/test_extension_fail_test: RuntimeError # Platform.executable
-precompilation_test: RuntimeError # Platform.executable
-io/file_read_special_device_test: RuntimeError # Platform.executable
-verbose_gc_to_bmu_test: RuntimeError # Platform.executable
-io/http_server_close_response_after_error_test: RuntimeError # Platform.executable
-io/http_client_stays_alive_test: RuntimeError # Platform.executable
-io/print_sync_test: RuntimeError # Platform.executable
-io/signals_test: RuntimeError # Platform.executable
-io/stdio_nonblocking_test: RuntimeError # Platform.executable
-io/regress_7191_test: RuntimeError # Platform.executable
-io/secure_unauthorized_test: RuntimeError # Platform.executable
-io/dart_std_io_pipe_test: RuntimeError # Platform.executable
-io/platform_test: RuntimeError # Platform.executable
-io/socket_cross_process_test: RuntimeError # Platform.executable
-io/test_runner_test: RuntimeError # Platform.executable
-io/file_lock_test: RuntimeError # Platform.executable
-io/code_collection_test: RuntimeError # Platform.executable
-io/file_lock_test: RuntimeError # Platform.executable
-io/code_collection_test: RuntimeError # Platform.executable
-io/raw_socket_cross_process_test: RuntimeError # Platform.executable
-io/test_extension_test: RuntimeError # Platform.executable
-io/regress_7679_test: RuntimeError # Platform.executable
-
+full_coverage_test: Skip # Platform.executable
+http_launch_test: Skip # Platform.executable
+io/addlatexhash_test: Skip # Platform.executable
+io/file_read_special_device_test: Skip # Platform.executable
+io/file_stream_test: Skip # Platform.executable
+io/file_test: Skip # Platform.executable
+io/http_cross_process_test: Skip # Platform.executable
+io/https_unauthorized_test: Skip # Platform.executable
+io/platform_resolved_executable_test: Skip # Platform.resolvedExecutable
+io/skipping_dart2js_compilations_test: Skip # Platform.executable
+io/snapshot_fail_test: Skip # Platform.executable
+io/stdin_sync_test: Skip # Platform.executable
+io/test_extension_fail_test: Skip # Platform.executable
+precompilation_test: Skip # Platform.executable
+io/file_read_special_device_test: Skip # Platform.executable
+verbose_gc_to_bmu_test: Skip # Platform.executable
+io/http_server_close_response_after_error_test: Skip # Platform.executable
+io/http_client_stays_alive_test: Skip # Platform.executable
+io/print_sync_test: Skip # Platform.executable
+io/signals_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
+io/dart_std_io_pipe_test: Skip # Platform.executable
+io/platform_test: Skip # Platform.executable
+io/socket_cross_process_test: Skip # Platform.executable
+io/test_runner_test: Skip # Platform.executable
+io/file_lock_test: Skip # Platform.executable
+io/code_collection_test: Skip # Platform.executable
+io/file_lock_test: Skip # Platform.executable
+io/code_collection_test: Skip # Platform.executable
+io/raw_socket_cross_process_test: Skip # Platform.executable
+io/test_extension_test: Skip # Platform.executable
+io/regress_7679_test: Skip # Platform.executable
 io/process_*: Skip # Most use Platform.executable
+assert_test: RuntimeError # Expects line and column numbers
 
 # Code coverage is not supported in product mode.
 [ $mode == product ]
@@ -285,3 +290,14 @@
 no_support_il_printer_test: SkipByDesign
 no_support_service_test: SkipByDesign
 no_support_timeline_test: SkipByDesign
+
+# Following tests are skipped on dart_product as package mapping is not supported.
+[ $runtime == dart_product ]
+package/scenarios/packages_file_strange_formatting/mixed_line_ends_test: Skip
+package/scenarios/packages_file_strange_formatting/empty_lines_test: Skip
+package/scenarios/invalid/invalid_utf8_test: Skip
+package/scenarios/invalid/same_package_twice_test: Skip
+package/scenarios/invalid/non_existent_packages_file_test: Skip
+package/scenarios/empty_packages_file/empty_packages_file_noimports_test: Skip
+package/scenarios/packages_option_only/packages_option_only_noimports_test: Skip
+package/scenarios/packages_option_only/packages_option_only_test: Skip
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index e81c804..992eeb2 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -22,10 +22,5 @@
 [ $compiler == dart2js && $mode == debug ]
 dummy_compiler_test: Slow, Pass
 
-[ ($compiler == none || $compiler == precompiler) && $runtime == ContentShellOnAndroid ]
-dummy_compiler_test: Pass, RuntimeError # Issue 17662
-recursive_import_test: Pass, RuntimeError # Issue 17662
-source_mirrors_test: Pass, RuntimeError # Issue 17662
-
-[ ($noopt || $compiler == precompiler) ]
+[ ($noopt || $compiler == precompiler || $compiler == dart2app) ]
 source_mirrors_test: SkipByDesign # Imports dart:mirrors
diff --git a/tools/VERSION b/tools/VERSION
index fde1253..888fdb3 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 15
 PATCH 0
-PRERELEASE 3
+PRERELEASE 4
 PRERELEASE_PATCH 0
diff --git a/tools/bots/bot_utils.py b/tools/bots/bot_utils.py
index 1feaf2c..1e2ce69 100644
--- a/tools/bots/bot_utils.py
+++ b/tools/bots/bot_utils.py
@@ -115,6 +115,12 @@
     return '/'.join([self.sdk_directory(revision),
       self.sdk_zipfilename(system, arch, mode)])
 
+  def unstripped_filepath(self, revision, system, arch):
+    return '/'.join([self._variant_directory('unstripped', revision),
+                     system,
+                     arch,
+                     self.unstripped_filename(system)])
+
   def dartium_variant_zipfilepath(self, revision, name, system, arch, mode):
     return '/'.join([self.dartium_directory(revision),
       self.dartium_variant_zipfilename(name, system, arch, mode)])
@@ -186,6 +192,9 @@
     return 'dartsdk-%s-%s-%s.zip' % (
         SYSTEM_RENAMES[system], ARCH_RENAMES[arch], mode)
 
+  def unstripped_filename(self, system):
+    return 'dart.exe' if system.startswith('win') else 'dart'
+
   def dartium_variant_zipfilename(self, name, system, arch, mode):
     assert name in ['chromedriver', 'dartium', 'content_shell']
     assert mode in Mode.ALL_MODES
diff --git a/tools/bots/compiler.py b/tools/bots/compiler.py
index a784a03..581d762 100644
--- a/tools/bots/compiler.py
+++ b/tools/bots/compiler.py
@@ -143,9 +143,8 @@
   if system.startswith('win'):
     system = 'windows'
 
-  # We have both 10.8 and 10.7 bots, functionality is the same.
-  if system == 'mac10.7' or system == 'mac10.8' or system == 'mac10.9':
-    builder_tag = system.replace('.', '_')
+  # We have both 10.8 and 10.9 bots, functionality is the same.
+  if system == 'mac10.8' or system == 'mac10.9':
     system = 'mac'
 
   if (system == 'windows' and platform.system() != 'Windows') or (
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index 7952885..00e7d35 100644
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -88,9 +88,25 @@
     DartArchiveFile(sdk32_zip, path32, checksum_files=True)
     DartArchiveFile(sdk64_zip, path64, checksum_files=True)
 
+def DartArchiveUnstrippedBinaries():
+  namer = bot_utils.GCSNamer(CHANNEL, bot_utils.ReleaseType.RAW)
+  revision = utils.GetArchiveVersion()
+  binary = namer.unstripped_filename(BUILD_OS)
+  ia32_binary = os.path.join(bot_utils.DART_DIR,
+                             utils.GetBuildRoot(BUILD_OS, 'release', 'ia32'),
+                             binary)
+  x64_binary = os.path.join(bot_utils.DART_DIR,
+                            utils.GetBuildRoot(BUILD_OS, 'release', 'x64'),
+                            binary)
+  gs_ia32_path = namer.unstripped_filepath(revision, BUILD_OS, 'ia32')
+  gs_x64_path = namer.unstripped_filepath(revision, BUILD_OS, 'x64')
+  DartArchiveFile(ia32_binary, gs_ia32_path)
+  DartArchiveFile(x64_binary, gs_x64_path)
+
 def CreateUploadSDK():
   BuildSDK()
   CreateUploadSDKZips()
+  DartArchiveUnstrippedBinaries()
 
 def CreateUploadAPIDocs():
   dartdoc_dir =  os.path.join(bot_utils.DART_DIR,
diff --git a/tools/create_sdk.py b/tools/create_sdk.py
index 1e4fc74..0d72c9d 100755
--- a/tools/create_sdk.py
+++ b/tools/create_sdk.py
@@ -44,6 +44,8 @@
 # ......dart_shared.platform
 # ......dart2dart.platform
 # ......_internal/
+#.........spec.sum
+#.........strong.sum
 # ......analysis_server/
 # ......analyzer/
 # ......async/
@@ -157,7 +159,13 @@
   PACKAGES_FILE = join(DARTDOC, '.packages')
   packages_file = open(PACKAGES_FILE, 'w')
   packages_file.write('dartdoc:.')
-  packages_file.close() 
+  packages_file.close()
+
+def CopyAnalysisSummaries(snapshots, lib):
+  copyfile(join(snapshots, 'spec.sum'),
+           join(lib, '_internal', 'spec.sum'))
+  copyfile(join(snapshots, 'strong.sum'),
+           join(lib, '_internal', 'strong.sum'))
 
 
 def Main():
@@ -290,10 +298,11 @@
 
   # Copy dart2js/pub.
   CopyDartScripts(HOME, SDK_tmp)
-  
+
   CopySnapshots(SNAPSHOT, SDK_tmp)
   CopyDartdocResources(HOME, SDK_tmp)
   CopyAnalyzerSources(HOME, LIB)
+  CopyAnalysisSummaries(SNAPSHOT, LIB)
 
   # Write the 'version' file
   version = utils.GetVersion()
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 43447ed..a510fd4 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -65,7 +65,7 @@
   "yaml_rev": "@563a5ffd4a800a2897b8f4dd6b19f2a370df2f2b",
   "zlib_rev": "@c3d0a6190f2f8c924a05ab6cc97b8f975bddd33f",
   "web_components_rev": "@0e636b534d9b12c9e96f841e6679398e91a986ec",
-  "WebCore_rev": "@5ecb723fd9ffcc0d108f5e0e24d12b8b3df7b200",
+  "WebCore_rev": "@a86fe28efadcfc781f836037a80f27e22a5dad17",
 
   "co19_rev": "@3ed795ea02e022ef19c77cf1b6095b7c8f5584d0",
 })
diff --git a/tools/dom/scripts/dartdomgenerator.py b/tools/dom/scripts/dartdomgenerator.py
index 4b07d77..cacdd63 100755
--- a/tools/dom/scripts/dartdomgenerator.py
+++ b/tools/dom/scripts/dartdomgenerator.py
@@ -106,6 +106,7 @@
                              exclude_suppressed = ['WebKit', 'Dart'])
   generator.FixEventTargets(webkit_database)
   generator.AddMissingArguments(webkit_database)
+  generator.HackCleanupTimers(webkit_database)
 
   emitters = multiemitter.MultiEmitter(logging_level)
   metadata = DartMetadata(
diff --git a/tools/dom/scripts/dartgenerator.py b/tools/dom/scripts/dartgenerator.py
index 55a3499..5adbe3a 100755
--- a/tools/dom/scripts/dartgenerator.py
+++ b/tools/dom/scripts/dartgenerator.py
@@ -244,3 +244,11 @@
 
         if 'ScriptArguments' in call_with:
           operation.arguments.append(ARG)
+
+  # TODO(terry): Hack to remove 3rd arguments in setInterval/setTimeout.
+  def HackCleanupTimers(self, database):
+    for interface in database.GetInterfaces():
+      for operation in interface.operations:
+        if ((operation.id == 'setInterval' or operation.id == 'setTimeout') and \
+            operation.arguments[0].type.id == 'any'):
+          operation.arguments.pop(2)
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index e0d28ab..b90a2b3 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -126,13 +126,13 @@
     # addEventListener on the target, so we avoid
     'Event.currentTarget': [
       "@Creates('Null')",
-      "@Returns('EventTarget|=Object|Null')",
+      "@Returns('EventTarget|=Object')",
     ],
 
     # Only nodes in the DOM bubble and have target !== currentTarget.
     'Event.target': [
       "@Creates('Node')",
-      "@Returns('EventTarget|=Object|Null')",
+      "@Returns('EventTarget|=Object')",
     ],
 
     'File.lastModifiedDate': [
@@ -273,7 +273,7 @@
 
     'MouseEvent.relatedTarget': [
       "@Creates('Node')",
-      "@Returns('EventTarget|=Object|Null')",
+      "@Returns('EventTarget|=Object')",
     ],
 
     'PopStateEvent.state': [
@@ -371,7 +371,7 @@
     ],
 
     'WebGLRenderingContext.getContextAttributes': [
-      "@Creates('ContextAttributes|=Object')",
+      "@Creates('ContextAttributes|Null')",
     ],
 
     'XMLHttpRequest.response': [
diff --git a/tools/dom/scripts/generate_blink_file.py b/tools/dom/scripts/generate_blink_file.py
index d5ea86f..a45b9ac 100644
--- a/tools/dom/scripts/generate_blink_file.py
+++ b/tools/dom/scripts/generate_blink_file.py
@@ -149,6 +149,11 @@
 #(operation_name, operationName)
 OPERATION_0 = '  %s_Callback_0_(mthis) => Blink_JsNative_DomException.callMethod(mthis, "%s", []);\n\n'
 
+# getter, setter, deleter and propertyQuery code
+OPERATION_1 = '  $%s_Callback_1_(mthis, __arg_0) => Blink_JsNative_DomException.callMethod(mthis, "%s", [__arg_0]);\n\n'
+OPERATION_2 = '  $%s_Callback_2_(mthis, __arg_0, __arg_1) => Blink_JsNative_DomException.callMethod(mthis, "%s", [__arg_0, __arg_1]);\n\n'
+OPERATION_PQ = '  $%s_Callback_1_(mthis, __arg_0) => mthis[__arg_0];\n\n'
+
 #(operation_name, argument_count, arguments, operation_name, arguments)
 ARGUMENT_NUM = "__arg_%s"
 OPERATION_ARGS = '  %s_Callback_%s_(mthis, %s) => Blink_JsNative_DomException.callMethod(mthis, "%s", [%s]);\n\n'
@@ -172,6 +177,13 @@
     lb = min_arg_count - 2 if min_arg_count > 2 else 0
     return (lb, arg_count + 1)
 
+constructor_renames = {
+    'RTCPeerConnection': 'webkitRTCPeerConnection',
+}
+
+def rename_constructor(name):
+  return constructor_renames[name] if name in constructor_renames else name
+
 def Generate_Blink(output_dir, database, type_registry):
   blink_filename = os.path.join(output_dir, '_blink_dartium.dart')
   blink_file = open(blink_filename, 'w')
@@ -201,7 +213,7 @@
       _Emit_Blink_Constructors(blink_file, analyzed_constructors)
     elif 'Constructor' in interface.ext_attrs:
       # Zero parameter constructor.
-      blink_file.write(CONSTRUCTOR_0 % name)
+      blink_file.write(CONSTRUCTOR_0 % rename_constructor(name))
 
     _Process_Attributes(blink_file, interface.attributes)
     _Process_Operations(blink_file, interface, interface.operations)
@@ -225,13 +237,13 @@
 
   for callback_index in range(arg_min_count, arg_max_count):
     if callback_index == 0:
-      blink_file.write(CONSTRUCTOR_0 % (name))
+      blink_file.write(CONSTRUCTOR_0 % (rename_constructor(name)))
     else:
       arguments = []
       for i in range(0, callback_index):
         arguments.append(ARGUMENT_NUM % i)
       argument_list = ', '.join(arguments)
-      blink_file.write(CONSTRUCTOR_ARGS % (callback_index, argument_list, name, argument_list))
+      blink_file.write(CONSTRUCTOR_ARGS % (callback_index, argument_list, rename_constructor(name), argument_list))
 
 def _Process_Attributes(blink_file, attributes):
   # Emit an interface's attributes and operations.
@@ -264,6 +276,25 @@
   (arg_min_count, arg_max_count) = generate_parameter_entries(analyzed.param_infos)
   name = analyzed.js_name
 
+  operation = analyzeOperations[0]
+  if (name.startswith('__') and \
+      ('getter' in operation.specials or \
+       'setter' in operation.specials or \
+       'deleter' in operation.specials)):
+    if name == '__propertyQuery__':
+      blink_file.write(OPERATION_PQ % (name))
+    else:
+      arg_min_count = arg_max_count
+      if arg_max_count == 2:
+        blink_file.write(OPERATION_1 % (name, name))
+      elif arg_max_count == 3:
+        blink_file.write(OPERATION_2 % (name, name))
+      else:
+        print "FATAL ERROR: _blink emitter operator %s.%s" % (interface.id, name)
+        exit
+
+    return
+
   for callback_index in range(arg_min_count, arg_max_count):
     if callback_index == 0:
       blink_file.write(OPERATION_0 % (name, name))
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index bb26d6f..a1ebfe2 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -294,7 +294,6 @@
 
   Returns: An OperationInfo object.
   """
-
   # split operations with optional args into multiple operations
   split_operations = []
   for operation in operations:
@@ -723,11 +722,12 @@
     'any set IDBCursor.update': _serialize_SSV,
 
     # postMessage
+    'SerializedScriptValue set': _serialize_SSV,
+    'any set CompositorWorkerGlobalScope.postMessage': _serialize_SSV,
+    'any set DedicatedWorkerGlobalScope.postMessage': _serialize_SSV,
     'any set MessagePort.postMessage': _serialize_SSV,
-    'SerializedScriptValue set Window.postMessage': _serialize_SSV,
-    'SerializedScriptValue set Worker.postMessage': _serialize_SSV,
-    'any set DedicatedWorkerGlobalScope.postMessage' : _serialize_SSV,
-    'SerializedScriptValue set ServiceWorkerClient.postMessage': _serialize_SSV,
+    'any set Window.postMessage': _serialize_SSV,
+    'any set _DOMWindowCrossFrame.postMessage': _serialize_SSV,
 
     '* get CustomEvent.detail':
       Conversion('convertNativeToDart_SerializedScriptValue',
@@ -1466,9 +1466,20 @@
     class_name = '%sIDLTypeInfo' % type_data.clazz
     return globals()[class_name](type_name, type_data)
 
+def isList(return_type):
+  return return_type.startswith('List<') if return_type else False
+
+def get_list_type(return_type):
+  # Get the list type NNNN inside of List<NNNN>
+  return return_type[5:-1] if isList(return_type) else return_type
+
 def wrap_unwrap_list_blink(return_type, type_registry):
-    """Return True if the type is a List<Node>"""
-    return return_type.startswith('List<Node>')
+  """Return True if the type is the list type is a blink know
+     type e.g., List<Node>, List<FontFace>, etc."""
+  if isList(return_type):
+    list_type = get_list_type(return_type)
+    if type_registry.HasInterface(list_type):
+      return True;
 
 def wrap_unwrap_type_blink(return_type, type_registry):
     """Returns True if the type is a blink type that requires wrap_jso or
diff --git a/tools/dom/scripts/htmldartgenerator.py b/tools/dom/scripts/htmldartgenerator.py
index b93b0ca..c944fc3 100644
--- a/tools/dom/scripts/htmldartgenerator.py
+++ b/tools/dom/scripts/htmldartgenerator.py
@@ -132,6 +132,13 @@
 
     secondary_parents = self._database.TransitiveSecondaryParents(interface,
                           not self._dart_use_blink)
+    remove_duplicate_parents = list(set(secondary_parents))
+    if len(secondary_parents) != len(remove_duplicate_parents):
+      secondary_parents = remove_duplicate_parents
+      parent_list = ", ".join(["  %s" % (parent.id) for parent in secondary_parents])
+      _logger.warn('Interface %s has duplicate parent interfaces %s - ' \
+                   'ignoring duplicates. Please file a bug with the dart:html team.' % (interface.id, parent_list))
+
     for parent_interface in sorted(secondary_parents):
       if isinstance(parent_interface, str):
         continue
diff --git a/tools/dom/scripts/htmlrenamer.py b/tools/dom/scripts/htmlrenamer.py
index 823666c..b05f9cc 100644
--- a/tools/dom/scripts/htmlrenamer.py
+++ b/tools/dom/scripts/htmlrenamer.py
@@ -136,6 +136,7 @@
   'WebKitMediaSource',
   'WebKitNotification',
   'WebGLRenderingContextBase',
+  'WebGL2RenderingContextBase',
   'WebKitSourceBuffer',
   'WebKitSourceBufferList',
   'WorkerLocation', # Workers
@@ -177,9 +178,19 @@
 # constructor for dispatch purposes.
 custom_html_constructors = monitored.Set(
     'htmlrenamer.custom_html_constructors', [
+  'CompositionEvent',       # 45 Roll hide default constructor use Dart's custom
+  'CustomEvent',            # 45 Roll hide default constructor use Dart's custom
+  'Event',                  # 45 Roll hide default constructor use Dart's custom
+  'HashChangeEvent',        # 45 Roll hide default constructor use Dart's custom
   'HTMLAudioElement',
   'HTMLOptionElement',
+  'KeyboardEvent',          # 45 Roll hide default constructor use Dart's custom
+  'MessageEvent',           # 45 Roll hide default constructor use Dart's custom
+  'MouseEvent',             # 45 Roll hide default constructor use Dart's custom
   'MutationObserver',
+  'StorageEvent',           # 45 Roll hide default constructor use Dart's custom
+  'UIEvent',                # 45 Roll hide default constructor use Dart's custom
+  'WheelEvent',             # 45 Roll hide default constructor use Dart's custom
 ])
 
 # Members from the standard dom that should not be exposed publicly in dart:html
@@ -253,18 +264,14 @@
   'Element.querySelectorAll',
   # TODO(vsm): These have been converted from int to double in Chrome 36.
   # Special case them so we run on 34, 35, and 36.
-  'Element.offsetLeft',
-  'Element.offsetTop',
-  'Element.offsetWidth',
-  'Element.offsetHeight',
-  'Element.clientLeft',
-  'Element.clientTop',
-  'Element.clientWidth',
-  'Element.clientHeight',
   'Element.scrollLeft',
   'Element.scrollTop',
   'Element.scrollWidth',
   'Element.scrollHeight',
+  'Element.clientLeft',
+  'Element.clientTop',
+  'Element.clientWidth',
+  'Element.clientHeight',
 
   'Event.initEvent',
   'EventTarget.addEventListener',
@@ -404,6 +411,7 @@
 # Members from the standard dom that exist in the dart:html library with
 # identical functionality but with cleaner names.
 renamed_html_members = monitored.Dict('htmlrenamer.renamed_html_members', {
+    'ConsoleBase.assert': 'assertCondition',
     'CSSKeyframesRule.insertRule': 'appendRule',
     'DirectoryEntry.getDirectory': '_getDirectory',
     'DirectoryEntry.getFile': '_getFile',
@@ -434,8 +442,6 @@
   'AudioContext.createBuffer(ArrayBuffer buffer, boolean mixToMono)':
       'createBufferFromBuffer',
   'CSS.supports(DOMString conditionText)': 'supportsCondition',
-  'CanvasRenderingContext2D.createPattern(HTMLImageElement image, '
-      'DOMString repetitionType)': 'createPatternFromImage',
   'DataTransferItemList.add(File file)': 'addFile',
   'DataTransferItemList.add(DOMString data, DOMString type)': 'addData',
   'FormData.append(DOMString name, Blob value, DOMString filename)':
@@ -486,7 +492,11 @@
   'WebSocket.send(ArrayBuffer data)': 'sendByteBuffer',
   'WebSocket.send(ArrayBufferView data)': 'sendTypedData',
   'WebSocket.send(DOMString data)': 'sendString',
-  'WebSocket.send(Blob data)': 'sendBlob'
+  'WebSocket.send(Blob data)': 'sendBlob',
+  'Window.setInterval(DOMString handler, long timeout, any arguments)': '_setInterval_String',
+  'Window.setTimeout(DOMString handler, long timeout, any arguments)': '_setTimeout_String',
+  'WindowTimers.setInterval(DOMString handler, long timeout, any arguments)': '_setInterval_String',
+  'WindowTimers.setTimeout(DOMString handler, long timeout, any arguments)': '_setTimeout_String',
 })
 
 # Members that have multiple definitions, but their types are identical (only
@@ -553,7 +563,10 @@
     'CanvasRenderingContext2D.setMiterLimit',
     'CanvasRenderingContext2D.setShadow',
     'CanvasRenderingContext2D.setStrokeColor',
+    # Disable the webKit version, imageSmoothingEnabled is exposed.
+    'CanvasRenderingContext2D.webkitImageSmoothingEnabled',
     'CharacterData.remove',
+    'ChildNode.replaceWith',
     'Window.call:blur',
     'Window.call:focus',
     'Window.clientInformation',
@@ -570,6 +583,7 @@
     'Window.webkitRequestAnimationFrame',
     'Document.alinkColor',
     'Document.all',
+    'Document.append',
     'Document.applets',
     'Document.bgColor',
     'Document.clear',
@@ -605,6 +619,7 @@
     'Document.location',
     'Document.on:wheel',
     'Document.open',
+    'Document.prepend',
     'Document.register',
     'Document.set:domain',
     'Document.vlinkColor',
@@ -643,14 +658,24 @@
     'DOMException.VALIDATION_ERR',
     'DOMException.WRONG_DOCUMENT_ERR',
     'Element.accessKey',
+    'Element.append',
     'Element.dataset',
     'Element.get:classList',
     'Element.getAttributeNode',
     'Element.getAttributeNodeNS',
     'Element.getElementsByTagNameNS',
     'Element.innerText',
+    # TODO(terry): All offset* attributes are in both HTMLElement and Element
+    #              (it's a Chrome bug with a FIXME note to correct - sometime).
+    #              Until corrected these Element attributes must be ignored.
+    'Element.offsetParent',
+    'Element.offsetTop',
+    'Element.offsetLeft',
+    'Element.offsetWidth',
+    'Element.offsetHeight',
     'Element.on:wheel',
     'Element.outerText',
+    'Element.prepend',
     'Element.removeAttributeNode',
     'Element.set:outerHTML',
     'Element.setAttributeNode',
@@ -774,6 +799,7 @@
     'HTMLUListElement.type',
     'IDBDatabase.transaction', # We do this in a template without the generated implementation at all.
     'Location.valueOf',
+    'MessageEvent.data',
     'MessageEvent.ports',
     'MessageEvent.webkitInitMessageEvent',
     'MouseEvent.x',
@@ -804,6 +830,8 @@
     'NodeIterator.expandEntityReferences',
     'NodeIterator.filter',
     'NodeList.item',
+    'ParentNode.append',
+    'ParentNode.prepend',
     'Performance.webkitClearMarks',
     'Performance.webkitClearMeasures',
     'Performance.webkitGetEntries',
@@ -817,6 +845,7 @@
     'Touch.get:webkitRadiusX',
     'Touch.get:webkitRadiusY',
     'Touch.get:webkitForce',
+    'Touch.get:webkitRotationAngle',
     'WheelEvent.wheelDelta',
     'WheelEvent.wheelDeltaX',
     'WheelEvent.wheelDeltaY',
@@ -869,6 +898,8 @@
       return html_interface_renames[interface_id]
     return None;
 
+  def isPrivate(self, interface, member):
+    return self._FindMatch(interface, member, '', private_html_members)
 
   def RenameMember(self, interface_name, member_node, member, member_prefix='',
       dartify_name=True):
diff --git a/tools/dom/scripts/idlnode.py b/tools/dom/scripts/idlnode.py
index 8dfd3b8..b5949a3 100755
--- a/tools/dom/scripts/idlnode.py
+++ b/tools/dom/scripts/idlnode.py
@@ -573,15 +573,25 @@
     elif ast.__module__ == "idl_types":
       if isinstance(ast, IdlType) or isinstance(ast, IdlArrayOrSequenceType) or \
          isinstance(ast, IdlNullableType):
-        type_name = str(ast)
-        # TODO(terry): For now don't handle unrestricted types see
-        #              https://code.google.com/p/chromium/issues/detail?id=354298
-        type_name = type_name.replace('unrestricted ', '', 1);
+        if isinstance(ast, IdlNullableType) and ast.inner_type.is_union_type:
+          print 'WARNING type %s is union mapped to \'any\'' % self.id
+          # TODO(terry): For union types use any otherwise type is unionType is
+          #              not found and is removed during merging.
+          self.id = 'any'
+        else:
+          type_name = str(ast)
+          # TODO(terry): For now don't handle unrestricted types see
+          #              https://code.google.com/p/chromium/issues/detail?id=354298
+          type_name = type_name.replace('unrestricted ', '', 1);
 
-        # TODO(terry): Handled USVString as a DOMString.
-        type_name = type_name.replace('USVString', 'DOMString', 1)
+          # TODO(terry): Handled USVString as a DOMString.
+          type_name = type_name.replace('USVString', 'DOMString', 1)
 
-        self.id = type_name
+          # TODO(terry); WindowTimers setInterval/setTimeout overloads with a
+          #              Function type - map to any until the IDL uses union.
+          type_name = type_name.replace('Function', 'any', 1)
+
+          self.id = type_name
       else:
         # IdlUnionType
         if ast.is_union_type:
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 09c242d..7656695 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -406,7 +406,7 @@
 ]
 
 js_support_checks = dict({
-    'AnimationPlayer': "JS('bool', '!!(document.body.animate)')",
+    'Animation': "JS('bool', '!!(document.body.animate)')",
     'AudioContext': "JS('bool', '!!(window.AudioContext ||"
         " window.webkitAudioContext)')",
     'Crypto':
@@ -705,7 +705,7 @@
     merged_interface = self._interface_type_info.merged_interface()
     if merged_interface:
       self._backend.AddMembers(self._database.GetInterface(merged_interface),
-        not self._backend.ImplementsMergedMembers())
+                               not self._backend.ImplementsMergedMembers())
 
     self._backend.AddMembers(self._interface, False, self._options.dart_js_interop)
     self._backend.AddSecondaryMembers(self._interface)
diff --git a/tools/dom/scripts/systemnative.py b/tools/dom/scripts/systemnative.py
index 3fc0638..5470993 100644
--- a/tools/dom/scripts/systemnative.py
+++ b/tools/dom/scripts/systemnative.py
@@ -13,287 +13,12 @@
 from idlnode import IDLArgument, IDLAttribute, IDLEnum, IDLMember
 from systemhtml import js_support_checks, GetCallbackInfo, HTML_LIBRARY_NAMES
 
-# TODO(vsm): This logic needs to pulled from the source IDL.  These tables are
-# an ugly workaround.
-_cpp_callback_map = {
-  ('DataTransferItem', 'webkitGetAsEntry'): 'DataTransferItemFileSystem',
-  ('Document', 'fonts'): 'DocumentFontFaceSet',
-  ('Document', 'webkitIsFullScreen'): 'DocumentFullscreen',
-  ('Document', 'webkitFullScreenKeyboardInputAllowed'): 'DocumentFullscreen',
-  ('Document', 'webkitCurrentFullScreenElement'): 'DocumentFullscreen',
-  ('Document', 'webkitCancelFullScreen'): 'DocumentFullscreen',
-  ('Document', 'webkitFullscreenEnabled'): 'DocumentFullscreen',
-  ('Document', 'webkitFullscreenElement'): 'DocumentFullscreen',
-  ('Document', 'webkitExitFullscreen'): 'DocumentFullscreen',
-  ('DOMWindow', 'crypto'): 'DOMWindowCrypto',
-  ('DOMWindow', 'indexedDB'): 'DOMWindowIndexedDatabase',
-  ('DOMWindow', 'speechSynthesis'): 'DOMWindowSpeechSynthesis',
-  ('DOMWindow', 'webkitNotifications'): 'DOMWindowNotifications',
-  ('DOMWindow', 'storage'): 'DOMWindowQuota',
-  ('DOMWindow', 'webkitStorageInfo'): 'DOMWindowQuota',
-  ('DOMWindow', 'openDatabase'): 'DOMWindowWebDatabase',
-  ('DOMWindow', 'webkitRequestFileSystem'): 'DOMWindowFileSystem',
-  ('DOMWindow', 'webkitResolveLocalFileSystemURL'): 'DOMWindowFileSystem',
-  ('DOMWindow', 'atob'): 'DOMWindowBase64',
-  ('DOMWindow', 'btoa'): 'DOMWindowBase64',
-  ('DOMWindow', 'clearTimeout'): 'DOMWindowTimers',
-  ('DOMWindow', 'clearInterval'): 'DOMWindowTimers',
-  ('DOMWindow', 'createImageBitmap'): 'ImageBitmapFactories',
-  ('Element', 'animate'): 'ElementAnimation',
-  ('HTMLInputElement', 'webkitEntries'): 'HTMLInputElementFileSystem',
-  ('HTMLVideoElement', 'getVideoPlaybackQuality'): 'HTMLVideoElementMediaSource',
-  ('Navigator', 'doNotTrack'): 'NavigatorDoNotTrack',
-  ('Navigator', 'geolocation'): 'NavigatorGeolocation',
-  ('Navigator', 'webkitPersistentStorage'): 'NavigatorStorageQuota',
-  ('Navigator', 'webkitTemporaryStorage'): 'NavigatorStorageQuota',
-  ('Navigator', 'registerProtocolHandler'): 'NavigatorContentUtils',
-  ('Navigator', 'unregisterProtocolHandler'): 'NavigatorContentUtils',
-  ('Navigator', 'webkitGetUserMedia'): 'NavigatorMediaStream',
-  ('Navigator', 'webkitGetGamepads'): 'NavigatorGamepad',
-  ('Navigator', 'requestMIDIAccess'): 'NavigatorWebMIDI',
-  ('Navigator', 'vibrate'): 'NavigatorVibration',
-  ('Navigator', 'appName'): 'NavigatorID',
-  ('Navigator', 'appVersion'): 'NavigatorID',
-  ('Navigator', 'appCodeName'): 'NavigatorID',
-  ('Navigator', 'platform'): 'NavigatorID',
-  ('Navigator', 'product'): 'NavigatorID',
-  ('Navigator', 'userAgent'): 'NavigatorID',
-  ('Navigator', 'onLine'): 'NavigatorOnLine',
-  ('Navigator', 'registerServiceWorker'): 'NavigatorServiceWorker',
-  ('Navigator', 'unregisterServiceWorker'): 'NavigatorServiceWorker',
-  ('Navigator', 'maxTouchPoints'): 'NavigatorEvents',
-  ('WorkerGlobalScope', 'crypto'): 'WorkerGlobalScopeCrypto',
-  ('WorkerGlobalScope', 'indexedDB'): 'WorkerGlobalScopeIndexedDatabase',
-  ('WorkerGlobalScope', 'webkitNotifications'): 'WorkerGlobalScopeNotifications',
-  ('WorkerGlobalScope', 'openDatabase'): 'WorkerGlobalScopeWebDatabase',
-  ('WorkerGlobalScope', 'openDatabaseSync'): 'WorkerGlobalScopeWebDatabase',
-  ('WorkerGlobalScope', 'performance'): 'WorkerGlobalScopePerformance',
-  ('WorkerGlobalScope', 'webkitRequestFileSystem'): 'WorkerGlobalScopeFileSystem',
-  ('WorkerGlobalScope', 'webkitRequestFileSystemSync'): 'WorkerGlobalScopeFileSystem',
-  ('WorkerGlobalScope', 'webkitResolveLocalFileSystemURL'): 'WorkerGlobalScopeFileSystem',
-  ('WorkerGlobalScope', 'webkitResolveLocalFileSystemSyncURL'): 'WorkerGlobalScopeFileSystem',
-  ('WorkerGlobalScope', 'atob'): 'DOMWindowBase64',
-  ('WorkerGlobalScope', 'btoa'): 'DOMWindowBase64',
-  ('WorkerGlobalScope', 'clearTimeout'): 'DOMWindowTimers',
-  ('WorkerGlobalScope', 'clearInterval'): 'DOMWindowTimers',
-  ('Document', 'rootElement'): 'SVGDocument',
-  ('Document', 'childElementCount'): 'ParentNode',
-  ('Document', 'firstElementChild'): 'ParentNode',
-  ('Document', 'lastElementChild'): 'ParentNode',
-  ('DocumentFragment', 'childElementCount'): 'ParentNode',
-  ('DocumentFragment', 'firstElementChild'): 'ParentNode',
-  ('DocumentFragment', 'lastElementChild'): 'ParentNode',
-  ('CharacterData', 'nextElementSibling'): 'ChildNode',
-  ('CharacterData', 'previousElementSibling'): 'ChildNode',
-  ('Element', 'childElementCount'): 'ParentNode',
-  ('Element', 'firstElementChild'): 'ParentNode',
-  ('Element', 'lastElementChild'): 'ParentNode',
-  ('Element', 'nextElementSibling'): 'ChildNode',
-  ('Element', 'previousElementSibling'): 'ChildNode',
-  ('SVGAnimationElement', 'requiredExtensions'): 'SVGTests',
-  ('SVGAnimationElement', 'requiredFeatures'): 'SVGTests',
-  ('SVGAnimationElement', 'systemLanguage'): 'SVGTests',
-  ('SVGAnimationElement', 'hasExtension'): 'SVGTests',
-  ('SVGGraphicsElement', 'requiredExtensions'): 'SVGTests',
-  ('SVGGraphicsElement', 'requiredFeatures'): 'SVGTests',
-  ('SVGGraphicsElement', 'systemLanguage'): 'SVGTests',
-  ('SVGGraphicsElement', 'hasExtension'): 'SVGTests',
-  ('SVGPatternElement', 'requiredExtensions'): 'SVGTests',
-  ('SVGPatternElement', 'requiredFeatures'): 'SVGTests',
-  ('SVGPatternElement', 'systemLanguage'): 'SVGTests',
-  ('SVGPatternElement', 'hasExtension'): 'SVGTests',
-  ('SVGUseElement', 'requiredExtensions'): 'SVGTests',
-  ('SVGUseElement', 'requiredFeatures'): 'SVGTests',
-  ('SVGUseElement', 'systemLanguage'): 'SVGTests',
-  ('SVGUseElement', 'hasExtension'): 'SVGTests',
-  ('SVGMaskElement', 'requiredExtensions'): 'SVGTests',
-  ('SVGMaskElement', 'requiredFeatures'): 'SVGTests',
-  ('SVGMaskElement', 'systemLanguage'): 'SVGTests',
-  ('SVGMaskElement', 'hasExtension'): 'SVGTests',
-  ('SVGViewSpec', 'zoomAndPan'): 'SVGZoomAndPan',
-  ('SVGViewSpec', 'setZoomAndPan'): 'SVGZoomAndPan',
-  ('SVGViewElement', 'setZoomAndPan'): 'SVGZoomAndPan',
-  ('SVGSVGElement', 'setZoomAndPan'): 'SVGZoomAndPan',
-  ('Screen', 'orientation'): 'ScreenOrientation',
-  ('Screen', 'lockOrientation'): 'ScreenOrientation',
-  ('Screen', 'unlockOrientation'): 'ScreenOrientation',
-  ('Navigator', 'serviceWorker'): 'NavigatorServiceWorker',
-  ('Navigator', 'storageQuota'): 'NavigatorStorageQuota',
-  ('Navigator', 'isProtocolHandlerRegistered'): 'NavigatorContentUtils',
-  ('SharedWorker', 'workerStart'): 'SharedWorkerPerformance',
-}
-
-_cpp_import_map = {
-  'ImageBitmapFactories' : 'modules/imagebitmap/ImageBitmapFactories',
-  'ScreenOrientation' : 'modules/screen_orientation/ScreenOrientation'
-}
-
-_cpp_overloaded_callback_map = {
-  ('DOMURL', 'createObjectUrlFromSourceCallback'): 'URLMediaSource',
-  ('DOMURL', 'createObjectUrlFromStreamCallback'): 'URLMediaStream',
-  ('DOMURL', '_createObjectUrlFromWebKitSourceCallback'): 'URLMediaSource',
-  ('DOMURL', '_createObjectURL_2Callback'): 'URLMediaSource',
-  ('DOMURL', '_createObjectURL_3Callback'): 'URLMediaStream',
-}
-
-_cpp_partial_map = {}
-
-_cpp_no_auto_scope_list = set([
-  ('Document', 'body', 'Getter'),
-  ('Document', 'getElementById', 'Callback'),
-  ('Document', 'getElementsByName', 'Callback'),
-  ('Document', 'getElementsByTagName', 'Callback'),
-  ('Element', 'getAttribute', 'Callback'),
-  ('Element', 'getAttributeNS', 'Callback'),
-  ('Element', 'id', 'Getter'),
-  ('Element', 'id', 'Setter'),
-  ('Element', 'setAttribute', 'Callback'),
-  ('Element', 'setAttributeNS', 'Callback'),
-  ('Node', 'firstChild', 'Getter'),
-  ('Node', 'lastChild', 'Getter'),
-  ('Node', 'nextSibling', 'Getter'),
-  ('Node', 'previousSibling', 'Getter'),
-  ('Node', 'childNodes', 'Getter'),
-  ('Node', 'nodeType', 'Getter'),
-  ('NodeList', 'length', 'Getter'),
-  ('NodeList', 'item', 'Callback'),
-  ('WebGLRenderingContext', 'drawingBufferHeight', 'Getter'),
-  ('WebGLRenderingContext', 'drawingBufferWidth', 'Getter'),
-  ('WebGLRenderingContext', 'activeTexture', 'Callback'),
-  ('WebGLRenderingContext', 'attachShader', 'Callback'),
-  ('WebGLRenderingContext', 'bindAttribLocation', 'Callback'),
-  ('WebGLRenderingContext', 'bindBuffer', 'Callback'),
-  ('WebGLRenderingContext', 'bindFramebuffer', 'Callback'),
-  ('WebGLRenderingContext', 'bindRenderbuffer', 'Callback'),
-  ('WebGLRenderingContext', 'bindTexture', 'Callback'),
-  ('WebGLRenderingContext', 'blendColor', 'Callback'),
-  ('WebGLRenderingContext', 'blendEquation', 'Callback'),
-  ('WebGLRenderingContext', 'blendEquationSeparate', 'Callback'),
-  ('WebGLRenderingContext', 'blendFunc', 'Callback'),
-  ('WebGLRenderingContext', 'blendFuncSeparate', 'Callback'),
-  ('WebGLRenderingContext', 'checkFramebufferStatus', 'Callback'),
-  ('WebGLRenderingContext', 'clear', 'Callback'),
-  ('WebGLRenderingContext', 'clearColor', 'Callback'),
-  ('WebGLRenderingContext', 'clearDepth', 'Callback'),
-  ('WebGLRenderingContext', 'clearStencil', 'Callback'),
-  ('WebGLRenderingContext', 'colorMask', 'Callback'),
-  ('WebGLRenderingContext', 'compileShader', 'Callback'),
-  ('WebGLRenderingContext', 'compressedTexImage2D', 'Callback'),
-  ('WebGLRenderingContext', 'compressedTexSubImage2D', 'Callback'),
-  ('WebGLRenderingContext', 'copyTexImage2D', 'Callback'),
-  ('WebGLRenderingContext', 'copyTexSubImage2D', 'Callback'),
-  ('WebGLRenderingContext', 'cullFace', 'Callback'),
-  ('WebGLRenderingContext', 'deleteBuffer', 'Callback'),
-  ('WebGLRenderingContext', 'deleteFramebuffer', 'Callback'),
-  ('WebGLRenderingContext', 'deleteProgram', 'Callback'),
-  ('WebGLRenderingContext', 'deleteRenderbuffer', 'Callback'),
-  ('WebGLRenderingContext', 'deleteShader', 'Callback'),
-  ('WebGLRenderingContext', 'deleteTexture', 'Callback'),
-  ('WebGLRenderingContext', 'depthFunc', 'Callback'),
-  ('WebGLRenderingContext', 'depthMask', 'Callback'),
-  ('WebGLRenderingContext', 'depthRange', 'Callback'),
-  ('WebGLRenderingContext', 'detachShader', 'Callback'),
-  ('WebGLRenderingContext', 'disable', 'Callback'),
-  ('WebGLRenderingContext', 'disableVertexAttribArray', 'Callback'),
-  ('WebGLRenderingContext', 'drawArrays', 'Callback'),
-  ('WebGLRenderingContext', 'drawElements', 'Callback'),
-  ('WebGLRenderingContext', 'enable', 'Callback'),
-  ('WebGLRenderingContext', 'enableVertexAttribArray', 'Callback'),
-  ('WebGLRenderingContext', 'finish', 'Callback'),
-  ('WebGLRenderingContext', 'flush', 'Callback'),
-  ('WebGLRenderingContext', 'framebufferRenderbuffer', 'Callback'),
-  ('WebGLRenderingContext', 'framebufferTexture2D', 'Callback'),
-  ('WebGLRenderingContext', 'frontFace', 'Callback'),
-  ('WebGLRenderingContext', 'generateMipmap', 'Callback'),
-  ('WebGLRenderingContext', 'getActiveAttrib', 'Callback'),
-  ('WebGLRenderingContext', 'getActiveUniform', 'Callback'),
-  ('WebGLRenderingContext', 'getAttachedShaders', 'Callback'),
-  ('WebGLRenderingContext', 'getAttribLocation', 'Callback'),
-  ('WebGLRenderingContext', 'hint', 'Callback'),
-  ('WebGLRenderingContext', 'isBuffer', 'Callback'),
-  ('WebGLRenderingContext', 'isContextLost', 'Callback'),
-  ('WebGLRenderingContext', 'isEnabled', 'Callback'),
-  ('WebGLRenderingContext', 'isFramebuffer', 'Callback'),
-  ('WebGLRenderingContext', 'isProgram', 'Callback'),
-  ('WebGLRenderingContext', 'isRenderbuffer', 'Callback'),
-  ('WebGLRenderingContext', 'isShader', 'Callback'),
-  ('WebGLRenderingContext', 'isTexture', 'Callback'),
-  ('WebGLRenderingContext', 'lineWidth', 'Callback'),
-  ('WebGLRenderingContext', 'linkProgram', 'Callback'),
-  ('WebGLRenderingContext', 'pixelStorei', 'Callback'),
-  ('WebGLRenderingContext', 'polygonOffset', 'Callback'),
-  ('WebGLRenderingContext', 'scissor', 'Callback'),
-  ('WebGLRenderingContext', 'stencilFunc', 'Callback'),
-  ('WebGLRenderingContext', 'stencilFuncSeparate', 'Callback'),
-  ('WebGLRenderingContext', 'stencilMask', 'Callback'),
-  ('WebGLRenderingContext', 'stencilMaskSeparate', 'Callback'),
-  ('WebGLRenderingContext', 'stencilOp', 'Callback'),
-  ('WebGLRenderingContext', 'stencilOpSeparate', 'Callback'),
-  ('WebGLRenderingContext', 'uniform1f', 'Callback'),
-  ('WebGLRenderingContext', 'uniform1fv', 'Callback'),
-  ('WebGLRenderingContext', 'uniform1i', 'Callback'),
-  ('WebGLRenderingContext', 'uniform1iv', 'Callback'),
-  ('WebGLRenderingContext', 'uniform2f', 'Callback'),
-  ('WebGLRenderingContext', 'uniform2fv', 'Callback'),
-  ('WebGLRenderingContext', 'uniform2i', 'Callback'),
-  ('WebGLRenderingContext', 'uniform2iv', 'Callback'),
-  ('WebGLRenderingContext', 'uniform3f', 'Callback'),
-  ('WebGLRenderingContext', 'uniform3fv', 'Callback'),
-  ('WebGLRenderingContext', 'uniform3i', 'Callback'),
-  ('WebGLRenderingContext', 'uniform3iv', 'Callback'),
-  ('WebGLRenderingContext', 'uniform4f', 'Callback'),
-  ('WebGLRenderingContext', 'uniform4fv', 'Callback'),
-  ('WebGLRenderingContext', 'uniform4i', 'Callback'),
-  ('WebGLRenderingContext', 'uniform4iv', 'Callback'),
-  ('WebGLRenderingContext', 'uniformMatrix2fv', 'Callback'),
-  ('WebGLRenderingContext', 'uniformMatrix3fv', 'Callback'),
-  ('WebGLRenderingContext', 'uniformMatrix4fv', 'Callback'),
-  ('WebGLRenderingContext', 'useProgram', 'Callback'),
-  ('WebGLRenderingContext', 'validateProgram', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttrib1f', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttrib1fv', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttrib2f', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttrib2fv', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttrib3f', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttrib3fv', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttrib4f', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttrib4fv', 'Callback'),
-  ('WebGLRenderingContext', 'vertexAttribPointer', 'Callback'),
-  ('WebGLRenderingContext', 'viewport', 'Callback'),
-])
 
 # TODO(vsm): This should be recoverable from IDL, but we appear to not
 # track the necessary info.
 _url_utils = ['hash', 'host', 'hostname', 'origin',
               'password', 'pathname', 'port', 'protocol',
               'search', 'username']
-_cpp_static_call_map = {
-  'DOMURL': _url_utils + ['href', 'toString'],
-  'HTMLAnchorElement': _url_utils,
-  'HTMLAreaElement': _url_utils,
-}
-
-def _GetCPPPartialNames(interface):
-  interface_name = interface.ext_attrs.get('ImplementedAs', interface.id)
-  if not _cpp_partial_map:
-    for (type, member) in _cpp_callback_map.keys():
-      if type not in _cpp_partial_map:
-        _cpp_partial_map[type] = set([])
-
-      name_with_path = _cpp_callback_map[(type, member)]
-      if name_with_path in _cpp_import_map:
-        name_with_path = _cpp_import_map[name_with_path]
-      _cpp_partial_map[type].add(name_with_path)
-
-    for (type, member) in _cpp_overloaded_callback_map.keys():
-      if type not in _cpp_partial_map:
-        _cpp_partial_map[type] = set([])
-      _cpp_partial_map[type].add(_cpp_overloaded_callback_map[(type, member)])
-
-  if interface_name in _cpp_partial_map:
-    return _cpp_partial_map[interface_name]
-  else:
-    return set([])
 
 def array_type(data_type):
     matched = re.match(r'([\w\d_\s]+)\[\]', data_type)
@@ -320,19 +45,6 @@
 
   return interface_id
 
-def _GetCPPTypeName(interface_name, callback_name, cpp_name):
-  # TODO(vsm): We need to track the original IDL file name in order to recover
-  # the proper CPP name.
-
-  cpp_tuple = (interface_name, callback_name)
-  if cpp_tuple in _cpp_callback_map:
-    cpp_type_name = _cpp_callback_map[cpp_tuple]
-  elif (interface_name, cpp_name) in _cpp_overloaded_callback_map:
-    cpp_type_name = _cpp_overloaded_callback_map[(interface_name, cpp_name)]
-  else:
-    cpp_type_name = interface_name
-  return cpp_type_name
-
 def DeriveQualifiedName(library_name, name):
     return library_name + "." + name
 
@@ -398,112 +110,7 @@
     return FindConversion(idl_type, 'set', self._interface.id, member)
 
   def GenerateCallback(self, info):
-    if IsPureInterface(self._interface.id) or IsCustomType(self._interface.id):
-      return
-
-    interface = self._interface
-    if interface.parents:
-      supertype = '%sClassId' % interface.parents[0].type.id
-    else:
-      supertype = '-1'
-
-    cpp_impl_includes = set(['"' + partial + '.h"'
-                             for partial in _GetCPPPartialNames(self._interface)])
-    cpp_header_handlers_emitter = emitter.Emitter()
-    cpp_impl_handlers_emitter = emitter.Emitter()
-    class_name = 'Dart%s' % self._interface.id
-    for operation in self._interface.operations:
-      function_name = operation.id
-      return_type = self.SecureOutputType(operation.type.id)
-      parameters = []
-      arguments = []
-      if operation.ext_attrs.get('CallWith') == 'ThisValue':
-        parameters.append('ScriptValue scriptValue')
-      conversion_includes = []
-      for argument in operation.arguments:
-        argument_type_info = self._TypeInfo(argument.type.id)
-        parameters.append('%s %s' % (argument_type_info.parameter_type(),
-                                     argument.id))
-        arguments.append(argument_type_info.to_dart_conversion(argument.id))
-        conversion_includes.extend(argument_type_info.conversion_includes())
-
-      # FIXME(vsm): Handle ThisValue attribute.
-      if (return_type == 'void'):
-        ret = ''
-      else:
-        ret = '        return 0;\n'
-
-      if operation.ext_attrs.get('CallWith') == 'ThisValue':
-        cpp_header_handlers_emitter.Emit(
-            '\n'
-            '    virtual $RETURN_TYPE $FUNCTION($PARAMETERS) {\n'
-            '        DART_UNIMPLEMENTED();\n'
-            '$RET'
-            '    }\n',
-            RETURN_TYPE=return_type,
-            RET=ret,
-            FUNCTION=function_name,
-            PARAMETERS=', '.join(parameters))
-        continue
-
-      cpp_header_handlers_emitter.Emit(
-          '\n'
-          '    virtual $RETURN_TYPE $FUNCTION($PARAMETERS);\n',
-          RETURN_TYPE=return_type,
-          FUNCTION=function_name,
-          PARAMETERS=', '.join(parameters))
-
-      if _IsCustom(operation):
-        continue
-
-      cpp_impl_includes |= set(conversion_includes)
-      arguments_declaration = 'Dart_Handle arguments[] = { %s }' % ', '.join(arguments)
-      if not len(arguments):
-        arguments_declaration = 'Dart_Handle* arguments = 0'
-      if (return_type == 'void'):
-        ret1 = 'return'
-        ret2 = ''
-      else:
-        ret1 = 'return 0'
-        ret2 = ' return'
-      cpp_impl_handlers_emitter.Emit(
-          '\n'
-          '$RETURN_TYPE $CLASS_NAME::$FUNCTION($PARAMETERS)\n'
-          '{\n'
-          '    if (!m_callback.isIsolateAlive())\n'
-          '        $RET1;\n'
-          '    DartIsolateScope scope(m_callback.isolate());\n'
-          '    DartApiScope apiScope;\n'
-          '    $ARGUMENTS_DECLARATION;\n'
-          '   $RET2 m_callback.handleEvent($ARGUMENT_COUNT, arguments);\n'
-          '}\n',
-          RETURN_TYPE=return_type,
-          RET1=ret1,
-          RET2=ret2,
-          CLASS_NAME=class_name,
-          FUNCTION=function_name,
-          PARAMETERS=', '.join(parameters),
-          ARGUMENTS_DECLARATION=arguments_declaration,
-          ARGUMENT_COUNT=len(arguments))
-
-    cpp_header_emitter = self._cpp_library_emitter.CreateHeaderEmitter(
-        self._interface.id,
-        self._renamer.GetLibraryName(self._interface),
-        True)
-    cpp_header_emitter.Emit(
-        self._template_loader.Load('cpp_callback_header.template'),
-        INTERFACE=self._interface.id,
-        HANDLERS=cpp_header_handlers_emitter.Fragments())
-
-    cpp_impl_emitter = self._cpp_library_emitter.CreateSourceEmitter(self._interface.id)
-    cpp_impl_emitter.Emit(
-        self._template_loader.Load('cpp_callback_implementation.template'),
-        INCLUDES=self._GenerateCPPIncludes(cpp_impl_includes),
-        INTERFACE=self._interface.id,
-        SUPER_INTERFACE=supertype,
-        HANDLERS=cpp_impl_handlers_emitter.Fragments(),
-        DART_IMPLEMENTATION_CLASS=self._interface_type_info.implementation_name(),
-        DART_IMPLEMENTATION_LIBRARY_ID='Dart%sLibraryId' % self._renamer.GetLibraryId(self._interface))
+    return None
 
   def ImplementationTemplate(self):
     template = None
@@ -588,10 +195,6 @@
 
     self._cpp_declarations_emitter = emitter.Emitter()
 
-    self._cpp_impl_includes = \
-      set(['"' + partial + '.h"'
-           for partial in _GetCPPPartialNames(self._interface)])
-
     # This is a hack to work around a strange C++ compile error that we weren't
     # able to track down the true cause of.
     if self._interface.id == 'Timing':
@@ -704,16 +307,6 @@
     if 'NamedConstructor' in ext_attrs:
       create_function = 'createForJSConstructor'
     function_expression = '%s::%s' % (self._interface_type_info.native_type(), create_function)
-    self._GenerateNativeCallback(
-        constructor_callback_cpp_name,
-        False,
-        function_expression,
-        self._interface,
-        arguments,
-        self._interface.id,
-        False,
-        'ConstructorRaisesException' in ext_attrs or 'RaisesException' in ext_attrs,
-        True)
 
   def HasSupportCheck(self):
     # Need to omit a support check if it is conditional in JS.
@@ -906,7 +499,7 @@
       self._AddSetter(attribute, html_name)
 
   def _GenerateAutoSetupScope(self, idl_name, native_suffix):
-    return (self._interface.id, idl_name, native_suffix) not in _cpp_no_auto_scope_list
+    return None
 
   def _AddGetter(self, attr, html_name, read_only):
     # Temporary hack to force dart:scalarlist clamped array for ImageData.data.
@@ -914,7 +507,14 @@
     if self._interface.id == 'ImageData' and html_name == 'data':
       html_name = '_data'
     type_info = self._TypeInfo(attr.type.id)
+
     return_type = self.SecureOutputType(attr.type.id, False, False if self._dart_use_blink else True)
+    dictionary_returned = False
+    # Return type for dictionary is any (untyped).
+    if attr.type.id == 'Dictionary':
+      return_type = '';
+      dictionary_returned = True;
+
     parameters = []
     dart_declaration = '%s get %s' % (return_type, html_name)
     is_custom = _IsCustom(attr) and (_IsCustomValue(attr, None) or
@@ -946,7 +546,7 @@
     cpp_callback_name = self._GenerateNativeBinding(attr.id, 1,
         dart_declaration, attr.is_static, return_type, parameters,
         native_suffix, is_custom, auto_scope_setup, native_entry=native_entry,
-        wrap_unwrap_list=wrap_unwrap_list)
+        wrap_unwrap_list=wrap_unwrap_list, dictionary_return=dictionary_returned)
     if is_custom:
       return
 
@@ -972,16 +572,6 @@
     function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, attr)
     raises = ('RaisesException' in attr.ext_attrs and
               attr.ext_attrs['RaisesException'] != 'Setter')
-    self._GenerateNativeCallback(
-        cpp_callback_name,
-        True,
-        function_expression,
-        attr,
-        [],
-        attr.type.id,
-        attr.type.nullable,
-        raises,
-        auto_scope_setup)
 
   def _AddSetter(self, attr, html_name):
     return_type = 'void'
@@ -1032,17 +622,6 @@
     function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, attr)
     raises = ('RaisesException' in attr.ext_attrs and
               attr.ext_attrs['RaisesException'] != 'Getter')
-    self._GenerateNativeCallback(
-        cpp_callback_name,
-        True,
-        function_expression,
-        attr,
-        [attr],
-        'void',
-        False,
-        raises,
-        auto_scope_setup,
-        generate_custom_element_scope_if_needed=True)
 
   def AddIndexer(self, element_type):
     """Adds all the methods required to complete implementation of List."""
@@ -1184,11 +763,28 @@
       dart_declaration, False, return_type, parameters,
       'Callback', True, False)
 
+  def _ChangePrivateOpMapArgToAny(self, operations):
+    # TODO(terry): Hack to map any operations marked as private to not
+    #              handle converting Map to native (JsObject) the public
+    #              members that call the private method will have done
+    #              conversions.
+    for operation in operations:
+      for arg in operation.arguments:
+        type = arg.type
+        if type.id == 'Dictionary':
+          type.id = 'any'
+
   def EmitOperation(self, info, html_name, dart_js_interop=False):
     """
     Arguments:
       info: An OperationInfo object.
     """
+    if self._renamer.isPrivate(self._interface, info.operations[0].id):
+      # Any private operations with Maps parameters changed to any type.
+      # The public method that delegates to this private operation has already
+      # converted from Map to native (JsObject) e.g., Element.animate.
+      self._ChangePrivateOpMapArgToAny(info.operations)
+
     return_type = self.SecureOutputType(info.type_name, False, False if dart_js_interop else True)
 
     formals = info.ParametersAsDeclaration(self._DartType)
@@ -1197,14 +793,21 @@
                                                   self._type_registry if self._dart_use_blink else None,
                                                   dart_js_interop,
                                                   self)
+
+    operation = info.operations[0]
+
+    dictionary_returned = False
+    # Return type for dictionary is any (untyped).
+    if operation.type.id == 'Dictionary':
+      return_type = '';
+      dictionary_returned = True;
+
     dart_declaration = '%s%s %s(%s)' % (
         'static ' if info.IsStatic() else '',
         return_type,
         html_name,
         formals)
 
-    operation = info.operations[0]
-
     is_custom = _IsCustom(operation)
     has_optional_arguments = any(IsOptional(argument) for argument in operation.arguments)
     needs_dispatcher = not is_custom and (len(info.operations) > 1 or has_optional_arguments)
@@ -1246,7 +849,8 @@
         info.IsStatic(), return_type, parameters,
         native_suffix, is_custom, auto_scope_setup,
         native_entry=native_entry,
-        wrap_unwrap_list=wrap_unwrap_list)
+        wrap_unwrap_list=wrap_unwrap_list,
+        dictionary_return=dictionary_returned)
       if not is_custom:
         self._GenerateOperationNativeCallback(operation, operation.arguments, cpp_callback_name, auto_scope_setup)
     else:
@@ -1317,392 +921,11 @@
     webcore_function_name = operation.ext_attrs.get('ImplementedAs', operation.id)
 
     function_expression = self._GenerateWebCoreFunctionExpression(webcore_function_name, operation, cpp_callback_name)
-    self._GenerateNativeCallback(
-        cpp_callback_name,
-        not operation.is_static,
-        function_expression,
-        operation,
-        arguments,
-        operation.type.id,
-        operation.type.nullable,
-        'RaisesException' in operation.ext_attrs,
-        auto_scope_setup,
-        generate_custom_element_scope_if_needed=True)
-
-  def _GenerateNativeCallback(self,
-      callback_name,
-      needs_receiver,
-      function_expression,
-      node,
-      arguments,
-      return_type,
-      return_type_is_nullable,
-      raises_dom_exception,
-      auto_scope_setup=True,
-      generate_custom_element_scope_if_needed=False):
-
-    ext_attrs = node.ext_attrs
-
-    if self._IsStatic(node.id):
-      needs_receiver = True
-
-    cpp_arguments = []
-    runtime_check = None
-    raises_exceptions = raises_dom_exception or arguments or needs_receiver
-    needs_custom_element_callbacks = False
-
-    # TODO(antonm): unify with ScriptState below.
-    call_with = ext_attrs.get('CallWith', [])
-    if not(isinstance(call_with, list)):
-      call_with = [call_with]
-    constructor_with = ext_attrs.get('ConstructorCallWith', [])
-    if not(isinstance(constructor_with, list)):
-      constructor_with = [constructor_with]
-    call_with = call_with + constructor_with
-
-
-    requires_stack_info = 'ScriptArguments' in call_with or 'ScriptState' in call_with
-    if requires_stack_info:
-      raises_exceptions = True
-      cpp_arguments = ['&state', 'scriptArguments.release()']
-      # WebKit uses scriptArguments to reconstruct last argument, so
-      # it's not needed and should be just removed.
-      arguments = arguments[:-1]
-
-    # TODO(antonm): unify with ScriptState below.
-    requires_script_arguments = (ext_attrs.get('CallWith') == 'ScriptArguments' or
-                                 ext_attrs.get('ConstructorCallWith') == 'ScriptArguments')
-    if requires_script_arguments:
-      raises_exceptions = True
-      cpp_arguments = ['scriptArguments.release()']
-      # WebKit uses scriptArguments to reconstruct last argument, so
-      # it's not needed and should be just removed.
-      arguments = arguments[:-1]
-
-    requires_script_execution_context = (ext_attrs.get('CallWith') == 'ExecutionContext' or
-                                         ext_attrs.get('ConstructorCallWith') == 'ExecutionContext')
-
-    # Hack because our parser misses that these IDL members require an execution
-    # context.
-
-    if (self._interface.id == 'FontFace'
-        and callback_name in ['familySetter', 'featureSettingsSetter', 'stretchSetter',
-                              'styleSetter', 'unicodeRangeSetter', 'variantSetter', 'weightSetter']):
-      requires_script_execution_context = True
-
-    requires_document = ext_attrs.get('ConstructorCallWith') == 'Document'
-
-    if requires_script_execution_context:
-      raises_exceptions = True
-      cpp_arguments = ['context']
-
-    requires_script_state = (ext_attrs.get('CallWith') == 'ScriptState' or
-                             ext_attrs.get('ConstructorCallWith') == 'ScriptState')
-    if requires_script_state:
-      raises_exceptions = True
-      cpp_arguments = ['&state']
-
-    requires_dom_window = 'NamedConstructor' in ext_attrs
-    if requires_dom_window or requires_document:
-      raises_exceptions = True
-      cpp_arguments = ['document']
-
-    if 'ImplementedBy' in ext_attrs:
-      assert needs_receiver
-      self._cpp_impl_includes.add('"%s.h"' % ext_attrs['ImplementedBy'])
-      cpp_arguments.append('receiver')
-
-    if 'Reflect' in ext_attrs:
-      cpp_arguments = [self._GenerateWebCoreReflectionAttributeName(node)]
-
-    if generate_custom_element_scope_if_needed and (ext_attrs.get('CustomElementCallbacks', 'None') != 'None' or 'Reflect' in ext_attrs):
-      self._cpp_impl_includes.add('"core/dom/custom/CustomElementCallbackDispatcher.h"')
-      needs_custom_element_callbacks = True
-
-    if return_type_is_nullable:
-      cpp_arguments = ['isNull']
-
-    v8EnabledPerContext = ext_attrs.get('synthesizedV8EnabledPerContext', ext_attrs.get('V8EnabledPerContext'))
-    v8EnabledAtRuntime = ext_attrs.get('synthesizedV8EnabledAtRuntime', ext_attrs.get('V8EnabledAtRuntime'))
-    assert(not (v8EnabledPerContext and v8EnabledAtRuntime))
-
-    if v8EnabledPerContext:
-      raises_exceptions = True
-      self._cpp_impl_includes.add('"ContextFeatures.h"')
-      self._cpp_impl_includes.add('"DOMWindow.h"')
-      runtime_check = emitter.Format(
-          '        if (!ContextFeatures::$(FEATURE)Enabled(DartUtilities::domWindowForCurrentIsolate()->document())) {\n'
-          '            exception = Dart_NewStringFromCString("Feature $FEATURE is not enabled");\n'
-          '            goto fail;\n'
-          '        }',
-          FEATURE=v8EnabledPerContext)
-
-    if v8EnabledAtRuntime:
-      raises_exceptions = True
-      self._cpp_impl_includes.add('"RuntimeEnabledFeatures.h"')
-      runtime_check = emitter.Format(
-          '        if (!RuntimeEnabledFeatures::$(FEATURE)Enabled()) {\n'
-          '            exception = Dart_NewStringFromCString("Feature $FEATURE is not enabled");\n'
-          '            goto fail;\n'
-          '        }',
-          FEATURE=self._ToWebKitName(v8EnabledAtRuntime))
-
-    body_emitter = self._cpp_definitions_emitter.Emit(
-        '\n'
-        'static void $CALLBACK_NAME(Dart_NativeArguments args)\n'
-        '{\n'
-        '$!BODY'
-        '}\n',
-        CALLBACK_NAME=callback_name)
-
-    if raises_exceptions:
-      body_emitter = body_emitter.Emit(
-          '    Dart_Handle exception = 0;\n'
-          '$!BODY'
-          '\n'
-          'fail:\n'
-          '    Dart_ThrowException(exception);\n'
-          '    ASSERT_NOT_REACHED();\n')
-
-    body_emitter = body_emitter.Emit(
-        '    {\n'
-        '$!BODY'
-        '        return;\n'
-        '    }\n')
-
-    if runtime_check:
-      body_emitter.Emit(
-          '$RUNTIME_CHECK\n',
-          RUNTIME_CHECK=runtime_check)
-
-    if requires_script_execution_context:
-      body_emitter.Emit(
-          '        ExecutionContext* context = DartUtilities::scriptExecutionContext();\n'
-          '        if (!context) {\n'
-          '            exception = Dart_NewStringFromCString("Failed to retrieve a context");\n'
-          '            goto fail;\n'
-          '        }\n\n')
-
-    if requires_script_state:
-      body_emitter.Emit(
-          '        ScriptState* currentState = DartUtilities::currentScriptState();\n'
-          '        if (!currentState) {\n'
-          '            exception = Dart_NewStringFromCString("Failed to retrieve a script state");\n'
-          '            goto fail;\n'
-          '        }\n'
-          '        ScriptState& state = *currentState;\n\n')
-
-    if requires_dom_window or requires_document:
-      self._cpp_impl_includes.add('"DOMWindow.h"')
-
-      body_emitter.Emit(
-          '        DOMWindow* domWindow = DartUtilities::domWindowForCurrentIsolate();\n'
-          '        if (!domWindow) {\n'
-          '            exception = Dart_NewStringFromCString("Failed to fetch domWindow");\n'
-          '            goto fail;\n'
-          '        }\n'
-          '        Document& document = *domWindow->document();\n')
-
-    if needs_receiver:
-      body_emitter.Emit(
-        '        $WEBCORE_CLASS_NAME* receiver = '
-        'DartDOMWrapper::receiverChecked<Dart$INTERFACE>(args, exception);\n'
-        '        if (exception)\n'
-        '            goto fail;\n',
-        WEBCORE_CLASS_NAME=self._interface_type_info.native_type(),
-        INTERFACE=self._interface.id)
-
-    if requires_stack_info:
-      self._cpp_impl_includes.add('"ScriptArguments.h"')
-      body_emitter.Emit(
-          '\n'
-          '        ScriptState* currentState = DartUtilities::currentScriptState();\n'
-          '        if (!currentState) {\n'
-          '            exception = Dart_NewStringFromCString("Failed to retrieve a script state");\n'
-          '            goto fail;\n'
-          '        }\n'
-          '        ScriptState& state = *currentState;\n'
-          '\n'
-          '        Dart_Handle customArgument = Dart_GetNativeArgument(args, $INDEX);\n'
-          '        RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArguments(customArgument, exception));\n'
-          '        if (!scriptArguments)\n'
-          '            goto fail;\n',
-          INDEX=len(arguments) + 1)
-
-    if requires_script_arguments:
-      self._cpp_impl_includes.add('"ScriptArguments.h"')
-      body_emitter.Emit(
-          '\n'
-          '        Dart_Handle customArgument = Dart_GetNativeArgument(args, $INDEX);\n'
-          '        RefPtr<ScriptArguments> scriptArguments(DartUtilities::createScriptArguments(customArgument, exception));\n'
-          '        if (!scriptArguments)\n'
-          '            goto fail;\n',
-          INDEX=len(arguments) + 1)
-
-    if needs_custom_element_callbacks:
-      body_emitter.Emit('        CustomElementCallbackDispatcher::CallbackDeliveryScope deliveryScope;\n');
-
-    # Emit arguments.
-    start_index = 1 if needs_receiver else 0
-    for i, argument in enumerate(arguments):
-      type_info = self._TypeInfo(argument.type.id)
-      self._cpp_impl_includes |= set(type_info.conversion_includes())
-      argument_expression_template, type, cls, function = \
-          type_info.to_native_info(argument, self._interface.id, callback_name)
-
-      def AllowsNull():
-        # TODO(vsm): HTMLSelectElement's indexed setter treats a null as a remove.
-        # We need to handle that.
-        # assert argument.ext_attrs.get('TreatNullAs', 'NullString') == 'NullString'
-        if argument.ext_attrs.get('TreatNullAs') == 'NullString':
-          return True
-
-        if argument.type.nullable:
-          return True
-
-        if isinstance(argument, IDLAttribute):
-          return (argument.type.id == 'DOMString') and \
-              ('Reflect' in argument.ext_attrs)
-
-        if isinstance(argument, IDLArgument):
-          if IsOptional(argument) and not self._IsArgumentOptionalInWebCore(node, argument):
-            return True
-          # argument default to null (e.g., DOMString arg = null).
-          if argument.default_value_is_null:
-            return True
-          if _IsOptionalStringArgumentInInitEventMethod(self._interface, node, argument):
-            return True
-
-        return False
-
-      if AllowsNull():
-        function += 'WithNullCheck'
-
-      argument_name = DartDomNameOfAttribute(argument)
-      if type_info.pass_native_by_ref():
-        invocation_template =\
-            '        $TYPE $ARGUMENT_NAME;\n'\
-            '        $CLS::$FUNCTION(args, $INDEX, $ARGUMENT_NAME, exception);\n'
-      else:
-        if not auto_scope_setup and type_info.native_type() == 'String':
-          invocation_template =\
-              '        $TYPE $ARGUMENT_NAME = $CLS::$FUNCTION(args, $INDEX, exception, false);\n'
-        else:
-          invocation_template =\
-              '        $TYPE $ARGUMENT_NAME = $CLS::$FUNCTION(args, $INDEX, exception);\n'
-      body_emitter.Emit(
-          '\n' +
-          invocation_template +
-          '        if (exception)\n'
-          '            goto fail;\n',
-          TYPE=type,
-          ARGUMENT_NAME=argument_name,
-          CLS=cls,
-          FUNCTION=function,
-          INDEX=start_index + i)
-      self._cpp_impl_includes.add('"%s.h"' % cls)
-      cpp_arguments.append(argument_expression_template % argument_name)
-
-    body_emitter.Emit('\n')
-
-    if 'NeedsUserGestureCheck' in ext_attrs:
-      cpp_arguments.append('DartUtilities::processingUserGesture')
-
-    invocation_emitter = body_emitter
-    if raises_dom_exception:
-      cpp_arguments.append('es')
-      invocation_emitter = body_emitter.Emit(
-        '        DartExceptionState es;\n'
-        '$!INVOCATION'
-        '        if (es.hadException()) {\n'
-        '            exception = DartDOMWrapper::exceptionCodeToDartException(es);\n'
-        '            goto fail;\n'
-        '        }\n')
-
-
-    interface_name = self._interface_type_info.native_type()
-
-    if needs_receiver:
-      # Hack to determine if this came from the _cpp_callback_map.
-      # In this case, the getter is mapped to a static method.
-      if function_expression.startswith('SVGTests::'):
-          cpp_arguments.insert(0, 'receiver')
-      elif (not function_expression.startswith('receiver->') and
-          not function_expression.startswith(interface_name + '::')):
-        if (interface_name in ['DOMWindow', 'Element', 'Navigator', 'WorkerGlobalScope']
-            or (interface_name in ['SVGViewSpec', 'SVGViewElement', 'SVGSVGElement']
-              and callback_name in ['setZoomAndPan', 'zoomAndPanSetter', 'zoomAndPan'])
-            or (interface_name == 'Screen'
-              and callback_name in ['_lockOrientation_1Callback', '_lockOrientation_2Callback', 'unlockOrientation', 'orientation'])):
-          cpp_arguments.insert(0, 'receiver')
-        else:
-          cpp_arguments.append('receiver')
-      elif self._IsStatic(node.id):
-        cpp_arguments.insert(0, 'receiver')
-
-    if interface_name in ['SVGPropertyTearOff<SVGTransform>', 'SVGPropertyTearOff<SVGAngle>', 'SVGMatrixTearOff'] and function_expression.startswith('receiver->'):
-      # This is a horrible hack. I don't know why this one case has to be
-      # special cased.
-      if not (self._interface.id == 'SVGTransformList' and callback_name == 'createSVGTransformFromMatrixCallback'):
-        function_expression = 'receiver->propertyReference().%s' % (function_expression[len('receiver->'):])
-
-    function_call = '%s(%s)' % (function_expression, ', '.join(cpp_arguments))
-    if return_type == 'void':
-      invocation_emitter.Emit(
-        '        $FUNCTION_CALL;\n',
-        FUNCTION_CALL=function_call)
-    else:
-      return_type_info = self._TypeInfo(return_type)
-      self._cpp_impl_includes |= set(return_type_info.conversion_includes())
-
-      if return_type_is_nullable:
-        invocation_emitter.Emit(
-          '        bool isNull = false;\n'
-          '        $NATIVE_TYPE result = $FUNCTION_CALL;\n'
-          '        if (isNull)\n'
-          '            return;\n',
-          NATIVE_TYPE=return_type_info.parameter_type(),
-          FUNCTION_CALL=function_call)
-        value_expression = 'result'
-      else:
-        value_expression = function_call
-
-      # Generate to Dart conversion of C++ value.
-      if return_type_info.dart_type() == 'bool':
-        set_return_value = 'Dart_SetBooleanReturnValue(args, %s)' % (value_expression)
-      elif return_type_info.dart_type() == 'int':
-        if return_type_info.native_type() == 'unsigned':
-          set_return_value = 'DartUtilities::setDartUnsignedReturnValue(args, %s)' % (value_expression)
-        elif return_type_info.native_type() == 'unsigned long long':
-          set_return_value = 'DartUtilities::setDartUnsignedLongLongReturnValue(args, %s)' % (value_expression)
-        else:
-          assert (return_type_info.native_type() == 'int' or return_type_info.native_type() == 'long long')
-          set_return_value = 'DartUtilities::setDartIntegerReturnValue(args, %s)' % (value_expression)
-      elif return_type_info.dart_type() == 'double':
-        set_return_value = 'Dart_SetDoubleReturnValue(args, %s)' % (value_expression)
-      elif return_type_info.dart_type() == 'String':
-        auto_dart_scope='true' if auto_scope_setup else 'false'
-        if ext_attrs and 'TreatReturnedNullStringAs' in ext_attrs:
-          set_return_value = 'DartUtilities::setDartStringReturnValueWithNullCheck(args, %s, %s)' % (value_expression, auto_dart_scope)
-        else:
-          set_return_value = 'DartUtilities::setDartStringReturnValue(args, %s, %s)' % (value_expression, auto_dart_scope)
-      elif return_type_info.dart_type() == 'num' and return_type_info.native_type() == 'double':
-        set_return_value = 'Dart_SetDoubleReturnValue(args, %s)' % (value_expression)
-      else:
-        return_to_dart_conversion = return_type_info.return_to_dart_conversion(
-            value_expression,
-            auto_scope_setup,
-            self._interface.id,
-            ext_attrs)
-        set_return_value = '%s' % (return_to_dart_conversion)
-      invocation_emitter.Emit(
-        '        $RETURN_VALUE;\n',
-        RETURN_VALUE=set_return_value)
 
   def _GenerateNativeBinding(self, idl_name, argument_count, dart_declaration,
       static, return_type, parameters, native_suffix, is_custom,
       auto_scope_setup=True, emit_metadata=True, emit_to_native=False,
-      native_entry=None, wrap_unwrap_list=[]):
+      native_entry=None, wrap_unwrap_list=[], dictionary_return=False):
     metadata = []
     if emit_metadata:
       metadata = self._metadata.GetFormattedMetadata(
@@ -1745,14 +968,19 @@
   $METADATA$DART_DECLARATION => $DART_NAME($ACTUALS);
   '''
             if wrap_unwrap_list and wrap_unwrap_list[0]:
-                emit_jso_template = '''
-  $METADATA$DART_DECLARATION => %s($DART_NAME($ACTUALS));
-  '''
                 if return_type == 'Rectangle':
                     jso_util_method = 'make_dart_rectangle'
                 elif wrap_unwrap_list[0]:
                     jso_util_method = 'wrap_jso'
 
+                if dictionary_return:
+                  emit_jso_template = '''
+  $METADATA$DART_DECLARATION => convertNativeDictionaryToDartDictionary(%s($DART_NAME($ACTUALS)));
+  '''
+                else:
+                  emit_jso_template = '''
+  $METADATA$DART_DECLARATION => %s($DART_NAME($ACTUALS));
+  '''
                 emit_template = emit_jso_template % jso_util_method
 
             if caller_emitter:
@@ -1795,22 +1023,10 @@
     return 'WebCore::%s::%sAttr' % (namespace, attribute_name)
 
   def _IsStatic(self, attribute_name):
-    cpp_type_name = self._interface_type_info.native_type()
-    if cpp_type_name in _cpp_static_call_map:
-      return attribute_name in _cpp_static_call_map[cpp_type_name]
     return False
 
   def _GenerateWebCoreFunctionExpression(self, function_name, idl_node, cpp_callback_name=None):
-    if 'ImplementedBy' in idl_node.ext_attrs:
-      return '%s::%s' % (idl_node.ext_attrs['ImplementedBy'], function_name)
-    cpp_type_name = self._interface_type_info.native_type()
-    impl_type_name = _GetCPPTypeName(cpp_type_name, function_name, cpp_callback_name)
-    if idl_node.is_static or self._IsStatic(idl_node.id):
-      return '%s::%s' % (impl_type_name, function_name)
-    if cpp_type_name == impl_type_name:
-      return '%s%s' % (self._interface_type_info.receiver(), function_name)
-    else:
-      return '%s::%s' % (impl_type_name, function_name)
+    return None
 
   def _IsArgumentOptionalInWebCore(self, operation, argument):
     if not IsOptional(argument):
@@ -1826,7 +1042,7 @@
     return True
 
   def _GenerateCPPIncludes(self, includes):
-    return ''.join(['#include %s\n' % include for include in sorted(includes)])
+    return None
 
   def _ToWebKitName(self, name):
     name = name[0].lower() + name[1:]
diff --git a/tools/dom/src/native_DOMImplementation.dart b/tools/dom/src/native_DOMImplementation.dart
index b624dd0..2aad83f 100644
--- a/tools/dom/src/native_DOMImplementation.dart
+++ b/tools/dom/src/native_DOMImplementation.dart
@@ -197,7 +197,7 @@
 
   // TODO(vsm): Make this API compatible with spawnUri.  It should also
   // return a Future<Isolate>.
-  static spawnDomUri(String uri) => _blink.Blink_Utils.spawnDomUri(uri);
+  static spawnDomUri(String uri) => wrap_jso(_blink.Blink_Utils.spawnDomUri(uri));
 
   // The following methods were added for debugger integration to make working
   // with the Dart C mirrors API simpler.
@@ -807,10 +807,10 @@
     String extendsTagName) => _blink.Blink_Utils.register(unwrap_jso(document), tag, customType, extendsTagName);
 
   static Element createElement(Document document, String tagName) =>
-    wrap_jso(_blink.Blink_Utils.createElement(unwrap_jso(document), tagName));
+      wrap_jso(_blink.Blink_Utils.createElement(unwrap_jso(document), tagName));
 
   static Element changeElementWrapper(HtmlElement element, Type type) =>
-    _blink.Blink_Utils.changeElementWrapper(unwrap_jso(element), type);
+      wrap_jso(_blink.Blink_Utils.changeElementWrapper(unwrap_jso(element), type));
 }
 
 class _DOMWindowCrossFrame extends DartHtmlDomObject implements
@@ -825,17 +825,18 @@
   _DOMWindowCrossFrame.internal();
 
   // Fields.
-  HistoryBase get history => _blink.Blink_DOMWindowCrossFrame.get_history(this);
-  LocationBase get location => _blink.Blink_DOMWindowCrossFrame.get_location(this);
-  bool get closed => _blink.Blink_DOMWindowCrossFrame.get_closed(this);
-  WindowBase get opener => _blink.Blink_DOMWindowCrossFrame.get_opener(this);
-  WindowBase get parent => _blink.Blink_DOMWindowCrossFrame.get_parent(this);
-  WindowBase get top => _blink.Blink_DOMWindowCrossFrame.get_top(this);
+  HistoryBase get history => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_history(unwrap_jso(this)));
+  LocationBase get location => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_location(unwrap_jso(this)));
+  bool get closed => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_closed(unwrap_jso(this)));
+  WindowBase get opener => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_opener(unwrap_jso(this)));
+  WindowBase get parent => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_parent(unwrap_jso(this)));
+  WindowBase get top => wrap_jso(_blink.Blink_DOMWindowCrossFrame.get_top(unwrap_jso(this)));
 
   // Methods.
-  void close() => _blink.Blink_DOMWindowCrossFrame.close(this);
+  void close() => _blink.Blink_DOMWindowCrossFrame.close(unwrap_jso(this));
   void postMessage(/*SerializedScriptValue*/ message, String targetOrigin, [List messagePorts]) =>
-    _blink.Blink_DOMWindowCrossFrame.postMessage(this, message, targetOrigin, messagePorts);
+      _blink.Blink_DOMWindowCrossFrame.postMessage(unwrap_jso(this),
+         convertDartToNative_SerializedScriptValue(message), targetOrigin, messagePorts);
 
   // Implementation support.
   String get typeName => "Window";
@@ -868,9 +869,9 @@
   _HistoryCrossFrame.internal();
 
   // Methods.
-  void back() => _blink.Blink_HistoryCrossFrame.back(this);
-  void forward() => _blink.Blink_HistoryCrossFrame.forward(this);
-  void go(int distance) => _blink.Blink_HistoryCrossFrame.go(this, distance);
+  void back() => _blink.Blink_HistoryCrossFrame.back(unwrap_jso(this));
+  void forward() => _blink.Blink_HistoryCrossFrame.forward(unwrap_jso(this));
+  void go(int distance) => _blink.Blink_HistoryCrossFrame.go(unwrap_jso(this), distance);
 
   // Implementation support.
   String get typeName => "History";
@@ -880,33 +881,12 @@
   _LocationCrossFrame.internal();
 
   // Fields.
-  set href(String h) => _blink.Blink_LocationCrossFrame.set_href(this, h);
+  set href(String h) => _blink.Blink_LocationCrossFrame.set_href(unwrap_jso(this), h);
 
   // Implementation support.
   String get typeName => "Location";
 }
 
-class _DOMStringMap extends DartHtmlDomObject implements Map<String, String> {
-  _DOMStringMap.internal();
-
-  bool containsValue(String value) => Maps.containsValue(this, value);
-  bool containsKey(String key) => _blink.Blink_DOMStringMap.containsKey(this, key);
-  String operator [](String key) => _blink.Blink_DOMStringMap.item(this, key);
-  void operator []=(String key, String value) => _blink.Blink_DOMStringMap.setItem(this, key, value);
-  String putIfAbsent(String key, String ifAbsent()) => Maps.putIfAbsent(this, key, ifAbsent);
-  String remove(String key) => _blink.Blink_DOMStringMap.remove(this, key);
-  void clear() => Maps.clear(this);
-  void forEach(void f(String key, String value)) => Maps.forEach(this, f);
-  Iterable<String> get keys => _blink.Blink_DOMStringMap.get_keys(this);
-  Iterable<String> get values => Maps.getValues(this);
-  int get length => Maps.length(this);
-  bool get isEmpty => Maps.isEmpty(this);
-  bool get isNotEmpty => Maps.isNotEmpty(this);
-  void addAll(Map<String, String> other) {
-    other.forEach((key, value) => this[key] = value);
-  }
-}
-
 // TODO(vsm): Remove DOM isolate code once we have Dartium isolates
 // as workers.  This is only used to support
 // printing and timers in background isolates. As workers they should
diff --git a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
index 2de24a0..fb00675 100644
--- a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
@@ -19,7 +19,8 @@
 import 'dart:_internal';
 import 'dart:html';
 import 'dart:html_common';
-import 'dart:_js_helper' show convertDartClosureToJS, Creates, JSName, Native;
+import 'dart:_js_helper' show convertDartClosureToJS, Creates, JSName, Native,
+    JavaScriptIndexingBehavior;
 import 'dart:_foreign_helper' show JS;
 import 'dart:_interceptors' show Interceptor;
 
diff --git a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
index bd70659..9173eff 100644
--- a/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
+++ b/tools/dom/templates/html/impl/impl_CanvasRenderingContext2D.darttemplate
@@ -59,6 +59,14 @@
 $endif
   }
 
+  @DomName('CanvasRenderingContext2D.createPatternFromImage')
+  CanvasPattern createPatternFromImage(ImageElement image, String repetitionType) =>
+$if DART2JS
+    JS('CanvasPattern', '#.createPattern(#, #)', this, image, repetitionType);
+$else
+    createPattern(image, repetitionType);
+$endif
+
   /**
    * Draws an image from a CanvasImageSource to an area of this canvas.
    *
diff --git a/tools/dom/templates/html/impl/impl_Element.darttemplate b/tools/dom/templates/html/impl/impl_Element.darttemplate
index 03539f5..a4ddc94 100644
--- a/tools/dom/templates/html/impl/impl_Element.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Element.darttemplate
@@ -796,7 +796,7 @@
    * on which the method is called, and calls the play() method of the
    * AnimationTimeline object of the document timeline of the node document
    * of the element, passing the newly created AnimationEffect as the argument
-   * to the method. Returns an AnimationPlayer for the effect.
+   * to the method. Returns an Animation for the effect.
    *
    * Examples
    *
@@ -815,7 +815,7 @@
   **/
   @Experimental()
   @SupportedBrowser(SupportedBrowser.CHROME, '36')
-  AnimationPlayer animate(Iterable<Map<String, dynamic>> frames, [timing]) {
+  Animation animate(Iterable<Map<String, dynamic>> frames, [timing]) {
     if (frames is! Iterable || !(frames.every((x) => x is Map))) {
       throw new ArgumentError("The frames parameter should be a List of Maps "
           "with frame information");
@@ -842,7 +842,7 @@
   @DomName('Element.animate')
   @JSName('animate')
   @Experimental() // untriaged
-  AnimationPlayer _animate(Object effect, [timing]) native;
+  Animation _animate(Object effect, [timing]) native;
 $endif
   /**
    * Called by the DOM whenever an attribute on this has been changed.
@@ -1520,6 +1520,10 @@
   }
 
 $if DART2JS
+  @DomName('Element.offsetParent')
+  @DocsEditable()
+  final Element offsetParent;
+
   @DomName('Element.offsetHeight')
   @DocsEditable()
   int get offsetHeight => JS('num', '#.offsetHeight', this).round();
@@ -1581,42 +1585,29 @@
   int get scrollWidth => JS('num', '#.scrollWidth', this).round();
 
 $else
-  $if JSINTEROP
   // Need to explicitly delegate because Element is no longer abstract for Dartium.
   bool get isContentEditable => _blink.BlinkHTMLElement.instance.isContentEditable_Getter_(unwrap_jso(this));
   void click() => _blink.BlinkHTMLElement.instance.click_Callback_0_(unwrap_jso(this));
 
+  @DomName('Element.offsetParent')
+  @DocsEditable()
+  Element get offsetParent => wrap_jso(_blink.BlinkElement.instance.offsetParent_Getter_(unwrap_jso(this)));
+
   @DomName('Element.offsetHeight')
   @DocsEditable()
-  int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(unwrap_jso(this)).round();
+  int get offsetHeight => _blink.BlinkElement.instance.offsetHeight_Getter_(unwrap_jso(this));
 
   @DomName('Element.offsetLeft')
   @DocsEditable()
-  int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(unwrap_jso(this)).round();
+  int get offsetLeft => _blink.BlinkElement.instance.offsetLeft_Getter_(unwrap_jso(this));
 
   @DomName('Element.offsetTop')
   @DocsEditable()
-  int get offsetTop => _blink.BlinkElement.instance.offsetTop_Getter_(unwrap_jso(this)).round();
+  int get offsetTop => _blink.BlinkElement.instance.offsetTop_Getter_(unwrap_jso(this));
 
   @DomName('Element.offsetWidth')
   @DocsEditable()
-  int get offsetWidth => _blink.BlinkElement.instance.offsetWidth_Getter_(unwrap_jso(this)).round();
-
-  @DomName('Element.clientHeight')
-  @DocsEditable()
-  int get clientHeight => _blink.BlinkElement.instance.clientHeight_Getter_(unwrap_jso(this)).round();
-
-  @DomName('Element.clientLeft')
-  @DocsEditable()
-  int get clientLeft => _blink.BlinkElement.instance.clientLeft_Getter_(unwrap_jso(this)).round();
-
-  @DomName('Element.clientTop')
-  @DocsEditable()
-  int get clientTop => _blink.BlinkElement.instance.clientTop_Getter_(unwrap_jso(this)).round();
-
-  @DomName('Element.clientWidth')
-  @DocsEditable()
-  int get clientWidth => _blink.BlinkElement.instance.clientWidth_Getter_(unwrap_jso(this)).round();
+  int get offsetWidth => _blink.BlinkElement.instance.offsetWidth_Getter_(unwrap_jso(this));
 
   @DomName('Element.scrollHeight')
   @DocsEditable()
@@ -1641,63 +1632,6 @@
   @DomName('Element.scrollWidth')
   @DocsEditable()
   int get scrollWidth => _blink.BlinkElement.instance.scrollWidth_Getter_(unwrap_jso(this)).round();
-  $else
-  @DomName('Element.offsetHeight')
-  @DocsEditable()
-  int get offsetHeight => _blink.BlinkElement.offsetHeight_Getter(this).round();
-
-  @DomName('Element.offsetLeft')
-  @DocsEditable()
-  int get offsetLeft => _blink.BlinkElement.offsetLeft_Getter(this).round();
-
-  @DomName('Element.offsetTop')
-  @DocsEditable()
-  int get offsetTop => _blink.BlinkElement.offsetTop_Getter(this).round();
-
-  @DomName('Element.offsetWidth')
-  @DocsEditable()
-  int get offsetWidth => _blink.BlinkElement.offsetWidth_Getter(this).round();
-
-  @DomName('Element.clientHeight')
-  @DocsEditable()
-  int get clientHeight => _blink.BlinkElement.clientHeight_Getter(this).round();
-
-  @DomName('Element.clientLeft')
-  @DocsEditable()
-  int get clientLeft => _blink.BlinkElement.clientLeft_Getter(this).round();
-
-  @DomName('Element.clientTop')
-  @DocsEditable()
-  int get clientTop => _blink.BlinkElement.clientTop_Getter(this).round();
-
-  @DomName('Element.clientWidth')
-  @DocsEditable()
-  int get clientWidth => _blink.BlinkElement.clientWidth_Getter(this).round();
-
-  @DomName('Element.scrollHeight')
-  @DocsEditable()
-  int get scrollHeight => _blink.BlinkElement.scrollHeight_Getter(this).round();
-
-  @DomName('Element.scrollLeft')
-  @DocsEditable()
-  int get scrollLeft => _blink.BlinkElement.scrollLeft_Getter(this).round();
-
-  @DomName('Element.scrollLeft')
-  @DocsEditable()
-  set scrollLeft(int value) => _blink.BlinkElement.scrollLeft_Setter(this, value.round());
-
-  @DomName('Element.scrollTop')
-  @DocsEditable()
-  int get scrollTop => _blink.BlinkElement.scrollTop_Getter(this).round();
-
-  @DomName('Element.scrollTop')
-  @DocsEditable()
-  set scrollTop(int value) => _blink.BlinkElement.scrollTop_Setter(this, value.round());
-
-  @DomName('Element.scrollWidth')
-  @DocsEditable()
-  int get scrollWidth => _blink.BlinkElement.scrollWidth_Getter(this).round();
-  $endif
 $endif
 
 $!MEMBERS
diff --git a/tools/dom/templates/html/impl/impl_Window.darttemplate b/tools/dom/templates/html/impl/impl_Window.darttemplate
index d891762..0b64409 100644
--- a/tools/dom/templates/html/impl/impl_Window.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Window.darttemplate
@@ -113,7 +113,7 @@
    * for the animation to continue.
    */
   @DomName('Window.requestAnimationFrame')
-  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
+  int requestAnimationFrame(FrameRequestCallback callback) {
     _ensureRequestAnimationFrame();
     return _requestAnimationFrame(_wrapZone(callback));
   }
@@ -132,7 +132,7 @@
   }
 
   @JSName('requestAnimationFrame')
-  int _requestAnimationFrame(RequestAnimationFrameCallback callback) native;
+  int _requestAnimationFrame(FrameRequestCallback callback) native;
 
   @JSName('cancelAnimationFrame')
   void _cancelAnimationFrame(int id) native;
@@ -200,7 +200,7 @@
    * for the animation to continue.
    */
   @DomName('Window.requestAnimationFrame')
-  int requestAnimationFrame(RequestAnimationFrameCallback callback) {
+  int requestAnimationFrame(FrameRequestCallback callback) {
     return _requestAnimationFrame(_wrapZone(callback));
   }
 $endif
diff --git a/tools/utils.py b/tools/utils.py
index 69d6a39..6965a1c 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -529,6 +529,7 @@
   print "GuessVisualStudioPath() -> ", GuessVisualStudioPath()
   print "GetGitRevision() -> ", GetGitRevision()
   print "GetVersionFileContent() -> ", GetVersionFileContent()
+  print "GetGitNumber() -> ", GetGitNumber()
 
 class Error(Exception):
   pass
diff --git a/utils/dartanalyzer/dartanalyzer.gyp b/utils/dartanalyzer/dartanalyzer.gyp
index 9617f05..74dbf43 100644
--- a/utils/dartanalyzer/dartanalyzer.gyp
+++ b/utils/dartanalyzer/dartanalyzer.gyp
@@ -30,6 +30,25 @@
             '../../pkg/analyzer_cli/bin/analyzer.dart',
           ],
         },
+        {
+          'action_name': 'generate_summaries',
+          'inputs': [
+            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+            '../../sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart',
+            '<(SHARED_INTERMEDIATE_DIR)/packages.stamp',
+            '<!@(["python", "../../tools/list_files.py", "\\.dart$", "../../pkg/analyzer"])',
+          ],
+          'outputs': [
+            '<(SHARED_INTERMEDIATE_DIR)/spec.sum',
+            '<(SHARED_INTERMEDIATE_DIR)/strong.sum',
+          ],
+          'action': [
+            '<(PRODUCT_DIR)/<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
+            '--package-root=<(PRODUCT_DIR)/packages/',
+            '../../pkg/analyzer/tool/summary/build_sdk_summaries.dart',
+            '<(SHARED_INTERMEDIATE_DIR)',
+          ],
+        },
       ],
     },
   ],