Version 2.0.0-dev.19.0

Merge commit '1065b683888b4578caa435a5b45f4095b9afbe64' into dev
diff --git a/BUILD.gn b/BUILD.gn
index e621934..3f93c69 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -4,9 +4,11 @@
 
 import("build/dart_host_sdk_toolchain.gni")
 
+targetting_fuchsia = target_os == "fuchsia"
+
 # This target will be built if no target is specified when invoking ninja.
 group("default") {
-  if (is_fuchsia || is_fuchsia_host) {
+  if (targetting_fuchsia) {
     # Fuchsia has run_vm_tests marked testonly.
     testonly = true
   }
@@ -16,7 +18,7 @@
 }
 
 group("most") {
-  if (is_fuchsia || is_fuchsia_host) {
+  if (targetting_fuchsia) {
     # Fuchsia has run_vm_tests marked testonly.
     testonly = true
   }
@@ -32,7 +34,7 @@
 }
 
 group("runtime") {
-  if (is_fuchsia || is_fuchsia_host) {
+  if (targetting_fuchsia) {
     # Fuchsia has run_vm_tests marked testonly.
     testonly = true
   }
@@ -47,7 +49,7 @@
 }
 
 group("runtime_kernel") {
-  if (is_fuchsia || is_fuchsia_host) {
+  if (targetting_fuchsia) {
     # Fuchsia has run_vm_tests marked testonly.
     testonly = true
   }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ad5a4f0..16177c9 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -18,6 +18,10 @@
     some breaking API changes. See https://goo.gl/y9mW2x for more information.
   * Renamed `Zone.ROOT` to `Zone.root`.
 
+* `dart:cli`
+  * Added function `waitFor` that suspends a stack to wait for a `Future` to
+    complete.
+
 * `dart:core`
   * The `Uri` class now correctly handles paths while running on Node.js on
     Windows.
@@ -167,6 +171,11 @@
   configure the number of dartdevc/analyzer workers that are used when compiling
   with `--web-compiler=dartdevc`.
 
+* The Flutter `sdk` source will now look for packages in
+  `flutter/bin/cache/pkg/` as well as `flutter/packages/`. In particular, this
+  means that packages can depend on the `sky_engine` package from the `sdk`
+  source ([issue 1775][pub#1775]).
+
 * Pub will now automatically retry HTTP requests that fail with a 502, 503, of
   504 error code ([issue 1556][pub#1556]).
 
@@ -178,6 +187,7 @@
 [pub#1556]: https://github.com/dart-lang/pub/issues/1556
 [pub#1747]: https://github.com/dart-lang/pub/issues/1747
 [pub#1769]: https://github.com/dart-lang/pub/issues/1769
+[pub#1775]: https://github.com/dart-lang/pub/issues/1775
 
 ##### Bug Fixes
 
diff --git a/DEPS b/DEPS
index 46b2c54..ce9dfaa 100644
--- a/DEPS
+++ b/DEPS
@@ -55,7 +55,7 @@
   "barback-0.14.0_rev": "@36398",
   "barback-0.14.1_rev": "@38525",
   "barback_tag" : "@0.15.2+14",
-  "bazel_worker_tag": "@v0.1.4",
+  "bazel_worker_tag": "@v0.1.9",
   "boolean_selector_tag" : "@1.0.2",
   "boringssl_gen_rev": "@d2b56d1b7657e52eb5a1f075968c773aa3e53614",
   "boringssl_rev" : "@d519bf6be0b447fb80fbc539d4bff4479b5482a2",
@@ -82,7 +82,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_tag": "@1.0.9",  # Please see the note above before updating.
 
-  "dartdoc_tag" : "@v0.15.0+1",
+  "dartdoc_tag" : "@v0.15.1",
   "fixnum_tag": "@0.10.5",
   "func_rev": "@25eec48146a58967d75330075ab376b3838b18a8",
   "glob_tag": "@1.1.5",
@@ -108,12 +108,12 @@
   "observatory_pub_packages_rev": "@4c282bb240b68f407c8c7779a65c68eeb0139dc6",
   "package_config_tag": "@1.0.3",
   "package_resolver_tag": "@1.0.2+1",
-  "path_tag": "@1.4.2",
+  "path_tag": "@1.5.1",
   "plugin_tag": "@0.2.0+2",
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "@1.3.4",
-  "protobuf_tag": "@0.6.0",
-  "pub_rev": "@ca0d52f5d4058e7b9ef7b5091e407ff3ac05198d",
+  "protobuf_tag": "@0.7.0",
+  "pub_rev": "@64c5f40adf6828da1b63320dd39bcedbef1354c6",
   "pub_semver_tag": "@1.3.2",
   "quiver_tag": "@0.27.0",
   "resource_rev":"@af5a5bf65511943398146cf146e466e5f0b95cb9",
diff --git a/build/config/BUILDCONFIG.gn b/build/config/BUILDCONFIG.gn
index 4dfbaf6..ff7b42f 100644
--- a/build/config/BUILDCONFIG.gn
+++ b/build/config/BUILDCONFIG.gn
@@ -154,7 +154,6 @@
   is_android = false
   is_chromeos = false
   is_fuchsia = false
-  is_fuchsia_host = false
   is_ios = false
   is_linux = false
   is_mac = false
@@ -165,7 +164,6 @@
   is_android = false
   is_chromeos = false
   is_fuchsia = false
-  is_fuchsia_host = false
   is_ios = false
   is_linux = false
   is_mac = true
@@ -176,7 +174,6 @@
   is_android = true
   is_chromeos = false
   is_fuchsia = false
-  is_fuchsia_host = false
   is_ios = false
   is_linux = false
   is_mac = false
@@ -187,7 +184,6 @@
   is_android = false
   is_chromeos = false
   is_fuchsia = false
-  is_fuchsia_host = false
   is_ios = false
   is_linux = true
   is_mac = false
@@ -252,9 +248,7 @@
 }
 
 if (is_clang) {
-  _native_compiler_configs += [
-    "//build/config/clang:extra_warnings",
-  ]
+  _native_compiler_configs += [ "//build/config/clang:extra_warnings" ]
 }
 
 # Optimizations and debug checking.
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 5a92034..451bee0 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -7,7 +7,7 @@
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
   analyzer: ^0.30.0
-  args: '>=0.13.0 <0.14.0'
+  args: '>=0.13.0 <2.0.0'
   dart_style: '^1.0.6'
   intl: ^0.15.0
   isolate: '>=0.2.2 <2.0.0'
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 883a143..19df163 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -299,7 +299,6 @@
   HintCode.UNUSED_IMPORT,
   HintCode.UNUSED_LOCAL_VARIABLE,
   HintCode.UNUSED_SHOWN_NAME,
-  HintCode.USES_DYNAMIC_AS_BOTTOM,
   HintCode.USE_OF_VOID_RESULT,
   HintCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD,
   HtmlErrorCode.PARSE_ERROR,
@@ -669,6 +668,7 @@
   StrongModeCode.TOP_LEVEL_INSTANCE_GETTER,
   StrongModeCode.TOP_LEVEL_TYPE_ARGUMENTS,
   StrongModeCode.TOP_LEVEL_UNSUPPORTED,
+  StrongModeCode.USES_DYNAMIC_AS_BOTTOM,
   TodoCode.TODO,
 ];
 
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index d1a4712..c2315b3 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -2250,7 +2250,7 @@
   ConstructorElementImpl.forKernel(ClassElementImpl enclosingClass,
       this._kernelConstructor, this._kernelFactory)
       : super.forKernel(enclosingClass, _kernelConstructor ?? _kernelFactory) {
-    isSynthetic = _kernelConstructor?.isSyntheticDefault ?? false;
+    isSynthetic = _kernelConstructor?.isSynthetic ?? false;
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index eb7771a..54ad677 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -38,18 +38,6 @@
       "The argument type '{0}' can't be assigned to the parameter type '{1}'.");
 
   /**
-   * This hint is generated when a function type is assigned to a function
-   * typed location, and the assignment will be invalid after fuzzy arrows
-   * (the treatment of dynamic as bottom in certain locations) is removed.
-   *
-   */
-  static const HintCode USES_DYNAMIC_AS_BOTTOM = const HintCode(
-      'USES_DYNAMIC_AS_BOTTOM',
-      "A function of type '{0}' can't be assigned to a variable of type '{1}'.",
-      "Try changing the type of the function, or "
-      "casting the right-hand type to '{1}'.");
-
-  /**
    * When the target expression uses '?.' operator, it can be `null`, so all the
    * subsequent invocations should also use '?.' operator.
    */
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 56e0f25..381296e 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -5052,10 +5052,11 @@
       "Try adding an explicit type to either the variable '{0}' or the variable '{1}'.");
 
   static const StrongModeCode TOP_LEVEL_INSTANCE_GETTER = const StrongModeCode(
-      ErrorType.HINT,
+      ErrorType.STATIC_WARNING,
       'TOP_LEVEL_INSTANCE_GETTER',
-      "The type of '{0}' can't be inferred because of the use of the instance getter '{1}'.",
-      "Try removing the use of the instance getter {1}, or add an explicit type for '{0}'.");
+      "The type of '{0}' can't be inferred because it refers to an instance "
+      "getter, '{1}', which has an implicit type.",
+      "Add an explicit type for either '{0}' or '{1}'.");
 
   static const StrongModeCode TOP_LEVEL_TYPE_ARGUMENTS = const StrongModeCode(
       ErrorType.HINT,
@@ -5069,6 +5070,19 @@
       "The type of '{0}' can't be inferred because {1} expressions aren't supported.",
       "Try adding an explicit type for '{0}'.");
 
+  /**
+   * This warning is generated when a function type is assigned to a function
+   * typed location, and the assignment will be invalid after fuzzy arrows
+   * (the treatment of dynamic as bottom in certain locations) is removed.
+   *
+   */
+  static const StrongModeCode USES_DYNAMIC_AS_BOTTOM = const StrongModeCode(
+      ErrorType.STATIC_TYPE_WARNING,
+      'USES_DYNAMIC_AS_BOTTOM',
+      "A function of type '{0}' can't be assigned to a location of type '{1}'.",
+      "Try changing the parameter types of the function or of the "
+      " receiving location.");
+
   @override
   final ErrorType type;
 
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index d0fe70f..1a944e0 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -235,6 +235,10 @@
         errorReporter?.reportErrorForOffset(
             StaticWarningCode.FINAL_NOT_INITIALIZED, offset, length, [name]);
         return;
+      case "FUNCTION_TYPED_PARAMETER_VAR":
+        errorReporter?.reportErrorForOffset(
+            ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, offset, length);
+        return;
       case "GETTER_WITH_PARAMETERS":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.GETTER_WITH_PARAMETERS, offset, length);
diff --git a/pkg/analyzer/lib/src/kernel/loader.dart b/pkg/analyzer/lib/src/kernel/loader.dart
index 525e5aa..24808f0 100644
--- a/pkg/analyzer/lib/src/kernel/loader.dart
+++ b/pkg/analyzer/lib/src/kernel/loader.dart
@@ -527,7 +527,7 @@
             name: _nameOfMember(element),
             isConst: constructor.isConst,
             isExternal: constructor.isExternal,
-            isSyntheticDefault: constructor.isSynthetic)
+            isSynthetic: constructor.isSynthetic)
           ..fileOffset = element.nameOffset;
 
       case ElementKind.FIELD:
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 395dd83..445e54a 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -1123,7 +1123,7 @@
       var cTo = rules.typeToConcreteType(to);
       // If still true, no warning needed
       if (rules.isSubtypeOf(cFrom, cTo)) return;
-      _recordMessage(expr, HintCode.USES_DYNAMIC_AS_BOTTOM, [from, to]);
+      _recordMessage(expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [from, to]);
     }
   }
 
@@ -1276,9 +1276,7 @@
         errorCode.name.startsWith('STRONG_MODE_TOP_LEVEL_')) {
       severity = ErrorSeverity.ERROR;
     }
-    if (severity != ErrorSeverity.INFO ||
-        _options.strongModeHints ||
-        errorCode == HintCode.USES_DYNAMIC_AS_BOTTOM) {
+    if (severity != ErrorSeverity.INFO || _options.strongModeHints) {
       int begin = node is AnnotatedNode
           ? node.firstTokenAfterCommentAndMetadata.offset
           : node.offset;
@@ -1314,8 +1312,20 @@
         return;
       }
 
-      if (e is PropertyAccessorElement) {
-        validateHasType(e);
+      Element enclosing = e.enclosingElement;
+      if (enclosing is CompilationUnitElement) {
+        if (e is PropertyAccessorElement) {
+          validateHasType(e);
+        }
+      } else if (enclosing is ClassElement) {
+        if (e is PropertyAccessorElement) {
+          if (e.isStatic) {
+            validateHasType(e);
+          } else if (e.hasImplicitReturnType) {
+            _recordMessage(
+                n, StrongModeCode.TOP_LEVEL_INSTANCE_GETTER, [name, e.name]);
+          }
+        }
       }
     }
 
@@ -1393,6 +1403,7 @@
     } else if (n is FunctionExpressionInvocation) {
       _validateTopLevelInitializer(name, n.function);
     } else if (n is MethodInvocation) {
+      _validateTopLevelInitializer(name, n.methodName);
       _validateTopLevelInitializer(name, n.target);
     } else if (n is CascadeExpression) {
       _validateTopLevelInitializer(name, n.target);
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index 9db22ac..cd35af5 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -3087,6 +3087,18 @@
     // Test passes, even though if fails in the superclass
     await super.test_yieldInNonGenerator_async();
   }
+
+  @override
+  @failingTest
+  test_implementsDisallowedClass_class_String_num() async {
+    await super.test_implementsDisallowedClass_class_String_num();
+  }
+
+  @override
+  @failingTest
+  test_implementsDisallowedClass_classTypeAlias_String_num() async {
+    await super.test_implementsDisallowedClass_classTypeAlias_String_num();
+  }
 }
 
 /// Tests marked with this annotation fail because of a Fasta problem.
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 de88150..89b011f 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -2859,8 +2859,15 @@
   final y = x;
 }''');
     await computeAnalysisResult(source);
-    assertErrors(
-        source, [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    if (enableKernelDriver) {
+      assertErrors(source,
+          [CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER]);
+    } else {
+      assertErrors(source, [
+        CompileTimeErrorCode.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER,
+        StrongModeCode.TOP_LEVEL_INSTANCE_GETTER
+      ]);
+    }
     verify([source]);
   }
 
diff --git a/pkg/analyzer/test/generated/hint_code_kernel_test.dart b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
index ccab1d2..9662e18 100644
--- a/pkg/analyzer/test/generated/hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
@@ -470,4 +470,10 @@
     // Expected 1 errors of type HintCode.UNUSED_SHOWN_NAME, found 0
     return super.test_unusedShownName_topLevelVariable();
   }
+
+  @failingTest
+  @override
+  test_importDeferredLibraryWithLoadFunction() async {
+    await super.test_importDeferredLibraryWithLoadFunction();
+  }
 }
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 4b5f6f7..40f3c65 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.dart
@@ -4,6 +4,7 @@
 
 library analyzer.test.generated.hint_code_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -2898,6 +2899,206 @@
     verify([source]);
   }
 
+  test_strongMode_topLevelInstanceGetter() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  int get g => 0;
+}
+var b = new A().g;
+''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    TopLevelVariableDeclaration b = analysisResult.unit.declarations[1];
+    expect(b.variables.variables[0].element.type.toString(), 'int');
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_call() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  int Function() get g => () => 0;
+}
+var a = new A();
+var b = a.g();
+''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    TopLevelVariableDeclaration b = analysisResult.unit.declarations[2];
+    expect(b.variables.variables[0].element.type.toString(), 'int');
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_field() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  int g;
+}
+var b = new A().g;
+''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    TopLevelVariableDeclaration b = analysisResult.unit.declarations[1];
+    expect(b.variables.variables[0].element.type.toString(), 'int');
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_field_call() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  int Function() g;
+}
+var a = new A();
+var b = a.g();
+''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    TopLevelVariableDeclaration b = analysisResult.unit.declarations[2];
+    expect(b.variables.variables[0].element.type.toString(), 'int');
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_field_prefixedIdentifier() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  int g;
+}
+var a = new A();
+var b = a.g;
+''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    TopLevelVariableDeclaration b = analysisResult.unit.declarations[2];
+    expect(b.variables.variables[0].element.type.toString(), 'int');
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_implicitlyTyped() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  get g => 0;
+}
+var b = new A().g;
+''');
+    await computeAnalysisResult(source);
+    if (enableKernelDriver) {
+      assertNoErrors(source);
+    } else {
+      assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+    }
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_implicitlyTyped_call() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  get g => () => 0;
+}
+var a = new A();
+var b = a.g();
+''');
+    await computeAnalysisResult(source);
+    if (enableKernelDriver) {
+      assertNoErrors(source);
+    } else {
+      assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+    }
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_implicitlyTyped_field() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  var g = 0;
+}
+var b = new A().g;
+''');
+    await computeAnalysisResult(source);
+    if (enableKernelDriver) {
+      assertNoErrors(source);
+    } else {
+      assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+    }
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_implicitlyTyped_field_call() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  var g = () => 0;
+}
+var a = new A();
+var b = a.g();
+''');
+    await computeAnalysisResult(source);
+    if (enableKernelDriver) {
+      assertNoErrors(source);
+    } else {
+      assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+    }
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_implicitlyTyped_field_prefixedIdentifier() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  var g = 0;
+}
+var a = new A();
+var b = a.g;
+''');
+    await computeAnalysisResult(source);
+    if (enableKernelDriver) {
+      assertNoErrors(source);
+    } else {
+      assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+    }
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_implicitlyTyped_prefixedIdentifier() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  get g => 0;
+}
+var a = new A();
+var b = a.g;
+''');
+    await computeAnalysisResult(source);
+    if (enableKernelDriver) {
+      assertNoErrors(source);
+    } else {
+      assertErrors(source, [StrongModeCode.TOP_LEVEL_INSTANCE_GETTER]);
+    }
+    verify([source]);
+  }
+
+  test_strongMode_topLevelInstanceGetter_prefixedIdentifier() async {
+    resetWith(options: new AnalysisOptionsImpl()..strongMode = true);
+    Source source = addSource('''
+class A {
+  int get g => 0;
+}
+var a = new A();
+var b = a.g;
+''');
+    var analysisResult = await computeAnalysisResult(source);
+    assertNoErrors(source);
+    TopLevelVariableDeclaration b = analysisResult.unit.declarations[2];
+    expect(b.variables.variables[0].element.type.toString(), 'int');
+    verify([source]);
+  }
+
   test_typeCheck_type_is_Null() async {
     Source source = addSource(r'''
 m(i) {
diff --git a/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart b/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
index e8a95d5..62c81bc 100644
--- a/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
@@ -126,4 +126,11 @@
   test_unusedImport_metadata() async {
     await super.test_unusedImport_metadata();
   }
+
+  @failingTest
+  @override
+  @potentialAnalyzerProblem
+  test_importDeferredLibraryWithLoadFunction() async {
+    await super.test_importDeferredLibraryWithLoadFunction();
+  }
 }
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index b5f10f5..bd0444f 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -389,42 +389,6 @@
 
   @override
   @failingTest
-  void test_functionTypedParameter_final() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 1 errors of type ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, found 0
-    super.test_functionTypedParameter_final();
-  }
-
-  @override
-  @failingTest
-  void test_functionTypedParameter_incomplete1() {
-    // TODO(brianwilkerson) Does not recover.
-    //   type 'FormalParameterListImpl' is not a subtype of type 'TypeParameterList' of 'typeParameters' where
-    //   FormalParameterListImpl is from package:analyzer/src/dart/ast/ast.dart
-    //   TypeParameterList is from package:analyzer/dart/ast/ast.dart
-    //
-    //   package:analyzer/src/fasta/ast_builder.dart 1122:40                AstBuilder.endTopLevelMethod
-    //   package:front_end/src/fasta/parser/parser.dart 1741:14             Parser.parseTopLevelMethod
-    //   package:front_end/src/fasta/parser/parser.dart 1646:11             Parser.parseTopLevelMember
-    //   package:front_end/src/fasta/parser/parser.dart 298:14              Parser._parseTopLevelDeclaration
-    //   package:front_end/src/fasta/parser/parser.dart 263:13              Parser.parseTopLevelDeclaration
-    //   package:front_end/src/fasta/parser/parser.dart 252:15              Parser.parseUnit
-    //   package:analyzer/src/generated/parser_fasta.dart 77:33             _Parser2.parseCompilationUnit2
-    //   package:analyzer/src/generated/parser_fasta.dart 72:12             _Parser2.parseCompilationUnit
-    //   test/generated/parser_fasta_test.dart 2543:35                      FastaParserTestCase.parseCompilationUnit
-    super.test_functionTypedParameter_incomplete1();
-  }
-
-  @override
-  @failingTest
-  void test_functionTypedParameter_var() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 1 errors of type ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, found 0
-    super.test_functionTypedParameter_var();
-  }
-
-  @override
-  @failingTest
   void test_getterInFunction_block_noReturnType() {
     // TODO(brianwilkerson) Does not recover.
     //   type 'ExpressionStatementImpl' is not a subtype of type 'FunctionDeclarationStatement' of 'statement' where
@@ -1464,18 +1428,6 @@
   }
 
   @override
-  void test_varAndType_local() {
-    // The inherited test is marked as failing.
-    super.test_varAndType_local();
-  }
-
-  @override
-  void test_varAndType_parameter() {
-    // The inherited test is marked as failing.
-    super.test_varAndType_parameter();
-  }
-
-  @override
 //  @failingTest
   void test_voidVariable_parseClassMember_initializer() {
     // TODO(brianwilkerson) Passes, but ought to fail.
@@ -2130,36 +2082,6 @@
 class FormalParameterParserTest_Fasta extends FastaParserTestCase
     with FormalParameterParserTestMixin {
   @override
-  @failingTest
-  void test_parseNormalFormalParameter_field_const_noType() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 0 errors of type ParserErrorCode.EXTRANEOUS_MODIFIER, found 1 (1)
-    super.test_parseNormalFormalParameter_field_const_noType();
-  }
-
-  @failingTest
-  void test_parseNormalFormalParameter_field_const_noType2() {
-    // TODO(danrubel): should not be generating an error
-    super.test_parseNormalFormalParameter_field_const_noType();
-    assertNoErrors();
-  }
-
-  @override
-  @failingTest
-  void test_parseNormalFormalParameter_field_const_type() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 0 errors of type ParserErrorCode.EXTRANEOUS_MODIFIER, found 1 (1)
-    super.test_parseNormalFormalParameter_field_const_type();
-  }
-
-  @failingTest
-  void test_parseNormalFormalParameter_field_const_type2() {
-    // TODO(danrubel): should not be generating an error
-    super.test_parseNormalFormalParameter_field_const_type();
-    assertNoErrors();
-  }
-
-  @override
   void test_parseNormalFormalParameter_function_noType_typeParameterComments() {
     // Ignored: Fasta does not support the generic comment syntax.
   }
@@ -2173,36 +2095,6 @@
   void test_parseNormalFormalParameter_function_void_typeParameterComments() {
     // Ignored: Fasta does not support the generic comment syntax.
   }
-
-  @override
-  @failingTest
-  void test_parseNormalFormalParameter_simple_const_noType() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 0 errors of type ParserErrorCode.EXTRANEOUS_MODIFIER, found 1 (1)
-    super.test_parseNormalFormalParameter_simple_const_noType();
-  }
-
-  @failingTest
-  void test_parseNormalFormalParameter_simple_const_noType2() {
-    // TODO(danrubel): should not be generating an error
-    super.test_parseNormalFormalParameter_simple_const_noType();
-    assertNoErrors();
-  }
-
-  @override
-  @failingTest
-  void test_parseNormalFormalParameter_simple_const_type() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 0 errors of type ParserErrorCode.EXTRANEOUS_MODIFIER, found 1 (1)
-    super.test_parseNormalFormalParameter_simple_const_type();
-  }
-
-  @failingTest
-  void test_parseNormalFormalParameter_simple_const_type2() {
-    // TODO(danrubel): should not be generating an error
-    super.test_parseNormalFormalParameter_simple_const_type();
-    assertNoErrors();
-  }
 }
 
 /**
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index e371ddd..8cbebc2 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2686,6 +2686,15 @@
     ]);
   }
 
+  void test_covariantAndType_local() {
+    // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
+    // this would be a better error message.
+    parseStatement("covariant int x;");
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 9)]
+        : [expectedError(ParserErrorCode.EXPECTED_TOKEN, 0, 9)]);
+  }
+
   void test_covariantMember_getter_noReturnType() {
     createParser('static covariant get x => 0;');
     ClassMember member = parser.parseClassMember('C');
@@ -3480,43 +3489,43 @@
   void test_functionTypedParameter_const() {
     parseCompilationUnit("void f(const x()) {}",
         errors: usingFastaParser
-            ? [expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 7, 5)]
+            ? [
+                expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 7, 5),
+                expectedError(
+                    ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 7, 5)
+              ]
             : [
                 expectedError(
-                    ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 7, 9)
+                    ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 7, 5)
               ]);
   }
 
   void test_functionTypedParameter_final() {
     parseCompilationUnit("void f(final x()) {}", errors: [
-      expectedError(ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 7, 9)
+      expectedError(ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 7, 5)
     ]);
   }
 
   void test_functionTypedParameter_incomplete1() {
-    // This caused an exception at one point.
-    if (fe.Scanner.useFasta) {
-      parseCompilationUnit("void f(int Function(", errors: [
-        expectedError(ScannerErrorCode.EXPECTED_TOKEN, 20, 0),
-        expectedError(ScannerErrorCode.EXPECTED_TOKEN, 20, 0),
-        expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 20, 0),
-        expectedError(ParserErrorCode.MISSING_IDENTIFIER, 20, 0),
-      ]);
-    } else {
-      parseCompilationUnit("void f(int Function(", codes: [
-        ParserErrorCode.MISSING_FUNCTION_BODY,
-        ParserErrorCode.MISSING_CLOSING_PARENTHESIS,
-        ParserErrorCode.EXPECTED_EXECUTABLE,
-        ParserErrorCode.MISSING_CONST_FINAL_VAR_OR_TYPE,
-        ParserErrorCode.EXPECTED_TOKEN,
-        ParserErrorCode.EXPECTED_TOKEN
-      ]);
-    }
+    parseCompilationUnit("void f(int Function(",
+        errors: usingFastaParser
+            ? [
+                expectedError(ScannerErrorCode.EXPECTED_TOKEN, 6, 1),
+                expectedError(ScannerErrorCode.EXPECTED_TOKEN, 19, 1),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 8),
+                expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 20, 0),
+              ]
+            : [
+                expectedError(ScannerErrorCode.EXPECTED_TOKEN, 20, 0),
+                expectedError(ScannerErrorCode.EXPECTED_TOKEN, 20, 0),
+                expectedError(ParserErrorCode.MISSING_FUNCTION_BODY, 20, 0),
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 20, 0),
+              ]);
   }
 
   void test_functionTypedParameter_var() {
     parseCompilationUnit("void f(var x()) {}", errors: [
-      expectedError(ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 7, 7)
+      expectedError(ParserErrorCode.FUNCTION_TYPED_PARAMETER_VAR, 7, 3)
     ]);
   }
 
@@ -5242,22 +5251,24 @@
         errors: [expectedError(ParserErrorCode.VAR_AND_TYPE, 14, 3)]);
   }
 
-  @failingTest
   void test_varAndType_local() {
     // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
     // this would be a better error message.
     parseStatement("var int x;");
-    listener.assertErrors([expectedError(ParserErrorCode.VAR_AND_TYPE, 4, 3)]);
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.VAR_AND_TYPE, 4, 3)]
+        : [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 8, 1)]);
   }
 
-  @failingTest
   void test_varAndType_parameter() {
     // This is currently reporting EXPECTED_TOKEN for a missing semicolon, but
     // this would be a better error message.
     createParser('(var int x)');
     FormalParameterList list = parser.parseFormalParameterList();
     expectNotNullIfNoErrors(list);
-    listener.assertErrors([expectedError(ParserErrorCode.VAR_AND_TYPE, 5, 3)]);
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.VAR_AND_TYPE, 5, 3)]
+        : [expectedError(ParserErrorCode.EXPECTED_TOKEN, 9, 1)]);
   }
 
   void test_varAndType_topLevelVariable() {
@@ -8815,8 +8826,9 @@
   }
 
   void test_parseNormalFormalParameter_field_const_noType() {
-    NormalFormalParameter parameter =
-        parseNormalFormalParameter('const this.a');
+    NormalFormalParameter parameter = parseNormalFormalParameter('const this.a',
+        errorCodes:
+            usingFastaParser ? [ParserErrorCode.EXTRANEOUS_MODIFIER] : []);
     expect(parameter, isNotNull);
     expect(parameter, new isInstanceOf<FieldFormalParameter>());
     FieldFormalParameter fieldParameter = parameter;
@@ -8827,15 +8839,11 @@
   }
 
   void test_parseNormalFormalParameter_field_const_type() {
-    NormalFormalParameter parameter =
-        parseNormalFormalParameter('const A this.a');
+    NormalFormalParameter parameter = parseNormalFormalParameter(
+        'const A this.a',
+        errorCodes:
+            usingFastaParser ? [ParserErrorCode.EXTRANEOUS_MODIFIER] : []);
     expect(parameter, isNotNull);
-    if (usingFastaParser) {
-      // TODO(danrubel): should not be generating an error
-      assertErrorsWithCodes([ParserErrorCode.EXTRANEOUS_MODIFIER]);
-    } else {
-      assertNoErrors();
-    }
     expect(parameter, new isInstanceOf<FieldFormalParameter>());
     FieldFormalParameter fieldParameter = parameter;
     expect(fieldParameter.keyword, isNotNull);
@@ -9116,14 +9124,10 @@
   }
 
   void test_parseNormalFormalParameter_simple_const_noType() {
-    NormalFormalParameter parameter = parseNormalFormalParameter('const a');
+    NormalFormalParameter parameter = parseNormalFormalParameter('const a',
+        errorCodes:
+            usingFastaParser ? [ParserErrorCode.EXTRANEOUS_MODIFIER] : []);
     expect(parameter, isNotNull);
-    if (usingFastaParser) {
-      // TODO(danrubel): should not be generating an error
-      assertErrorsWithCodes([ParserErrorCode.EXTRANEOUS_MODIFIER]);
-    } else {
-      assertNoErrors();
-    }
     expect(parameter, new isInstanceOf<SimpleFormalParameter>());
     SimpleFormalParameter simpleParameter = parameter;
     expect(simpleParameter.keyword, isNotNull);
@@ -9132,14 +9136,10 @@
   }
 
   void test_parseNormalFormalParameter_simple_const_type() {
-    NormalFormalParameter parameter = parseNormalFormalParameter('const A a');
+    NormalFormalParameter parameter = parseNormalFormalParameter('const A a',
+        errorCodes:
+            usingFastaParser ? [ParserErrorCode.EXTRANEOUS_MODIFIER] : []);
     expect(parameter, isNotNull);
-    if (usingFastaParser) {
-      // TODO(danrubel): should not be generating an error
-      assertErrorsWithCodes([ParserErrorCode.EXTRANEOUS_MODIFIER]);
-    } else {
-      assertNoErrors();
-    }
     expect(parameter, new isInstanceOf<SimpleFormalParameter>());
     SimpleFormalParameter simpleParameter = parameter;
     expect(simpleParameter.keyword, isNotNull);
diff --git a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
index 2173912..e6af706 100644
--- a/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/paired_tokens_test.dart
@@ -136,12 +136,10 @@
  */
 @reflectiveTest
 class BracketsTest extends AbstractRecoveryTest {
-  @failingTest
   void test_indexOperator() {
-    // Parser crashes
     testRecovery('''
 f(x) => l[x
-''', [ScannerErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN], '''
+''', [ScannerErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN], '''
 f(x) => l[x];
 ''');
   }
@@ -166,12 +164,10 @@
 ''');
   }
 
-  @failingTest
   void test_listLiteral_outer_last() {
-    // Parser crashes
     testRecovery('''
 var x = [0, 1
-''', [ScannerErrorCode.EXPECTED_TOKEN, ScannerErrorCode.EXPECTED_TOKEN], '''
+''', [ScannerErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN], '''
 var x = [0, 1];
 ''');
   }
@@ -224,12 +220,11 @@
 ''');
   }
 
-  @failingTest
   void test_parameterList_eof() {
-    // Parser crashes
     testRecovery('''
 f(x
-''', [ScannerErrorCode.EXPECTED_TOKEN], '''
+''', [ScannerErrorCode.EXPECTED_TOKEN, ParserErrorCode.MISSING_FUNCTION_BODY],
+        '''
 f(x) {}
 ''');
   }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 58cc888..4c392b1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -1152,7 +1152,9 @@
   void compareVariableElements(
       VariableElement resynthesized, VariableElement original, String desc) {
     compareElements(resynthesized, original, desc);
-    compareTypes(resynthesized.type, original.type, '$desc.type');
+    if ((resynthesized as VariableElementImpl).typeInferenceError == null) {
+      compareTypes(resynthesized.type, original.type, '$desc.type');
+    }
     VariableElementImpl resynthesizedActual =
         getActualElement(resynthesized, desc);
     VariableElementImpl originalActual = getActualElement(original, desc);
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 9479152..fa4342b 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -270,6 +270,7 @@
         removeCode(StrongModeCode.TOP_LEVEL_INSTANCE_GETTER);
         removeCode(StrongModeCode.TOP_LEVEL_TYPE_ARGUMENTS);
         removeCode(StrongModeCode.TOP_LEVEL_UNSUPPORTED);
+        removeCode(StrongModeCode.USES_DYNAMIC_AS_BOTTOM);
       } else if (errorType == TodoCode) {
         declaredNames.remove('TODO_REGEX');
       }
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 2ed061e..7b914d9 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -489,7 +489,7 @@
   f1("hello");
   dynamic f2 = foo;
   (/*info:DYNAMIC_INVOKE*/f2("hello"));
-  DynFun f3 = /*info:USES_DYNAMIC_AS_BOTTOM*/foo;
+  DynFun f3 = /*warning:USES_DYNAMIC_AS_BOTTOM*/foo;
   (/*info:DYNAMIC_INVOKE*/f3("hello"));
   (/*info:DYNAMIC_INVOKE*/f3(42));
   StrFun f4 = foo;
@@ -673,7 +673,7 @@
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(3);
   }
   {
-    A f = /*info:USES_DYNAMIC_AS_BOTTOM*/new B();
+    A f = /*warning:USES_DYNAMIC_AS_BOTTOM*/new B();
     int x;
     double y;
     x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
@@ -686,7 +686,7 @@
     /*info:DYNAMIC_INVOKE*/g.col(42.0);
     /*info:DYNAMIC_INVOKE*/g.foo(42.0);
     /*info:DYNAMIC_INVOKE*/g.x;
-    A f = /*info:USES_DYNAMIC_AS_BOTTOM*/new B();
+    A f = /*warning:USES_DYNAMIC_AS_BOTTOM*/new B();
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(42.0);
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/foo(42.0);
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_GETTER*/x;
@@ -3091,7 +3091,7 @@
   TakesA<int> f;
   TakesA<dynamic> g;
   TakesA<String> h;
-  g = /*info:USES_DYNAMIC_AS_BOTTOM*/h;
+  g = /*warning:USES_DYNAMIC_AS_BOTTOM*/h;
   f = /*info:DOWN_CAST_COMPOSITE*/f ?? g;
 }
 ''');
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index baf4e6f..8de598f 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -7,7 +7,7 @@
   sdk: '>=1.12.0 <2.0.0'
 dependencies:
   analyzer: ^0.27.0
-  args: ^0.13.0
+  args: '>=0.13.0 <2.0.0'
   bazel_worker: ^0.1.0
   cli_util: ^0.1.0
   collection: ^1.14.1
diff --git a/pkg/analyzer_cli/tool/perf.dart b/pkg/analyzer_cli/tool/perf.dart
index f8a7803..4aa3aa6 100644
--- a/pkg/analyzer_cli/tool/perf.dart
+++ b/pkg/analyzer_cli/tool/perf.dart
@@ -149,6 +149,7 @@
 
   var libs = [
     "dart:async",
+    "dart:cli",
     "dart:collection",
     "dart:convert",
     "dart:core",
@@ -158,7 +159,7 @@
     "dart:math",
     "dart:mirrors",
     "dart:typed_data",
-    "dart:io"
+    "dart:io",
   ];
 
   for (var lib in libs) {
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index c1755d7..bd60f84 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -1486,40 +1486,12 @@
       MessageKind.FINAL_FUNCTION_TYPE_PARAMETER: const MessageTemplate(
           MessageKind.FINAL_FUNCTION_TYPE_PARAMETER,
           "A function type parameter can't be declared final.",
-          howToFix: "Try removing 'final'.",
-          examples: const [
-            """
-foo(final int x(int a)) {}
-main() => foo((y) => 42);
-""",
-            """
-foo({final int x(int a)}) {}
-main() => foo((y) => 42);
-""",
-            """
-foo([final int x(int a)]) {}
-main() => foo((y) => 42);
-"""
-          ]),
+          howToFix: "Try removing 'final'."),
 
       MessageKind.VAR_FUNCTION_TYPE_PARAMETER: const MessageTemplate(
           MessageKind.VAR_FUNCTION_TYPE_PARAMETER,
           "A function type parameter can't be declared with 'var'.",
-          howToFix: "Try removing 'var'.",
-          examples: const [
-            """
-foo(var int x(int a)) {}
-main() => foo((y) => 42);
-""",
-            """
-foo({var int x(int a)}) {}
-main() => foo((y) => 42);
-""",
-            """
-foo([var int x(int a)]) {}
-main() => foo((y) => 42);
-"""
-          ]),
+          howToFix: "Try removing 'var'."),
 
       MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE: const MessageTemplate(
           MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index e508a0c..a02087a 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -1680,6 +1680,11 @@
   }
 
   @override
+  TypeInformation visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded node) {
+    return _types.nonNullEmpty();
+  }
+
+  @override
   TypeInformation visitInvalidExpression(ir.InvalidExpression node) {
     // TODO(johnniwinther): Maybe this should be [empty] instead?
     return _types.dynamicType;
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index 097def4..21cb15e 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -116,6 +116,9 @@
   // used in impact builder for symbol constants.
   ConstantValue getConstantValue(ir.Expression expression,
       {bool requireConstant: true, bool implicitNull: false});
+
+  /// Return the [ImportEntity] corresponding to [node].
+  ImportEntity getImport(ir.LibraryDependency node);
 }
 
 /// Interface that translates between Kernel IR nodes and entities used for
@@ -182,9 +185,6 @@
 
   /// Returns the definition information for [cls].
   ClassDefinition getClassDefinition(covariant ClassEntity cls);
-
-  /// Return the [ImportEntity] corresponding to [node].
-  ImportEntity getImport(ir.LibraryDependency node);
 }
 
 /// Interface that translates between Kernel IR nodes and entities used for
@@ -229,11 +229,6 @@
   /// Returns the constructor body entity corresponding to [constructor].
   FunctionEntity getConstructorBody(ir.Constructor node);
 
-  /// Returns the uri for the deferred import [node].
-  // TODO(johnniwinther): Avoid this method by deriving the uri directly from
-  // the node.
-  String getDeferredUri(ir.LibraryDependency node);
-
   /// Make a record to ensure variables that are are declared in one scope and
   /// modified in another get their values updated correctly.
   Map<Local, JRecordField> makeRecordContainer(
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index c9e1de2..4734f47 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -796,6 +796,13 @@
     assert(checkFamily(cls));
     return _classes.getData(cls).definition;
   }
+
+  @override
+  ImportEntity getImport(ir.LibraryDependency node) {
+    ir.Library library = node.parent;
+    LibraryData data = _libraries.getData(_getLibrary(library));
+    return data.imports[node];
+  }
 }
 
 /// Mixin that implements the abstract methods in [KernelToElementMapBase].
@@ -1285,13 +1292,6 @@
   }
 
   @override
-  ImportEntity getImport(ir.LibraryDependency node) {
-    ir.Library library = node.parent;
-    LibraryData data = _libraries.getData(_getLibrary(library));
-    return data.imports[node];
-  }
-
-  @override
   MemberDefinition getMemberDefinition(MemberEntity member) {
     return _getMemberDefinition(member);
   }
@@ -2721,10 +2721,6 @@
   String _getClosureVariableName(String name, int id) {
     return "_captured_${name}_$id";
   }
-
-  String getDeferredUri(ir.LibraryDependency node) {
-    throw new UnimplementedError('JsKernelToElementMap.getDeferredUri');
-  }
 }
 
 class KernelClassQueries extends ClassQueries {
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 8d9f0d6..8e99d15 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -157,7 +157,7 @@
   Iterable<ConstantValue> _metadata;
   Map<ir.LibraryDependency, ImportEntity> imports;
 
-  LibraryData(this.library);
+  LibraryData(this.library, [this.imports]);
 
   Iterable<ConstantValue> getMetadata(KernelToElementMapBase elementMap) {
     return _metadata ??= elementMap.getMetadata(library.annotations);
@@ -184,7 +184,7 @@
   }
 
   LibraryData copy() {
-    return new LibraryData(library);
+    return new LibraryData(library, imports);
   }
 }
 
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index e79d5da..24b957d 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -192,6 +192,7 @@
   /// The locations of js patch-files relative to the sdk-descriptors.
   static const _patchLocations = const <String, String>{
     "async": "_internal/js_runtime/lib/async_patch.dart",
+    "cli": "_internal/js_runtime/lib/cli_patch.dart",
     "collection": "_internal/js_runtime/lib/collection_patch.dart",
     "convert": "_internal/js_runtime/lib/convert_patch.dart",
     "core": "_internal/js_runtime/lib/core_patch.dart",
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 5c6a96f..ce0d531 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -1146,10 +1146,12 @@
 
   @override
   void visitCheckLibraryIsLoaded(ir.CheckLibraryIsLoaded checkLoad) {
-    HInstruction prefixConstant =
-        graph.addConstantString(checkLoad.import.name, closedWorld);
-    String uri = _elementMap.getDeferredUri(checkLoad.import);
-    HInstruction uriConstant = graph.addConstantString(uri, closedWorld);
+    ImportEntity import = _elementMap.getImport(checkLoad.import);
+    String loadId = deferredLoadTask.getImportDeferName(
+        _elementMap.getSpannable(targetElement, checkLoad), import);
+    HInstruction prefixConstant = graph.addConstantString(loadId, closedWorld);
+    HInstruction uriConstant =
+        graph.addConstantString('${import.uri}', closedWorld);
     _pushStaticInvocation(
         _commonElements.checkDeferredIsLoaded,
         [prefixConstant, uriConstant],
@@ -1159,11 +1161,12 @@
 
   @override
   void visitLoadLibrary(ir.LoadLibrary loadLibrary) {
+    String loadId = deferredLoadTask.getImportDeferName(
+        _elementMap.getSpannable(targetElement, loadLibrary),
+        _elementMap.getImport(loadLibrary.import));
     // TODO(efortuna): Source information!
-    push(new HInvokeStatic(
-        commonElements.loadDeferredLibrary,
-        [graph.addConstantString(loadLibrary.import.name, closedWorld)],
-        commonMasks.nonNullType,
+    push(new HInvokeStatic(commonElements.loadDeferredLibrary,
+        [graph.addConstantString(loadId, closedWorld)], commonMasks.nonNullType,
         targetCanThrow: false));
   }
 
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 2b98deb..bac6584 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -959,8 +959,8 @@
   }
 
   /// An instruction is an 'allocation' is it is the sole alias for an object.
-  /// This applies to to instructions that allocate new objects and can be
-  /// extended to methods that return other allocations without escaping them.
+  /// This applies to instructions that allocate new objects and can be extended
+  /// to methods that return other allocations without escaping them.
   bool get isAllocation => false;
 
   /// Overridden by [HCheck] to return the actual non-[HCheck]
@@ -1658,11 +1658,7 @@
 }
 
 abstract class HInvoke extends HInstruction {
-  /**
-    * The first argument must be the target: either an [HStatic] node, or
-    * the receiver of a method-call. The remaining inputs are the arguments
-    * to the invocation.
-    */
+  bool isAllocation = false;
   HInvoke(List<HInstruction> inputs, type) : super(inputs, type) {
     sideEffects.setAllSideEffects();
     sideEffects.setDependsOnSomething();
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 9c972af..f27483a 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -421,10 +421,7 @@
         }
       } else if (input.isStringOrNull(_closedWorld)) {
         if (applies(commonElements.jsStringSplit)) {
-          HInstruction argument = node.inputs[2];
-          if (argument.isString(_closedWorld)) {
-            target = commonElements.jsStringSplit;
-          }
+          return handleStringSplit(node);
         } else if (applies(commonElements.jsStringOperatorAdd)) {
           // `operator+` is turned into a JavaScript '+' so we need to
           // make sure the receiver and the argument are not null.
@@ -466,6 +463,63 @@
     return node;
   }
 
+  HInstruction handleStringSplit(HInvokeDynamic node) {
+    HInstruction argument = node.inputs[2];
+    if (!argument.isString(_closedWorld)) return node;
+
+    // Replace `s.split$1(pattern)` with
+    //
+    //     t1 = s.split(pattern);
+    //     t2 = String;
+    //     t3 = JSArray<t2>;
+    //     t4 = setRuntimeTypeInfo(t1, t3);
+    //
+
+    TypeMask resultMask = _closedWorld.commonMasks.growableListType;
+
+    HInvokeDynamicMethod splitInstruction = new HInvokeDynamicMethod(
+        node.selector,
+        node.mask,
+        node.inputs.sublist(1),
+        resultMask,
+        node.sourceInformation)
+      ..element = commonElements.jsStringSplit
+      ..isAllocation = true;
+
+    if (!_closedWorld.rtiNeed
+        .classNeedsTypeArguments(commonElements.jsArrayClass)) {
+      return splitInstruction;
+    }
+
+    node.block.addBefore(node, splitInstruction);
+
+    HInstruction stringTypeInfo = new HTypeInfoExpression(
+        TypeInfoExpressionKind.COMPLETE,
+        _closedWorld.elementEnvironment.getThisType(commonElements.stringClass),
+        <HInstruction>[],
+        _closedWorld.commonMasks.dynamicType);
+    node.block.addBefore(node, stringTypeInfo);
+
+    HInstruction typeInfo = new HTypeInfoExpression(
+        TypeInfoExpressionKind.INSTANCE,
+        _closedWorld.elementEnvironment
+            .getThisType(commonElements.jsArrayClass),
+        <HInstruction>[stringTypeInfo],
+        _closedWorld.commonMasks.dynamicType);
+    node.block.addBefore(node, typeInfo);
+
+    HInvokeStatic tagInstruction = new HInvokeStatic(
+        commonElements.setRuntimeTypeInfo,
+        <HInstruction>[splitInstruction, typeInfo],
+        resultMask);
+    // 'Linear typing' trick: [tagInstruction] is the only use of the
+    // [splitInstruction], so it becomes the sole alias.
+    // TODO(sra): Build this knowledge into alias analysis.
+    tagInstruction.isAllocation = true;
+
+    return tagInstruction;
+  }
+
   HInstruction visitInvokeDynamicMethod(HInvokeDynamicMethod node) {
     propagateConstantValueToUses(node);
     if (node.isInterceptedCall) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index d08f1e3..d8cf050 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -6070,15 +6070,16 @@
         return type;
       }
     }
-    if (type.isDynamic) {
-      return type;
-    } else if (type is InterfaceType && type.element == expectedType.element) {
+    if (type.isDynamic) return type;
+    if (type is InterfaceType &&
+        (type.element == expectedType.element ||
+            expectedType == types.futureType &&
+                type.element == types.futureOrType.element)) {
       return type.typeArguments[0];
-    } else {
-      // TODO(leafp): The above only handles the case where the return type
-      // is exactly Future/Stream/Iterable.  Handle the subtype case.
-      return DynamicTypeImpl.instance;
     }
+    // TODO(leafp): The above only handles the case where the return type
+    // is exactly Future/Stream/Iterable.  Handle the subtype case.
+    return DynamicTypeImpl.instance;
   }
 
   JS.Expression _callHelper(String code, [args]) {
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 2c07cf0..e35b71a 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -19,7 +19,6 @@
 import '../compiler/module_builder.dart';
 import '../js_ast/js_ast.dart' as JS;
 import 'compiler.dart';
-import 'native_types.dart';
 import 'source_map_printer.dart';
 
 const _binaryName = 'dartdevk';
@@ -121,7 +120,12 @@
         allowMultiple: true)
     ..addFlag('source-map', help: 'emit source mapping', defaultsTo: true)
     ..addOption('summary-input-dir', allowMultiple: true)
-    ..addOption('custom-app-scheme', defaultsTo: 'org-dartlang-app');
+    ..addOption('custom-app-scheme', defaultsTo: 'org-dartlang-app')
+    // Ignore dart2js options that we don't support in DDC.
+    ..addFlag('enable-enum', hide: true)
+    ..addFlag('experimental-trust-js-interop-type-annotations', hide: true)
+    ..addFlag('trust-type-annotations', hide: true)
+    ..addFlag('supermixin', hide: true);
 
   addModuleFormatOptions(argParser, singleOutFile: false);
 
@@ -216,8 +220,7 @@
 
 JS.Program compileToJSModule(Program p, List<Program> summaries,
     List<Uri> summaryUris, Map<String, String> declaredVariables) {
-  var compiler = new ProgramCompiler(new NativeTypeSet(p),
-      declaredVariables: declaredVariables);
+  var compiler = new ProgramCompiler(p, declaredVariables: declaredVariables);
   return compiler.emitProgram(p, summaries, summaryUris);
 }
 
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index f1f7661..6b7f851 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -115,7 +115,7 @@
   /// unit.
   final virtualFields = new VirtualFieldModel();
 
-  JSTypeRep _typeRep;
+  final JSTypeRep _typeRep;
 
   bool _superAllowed = true;
 
@@ -188,17 +188,28 @@
 
   final ConstantVisitor _constants;
 
-  NullableInference _nullableInference;
+  final NullableInference _nullableInference;
 
-  ProgramCompiler(NativeTypeSet nativeTypes,
-      {this.emitMetadata: true,
-      this.replCompile: false,
-      this.declaredVariables: const {}})
+  factory ProgramCompiler(Program program,
+      {bool emitMetadata: true,
+      bool replCompile: false,
+      Map<String, String> declaredVariables: const {}}) {
+    var nativeTypes = new NativeTypeSet(program);
+    var types = new TypeSchemaEnvironment(
+        nativeTypes.coreTypes, new ClassHierarchy(program), true);
+    return new ProgramCompiler._(
+        nativeTypes, new JSTypeRep(types, nativeTypes.sdk),
+        emitMetadata: emitMetadata,
+        replCompile: replCompile,
+        declaredVariables: declaredVariables);
+  }
+
+  ProgramCompiler._(NativeTypeSet nativeTypes, this._typeRep,
+      {this.emitMetadata, this.replCompile, this.declaredVariables})
       : _extensionTypes = nativeTypes,
+        types = _typeRep.types,
         coreTypes = nativeTypes.coreTypes,
         _constants = new ConstantVisitor(nativeTypes.coreTypes),
-        types = new TypeSchemaEnvironment(nativeTypes.coreTypes,
-            new ClassHierarchy.deprecated_incremental(), true),
         _jsArrayClass =
             nativeTypes.sdk.getClass('dart:_interceptors', 'JSArray'),
         _asyncStreamIteratorClass =
@@ -214,10 +225,8 @@
         identityHashSetImplClass =
             nativeTypes.sdk.getClass('dart:collection', '_IdentityHashSet'),
         syncIterableClass =
-            nativeTypes.sdk.getClass('dart:_js_helper', 'SyncIterable') {
-    _typeRep = new JSTypeRep(types, nativeTypes.sdk);
-    _nullableInference = new NullableInference(_typeRep);
-  }
+            nativeTypes.sdk.getClass('dart:_js_helper', 'SyncIterable'),
+        _nullableInference = new NullableInference(_typeRep);
 
   ClassHierarchy get hierarchy => types.hierarchy;
 
@@ -771,12 +780,6 @@
       body.add(_addConstructorToClass(className, name, jsCtor));
     }
 
-    if (c.isEnum) {
-      assert(!isCallable, 'enums should not be callable');
-      addConstructor('', js.call('function(x) { this.index = x; }'));
-      return body;
-    }
-
     var fields = c.fields;
     for (var ctor in c.constructors) {
       if (ctor.isExternal) continue;
@@ -1027,9 +1030,24 @@
   /// Emits static fields for a class, and initialize them eagerly if possible,
   /// otherwise define them as lazy properties.
   void _emitStaticFields(Class c, List<JS.Statement> body) {
-    var lazyStatics = c.fields.where((f) => f.isStatic).toList();
-    if (lazyStatics.isNotEmpty) {
-      body.add(_emitLazyFields(c, lazyStatics));
+    var fields = c.fields.where((f) => f.isStatic).toList();
+    if (c.isEnum) {
+      // We know enum fields can be safely emitted as const fields, as long
+      // as the `values` field is emitted last.
+      var classRef = _emitTopLevelName(c);
+      var valueField = fields.firstWhere((f) => f.name.name == 'values');
+      fields.remove(valueField);
+      fields.add(valueField);
+      for (var f in fields) {
+        assert(f.isConst);
+        body.add(_defineValueOnClass(
+                classRef,
+                _emitStaticMemberName(f.name.name),
+                _visitInitializer(f.initializer, f.annotations))
+            .toStatement());
+      }
+    } else if (fields.isNotEmpty) {
+      body.add(_emitLazyFields(c, fields));
     }
   }
 
@@ -1037,11 +1055,13 @@
       List<JS.Statement> body) {
     // Metadata
     if (emitMetadata && metadata.isNotEmpty) {
-      body.add(js.statement('#[#.metadata] = () => #;', [
+      body.add(js.statement('#[#.metadata] = #;', [
         className,
         _runtimeModule,
-        new JS.ArrayInitializer(
-            new List<JS.Expression>.from(metadata.map(_instantiateAnnotation)))
+        new JS.ArrowFun(
+            [],
+            _withLetScopeArrowFunction(() => new JS.ArrayInitializer(
+                new List.from(metadata.map(_instantiateAnnotation)))))
       ]));
     }
   }
@@ -1273,20 +1293,11 @@
         () => _superDisallowed(
             () => _emitConstructorBody(node, fields, className)));
 
-    return _finishConstructorFunction(params, body, isCallable);
+    var block = new JS.Block(body)..sourceInformation = node;
+    return _finishConstructorFunction(params, block, isCallable);
   }
 
-  void addStatementToList(JS.Statement statement, List<JS.Statement> list) {
-    // If the statement is a nested block, flatten it into the list when
-    // possible.  If the statement is empty, discard it.
-    if (statement is JS.Block && (list.isEmpty || !statement.isScope)) {
-      list.addAll(statement.statements);
-    } else if (statement is! JS.EmptyStatement) {
-      list.add(statement);
-    }
-  }
-
-  JS.Block _emitConstructorBody(
+  List<JS.Statement> _emitConstructorBody(
       Constructor node, List<Field> fields, JS.Expression className) {
     var cls = node.enclosingClass;
 
@@ -1305,15 +1316,14 @@
 
     if (redirectCall != null) {
       body.add(_emitRedirectingConstructor(redirectCall, className));
-      _initTempVars(body);
-      return new JS.Block(body);
+      return body;
     }
 
     // Generate field initializers.
     // These are expanded into each non-redirecting constructor.
     // In the future we may want to create an initializer function if we have
     // multiple constructors, but it needs to be balanced against readability.
-    addStatementToList(_initializeFields(fields, node), body);
+    _addStatementToList(_initializeFields(fields, node), body);
 
     var superCall = node.initializers.firstWhere((i) => i is SuperInitializer,
         orElse: () => null) as SuperInitializer;
@@ -1323,13 +1333,12 @@
     // enclosing class is class Object.
     var jsSuper = _emitSuperConstructorCallIfNeeded(cls, className, superCall);
     if (jsSuper != null) {
-      addStatementToList(jsSuper..sourceInformation = superCall, body);
+      _addStatementToList(jsSuper..sourceInformation = superCall, body);
     }
 
     var jsBody = _visitStatement(node.function.body);
-    if (jsBody != null) addStatementToList(jsBody, body);
-    _initTempVars(body);
-    return new JS.Block(body)..sourceInformation = node;
+    if (jsBody != null) _addStatementToList(jsBody, body);
+    return body;
   }
 
   JS.Expression _constructorName(String name) {
@@ -1390,7 +1399,7 @@
   bool _hasUnnamedConstructor(Class c) {
     if (c == null || c == coreTypes.objectClass) return false;
     var ctor = unnamedConstructor(c);
-    if (ctor != null && !ctor.isSyntheticDefault) return true;
+    if (ctor != null && !ctor.isSynthetic) return true;
     if (c.fields.any((f) => !f.isStatic)) return true;
     return _hasUnnamedSuperConstructor(c);
   }
@@ -1501,16 +1510,20 @@
 
   JS.Statement _addConstructorToClass(
       JS.Expression className, String name, JS.Expression jsCtor) {
-    var ctorName = _constructorName(name);
-    if (JS.invalidStaticFieldName(name)) {
-      jsCtor =
-          _callHelper('defineValue(#, #, #)', [className, ctorName, jsCtor]);
-    } else {
-      jsCtor = js.call('#.# = #', [className, ctorName, jsCtor]);
-    }
+    jsCtor = _defineValueOnClass(className, _constructorName(name), jsCtor);
     return js.statement('#.prototype = #.prototype;', [jsCtor, className]);
   }
 
+  JS.Expression _defineValueOnClass(
+      JS.Expression className, JS.Expression name, JS.Expression value) {
+    var args = [className, name, value];
+    if (name is JS.LiteralString &&
+        JS.invalidStaticFieldName(name.valueWithoutQuotes)) {
+      return _callHelper('defineValue(#, #, #)', args);
+    }
+    return js.call('#.# = #', args);
+  }
+
   List<JS.Method> _emitClassMethods(Class c) {
     var virtualFields = _classProperties.virtualFields;
 
@@ -2069,17 +2082,35 @@
   }
 
   JS.Fun _emitStaticFieldInitializer(Field field) {
+    return new JS.Fun(
+        [],
+        new JS.Block(_withLetScope(() => [
+              new JS.Return(
+                  _visitInitializer(field.initializer, field.annotations))
+            ])));
+  }
+
+  List<JS.Statement> _withLetScope(List<JS.Statement> visitBody()) {
     var savedLetVariables = _letVariables;
     _letVariables = [];
 
-    var body = [
-      new JS.Return(_visitInitializer(field.initializer, field.annotations))
-    ];
-    _initTempVars(body);
+    var body = visitBody();
+    var letVars = _initLetVariables();
+    if (letVars != null) body.insert(0, letVars);
 
     _letVariables = savedLetVariables;
+    return body;
+  }
 
-    return new JS.Fun([], new JS.Block(body));
+  JS.Node _withLetScopeArrowFunction(JS.Expression visitBody()) {
+    var savedLetVariables = _letVariables;
+    _letVariables = [];
+
+    var expr = visitBody();
+    var letVars = _initLetVariables();
+
+    _letVariables = savedLetVariables;
+    return letVars == null ? expr : new JS.Block([letVars, expr.toReturn()]);
   }
 
   JS.PropertyAccess _emitTopLevelName(NamedNode n, {String suffix: ''}) {
@@ -2336,21 +2367,22 @@
   }
 
   void _emitLibraryProcedures(Library library) {
-    var procedures =
-        library.procedures.where((p) => !p.isExternal && !p.isAbstract);
+    var procedures = library.procedures
+        .where((p) => !p.isExternal && !p.isAbstract)
+        .toList();
     _moduleItems.addAll(procedures
         .where((p) => !p.isAccessor)
         .map(_emitLibraryFunction)
         .toList());
-    _moduleItems
-        .add(_emitLibraryAccessors(procedures.where((p) => p.isAccessor)));
+    _emitLibraryAccessors(procedures.where((p) => p.isAccessor).toList());
   }
 
-  JS.Statement _emitLibraryAccessors(Iterable<Procedure> accessors) {
-    return _callHelperStatement('copyProperties(#, { # });', [
+  void _emitLibraryAccessors(Iterable<Procedure> accessors) {
+    if (accessors.isEmpty) return;
+    _moduleItems.add(_callHelperStatement('copyProperties(#, { # });', [
       emitLibraryName(_currentLibrary),
       accessors.map(_emitLibraryAccessor).toList()
-    ]);
+    ]));
   }
 
   JS.Method _emitLibraryAccessor(Procedure node) {
@@ -2675,7 +2707,7 @@
   List<JS.Parameter> _emitTypeFormals(List<TypeParameter> typeFormals) {
     return typeFormals
         .map((t) => new JS.Identifier(getTypeParameterName(t)))
-        .toList(growable: false);
+        .toList();
   }
 
   JS.Expression _emitGeneratorFunction(FunctionNode function, String name) {
@@ -2768,30 +2800,30 @@
     //
     // In the body of an `async`, `await` is generated simply as `yield`.
     var gen = emitGeneratorFn((_) => []);
-    var returnType = _getExpectedReturnType(function, coreTypes.futureClass);
+    // Return type of an async body is `Future<flatten(T)>`, where T is the
+    // declared return type.
+    var returnType = types.unfutureType(function.functionType.returnType);
     return js.call('#.async(#, #)',
         [emitLibraryName(coreTypes.asyncLibrary), _emitType(returnType), gen])
       ..sourceInformation = function;
   }
 
-  // TODO(leafp): Various analyzer pieces computed similar things.
-  // Share this logic somewhere?
+  /// Gets the expected return type of a `sync*` or `async*` body.
   DartType _getExpectedReturnType(FunctionNode f, Class expected) {
     var type = f.functionType.returnType;
     if (type is InterfaceType) {
       var match = hierarchy.getTypeAsInstanceOf(type, expected);
-      return match.typeArguments[0];
+      if (match != null) return match.typeArguments[0];
     }
     return const DynamicType();
   }
 
   JS.Block _emitFunctionBody(FunctionNode f) {
-    List<JS.Statement> block;
-    _withCurrentFunction(f, () {
-      block = _emitArgumentInitializers(f);
+    var block = _withCurrentFunction(f, () {
+      var block = _emitArgumentInitializers(f);
       var jsBody = _visitStatement(f.body);
-      if (jsBody != null) addStatementToList(jsBody, block);
-      _initTempVars(block);
+      if (jsBody != null) _addStatementToList(jsBody, block);
+      return block;
     });
 
     if (f.asyncMarker == AsyncMarker.Sync) {
@@ -2812,18 +2844,16 @@
     return new JS.Block(block);
   }
 
-  T _withCurrentFunction<T>(FunctionNode fn, T action()) {
+  List<JS.Statement> _withCurrentFunction(
+      FunctionNode fn, List<JS.Statement> action()) {
     var savedFunction = _currentFunction;
     _currentFunction = fn;
-    var savedLetVariables = _letVariables;
-    _letVariables = [];
     _nullableInference.enterFunction(fn);
 
-    var result = action();
+    var result = _withLetScope(action);
 
     _nullableInference.exitFunction(fn);
     _currentFunction = savedFunction;
-    _letVariables = savedLetVariables;
     return result;
   }
 
@@ -3530,17 +3560,16 @@
     return new JS.Identifier(name);
   }
 
-  void _initTempVars(List<JS.Statement> block) {
-    if (_letVariables.isEmpty) return;
-    block.insert(
-        0,
-        new JS.VariableDeclarationList(
-                'let',
-                _letVariables
-                    .map((v) => new JS.VariableInitialization(v, null))
-                    .toList())
-            .toStatement());
+  JS.Statement _initLetVariables() {
+    if (_letVariables.isEmpty) return null;
+    var result = new JS.VariableDeclarationList(
+            'let',
+            _letVariables
+                .map((v) => new JS.VariableInitialization(v, null))
+                .toList())
+        .toStatement();
     _letVariables.clear();
+    return result;
   }
 
   // TODO(jmesserly): resugar operators for kernel, such as ++x, x++, x+=.
@@ -3629,7 +3658,7 @@
   @override
   visitSuperPropertySet(SuperPropertySet node) {
     var target = node.interfaceTarget;
-    var jsTarget = _emitSuperTarget(target);
+    var jsTarget = _emitSuperTarget(target, setter: true);
     return _visitExpression(node.value).toAssignExpression(jsTarget);
   }
 
@@ -4067,8 +4096,8 @@
       var isAccessor = member is Procedure ? member.isAccessor : true;
       if (isAccessor) {
         assert(member is Procedure
-            ? setter == member.isSetter
-            : (member as Field).isFinal != setter);
+            ? member.isSetter == setter
+            : !setter || !(member as Field).isFinal);
         var fn = js.call(
             setter
                 ? 'function(x) { super[#] = x; }'
@@ -4316,9 +4345,6 @@
   visitConstructorInvocation(ConstructorInvocation node) {
     var ctor = node.target;
     var args = node.arguments;
-    var ctorClass = ctor.enclosingClass;
-    if (_isObjectLiteral(ctorClass)) return _emitObjectLiteral(args);
-
     JS.Expression emitNew() {
       return new JS.New(_emitConstructorName(node.constructedType, ctor),
           _emitArgumentList(args, types: false));
@@ -4331,6 +4357,10 @@
     var args = node.arguments;
     var ctor = node.target;
     var ctorClass = ctor.enclosingClass;
+    if (ctor.isExternal && _isJSNative(ctorClass)) {
+      return _emitJSInteropNew(ctor, args);
+    }
+
     var type = ctorClass.typeParameters.isEmpty
         ? ctorClass.rawType
         : new InterfaceType(ctorClass, args.types);
@@ -4395,7 +4425,6 @@
     }
 
     JS.Expression emitNew() {
-      // Native factory constructors are JS constructors - use new here.
       return new JS.Call(_emitConstructorName(type, ctor),
           _emitArgumentList(args, types: false));
     }
@@ -4403,6 +4432,13 @@
     return node.isConst ? _emitConst(emitNew) : emitNew();
   }
 
+  JS.Expression _emitJSInteropNew(Member ctor, Arguments args) {
+    var ctorClass = ctor.enclosingClass;
+    if (_isObjectLiteral(ctorClass)) return _emitObjectLiteral(args);
+    return new JS.New(_emitConstructorName(ctorClass.rawType, ctor),
+        _emitArgumentList(args, types: false));
+  }
+
   JS.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) return _emitType(type);
@@ -4420,11 +4456,10 @@
   }
 
   bool _isObjectLiteral(Class c) {
-    return _isJSNative(c) && findAnnotation(c, isJSAnonymousAnnotation) != null;
+    return _isJSNative(c) && c.annotations.any(isJSAnonymousAnnotation);
   }
 
-  bool _isJSNative(NamedNode c) =>
-      findAnnotation(c, isPublicJSAnnotation) != null;
+  bool _isJSNative(Class c) => c.annotations.any(isPublicJSAnnotation);
 
   JS.Expression _emitObjectLiteral(Arguments node) {
     var args = _emitArgumentList(node);
@@ -4737,8 +4772,17 @@
     var body = _visitExpression(node.body);
     var temp = _tempVariables.remove(v);
     if (temp != null) {
-      init = new JS.Assignment(temp, init);
-      _letVariables.add(temp);
+      if (_letVariables != null) {
+        init = new JS.Assignment(temp, init);
+        _letVariables.add(temp);
+      } else {
+        // TODO(jmesserly): make sure this doesn't happen on any performance
+        // critical call path.
+        //
+        // Annotations on a top-level, non-lazy function type should be the only
+        // remaining use.
+        return new JS.Call(new JS.ArrowFun([temp], body), [init]);
+      }
     }
     return new JS.Binary(',', init, body);
   }
@@ -4893,3 +4937,13 @@
 
 bool _isObjectMethod(String name) =>
     name == 'toString' || name == 'noSuchMethod';
+
+void _addStatementToList(JS.Statement statement, List<JS.Statement> list) {
+  // If the statement is a nested block, flatten it into the list when
+  // possible.  If the statement is empty, discard it.
+  if (statement is JS.Block && (list.isEmpty || !statement.isScope)) {
+    list.addAll(statement.statements);
+  } else if (statement is! JS.EmptyStatement) {
+    list.add(statement);
+  }
+}
diff --git a/pkg/dev_compiler/lib/src/kernel/js_interop.dart b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
index 7147be1..419823b 100644
--- a/pkg/dev_compiler/lib/src/kernel/js_interop.dart
+++ b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
@@ -10,19 +10,23 @@
 bool _isJSLibrary(Library library) {
   if (library == null) return false;
   var uri = library.importUri;
-  if (uri.scheme == 'package' && uri.path.startsWith('js/')) return true;
-  if (uri.scheme == 'dart') {
-    return uri.path == '_js_helper' || uri.path == '_foreign_helper';
-  }
-  return false;
+  var scheme = uri.scheme;
+  return scheme == 'package' && uri.pathSegments[0] == 'js' ||
+      scheme == 'dart' &&
+          (uri.path == '_js_helper' || uri.path == '_foreign_helper');
 }
 
 bool _annotationIsFromJSLibrary(String expectedName, Expression value) {
+  Class c;
   if (value is ConstructorInvocation) {
-    var c = value.target.enclosingClass;
-    return c.name == expectedName && _isJSLibrary(getLibrary(c));
+    c = value.target.enclosingClass;
+  } else if (value is StaticGet) {
+    var type = value.target.getterType;
+    if (type is InterfaceType) c = type.classNode;
   }
-  return false;
+  return c != null &&
+      c.name == expectedName &&
+      _isJSLibrary(c.enclosingLibrary);
 }
 
 /// Whether [value] is a `@rest` annotation (to be used on function parameters
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 7fc8071..434170f 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -17,13 +17,12 @@
   return n;
 }
 
-final Pattern genericTypeEncodingCharacters = new RegExp('[&^#]');
+final Pattern _syntheticTypeCharacters = new RegExp('[&^#.]');
 
-// TODO(karlklose): add a namer for all identifiers?
 String _escapeIdentifier(String identifier) {
   // Remove the special characters used to encode mixin application class names
   // which are legal in Kernel, but not in JavaScript.
-  return identifier?.replaceAll(genericTypeEncodingCharacters, r'$');
+  return identifier?.replaceAll(_syntheticTypeCharacters, r'$');
 }
 
 /// Returns the escaped name for class [node].
@@ -109,7 +108,7 @@
 String getAnnotationName(NamedNode node, bool test(Expression value)) {
   var match = findAnnotation(node, test);
   if (match is ConstructorInvocation && match.arguments.positional.isNotEmpty) {
-    var first = match.arguments.positional[0];
+    var first = _followConstFields(match.arguments.positional[0]);
     if (first is StringLiteral) {
       return first.value;
     }
@@ -117,6 +116,16 @@
   return null;
 }
 
+Expression _followConstFields(Expression expr) {
+  if (expr is StaticGet) {
+    var target = expr.target;
+    if (target is Field) {
+      return _followConstFields(target.initializer);
+    }
+  }
+  return expr;
+}
+
 /// Finds constant expressions as defined in Dart language spec 4th ed,
 /// 16.1 Constants
 class ConstantVisitor extends ExpressionVisitor<bool> {
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index b589cc1..76e9761 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -141,6 +141,10 @@
     if (field.isStatic) return false;
 
     var class_ = field.enclosingClass;
+    if (class_.isEnum) {
+      // Enums are not extensible.
+      return false;
+    }
     var libraryUri = class_.enclosingLibrary.importUri;
     if (libraryUri.scheme == 'dart' && libraryUri.path.startsWith('_')) {
       // There should be no extensible fields in private SDK libraries.
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/libraries.json b/pkg/dev_compiler/tool/input_sdk/lib/libraries.json
index 1a51699..4c3c787 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/libraries.json
+++ b/pkg/dev_compiler/tool/input_sdk/lib/libraries.json
@@ -110,4 +110,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/dev_compiler/tool/input_sdk/libraries.dart b/pkg/dev_compiler/tool/input_sdk/libraries.dart
index aa4aede..cd7a447 100644
--- a/pkg/dev_compiler/tool/input_sdk/libraries.dart
+++ b/pkg/dev_compiler/tool/input_sdk/libraries.dart
@@ -115,6 +115,9 @@
       implementation: true,
       documented: false,
       platforms: DART2JS_PLATFORM),
+  "cli": const LibraryInfo("cli/cli.dart",
+      categories: "Server",
+      dart2jsPatchPath: "_internal/js_runtime/lib/cli_patch.dart"),
   "svg": const LibraryInfo("svg/dart2js/svg_dart2js.dart",
       categories: "Client",
       maturity: Maturity.WEB_STABLE,
diff --git a/pkg/dev_compiler/tool/input_sdk/libraries.json b/pkg/dev_compiler/tool/input_sdk/libraries.json
index a30411c..96f5163 100644
--- a/pkg/dev_compiler/tool/input_sdk/libraries.json
+++ b/pkg/dev_compiler/tool/input_sdk/libraries.json
@@ -99,4 +99,4 @@
       }
     }
   }
-}
\ No newline at end of file
+}
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/cli_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/cli_patch.dart
new file mode 100644
index 0000000..6921e60
--- /dev/null
+++ b/pkg/dev_compiler/tool/input_sdk/patch/cli_patch.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:_js_helper' show patch;
+
+@patch
+void _waitForEvent(int timeoutMillis) {
+  throw new UnsupportedError("waitForEvent");
+}
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
index 9fe761c..4531ea6 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -691,3 +691,13 @@
   @patch
   _throw(error) => throw error;
 }
+
+// TODO(jmesserly): this class is supposed to be obsolete in Strong Mode, but
+// the front-end crashes without it
+class _DuplicatedFieldInitializerError {
+  final String _name;
+
+  _DuplicatedFieldInitializerError(this._name);
+
+  toString() => "Error: field '$_name' is already initialized.";
+}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_string.dart b/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
index b613734..65b77a8 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_string.dart
@@ -182,13 +182,12 @@
     return JS('String', r'#.toUpperCase()', this);
   }
 
-  // Characters with Whitespace property (Unicode 6.2).
+  // Characters with Whitespace property (Unicode 6.3).
   // 0009..000D    ; White_Space # Cc       <control-0009>..<control-000D>
   // 0020          ; White_Space # Zs       SPACE
   // 0085          ; White_Space # Cc       <control-0085>
   // 00A0          ; White_Space # Zs       NO-BREAK SPACE
   // 1680          ; White_Space # Zs       OGHAM SPACE MARK
-  // 180E          ; White_Space # Zs       MONGOLIAN VOWEL SEPARATOR
   // 2000..200A    ; White_Space # Zs       EN QUAD..HAIR SPACE
   // 2028          ; White_Space # Zl       LINE SEPARATOR
   // 2029          ; White_Space # Zp       PARAGRAPH SEPARATOR
@@ -218,7 +217,6 @@
     }
     switch (codeUnit) {
       case 0x1680:
-      case 0x180E:
       case 0x2000:
       case 0x2001:
       case 0x2002:
diff --git a/pkg/front_end/lib/src/external_state_snapshot.dart b/pkg/front_end/lib/src/external_state_snapshot.dart
index c77c4486..cdb31e9 100644
--- a/pkg/front_end/lib/src/external_state_snapshot.dart
+++ b/pkg/front_end/lib/src/external_state_snapshot.dart
@@ -4,15 +4,15 @@
 
 // TODO(ahe): Remove this file.
 
-import 'package:kernel/kernel.dart' show Library, LibraryDependency, Program;
+import 'package:kernel/kernel.dart' show Library, Program;
 
 /// Helper class to work around modifications in [kernel_generator_impl.dart].
 class ExternalStateSnapshot {
   final List<ExternalState> snapshots;
 
   ExternalStateSnapshot(Program program)
-      : snapshots = new List<ExternalState>.from(program.libraries.map((l) =>
-            new ExternalState(l, l.dependencies.toList(), l.isExternal)));
+      : snapshots = new List<ExternalState>.from(
+            program.libraries.map((l) => new ExternalState(l, l.isExternal)));
 
   void restore() {
     for (ExternalState state in snapshots) {
@@ -23,15 +23,11 @@
 
 class ExternalState {
   final Library library;
-  final List<LibraryDependency> dependencies;
   final bool isExternal;
 
-  ExternalState(this.library, this.dependencies, this.isExternal);
+  ExternalState(this.library, this.isExternal);
 
   void restore() {
     library.isExternal = isExternal;
-    library.dependencies
-      ..clear()
-      ..addAll(dependencies);
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 4eaf799..c90fb50 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -96,6 +96,38 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(String name, DartType _type, DartType _type2)>
+    templateAmbiguousSupertypes = const Template<
+            Message Function(String name, DartType _type, DartType _type2)>(
+        messageTemplate:
+            r"""'#name' can't implement both '#type' and '#type2'""",
+        withArguments: _withArgumentsAmbiguousSupertypes);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(String name, DartType _type, DartType _type2)>
+    codeAmbiguousSupertypes =
+    const Code<Message Function(String name, DartType _type, DartType _type2)>(
+        "AmbiguousSupertypes", templateAmbiguousSupertypes,
+        severity: Severity.error);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsAmbiguousSupertypes(
+    String name, DartType _type, DartType _type2) {
+  NameSystem nameSystem = new NameSystem();
+  StringBuffer buffer = new StringBuffer();
+  new Printer(buffer, syntheticNames: nameSystem).writeNode(_type);
+  String type = '$buffer';
+
+  buffer = new StringBuffer();
+  new Printer(buffer, syntheticNames: nameSystem).writeNode(_type2);
+  String type2 = '$buffer';
+
+  return new Message(codeAmbiguousSupertypes,
+      message: """'$name' can't implement both '$type' and '$type2'""",
+      arguments: {'name': name, 'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeAnnotationOnEnumConstant = messageAnnotationOnEnumConstant;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1935,6 +1967,19 @@
     message: r"""Can't have a default value in a function type.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeFunctionTypedParameterVar =
+    messageFunctionTypedParameterVar;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageFunctionTypedParameterVar = const MessageCode(
+    "FunctionTypedParameterVar",
+    analyzerCode: "FUNCTION_TYPED_PARAMETER_VAR",
+    dart2jsCode: "*fatal*",
+    message:
+        r"""Function-typed parameters can't specify 'const', 'final' or 'var' in place of a return type.""",
+    tip: r"""Try replacing the keyword with a return type.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeGeneratorReturnsValue = messageGeneratorReturnsValue;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index b2c9042..f9556b0 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1292,8 +1292,12 @@
       return new ThisPropertyAccessor(this, token, n, getter, setter);
     } else if (builder.isRegularMethod) {
       assert(builder.isStatic || builder.isTopLevel);
-      return new StaticAccessor(this, token, builder.target, null,
+      StaticAccessor accessor = new StaticAccessor(
+          this, token, builder.target, null,
           prefixName: prefix?.name);
+      return (prefix?.deferred == true)
+          ? new DeferredAccessor(this, token, prefix, accessor)
+          : accessor;
     } else if (builder is PrefixBuilder) {
       if (constantExpressionRequired && builder.deferred) {
         deprecated_addCompileTimeError(
@@ -1329,7 +1333,9 @@
               charOffset, "Not a constant expression.");
         }
       }
-      return accessor;
+      return (prefix?.deferred == true)
+          ? new DeferredAccessor(this, token, prefix, accessor)
+          : accessor;
     }
   }
 
@@ -3632,6 +3638,14 @@
         prefixName, targetOffset, targetClass, readTarget)
       ..fileOffset = offsetForToken(token);
   }
+
+  @override
+  Expression makeDeferredCheck(Expression expression, PrefixBuilder prefix) {
+    return new Let(
+        new VariableDeclaration.forValue(
+            new CheckLibraryIsLoaded(prefix.dependency)),
+        expression);
+  }
 }
 
 class Identifier {
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
index 5f39fe4..a5800d5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -32,6 +32,7 @@
         LoadLibraryAccessor,
         PropertyAccessor,
         ReadOnlyAccessor,
+        DeferredAccessor,
         DelayedErrorAccessor,
         StaticAccessor,
         SuperIndexAccessor,
@@ -138,6 +139,8 @@
   StaticGet makeStaticGet(Member readTarget, Token token,
       {String prefixName, int targetOffset: -1, Class targetClass});
 
+  Expression makeDeferredCheck(Expression expression, PrefixBuilder prefix);
+
   dynamic deprecated_addCompileTimeError(int charOffset, String message);
 
   bool isIdentical(Member member);
@@ -825,6 +828,24 @@
   }
 }
 
+class DeferredAccessor extends kernel.DeferredAccessor with FastaAccessor {
+  DeferredAccessor(BuilderHelper helper, Token token, PrefixBuilder builder,
+      StaticAccessor expression)
+      : super(helper, token, builder, expression);
+
+  String get plainNameForRead {
+    return unsupported(
+        "deferredAccessor.plainNameForRead", offsetForToken(token), uri);
+  }
+
+  StaticAccessor get staticAccessor => super.staticAccessor;
+
+  Expression doInvocation(int offset, Arguments arguments) {
+    return helper.makeDeferredCheck(
+        staticAccessor.doInvocation(offset, arguments), builder);
+  }
+}
+
 class SuperPropertyAccessor extends kernel.SuperPropertyAccessor
     with FastaAccessor {
   SuperPropertyAccessor(BuilderHelper helper, Token token, Name name,
diff --git a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
index d2920fa..c0afd0a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/frontend_accessors.dart
@@ -15,7 +15,7 @@
 
 import 'fasta_accessors.dart' show BuilderHelper;
 
-import 'kernel_builder.dart' show LoadLibraryBuilder;
+import 'kernel_builder.dart' show LoadLibraryBuilder, PrefixBuilder;
 
 import 'kernel_shadow_ast.dart'
     show
@@ -736,6 +736,27 @@
   }
 }
 
+abstract class DeferredAccessor extends Accessor {
+  final PrefixBuilder builder;
+  final StaticAccessor staticAccessor;
+
+  DeferredAccessor(
+      BuilderHelper helper, Token token, this.builder, this.staticAccessor)
+      : super(helper, token);
+
+  Expression _makeRead(ShadowComplexAssignment complexAssignment) {
+    return helper.makeDeferredCheck(
+        staticAccessor._makeRead(complexAssignment), builder);
+  }
+
+  Expression _makeWrite(Expression value, bool voidContext,
+      ShadowComplexAssignment complexAssignment) {
+    return helper.makeDeferredCheck(
+        staticAccessor._makeWrite(value, voidContext, complexAssignment),
+        builder);
+  }
+}
+
 class ReadOnlyAccessor extends Accessor {
   Expression expression;
   VariableDeclaration value;
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
index 3c0a807..31fc317 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_procedure_builder.dart
@@ -114,8 +114,17 @@
     }
     actualBody = newBody;
     if (function != null) {
-      function.body = newBody;
-      newBody?.parent = function;
+      // A forwarding semi-stub is a method that is abstract in the source code,
+      // but which needs to have a forwarding stub body in order to ensure that
+      // covariance checks occur.  We don't want to replace the forwarding stub
+      // body with null.
+      var parent = function.parent;
+      if (!(newBody == null &&
+          parent is Procedure &&
+          parent.isForwardingSemiStub)) {
+        function.body = newBody;
+        newBody?.parent = function;
+      }
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 9ab59f7..d59f8de 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -374,17 +374,20 @@
     loader.builders.forEach((Uri uri, LibraryBuilder library) {
       if (library.loader == loader) {
         library.forEach((String name, Builder builder) {
-          if (builder is SourceClassBuilder) {
-            Class cls = builder.target;
-            if (cls != objectClass) {
-              cls.supertype ??= objectClass.asRawSupertype;
-              builder.supertype ??= new KernelNamedTypeBuilder("Object", null)
-                ..bind(objectClassBuilder);
+          while (builder != null) {
+            if (builder is SourceClassBuilder) {
+              Class cls = builder.target;
+              if (cls != objectClass) {
+                cls.supertype ??= objectClass.asRawSupertype;
+                builder.supertype ??= new KernelNamedTypeBuilder("Object", null)
+                  ..bind(objectClassBuilder);
+              }
+              if (builder.isMixinApplication) {
+                cls.mixedInType = builder.mixedInType.buildSupertype(
+                    library, builder.charOffset, builder.fileUri);
+              }
             }
-            if (builder.isMixinApplication) {
-              cls.mixedInType = builder.mixedInType
-                  .buildSupertype(library, builder.charOffset, builder.fileUri);
-            }
+            builder = builder.next;
           }
         });
       }
@@ -515,7 +518,7 @@
     return new Constructor(
         new FunctionNode(new EmptyStatement(), returnType: const VoidType()),
         name: new Name(""),
-        isSyntheticDefault: true);
+        isSynthetic: true);
   }
 
   void computeCoreTypes() {
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index 062b01d..cc9c060 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -74,6 +74,22 @@
   return token;
 }
 
+TypeContinuation typeContinuationAfterVar(TypeContinuation typeContinuation) {
+  switch (typeContinuation) {
+    case TypeContinuation.NormalFormalParameter:
+      return TypeContinuation.NormalFormalParameterAfterVar;
+
+    case TypeContinuation.OptionalPositionalFormalParameter:
+      return TypeContinuation.OptionalPositionalFormalParameterAfterVar;
+
+    case TypeContinuation.NamedFormalParameter:
+      return TypeContinuation.NamedFormalParameterAfterVar;
+
+    default:
+      return TypeContinuation.OptionalAfterVar;
+  }
+}
+
 TypeContinuation typeContinuationFromMemberKind(
         bool isVarAllowed, MemberKind memberKind) =>
     (isVarAllowed || memberKind == MemberKind.GeneralizedFunctionType)
@@ -109,6 +125,7 @@
       memberKind != MemberKind.NonStaticField;
 
   Token parseOpt(Token token) {
+    assert(lastModifier != null);
     if (token != lastModifier) {
       if (optional('external', token.next)) {
         token = parseExternalOpt(token);
@@ -173,6 +190,7 @@
       return token;
     }
     switch (memberKind) {
+      case MemberKind.Local:
       case MemberKind.StaticField:
       case MemberKind.StaticMethod:
       case MemberKind.TopLevelField:
@@ -268,24 +286,7 @@
           next, fasta.templateExtraneousModifier);
       return next;
     }
-    switch (typeContinuation ?? TypeContinuation.Required) {
-      case TypeContinuation.NormalFormalParameter:
-        typeContinuation = TypeContinuation.NormalFormalParameterAfterVar;
-        break;
-
-      case TypeContinuation.OptionalPositionalFormalParameter:
-        typeContinuation =
-            TypeContinuation.OptionalPositionalFormalParameterAfterVar;
-        break;
-
-      case TypeContinuation.NamedFormalParameter:
-        typeContinuation = TypeContinuation.NamedFormalParameterAfterVar;
-        break;
-
-      default:
-        typeContinuation = TypeContinuation.OptionalAfterVar;
-        break;
-    }
+    typeContinuation = typeContinuationAfterVar(typeContinuation);
     varFinalOrConst ??= next;
     modifierCount++;
     return parser.parseModifier(token);
@@ -306,7 +307,7 @@
       FormalParameterKind parameterKind,
       bool isVarAllowed,
       TypeContinuation typeContinuation,
-      Token lastModifier)
+      [Token lastModifier])
       : super(parser, memberKind, parameterKind, isVarAllowed, typeContinuation,
             lastModifier);
 
@@ -344,6 +345,52 @@
     return token;
   }
 
+  Token parseRecovery(Token token,
+      {Token covariantToken, Token varFinalOrConst}) {
+    if (covariantToken != null) {
+      this.covariantToken = covariantToken;
+      ++modifierCount;
+    }
+    if (varFinalOrConst != null) {
+      ++modifierCount;
+      if (optional('var', varFinalOrConst)) {
+        varToken = varFinalOrConst;
+      } else if (optional('final', varFinalOrConst)) {
+        finalToken = varFinalOrConst;
+      } else if (optional('const', varFinalOrConst)) {
+        constToken = varFinalOrConst;
+      } else {
+        throw "Internal error: Unexpected varFinalOrConst '$varFinalOrConst'.";
+      }
+    }
+
+    // Process invalid and out-of-order modifiers
+    Token next = token.next;
+    while (isModifier(next)) {
+      final value = next.stringValue;
+      if (identical('abstract', value)) {
+        token = parseAbstract(token);
+      } else if (identical('const', value)) {
+        token = parseConst(token);
+      } else if (identical('covariant', value)) {
+        token = parseCovariantOpt(token);
+      } else if (identical('external', value)) {
+        token = parseExternalOpt(token);
+      } else if (identical('final', value)) {
+        token = parseFinal(token);
+      } else if (identical('static', value)) {
+        token = parseStaticOpt(token);
+      } else if (identical('var', value)) {
+        token = parseVar(token);
+      } else {
+        token = parseExtraneousModifier(token);
+      }
+      next = token.next;
+    }
+
+    return token;
+  }
+
   Token parseAbstract(Token token) {
     assert(optional('abstract', token.next));
     if (memberKind == MemberKind.NonStaticField ||
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index fd654fe..8c558ac 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -79,11 +79,11 @@
         ClassMethodModifierContext,
         FactoryModifierContext,
         ModifierContext,
+        ModifierRecoveryContext,
         TopLevelMethodModifierContext,
         isModifier,
         parseModifiersOpt,
-        skipToLastModifier,
-        typeContinuationFromMemberKind;
+        typeContinuationAfterVar;
 
 import 'recovery_listeners.dart'
     show ClassHeaderRecoveryListener, ImportRecoveryListener;
@@ -1152,31 +1152,59 @@
   /// ```
   Token parseFormalParameter(
       Token token, FormalParameterKind parameterKind, MemberKind memberKind) {
+    assert(parameterKind != null);
     token = parseMetadataStar(token);
     Token next = token.next;
     listener.beginFormalParameter(next, memberKind);
 
     TypeContinuation typeContinuation =
         typeContinuationFromFormalParameterKind(parameterKind);
+    Token varFinalOrConst;
     if (isModifier(next)) {
-      ModifierContext modifierContext = parseModifiersOpt(
-          this,
-          token,
-          skipToLastModifier(token),
-          memberKind,
-          parameterKind,
-          false,
-          typeContinuation);
-      typeContinuation = modifierContext.typeContinuation;
-      memberKind = modifierContext.memberKind;
-      token = modifierContext.lastModifier;
-      modifierContext = null;
+      int modifierCount = 0;
+      Token covariantToken;
+      if (optional('covariant', next)) {
+        if (memberKind != MemberKind.StaticMethod &&
+            memberKind != MemberKind.TopLevelMethod) {
+          covariantToken = token = parseModifier(token);
+          ++modifierCount;
+          next = token.next;
+        }
+      }
+
+      if (isModifier(next)) {
+        if (optional('var', next)) {
+          typeContinuation = typeContinuationAfterVar(typeContinuation);
+          varFinalOrConst = token = parseModifier(token);
+          ++modifierCount;
+          next = token.next;
+        } else if (optional('final', next)) {
+          varFinalOrConst = token = parseModifier(token);
+          ++modifierCount;
+          next = token.next;
+        }
+
+        if (isModifier(next)) {
+          // Recovery
+          ModifierRecoveryContext modifierContext = new ModifierRecoveryContext(
+              this, memberKind, parameterKind, false, typeContinuation);
+          token = modifierContext.parseRecovery(token,
+              covariantToken: covariantToken, varFinalOrConst: varFinalOrConst);
+
+          memberKind = modifierContext.memberKind;
+          typeContinuation = modifierContext.typeContinuation;
+          varFinalOrConst = modifierContext.varFinalOrConst;
+          modifierCount = modifierContext.modifierCount;
+          modifierContext = null;
+        }
+      }
+      listener.handleModifiers(modifierCount);
     } else {
       listener.handleModifiers(0);
-      typeContinuation ??= typeContinuationFromMemberKind(false, memberKind);
     }
 
-    return parseType(token, typeContinuation, null, memberKind);
+    return parseType(
+        token, typeContinuation, null, memberKind, varFinalOrConst);
   }
 
   /// ```
@@ -2061,7 +2089,8 @@
   Token parseType(Token token,
       [TypeContinuation continuation = TypeContinuation.Required,
       IdentifierContext continuationContext,
-      MemberKind memberKind]) {
+      MemberKind memberKind,
+      Token varFinalOrConst]) {
     /// True if we've seen the `var` keyword.
     bool hasVar = false;
 
@@ -2580,12 +2609,20 @@
           Token closer = closeBraceTokenFor(token);
           if (closer != null) {
             if (optional("(", closer.next)) {
+              if (varFinalOrConst != null) {
+                reportRecoverableError(
+                    varFinalOrConst, fasta.messageFunctionTypedParameterVar);
+              }
               inlineFunctionTypeStart = beforeToken;
               beforeToken = token;
               token = token.next;
             }
           }
         } else if (optional("(", token)) {
+          if (varFinalOrConst != null) {
+            reportRecoverableError(
+                varFinalOrConst, fasta.messageFunctionTypedParameterVar);
+          }
           inlineFunctionTypeStart = beforeToken;
           beforeToken = closeBraceTokenFor(token);
           token = beforeToken.next;
@@ -4186,6 +4223,8 @@
       throw "Internal error: Unknown asyncState: '$asyncState'.";
     } else if (identical(value, 'const')) {
       return parseExpressionStatementOrConstDeclaration(token);
+    } else if (isModifier(token.next)) {
+      return parseVariablesDeclaration(token);
     } else if (token.next.isIdentifier) {
       return parseExpressionStatementOrDeclaration(token);
     } else if (identical(value, '@')) {
@@ -5360,22 +5399,43 @@
   Token parseVariablesDeclarationMaybeSemicolon(
       Token token, bool endWithSemicolon) {
     token = parseMetadataStar(token);
+    Token next = token.next;
 
     MemberKind memberKind = MemberKind.Local;
     TypeContinuation typeContinuation;
-    if (isModifier(token.next)) {
-      ModifierContext modifierContext = parseModifiersOpt(
-          this, token, skipToLastModifier(token), memberKind, null, true, null);
-      token = modifierContext.lastModifier;
-      typeContinuation = modifierContext.typeContinuation;
-      memberKind = modifierContext.memberKind;
-      modifierContext = null;
+    Token varFinalOrConst;
+    if (isModifier(next)) {
+      if (optional('var', next)) {
+        typeContinuation = TypeContinuation.OptionalAfterVar;
+        varFinalOrConst = token = parseModifier(token);
+        next = token.next;
+      } else if (optional('final', next) || optional('const', next)) {
+        typeContinuation = TypeContinuation.Optional;
+        varFinalOrConst = token = parseModifier(token);
+        next = token.next;
+      }
+
+      if (isModifier(next)) {
+        // Recovery
+        ModifierRecoveryContext modifierContext = new ModifierRecoveryContext(
+            this, memberKind, null, true, typeContinuation);
+        token = modifierContext.parseRecovery(token,
+            varFinalOrConst: varFinalOrConst);
+
+        memberKind = modifierContext.memberKind;
+        typeContinuation = modifierContext.typeContinuation;
+        varFinalOrConst = modifierContext.varFinalOrConst;
+        listener.handleModifiers(modifierContext.modifierCount);
+        modifierContext = null;
+      } else {
+        listener.handleModifiers(1);
+      }
     } else {
       listener.handleModifiers(0);
-      typeContinuation = typeContinuationFromMemberKind(true, memberKind);
     }
 
-    token = parseType(token, typeContinuation, null, memberKind);
+    token = parseType(
+        token, typeContinuation ?? TypeContinuation.Required, null, memberKind);
     return parseVariablesDeclarationMaybeSemicolonRest(token, endWithSemicolon);
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 9f8bf37..9c361ef 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -11,12 +11,22 @@
 import 'package:front_end/src/fasta/type_inference/interface_resolver.dart'
     show InterfaceResolver;
 
-import 'package:kernel/ast.dart' show Arguments, Expression, Library, Program;
+import 'package:kernel/ast.dart'
+    show
+        Arguments,
+        Class,
+        Expression,
+        Library,
+        LibraryDependency,
+        Program,
+        Supertype;
 
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 
 import 'package:kernel/core_types.dart' show CoreTypes;
 
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
+
 import '../../api_prototype/file_system.dart';
 
 import '../../base/instrumentation.dart'
@@ -45,6 +55,7 @@
         Message,
         SummaryTemplate,
         Template,
+        templateAmbiguousSupertypes,
         templateCyclicClassHierarchy,
         templateExtendingEnum,
         templateExtendingRestricted,
@@ -541,20 +552,58 @@
   }
 
   Program computeFullProgram() {
-    List<Library> libraries = <Library>[];
+    Set<Library> libraries = new Set<Library>();
+    List<Library> workList = <Library>[];
     builders.forEach((Uri uri, LibraryBuilder library) {
       if (!library.isPart && !library.isPatch) {
-        libraries.add(library.target);
+        if (libraries.add(library.target)) {
+          workList.add(library.target);
+        }
       }
     });
+    while (workList.isNotEmpty) {
+      Library library = workList.removeLast();
+      for (LibraryDependency dependency in library.dependencies) {
+        if (libraries.add(dependency.targetLibrary)) {
+          workList.add(dependency.targetLibrary);
+        }
+      }
+    }
     return new Program()..libraries.addAll(libraries);
   }
 
   void computeHierarchy() {
-    hierarchy = new ClassHierarchy.deprecated_incremental(computeFullProgram());
+    List<List> ambiguousTypesRecords = [];
+    hierarchy = new ClassHierarchy(computeFullProgram(),
+        onAmbiguousSupertypes: (Class cls, Supertype a, Supertype b) {
+      if (ambiguousTypesRecords != null) {
+        ambiguousTypesRecords.add([cls, a, b]);
+      }
+    });
+    for (List record in ambiguousTypesRecords) {
+      handleAmbiguousSupertypes(record[0], record[1], record[2]);
+    }
+    ambiguousTypesRecords = null;
     ticker.logMs("Computed class hierarchy");
   }
 
+  void handleAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {
+    String name = cls.name;
+    TypeEnvironment env = new TypeEnvironment(coreTypes, hierarchy,
+        strongMode: target.strongMode);
+
+    if (cls.isSyntheticMixinImplementation) return;
+
+    if (env.isSubtypeOf(a.asInterfaceType, b.asInterfaceType)) return;
+    addProblem(
+        templateAmbiguousSupertypes.withArguments(
+            name, a.asInterfaceType, b.asInterfaceType),
+        cls.fileOffset,
+        cls.fileUri);
+  }
+
+  void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
+
   void computeCoreTypes(Program program) {
     coreTypes = new CoreTypes(program);
     ticker.logMs("Computed core types");
@@ -634,8 +683,9 @@
     // target those forwarding stubs.
     // TODO(paulberry): could we make this unnecessary by not clearing class
     // inference info?
-    typeInferenceEngine.classHierarchy = hierarchy =
-        new ClassHierarchy.deprecated_incremental(computeFullProgram());
+    typeInferenceEngine.classHierarchy = hierarchy = new ClassHierarchy(
+        computeFullProgram(),
+        onAmbiguousSupertypes: ignoreAmbiguousSupertypes);
     ticker.logMs("Performed top level inference");
   }
 
diff --git a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
index 78cf4a8..07486e1 100644
--- a/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
+++ b/pkg/front_end/lib/src/fasta/testing/kernel_chain.dart
@@ -9,7 +9,7 @@
 
 import 'dart:async' show Future;
 
-import 'dart:io' show Directory, File, IOSink, Platform;
+import 'dart:io' show Directory, File, IOSink;
 
 import 'dart:typed_data' show Uint8List;
 
@@ -275,19 +275,9 @@
 }
 
 Future<String> runDiff(Uri expected, String actual) async {
-  if (Platform.isWindows) {
-    // TODO(ahe): Implement this for Windows.
-    return """
-==> Expected ($expected) <==
-${new File.fromUri(expected).readAsStringSync()}
-
-==> Actual <==
-$actual
-
-""";
-  }
-  StdioProcess process = await StdioProcess
-      .run("diff", <String>["-u", expected.toFilePath(), "-"], input: actual);
+  StdioProcess process = await StdioProcess.run(
+      "git", <String>["diff", "--no-index", "-u", expected.toFilePath(), "-"],
+      input: actual, runInShell: true);
   return process.output;
 }
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
index 1105396..54dd9e5 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -366,11 +366,16 @@
     }
     procedure.isAbstract = false;
     if (!procedure.isForwardingStub) {
+      // This procedure exists abstractly in the source code; we need to make it
+      // concrete and give it a body that is a forwarding stub.  This situation
+      // is called a "forwarding semi-stub".
+      procedure.isForwardingStub = true;
+      procedure.isForwardingSemiStub = true;
       _interfaceResolver._instrumentation?.record(
           procedure.fileUri,
           procedure.fileOffset,
           'forwardingStub',
-          new InstrumentationValueLiteral('implementation'));
+          new InstrumentationValueLiteral('semi-stub'));
     }
     var positionalArguments = function.positionalParameters
         .map<Expression>((parameter) => new VariableGet(parameter))
@@ -799,6 +804,7 @@
       }
       if (resolution is Procedure &&
           resolution.isForwardingStub &&
+          !resolution.isForwardingSemiStub &&
           identical(resolution.enclosingClass, class_)) {
         if (strongMode) class_.addMember(resolution);
         _instrumentation?.record(
@@ -971,7 +977,9 @@
     for (var procedure in class_.procedures) {
       if (procedure.isStatic) continue;
       // Forwarding stubs are annotated separately
-      if (procedure.isForwardingStub) continue;
+      if (procedure.isForwardingStub && !procedure.isForwardingSemiStub) {
+        continue;
+      }
       void recordFormalAnnotations(VariableDeclaration formal) {
         recordCovariance(formal.fileOffset, formal.isCovariant,
             formal.isGenericCovariantInterface, formal.isGenericCovariantImpl);
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 2ff707a..a41e93a 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -80,7 +80,6 @@
     dillTarget.loader.libraries.forEach((lib) {
       // TODO(ahe): Don't do this, and remove [external_state_snapshot.dart].
       lib.isExternal = true;
-      lib.dependencies.clear();
     });
 
     // Linked dependencies are meant to be part of the program so they are not
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index ebab622..885b361 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -278,6 +278,16 @@
   script:
     - "class C { static f; }"
 
+FunctionTypedParameterVar:
+  template: "Function-typed parameters can't specify 'const', 'final' or 'var' in place of a return type."
+  tip: "Try replacing the keyword with a return type."
+  analyzerCode: FUNCTION_TYPED_PARAMETER_VAR
+  dart2jsCode: "*fatal*"
+  script:
+    - "void f(const x()) {}"
+    - "void f(final x()) {}"
+    - "void f(var x()) {}"
+
 AbstractClassMember:
   template: "Members of classes can't be declared to be 'abstract'."
   tip: "Try removing the 'abstract' keyword. You can add the 'abstract' keyword before the class declaration."
@@ -1786,6 +1796,7 @@
       C c;
       c.foo();
     }
+
 SourceOutlineSummary:
   template: |
     Built outlines for #count compilation units (#count2 bytes) in #string, that is,
@@ -1812,3 +1823,7 @@
   template: "Can't infer the type of '#string': circularity found during type inference."
   tip: "Specify the type explicitly."
   severity: ERROR
+
+AmbiguousSupertypes:
+  template: "'#name' can't implement both '#type' and '#type2'"
+  severity: ERROR
diff --git a/pkg/front_end/test/src/incremental/mock_sdk.dart b/pkg/front_end/test/src/incremental/mock_sdk.dart
index f2b817e..1cbbc83 100644
--- a/pkg/front_end/test/src/incremental/mock_sdk.dart
+++ b/pkg/front_end/test/src/incremental/mock_sdk.dart
@@ -302,6 +302,7 @@
   addSdkLibrary('convert', 'library dart.convert;');
   addSdkLibrary('developer', 'library dart.developer;');
   addSdkLibrary('io', 'library dart.io;');
+  addSdkLibrary('cli', 'library dart.cli;');
   addSdkLibrary('isolate', 'library dart.isolate;');
   addSdkLibrary('math', '''
 library dart.math;
diff --git a/pkg/front_end/testcases/ast_builder.status b/pkg/front_end/testcases/ast_builder.status
index b86de60..55d5d5f 100644
--- a/pkg/front_end/testcases/ast_builder.status
+++ b/pkg/front_end/testcases/ast_builder.status
@@ -10,6 +10,11 @@
 argument_mismatch: Crash
 bad_setter_abstract: Crash
 cascade: Crash
+check_deferred_read: Crash
+check_deferred_before_write: Crash
+check_deferred_before_call: Crash
+check_deferred_before_args: Crash
+check_deferred_before_args2: Crash
 classes: Crash
 duplicated_named_args_3: Crash
 dynamic_and_void: Fail
@@ -109,6 +114,7 @@
 rasta/malformed_function: Crash
 rasta/mandatory_parameter_initializer: Crash
 rasta/parser_error: Crash
+rasta/previsit_deferred: Crash
 rasta/static: Crash
 rasta/super_initializer: Crash
 rasta/supports_reflection: VerificationError
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart b/pkg/front_end/testcases/check_deferred_before_args.dart
new file mode 100644
index 0000000..cd12c6d
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {
+  lib.x = m2();
+  lib.m(m2());
+}
+
+m2() => 1;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.direct.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.direct.expect
new file mode 100644
index 0000000..0ff5bf9
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.direct.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = self::m2();
+  let final dynamic #t2 = CheckLibraryIsLoaded(lib) in def::m(self::m2());
+}
+static method m2() → dynamic
+  return 1;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.outline.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.outline.expect
new file mode 100644
index 0000000..8140e58
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.outline.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
+static method test() → dynamic
+  ;
+static method m2() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect
new file mode 100644
index 0000000..0ff5bf9
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args.dart.strong.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = self::m2();
+  let final dynamic #t2 = CheckLibraryIsLoaded(lib) in def::m(self::m2());
+}
+static method m2() → dynamic
+  return 1;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart b/pkg/front_end/testcases/check_deferred_before_args2.dart
new file mode 100644
index 0000000..d885bb9
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+
+test() async {
+  // The current evaluation order will triger the check of lib.m before the
+  // loadLibrary call.
+  lib.m(await lib.loadLibrary());
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.direct.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.direct.expect
new file mode 100644
index 0000000..5b1c7ee
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.direct.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic async {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(await LoadLibrary(lib));
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.outline.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
+static method test() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect
new file mode 100644
index 0000000..5b1c7ee
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_args2.dart.strong.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic async {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(await LoadLibrary(lib));
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart b/pkg/front_end/testcases/check_deferred_before_call.dart
new file mode 100644
index 0000000..aa6ad85
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+
+test() {
+  lib.m(3);
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.direct.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.direct.expect
new file mode 100644
index 0000000..9aef4cf
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.direct.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(3);
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.outline.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
+static method test() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect
new file mode 100644
index 0000000..9aef4cf
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_call.dart.strong.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::m(3);
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart b/pkg/front_end/testcases/check_deferred_before_write.dart
new file mode 100644
index 0000000..5a8f96c
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {
+  lib.x = 2;
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.direct.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.direct.expect
new file mode 100644
index 0000000..2b7ef3d
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.direct.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = 2;
+}
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.outline.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
+static method test() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect
new file mode 100644
index 0000000..2b7ef3d
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_before_write.dart.strong.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x = 2;
+}
diff --git a/pkg/front_end/testcases/check_deferred_read.dart b/pkg/front_end/testcases/check_deferred_read.dart
new file mode 100644
index 0000000..0cebef0
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+import 'deferred_lib.dart' deferred as lib;
+
+main() {}
+test() {
+  print(lib.x + 1);
+}
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.direct.expect b/pkg/front_end/testcases/check_deferred_read.dart.direct.expect
new file mode 100644
index 0000000..5fd285b
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read.dart.direct.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print((let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x).+(1));
+}
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.outline.expect b/pkg/front_end/testcases/check_deferred_read.dart.outline.expect
new file mode 100644
index 0000000..7a4d537
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read.dart.outline.expect
@@ -0,0 +1,7 @@
+library;
+import self as self;
+
+static method main() → dynamic
+  ;
+static method test() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/check_deferred_read.dart.strong.expect b/pkg/front_end/testcases/check_deferred_read.dart.strong.expect
new file mode 100644
index 0000000..5fd285b
--- /dev/null
+++ b/pkg/front_end/testcases/check_deferred_read.dart.strong.expect
@@ -0,0 +1,9 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  core::print((let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::x).+(1));
+}
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart
new file mode 100644
index 0000000..3385d23
--- /dev/null
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+ * for details. All rights reserved. Use of this source code is governed by a
+ * BSD-style license that can be found in the LICENSE file.
+ */
+/**
+ * @assertion
+ *  metadata:
+ *   (‘@’ qualified (‘.’ identifier)? (arguments)?)*
+ *   ;
+ * @description Check that it is a compile time error, if @ is missing
+ * @compile-error
+ * @author a.semenov@unipro.ru
+ */
+
+class A {
+  const A();
+}
+
+A()
+class B {}
+
+main() {
+}
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.expect
new file mode 100644
index 0000000..6262bfd
--- /dev/null
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.direct.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:9: Error: Duplicated name: A\nclass A {\n        ^";
+}
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect
new file mode 100644
index 0000000..869f502
--- /dev/null
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.outline.expect
@@ -0,0 +1,16 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  const constructor •() → void
+    ;
+}
+class B extends core::Object {
+  default constructor •() → void
+    ;
+}
+static method A() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect
new file mode 100644
index 0000000..6262bfd
--- /dev/null
+++ b/pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart.strong.expect
@@ -0,0 +1,6 @@
+library;
+import self as self;
+
+static method #main() → dynamic {
+  throw "pkg/front_end/testcases/co19_language_metadata_syntax_t04.dart:16:9: Error: Duplicated name: A\nclass A {\n        ^";
+}
diff --git a/pkg/front_end/testcases/compile.status b/pkg/front_end/testcases/compile.status
index 41e6f96..3945492 100644
--- a/pkg/front_end/testcases/compile.status
+++ b/pkg/front_end/testcases/compile.status
@@ -120,3 +120,5 @@
 rasta/foo: RuntimeError # Expected, this file has no main method.
 
 incomplete_field_formal_parameter: Fail # Fasta doesn't recover well
+
+co19_language_metadata_syntax_t04: RuntimeError # Fasta doesn't recover well
diff --git a/pkg/front_end/testcases/deferred_lib.dart b/pkg/front_end/testcases/deferred_lib.dart
new file mode 100644
index 0000000..b08a2df
--- /dev/null
+++ b/pkg/front_end/testcases/deferred_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE.md file.
+
+dynamic m(x) => null;
+
+var x = 0;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart b/pkg/front_end/testcases/rasta/previsit_deferred.dart
index 6bdd3e9..ac2c00c 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart
@@ -4,6 +4,7 @@
 
 import 'deferred_lib.dart' deferred as lib;
 
-main() {
+main() {}
+test() {
   lib.foo();
 }
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.direct.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.direct.expect
index 93e2b71..f479708 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.direct.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.direct.expect
@@ -2,6 +2,7 @@
 import self as self;
 import "./deferred_lib.dart" as def;
 
-static method main() → dynamic {
-  def::foo();
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::foo();
 }
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.outline.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.outline.expect
index 6a28c0d..7a4d537 100644
--- a/pkg/front_end/testcases/rasta/previsit_deferred.dart.outline.expect
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.outline.expect
@@ -3,3 +3,5 @@
 
 static method main() → dynamic
   ;
+static method test() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect
new file mode 100644
index 0000000..f479708
--- /dev/null
+++ b/pkg/front_end/testcases/rasta/previsit_deferred.dart.strong.expect
@@ -0,0 +1,8 @@
+library;
+import self as self;
+import "./deferred_lib.dart" as def;
+
+static method main() → dynamic {}
+static method test() → dynamic {
+  let final dynamic #t1 = CheckLibraryIsLoaded(lib) in def::foo();
+}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
index c38e6e0..111cb15 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart
@@ -14,7 +14,7 @@
 }
 
 class C extends B implements I<num> {
-  void /*@forwardingStub=implementation*/ f(num /*@covariance=genericImpl*/ x);
+  void /*@forwardingStub=semi-stub*/ f(num /*@covariance=genericImpl*/ x);
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.strong.expect b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.strong.expect
index 0a9b961..ac8f153 100644
--- a/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.strong.expect
+++ b/pkg/front_end/testcases/runtime_checks_new/abstract_override_becomes_forwarding_stub.dart.strong.expect
@@ -18,6 +18,7 @@
   default constructor •() → void
     : super self::B::•()
     ;
-  method f(generic-covariant-impl core::num x) → void;
+  forwarding-stub forwarding-semi-stub method f(generic-covariant-impl core::num x) → void
+    return super.{self::B::f}(x);
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 8f24726..ec8fc44 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -67,6 +67,7 @@
 unused_methods: Fail
 void_methods: Fail
 warn_unresolved_sends: Fail # Test assumes Dart 1.0 semantics
+check_deferred_read: Fail
 
 inference/abstract_class_instantiation: Fail # Issue #30040
 inference/conflicts_can_happen: TypeCheckError
@@ -174,7 +175,6 @@
 rasta/mixin_library: TypeCheckError
 rasta/native_is_illegal: Fail
 rasta/parser_error: Fail
-rasta/previsit_deferred: Fail
 rasta/static: Fail
 rasta/super: TypeCheckError
 rasta/super_initializer: Fail
@@ -217,3 +217,5 @@
 rasta/foo: RuntimeError # Expected, this file has no main method.
 
 incomplete_field_formal_parameter: Fail # Fasta doesn't recover well
+
+co19_language_metadata_syntax_t04: RuntimeError # Fasta doesn't recover well
diff --git a/pkg/js_ast/pubspec.yaml b/pkg/js_ast/pubspec.yaml
index accf876..6994e78 100644
--- a/pkg/js_ast/pubspec.yaml
+++ b/pkg/js_ast/pubspec.yaml
@@ -3,6 +3,6 @@
 description: Library creating and printing JavaScript ASTs.
 homepage: http://www.dartlang.org
 dev_dependencies:
-  unittest: ">=0.9.0 <0.10.0"
+  test: '^0.12.29'
 environment:
   sdk: ">=0.8.10+6 <2.0.0"
diff --git a/pkg/js_ast/test/printer_callback_test.dart b/pkg/js_ast/test/printer_callback_test.dart
index 6483d28..7d8fb30 100644
--- a/pkg/js_ast/test/printer_callback_test.dart
+++ b/pkg/js_ast/test/printer_callback_test.dart
@@ -9,7 +9,7 @@
 library js_ast.printer.callback_test;
 
 import 'package:js_ast/js_ast.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
 
 enum TestMode {
   INPUT,
@@ -246,5 +246,7 @@
 }
 
 void main() {
-  DATA.forEach(check);
+  test('printer callback test', () {
+    DATA.forEach(check);
+  });
 }
diff --git a/pkg/js_ast/test/string_escape_test.dart b/pkg/js_ast/test/string_escape_test.dart
index 118225b..9277ed6 100644
--- a/pkg/js_ast/test/string_escape_test.dart
+++ b/pkg/js_ast/test/string_escape_test.dart
@@ -6,7 +6,7 @@
 
 import 'package:js_ast/js_ast.dart';
 import 'package:js_ast/src/characters.dart';
-import 'package:unittest/unittest.dart';
+import 'package:test/test.dart';
 
 const int $LCURLY = $OPEN_CURLY_BRACKET;
 const int $RCURLY = $CLOSE_CURLY_BRACKET;
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 519bd6d..85e2fbe 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -324,7 +324,7 @@
   CanonicalNameReference canonicalName;
   FileOffset fileOffset;
   FileOffset fileEndOffset;
-  Byte flags (isConst, isExternal);
+  Byte flags (isConst, isExternal, isSynthetic);
   Name name;
   UriReference fileUri;
   List<Expression> annotations;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index eb61c33..c07f52a 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1234,7 +1234,7 @@
       {Name name,
       bool isConst: false,
       bool isExternal: false,
-      bool isSyntheticDefault: false,
+      bool isSynthetic: false,
       List<Initializer> initializers,
       int transformerFlags: 0,
       this.fileUri,
@@ -1245,20 +1245,20 @@
     setParents(this.initializers, this);
     this.isConst = isConst;
     this.isExternal = isExternal;
-    this.isSyntheticDefault = isSyntheticDefault;
+    this.isSynthetic = isSynthetic;
     this.transformerFlags = transformerFlags;
   }
 
   static const int FlagConst = 1 << 0; // Must match serialized bit positions.
   static const int FlagExternal = 1 << 1;
-  static const int FlagSyntheticDefault = 1 << 2;
+  static const int FlagSynthetic = 1 << 2;
 
   bool get isConst => flags & FlagConst != 0;
   bool get isExternal => flags & FlagExternal != 0;
 
-  /// True if this is a synthetic default constructor inserted in a class that
+  /// True if this is a synthetic constructor inserted in a class that
   /// does not otherwise declare any constructors.
-  bool get isSyntheticDefault => flags & FlagSyntheticDefault != 0;
+  bool get isSynthetic => flags & FlagSynthetic != 0;
 
   void set isConst(bool value) {
     flags = value ? (flags | FlagConst) : (flags & ~FlagConst);
@@ -1268,10 +1268,8 @@
     flags = value ? (flags | FlagExternal) : (flags & ~FlagExternal);
   }
 
-  void set isSyntheticDefault(bool value) {
-    flags = value
-        ? (flags | FlagSyntheticDefault)
-        : (flags & ~FlagSyntheticDefault);
+  void set isSynthetic(bool value) {
+    flags = value ? (flags | FlagSynthetic) : (flags & ~FlagSynthetic);
   }
 
   bool get isInstanceMember => false;
@@ -1363,7 +1361,6 @@
       {Name name,
       bool isConst: false,
       bool isExternal: false,
-      bool isSyntheticDefault: false,
       int transformerFlags: 0,
       List<DartType> typeArguments,
       List<TypeParameter> typeParameters,
@@ -1390,7 +1387,6 @@
 
   static const int FlagConst = 1 << 0; // Must match serialized bit positions.
   static const int FlagExternal = 1 << 1;
-  static const int FlagSyntheticDefault = 1 << 2;
 
   bool get isConst => flags & FlagConst != 0;
   bool get isExternal => flags & FlagExternal != 0;
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index d43b7ff..5f2954d 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -656,10 +656,6 @@
 
   void _readLibraryDependencies(Library library) {
     int length = readUInt();
-    if (library.isExternal) {
-      assert(length == 0);
-      return;
-    }
     library.dependencies.length = length;
     for (int i = 0; i < length; ++i) {
       library.dependencies[i] = readLibraryDependency(library);
diff --git a/pkg/kernel/lib/class_hierarchy.dart b/pkg/kernel/lib/class_hierarchy.dart
index 5eb3ab5..397e7f7 100644
--- a/pkg/kernel/lib/class_hierarchy.dart
+++ b/pkg/kernel/lib/class_hierarchy.dart
@@ -11,16 +11,25 @@
 
 import 'src/incremental_class_hierarchy.dart' show IncrementalClassHierarchy;
 
+typedef HandleAmbiguousSupertypes = void Function(Class, Supertype, Supertype);
+
 /// Interface for answering various subclassing queries.
 /// TODO(scheglov) Several methods are not used, or used only in tests.
 /// Check if these methods are not useful and should be removed .
 abstract class ClassHierarchy {
-  factory ClassHierarchy(Program program) {
+  factory ClassHierarchy(Program program,
+      {HandleAmbiguousSupertypes onAmbiguousSupertypes}) {
     int numberOfClasses = 0;
     for (var library in program.libraries) {
       numberOfClasses += library.classes.length;
     }
-    return new ClosedWorldClassHierarchy._internal(program, numberOfClasses)
+    onAmbiguousSupertypes ??= (Class cls, Supertype a, Supertype b) {
+      if (!cls.isSyntheticMixinImplementation) {
+        throw "$cls can't implement both $a and $b";
+      }
+    };
+    return new ClosedWorldClassHierarchy._internal(
+        program, numberOfClasses, onAmbiguousSupertypes)
       .._initialize();
   }
 
@@ -94,6 +103,24 @@
   /// is resolved if the class was not abstract.
   Member getDispatchTarget(Class class_, Name name, {bool setter: false});
 
+  /// Returns the list of potential targets of dynamic dispatch to an instance
+  /// of [class_].
+  ///
+  /// If [setters] is `false`, only potential targets of a getter or call
+  /// dispatch are returned.  If [setters] is `true`, only potential targets
+  /// of a setter dispatch are returned.
+  ///
+  /// See [getDispatchTarget] for more details.
+  ///
+  /// The returned list should not be modified.
+  List<Member> getDispatchTargets(Class class_, {bool setters: false});
+
+  /// Returns the single concrete target for invocation of the given interface
+  /// target, or `null` if it could not be resolved or there are multiple
+  /// possible targets.
+  Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
+      {bool setter: false});
+
   /// Returns the possibly abstract interface member of [class_] with the given
   /// [name].
   ///
@@ -122,6 +149,34 @@
   /// classes.
   List<Member> getDeclaredMembers(Class class_, {bool setters: false});
 
+  /// Returns the subclasses of [class_] as an interval list.
+  ClassSet getSubclassesOf(Class class_);
+
+  /// Returns the subtypes of [class_] as an interval list.
+  ClassSet getSubtypesOf(Class class_);
+
+  /// True if [subclass] inherits from [superclass] though zero or more
+  /// `extends` relationships.
+  bool isSubclassOf(Class subclass, Class superclass);
+
+  /// True if [submixture] inherits from [superclass] though zero or more
+  /// `extends` and `with` relationships.
+  bool isSubmixtureOf(Class submixture, Class superclass);
+
+  /// True if [subtype] inherits from [superclass] though zero or more
+  /// `extends`, `with`, and `implements` relationships.
+  bool isSubtypeOf(Class subtype, Class superclass);
+
+  /// True if the given class is used as the right-hand operand to a
+  /// mixin application (i.e. [Class.mixedInType]).
+  bool isUsedAsMixin(Class class_);
+
+  /// True if the given class is the direct super class of another class.
+  bool isUsedAsSuperClass(Class class_);
+
+  /// True if the given class is used in an `implements` clause.
+  bool isUsedAsSuperInterface(Class class_);
+
   /// Invokes [callback] for every member declared in or inherited by [class_]
   /// that overrides or implements a member in a supertype of [class_]
   /// (or in rare cases, overrides a member declared in [class_]).
@@ -271,6 +326,8 @@
 
 /// Implementation of [ClassHierarchy] for closed world.
 class ClosedWorldClassHierarchy implements ClassHierarchy {
+  final HandleAmbiguousSupertypes _onAmbiguousSupertypes;
+
   /// The [Program] that this class hierarchy represents.
   final Program _program;
 
@@ -281,7 +338,8 @@
 
   final Map<Class, _ClassInfo> _infoFor = <Class, _ClassInfo>{};
 
-  ClosedWorldClassHierarchy._internal(this._program, int numberOfClasses)
+  ClosedWorldClassHierarchy._internal(
+      this._program, int numberOfClasses, this._onAmbiguousSupertypes)
       : classes = new List<Class>(numberOfClasses);
 
   @override
@@ -293,39 +351,35 @@
     return classes.where(unorderedSet.contains);
   }
 
-  /// True if [subclass] inherits from [superclass] though zero or more
-  /// `extends` relationships.
+  @override
   bool isSubclassOf(Class subclass, Class superclass) {
     if (identical(subclass, superclass)) return true;
     return _infoFor[subclass].isSubclassOf(_infoFor[superclass]);
   }
 
-  /// True if [submixture] inherits from [superclass] though zero or more
-  /// `extends` and `with` relationships.
+  @override
   bool isSubmixtureOf(Class submixture, Class superclass) {
     if (identical(submixture, superclass)) return true;
     return _infoFor[submixture].isSubmixtureOf(_infoFor[superclass]);
   }
 
-  /// True if [subtype] inherits from [superclass] though zero or more
-  /// `extends`, `with`, and `implements` relationships.
+  @override
   bool isSubtypeOf(Class subtype, Class superclass) {
     if (identical(subtype, superclass)) return true;
     return _infoFor[subtype].isSubtypeOf(_infoFor[superclass]);
   }
 
-  /// True if the given class is the direct super class of another class.
+  @override
   bool isUsedAsSuperClass(Class class_) {
     return _infoFor[class_].directExtenders.isNotEmpty;
   }
 
-  /// True if the given class is used as the right-hand operand to a
-  /// mixin application (i.e. [Class.mixedInType]).
+  @override
   bool isUsedAsMixin(Class class_) {
     return _infoFor[class_].directMixers.isNotEmpty;
   }
 
-  /// True if the given class is used in an `implements` clause.
+  @override
   bool isUsedAsSuperInterface(Class class_) {
     return _infoFor[class_].directImplementers.isNotEmpty;
   }
@@ -446,11 +500,11 @@
         var superType1 = identical(info1, next)
             ? type1
             : Substitution.fromInterfaceType(type1).substituteType(
-                info1.genericSuperTypes[next.classNode].asInterfaceType);
+                info1.genericSuperTypes[next.classNode].first.asInterfaceType);
         var superType2 = identical(info2, next)
             ? type2
             : Substitution.fromInterfaceType(type2).substituteType(
-                info2.genericSuperTypes[next.classNode].asInterfaceType);
+                info2.genericSuperTypes[next.classNode].first.asInterfaceType);
         if (superType1 == superType2) {
           candidate = superType1;
           ++numCandidatesAtThisDepth;
@@ -463,10 +517,16 @@
   Supertype getClassAsInstanceOf(Class class_, Class superclass) {
     if (identical(class_, superclass)) return class_.asThisSupertype;
     _ClassInfo info = _infoFor[class_];
+    if (info == null) {
+      throw "${class_.fileUri}: No class info for ${class_.name}";
+    }
     _ClassInfo superInfo = _infoFor[superclass];
+    if (info == null) {
+      throw "${superclass.fileUri}: No class info for ${superclass.name}";
+    }
     if (!info.isSubtypeOf(superInfo)) return null;
     if (superclass.typeParameters.isEmpty) return superclass.asRawSupertype;
-    return info.genericSuperTypes[superclass];
+    return info.genericSuperTypes[superclass]?.first;
   }
 
   @override
@@ -486,24 +546,13 @@
     return ClassHierarchy.findMemberByName(list, name);
   }
 
-  /// Returns the list of potential targets of dynamic dispatch to an instance
-  /// of [class_].
-  ///
-  /// If [setters] is `false`, only potential targets of a getter or call
-  /// dispatch are returned.  If [setters] is `true`, only potential targets
-  /// of a setter dispatch are returned.
-  ///
-  /// See [getDispatchTarget] for more details.
-  ///
-  /// The returned list should not be modified.
+  @override
   List<Member> getDispatchTargets(Class class_, {bool setters: false}) {
     _ClassInfo info = _infoFor[class_];
     return setters ? info.implementedSetters : info.implementedGettersAndCalls;
   }
 
-  /// Returns the single concrete target for invocation of the given interface
-  /// target, or `null` if it could not be resolved or there are multiple
-  /// possible targets.
+  @override
   Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
       {bool setter: false}) {
     Name name = interfaceTarget.name;
@@ -611,12 +660,12 @@
     return !getSubtypesOf(class_).isSingleton;
   }
 
-  /// Returns the subtypes of [class_] as an interval list.
+  @override
   ClassSet getSubtypesOf(Class class_) {
     return new ClassSet(this, _infoFor[class_].subtypeIntervalList);
   }
 
-  /// Returns the subclasses of [class_] as an interval list.
+  @override
   ClassSet getSubclassesOf(Class class_) {
     return new ClassSet(this, _infoFor[class_].subclassIntervalList);
   }
@@ -624,7 +673,8 @@
   @override
   ClassHierarchy applyChanges(Iterable<Class> classes) {
     if (classes.isEmpty) return this;
-    return new ClassHierarchy(_program);
+    return new ClassHierarchy(_program,
+        onAmbiguousSupertypes: _onAmbiguousSupertypes);
   }
 
   void _initialize() {
@@ -671,7 +721,11 @@
         throw "No info for ${cls.name} from ${cls.fileUri}.";
       }
       if (info.topologicalIndex != i) {
-        throw "Unexpected topologicalIndex (${info.topologicalIndex} != $i) for ${cls.name} from ${cls.fileUri}.";
+        throw "Unexpected topologicalIndex (${info.topologicalIndex} != $i) "
+            "for ${cls.name} from ${cls.fileUri}.";
+      }
+      if (info.subtypeIntervalList == null) {
+        throw "No subtypeIntervalList for ${cls.name} from ${cls.fileUri}.";
       }
     }
   }
@@ -900,8 +954,13 @@
         superInfo.ownsGenericSuperTypeMap = false;
       } else {
         // Copy over the super type entries.
-        subInfo.genericSuperTypes ??= <Class, Supertype>{};
-        subInfo.genericSuperTypes.addAll(superInfo.genericSuperTypes);
+        subInfo.genericSuperTypes ??= <Class, List<Supertype>>{};
+        superInfo.genericSuperTypes
+            ?.forEach((Class key, List<Supertype> types) {
+          for (Supertype type in types) {
+            subInfo.recordGenericSuperType(key, type, _onAmbiguousSupertypes);
+          }
+        });
       }
     } else {
       // Copy over all transitive generic super types, and substitute the
@@ -909,11 +968,16 @@
       Class superclass = supertype.classNode;
       var substitution = Substitution.fromPairs(
           superclass.typeParameters, supertype.typeArguments);
-      subInfo.genericSuperTypes ??= <Class, Supertype>{};
-      superInfo.genericSuperTypes?.forEach((Class key, Supertype type) {
-        subInfo.genericSuperTypes[key] = substitution.substituteSupertype(type);
+      subInfo.genericSuperTypes ??= <Class, List<Supertype>>{};
+      superInfo.genericSuperTypes?.forEach((Class key, List<Supertype> types) {
+        for (Supertype type in types) {
+          subInfo.recordGenericSuperType(key,
+              substitution.substituteSupertype(type), _onAmbiguousSupertypes);
+        }
       });
-      subInfo.genericSuperTypes[superclass] = supertype;
+
+      subInfo.recordGenericSuperType(
+          superclass, supertype, _onAmbiguousSupertypes);
     }
   }
 
@@ -1151,7 +1215,7 @@
   ///
   /// In this case, a single map object `{A: A<String>, Q: Q<int>}` may be
   /// shared by the classes `B` and `C`.
-  Map<Class, Supertype> genericSuperTypes;
+  Map<Class, List<Supertype>> genericSuperTypes;
 
   /// If true, this is the current "owner" of [genericSuperTypes], meaning
   /// we may add additional entries to the map or transfer ownership to another
@@ -1178,6 +1242,17 @@
   List<Member> interfaceSetters;
 
   _ClassInfo(this.classNode);
+
+  void recordGenericSuperType(Class cls, Supertype type,
+      HandleAmbiguousSupertypes onAmbiguousSupertypes) {
+    List<Supertype> existing = genericSuperTypes[cls];
+    if (existing == null) {
+      genericSuperTypes[cls] = <Supertype>[type];
+    } else if (type != existing.first) {
+      existing.add(type);
+      onAmbiguousSupertypes(classNode, existing.first, type);
+    }
+  }
 }
 
 /// An immutable set of classes, internally represented as an interval list.
diff --git a/pkg/kernel/lib/src/incremental_class_hierarchy.dart b/pkg/kernel/lib/src/incremental_class_hierarchy.dart
index 21f219e..76c26da 100644
--- a/pkg/kernel/lib/src/incremental_class_hierarchy.dart
+++ b/pkg/kernel/lib/src/incremental_class_hierarchy.dart
@@ -585,6 +585,57 @@
       }
     }
   }
+
+  @override
+  List<Member> getDispatchTargets(Class class_, {bool setters: false}) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  bool isUsedAsSuperInterface(Class class_) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  bool isUsedAsSuperClass(Class class_) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  bool isUsedAsMixin(Class class_) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  bool isSubtypeOf(Class subtype, Class superclass) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  bool isSubmixtureOf(Class submixture, Class superclass) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  bool isSubclassOf(Class subclass, Class superclass) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  ClassSet getSubtypesOf(Class class_) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  ClassSet getSubclassesOf(Class class_) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  Member getSingleTargetForInterfaceInvocation(Member interfaceTarget,
+      {bool setter: false}) {
+    throw new UnimplementedError();
+  }
 }
 
 /// Information about a [Class].
diff --git a/pkg/kernel/lib/target/vm.dart b/pkg/kernel/lib/target/vm.dart
index eefe395..a30abbb 100644
--- a/pkg/kernel/lib/target/vm.dart
+++ b/pkg/kernel/lib/target/vm.dart
@@ -52,6 +52,7 @@
         'dart:_builtin',
         'dart:nativewrappers',
         'dart:io',
+        'dart:cli',
       ];
 
   @override
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 3578de3..5d84fa3 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -944,7 +944,7 @@
     writeIndentation();
     writeModifier(node.isExternal, 'external');
     writeModifier(node.isConst, 'const');
-    writeModifier(node.isSyntheticDefault, 'default');
+    writeModifier(node.isSynthetic, 'default');
     writeWord('constructor');
     writeFunction(node.function,
         name: node.name, initializers: node.initializers);
diff --git a/pkg/kernel/test/type_subtype_test.dart b/pkg/kernel/test/type_subtype_test.dart
index 1517b25..29e7bae 100644
--- a/pkg/kernel/test/type_subtype_test.dart
+++ b/pkg/kernel/test/type_subtype_test.dart
@@ -18,6 +18,7 @@
   'List<T>': ['Iterable<T>'],
   'Future<T>': ['Object'],
   'FutureOr<T>': ['Object'],
+  'Null': ['Object'],
 };
 
 List<TestCase> testCases = <TestCase>[
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 21a7c83..a12448f 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -49,6 +49,7 @@
 front_end/tool/incremental_perf_test: Slow, Pass
 kernel/test/closures_test: Slow, Pass
 kernel/testcases/*: Skip # These are not tests but input for tests.
+vm/testcases/*: SkipByDesign # These are not tests but input for tests.
 
 [ $compiler == dart2analyzer ]
 dev_compiler/test/options/*: SkipByDesign
@@ -112,9 +113,12 @@
 [ $runtime != vm ]
 dev_compiler/test/options/*: SkipByDesign
 front_end/test/src/incremental/hot_reload_e2e_test: Skip
+vm/test/*: SkipByDesign # Only meant to run on vm
 
 [ $system == windows ]
+front_end/test/fasta/bootstrap_test: Skip # Issue 31902
 front_end/test/src/incremental/hot_reload_e2e_test: Skip # Issue 31901
+front_end/test/whole_program_test: Skip # Issue 31902
 
 [ $browser ]
 */test/analyzer_test: SkipByDesign # No need to run analysis tests on browser bots
diff --git a/pkg/status_file/test/data/co19-dart2js.status b/pkg/status_file/test/data/co19-dart2js.status
index 6f8403f..438316b 100644
--- a/pkg/status_file/test/data/co19-dart2js.status
+++ b/pkg/status_file/test/data/co19-dart2js.status
@@ -205,7 +205,6 @@
 LibTest/core/int/operator_remainder_A01_t01: RuntimeError, OK # Requires bigints.
 LibTest/core/int/operator_right_shift_A01_t01: RuntimeError, OK # Expects negative result from bit-operation.
 LibTest/core/int/toDouble_A01_t01: RuntimeError, OK # co19 issue 200
-LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Pass,RuntimeError # https://github.com/dart-lang/sdk/issues/29814
 LibTest/html/HttpRequest/responseType_A01_t03: CompileTimeError # co19-roll r706: Please triage this failure
 LibTest/html/IFrameElement/enteredView_A01_t01: CompileTimeError # co19-roll r706: Please triage this failure
 LibTest/isolate/Isolate/spawnUri_A01_t01: Fail # Dart issue 15974
@@ -626,7 +625,7 @@
 LibTest/async/Zone/createTimer_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/List/sort_A01_t04: Skip # Must be a bug in jsshell, test sometimes times out.
 LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # co19-roll r706: Please triage this failure.
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # JS engine has not moved to Unicode 6.3 yet.
 LibTest/core/Stopwatch/elapsedInMs_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/Stopwatch/elapsedInUs_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/Stopwatch/elapsedTicks_A01_t01: RuntimeError # Please triage this failure
@@ -676,7 +675,7 @@
 LibTest/core/Uri/encodeQueryComponent_A01_t02: Skip # Issue 18093, timeout.
 
 [ $compiler == dart2js && $jscl ]
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail, Pass # issue 3333
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail, Pass # Does not work with old JS engines that are on Unicode 6.2
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError, OK # This is not rejected by V8. Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
@@ -1444,7 +1443,6 @@
 LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xsl/default-html_t01: RuntimeError # Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Pass,RuntimeError # https://github.com/dart-lang/sdk/issues/29814
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
@@ -2253,7 +2251,7 @@
 LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xsl/default-html_t01: RuntimeError # Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # DRT may not be on Unicode 6.2
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Please triage this failure
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Please triage this failure
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Please triage this failure
@@ -4902,7 +4900,7 @@
 LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xsl/default-html_t01: RuntimeError # Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Safari may not be on Unicode 6.3
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
@@ -6630,7 +6628,7 @@
 LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # Please triage this failure
 LibTest/async/Timer/Timer.periodic_A01_t01: Pass, RuntimeError # Please triage this failure
 LibTest/async/Timer/Timer_A01_t01: Pass, RuntimeError # Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # IE11 may not be on Unicode 6.3
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
diff --git a/pkg/testing/lib/src/stdio_process.dart b/pkg/testing/lib/src/stdio_process.dart
index f6c5878..1004a59 100644
--- a/pkg/testing/lib/src/stdio_process.dart
+++ b/pkg/testing/lib/src/stdio_process.dart
@@ -43,8 +43,10 @@
   static Future<StdioProcess> run(String executable, List<String> arguments,
       {String input,
       Duration timeout: const Duration(seconds: 60),
-      bool suppressOutput: true}) async {
-    Process process = await Process.start(executable, arguments);
+      bool suppressOutput: true,
+      bool runInShell: false}) async {
+    Process process =
+        await Process.start(executable, arguments, runInShell: runInShell);
     Timer timer;
     StringBuffer sb = new StringBuffer();
     if (timeout != null) {
diff --git a/pkg/vm/bin/dump_kernel.dart b/pkg/vm/bin/dump_kernel.dart
index e2bbb61..28499bc 100644
--- a/pkg/vm/bin/dump_kernel.dart
+++ b/pkg/vm/bin/dump_kernel.dart
@@ -9,6 +9,8 @@
     show BinaryBuilderWithMetadata;
 
 import 'package:vm/metadata/direct_call.dart' show DirectCallMetadataRepository;
+import 'package:vm/metadata/inferred_type.dart'
+    show InferredTypeMetadataRepository;
 
 final String _usage = '''
 Usage: dump_kernel input.dill output.txt
@@ -28,6 +30,7 @@
 
   // Register VM-specific metadata.
   program.addMetadataRepository(new DirectCallMetadataRepository());
+  program.addMetadataRepository(new InferredTypeMetadataRepository());
 
   final List<int> bytes = new File(input).readAsBytesSync();
   new BinaryBuilderWithMetadata(bytes).readProgram(program);
diff --git a/pkg/vm/lib/metadata/inferred_type.dart b/pkg/vm/lib/metadata/inferred_type.dart
new file mode 100644
index 0000000..dafb370
--- /dev/null
+++ b/pkg/vm/lib/metadata/inferred_type.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library vm.metadata.inferred_type;
+
+import 'package:kernel/ast.dart';
+
+/// Metadata for annotating nodes with an inferred type information.
+class InferredType {
+  final Reference _concreteClassReference;
+  final bool nullable;
+
+  InferredType(Class concreteClass, bool nullable)
+      : this._byReference(getClassReference(concreteClass), nullable);
+
+  InferredType._byReference(this._concreteClassReference, this.nullable);
+
+  Class get concreteClass => _concreteClassReference?.asClass;
+
+  @override
+  String toString() =>
+      "${concreteClass != null ? concreteClass : '!'}${nullable ? '?' : ''}";
+}
+
+/// Repository for [InferredType].
+class InferredTypeMetadataRepository extends MetadataRepository<InferredType> {
+  @override
+  final String tag = 'vm.inferred-type.metadata';
+
+  @override
+  final Map<TreeNode, InferredType> mapping = <TreeNode, InferredType>{};
+
+  @override
+  void writeToBinary(InferredType metadata, BinarySink sink) {
+    sink.writeCanonicalNameReference(
+        getCanonicalNameOfClass(metadata.concreteClass));
+    sink.writeByte(metadata.nullable ? 1 : 0);
+  }
+
+  @override
+  InferredType readFromBinary(BinarySource source) {
+    final concreteClassReference =
+        source.readCanonicalNameReference()?.getReference();
+    final nullable = (source.readByte() != 0);
+    return new InferredType._byReference(concreteClassReference, nullable);
+  }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 871c63b..cd3cafb 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -24,7 +24,6 @@
 // organized in several categories:
 //
 // === Correctness ===
-// * Add unit tests!!!
 // * Support dynamic calls via getters & dynamic tear-offs.
 // * Re-evaluate field initializer if its dependency changes (avoid
 //   re-using cached value).
@@ -350,6 +349,12 @@
   final Set<Class> allocatedClasses = new Set<Class>();
   final Map<Class, _ClassData> classes = <Class, _ClassData>{};
 
+  /// Class hierarchy is sealed after analysis is finished.
+  /// Once it is sealed, no new allocated classes may be added and no new
+  /// targets of invocations may appear.
+  /// It also means that there is no need to add dependencies on classes.
+  bool _sealed = false;
+
   final Map<Member, _ProcedureInvocationHandler> _procedureHandlers =
       <Member, _ProcedureInvocationHandler>{};
   final Map<Field, _FieldGetterInvocationHandler> _fieldGetterHandlers =
@@ -375,6 +380,7 @@
 
   void addAllocatedClass(Class cl) {
     assertx(!cl.isAbstract);
+    assertx(!_sealed);
 
     if (allocatedClasses.add(cl)) {
       final _ClassData classData = getClassData(cl);
@@ -392,10 +398,16 @@
     }
   }
 
+  void seal() {
+    _sealed = true;
+  }
+
   @override
   bool isSubtype(DartType subType, DartType superType) {
-    tracePrint(
-        "isSubtype for sub = $subType (${subType.runtimeType}), sup = $superType (${superType.runtimeType})");
+    if (kPrintTrace) {
+      tracePrint("isSubtype for sub = $subType (${subType
+              .runtimeType}), sup = $superType (${superType.runtimeType})");
+    }
     if (subType == superType) {
       return true;
     }
@@ -459,7 +471,9 @@
     _ClassData classData = getClassData((base as InterfaceType).classNode);
 
     final allocatedSubtypes = classData.allocatedSubtypes;
-    classData.addDependentInvocation(_typeFlowAnalysis.currentInvocation);
+    if (!_sealed) {
+      classData.addDependentInvocation(_typeFlowAnalysis.currentInvocation);
+    }
 
     final int numSubTypes = allocatedSubtypes.length;
 
@@ -515,6 +529,7 @@
   }
 
   void _addDynamicTarget(Class c, _DynamicInvocationHandler handler) {
+    assertx(!_sealed);
     final selector = handler.selector;
     final member = hierarchy.getDispatchTarget(c, selector.name,
         setter: selector.isSetter);
@@ -815,6 +830,7 @@
 
   void process() {
     workList.process();
+    hierarchyCache.seal();
   }
 
   bool isMemberUsed(Member member) => hierarchyCache.isMemberUsed(member);
diff --git a/pkg/vm/lib/transformations/type_flow/entry_points.json b/pkg/vm/lib/transformations/type_flow/entry_points.json
index 17b472c..95d1f01 100644
--- a/pkg/vm/lib/transformations/type_flow/entry_points.json
+++ b/pkg/vm/lib/transformations/type_flow/entry_points.json
@@ -501,6 +501,11 @@
       "action": "create-instance"
     },
     {
+      "library": "dart:async",
+      "name": "_ensureScheduleImmediate",
+      "action": "call"
+    },
+    {
       "library": "dart:core",
       "name": "_completeDeferredLoads",
       "action": "call"
@@ -631,6 +636,11 @@
     },
     {
       "library": "dart:isolate",
+      "name": "_runPendingImmediateCallback",
+      "action": "call"
+    },
+    {
+      "library": "dart:isolate",
       "name": "_startIsolate",
       "action": "call"
     },
@@ -692,11 +702,6 @@
       "action": "call"
     },
     {
-      "library": "dart:isolate",
-      "name": "_runPendingImmediateCallback",
-      "action": "call"
-    },
-    {
       "library": "dart:core",
       "class": "Error",
       "name": "_stackTrace",
@@ -766,6 +771,21 @@
       "action": "call"
     },
     {
+      "library": "dart:cli",
+      "name": "_getWaitForEvent",
+      "action": "call"
+    },
+    {
+      "library": "dart:cli",
+      "name": "_waitForEventClosure",
+      "action": "get"
+    },
+    {
+      "library": "dart:cli",
+      "name": "_waitForEventClosure",
+      "action": "set"
+    },
+    {
       "library": "dart:io",
       "name": "_getUriBaseClosure",
       "action": "call"
diff --git a/pkg/vm/lib/transformations/type_flow/summary.dart b/pkg/vm/lib/transformations/type_flow/summary.dart
index cb5aca1..1272b69 100644
--- a/pkg/vm/lib/transformations/type_flow/summary.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary.dart
@@ -155,13 +155,14 @@
       }
       argTypes[i] = type;
     }
+    setReachable();
     if (selector is! DirectSelector) {
       _observeReceiverType(argTypes[0]);
     }
     final Type result = callHandler.applyCall(this, selector,
         new Args<Type>(argTypes, names: args.names), isResultUsed);
     if (isResultUsed) {
-      _observeResultType(result);
+      _observeResultType(result, typeHierarchy);
     }
     return result;
   }
@@ -169,12 +170,13 @@
   // --- Inferred call site information. ---
 
   int _flags = 0;
+  Type _resultType = const EmptyType();
 
   static const int kMonomorphic = (1 << 0);
   static const int kPolymorphic = (1 << 1);
   static const int kNullableReceiver = (1 << 2);
   static const int kResultUsed = (1 << 3);
-  static const int kNullableResult = (1 << 4);
+  static const int kReachable = (1 << 4);
 
   Member _monomorphicTarget;
 
@@ -188,12 +190,18 @@
 
   bool get isResultUsed => (_flags & kResultUsed) != 0;
 
-  bool get isNullableResult => (_flags & kNullableResult) != 0;
+  bool get isReachable => (_flags & kReachable) != 0;
+
+  Type get resultType => _resultType;
 
   void setResultUsed() {
     _flags |= kResultUsed;
   }
 
+  void setReachable() {
+    _flags |= kReachable;
+  }
+
   void setPolymorphic() {
     _flags = (_flags & ~kMonomorphic) | kPolymorphic;
     _monomorphicTarget = null;
@@ -218,11 +226,8 @@
     }
   }
 
-  void _observeResultType(Type result) {
-    if (result is NullableType) {
-      _flags |= kNullableResult;
-    }
-    // TODO(alexmarkov): Record result types.
+  void _observeResultType(Type result, TypeHierarchy typeHierarchy) {
+    _resultType = _resultType.union(result, typeHierarchy);
   }
 }
 
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 2947b68..1d19d63 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -16,16 +16,23 @@
 import 'analysis.dart';
 import 'calls.dart';
 import 'summary_collector.dart';
+import 'types.dart';
 import 'utils.dart';
 import '../devirtualization.dart' show Devirtualization;
 import '../../metadata/direct_call.dart';
+import '../../metadata/inferred_type.dart';
 
 const bool kDumpAllSummaries =
     const bool.fromEnvironment('global.type.flow.dump.all.summaries');
 
 /// Whole-program type flow analysis and transformation.
 /// Assumes strong mode and closed world.
-Program transformProgram(CoreTypes coreTypes, Program program) {
+Program transformProgram(CoreTypes coreTypes, Program program,
+    // TODO(alexmarkov): Pass entry points descriptors from command line.
+    {List<String> entryPointsJSONFiles: const [
+      'pkg/vm/lib/transformations/type_flow/entry_points.json',
+      'pkg/vm/lib/transformations/type_flow/entry_points_extra.json',
+    ]}) {
   final hierarchy = new ClassHierarchy(program);
   final types = new TypeEnvironment(coreTypes, hierarchy, strongMode: true);
   final libraryIndex = new LibraryIndex.all(program);
@@ -40,11 +47,7 @@
   final analysisStopWatch = new Stopwatch()..start();
 
   final typeFlowAnalysis = new TypeFlowAnalysis(hierarchy, types, libraryIndex,
-      // TODO(alexmarkov): Pass entry points descriptors from command line.
-      entryPointsJSONFiles: [
-        'pkg/vm/lib/transformations/type_flow/entry_points.json',
-        'pkg/vm/lib/transformations/type_flow/entry_points_extra.json',
-      ]);
+      entryPointsJSONFiles: entryPointsJSONFiles);
 
   Procedure main = program.mainMethod;
   final Selector mainSelector = new DirectSelector(main);
@@ -59,6 +62,9 @@
 
   new TFADevirtualization(program, typeFlowAnalysis).visitProgram(program);
 
+  new AnnotateWithInferredTypes(program, typeFlowAnalysis)
+      .visitProgram(program);
+
   transformsStopWatch.stop();
 
   statPrint("TF analysis took ${analysisStopWatch.elapsedMilliseconds}ms");
@@ -117,3 +123,91 @@
     }
   }
 }
+
+/// Annotates kernel AST with types inferred by type flow analysis.
+class AnnotateWithInferredTypes extends RecursiveVisitor<Null> {
+  final TypeFlowAnalysis _typeFlowAnalysis;
+  final InferredTypeMetadataRepository _metadata;
+
+  AnnotateWithInferredTypes(Program program, this._typeFlowAnalysis)
+      : _metadata = new InferredTypeMetadataRepository() {
+    program.addMetadataRepository(_metadata);
+  }
+
+  void _annotateNode(TreeNode node) {
+    final callSite = _typeFlowAnalysis.callSite(node);
+    if ((callSite != null) && callSite.isResultUsed && callSite.isReachable) {
+      final resultType = callSite.resultType;
+      assertx(resultType != null);
+
+      Class concreteClass;
+
+      final nullable = resultType is NullableType;
+      if (nullable) {
+        final baseType = (resultType as NullableType).baseType;
+
+        if (baseType == const EmptyType()) {
+          concreteClass = _typeFlowAnalysis.environment.coreTypes.nullClass;
+        } else {
+          concreteClass =
+              baseType.getConcreteClass(_typeFlowAnalysis.hierarchyCache);
+        }
+      } else {
+        concreteClass =
+            resultType.getConcreteClass(_typeFlowAnalysis.hierarchyCache);
+      }
+
+      if ((concreteClass != null) || !nullable) {
+        _metadata.mapping[node] = new InferredType(concreteClass, nullable);
+      }
+    }
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    _annotateNode(node);
+    super.visitMethodInvocation(node);
+  }
+
+  @override
+  visitPropertyGet(PropertyGet node) {
+    _annotateNode(node);
+    super.visitPropertyGet(node);
+  }
+
+  @override
+  visitDirectMethodInvocation(DirectMethodInvocation node) {
+    _annotateNode(node);
+    super.visitDirectMethodInvocation(node);
+  }
+
+  @override
+  visitDirectPropertyGet(DirectPropertyGet node) {
+    _annotateNode(node);
+    super.visitDirectPropertyGet(node);
+  }
+
+  @override
+  visitSuperMethodInvocation(SuperMethodInvocation node) {
+    _annotateNode(node);
+    super.visitSuperMethodInvocation(node);
+  }
+
+  @override
+  visitSuperPropertyGet(SuperPropertyGet node) {
+    _annotateNode(node);
+    super.visitSuperPropertyGet(node);
+  }
+
+  @override
+  visitStaticInvocation(StaticInvocation node) {
+    _annotateNode(node);
+    super.visitStaticInvocation(node);
+  }
+
+  @override
+  visitStaticGet(StaticGet node) {
+    _annotateNode(node);
+    super.visitStaticGet(node);
+  }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index a73bdd6..d9d9a68 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -65,7 +65,7 @@
   /// instances of all Dart types which extend, mix-in or implement [dartType].
   factory Type.cone(DartType dartType) {
     dartType = _normalizeDartType(dartType);
-    if (dartType == const DynamicType()) {
+    if ((dartType == const DynamicType()) || (dartType == const VoidType())) {
       return const AnyType();
     } else {
       return new ConeType(dartType);
@@ -88,7 +88,7 @@
   /// Dart type annotation [dartType].
   factory Type.fromStatic(DartType dartType) {
     dartType = _normalizeDartType(dartType);
-    if (dartType == const DynamicType()) {
+    if ((dartType == const DynamicType()) || (dartType == const VoidType())) {
       return new Type.nullable(const AnyType());
     } else if (dartType == const BottomType()) {
       return new Type.nullable(new Type.empty());
@@ -99,6 +99,8 @@
   @override
   DartType get staticType;
 
+  Class getConcreteClass(TypeHierarchy typeHierarchy) => null;
+
   @override
   Type getComputedType(List<Type> types) => this;
 
@@ -338,6 +340,11 @@
   DartType get staticType => dartType;
 
   @override
+  Class getConcreteClass(TypeHierarchy typeHierarchy) => typeHierarchy
+      .specializeTypeCone(dartType)
+      .getConcreteClass(typeHierarchy);
+
+  @override
   int get hashCode => (dartType.hashCode + 37) & kHashMask;
 
   @override
@@ -365,6 +372,10 @@
       if (typeHierarchy.isSubtype(this.dartType, other.dartType)) {
         return other;
       }
+    } else if (other is ConcreteType) {
+      if (typeHierarchy.isSubtype(other.dartType, this.dartType)) {
+        return this;
+      }
     }
     return typeHierarchy
         .specializeTypeCone(dartType)
@@ -414,6 +425,12 @@
   DartType get staticType => dartType;
 
   @override
+  Class getConcreteClass(TypeHierarchy typeHierarchy) =>
+      (dartType is InterfaceType)
+          ? (dartType as InterfaceType).classNode
+          : null;
+
+  @override
   int get hashCode => (dartType.hashCode ^ 0x1234) & kHashMask;
 
   @override
diff --git a/pkg/vm/test/transformations/type_flow/common_test_utils.dart b/pkg/vm/test/transformations/type_flow/common_test_utils.dart
new file mode 100644
index 0000000..01834d6
--- /dev/null
+++ b/pkg/vm/test/transformations/type_flow/common_test_utils.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:front_end/src/api_prototype/front_end.dart';
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+    show computePlatformBinariesLocation;
+import 'package:kernel/ast.dart';
+import 'package:kernel/target/targets.dart';
+import 'package:kernel/target/vm.dart';
+import 'package:test/test.dart';
+
+const bool kDumpActualResult = const bool.fromEnvironment('dump.actual.result');
+
+Future<Program> compileTestCaseToKernelProgram(Uri sourceUri) async {
+  final platformKernel =
+      computePlatformBinariesLocation().resolve('vm_platform_strong.dill');
+  final options = new CompilerOptions()
+    ..strongMode = true
+    ..target = new VmTarget(new TargetFlags(strongMode: true))
+    ..linkedDependencies = <Uri>[platformKernel]
+    ..reportMessages = true
+    ..onError = (CompilationMessage error) {
+      fail("Compilation error: ${error}");
+    };
+  return kernelForProgram(sourceUri, options);
+}
+
+void compareResultWithExpectationsFile(Uri source, String actual) {
+  final expectFile = new File(source.toFilePath() + '.expect');
+  final expected = expectFile.existsSync() ? expectFile.readAsStringSync() : '';
+
+  if (actual != expected) {
+    if (kDumpActualResult) {
+      new File(source.toFilePath() + '.actual').writeAsStringSync(actual);
+    }
+    expect(actual, equals(expected), reason: "Test case: $source");
+  }
+}
diff --git a/pkg/vm/test/transformations/type_flow/summary_collector_test.dart b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
new file mode 100644
index 0000000..9e051d2
--- /dev/null
+++ b/pkg/vm/test/transformations/type_flow/summary_collector_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/type_environment.dart';
+import 'package:test/test.dart';
+import 'package:vm/transformations/type_flow/native_code.dart';
+import 'package:vm/transformations/type_flow/summary_collector.dart';
+
+import 'common_test_utils.dart';
+
+final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
+
+class PrintSummaries extends RecursiveVisitor<Null> {
+  final SummaryCollector _summaryColector;
+  final StringBuffer _buf = new StringBuffer();
+
+  PrintSummaries(TypeEnvironment environment)
+      : _summaryColector = new SummaryCollector(
+            environment, new EntryPointsListener(), new NativeCodeOracle(null));
+
+  String print(TreeNode node) {
+    visitLibrary(node);
+    return _buf.toString();
+  }
+
+  @override
+  defaultMember(Member member) {
+    if (!member.isAbstract) {
+      _buf.writeln("------------ $member ------------");
+      _buf.writeln(_summaryColector.createSummary(member));
+    }
+  }
+}
+
+runTestCase(Uri source) async {
+  final Program program = await compileTestCaseToKernelProgram(source);
+  final Library library = program.mainMethod.enclosingLibrary;
+
+  // Make sure the library name is the same and does not depend on the order
+  // of test cases.
+  library.name = '#lib';
+
+  final typeEnvironment =
+      new TypeEnvironment(new CoreTypes(program), new ClassHierarchy(program));
+
+  final actual = new PrintSummaries(typeEnvironment).print(library);
+
+  compareResultWithExpectationsFile(source, actual);
+}
+
+main() {
+  group('collect-summary', () {
+    final testCasesDir = new Directory(
+        pkgVmDir + '/testcases/transformations/type_flow/summary_collector');
+
+    for (var entry
+        in testCasesDir.listSync(recursive: true, followLinks: false)) {
+      if (entry.path.endsWith(".dart")) {
+        test(entry.path, () => runTestCase(entry.uri));
+      }
+    }
+  });
+}
diff --git a/pkg/vm/test/transformations/type_flow/transformer_test.dart b/pkg/vm/test/transformations/type_flow/transformer_test.dart
new file mode 100644
index 0000000..61de1ec
--- /dev/null
+++ b/pkg/vm/test/transformations/type_flow/transformer_test.dart
@@ -0,0 +1,53 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/kernel.dart';
+import 'package:kernel/text/ast_to_text.dart';
+import 'package:test/test.dart';
+import 'package:vm/transformations/type_flow/transformer.dart'
+    show transformProgram;
+
+import 'common_test_utils.dart';
+
+final String pkgVmDir = Platform.script.resolve('../../..').toFilePath();
+
+runTestCase(Uri source) async {
+  Program program = await compileTestCaseToKernelProgram(source);
+
+  // Make sure the library name is the same and does not depend on the order
+  // of test cases.
+  program.mainMethod.enclosingLibrary.name = '#lib';
+
+  final coreTypes = new CoreTypes(program);
+
+  program = transformProgram(coreTypes, program, entryPointsJSONFiles: [
+    pkgVmDir + '/lib/transformations/type_flow/entry_points.json',
+    pkgVmDir + '/lib/transformations/type_flow/entry_points_extra.json',
+  ]);
+
+  final StringBuffer buffer = new StringBuffer();
+  new Printer(buffer, showExternal: false, showMetadata: true)
+      .writeLibraryFile(program.mainMethod.enclosingLibrary);
+  final actual = buffer.toString();
+
+  compareResultWithExpectationsFile(source, actual);
+}
+
+main() {
+  group('transform-program', () {
+    final testCasesDir = new Directory(
+        pkgVmDir + '/testcases/transformations/type_flow/transformer');
+
+    for (var entry
+        in testCasesDir.listSync(recursive: true, followLinks: false)) {
+      if (entry.path.endsWith(".dart")) {
+        test(entry.path, () => runTestCase(entry.uri));
+      }
+    }
+  });
+}
diff --git a/pkg/vm/test/transformations/type_flow/types_test.dart b/pkg/vm/test/transformations/type_flow/types_test.dart
new file mode 100644
index 0000000..7d60091
--- /dev/null
+++ b/pkg/vm/test/transformations/type_flow/types_test.dart
@@ -0,0 +1,383 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:core' hide Type;
+
+import 'package:kernel/ast.dart';
+import 'package:test/test.dart';
+import 'package:vm/transformations/type_flow/types.dart';
+
+class TestTypeHierarchy implements TypeHierarchy {
+  final Map<DartType, List<DartType>> subtypes;
+  final Map<DartType, Type> specializations;
+
+  TestTypeHierarchy(this.subtypes, this.specializations);
+
+  @override
+  bool isSubtype(DartType subType, DartType superType) {
+    return subtypes[superType].contains(subType);
+  }
+
+  @override
+  Type specializeTypeCone(DartType base) {
+    Type result = specializations[base];
+    expect(result, isNotNull,
+        reason: "specializeTypeCone($base) is not defined");
+    return result;
+  }
+}
+
+main() {
+  test('factory-constructors', () {
+    Class c1 = new Class(name: 'C1');
+    Class c2 = new Class(name: 'C2', typeParameters: [new TypeParameter('E')]);
+    InterfaceType t1 = new InterfaceType(c1);
+    InterfaceType t2Raw = new InterfaceType(c2);
+    InterfaceType t2Generic = new InterfaceType(c2, [t1]);
+    FunctionType f1 = new FunctionType([t1], const VoidType());
+
+    expect(new Type.empty(), equals(const EmptyType()));
+
+    expect(new Type.cone(const DynamicType()), equals(const AnyType()));
+    expect(new Type.cone(t1), equals(new ConeType(t1)));
+    expect(new Type.cone(t2Raw), equals(new ConeType(t2Raw)));
+    expect(new Type.cone(t2Generic), equals(new ConeType(t2Raw)));
+    expect(new Type.cone(f1), equals(const AnyType()));
+
+    expect(new Type.concrete(t1), equals(new ConcreteType(t1)));
+    expect(new Type.concrete(t2Raw), equals(new ConcreteType(t2Raw)));
+    expect(new Type.concrete(t2Generic), equals(new ConcreteType(t2Raw)));
+
+    expect(new Type.nullable(new Type.empty()),
+        equals(new NullableType(new EmptyType())));
+    expect(new Type.nullable(new Type.cone(t1)),
+        equals(new NullableType(new ConeType(t1))));
+    expect(new Type.nullable(new Type.concrete(t1)),
+        equals(new NullableType(new ConcreteType(t1))));
+
+    expect(new Type.fromStatic(const DynamicType()),
+        equals(new NullableType(new AnyType())));
+    expect(new Type.fromStatic(const BottomType()),
+        equals(new NullableType(new EmptyType())));
+    expect(new Type.fromStatic(t1), equals(new NullableType(new ConeType(t1))));
+    expect(new Type.fromStatic(t2Raw),
+        equals(new NullableType(new ConeType(t2Raw))));
+    expect(new Type.fromStatic(t2Generic),
+        equals(new NullableType(new ConeType(t2Raw))));
+  });
+
+  test('static-type', () {
+    InterfaceType classType = new InterfaceType(new Class(name: 'C'));
+    FunctionType funcType = new FunctionType([], const VoidType());
+
+    // [T, T.staticType]
+    final testCases = [
+      [new Type.cone(classType), classType],
+      [new Type.cone(funcType), const DynamicType()],
+      [new Type.concrete(classType), classType],
+      [new AnyType(), const DynamicType()],
+      [new Type.nullable(new Type.empty()), const BottomType()],
+      [new Type.nullable(new Type.cone(classType)), classType],
+      [new Type.nullable(new Type.concrete(classType)), classType],
+      [new Type.nullable(new AnyType()), const DynamicType()],
+      [new Type.fromStatic(const DynamicType()), const DynamicType()],
+      [new Type.fromStatic(const BottomType()), const BottomType()],
+      [new Type.fromStatic(classType), classType],
+      [new Type.fromStatic(funcType), const DynamicType()],
+    ];
+
+    for (List testCase in testCases) {
+      Type type = testCase[0] as Type;
+      DartType staticType = testCase[1] as DartType;
+
+      expect(type.staticType, equals(staticType),
+          reason:
+              "Test case: ${type}.staticType is expected to be $staticType");
+    }
+  });
+
+  test('union-intersection', () {
+    // T1 <: T3, T2 <: T3
+
+    InterfaceType t1 = new InterfaceType(new Class(name: 'T1'));
+    InterfaceType t2 = new InterfaceType(new Class(name: 'T2'));
+    InterfaceType t3 = new InterfaceType(new Class(name: 'T3'));
+    InterfaceType t4 = new InterfaceType(new Class(name: 'T4'));
+
+    final empty = new EmptyType();
+    final any = new AnyType();
+    final concreteT1 = new ConcreteType(t1);
+    final concreteT2 = new ConcreteType(t2);
+    final concreteT3 = new ConcreteType(t3);
+    final concreteT4 = new ConcreteType(t4);
+    final coneT1 = new ConeType(t1);
+    final coneT2 = new ConeType(t2);
+    final coneT3 = new ConeType(t3);
+    final coneT4 = new ConeType(t4);
+    final setT12 = new SetType([concreteT1, concreteT2].toSet());
+    final setT14 = new SetType([concreteT1, concreteT4].toSet());
+    final setT23 = new SetType([concreteT2, concreteT3].toSet());
+    final setT34 = new SetType([concreteT3, concreteT4].toSet());
+    final setT123 = new SetType([concreteT1, concreteT2, concreteT3].toSet());
+    final setT124 = new SetType([concreteT1, concreteT2, concreteT4].toSet());
+    final setT1234 =
+        new SetType([concreteT1, concreteT2, concreteT3, concreteT4].toSet());
+    final nullableEmpty = new Type.nullable(empty);
+    final nullableAny = new Type.nullable(any);
+    final nullableConcreteT1 = new Type.nullable(concreteT1);
+    final nullableConcreteT2 = new Type.nullable(concreteT2);
+    final nullableConcreteT3 = new Type.nullable(concreteT3);
+    final nullableConeT1 = new Type.nullable(coneT1);
+    final nullableConeT3 = new Type.nullable(coneT3);
+    final nullableConeT4 = new Type.nullable(coneT4);
+    final nullableSetT12 = new Type.nullable(setT12);
+    final nullableSetT14 = new Type.nullable(setT14);
+    final nullableSetT23 = new Type.nullable(setT23);
+    final nullableSetT34 = new Type.nullable(setT34);
+    final nullableSetT123 = new Type.nullable(setT123);
+    final nullableSetT124 = new Type.nullable(setT124);
+    final nullableSetT1234 = new Type.nullable(setT1234);
+
+    // [A, B, union, intersection]
+    final testCases = [
+      // empty
+      [empty, empty, empty, empty],
+      [empty, any, any, empty],
+      [empty, concreteT1, concreteT1, empty],
+      [empty, coneT1, coneT1, empty],
+      [empty, setT12, setT12, empty],
+      [empty, nullableEmpty, nullableEmpty, empty],
+      [empty, nullableAny, nullableAny, empty],
+      [empty, nullableConcreteT1, nullableConcreteT1, empty],
+      [empty, nullableConeT1, nullableConeT1, empty],
+      [empty, nullableSetT12, nullableSetT12, empty],
+      // any
+      [any, any, any, any],
+      [any, concreteT1, any, concreteT1],
+      [any, coneT1, any, coneT1],
+      [any, setT12, any, setT12],
+      [any, nullableEmpty, nullableAny, empty],
+      [any, nullableAny, nullableAny, any],
+      [any, nullableConcreteT1, nullableAny, concreteT1],
+      [any, nullableConeT1, nullableAny, coneT1],
+      [any, nullableSetT12, nullableAny, setT12],
+      // nullableEmpty
+      [nullableEmpty, concreteT1, nullableConcreteT1, empty],
+      [nullableEmpty, coneT1, nullableConeT1, empty],
+      [nullableEmpty, setT12, nullableSetT12, empty],
+      [nullableEmpty, nullableEmpty, nullableEmpty, nullableEmpty],
+      [nullableEmpty, nullableAny, nullableAny, nullableEmpty],
+      [nullableEmpty, nullableConcreteT1, nullableConcreteT1, nullableEmpty],
+      [nullableEmpty, nullableConeT1, nullableConeT1, nullableEmpty],
+      [nullableEmpty, nullableSetT12, nullableSetT12, nullableEmpty],
+      // nullableAny
+      [nullableAny, concreteT1, nullableAny, concreteT1],
+      [nullableAny, coneT1, nullableAny, coneT1],
+      [nullableAny, setT12, nullableAny, setT12],
+      [nullableAny, nullableAny, nullableAny, nullableAny],
+      [nullableAny, nullableConcreteT1, nullableAny, nullableConcreteT1],
+      [nullableAny, nullableConeT1, nullableAny, nullableConeT1],
+      [nullableAny, nullableSetT12, nullableAny, nullableSetT12],
+      // concrete
+      [concreteT1, concreteT1, concreteT1, concreteT1],
+      [concreteT1, concreteT2, setT12, empty],
+      [concreteT1, coneT1, coneT1, concreteT1],
+      [concreteT1, coneT2, setT12, empty],
+      [concreteT1, coneT3, coneT3, concreteT1],
+      [concreteT1, coneT4, setT14, empty],
+      [concreteT1, setT12, setT12, concreteT1],
+      [concreteT1, setT23, setT123, empty],
+      [concreteT1, nullableConcreteT1, nullableConcreteT1, concreteT1],
+      [concreteT1, nullableConcreteT2, nullableSetT12, empty],
+      [concreteT1, nullableConeT1, nullableConeT1, concreteT1],
+      [concreteT1, nullableConeT3, nullableConeT3, concreteT1],
+      [concreteT1, nullableConeT4, nullableSetT14, empty],
+      [concreteT1, nullableSetT12, nullableSetT12, concreteT1],
+      [concreteT1, nullableSetT23, nullableSetT123, empty],
+      // cone
+      [coneT1, coneT1, coneT1, coneT1],
+      [coneT1, coneT2, setT12, empty],
+      [coneT1, coneT3, coneT3, coneT1],
+      [coneT3, coneT4, setT1234, empty],
+      [coneT1, setT12, setT12, concreteT1],
+      [coneT1, setT23, setT123, empty],
+      [coneT3, setT12, setT123, setT12],
+      [coneT3, setT1234, setT1234, setT123],
+      [coneT1, nullableConcreteT1, nullableConeT1, concreteT1],
+      [coneT1, nullableConcreteT2, nullableSetT12, empty],
+      [coneT3, nullableConcreteT2, nullableConeT3, concreteT2],
+      [coneT1, nullableConeT1, nullableConeT1, coneT1],
+      [coneT1, nullableConeT3, nullableConeT3, coneT1],
+      [coneT1, nullableConeT4, nullableSetT14, empty],
+      [coneT1, nullableSetT12, nullableSetT12, concreteT1],
+      [coneT3, nullableSetT23, nullableSetT123, setT23],
+      // set
+      [setT12, setT12, setT12, setT12],
+      [setT12, setT123, setT123, setT12],
+      [setT12, setT23, setT123, concreteT2],
+      [setT12, setT34, setT1234, empty],
+      [setT12, nullableConcreteT1, nullableSetT12, concreteT1],
+      [setT12, nullableConcreteT3, nullableSetT123, empty],
+      [setT12, nullableConeT1, nullableSetT12, concreteT1],
+      [setT12, nullableConeT3, nullableSetT123, setT12],
+      [setT12, nullableConeT4, nullableSetT124, empty],
+      [setT12, nullableSetT12, nullableSetT12, setT12],
+      [setT12, nullableSetT123, nullableSetT123, setT12],
+      [setT12, nullableSetT23, nullableSetT123, concreteT2],
+      [setT12, nullableSetT34, nullableSetT1234, empty],
+      // nullableConcrete
+      [
+        nullableConcreteT1,
+        nullableConcreteT1,
+        nullableConcreteT1,
+        nullableConcreteT1
+      ],
+      [nullableConcreteT1, nullableConcreteT2, nullableSetT12, nullableEmpty],
+      [nullableConcreteT1, nullableConeT1, nullableConeT1, nullableConcreteT1],
+      [nullableConcreteT1, nullableConeT3, nullableConeT3, nullableConcreteT1],
+      [nullableConcreteT1, nullableConeT4, nullableSetT14, nullableEmpty],
+      [nullableConcreteT1, nullableSetT12, nullableSetT12, nullableConcreteT1],
+      [nullableConcreteT1, nullableSetT23, nullableSetT123, nullableEmpty],
+      // nullableCone
+      [nullableConeT1, nullableConeT1, nullableConeT1, nullableConeT1],
+      [nullableConeT1, nullableConeT3, nullableConeT3, nullableConeT1],
+      [nullableConeT1, nullableConeT4, nullableSetT14, nullableEmpty],
+      [nullableConeT1, nullableSetT12, nullableSetT12, nullableConcreteT1],
+      [nullableConeT1, nullableSetT23, nullableSetT123, nullableEmpty],
+      [nullableConeT3, nullableSetT14, nullableSetT1234, nullableConcreteT1],
+      // nullableSet
+      [nullableSetT12, nullableSetT12, nullableSetT12, nullableSetT12],
+      [nullableSetT12, nullableSetT23, nullableSetT123, nullableConcreteT2],
+      [nullableSetT12, nullableSetT34, nullableSetT1234, nullableEmpty],
+    ];
+
+    final hierarchy = new TestTypeHierarchy(
+        // subtypes
+        {
+          t1: [t1],
+          t2: [t2],
+          t3: [t1, t2, t3],
+          t4: [t4],
+        },
+        // specializations
+        {
+          t1: concreteT1,
+          t2: concreteT2,
+          t3: setT123,
+          t4: concreteT4
+        });
+
+    for (List testCase in testCases) {
+      Type a = testCase[0] as Type;
+      Type b = testCase[1] as Type;
+      Type union = testCase[2] as Type;
+      Type intersection = testCase[3] as Type;
+
+      expect(a.union(b, hierarchy), equals(union),
+          reason: "Test case: UNION($a, $b) = $union");
+      expect(b.union(a, hierarchy), equals(union),
+          reason: "Test case: UNION($b, $a) = $union");
+      expect(a.intersection(b, hierarchy), equals(intersection),
+          reason: "Test case: INTERSECTION($a, $b) = $intersection");
+      expect(b.intersection(a, hierarchy), equals(intersection),
+          reason: "Test case: INTERSECTION($b, $a) = $intersection");
+    }
+  });
+
+  test('hashcode-equals', () {
+    final c1 = new Class(name: 'C1');
+    final c2 = new Class(name: 'C2');
+    final c3 = new Class(name: 'C3');
+
+    final t1a = new InterfaceType(c1);
+    final t1b = new InterfaceType(c1);
+    final t2 = new InterfaceType(c2);
+    final t3 = new InterfaceType(c3);
+    final f1a = new FunctionType([t1a], const VoidType());
+    final f1b = new FunctionType([t1b], const VoidType());
+    final f2 = new FunctionType([t1a, t1a], const VoidType());
+
+    void eq(dynamic a, dynamic b) {
+      expect(a == b, isTrue, reason: "Test case: $a == $b");
+      expect(a.hashCode == b.hashCode, isTrue,
+          reason: "Test case: ${a}.hashCode == ${b}.hashCode");
+    }
+
+    void ne(dynamic a, dynamic b) {
+      expect(a == b, isFalse, reason: "Test case: $a != $b");
+
+      // Hash codes can be the same, but it is unlikely.
+      expect(a.hashCode == b.hashCode, isFalse,
+          reason: "Test case: ${a}.hashCode != ${b}.hashCode");
+    }
+
+    eq(t1a, t1b);
+    ne(t1a, t2);
+    eq(f1a, f1b);
+    ne(f1a, f2);
+    ne(t1a, f1a);
+
+    eq(new EmptyType(), new EmptyType());
+    ne(new EmptyType(), new AnyType());
+    ne(new EmptyType(), new ConcreteType(t1a));
+    ne(new EmptyType(), new ConeType(t1a));
+    ne(new EmptyType(),
+        new SetType([new ConcreteType(t1a), new ConcreteType(t2)].toSet()));
+    ne(new EmptyType(), new NullableType(new EmptyType()));
+
+    eq(new AnyType(), new AnyType());
+    ne(new AnyType(), new ConcreteType(t1a));
+    ne(new AnyType(), new ConeType(t1a));
+    ne(new AnyType(),
+        new SetType([new ConcreteType(t1a), new ConcreteType(t2)].toSet()));
+    ne(new AnyType(), new NullableType(new EmptyType()));
+
+    eq(new ConcreteType(t1a), new ConcreteType(t1b));
+    eq(new ConcreteType(f1a), new ConcreteType(f1b));
+    ne(new ConcreteType(t1a), new ConcreteType(t2));
+    ne(new ConcreteType(f1a), new ConcreteType(f2));
+    ne(new ConcreteType(t1a), new ConcreteType(f1a));
+    ne(new ConcreteType(t1a), new ConeType(t1a));
+    ne(new ConcreteType(t1a), new ConeType(t2));
+    ne(new ConcreteType(t1a),
+        new SetType([new ConcreteType(t1a), new ConcreteType(t2)].toSet()));
+    ne(new ConcreteType(t1a), new NullableType(new ConcreteType(t1a)));
+
+    eq(new ConeType(t1a), new ConeType(t1b));
+    eq(new ConeType(f1a), new ConeType(f1b));
+    ne(new ConeType(t1a), new ConeType(t2));
+    ne(new ConeType(f1a), new ConeType(f2));
+    ne(new ConeType(t1a), new ConeType(f1a));
+    ne(new ConeType(t1a),
+        new SetType([new ConcreteType(t1a), new ConcreteType(t2)].toSet()));
+    ne(new ConeType(t1a), new NullableType(new ConeType(t1a)));
+
+    eq(new SetType([new ConcreteType(t1a), new ConcreteType(t2)].toSet()),
+        new SetType([new ConcreteType(t2), new ConcreteType(t1b)].toSet()));
+    eq(
+        new SetType([
+          new ConcreteType(t1a),
+          new ConcreteType(t2),
+          new ConcreteType(t3)
+        ].toSet()),
+        new SetType([
+          new ConcreteType(t2),
+          new ConcreteType(t1b),
+          new ConcreteType(t3)
+        ].toSet()));
+    ne(
+        new SetType([new ConcreteType(t1a), new ConcreteType(t2)].toSet()),
+        new SetType([
+          new ConcreteType(t1a),
+          new ConcreteType(t2),
+          new ConcreteType(t3)
+        ].toSet()));
+    ne(new SetType([new ConcreteType(t1a), new ConcreteType(t2)].toSet()),
+        new SetType([new ConcreteType(t1a), new ConcreteType(t3)].toSet()));
+    ne(
+        new SetType([new ConcreteType(t1a), new ConcreteType(t2)].toSet()),
+        new NullableType(new SetType(
+            [new ConcreteType(t1a), new ConcreteType(t2)].toSet())));
+  });
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart
new file mode 100644
index 0000000..06cf7ea
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class A {
+  void foo1(Object x) {}
+  dynamic get foo2;
+  set foo3(int x);
+}
+
+class B {
+  void bar1(Object arg) {}
+  dynamic get bar2 => null;
+  set bar3(int y) {}
+  int bar4;
+}
+
+class C {
+  interfaceCalls(A aa, Object a2, Object a3, Object a4) {
+    aa.foo1(new B());
+    aa.foo3 = aa.foo2;
+    a4 = aa.foo2(a2, a3, aa.foo1);
+    return a4;
+  }
+
+  dynamicCalls(dynamic aa, Object a2, Object a3, Object a4) {
+    aa.foo1(new B());
+    aa.foo3 = aa.foo2;
+    a4 = aa.foo2(a2, a3, aa.foo1);
+    return a4;
+  }
+}
+
+class D extends B {
+  superCalls(Object a1, Object a2, Object a3, Object a4) {
+    super.bar1(a1);
+    super.bar3 = super.bar4;
+    a4 = super.bar2(a2, a3, super.bar1);
+    return a4;
+  }
+}
+
+main() {}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
new file mode 100644
index 0000000..1e61c59
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/calls.dart.expect
@@ -0,0 +1,78 @@
+------------ #lib::A:: ------------
+%this = _Parameter #0 [#lib::A]
+t1 = _Call direct [dart.core::Object::] (%this)
+RESULT: _T {}?
+------------ #lib::A::foo1 ------------
+%this = _Parameter #0 [#lib::A]
+%x = _Parameter #1 [dart.core::Object]
+RESULT: _T {}?
+------------ #lib::B:: ------------
+%this = _Parameter #0 [#lib::B]
+t1 = _Call direct [dart.core::Object::] (%this)
+RESULT: _T {}?
+------------ #lib::B::bar1 ------------
+%this = _Parameter #0 [#lib::B]
+%arg = _Parameter #1 [dart.core::Object]
+RESULT: _T {}?
+------------ #lib::B::bar2 ------------
+%this = _Parameter #0 [#lib::B]
+RESULT: _T {}?
+------------ #lib::B::bar3 ------------
+%this = _Parameter #0 [#lib::B]
+%y = _Parameter #1 [dart.core::int]
+RESULT: _T {}?
+------------ #lib::B::bar4 ------------
+
+RESULT: _T {}?
+------------ #lib::C:: ------------
+%this = _Parameter #0 [#lib::C]
+t1 = _Call direct [dart.core::Object::] (%this)
+RESULT: _T {}?
+------------ #lib::C::interfaceCalls ------------
+%this = _Parameter #0 [#lib::C]
+%aa = _Parameter #1 [#lib::A]
+%a2 = _Parameter #2 [dart.core::Object]
+%a3 = _Parameter #3 [dart.core::Object]
+%a4 = _Parameter #4 [dart.core::Object]
+t5 = _Call direct [#lib::B::] (_T (#lib::B))
+t6 = _Call [#lib::A::foo1] (%aa, _T (#lib::B))
+t7* = _Call get [#lib::A::foo2] (%aa)
+t8 = _Narrow (t7 to _T (dart.core::int)+?)
+t9 = _Call set [#lib::A::foo3] (%aa, t8)
+t10 = _Call get [#lib::A::foo2] (%aa)
+a4 = _Join [dart.core::Object] (%a4, _T ANY?)
+RESULT: a4
+------------ #lib::C::dynamicCalls ------------
+%this = _Parameter #0 [#lib::C]
+%aa = _Parameter #1 [dynamic]
+%a2 = _Parameter #2 [dart.core::Object]
+%a3 = _Parameter #3 [dart.core::Object]
+%a4 = _Parameter #4 [dart.core::Object]
+t5 = _Call direct [#lib::B::] (_T (#lib::B))
+t6 = _Call dynamic [foo1] (%aa, _T (#lib::B))
+t7* = _Call dynamic get [foo2] (%aa)
+t8 = _Call dynamic set [foo3] (%aa, t7)
+t9* = _Call dynamic get [foo1] (%aa)
+t10* = _Call dynamic [foo2] (%aa, %a2, %a3, t9)
+a4 = _Join [dart.core::Object] (%a4, t10)
+RESULT: a4
+------------ #lib::D:: ------------
+%this = _Parameter #0 [#lib::D]
+t1 = _Call direct [#lib::B::] (%this)
+RESULT: _T {}?
+------------ #lib::D::superCalls ------------
+%this = _Parameter #0 [#lib::D]
+%a1 = _Parameter #1 [dart.core::Object]
+%a2 = _Parameter #2 [dart.core::Object]
+%a3 = _Parameter #3 [dart.core::Object]
+%a4 = _Parameter #4 [dart.core::Object]
+t5 = _Call direct [#lib::B::bar1] (%this, %a1)
+t6* = _Call direct get [#lib::B::bar4] (%this)
+t7 = _Call direct set [#lib::B::bar3] (%this, t6)
+t8* = _Call direct get [#lib::B::bar2] (%this)
+t9* = _Call dynamic [call] (t8, %a2, %a3, _T ANY?)
+a4 = _Join [dart.core::Object] (%a4, t9)
+RESULT: a4
+------------ #lib::main ------------
+
+RESULT: _T {}?
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart
new file mode 100644
index 0000000..820ca28
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+main(List<String> args) {
+  print('Hello, world!');
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart.expect
new file mode 100644
index 0000000..2f27227
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/hello.dart.expect
@@ -0,0 +1,4 @@
+------------ #lib::main ------------
+%args = _Parameter #0 [dart.core::List<dart.core::String>]
+t1 = _Call direct [dart.core::print] (_T (dart.core::String)+)
+RESULT: _T {}?
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart
new file mode 100644
index 0000000..753486f
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+bool someStatic;
+
+class A {}
+
+class B {}
+
+Object foo(Object a1, [Object a2]) {
+  if (someStatic) {
+    a1 = new A();
+  }
+  bar(a1, 42);
+  a1 = new B();
+  return (a1 != a2) ? a1 : a2;
+}
+
+int bar(Object a1, int a2) {
+  Object v1 = a1;
+  if (v1 is int) {
+    int v2 = v1 + a2;
+    return v2 * 3;
+  }
+  return -1;
+}
+
+Object loop1(Object a1, Object a2) {
+  Object x = a1;
+  x = loop1(x, a1);
+  x = a2;
+  return x;
+}
+
+int loop2(int x) {
+  for (int i = 0; i < 5; i++) {
+    x = x + 10;
+  }
+  return x;
+}
+
+main() {}
diff --git a/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
new file mode 100644
index 0000000..d334286
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/summary_collector/vars.dart.expect
@@ -0,0 +1,50 @@
+------------ #lib::A:: ------------
+%this = _Parameter #0 [#lib::A]
+t1 = _Call direct [dart.core::Object::] (%this)
+RESULT: _T {}?
+------------ #lib::B:: ------------
+%this = _Parameter #0 [#lib::B]
+t1 = _Call direct [dart.core::Object::] (%this)
+RESULT: _T {}?
+------------ #lib::foo ------------
+%a1 = _Parameter #0 [dart.core::Object]
+%a2 = _Parameter #1 [dart.core::Object]
+t2 = _Call direct get [#lib::someStatic] ()
+t3 = _Call direct [#lib::A::] (_T (#lib::A))
+a1 = _Join [dart.core::Object] (%a1, _T (#lib::A), _T (#lib::B))
+t5 = _Call direct [#lib::bar] (a1, _T (dart.core::int)+)
+t6 = _Call direct [#lib::B::] (_T (#lib::B))
+a2 = _Join [dart.core::Object] (_T {}?, %a2)
+t8 = _Call [dart.core::Object::==] (a1, a2)
+t9 = _Join [dart.core::Object] (a1, a2)
+t10 = _Narrow (t9 to _T (dart.core::Object)+?)
+RESULT: t10
+------------ #lib::bar ------------
+%a1 = _Parameter #0 [dart.core::Object]
+%a2 = _Parameter #1 [dart.core::int]
+t2 = _Narrow (%a1 to _T (dart.core::int)+)
+t3* = _Call [dart.core::num::+] (t2, %a2)
+t4* = _Call [dart.core::num::*] (t3, _T (dart.core::int)+)
+t5* = _Call [dart.core::int::unary-] (_T (dart.core::int)+)
+%result = _Join [dart.core::int] (t4, t5)
+RESULT: %result
+------------ #lib::loop1 ------------
+%a1 = _Parameter #0 [dart.core::Object]
+%a2 = _Parameter #1 [dart.core::Object]
+t2* = _Call direct [#lib::loop1] (_T (dart.core::Object)+?, %a1)
+x = _Join [dart.core::Object] (%a1, t2, %a2)
+RESULT: x
+------------ #lib::loop2 ------------
+%x = _Parameter #0 [dart.core::int]
+t1* = _Call [dart.core::num::+] (_T (dart.core::int)+?, _T (dart.core::int)+)
+i = _Join [dart.core::int] (_T (dart.core::int)+, t1)
+t3 = _Call [dart.core::num::<] (i, _T (dart.core::int)+)
+t4* = _Call [dart.core::num::+] (_T (dart.core::int)+?, _T (dart.core::int)+)
+x = _Join [dart.core::int] (%x, t4)
+RESULT: x
+------------ #lib::main ------------
+
+RESULT: _T {}?
+------------ #lib::someStatic ------------
+
+RESULT: _T {}?
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart
new file mode 100644
index 0000000..e1fd3c5
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart
@@ -0,0 +1,44 @@
+import 'dart:typed_data';
+
+class _Vector {
+  _Vector(int size)
+      : _offset = 0,
+        _length = size,
+        _elements = new Float64List(size);
+
+  _Vector.fromVOL(List<double> values, int offset, int length)
+      : _offset = offset,
+        _length = length,
+        _elements = values;
+
+  final int _offset;
+
+  final int _length;
+
+  final List<double> _elements;
+
+  double operator [](int i) => _elements[i + _offset];
+  void operator []=(int i, double value) {
+    _elements[i + _offset] = value;
+  }
+
+  double operator *(_Vector a) {
+    double result = 0.0;
+    for (int i = 0; i < _length; i += 1) result += this[i] * a[i];
+    return result;
+  }
+}
+
+_Vector v = new _Vector(10);
+double x = 0.0;
+
+main(List<String> args) {
+  Stopwatch timer = new Stopwatch()..start();
+
+  for (int i = 0; i < 100000000; i++) {
+    x = x + v * v;
+  }
+
+  timer.stop();
+  print("Elapsed ${timer.elapsedMilliseconds}ms, result $x");
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
new file mode 100644
index 0000000..e409910
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
@@ -0,0 +1,37 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+import "dart:typed_data" as typ;
+
+class _Vector extends core::Object {
+  final field core::int _offset;
+  final field core::int _length;
+  final field core::List<core::double> _elements;
+  constructor •(core::int size) → void
+    : self::_Vector::_offset = 0, self::_Vector::_length = size, self::_Vector::_elements = [@vm.inferred-type.metadata=dart.typed_data::_Float64List] typ::Float64List::•(size), super core::Object::•()
+    ;
+  constructor fromVOL(core::List<core::double> values, core::int offset, core::int length) → void
+    : self::_Vector::_offset = offset, self::_Vector::_length = length, self::_Vector::_elements = values, super core::Object::•()
+    throw "TFA Error: #lib::_Vector::fromVOL";
+  operator [](core::int i) → core::double
+    return [@vm.direct-call.metadata=dart.typed_data::_Float64List::[]] [@vm.inferred-type.metadata=dart.core::_Double] [@vm.direct-call.metadata=#lib::_Vector::_elements??] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]}(i.{core::num::+}([@vm.direct-call.metadata=#lib::_Vector::_offset??] [@vm.inferred-type.metadata=!] this.{self::_Vector::_offset}));
+  operator []=(core::int i, core::double value) → void {
+    [@vm.direct-call.metadata=#lib::_Vector::_elements??] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]=}([@vm.inferred-type.metadata=!] i.{core::num::+}([@vm.direct-call.metadata=#lib::_Vector::_offset??] [@vm.inferred-type.metadata=!] this.{self::_Vector::_offset}), value);
+  }
+  operator *(self::_Vector a) → core::double {
+    core::double result = 0.0;
+    for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<??] i.{core::num::<}([@vm.direct-call.metadata=#lib::_Vector::_length] [@vm.inferred-type.metadata=!] this.{self::_Vector::_length}); i = i.{core::num::+}(1))
+      result = [@vm.direct-call.metadata=dart.core::_Double::+??] [@vm.inferred-type.metadata=dart.core::_Double] result.{core::double::+}([@vm.direct-call.metadata=dart.core::_Double::*] [@vm.inferred-type.metadata=dart.core::_Double] [@vm.direct-call.metadata=#lib::_Vector::[]] [@vm.inferred-type.metadata=dart.core::_Double] this.{self::_Vector::[]}(i).{core::double::*}([@vm.direct-call.metadata=#lib::_Vector::[]] [@vm.inferred-type.metadata=dart.core::_Double] a.{self::_Vector::[]}(i)));
+    return result;
+  }
+}
+static field self::_Vector v = new self::_Vector::•(10);
+static field core::double x = 0.0;
+static method main(core::List<core::String> args) → dynamic {
+  core::Stopwatch timer = let final core::Stopwatch #t1 = new core::Stopwatch::•() in let final dynamic #t2 = [@vm.direct-call.metadata=dart.core::Stopwatch::start] #t1.{core::Stopwatch::start}() in #t1;
+  for (core::int i = 0; [@vm.direct-call.metadata=dart.core::_IntegerImplementation::<??] i.{core::num::<}(100000000); i = i.{core::num::+}(1)) {
+    self::x = [@vm.direct-call.metadata=dart.core::_Double::+] [@vm.inferred-type.metadata=dart.core::_Double] [@vm.inferred-type.metadata=dart.core::_Double] self::x.{core::double::+}([@vm.direct-call.metadata=#lib::_Vector::*] [@vm.inferred-type.metadata=dart.core::_Double] [@vm.inferred-type.metadata=#lib::_Vector] self::v.{self::_Vector::*}([@vm.inferred-type.metadata=#lib::_Vector] self::v));
+  }
+  [@vm.direct-call.metadata=dart.core::Stopwatch::stop] timer.{core::Stopwatch::stop}();
+  core::print("Elapsed ${[@vm.direct-call.metadata=dart.core::Stopwatch::elapsedMilliseconds] timer.{core::Stopwatch::elapsedMilliseconds}}ms, result ${self::x}");
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart
new file mode 100644
index 0000000..9fa7451
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+abstract class A {
+  int foo();
+}
+
+class B extends A {
+  int foo() => 1;
+}
+
+class C implements A {
+  int foo() => 2;
+}
+
+class D extends C {}
+
+class E {
+  String toString() => 'D';
+}
+
+void callerA1(A aa) {
+  aa.foo();
+}
+
+void callerA2(A aa) {
+  aa.foo();
+}
+
+void callerA3(A aa) {
+  aa.foo();
+}
+
+void callerA4(A aa) {
+  aa.foo();
+}
+
+void callerE1(x) {
+  x.toString();
+}
+
+void callerE2(x) {
+  x.toString();
+}
+
+A dd;
+E ee = new E();
+
+main(List<String> args) {
+  callerA1(new B());
+  callerA1(new C());
+  callerA2(new B());
+  callerA3(new C());
+  callerA4(dd);
+  dd = new D();
+
+  callerE1('abc');
+  callerE2(ee);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
new file mode 100644
index 0000000..8b353eb
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/devirt.dart.expect
@@ -0,0 +1,66 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → core::int;
+}
+class B extends self::A {
+  default constructor •() → void
+    : super self::A::•()
+    ;
+  method foo() → core::int
+    return 1;
+}
+class C extends core::Object implements self::A {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → core::int
+    return 2;
+}
+class D extends self::C {
+  default constructor •() → void
+    : super self::C::•()
+    ;
+}
+class E extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method toString() → core::String
+    return "D";
+}
+static field self::A dd;
+static field self::E ee = new self::E::•();
+static method callerA1(self::A aa) → void {
+  aa.{self::A::foo}();
+}
+static method callerA2(self::A aa) → void {
+  [@vm.direct-call.metadata=#lib::B::foo] aa.{self::A::foo}();
+}
+static method callerA3(self::A aa) → void {
+  [@vm.direct-call.metadata=#lib::C::foo] aa.{self::A::foo}();
+}
+static method callerA4(self::A aa) → void {
+  [@vm.direct-call.metadata=#lib::C::foo??] aa.{self::A::foo}();
+}
+static method callerE1(dynamic x) → void {
+  [@vm.direct-call.metadata=dart.core::_StringBase::toString] x.{core::Object::toString}();
+}
+static method callerE2(dynamic x) → void {
+  [@vm.direct-call.metadata=#lib::E::toString] x.{core::Object::toString}();
+}
+static method main(core::List<core::String> args) → dynamic {
+  self::callerA1(new self::B::•());
+  self::callerA1(new self::C::•());
+  self::callerA2(new self::B::•());
+  self::callerA3(new self::C::•());
+  self::callerA4([@vm.inferred-type.metadata=#lib::D?] self::dd);
+  self::dd = new self::D::•();
+  self::callerE1("abc");
+  self::callerE2([@vm.inferred-type.metadata=#lib::E] self::ee);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart b/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart
new file mode 100644
index 0000000..11752a9
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class A {}
+
+Object foo() => new A();
+
+main(List<String> args) {
+  print(foo());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart.expect
new file mode 100644
index 0000000..936910d
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/hello.dart.expect
@@ -0,0 +1,14 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+}
+static method foo() → core::Object
+  return new self::A::•();
+static method main(core::List<core::String> args) → dynamic {
+  core::print([@vm.inferred-type.metadata=#lib::A] self::foo());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart
new file mode 100644
index 0000000..b70a6cf
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class T1 {}
+
+class T2 {}
+
+abstract class A {
+  foo();
+}
+
+class B extends A {
+  foo() => new T1();
+}
+
+class C implements B {
+  foo() => new T2();
+}
+
+class Intermediate {
+  bar(A aa) => aa.foo();
+}
+
+use1(Intermediate i, A aa) => i.bar(aa);
+use2(Intermediate i, A aa) => i.bar(aa);
+
+Function unknown;
+
+getDynamic() => unknown.call();
+
+allocateB() {
+  new B();
+}
+
+main(List<String> args) {
+  use1(new Intermediate(), getDynamic()); // No subclasses of A allocated.
+
+  allocateB();
+
+  use2(new Intermediate(), getDynamic()); // Now B is allocated.
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
new file mode 100644
index 0000000..72ac45b
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class1.dart.expect
@@ -0,0 +1,56 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class T1 extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class T2 extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    throw "TFA Error: #lib::T2::";
+}
+abstract class A extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → dynamic;
+}
+class B extends self::A {
+  default constructor •() → void
+    : super self::A::•()
+    ;
+  method foo() → dynamic
+    return new self::T1::•();
+}
+class C extends core::Object implements self::B {
+  default constructor •() → void
+    : super core::Object::•()
+    throw "TFA Error: #lib::C::";
+  method foo() → dynamic
+    throw "TFA Error: #lib::C::foo";
+}
+class Intermediate extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method bar(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::B::foo??] [@vm.inferred-type.metadata=#lib::T1] aa.{self::A::foo}();
+}
+static field core::Function unknown;
+static method use1(self::Intermediate i, self::A aa) → dynamic
+  return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=#lib::T1] i.{self::Intermediate::bar}(aa);
+static method use2(self::Intermediate i, self::A aa) → dynamic
+  return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=#lib::T1] i.{self::Intermediate::bar}(aa);
+static method getDynamic() → dynamic
+  return self::unknown.call();
+static method allocateB() → dynamic {
+  new self::B::•();
+}
+static method main(core::List<core::String> args) → dynamic {
+  self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError} self::A);
+  self::allocateB();
+  self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError} self::A);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart
new file mode 100644
index 0000000..5248ac9
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class T1 {}
+
+class T2 {}
+
+abstract class A {
+  foo();
+}
+
+class B extends A {
+  foo() => new T1();
+}
+
+abstract class C implements B {}
+
+class D {}
+
+class E extends D with C {
+  foo() => new T2();
+}
+
+class Intermediate {
+  bar(A aa) => aa.foo();
+}
+
+use1(Intermediate i, A aa) => i.bar(aa);
+use2(Intermediate i, A aa) => i.bar(aa);
+use3(Intermediate i, A aa) => i.bar(aa);
+
+Function unknown;
+
+getDynamic() => unknown.call();
+
+allocateB() {
+  new B();
+}
+
+allocateE() {
+  new E();
+}
+
+main(List<String> args) {
+  use1(new Intermediate(), getDynamic()); // No subclasses of A allocated.
+
+  allocateB();
+
+  use2(new Intermediate(), getDynamic()); // Now B is allocated.
+
+  allocateE();
+
+  use3(new Intermediate(), getDynamic()); // Now E is also allocated.
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
new file mode 100644
index 0000000..2559e906
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_new_class2.dart.expect
@@ -0,0 +1,78 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class T1 extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class T2 extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class A extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → dynamic;
+}
+class B extends self::A {
+  default constructor •() → void
+    : super self::A::•()
+    ;
+  method foo() → dynamic
+    return new self::T1::•();
+}
+abstract class C extends core::Object implements self::B {
+  default constructor •() → void
+    : super core::Object::•()
+    throw "TFA Error: #lib::C::";
+}
+class D extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+}
+abstract class _D&C extends self::D implements self::C {
+  constructor •() → void
+    : super self::D::•()
+    ;
+}
+class E extends self::_D&C {
+  default constructor •() → void
+    : super self::D::•()
+    ;
+  method foo() → dynamic
+    return new self::T2::•();
+}
+class Intermediate extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method bar(self::A aa) → dynamic
+    return [@vm.inferred-type.metadata=!] aa.{self::A::foo}();
+}
+static field core::Function unknown;
+static method use1(self::Intermediate i, self::A aa) → dynamic
+  return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=!] i.{self::Intermediate::bar}(aa);
+static method use2(self::Intermediate i, self::A aa) → dynamic
+  return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=!] i.{self::Intermediate::bar}(aa);
+static method use3(self::Intermediate i, self::A aa) → dynamic
+  return [@vm.direct-call.metadata=#lib::Intermediate::bar] [@vm.inferred-type.metadata=!] i.{self::Intermediate::bar}(aa);
+static method getDynamic() → dynamic
+  return self::unknown.call();
+static method allocateB() → dynamic {
+  new self::B::•();
+}
+static method allocateE() → dynamic {
+  new self::E::•();
+}
+static method main(core::List<core::String> args) → dynamic {
+  self::use1(new self::Intermediate::•(), self::getDynamic() as{TypeError} self::A);
+  self::allocateB();
+  self::use2(new self::Intermediate::•(), self::getDynamic() as{TypeError} self::A);
+  self::allocateE();
+  self::use3(new self::Intermediate::•(), self::getDynamic() as{TypeError} self::A);
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart
new file mode 100644
index 0000000..7fb845e
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+class T1 {}
+
+class T2 {}
+
+class A {
+  dynamic field1 = new T1();
+  dynamic field2 = new T1();
+}
+
+// Methods of this class should have inferred type = T1.
+class DeepCaller1 {
+  barL1(A aa) => barL2(aa);
+  barL2(A aa) => barL3(aa);
+  barL3(A aa) => barL4(aa);
+  barL4(A aa) => aa.field1;
+}
+
+// Methods of this class should have inferred type = T1 | T2.
+class DeepCaller2 {
+  barL1(A aa) => barL2(aa);
+  barL2(A aa) => barL3(aa);
+  barL3(A aa) => barL4(aa);
+  barL4(A aa) => aa.field2;
+}
+
+use1(DeepCaller1 x, A aa) => x.barL1(aa);
+use2(DeepCaller2 x, A aa) => x.barL1(aa);
+
+Function unknown;
+
+getDynamic() => unknown.call();
+
+void setField2(A aa, dynamic value) {
+  aa.field2 = value;
+}
+
+main(List<String> args) {
+  new A();
+  new T1();
+  new T2();
+
+  use1(new DeepCaller1(), getDynamic());
+  use2(new DeepCaller2(), getDynamic());
+
+  setField2(new A(), new T2());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
new file mode 100644
index 0000000..d3ac445
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_set_field.dart.expect
@@ -0,0 +1,65 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+class T1 extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class T2 extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class A extends core::Object {
+  field dynamic field1 = new self::T1::•();
+  field dynamic field2 = new self::T1::•();
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+}
+class DeepCaller1 extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method barL1(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::DeepCaller1::barL2] [@vm.inferred-type.metadata=#lib::T1] this.{self::DeepCaller1::barL2}(aa);
+  method barL2(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::DeepCaller1::barL3] [@vm.inferred-type.metadata=#lib::T1] this.{self::DeepCaller1::barL3}(aa);
+  method barL3(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::DeepCaller1::barL4] [@vm.inferred-type.metadata=#lib::T1] this.{self::DeepCaller1::barL4}(aa);
+  method barL4(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::A::field1??] [@vm.inferred-type.metadata=#lib::T1] aa.{self::A::field1};
+}
+class DeepCaller2 extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method barL1(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::DeepCaller2::barL2] [@vm.inferred-type.metadata=!] this.{self::DeepCaller2::barL2}(aa);
+  method barL2(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::DeepCaller2::barL3] [@vm.inferred-type.metadata=!] this.{self::DeepCaller2::barL3}(aa);
+  method barL3(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::DeepCaller2::barL4] [@vm.inferred-type.metadata=!] this.{self::DeepCaller2::barL4}(aa);
+  method barL4(self::A aa) → dynamic
+    return [@vm.direct-call.metadata=#lib::A::field2??] [@vm.inferred-type.metadata=!] aa.{self::A::field2};
+}
+static field core::Function unknown;
+static method use1(self::DeepCaller1 x, self::A aa) → dynamic
+  return [@vm.direct-call.metadata=#lib::DeepCaller1::barL1] [@vm.inferred-type.metadata=#lib::T1] x.{self::DeepCaller1::barL1}(aa);
+static method use2(self::DeepCaller2 x, self::A aa) → dynamic
+  return [@vm.direct-call.metadata=#lib::DeepCaller2::barL1] [@vm.inferred-type.metadata=!] x.{self::DeepCaller2::barL1}(aa);
+static method getDynamic() → dynamic
+  return self::unknown.call();
+static method setField2(self::A aa, dynamic value) → void {
+  [@vm.direct-call.metadata=#lib::A::field2] aa.{self::A::field2} = value;
+}
+static method main(core::List<core::String> args) → dynamic {
+  new self::A::•();
+  new self::T1::•();
+  new self::T2::•();
+  self::use1(new self::DeepCaller1::•(), self::getDynamic() as{TypeError} self::A);
+  self::use2(new self::DeepCaller2::•(), self::getDynamic() as{TypeError} self::A);
+  self::setField2(new self::A::•(), new self::T2::•());
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart
new file mode 100644
index 0000000..db52bf0
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+A aa = new B();
+
+dynamic knownResult() => new B();
+
+abstract class A {
+  int foo();
+}
+
+class B extends A {
+  int foo() => 1 + knownResult().foo(); // Should have metadata.
+}
+
+class C implements A {
+  int foo() => 2 + knownResult().foo(); // Should be unreachable.
+}
+
+class TearOffInterfaceMethod {
+  dynamic bazz;
+  TearOffInterfaceMethod(A arg) : bazz = arg.foo;
+}
+
+main(List<String> args) {
+  new TearOffInterfaceMethod(new B()).bazz();
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
new file mode 100644
index 0000000..65f9cd2
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_interface_method.dart.expect
@@ -0,0 +1,36 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → core::int;
+}
+class B extends self::A {
+  default constructor •() → void
+    : super self::A::•()
+    ;
+  method foo() → core::int
+    return 1.{core::num::+}([@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
+}
+class C extends core::Object implements self::A {
+  default constructor •() → void
+    : super core::Object::•()
+    throw "TFA Error: #lib::C::";
+  method foo() → core::int
+    throw "TFA Error: #lib::C::foo";
+}
+class TearOffInterfaceMethod extends core::Object {
+  field dynamic bazz;
+  constructor •(self::A arg) → void
+    : self::TearOffInterfaceMethod::bazz = arg.{self::A::foo}, super core::Object::•()
+    ;
+}
+static field self::A aa = throw "TFA Error: #lib::aa";
+static method knownResult() → dynamic
+  return new self::B::•();
+static method main(core::List<core::String> args) → dynamic {
+  new self::TearOffInterfaceMethod::•(new self::B::•()).{self::TearOffInterfaceMethod::bazz}();
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart
new file mode 100644
index 0000000..ebe01db
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+A aa = new B();
+
+dynamic knownResult() => new B();
+
+abstract class A {
+  int foo();
+}
+
+class B extends A {
+  int foo() => 1 + knownResult().foo(); // Should have metadata.
+}
+
+class C implements A {
+  int foo() => 2 + knownResult().foo(); // Should be unreachable.
+}
+
+class Base {
+  int foo() => 3 + knownResult().foo(); // Should have metadata.
+  int doCall(x) => x();
+}
+
+class TearOffSuperMethod extends Base {
+  int foo() {
+    // Should be unreachable.
+    aa = new C();
+    return 4 + knownResult().foo();
+  }
+
+  int bar() => doCall(super.foo);
+}
+
+main(List<String> args) {
+  new TearOffSuperMethod().bar();
+
+  aa.foo(); // Should be devirtualized.
+}
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
new file mode 100644
index 0000000..4f68c9e
--- /dev/null
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_super_method.dart.expect
@@ -0,0 +1,49 @@
+library #lib;
+import self as self;
+import "dart:core" as core;
+
+abstract class A extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  abstract method foo() → core::int;
+}
+class B extends self::A {
+  default constructor •() → void
+    : super self::A::•()
+    ;
+  method foo() → core::int
+    return 1.{core::num::+}([@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
+}
+class C extends core::Object implements self::A {
+  default constructor •() → void
+    : super core::Object::•()
+    throw "TFA Error: #lib::C::";
+  method foo() → core::int
+    throw "TFA Error: #lib::C::foo";
+}
+class Base extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method foo() → core::int
+    return 3.{core::num::+}([@vm.inferred-type.metadata=#lib::B] self::knownResult().foo() as{TypeError} core::num) as{TypeError} core::int;
+  method doCall(dynamic x) → core::int
+    return x.call() as{TypeError} core::int;
+}
+class TearOffSuperMethod extends self::Base {
+  default constructor •() → void
+    : super self::Base::•()
+    ;
+  method foo() → core::int
+    throw "TFA Error: #lib::TearOffSuperMethod::foo";
+  method bar() → core::int
+    return [@vm.direct-call.metadata=#lib::Base::doCall] this.{self::Base::doCall}(super.{self::Base::foo});
+}
+static field self::A aa = new self::B::•();
+static method knownResult() → dynamic
+  return new self::B::•();
+static method main(core::List<core::String> args) → dynamic {
+  [@vm.direct-call.metadata=#lib::TearOffSuperMethod::bar] new self::TearOffSuperMethod::•().{self::TearOffSuperMethod::bar}();
+  [@vm.direct-call.metadata=#lib::B::foo] [@vm.inferred-type.metadata=#lib::B] self::aa.{self::A::foo}();
+}
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 6afa317..9142737 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -5,6 +5,7 @@
 import("../../build/compiled_action.gni")
 import("../../sdk/lib/_http/http_sources.gni")
 import("../../sdk/lib/io/io_sources.gni")
+import("../../sdk/lib/cli/cli_sources.gni")
 import("../runtime_args.gni")
 import("../vm/compiler/compiler_sources.gni")
 import("../vm/vm_sources.gni")
@@ -12,6 +13,8 @@
 import("builtin_sources.gni")
 import("io_impl_sources.gni")
 import("io_sources.gni")
+import("cli_impl_sources.gni")
+import("cli_sources.gni")
 import("vmservice/vmservice_sources.gni")
 
 # Generate a resources.cc file for the service isolate without Observatory.
@@ -109,6 +112,22 @@
   output = "$target_gen_dir/http_gen.cc"
 }
 
+rebased_cli_sdk_sources = rebase_path(cli_sdk_sources, ".", "../../sdk/lib/cli")
+
+gen_library_src_path("generate_cli_cc_file") {
+  name = "cli"
+  kind = "source"
+  sources = [ "../../sdk/lib/cli/cli.dart" ] + rebased_cli_sdk_sources
+  output = "$target_gen_dir/cli_gen.cc"
+}
+
+gen_library_src_path("generate_cli_patch_cc_file") {
+  name = "cli"
+  kind = "patch"
+  sources = cli_runtime_sources
+  output = "$target_gen_dir/cli_patch_gen.cc"
+}
+
 gen_library_src_path("generate_html_cc_file") {
   name = "html"
   kind = "source"
@@ -235,6 +254,8 @@
     public_configs = [ ":libdart_builtin_config" ]
     deps = [
       ":generate_builtin_cc_file",
+      ":generate_cli_cc_file",
+      ":generate_cli_patch_cc_file",
       ":generate_html_cc_file",
       ":generate_html_common_cc_file",
       ":generate_http_cc_file",
@@ -297,11 +318,15 @@
              ":generate_http_cc_file",
              ":generate_io_cc_file",
              ":generate_io_patch_cc_file",
+             ":generate_cli_cc_file",
+             ":generate_cli_patch_cc_file",
            ] + extra_deps
 
     sources = [
       # Include generated source files.
       "$target_gen_dir/builtin_gen.cc",
+      "$target_gen_dir/cli_gen.cc",
+      "$target_gen_dir/cli_patch_gen.cc",
       "$target_gen_dir/http_gen.cc",
       "$target_gen_dir/io_gen.cc",
       "$target_gen_dir/io_patch_gen.cc",
@@ -417,7 +442,7 @@
 
     defines = [ "DART_IO_SECURE_SOCKET_DISABLED" ]
 
-    sources = io_impl_sources + builtin_impl_sources
+    sources = io_impl_sources + builtin_impl_sources + cli_impl_sources
     sources += [
       "io_natives.cc",
       "io_natives.h",
@@ -494,7 +519,7 @@
       libs = [ "launchpad" ]
     }
 
-    sources = io_impl_sources + builtin_impl_sources
+    sources = io_impl_sources + builtin_impl_sources + cli_impl_sources
     sources += [
                  "builtin_natives.cc",
                  "io_natives.cc",
@@ -712,7 +737,7 @@
     if (is_fuchsia) {
       configs -= [ "//build/config:symbol_visibility_hidden" ]
     }
-    if (is_fuchsia_host) {
+    if (target_os != current_os && target_os == "fuchsia") {
       # We already have these in the standalone build, but Fuchsia doesn't
       # have them. They are needed for running Fuchsia binaries built for the
       # host.
@@ -840,6 +865,8 @@
     ":generate_js_util_cc_file",
     ":generate_metadata_cc_file",
     ":generate_svg_cc_file",
+    ":generate_cli_cc_file",
+    ":generate_cli_patch_cc_file",
     ":generate_web_audio_cc_file",
     ":generate_web_gl_cc_file",
     ":generate_web_sql_cc_file",
@@ -871,6 +898,8 @@
     "$target_gen_dir/metadata_gen.cc",
     "$target_gen_dir/resources_gen.cc",
     "$target_gen_dir/svg_gen.cc",
+    "$target_gen_dir/cli_gen.cc",
+    "$target_gen_dir/cli_patch_gen.cc",
     "$target_gen_dir/web_audio_gen.cc",
     "$target_gen_dir/web_gl_gen.cc",
     "$target_gen_dir/web_sql_gen.cc",
@@ -1005,7 +1034,7 @@
 }
 
 executable("run_vm_tests") {
-  if (is_fuchsia || is_fuchsia_host) {
+  if (target_os == "fuchsia") {
     testonly = true
   }
 
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index 049d2e9..3d205b9 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -23,6 +23,8 @@
     {DartUtils::kIOLibURL, io_source_paths_, DartUtils::kIOLibPatchURL,
      io_patch_paths_, true},
     {DartUtils::kHttpLibURL, _http_source_paths_, NULL, NULL, false},
+    {DartUtils::kCLILibURL, cli_source_paths_, DartUtils::kCLILibPatchURL,
+     cli_patch_paths_, true},
 
 #if defined(DART_NO_SNAPSHOT)
     // Only include these libraries in the dart_bootstrap case for now.
diff --git a/runtime/bin/builtin.h b/runtime/bin/builtin.h
index 8182f3b..4823d91 100644
--- a/runtime/bin/builtin.h
+++ b/runtime/bin/builtin.h
@@ -30,6 +30,7 @@
     kBuiltinLibrary = 0,
     kIOLibrary,
     kHttpLibrary,
+    kCLILibrary,
   };
 
   // Get source corresponding to built in library specified in 'id'.
@@ -79,6 +80,8 @@
   static const char* web_gl_source_paths_[];
   static const char* metadata_source_paths_[];
   static const char* web_sql_source_paths_[];
+  static const char* cli_source_paths_[];
+  static const char* cli_patch_paths_[];
   static const char* svg_source_paths_[];
   static const char* web_audio_source_paths_[];
 
diff --git a/runtime/bin/builtin_nolib.cc b/runtime/bin/builtin_nolib.cc
index 4b11341..2bf2599 100644
--- a/runtime/bin/builtin_nolib.cc
+++ b/runtime/bin/builtin_nolib.cc
@@ -18,6 +18,7 @@
     {DartUtils::kBuiltinLibURL, NULL, NULL, NULL, true},
     {DartUtils::kIOLibURL, NULL, NULL, NULL, true},
     {DartUtils::kHttpLibURL, NULL, NULL, NULL, false},
+    {DartUtils::kCLILibURL, NULL, NULL, NULL, true},
     // End marker.
     {NULL, NULL, NULL, NULL, false}};
 
diff --git a/runtime/bin/cli.cc b/runtime/bin/cli.cc
new file mode 100644
index 0000000..d56d522
--- /dev/null
+++ b/runtime/bin/cli.cc
@@ -0,0 +1,27 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#include "bin/builtin.h"
+#include "bin/dartutils.h"
+
+#include "include/dart_api.h"
+
+namespace dart {
+namespace bin {
+
+void FUNCTION_NAME(CLI_WaitForEvent)(Dart_NativeArguments args) {
+  int64_t timeout_millis;
+  Dart_Handle result = Dart_GetNativeIntegerArgument(args, 0, &timeout_millis);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  result = Dart_WaitForEvent(timeout_millis);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
+  Dart_SetReturnValue(args, result);
+}
+
+}  // namespace bin
+}  // namespace dart
diff --git a/runtime/bin/cli_impl_sources.gni b/runtime/bin/cli_impl_sources.gni
new file mode 100644
index 0000000..86f8fd7
--- /dev/null
+++ b/runtime/bin/cli_impl_sources.gni
@@ -0,0 +1,6 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file contains some C++ sources for the dart:cli library.
+cli_impl_sources = [ "cli.cc" ]
diff --git a/runtime/bin/cli_patch.dart b/runtime/bin/cli_patch.dart
new file mode 100644
index 0000000..504a0db
--- /dev/null
+++ b/runtime/bin/cli_patch.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "dart:_internal" show patch;
+
+@patch
+void _waitForEvent(int timeoutMillis) native "CLI_WaitForEvent";
diff --git a/runtime/bin/cli_sources.gni b/runtime/bin/cli_sources.gni
new file mode 100644
index 0000000..532fbba
--- /dev/null
+++ b/runtime/bin/cli_sources.gni
@@ -0,0 +1,6 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file contains all sources for the dart:cli library.
+cli_runtime_sources = [ "cli_patch.dart" ]
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index e53d6db..f42ca27 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -46,6 +46,8 @@
 const char* const DartUtils::kHttpLibURL = "dart:_http";
 const char* const DartUtils::kIOLibURL = "dart:io";
 const char* const DartUtils::kIOLibPatchURL = "dart:io-patch";
+const char* const DartUtils::kCLILibURL = "dart:cli";
+const char* const DartUtils::kCLILibPatchURL = "dart:cli-patch";
 const char* const DartUtils::kUriLibURL = "dart:uri";
 const char* const DartUtils::kHttpScheme = "http:";
 const char* const DartUtils::kVMServiceLibURL = "dart:vmservice";
@@ -169,6 +171,10 @@
   return (strcmp(url_name, kIOLibURL) == 0);
 }
 
+bool DartUtils::IsDartCLILibURL(const char* url_name) {
+  return (strcmp(url_name, kCLILibURL) == 0);
+}
+
 bool DartUtils::IsDartHttpLibURL(const char* url_name) {
   return (strcmp(url_name, kHttpLibURL) == 0);
 }
@@ -477,6 +483,14 @@
   return Dart_Invoke(isolate_lib, NewString("_setupHooks"), 0, NULL);
 }
 
+Dart_Handle DartUtils::PrepareCLILibrary(Dart_Handle cli_lib) {
+  Dart_Handle wait_for_event_handle =
+      Dart_Invoke(cli_lib, NewString("_getWaitForEvent"), 0, NULL);
+  RETURN_IF_ERROR(wait_for_event_handle);
+  return Dart_SetField(cli_lib, NewString("_waitForEventClosure"),
+                       wait_for_event_handle);
+}
+
 Dart_Handle DartUtils::SetupServiceLoadPort() {
   // Wait for the service isolate to initialize the load port.
   Dart_Port load_port = Dart_ServiceWaitForLoadPort();
@@ -539,6 +553,9 @@
   Dart_Handle io_lib = Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
   RETURN_IF_ERROR(io_lib);
   Builtin::SetNativeResolver(Builtin::kIOLibrary);
+  Dart_Handle cli_lib = Builtin::LoadAndCheckLibrary(Builtin::kCLILibrary);
+  RETURN_IF_ERROR(cli_lib);
+  Builtin::SetNativeResolver(Builtin::kCLILibrary);
 
   // Setup the builtin library in a persistent handle attached the isolate
   // specific data as we seem to lookup and use builtin lib a lot.
@@ -560,6 +577,7 @@
   RETURN_IF_ERROR(PrepareCoreLibrary(core_lib, io_lib, is_service_isolate));
   RETURN_IF_ERROR(PrepareIsolateLibrary(isolate_lib));
   RETURN_IF_ERROR(PrepareIOLibrary(io_lib));
+  RETURN_IF_ERROR(PrepareCLILibrary(cli_lib));
   return result;
 }
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index 8c619c4..e2972cc 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -113,6 +113,7 @@
   static bool IsDartSchemeURL(const char* url_name);
   static bool IsDartExtensionSchemeURL(const char* url_name);
   static bool IsDartIOLibURL(const char* url_name);
+  static bool IsDartCLILibURL(const char* url_name);
   static bool IsDartHttpLibURL(const char* url_name);
   static bool IsDartBuiltinLibURL(const char* url_name);
   static bool IsHttpSchemeURL(const char* url_name);
@@ -235,6 +236,8 @@
   static const char* const kHttpLibURL;
   static const char* const kIOLibURL;
   static const char* const kIOLibPatchURL;
+  static const char* const kCLILibURL;
+  static const char* const kCLILibPatchURL;
   static const char* const kUriLibURL;
   static const char* const kHttpScheme;
   static const char* const kVMServiceLibURL;
@@ -254,6 +257,7 @@
                                          Dart_Handle isolate_lib);
   static Dart_Handle PrepareIOLibrary(Dart_Handle io_lib);
   static Dart_Handle PrepareIsolateLibrary(Dart_Handle isolate_lib);
+  static Dart_Handle PrepareCLILibrary(Dart_Handle cli_lib);
 
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(DartUtils);
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 3329221..c5a2e15 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -78,6 +78,9 @@
   delete reinterpret_cast<kernel::Program*>(kernel_platform_);
   kernel_platform_ = NULL;
 
+  delete reinterpret_cast<kernel::Program*>(kKernelServiceProgram);
+  kKernelServiceProgram = NULL;
+
   delete reinterpret_cast<kernel::Program*>(application_kernel_binary_);
   application_kernel_binary_ = NULL;
 }
@@ -109,6 +112,10 @@
   return frontend_filename_;
 }
 
+bool DFE::KernelServiceDillAvailable() {
+  return kernel_service_dill != NULL;
+}
+
 static void NoopRelease(uint8_t* buffer) {}
 
 void* DFE::KernelServiceProgram() {
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index ead2c75..fb3258a 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -72,6 +72,7 @@
   void* ReadScript(const char* script_uri) const;
 
   static void* KernelServiceProgram();
+  static bool KernelServiceDillAvailable();
 
  private:
   // Tries to read [script_uri] as a Kernel IR file.
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 82ab90e..956cfe2 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -462,6 +462,9 @@
   if (DartUtils::IsDartHttpLibURL(url)) {
     return Builtin::kHttpLibrary;
   }
+  if (DartUtils::IsDartCLILibURL(url)) {
+    return Builtin::kCLILibrary;
+  }
   return Builtin::kInvalidLibrary;
 }
 
@@ -1302,6 +1305,9 @@
 
   Dart_Handle library = LoadGenericSnapshotCreationScript(Builtin::kIOLibrary);
   CHECK_RESULT(library);
+  Dart_Handle standalone_library =
+      LoadGenericSnapshotCreationScript(Builtin::kCLILibrary);
+  CHECK_RESULT(standalone_library);
   Dart_Handle result = Dart_FinalizeLoading(false);
   if (Dart_IsError(result)) {
     const char* err_msg = Dart_GetError(library);
@@ -1344,6 +1350,7 @@
   // Setup the native resolver.
   Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
   Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
+  Builtin::LoadAndCheckLibrary(Builtin::kCLILibrary);
 
   ASSERT(Dart_IsServiceIsolate(isolate));
   // Load embedder specific bits and return. Will not start http server.
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 9ecb61d..c207088 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -19,6 +19,7 @@
 // Some classes, like File and Directory, list their implementations in
 // builtin_natives.cc instead.
 #define IO_NATIVE_LIST(V)                                                      \
+  V(CLI_WaitForEvent, 1)                                                       \
   V(Crypto_GetRandomBytes, 1)                                                  \
   V(Directory_Create, 2)                                                       \
   V(Directory_CreateTemp, 2)                                                   \
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 892417f..77004f5 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -221,6 +221,7 @@
     // Setup the native resolver as the snapshot does not carry it.
     Builtin::SetNativeResolver(Builtin::kBuiltinLibrary);
     Builtin::SetNativeResolver(Builtin::kIOLibrary);
+    Builtin::SetNativeResolver(Builtin::kCLILibrary);
   }
   if (isolate_run_app_snapshot) {
     Dart_Handle result = Loader::ReloadNativeExtensions();
@@ -686,6 +687,8 @@
     {"dart:_builtin", "::", "_setPackagesMap"},
     {"dart:_builtin", "::", "_setWorkingDirectory"},
     {"dart:async", "::", "_setScheduleImmediateClosure"},
+    {"dart:cli", "::", "_getWaitForEvent"},
+    {"dart:cli", "::", "_waitForEventClosure"},
     {"dart:io", "::", "_getUriBaseClosure"},
     {"dart:io", "::", "_getWatchSignalInternal"},
     {"dart:io", "::", "_makeDatagram"},
@@ -1091,7 +1094,16 @@
   init_params.entropy_source = DartUtils::EntropySource;
   init_params.get_service_assets = GetVMServiceAssetsArchiveCallback;
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  init_params.start_kernel_isolate = dfe.UseDartFrontend();
+  // Start the kernel isolate only if
+  // 1. --dart_preview_2 and/or --dfe is used
+  //
+  // or
+  //
+  // 2. If we have kernel service dill file linked in and a dill file
+  // was specified as the main dart program.
+  init_params.start_kernel_isolate =
+      dfe.UseDartFrontend() ||
+      (dfe.kernel_file_specified() && DFE::KernelServiceDillAvailable());
 #else
   init_params.start_kernel_isolate = false;
 #endif
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index 03b348f..5b89ff9 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -68,6 +68,8 @@
 
 DEFINE_BOOL_OPTION_CB(preview_dart_2, { Options::dfe()->set_use_dfe(); });
 
+// TODO(sivachandra): Make it an error to specify --dfe without
+// specifying --preview_dart_2.
 DEFINE_STRING_OPTION_CB(dfe, { Options::dfe()->set_frontend_filename(value); });
 
 DEFINE_STRING_OPTION_CB(kernel_binaries,
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index ce36ebc..de90aed 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -1222,6 +1222,16 @@
 DART_EXPORT Dart_Handle Dart_HandleMessages();
 
 /**
+ * Drains the microtask queue, then blocks the calling thread until the current
+ * isolate recieves a message, then handles all messages.
+ *
+ * \param timeout_millis When non-zero, the call returns after the indicated
+          number of milliseconds even if no message was received.
+ * \return A valid handle if no error occurs, otherwise an error handle.
+ */
+DART_EXPORT Dart_Handle Dart_WaitForEvent(int64_t timeout_millis);
+
+/**
  * Handles any pending messages for the vm service for the current
  * isolate.
  *
@@ -2331,7 +2341,7 @@
  * \return An error handle if the exception was not thrown.
  *   Otherwise the function does not return.
  */
-DART_EXPORT Dart_Handle Dart_RethrowException(Dart_Handle exception,
+DART_EXPORT Dart_Handle Dart_ReThrowException(Dart_Handle exception,
                                               Dart_Handle stacktrace);
 
 /*
diff --git a/runtime/lib/integers.dart b/runtime/lib/integers.dart
index 46562e6..7d13829 100644
--- a/runtime/lib/integers.dart
+++ b/runtime/lib/integers.dart
@@ -288,6 +288,12 @@
     if (radix == 10) return this.toString();
     final bool isNegative = this < 0;
     int value = isNegative ? -this : this;
+    if (value < 0) {
+      // With integers limited to 64 bits, the value
+      // MIN_INT64 = -0x8000000000000000 overflows at negation:
+      // -MIN_INT64 == MIN_INT64, so it requires special handling.
+      return _minInt64ToRadixString(radix);
+    }
     List temp = new List();
     do {
       int digit = value % radix;
@@ -313,6 +319,12 @@
     if (negative) {
       value = -value;
       length = 1;
+      if (value < 0) {
+        // With integers limited to 64 bits, the value
+        // MIN_INT64 = -0x8000000000000000 overflows at negation:
+        // -MIN_INT64 == MIN_INT64, so it requires special handling.
+        return _minInt64ToRadixString(radix);
+      }
     }
     // Integer division, rounding up, to find number of _digits.
     length += (value.bitLength + bitsPerDigit - 1) ~/ bitsPerDigit;
@@ -326,6 +338,27 @@
     return string;
   }
 
+  /// Converts negative value to radix string.
+  /// This method is only used to handle corner case of
+  /// MIN_INT64 = -0x8000000000000000.
+  String _minInt64ToRadixString(int radix) {
+    List temp = new List();
+    int value = this;
+    assert(value < 0);
+    do {
+      int digit = -value.remainder(radix);
+      value ~/= radix;
+      temp.add(_digits.codeUnitAt(digit));
+    } while (value != 0);
+    temp.add(0x2d); // '-'.
+
+    _OneByteString string = _OneByteString._allocate(temp.length);
+    for (int i = 0, j = temp.length; j > 0; i++) {
+      string._setAt(i, temp[--j]);
+    }
+    return string;
+  }
+
   // Returns pow(this, e) % m.
   int modPow(int e, int m) {
     if (e is! int) {
diff --git a/runtime/lib/isolate_patch.dart b/runtime/lib/isolate_patch.dart
index 99cb61b..ad4f63b 100644
--- a/runtime/lib/isolate_patch.dart
+++ b/runtime/lib/isolate_patch.dart
@@ -100,7 +100,8 @@
 /// The closure that should be used as scheduleImmediateClosure, when the VM
 /// is responsible for the event loop.
 void _isolateScheduleImmediate(void callback()) {
-  assert(_pendingImmediateCallback == null);
+  assert((_pendingImmediateCallback == null) ||
+      (_pendingImmediateCallback == callback));
   _pendingImmediateCallback = callback;
 }
 
diff --git a/runtime/lib/schedule_microtask_patch.dart b/runtime/lib/schedule_microtask_patch.dart
index d450e8c..4dc837d 100644
--- a/runtime/lib/schedule_microtask_patch.dart
+++ b/runtime/lib/schedule_microtask_patch.dart
@@ -24,3 +24,7 @@
 void _setScheduleImmediateClosure(_ScheduleImmediateClosure closure) {
   _ScheduleImmediate._closure = closure;
 }
+
+void _ensureScheduleImmediate() {
+  _AsyncRun._scheduleImmediate(_startMicrotaskLoop);
+}
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index 03cebd3..c111ac6 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -404,13 +404,12 @@
     return (codeUnit == 0x85) || (codeUnit == 0xA0); // NEL, NBSP.
   }
 
-  // Characters with Whitespace property (Unicode 6.2).
+  // Characters with Whitespace property (Unicode 6.3).
   // 0009..000D    ; White_Space # Cc       <control-0009>..<control-000D>
   // 0020          ; White_Space # Zs       SPACE
   // 0085          ; White_Space # Cc       <control-0085>
   // 00A0          ; White_Space # Zs       NO-BREAK SPACE
   // 1680          ; White_Space # Zs       OGHAM SPACE MARK
-  // 180E          ; White_Space # Zs       MONGOLIAN VOWEL SEPARATOR
   // 2000..200A    ; White_Space # Zs       EN QUAD..HAIR SPACE
   // 2028          ; White_Space # Zl       LINE SEPARATOR
   // 2029          ; White_Space # Zp       PARAGRAPH SEPARATOR
@@ -426,7 +425,7 @@
     if (codeUnit < 0x85) return false;
     if ((codeUnit == 0x85) || (codeUnit == 0xA0)) return true;
     return (codeUnit <= 0x200A)
-        ? ((codeUnit == 0x1680) || (codeUnit == 0x180E) || (0x2000 <= codeUnit))
+        ? ((codeUnit == 0x1680) || (0x2000 <= codeUnit))
         : ((codeUnit == 0x2028) ||
             (codeUnit == 0x2029) ||
             (codeUnit == 0x202F) ||
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index 1f74a04..bc194bc 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -19,6 +19,7 @@
 import("../../utils/compile_platform.gni")
 import("../../utils/generate_patch_sdk.gni")
 import("../bin/io_sources.gni")
+import("../bin/cli_sources.gni")
 import("../lib/async_sources.gni")
 import("../lib/collection_sources.gni")
 import("../lib/convert_sources.gni")
@@ -72,13 +73,14 @@
     if (is_fuchsia) {
       configs -= [ "//build/config:symbol_visibility_hidden" ]
       deps = [
+        # TODO(US-399): Remove time_service specific code when it is no longer
+        # necessary.
+        "//garnet/public/lib/app/cpp",
+        "//garnet/public/lib/time_service/fidl",
+
         # TODO(zra): When the platform-specific timeline code is moved out to
         # the embedder, this can go away.
         "//zircon/system/ulib/fbl",
-        # TODO(US-399): Remove time_service specific code when it is no longer
-        # necessary.
-        "//garnet/public/lib/time_service/fidl",
-        "//garnet/public/lib/app/cpp",
       ]
     }
     public_configs = [ ":libdart_vm_config" ]
@@ -572,6 +574,11 @@
       io_runtime_sources,
       "../bin",
     ],
+    [
+      "cli",
+      cli_runtime_sources,
+      "../bin",
+    ],
   ]
 }
 
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 778ec14..e0764a2 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -111,6 +111,7 @@
 BENCHMARK(CorelibCompileAll) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+  bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
   TransitionNativeToVM transition(thread);
   Timer timer(true, "Compile all of Core lib benchmark");
   timer.Start();
@@ -129,6 +130,7 @@
 BENCHMARK(CorelibCompilerStats) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+  bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
   TransitionNativeToVM transition(thread);
   CompilerStats* stats = thread->isolate()->aggregate_compiler_stats();
   ASSERT(stats != NULL);
@@ -148,6 +150,7 @@
 BENCHMARK(Dart2JSCompilerStats) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+  bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
   SetupDart2JSPackagePath();
   char* dart_root = ComputeDart2JSPath(Benchmark::Executable());
   char* script = NULL;
@@ -349,6 +352,7 @@
 BENCHMARK(Dart2JSCompileAll) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+  bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
   SetupDart2JSPackagePath();
   char* dart_root = ComputeDart2JSPath(Benchmark::Executable());
   char* script = NULL;
@@ -530,6 +534,7 @@
       "import 'dart:typed_data';\n"
       "import 'dart:_builtin';\n"
       "import 'dart:io';\n"
+      "import 'dart:cli';\n"
       "\n";
 
   // Start an Isolate, load a script and create a full snapshot.
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index e2b8ec5..68b4238 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -161,7 +161,7 @@
   ASSERT(!function.IsNull());
   const Function& target = Function::ZoneHandle(Z, function.raw());
   StaticCallInstr* static_call = StaticCallInstr::FromCall(Z, call, target);
-  static_call->set_result_cid(kTypeCid);
+  static_call->SetResultType(Z, CompileType::FromCid(kTypeCid));
   call->ReplaceWith(static_call, current_iterator());
   return true;
 }
@@ -208,7 +208,7 @@
         call->token_pos(), have_same_runtime_type, kTypeArgsLen,
         Object::null_array(),  // argument_names
         args, call->deopt_id(), call->CallCount(), ICData::kOptimized);
-    static_call->set_result_cid(kBoolCid);
+    static_call->SetResultType(Z, CompileType::FromCid(kBoolCid));
     ReplaceCall(call, static_call);
     return true;
   }
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index bdb87e3..89aa1a8 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -580,6 +580,7 @@
 
 static Dart_QualifiedFunctionName vm_entry_points[] = {
     // Functions
+    {"dart:async", "::", "_ensureScheduleImmediate"},
     {"dart:core", "::", "_completeDeferredLoads"},
     {"dart:core", "::", "identityHashCode"},
     {"dart:core", "AbstractClassInstantiationError",
@@ -603,6 +604,7 @@
     {"dart:core", "_TypeError", "_TypeError._create"},
     {"dart:collection", "::", "_rehashObjects"},
     {"dart:isolate", "IsolateSpawnException", "IsolateSpawnException."},
+    {"dart:isolate", "::", "_runPendingImmediateCallback"},
     {"dart:isolate", "::", "_startIsolate"},
     {"dart:isolate", "_RawReceivePortImpl", "_handleMessage"},
     {"dart:isolate", "_RawReceivePortImpl", "_lookupHandler"},
@@ -615,7 +617,6 @@
     {"dart:_vmservice", "::", "_registerIsolate"},
     {"dart:developer", "Metrics", "_printMetrics"},
     {"dart:developer", "::", "_runExtension"},
-    {"dart:isolate", "::", "_runPendingImmediateCallback"},
 #endif  // !PRODUCT
     // Fields
     {"dart:core", "Error", "_stackTrace"},
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 3f14be9..b5d4b7f 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -3102,6 +3102,7 @@
         token_kind_(token_kind),
         checked_argument_count_(checked_argument_count),
         interface_target_(interface_target),
+        result_type_(NULL),
         has_unique_selector_(false) {
     ic_data_ = GetICData(ic_data_array);
     ASSERT(function_name.IsNotTemporaryScopedHandle());
@@ -3141,6 +3142,7 @@
         token_kind_(token_kind),
         checked_argument_count_(checked_argument_count),
         interface_target_(interface_target),
+        result_type_(NULL),
         has_unique_selector_(false) {
     ASSERT(function_name.IsNotTemporaryScopedHandle());
     ASSERT(interface_target_.IsNotTemporaryScopedHandle());
@@ -3189,6 +3191,16 @@
 
   virtual bool HasUnknownSideEffects() const { return true; }
 
+  void SetResultType(Zone* zone, CompileType new_type) {
+    result_type_ = new (zone) CompileType(new_type);
+  }
+
+  CompileType* result_type() const { return result_type_; }
+
+  intptr_t result_cid() const {
+    return (result_type_ != NULL) ? result_type_->ToCid() : kDynamicCid;
+  }
+
   PRINT_OPERANDS_TO_SUPPORT
 
   bool MatchesCoreName(const String& name);
@@ -3205,6 +3217,7 @@
   const Token::Kind token_kind_;  // Binary op, unary op, kGET or kILLEGAL.
   const intptr_t checked_argument_count_;
   const Function& interface_target_;
+  CompileType* result_type_;  // Inferred result type.
   bool has_unique_selector_;
 
   DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr);
@@ -3273,6 +3286,9 @@
 
   static RawType* ComputeRuntimeType(const CallTargets& targets);
 
+  CompileType* result_type() const { return instance_call()->result_type(); }
+  intptr_t result_cid() const { return instance_call()->result_cid(); }
+
   PRINT_OPERANDS_TO_SUPPORT
 
  private:
@@ -3595,7 +3611,7 @@
         call_count_(0),
         function_(function),
         rebind_rule_(rebind_rule),
-        result_cid_(kDynamicCid),
+        result_type_(NULL),
         is_known_list_constructor_(false),
         identity_(AliasIdentity::Unknown()) {
     ic_data_ = GetICData(ic_data_array);
@@ -3622,7 +3638,7 @@
         call_count_(call_count),
         function_(function),
         rebind_rule_(rebind_rule),
-        result_cid_(kDynamicCid),
+        result_type_(NULL),
         is_known_list_constructor_(false),
         identity_(AliasIdentity::Unknown()) {
     ASSERT(function.IsZoneHandle());
@@ -3640,10 +3656,14 @@
     for (intptr_t i = 0; i < call->ArgumentCount(); i++) {
       args->Add(call->PushArgumentAt(i));
     }
-    return new (zone)
+    StaticCallInstr* new_call = new (zone)
         StaticCallInstr(call->token_pos(), target, call->type_args_len(),
                         call->argument_names(), args, call->deopt_id(),
                         call->CallCount(), ICData::kNoRebind);
+    if (call->result_type() != NULL) {
+      new_call->result_type_ = call->result_type();
+    }
+    return new_call;
   }
 
   // ICData for static calls carries call count.
@@ -3673,7 +3693,15 @@
 
   virtual bool HasUnknownSideEffects() const { return true; }
 
-  void set_result_cid(intptr_t value) { result_cid_ = value; }
+  void SetResultType(Zone* zone, CompileType new_type) {
+    result_type_ = new (zone) CompileType(new_type);
+  }
+
+  CompileType* result_type() const { return result_type_; }
+
+  intptr_t result_cid() const {
+    return (result_type_ != NULL) ? result_type_->ToCid() : kDynamicCid;
+  }
 
   bool is_known_list_constructor() const { return is_known_list_constructor_; }
   void set_is_known_list_constructor(bool value) {
@@ -3692,7 +3720,7 @@
   const intptr_t call_count_;
   const Function& function_;
   const ICData::RebindRule rebind_rule_;
-  intptr_t result_cid_;  // For some library functions we know the result.
+  CompileType* result_type_;  // Known or inferred result type.
 
   // 'True' for recognized list constructors.
   bool is_known_list_constructor_;
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index da721b8..52fbe2c 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -1819,7 +1819,8 @@
 
     if (ShouldEmitStoreBarrier()) {
       // Value input is a writable register and should be manually preserved
-      // across allocation slow-path.
+      // across allocation slow-path.  Add it to live_registers set which
+      // determines which registers to preserve.
       locs()->live_registers()->Add(locs()->in(1), kTagged);
     }
 
@@ -3448,54 +3449,70 @@
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
   const intptr_t kNumTemps = ValueFitsSmi() ? 0 : 1;
-  LocationSummary* summary = new (zone)
-      LocationSummary(zone, kNumInputs, kNumTemps,
-                      ValueFitsSmi() ? LocationSummary::kNoCall
-                                     : LocationSummary::kCallOnSlowPath);
-  const bool needs_writable_input =
-      ValueFitsSmi() || (from_representation() == kUnboxedUint32);
-  summary->set_in(0, needs_writable_input ? Location::RequiresRegister()
-                                          : Location::WritableRegister());
-  if (!ValueFitsSmi()) {
+  if (ValueFitsSmi()) {
+    LocationSummary* summary = new (zone)
+        LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+    // Same regs, can overwrite input.
+    summary->set_in(0, Location::RequiresRegister());
+    summary->set_out(0, Location::SameAsFirstInput());
+    return summary;
+  } else {
+    LocationSummary* summary = new (zone) LocationSummary(
+        zone, kNumInputs, kNumTemps, LocationSummary::kCallOnSlowPath);
+    // Guaranteed different regs.  In the signed case we are going to use the
+    // input for sign extension of any Mint.
+    const bool needs_writable_input = (from_representation() == kUnboxedInt32);
+    summary->set_in(0, needs_writable_input ? Location::WritableRegister()
+                                            : Location::RequiresRegister());
     summary->set_temp(0, Location::RequiresRegister());
+    summary->set_out(0, Location::RequiresRegister());
+    return summary;
   }
-  summary->set_out(0, ValueFitsSmi() ? Location::SameAsFirstInput()
-                                     : Location::RequiresRegister());
-  return summary;
 }
 
 void BoxInteger32Instr::EmitNativeCode(FlowGraphCompiler* compiler) {
   const Register value = locs()->in(0).reg();
   const Register out = locs()->out(0).reg();
 
-  __ MoveRegister(out, value);
-  __ shll(out, Immediate(kSmiTagSize));
-  if (!ValueFitsSmi()) {
-    Label done;
-    ASSERT(value != out);
-    if (from_representation() == kUnboxedInt32) {
-      __ j(NO_OVERFLOW, &done);
-    } else {
-      __ testl(value, Immediate(0xC0000000));
-      __ j(ZERO, &done);
-    }
-
-    // Allocate a mint.
-    // Value input is writable register and has to be manually preserved
-    // on the slow path.
-    locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32);
-    BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
-                                    locs()->temp(0).reg());
-    __ movl(FieldAddress(out, Mint::value_offset()), value);
-    if (from_representation() == kUnboxedInt32) {
-      __ sarl(value, Immediate(31));  // Sign extend.
-      __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value);
-    } else {
-      __ movl(FieldAddress(out, Mint::value_offset() + kWordSize),
-              Immediate(0));
-    }
-    __ Bind(&done);
+  if (ValueFitsSmi()) {
+    ASSERT(value == out);
+    ASSERT(kSmiTag == 0);
+    __ shll(out, Immediate(kSmiTagSize));
+    return;
   }
+
+  __ movl(out, value);
+  __ shll(out, Immediate(kSmiTagSize));
+  Label done;
+  if (from_representation() == kUnboxedInt32) {
+    __ j(NO_OVERFLOW, &done);
+  } else {
+    ASSERT(value != out);  // Value was not overwritten.
+    __ testl(value, Immediate(0xC0000000));
+    __ j(ZERO, &done);
+  }
+
+  // Allocate a Mint.
+  if (from_representation() == kUnboxedInt32) {
+    // Value input is a writable register and should be manually preserved
+    // across allocation slow-path.  Add it to live_registers set which
+    // determines which registers to preserve.
+    locs()->live_registers()->Add(locs()->in(0), kUnboxedInt32);
+  }
+  ASSERT(value != out);  // We need the value after the allocation.
+  BoxAllocationSlowPath::Allocate(compiler, this, compiler->mint_class(), out,
+                                  locs()->temp(0).reg());
+  __ movl(FieldAddress(out, Mint::value_offset()), value);
+  if (from_representation() == kUnboxedInt32) {
+    // In the signed may-overflow case we asked for the input (value) to be
+    // writable so we can use it as a temp to put the sign extension bits in.
+    __ sarl(value, Immediate(31));  // Sign extend the Mint.
+    __ movl(FieldAddress(out, Mint::value_offset() + kWordSize), value);
+  } else {
+    __ movl(FieldAddress(out, Mint::value_offset() + kWordSize),
+            Immediate(0));  // Zero extend the Mint.
+  }
+  __ Bind(&done);
 }
 
 LocationSummary* BoxInt64Instr::MakeLocationSummary(Zone* zone,
@@ -3755,6 +3772,8 @@
       Register temp = locs()->temp(0).reg();
       Register temp2 = locs()->temp(1).reg();
       // Temp register needs to be manually preserved on allocation slow-path.
+      // Add it to live_registers set which determines which registers to
+      // preserve.
       locs()->live_registers()->Add(locs()->temp(0), kUnboxedInt32);
 
       ASSERT(temp != result);
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 3aa37d8..b8042bd 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1048,6 +1048,14 @@
 }
 
 CompileType InstanceCallInstr::ComputeType() const {
+  // TODO(alexmarkov): calculate type of InstanceCallInstr eagerly
+  // (in optimized mode) and avoid keeping separate result_type.
+  CompileType* inferred_type = result_type();
+  if ((inferred_type != NULL) &&
+      (inferred_type->ToNullableCid() != kDynamicCid)) {
+    return *inferred_type;
+  }
+
   if (Isolate::Current()->strong() && FLAG_use_strong_mode_types) {
     const Function& target = interface_target();
     if (!target.IsNull()) {
@@ -1063,7 +1071,9 @@
       // TODO(dartbug.com/30480): instantiate generic result_type
       if (result_type.IsInstantiated()) {
         TraceStrongModeType(this, result_type);
-        return CompileType::FromAbstractType(result_type);
+        const bool is_nullable =
+            (inferred_type == NULL) || inferred_type->is_nullable();
+        return CompileType::FromAbstractType(result_type, is_nullable);
       }
     }
   }
@@ -1089,8 +1099,12 @@
 }
 
 CompileType StaticCallInstr::ComputeType() const {
-  if (result_cid_ != kDynamicCid) {
-    return CompileType::FromCid(result_cid_);
+  // TODO(alexmarkov): calculate type of StaticCallInstr eagerly
+  // (in optimized mode) and avoid keeping separate result_type.
+  CompileType* inferred_type = result_type();
+  if ((inferred_type != NULL) &&
+      (inferred_type->ToNullableCid() != kDynamicCid)) {
+    return *inferred_type;
   }
 
   if (function_.recognized_kind() != MethodRecognizer::kUnknown) {
@@ -1107,7 +1121,9 @@
     // non-instantiated types properly.
     if (result_type.IsInstantiated()) {
       TraceStrongModeType(this, result_type);
-      return CompileType::FromAbstractType(result_type);
+      const bool is_nullable =
+          (inferred_type == NULL) || inferred_type->is_nullable();
+      return CompileType::FromAbstractType(result_type, is_nullable);
     }
   }
 
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 1e12eda..628bd55 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -2511,7 +2511,8 @@
       node->arguments()->names(), arguments, owner()->ic_data_array(),
       owner()->GetNextDeoptId(), ConvertRebindRule(node->rebind_rule()));
   if (node->function().recognized_kind() != MethodRecognizer::kUnknown) {
-    call->set_result_cid(MethodRecognizer::ResultCid(node->function()));
+    call->SetResultType(
+        Z, CompileType::FromCid(MethodRecognizer::ResultCid(node->function())));
   }
   ReturnDefinition(call);
 }
@@ -2650,7 +2651,7 @@
         owner()->GetNextDeoptId(), ICData::kStatic);
     const intptr_t result_cid = GetResultCidOfListFactory(node);
     if (result_cid != kDynamicCid) {
-      call->set_result_cid(result_cid);
+      call->SetResultType(Z, CompileType::FromCid(result_cid));
       call->set_is_known_list_constructor(true);
       // Recognized fixed length array factory must have two arguments:
       // (0) type-arguments, (1) length.
@@ -2658,7 +2659,8 @@
              arguments->length() == 2);
     } else if (node->constructor().recognized_kind() !=
                MethodRecognizer::kUnknown) {
-      call->set_result_cid(MethodRecognizer::ResultCid(node->constructor()));
+      call->SetResultType(Z, CompileType::FromCid(MethodRecognizer::ResultCid(
+                                 node->constructor())));
     }
     ReturnDefinition(call);
     return;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 9cf6b55..52d5650 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -732,6 +732,32 @@
   return DirectCallMetadata(target, check_receiver_for_null);
 }
 
+InferredTypeMetadata InferredTypeMetadataHelper::GetInferredType(
+    intptr_t node_offset) {
+  const intptr_t md_offset = GetNextMetadataPayloadOffset(node_offset);
+  if (md_offset < 0) {
+    return InferredTypeMetadata(kDynamicCid, true);
+  }
+
+  AlternativeReadingScope alt(builder_->reader_, &H.metadata_payloads(),
+                              md_offset - MetadataPayloadOffset);
+
+  const NameIndex kernel_name = builder_->ReadCanonicalNameReference();
+  const bool nullable = builder_->ReadBool();
+
+  if (H.IsRoot(kernel_name)) {
+    return InferredTypeMetadata(kDynamicCid, nullable);
+  }
+
+  const Class& klass =
+      Class::Handle(builder_->zone_, H.LookupClassByKernelClass(kernel_name));
+  ASSERT(!klass.IsNull());
+
+  const intptr_t cid = klass.id();
+
+  return InferredTypeMetadata(cid, nullable);
+}
+
 StreamingScopeBuilder::StreamingScopeBuilder(ParsedFunction* parsed_function)
     : result_(NULL),
       parsed_function_(parsed_function),
@@ -4004,7 +4030,8 @@
   intptr_t argument_count = positional_argument_count + named_argument_count;
   if (!target.is_static()) ++argument_count;
   body += StaticCall(TokenPosition::kNoSource, target, argument_count,
-                     argument_names, ICData::kNoRebind, type_args_len);
+                     argument_names, ICData::kNoRebind,
+                     /* result_type = */ NULL, type_args_len);
 
   // Return the result.
   body += Return(function_node_helper.end_position_);
@@ -5674,12 +5701,14 @@
     intptr_t argument_count,
     const Array& argument_names,
     ICData::RebindRule rebind_rule,
+    const InferredTypeMetadata* result_type,
     intptr_t type_args_count,
     intptr_t argument_check_bits,
     intptr_t type_argument_check_bits) {
   return flow_graph_builder_->StaticCall(
       position, target, argument_count, argument_names, rebind_rule,
-      type_args_count, argument_check_bits, type_argument_check_bits);
+      result_type, type_args_count, argument_check_bits,
+      type_argument_check_bits);
 }
 
 Fragment StreamingFlowGraphBuilder::InstanceCall(
@@ -5703,12 +5732,13 @@
     const Array& argument_names,
     intptr_t checked_argument_count,
     const Function& interface_target,
+    const InferredTypeMetadata* result_type,
     intptr_t argument_check_bits,
     intptr_t type_argument_check_bits) {
   return flow_graph_builder_->InstanceCall(
       position, name, kind, type_args_len, argument_count, argument_names,
-      checked_argument_count, interface_target, argument_check_bits,
-      type_argument_check_bits);
+      checked_argument_count, interface_target, result_type,
+      argument_check_bits, type_argument_check_bits);
 }
 
 Fragment StreamingFlowGraphBuilder::ThrowException(TokenPosition position) {
@@ -6072,6 +6102,8 @@
 
   const DirectCallMetadata direct_call =
       direct_call_metadata_helper_.GetDirectTargetForPropertyGet(offset);
+  const InferredTypeMetadata result_type =
+      inferred_type_metadata_helper_.GetInferredType(offset);
 
   ReadFlags();  // read flags
 
@@ -6105,13 +6137,14 @@
   if (!direct_call.target_.IsNull()) {
     ASSERT(FLAG_precompiled_mode);
     instructions +=
-        StaticCall(position, direct_call.target_, 1, ICData::kNoRebind);
+        StaticCall(position, direct_call.target_, 1, Array::null_array(),
+                   ICData::kNoRebind, &result_type);
   } else {
     const intptr_t kTypeArgsLen = 0;
     const intptr_t kNumArgsChecked = 1;
-    instructions +=
-        InstanceCall(position, getter_name, Token::kGET, kTypeArgsLen, 1,
-                     Array::null_array(), kNumArgsChecked, *interface_target);
+    instructions += InstanceCall(
+        position, getter_name, Token::kGET, kTypeArgsLen, 1,
+        Array::null_array(), kNumArgsChecked, *interface_target, &result_type);
   }
 
   if (direct_call.check_receiver_for_null_) {
@@ -6173,16 +6206,17 @@
 
   if (!direct_call.target_.IsNull()) {
     ASSERT(FLAG_precompiled_mode);
-    instructions += StaticCall(position, direct_call.target_, 2,
-                               Array::null_array(), ICData::kNoRebind,
-                               /*type_args_len=*/0, argument_check_bits);
+    instructions +=
+        StaticCall(position, direct_call.target_, 2, Array::null_array(),
+                   ICData::kNoRebind, /* result_type = */ NULL,
+                   /*type_args_len=*/0, argument_check_bits);
   } else {
     const intptr_t kTypeArgsLen = 0;
     const intptr_t kNumArgsChecked = 1;
     instructions +=
         InstanceCall(position, setter_name, Token::kSET, kTypeArgsLen, 2,
                      Array::null_array(), kNumArgsChecked, *interface_target,
-                     argument_check_bits);
+                     /* result_type = */ NULL, argument_check_bits);
   }
 
   instructions += Drop();  // Drop result of the setter invocation.
@@ -6267,9 +6301,13 @@
 }
 
 Fragment StreamingFlowGraphBuilder::BuildSuperPropertyGet(TokenPosition* p) {
+  const intptr_t offset = ReaderOffset() - 1;     // Include the tag.
   const TokenPosition position = ReadPosition();  // read position.
   if (p != NULL) *p = position;
 
+  const InferredTypeMetadata result_type =
+      inferred_type_metadata_helper_.GetInferredType(offset);
+
   Class& klass = GetSuperOrDie();
 
   StringIndex name_index = ReadStringReference();  // read name index.
@@ -6332,7 +6370,8 @@
 
     instructions +=
         StaticCall(position, Function::ZoneHandle(Z, function.raw()),
-                   /* argument_count = */ 1, ICData::kSuper);
+                   /* argument_count = */ 1, Array::null_array(),
+                   ICData::kSuper, &result_type);
   }
 
   return instructions;
@@ -6402,9 +6441,13 @@
 }
 
 Fragment StreamingFlowGraphBuilder::BuildDirectPropertyGet(TokenPosition* p) {
+  const intptr_t offset = ReaderOffset() - 1;     // Include the tag.
   const TokenPosition position = ReadPosition();  // read position.
   if (p != NULL) *p = position;
 
+  const InferredTypeMetadata result_type =
+      inferred_type_metadata_helper_.GetInferredType(offset);
+
   ReadFlags();  // read flags.
 
   const Tag receiver_tag = PeekTag();         // peek tag for receiver.
@@ -6448,7 +6491,8 @@
   // can't change their structure during hot reload.
   // If there are other sources of DirectPropertyGet in the future, this code
   // have to be adjusted.
-  return instructions + StaticCall(position, target, 1, ICData::kNoRebind);
+  return instructions + StaticCall(position, target, 1, Array::null_array(),
+                                   ICData::kNoRebind, &result_type);
 }
 
 Fragment StreamingFlowGraphBuilder::BuildDirectPropertySet(TokenPosition* p) {
@@ -6484,6 +6528,7 @@
   // have to be adjusted.
   instructions +=
       StaticCall(position, target, 2, Array::null_array(), ICData::kNoRebind,
+                 /* result_type = */ NULL,
                  /*type_args_len=*/0, argument_check_bits,
                  /*type_argument_check_bits=*/0);
 
@@ -6492,11 +6537,14 @@
 
 Fragment StreamingFlowGraphBuilder::BuildStaticGet(TokenPosition* p) {
   ASSERT(Error::Handle(Z, H.thread()->sticky_error()).IsNull());
-  intptr_t offset = ReaderOffset() - 1;  // Include the tag.
+  const intptr_t offset = ReaderOffset() - 1;  // Include the tag.
 
   TokenPosition position = ReadPosition();  // read position.
   if (p != NULL) *p = position;
 
+  const InferredTypeMetadata result_type =
+      inferred_type_metadata_helper_.GetInferredType(offset);
+
   NameIndex target = ReadCanonicalNameReference();  // read target_reference.
 
   if (H.IsField(target)) {
@@ -6513,7 +6561,8 @@
         Fragment instructions = Constant(field);
         return instructions + LoadStaticField();
       } else {
-        return StaticCall(position, getter, 0, ICData::kStatic);
+        return StaticCall(position, getter, 0, Array::null_array(),
+                          ICData::kStatic, &result_type);
       }
     }
   } else {
@@ -6521,7 +6570,8 @@
         Function::ZoneHandle(Z, H.LookupStaticMethodByKernelProcedure(target));
 
     if (H.IsGetter(target)) {
-      return StaticCall(position, function, 0, ICData::kStatic);
+      return StaticCall(position, function, 0, Array::null_array(),
+                        ICData::kStatic, &result_type);
     } else if (H.IsMethod(target)) {
       return Constant(constant_evaluator_.EvaluateExpression(offset));
     } else {
@@ -6755,6 +6805,8 @@
 
   const DirectCallMetadata direct_call =
       direct_call_metadata_helper_.GetDirectTargetForMethodInvocation(offset);
+  const InferredTypeMetadata result_type =
+      inferred_type_metadata_helper_.GetInferredType(offset);
 
   uint8_t flags = ReadFlags();  // read flags.
 
@@ -6904,13 +6956,14 @@
   if (!direct_call.target_.IsNull()) {
     ASSERT(FLAG_precompiled_mode);
     instructions += StaticCall(position, direct_call.target_, argument_count,
-                               argument_names, ICData::kNoRebind, type_args_len,
-                               argument_check_bits, type_argument_check_bits);
+                               argument_names, ICData::kNoRebind, &result_type,
+                               type_args_len, argument_check_bits,
+                               type_argument_check_bits);
   } else {
-    instructions +=
-        InstanceCall(position, name, token_kind, type_args_len, argument_count,
-                     argument_names, checked_argument_count, *interface_target,
-                     argument_check_bits, type_argument_check_bits);
+    instructions += InstanceCall(
+        position, name, token_kind, type_args_len, argument_count,
+        argument_names, checked_argument_count, *interface_target, &result_type,
+        argument_check_bits, type_argument_check_bits);
   }
 
   // Drop temporaries preserving result on the top of the stack.
@@ -6935,9 +6988,13 @@
 
 Fragment StreamingFlowGraphBuilder::BuildDirectMethodInvocation(
     TokenPosition* p) {
+  const intptr_t offset = ReaderOffset() - 1;  // Include the tag.
   TokenPosition position = ReadPosition();  // read offset.
   if (p != NULL) *p = position;
 
+  const InferredTypeMetadata result_type =
+      inferred_type_metadata_helper_.GetInferredType(offset);
+
   uint8_t flags = ReadFlags();  // read flags.
 
   Tag receiver_tag = PeekTag();  // peek tag for receiver.
@@ -7001,17 +7058,21 @@
       target, static_cast<DispatchCategory>(flags & 3), &argument_check_bits,
       &type_argument_check_bits);
 
-  return instructions + StaticCall(position, target, argument_count,
-                                   argument_names, ICData::kNoRebind,
-                                   type_args_len, argument_check_bits,
-                                   type_argument_check_bits);
+  return instructions +
+         StaticCall(position, target, argument_count, argument_names,
+                    ICData::kNoRebind, &result_type, type_args_len,
+                    argument_check_bits, type_argument_check_bits);
 }
 
 Fragment StreamingFlowGraphBuilder::BuildSuperMethodInvocation(
     TokenPosition* p) {
+  const intptr_t offset = ReaderOffset() - 1;     // Include the tag.
   const TokenPosition position = ReadPosition();  // read position.
   if (p != NULL) *p = position;
 
+  const InferredTypeMetadata result_type =
+      inferred_type_metadata_helper_.GetInferredType(offset);
+
   intptr_t type_args_len = 0;
   if (I->reify_generic_functions()) {
     AlternativeReadingScope alt(reader_);
@@ -7140,18 +7201,22 @@
         /* positional_argument_count = */ NULL);  // read arguments.
     ++argument_count;                             // include receiver
     SkipCanonicalNameReference();                 // interfaceTargetReference
-    return instructions + StaticCall(position,
-                                     Function::ZoneHandle(Z, function.raw()),
-                                     argument_count, argument_names,
-                                     ICData::kSuper, type_args_len);
+    return instructions +
+           StaticCall(position, Function::ZoneHandle(Z, function.raw()),
+                      argument_count, argument_names, ICData::kSuper,
+                      &result_type, type_args_len);
   }
 }
 
 Fragment StreamingFlowGraphBuilder::BuildStaticInvocation(bool is_const,
                                                           TokenPosition* p) {
+  const intptr_t offset = ReaderOffset() - 1;  // Include the tag.
   TokenPosition position = ReadPosition();  // read position.
   if (p != NULL) *p = position;
 
+  const InferredTypeMetadata result_type =
+      inferred_type_metadata_helper_.GetInferredType(offset);
+
   NameIndex procedure_reference =
       ReadCanonicalNameReference();  // read procedure reference.
   intptr_t argument_count = PeekArgumentsCount();
@@ -7233,7 +7298,7 @@
     instructions += StrictCompare(Token::kEQ_STRICT, /*number_check=*/true);
   } else {
     instructions += StaticCall(position, target, argument_count, argument_names,
-                               ICData::kStatic, type_args_len);
+                               ICData::kStatic, &result_type, type_args_len);
     if (target.IsGenerativeConstructor()) {
       // Drop the result of the constructor call and leave [instance_variable]
       // on top-of-stack.
@@ -7332,7 +7397,7 @@
       Z, H.LookupConstructorByKernelConstructor(klass, kernel_name));
   ++argument_count;
   instructions += StaticCall(position, target, argument_count, argument_names,
-                             ICData::kStatic);
+                             ICData::kStatic, /* result_type = */ NULL);
   return instructions + Drop();
 }
 
@@ -9556,6 +9621,16 @@
         direct_call_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
                                                          mappings_num);
       }
+    } else if (H.StringEquals(tag, InferredTypeMetadataHelper::tag())) {
+      ASSERT(node_references_num == 0);
+
+      if (mappings_num > 0) {
+        if (!FLAG_precompiled_mode) {
+          FATAL("InferredTypeMetadata is allowed in precompiled mode only");
+        }
+        inferred_type_metadata_helper_.SetMetadataMappings(offset + kUInt32Size,
+                                                           mappings_num);
+      }
     }
   }
 }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 638f638..7a2ea01 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -329,7 +329,7 @@
   enum Flag {
     kConst = 1 << 0,
     kExternal = 1 << 1,
-    kSyntheticDefault = 1 << 2,
+    kSynthetic = 1 << 2,
   };
 
   explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
@@ -348,7 +348,7 @@
 
   bool IsExternal() { return (flags_ & kExternal) != 0; }
   bool IsConst() { return (flags_ & kConst) != 0; }
-  bool IsSyntheticDefault() { return (flags_ & kSyntheticDefault) != 0; }
+  bool IsSynthetic() { return (flags_ & kSynthetic) != 0; }
 
   NameIndex canonical_name_;
   TokenPosition position_;
@@ -571,6 +571,25 @@
                     bool* check_receiver_for_null);
 };
 
+struct InferredTypeMetadata {
+  InferredTypeMetadata(intptr_t cid_, bool nullable_)
+      : cid(cid_), nullable(nullable_) {}
+
+  const intptr_t cid;
+  const bool nullable;
+};
+
+// Helper class which provides access to inferred type metadata.
+class InferredTypeMetadataHelper : public MetadataHelper {
+ public:
+  static const char* tag() { return "vm.inferred-type.metadata"; }
+
+  explicit InferredTypeMetadataHelper(StreamingFlowGraphBuilder* builder)
+      : MetadataHelper(builder) {}
+
+  InferredTypeMetadata GetInferredType(intptr_t node_offset);
+};
+
 class StreamingDartTypeTranslator {
  public:
   StreamingDartTypeTranslator(StreamingFlowGraphBuilder* builder,
@@ -874,6 +893,7 @@
         record_token_positions_into_(NULL),
         record_yield_positions_into_(NULL),
         direct_call_metadata_helper_(this),
+        inferred_type_metadata_helper_(this),
         metadata_scanned_(false) {}
 
   StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
@@ -894,6 +914,7 @@
         record_token_positions_into_(NULL),
         record_yield_positions_into_(NULL),
         direct_call_metadata_helper_(this),
+        inferred_type_metadata_helper_(this),
         metadata_scanned_(false) {}
 
   StreamingFlowGraphBuilder(TranslationHelper* translation_helper,
@@ -914,6 +935,7 @@
         record_token_positions_into_(NULL),
         record_yield_positions_into_(NULL),
         direct_call_metadata_helper_(this),
+        inferred_type_metadata_helper_(this),
         metadata_scanned_(false) {}
 
   ~StreamingFlowGraphBuilder() { delete reader_; }
@@ -1084,6 +1106,7 @@
                       intptr_t argument_count,
                       const Array& argument_names,
                       ICData::RebindRule rebind_rule,
+                      const InferredTypeMetadata* result_type = NULL,
                       intptr_t type_args_len = 0,
                       intptr_t argument_check_bits = 0,
                       intptr_t type_argument_check_bits = 0);
@@ -1100,6 +1123,7 @@
                         const Array& argument_names,
                         intptr_t checked_argument_count,
                         const Function& interface_target,
+                        const InferredTypeMetadata* result_type = NULL,
                         intptr_t argument_check_bits = 0,
                         intptr_t type_argument_check_bits = 0);
   Fragment BuildArgumentTypeChecks();
@@ -1298,6 +1322,7 @@
   GrowableArray<intptr_t>* record_token_positions_into_;
   GrowableArray<intptr_t>* record_yield_positions_into_;
   DirectCallMetadataHelper direct_call_metadata_helper_;
+  InferredTypeMetadataHelper inferred_type_metadata_helper_;
   bool metadata_scanned_;
 
   friend class ClassHelper;
@@ -1306,6 +1331,7 @@
   friend class DirectCallMetadataHelper;
   friend class FieldHelper;
   friend class FunctionNodeHelper;
+  friend class InferredTypeMetadataHelper;
   friend class KernelLoader;
   friend class KernelReader;
   friend class LibraryDependencyHelper;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index cc5a679..f004628 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1235,6 +1235,7 @@
                                         const Array& argument_names,
                                         intptr_t checked_argument_count,
                                         const Function& interface_target,
+                                        const InferredTypeMetadata* result_type,
                                         intptr_t argument_bits,
                                         intptr_t type_argument_bits) {
   const intptr_t total_count = argument_count + (type_args_len > 0 ? 1 : 0);
@@ -1243,6 +1244,10 @@
       position, name, kind, arguments, type_args_len, argument_names,
       checked_argument_count, ic_data_array_, GetNextDeoptId(),
       interface_target, argument_bits, type_argument_bits);
+  if (result_type != NULL) {
+    call->SetResultType(Z, CompileType::CreateNullable(result_type->nullable,
+                                                       result_type->cid));
+  }
   Push(call);
   return Fragment(call);
 }
@@ -1506,6 +1511,7 @@
                                       intptr_t argument_count,
                                       const Array& argument_names,
                                       ICData::RebindRule rebind_rule,
+                                      const InferredTypeMetadata* result_type,
                                       intptr_t type_args_count,
                                       intptr_t argument_bits,
                                       intptr_t type_argument_check_bits) {
@@ -1518,10 +1524,18 @@
   const intptr_t list_cid =
       GetResultCidOfListFactory(Z, target, argument_count);
   if (list_cid != kDynamicCid) {
-    call->set_result_cid(list_cid);
+    ASSERT((result_type == NULL) || (result_type->cid == kDynamicCid) ||
+           (result_type->cid == list_cid));
+    call->SetResultType(Z, CompileType::FromCid(list_cid));
     call->set_is_known_list_constructor(true);
   } else if (target.recognized_kind() != MethodRecognizer::kUnknown) {
-    call->set_result_cid(MethodRecognizer::ResultCid(target));
+    intptr_t recognized_cid = MethodRecognizer::ResultCid(target);
+    ASSERT((result_type == NULL) || (result_type->cid == kDynamicCid) ||
+           (result_type->cid == recognized_cid));
+    call->SetResultType(Z, CompileType::FromCid(recognized_cid));
+  } else if (result_type != NULL) {
+    call->SetResultType(Z, CompileType::CreateNullable(result_type->nullable,
+                                                       result_type->cid));
   }
   Push(call);
   return Fragment(call);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 167e13b..6d9948d 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -18,6 +18,7 @@
 namespace kernel {
 
 class StreamingFlowGraphBuilder;
+struct InferredTypeMetadata;
 
 class KernelConstMapKeyEqualsTraits {
  public:
@@ -699,6 +700,7 @@
                         const Array& argument_names,
                         intptr_t checked_argument_count,
                         const Function& interface_target,
+                        const InferredTypeMetadata* result_type = NULL,
                         intptr_t argument_bits = 0,
                         intptr_t type_argument_bits = 0);
   Fragment ClosureCall(intptr_t type_args_len,
@@ -728,6 +730,7 @@
                       intptr_t argument_count,
                       const Array& argument_names,
                       ICData::RebindRule rebind_rule,
+                      const InferredTypeMetadata* result_type = NULL,
                       intptr_t type_args_len = 0,
                       intptr_t argument_bits = 0,
                       intptr_t type_argument_check_bits = 0);
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 94f0dd9..990ce17 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -147,6 +147,7 @@
   NOT_IN_PRODUCT(
       TimelineDurationScope tds(Timeline::GetVMStream(), "Dart::InitOnce"));
   Isolate::InitOnce();
+  IdleNotifier::InitOnce();
   PortMap::InitOnce();
   FreeListElement::InitOnce();
   ForwardingCorpse::InitOnce();
@@ -415,6 +416,7 @@
   }
   WaitForIsolateShutdown();
 
+  IdleNotifier::Stop();
   // Shutdown the thread pool. On return, all thread pool threads have exited.
   if (FLAG_trace_shutdown) {
     OS::PrintErr("[+%" Pd64 "ms] SHUTDOWN: Deleting thread pool\n",
@@ -446,6 +448,7 @@
   ShutdownIsolate();
   vm_isolate_ = NULL;
   ASSERT(Isolate::IsolateListLength() == 0);
+  IdleNotifier::Cleanup();
 
   TargetCPUFeatures::Cleanup();
   StoreBuffer::ShutDown();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index acc162c..6219611 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1444,7 +1444,7 @@
   CHECK_ISOLATE(T->isolate());
   API_TIMELINE_BEGIN_END;
   TransitionNativeToVM transition(T);
-  T->isolate()->heap()->NotifyIdle(deadline);
+  T->isolate()->NotifyIdle(deadline);
 }
 
 DART_EXPORT void Dart_NotifyLowMemory() {
@@ -1672,6 +1672,57 @@
   return Api::Success();
 }
 
+DART_EXPORT Dart_Handle Dart_WaitForEvent(int64_t timeout_millis) {
+  Thread* T = Thread::Current();
+  Isolate* I = T->isolate();
+  CHECK_API_SCOPE(T);
+  CHECK_CALLBACK_STATE(T);
+  API_TIMELINE_BEGIN_END_BASIC;
+  TransitionNativeToVM transition(T);
+  if (I->message_notify_callback() != NULL) {
+    return Api::NewError("waitForEventSync is not supported by this embedder");
+  }
+  Object& result =
+      Object::Handle(Z, DartLibraryCalls::EnsureScheduleImmediate());
+  if (result.IsError()) {
+    return Api::NewHandle(T, result.raw());
+  }
+
+  // Drain the microtask queue. Propagate any errors to the entry frame.
+  result = DartLibraryCalls::DrainMicrotaskQueue();
+  if (result.IsError()) {
+    // Persist the error across unwiding scopes before propagating.
+    const Error* error;
+    {
+      NoSafepointScope no_safepoint;
+      RawError* raw_error = Error::Cast(result).raw();
+      T->UnwindScopes(T->top_exit_frame_info());
+      error = &Error::Handle(T->zone(), raw_error);
+    }
+    Exceptions::PropagateToEntry(*error);
+    UNREACHABLE();
+    return Api::NewError("Unreachable");
+  }
+
+  // Block to wait for messages and then handle them. Propagate any errors to
+  // the entry frame.
+  if (I->message_handler()->PauseAndHandleAllMessages(timeout_millis) !=
+      MessageHandler::kOK) {
+    // Persist the error across unwiding scopes before propagating.
+    const Error* error;
+    {
+      NoSafepointScope no_safepoint;
+      RawError* raw_error = T->get_and_clear_sticky_error();
+      T->UnwindScopes(T->top_exit_frame_info());
+      error = &Error::Handle(T->zone(), raw_error);
+    }
+    Exceptions::PropagateToEntry(*error);
+    UNREACHABLE();
+    return Api::NewError("Unreachable");
+  }
+  return Api::Success();
+}
+
 DART_EXPORT bool Dart_HandleServiceMessages() {
 #if defined(PRODUCT)
   return true;
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 2fde805..7f22976 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -6528,6 +6528,7 @@
 
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+  bin::Builtin::SetNativeResolver(bin::Builtin::kCLILibrary);
 
   Dart_Handle result = Dart_SetLibraryTagHandler(library_handler);
   EXPECT_VALID(result);
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 6129213..47c52c0 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -660,6 +660,20 @@
   return result.raw();
 }
 
+RawObject* DartLibraryCalls::EnsureScheduleImmediate() {
+  Zone* zone = Thread::Current()->zone();
+  const Library& async_lib = Library::Handle(zone, Library::AsyncLibrary());
+  ASSERT(!async_lib.IsNull());
+  const Function& function =
+      Function::Handle(zone, async_lib.LookupFunctionAllowPrivate(
+                                 Symbols::_ensureScheduleImmediate()));
+  ASSERT(!function.IsNull());
+  const Object& result = Object::Handle(
+      zone, DartEntry::InvokeFunction(function, Object::empty_array()));
+  ASSERT(result.IsNull() || result.IsError());
+  return result.raw();
+}
+
 RawObject* DartLibraryCalls::MapSetAt(const Instance& map,
                                       const Instance& key,
                                       const Instance& value) {
diff --git a/runtime/vm/dart_entry.h b/runtime/vm/dart_entry.h
index 79ba34b..d28a5cd 100644
--- a/runtime/vm/dart_entry.h
+++ b/runtime/vm/dart_entry.h
@@ -282,6 +282,11 @@
   // Returns null on success, a RawError on failure.
   static RawObject* DrainMicrotaskQueue();
 
+  // Ensures that the isolate's _pendingImmediateCallback is set to
+  // _startMicrotaskLoop from dart:async.
+  // Returns null on success, a RawError on failure.
+  static RawObject* EnsureScheduleImmediate();
+
   // map[key] = value;
   //
   // Returns null on success, a RawError on failure.
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 01ff1c8..667e819 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -815,6 +815,26 @@
   UNREACHABLE();
 }
 
+void Exceptions::PropagateToEntry(const Error& error) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  ASSERT(thread->top_exit_frame_info() != 0);
+  Instance& stacktrace = Instance::Handle(zone);
+  if (error.IsUnhandledException()) {
+    const UnhandledException& uhe = UnhandledException::Cast(error);
+    stacktrace = uhe.stacktrace();
+  } else {
+    stacktrace = Exceptions::CurrentStackTrace();
+  }
+  uword handler_pc = 0;
+  uword handler_sp = 0;
+  uword handler_fp = 0;
+  FindErrorHandler(&handler_pc, &handler_sp, &handler_fp);
+  JumpToExceptionHandler(thread, handler_pc, handler_sp, handler_fp, error,
+                         stacktrace);
+  UNREACHABLE();
+}
+
 void Exceptions::ThrowByType(ExceptionType type, const Array& arguments) {
   Thread* thread = Thread::Current();
   const Object& result =
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 114e085..fe58b37 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -33,6 +33,9 @@
                       const Instance& stacktrace);
   static void PropagateError(const Error& error);
 
+  // Propagate an error to the entry frame, skipping over Dart frames.
+  static void PropagateToEntry(const Error& error);
+
   // Helpers to create and throw errors.
   static RawStackTrace* CurrentStackTrace();
   static RawScript* GetCallerScript(DartFrameIterator* iterator);
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 4e0189c..67d23d6 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -97,6 +97,10 @@
     "Artificially create type feedback for arithmetic etc. operations")        \
   P(huge_method_cutoff_in_tokens, int, 20000,                                  \
     "Huge method cutoff in tokens: Disables optimizations for huge methods.")  \
+  P(idle_timeout_micros, int, 1000 * kMicrosecondsPerMillisecond,              \
+    "Consider thread pool isolates for idle tasks after this long.")           \
+  P(idle_duration_micros, int, 500 * kMicrosecondsPerMillisecond,              \
+    "Allow idle tasks to run for this long.")                                  \
   P(interpret_irregexp, bool, USING_DBC, "Use irregexp bytecode interpreter")  \
   P(lazy_dispatchers, bool, true, "Generate dispatchers lazily")               \
   P(link_natives_lazily, bool, false, "Link native calls lazily")              \
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 7299746..da02f72 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -783,7 +783,7 @@
   // clang-format off
   const char* space_str = stats_.space_ == kNew ? "Scavenge" : "Mark-Sweep";
   OS::PrintErr(
-    "[ GC %9" Pd64 " : %10s(%9s), "  // GC(isolate), space(reason)
+    "[ %-13.13s, %10s(%9s), "  // GC(isolate), space(reason)
     "%4" Pd ", "  // count
     "%6.2f, "  // start time
     "%5.1f, "  // total time
@@ -796,7 +796,7 @@
     "%6.2f, %6.2f, %6.2f, %6.2f, %6.2f, %6.2f, "  // times
     "%" Pd ", %" Pd ", %" Pd ", %" Pd ", "  // data
     "]\n",  // End with a comma to make it easier to import in spreadsheets.
-    isolate()->main_port(), space_str, GCReasonToString(stats_.reason_),
+    isolate()->name(), space_str, GCReasonToString(stats_.reason_),
     stats_.num_,
     MicrosecondsToSeconds(isolate()->UptimeMicros()),
     MicrosecondsToMilliseconds(stats_.after_.micros_ -
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index b755770..17bbc19 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1638,6 +1638,10 @@
                          reinterpret_cast<uword>(this));
 }
 
+void Isolate::NotifyIdle(int64_t deadline) {
+  heap()->NotifyIdle(deadline);
+}
+
 void Isolate::AddClosureFunction(const Function& function) const {
   ASSERT(!Compiler::IsBackgroundCompilation());
   GrowableObjectArray& closures =
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 6a569bc..85e8c46 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -317,6 +317,8 @@
 #endif
   }
 
+  void NotifyIdle(int64_t deadline);
+
   bool compaction_in_progress() const {
     return CompactionInProgressBit::decode(isolate_flags_);
   }
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 10c8a24..f2e7227 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -985,7 +985,7 @@
                                      true,   // is_method
                                      false,  // is_closure
                                      &function_node_helper);
-    if (constructor_helper.IsSyntheticDefault()) {
+    if (constructor_helper.IsSynthetic()) {
       function.set_is_debuggable(false);
     }
 
diff --git a/runtime/vm/message_handler.cc b/runtime/vm/message_handler.cc
index e35d72a..f7f94ef 100644
--- a/runtime/vm/message_handler.cc
+++ b/runtime/vm/message_handler.cc
@@ -54,6 +54,7 @@
     : queue_(new MessageQueue()),
       oob_queue_(new MessageQueue()),
       oob_message_handling_allowed_(true),
+      paused_for_messages_(false),
       live_ports_(0),
       paused_(0),
 #if !defined(PRODUCT)
@@ -66,6 +67,7 @@
       delete_me_(false),
       pool_(NULL),
       task_(NULL),
+      idle_start_time_(0),
       start_callback_(NULL),
       end_callback_(NULL),
       callback_data_(0) {
@@ -74,6 +76,7 @@
 }
 
 MessageHandler::~MessageHandler() {
+  IdleNotifier::Remove(this);
   delete queue_;
   delete oob_queue_;
   queue_ = NULL;
@@ -151,6 +154,9 @@
     } else {
       queue_->Enqueue(message, before_events);
     }
+    if (paused_for_messages_) {
+      ml.Notify();
+    }
     message = NULL;  // Do not access message.  May have been deleted.
 
     if ((pool_ != NULL) && (task_ == NULL)) {
@@ -165,6 +171,19 @@
   MessageNotify(saved_priority);
 }
 
+void MessageHandler::EnsureTaskForIdleCheck() {
+  MonitorLocker ml(&monitor_);
+  if ((pool_ != NULL) && (task_ == NULL)) {
+    task_ = new MessageHandlerTask(this);
+    bool task_running = pool_->Run(task_);
+    if (!task_running) {
+      OS::PrintErr("Failed to start idle wakeup\n");
+      delete task_;
+      task_ = NULL;
+    }
+  }
+}
+
 Message* MessageHandler::DequeueMessage(Message::Priority min_priority) {
   // TODO(turnidge): Add assert that monitor_ is held here.
   Message* message = oob_queue_->Dequeue();
@@ -230,6 +249,13 @@
       break;
     }
 
+    // Remember time since the last message. Don't consider OOB messages so
+    // using Observatory doesn't trigger additional idle tasks.
+    if ((FLAG_idle_timeout_micros != 0) &&
+        (saved_priority == Message::kNormalPriority)) {
+      idle_start_time_ = OS::GetCurrentMonotonicMicros();
+    }
+
     // Some callers want to process only one normal message and then quit. At
     // the same time it is OK to process multiple OOB messages.
     if ((saved_priority == Message::kNormalPriority) &&
@@ -276,6 +302,36 @@
   return HandleMessages(&ml, true, true);
 }
 
+MessageHandler::MessageStatus MessageHandler::PauseAndHandleAllMessages(
+    int64_t timeout_millis) {
+  MonitorLocker ml(&monitor_);
+  ASSERT(task_ != NULL);
+  ASSERT(!delete_me_);
+#if defined(DEBUG)
+  CheckAccess();
+#endif
+  paused_for_messages_ = true;
+  while (queue_->IsEmpty() && oob_queue_->IsEmpty()) {
+    Monitor::WaitResult wr = ml.Wait(timeout_millis);
+    ASSERT(task_ != NULL);
+    ASSERT(!delete_me_);
+    if (wr == Monitor::kTimedOut) {
+      break;
+    }
+    if (queue_->IsEmpty()) {
+      // There are only OOB messages. Handle them and then continue waiting for
+      // normal messages unless there is an error.
+      MessageStatus status = HandleMessages(&ml, false, false);
+      if (status != kOK) {
+        paused_for_messages_ = false;
+        return status;
+      }
+    }
+  }
+  paused_for_messages_ = false;
+  return HandleMessages(&ml, true, true);
+}
+
 MessageHandler::MessageStatus MessageHandler::HandleOOBMessages() {
   if (!oob_message_handling_allowed_) {
     return kOK;
@@ -373,9 +429,18 @@
         ml.Enter();
       }
 
-      // Handle any pending messages for this message handler.
-      if (status != kShutdown) {
-        status = HandleMessages(&ml, (status == kOK), true);
+      bool handle_messages = true;
+      while (handle_messages) {
+        handle_messages = false;
+
+        // Handle any pending messages for this message handler.
+        if (status != kShutdown) {
+          status = HandleMessages(&ml, (status == kOK), true);
+        }
+
+        if (status == kOK) {
+          handle_messages = CheckAndRunIdleLocked(&ml);
+        }
       }
     }
 
@@ -448,6 +513,36 @@
   }
 }
 
+bool MessageHandler::CheckAndRunIdleLocked(MonitorLocker* ml) {
+  if ((isolate() == NULL) || (idle_start_time_ == 0) ||
+      (FLAG_idle_timeout_micros == 0)) {
+    return false;
+  }
+
+  const int64_t now = OS::GetCurrentMonotonicMicros();
+  const int64_t idle_expirary = idle_start_time_ + FLAG_idle_timeout_micros;
+  if (idle_expirary > now) {
+    IdleNotifier::Update(this, idle_expirary);
+    // No new messages.
+    return false;
+  }
+
+  // We've been without a message long enough to hope we can do some
+  // cleanup before the next message arrives.
+  const int64_t deadline = now + FLAG_idle_duration_micros;
+  // Idle tasks may take a while: don't block other isolates sending
+  // us messages.
+  ml->Exit();
+  {
+    StartIsolateScope start_isolate(isolate());
+    isolate()->NotifyIdle(deadline);
+    idle_start_time_ = 0;
+  }
+  ml->Enter();
+  // We may have received new messages while the monitor was released.
+  return true;
+}
+
 void MessageHandler::ClosePort(Dart_Port port) {
   MonitorLocker ml(&monitor_);
   if (FLAG_trace_isolates) {
@@ -583,4 +678,122 @@
   handler_->oob_message_handling_allowed_ = true;
 }
 
+Monitor* IdleNotifier::monitor_ = NULL;
+bool IdleNotifier::task_running_ = false;
+IdleNotifier::Timer* IdleNotifier::queue_ = NULL;
+
+void IdleNotifier::InitOnce() {
+  monitor_ = new Monitor();
+}
+
+void IdleNotifier::Stop() {
+  Timer* timer;
+
+  {
+    MonitorLocker ml(monitor_);
+    timer = queue_;
+    queue_ = NULL;
+    ml.Notify();
+    while (task_running_) {
+      ml.Wait();
+    }
+  }
+
+  while (timer != NULL) {
+    Timer* next = timer->next;
+    delete timer;
+    timer = next;
+  }
+}
+
+void IdleNotifier::Cleanup() {
+  ASSERT(queue_ == NULL);
+  ASSERT(!task_running_);
+  delete monitor_;
+  monitor_ = NULL;
+}
+
+class IdleNotifier::Task : public ThreadPool::Task {
+ private:
+  void Run() {
+    MonitorLocker ml(monitor_);
+    while (queue_ != NULL) {
+      Timer* timer = queue_;
+      const int64_t now = OS::GetCurrentMonotonicMicros();
+      if (now >= timer->expirary) {
+        MessageHandler* handler = timer->handler;
+        queue_ = timer->next;
+        delete timer;
+        // A handler may try to update its expirary while we try to start its
+        // task for idle notification.
+        ml.Exit();
+        handler->EnsureTaskForIdleCheck();
+        ml.Enter();
+      } else {
+        ml.WaitMicros(timer->expirary - now);
+      }
+    }
+    task_running_ = false;
+    ml.Notify();
+  }
+};
+
+void IdleNotifier::Update(MessageHandler* handler, int64_t expirary) {
+  MonitorLocker ml(monitor_);
+
+  Timer* prev = NULL;
+  Timer* timer = queue_;
+  while (timer != NULL) {
+    if (timer->handler == handler) {
+      if (prev == NULL) {
+        queue_ = timer->next;
+      } else {
+        prev->next = timer->next;
+      }
+      if (expirary == 0) {
+        delete timer;
+      } else {
+        timer->expirary = expirary;
+      }
+      break;
+    } else {
+      prev = timer;
+      timer = timer->next;
+    }
+  }
+
+  if (expirary != 0) {
+    Timer* insert_timer = timer;
+    if (insert_timer == NULL) {
+      insert_timer = new Timer;
+      insert_timer->handler = handler;
+      insert_timer->expirary = expirary;
+    }
+
+    prev = NULL;
+    timer = queue_;
+    while ((timer != NULL) && (timer->expirary < insert_timer->expirary)) {
+      prev = timer;
+      timer = timer->next;
+    }
+    if (prev == NULL) {
+      queue_ = insert_timer;
+    } else {
+      prev->next = insert_timer;
+    }
+    insert_timer->next = timer;
+  }
+
+  if (task_running_) {
+    ml.Notify();
+  } else if (queue_ != NULL) {
+    Task* task = new Task();
+    task_running_ = Dart::thread_pool()->Run(task);
+    if (!task_running_) {
+      OS::PrintErr("Failed to start idle ticker\n");
+      delete task;
+    }
+  }
+}
+
 }  // namespace dart
diff --git a/runtime/vm/message_handler.h b/runtime/vm/message_handler.h
index d34b05b..a7d9f96 100644
--- a/runtime/vm/message_handler.h
+++ b/runtime/vm/message_handler.h
@@ -50,6 +50,10 @@
            EndCallback end_callback,
            CallbackData data);
 
+  // Starts a task for the message handler if it runs on the thread pool and a
+  // task is not already running.
+  void EnsureTaskForIdleCheck();
+
   // Handles the next message for this message handler.  Should only
   // be used when not running the handler on the thread pool (via Run
   // or RunBlocking).
@@ -70,6 +74,10 @@
   // Returns true on success.
   MessageStatus HandleOOBMessages();
 
+  // Blocks the thread on a condition variable until a message arrives, and then
+  // handles all messages.
+  MessageStatus PauseAndHandleAllMessages(int64_t timeout_millis);
+
   // Returns true if there are pending OOB messages for this message
   // handler.
   bool HasOOBMessages();
@@ -210,6 +218,10 @@
   // Called by MessageHandlerTask to process our task queue.
   void TaskCallback();
 
+  // Returns true if the monitor was exited and there may be new OOB messages
+  // to process.
+  bool CheckAndRunIdleLocked(MonitorLocker* ml);
+
   // NOTE: These two functions release and reacquire the monitor, you may
   // need to call HandleMessages to ensure all pending messages are handled.
   void PausedOnStartLocked(MonitorLocker* ml, bool paused);
@@ -232,6 +244,7 @@
   // This flag is not thread safe and can only reliably be accessed on a single
   // thread.
   bool oob_message_handling_allowed_;
+  bool paused_for_messages_;
   intptr_t live_ports_;  // The number of open ports, including control ports.
   intptr_t paused_;      // The number of pause messages received.
 #if !defined(PRODUCT)
@@ -244,6 +257,7 @@
   bool delete_me_;
   ThreadPool* pool_;
   ThreadPool::Task* task_;
+  int64_t idle_start_time_;
   StartCallback start_callback_;
   EndCallback end_callback_;
   CallbackData callback_data_;
@@ -251,6 +265,28 @@
   DISALLOW_COPY_AND_ASSIGN(MessageHandler);
 };
 
+class IdleNotifier : public AllStatic {
+ public:
+  static void InitOnce();
+  static void Stop();
+  static void Cleanup();
+  static void Update(MessageHandler* handler, int64_t expirary);
+  static void Remove(MessageHandler* handler) { Update(handler, 0); }
+
+ private:
+  class Task;
+
+  struct Timer {
+    MessageHandler* handler;
+    int64_t expirary;
+    Timer* next;
+  };
+
+  static Monitor* monitor_;
+  static bool task_running_;
+  static Timer* queue_;
+};
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_MESSAGE_HANDLER_H_
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 62e072a..ff43451 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -1247,7 +1247,7 @@
       heap_growth_max_(heap_growth_max),
       garbage_collection_time_ratio_(garbage_collection_time_ratio),
       last_code_collection_in_us_(OS::GetCurrentMonotonicMicros()),
-      idle_gc_threshold_in_words_(grow_heap_ / 2 * kPageSizeInWords) {}
+      idle_gc_threshold_in_words_(0) {}
 
 PageSpaceController::~PageSpaceController() {}
 
@@ -1267,22 +1267,11 @@
       Utils::RoundUp(capacity_increase_in_words, kPageSizeInWords);
   intptr_t capacity_increase_in_pages =
       capacity_increase_in_words / kPageSizeInWords;
-  double multiplier = 1.0;
-  // To avoid waste, the first GC should be triggered before too long. After
-  // kInitialTimeoutSeconds, gradually lower the capacity limit.
-  static const double kInitialTimeoutSeconds = 1.00;
-  if (history_.IsEmpty()) {
-    double seconds_since_init =
-        MicrosecondsToSeconds(heap_->isolate()->UptimeMicros());
-    if (seconds_since_init > kInitialTimeoutSeconds) {
-      multiplier *= (seconds_since_init / kInitialTimeoutSeconds);
-    }
-  }
-  bool needs_gc = capacity_increase_in_pages * multiplier > grow_heap_;
+  bool needs_gc = capacity_increase_in_pages > grow_heap_;
   if (FLAG_log_growth) {
-    OS::PrintErr("%s: %" Pd " * %f %s %" Pd "\n",
-                 needs_gc ? "NEEDS GC" : "grow", capacity_increase_in_pages,
-                 multiplier, needs_gc ? ">" : "<=", grow_heap_);
+    OS::PrintErr("%s: allocate %s %" Pd " %s %" Pd "\n",
+                 heap_->isolate()->name(), needs_gc ? "collect" : "grow",
+                 capacity_increase_in_pages, needs_gc ? ">" : "<=", grow_heap_);
   }
   return needs_gc;
 }
@@ -1294,19 +1283,12 @@
   if (heap_growth_ratio_ == 100) {
     return false;
   }
-  double multiplier = 1.0;
-  // To avoid waste, the first GC should be triggered before too long. After
-  // kInitialTimeoutSeconds, gradually lower the capacity limit.
-  static const double kInitialTimeoutSeconds = 1.00;
-  if (history_.IsEmpty()) {
-    double seconds_since_init =
-        MicrosecondsToSeconds(heap_->isolate()->UptimeMicros());
-    if (seconds_since_init > kInitialTimeoutSeconds) {
-      multiplier *= (seconds_since_init / kInitialTimeoutSeconds);
-    }
+  bool needs_gc = current.used_in_words > idle_gc_threshold_in_words_;
+  if (FLAG_log_growth) {
+    OS::PrintErr("%s: idle %s %" Pd " %s %" Pd "\n", heap_->isolate()->name(),
+                 needs_gc ? "collect" : "grow", current.used_in_words,
+                 needs_gc ? ">" : "<=", idle_gc_threshold_in_words_);
   }
-  bool needs_gc =
-      current.used_in_words * multiplier > idle_gc_threshold_in_words_;
   return needs_gc;
 }
 
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index fbbc1b7..4d99e0f 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -2678,9 +2678,11 @@
 // The '2' variant is inclusive from and exclusive to.
 // This covers \s as defined in ECMA-262 5.1, 15.10.2.12,
 // which include WhiteSpace (7.2) or LineTerminator (7.3) values.
+// 0x180E has been removed from Unicode's Zs category and thus
+// from ECMAScript's WhiteSpace category as of Unicode 6.3.
 static const intptr_t kSpaceRanges[] = {
-    '\t',   '\r' + 1, ' ',    ' ' + 1, 0x00A0, 0x00A1, 0x1680, 0x1681,
-    0x180E, 0x180F,   0x2000, 0x200B,  0x2028, 0x202A, 0x202F, 0x2030,
+    '\t',   '\r' + 1, ' ',    ' ' + 1, 0x00A0, 0x00A1, 0x1680,
+    0x1681, 0x2000,   0x200B, 0x2028,  0x202A, 0x202F, 0x2030,
     0x205F, 0x2060,   0x3000, 0x3001,  0xFEFF, 0xFF00, 0x10000};
 static const intptr_t kSpaceRangeCount = ARRAY_SIZE(kSpaceRanges);
 static const intptr_t kWordRanges[] = {'0',     '9' + 1, 'A',     'Z' + 1, '_',
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 5c7f208..0d2dfcd 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -430,6 +430,7 @@
   V(ConstructorStacktracePrefix, "new ")                                       \
   V(_runExtension, "_runExtension")                                            \
   V(_runPendingImmediateCallback, "_runPendingImmediateCallback")              \
+  V(_ensureScheduleImmediate, "_ensureScheduleImmediate")                      \
   V(DartLibrary, "dart.library.")                                              \
   V(DartLibraryMirrors, "dart.library.mirrors")                                \
   V(_name, "_name")                                                            \
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 74f34c4..caba5b0 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -285,6 +285,7 @@
 
   bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_chars);
   bool is_io_library = DartUtils::IsDartIOLibURL(library_url_string);
+  bool is_standalone_library = DartUtils::IsDartCLILibURL(library_url_string);
   if (is_dart_scheme_url) {
     ASSERT(tag == Dart_kImportTag);
     // Handle imports of other built-in libraries present in the SDK.
@@ -292,6 +293,8 @@
       return Builtin::LoadAndCheckLibrary(Builtin::kIOLibrary);
     } else if (DartUtils::IsDartBuiltinLibURL(url_chars)) {
       return Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary);
+    } else if (DartUtils::IsDartCLILibURL(url_chars)) {
+      return Builtin::LoadAndCheckLibrary(Builtin::kCLILibrary);
     } else {
       return DartUtils::NewError("Do not know how to load '%s'", url_chars);
     }
@@ -316,6 +319,12 @@
                            Builtin::PartSource(Builtin::kIOLibrary, url_chars),
                            0, 0);
   }
+  if (is_standalone_library) {
+    ASSERT(tag == Dart_kSourceTag);
+    return Dart_LoadSource(library, url, Dart_Null(),
+                           Builtin::PartSource(Builtin::kCLILibrary, url_chars),
+                           0, 0);
+  }
   Dart_Handle resolved_url = url;
   const char* resolved_url_chars = url_chars;
   if (IsPackageSchemeURL(url_chars)) {
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 41adf01..1bff383 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -179,6 +179,7 @@
 _platform_sdk_libraries = [
   "_internal",
   "async",
+  "cli",
   "collection",
   "convert",
   "core",
@@ -198,6 +199,7 @@
   "_chrome",
   "_internal",
   "async",
+  "cli",
   "collection",
   "convert",
   "core",
@@ -314,7 +316,7 @@
 }
 
 # Copies the Dart VM binary into bin/
-if (is_fuchsia_host) {
+if (target_os != current_os && target_os == "fuchsia") {
   # In the Fuchsia build, this has to use a symlink for two reasons.
   # First, it makes the lookup of shared libraries relative to $ORIGIN
   # (Linux) or @loader_path (macOS) find the libraries where they are,
diff --git a/sdk/lib/_internal/js_runtime/lib/cli_patch.dart b/sdk/lib/_internal/js_runtime/lib/cli_patch.dart
new file mode 100644
index 0000000..6921e60
--- /dev/null
+++ b/sdk/lib/_internal/js_runtime/lib/cli_patch.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:_js_helper' show patch;
+
+@patch
+void _waitForEvent(int timeoutMillis) {
+  throw new UnsupportedError("waitForEvent");
+}
diff --git a/sdk/lib/_internal/js_runtime/lib/interceptors.dart b/sdk/lib/_internal/js_runtime/lib/interceptors.dart
index 9bc4bf1..7221968 100644
--- a/sdk/lib/_internal/js_runtime/lib/interceptors.dart
+++ b/sdk/lib/_internal/js_runtime/lib/interceptors.dart
@@ -36,6 +36,7 @@
         stringReplaceFirstUnchecked,
         stringReplaceFirstMappedUnchecked,
         stringReplaceRangeUnchecked,
+        stringSplitUnchecked,
         throwConcurrentModificationError,
         lookupAndCacheInterceptor,
         StringMatch,
diff --git a/sdk/lib/_internal/js_runtime/lib/js_string.dart b/sdk/lib/_internal/js_runtime/lib/js_string.dart
index b149c23..91e9734 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_string.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_string.dart
@@ -92,10 +92,10 @@
   List<String> split(Pattern pattern) {
     checkNull(pattern);
     if (pattern is String) {
-      return JS('JSExtendableArray', r'#.split(#)', this, pattern);
+      return stringSplitUnchecked(this, pattern);
     } else if (pattern is JSSyntaxRegExp && regExpCaptureCount(pattern) == 0) {
       var re = regExpGetNative(pattern);
-      return JS('JSExtendableArray', r'#.split(#)', this, re);
+      return stringSplitUnchecked(this, re);
     } else {
       return _defaultSplit(pattern);
     }
diff --git a/sdk/lib/_internal/js_runtime/lib/string_helper.dart b/sdk/lib/_internal/js_runtime/lib/string_helper.dart
index cf8b17a..0180369 100644
--- a/sdk/lib/_internal/js_runtime/lib/string_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/string_helper.dart
@@ -20,6 +20,11 @@
   return stringIndexOfStringUnchecked(receiver, other, startIndex) >= 0;
 }
 
+List<String> stringSplitUnchecked(String receiver, pattern) {
+  return new JSArray<String>.markGrowable(JS(
+      'returns:JSExtendableArray;new:true', '#.split(#)', receiver, pattern));
+}
+
 class StringMatch implements Match {
   const StringMatch(int this.start, String this.input, String this.pattern);
 
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index 6b016f4..5f3a40c 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -117,6 +117,9 @@
       implementation: true,
       documented: false,
       platforms: DART2JS_PLATFORM),
+  "cli": const LibraryInfo("cli/cli.dart",
+      categories: "Server",
+      dart2jsPatchPath: "_internal/js_runtime/lib/cli_patch.dart"),
   "svg": const LibraryInfo("svg/dart2js/svg_dart2js.dart",
       categories: "Client",
       maturity: Maturity.WEB_STABLE,
diff --git a/sdk/lib/cli/cli.dart b/sdk/lib/cli/cli.dart
new file mode 100644
index 0000000..1dc4ca7
--- /dev/null
+++ b/sdk/lib/cli/cli.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart.cli;
+
+import 'dart:async';
+import 'dart:math';
+
+part 'wait_for.dart';
diff --git a/sdk/lib/cli/cli_sources.gni b/sdk/lib/cli/cli_sources.gni
new file mode 100644
index 0000000..e90e1de
--- /dev/null
+++ b/sdk/lib/cli/cli_sources.gni
@@ -0,0 +1,10 @@
+# Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+cli_sdk_sources = [
+  "cli.dart",
+
+  # The above file needs to be first if additional parts are added to the lib.
+  "wait_for.dart",
+]
diff --git a/sdk/lib/cli/wait_for.dart b/sdk/lib/cli/wait_for.dart
new file mode 100644
index 0000000..03089bd
--- /dev/null
+++ b/sdk/lib/cli/wait_for.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of dart.cli;
+
+/**
+ * Synchronously blocks the calling isolate to wait for asynchronous events to
+ * complete.
+ *
+ * If the [timeout] parameter is supplied, [waitForEvent] will return after
+ * the specified timeout even if no events have occurred.
+ *
+ * This call does the following:
+ * - suspends the current execution stack,
+ * - runs the microtask queue until it is empty,
+ * - waits until the message queue is not empty,
+ * - handles messages on the message queue, plus their associated microtasks,
+ *   until the message queue is empty,
+ * - resumes the original stack.
+ *
+ * This function breaks the usual promise offered by Dart semantics that
+ * message handlers and microtasks run to completion before the next message
+ * handler or microtask begins to run. Of particular note is that use of this
+ * function in a finally block will allow microtasks and message handlers to
+ * run before all finally blocks for an exception have completed, possibly
+ * breaking invariants in your program.
+ *
+ * This function will synchronously throw the first unhandled exception it
+ * encounters in running the microtasks and message handlers as though the
+ * throwing microtask or message handler was the only Dart invocation on the
+ * stack. That is, unhandled exceptions in a microtask or message handler will
+ * skip over stacks suspended in a call to [waitForEvent].
+ *
+ * Calls to this function may be nested. Earlier invocations will not
+ * be able to complete until subsequent ones do. Messages that arrive after
+ * a subsequent invocation are "consumed" by that invocation, and do not
+ * unblock an earlier invocation. Please be aware that nesting calls to
+ * [waitForEvent] can lead to deadlock when subsequent calls block to wait for
+ * a condition that is only satisfied after an earlier call returns.
+ *
+ * Please note that this call is only available in the standalone command-line
+ * Dart VM. Further, because it suspends the current execution stack until the
+ * message queue is empty, even when running in the standalone command-line VM
+ * there exists a risk that the current execution stack will be starved.
+ */
+external void _waitForEvent(int timeoutMillis);
+
+void Function(int) _getWaitForEvent() => _waitForEvent;
+
+// This should be set from C++ code by the embedder to wire up waitFor() to the
+// native implementation. In the standalone VM this is set to _waitForEvent()
+// above. If it is null, calling waitFor() will throw an UnsupportedError.
+void Function(int) _waitForEventClosure;
+
+class _WaitForUtils {
+  static void waitForEvent({Duration timeout}) {
+    if (_waitForEventClosure == null) {
+      throw new UnsupportedError("waitFor is not supported by this embedder");
+    }
+    _waitForEventClosure(timeout == null ? 0 : max(1, timeout.inMilliseconds));
+  }
+}
+
+/**
+ * Suspends the stack, runs microtasks, and handles incoming events until
+ * [future] completes.
+ *
+ * WARNING: EXPERIMENTAL. USE AT YOUR OWN RISK.
+ *
+ * This call does the following:
+ * - While [future] is not completed:
+ *   - suspends the current execution stack,
+ *   - runs the microtask queue until it is empty,
+ *   - waits until the message queue is not empty,
+ *   - handles messages on the message queue, plus their associated microtasks,
+ *     until the message queue is empty,
+ *   - resumes the original stack.
+ *
+ * This function breaks the usual promise offered by Dart semantics that
+ * message handlers and microtasks run to completion before the next message
+ * handler or microtask begins to run. Of particular note is that use of this
+ * function in a finally block will allow microtasks and message handlers to
+ * run before all finally blocks for an exception have completed, possibly
+ * breaking invariants in your program.
+ *
+ * Use of this function should be considered a last resort when it is not
+ * possible to convert a Dart program entirely to an asynchronous style using
+ * `async` and `await`.
+ *
+ * If the [Future] completes normally, its result is returned. If the [Future]
+ * completes with an error, the error and stack trace are wrapped in an
+ * [AsyncError] and thrown. If a microtask or message handler run during this
+ * call results in an unhandled exception, that exception will be propagated
+ * as though the microtask or message handler was the only Dart invocation on
+ * the stack. That is, unhandled exceptions in a microtask or message handler
+ * will skip over stacks suspended in a call to [waitFor].
+ *
+ * If the optional `timeout` parameter is passed, [waitFor] throws a
+ * [TimeoutException] if the [Future] is not completed within the specified
+ * period.
+ *
+ * Calls to [waitFor] may be nested. Earlier invocations will not complete
+ * until subsequent ones do, but the completion of a subsequent invocation will
+ * cause the previous invocation to wake up and check its [Future] for
+ * completion.
+ *
+ * Please be aware that nesting calls to [waitFor] can lead to deadlock if
+ * subsequent calls block waiting for a condition that is only satisfied when
+ * an earlier call returns.
+ */
+@provisional
+T waitFor<T>(Future<T> future, {Duration timeout}) {
+  T result;
+  Object error;
+  StackTrace stacktrace;
+  future.then((r) {
+    result = r;
+  }, onError: (e, st) {
+    error = e;
+    stacktrace = st;
+  });
+
+  Stopwatch s;
+  if (timeout != null) {
+    s = new Stopwatch()..start();
+  }
+  Timer.run(() {}); // Enusre there is at least one message.
+  while ((result == null) && (error == null)) {
+    Duration remaining;
+    if (timeout != null) {
+      if (s.elapsed >= timeout) {
+        throw new TimeoutException("waitFor() timed out", timeout);
+      }
+      remaining = timeout - s.elapsed;
+    }
+    _WaitForUtils.waitForEvent(timeout: remaining);
+  }
+  if (timeout != null) {
+    s.stop();
+  }
+  Timer.run(() {}); // Ensure that previous calls to waitFor are woken up.
+
+  if (error != null) {
+    throw new AsyncError(error, stacktrace);
+  }
+
+  return result;
+}
diff --git a/sdk/lib/convert/utf.dart b/sdk/lib/convert/utf.dart
index 1dadd36..b5850a6 100644
--- a/sdk/lib/convert/utf.dart
+++ b/sdk/lib/convert/utf.dart
@@ -27,7 +27,7 @@
  *                                0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
  */
 const Utf8Codec utf8 = const Utf8Codec();
-/** Deprecated, use [tf8Codec] instead. */
+/** Deprecated, use [Utf8Codec] instead. */
 const Utf8Codec UTF8 = utf8;
 
 /**
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index bf18121..ce66b2d 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -321,14 +321,13 @@
    * Whitespace is defined by the Unicode White_Space property (as defined in
    * version 6.2 or later) and the BOM character, 0xFEFF.
    *
-   * Here is the list of trimmed characters (following version 6.2):
+   * Here is the list of trimmed characters (following version 6.3):
    *
    *     0009..000D    ; White_Space # Cc   <control-0009>..<control-000D>
    *     0020          ; White_Space # Zs   SPACE
    *     0085          ; White_Space # Cc   <control-0085>
    *     00A0          ; White_Space # Zs   NO-BREAK SPACE
    *     1680          ; White_Space # Zs   OGHAM SPACE MARK
-   *     180E          ; White_Space # Zs   MONGOLIAN VOWEL SEPARATOR
    *     2000..200A    ; White_Space # Zs   EN QUAD..HAIR SPACE
    *     2028          ; White_Space # Zl   LINE SEPARATOR
    *     2029          ; White_Space # Zp   PARAGRAPH SEPARATOR
diff --git a/sdk/lib/dart_client.platform b/sdk/lib/dart_client.platform
index a42f16b..3813dc0 100644
--- a/sdk/lib/dart_client.platform
+++ b/sdk/lib/dart_client.platform
@@ -29,6 +29,7 @@
 _http: unsupported:_http/http.dart
 indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
 io: unsupported:io/io.dart
+cli: unsupported:cli/cli.dart
 isolate: isolate/isolate.dart
 js: js/dart2js/js_dart2js.dart
 js_util: js_util/dart2js/js_util_dart2js.dart
diff --git a/sdk/lib/dart_server.platform b/sdk/lib/dart_server.platform
index 6aadf8a..de57d4c 100644
--- a/sdk/lib/dart_server.platform
+++ b/sdk/lib/dart_server.platform
@@ -20,6 +20,7 @@
 core: core/core.dart
 developer: developer/developer.dart
 io: io/io.dart
+cli: cli/cli.dart
 isolate: isolate/isolate.dart
 math: math/math.dart
 mirrors: mirrors/mirrors.dart
diff --git a/sdk/lib/dart_shared.platform b/sdk/lib/dart_shared.platform
index 3d98e94..be8ed61 100644
--- a/sdk/lib/dart_shared.platform
+++ b/sdk/lib/dart_shared.platform
@@ -23,6 +23,7 @@
 _http: _http/http.dart
 indexed_db: indexed_db/dart2js/indexed_db_dart2js.dart
 io: io/io.dart
+cli: cli/cli.dart
 isolate: isolate/isolate.dart
 js: js/dart2js/js_dart2js.dart
 js_util: js_util/dart2js/js_util_dart2js.dart
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index e374096d..5f57649 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -78,7 +78,7 @@
 ///
 /// [Timeline]'s methods add synchronous events to the timeline. When
 /// generating a timeline in Chrome's tracing format, using [Timeline] generates
-/// "Complete" events. [Timeline]'s [startSync] and [endSync] can be used
+/// "Complete" events. [Timeline]'s [startSync] and [finishSync] can be used
 /// explicitly, or implicitly by wrapping a closure in [timeSync]. For exmaple:
 ///
 /// ```dart
diff --git a/sdk/lib/internal/iterable.dart b/sdk/lib/internal/iterable.dart
index 01ac05e..7123c47 100644
--- a/sdk/lib/internal/iterable.dart
+++ b/sdk/lib/internal/iterable.dart
@@ -730,7 +730,7 @@
 
   Iterable<E> where(bool test(E element)) => this;
 
-  Iterable<T> map<T>(T f(E element)) => const EmptyIterable();
+  Iterable<T> map<T>(T f(E element)) => new EmptyIterable<T>();
 
   E reduce(E combine(E value, E element)) {
     throw IterableElementError.noElement();
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 82c4ff4..be981c7 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -6,6 +6,12 @@
       "_builtin": {
         "uri": "../../runtime/bin/builtin.dart"
       },
+      "cli": {
+        "patches": [
+          "../../runtime/bin/cli_patch.dart"
+        ],
+        "uri": "cli/cli.dart"
+      },
       "core": {
         "patches": [
           "../../runtime/lib/core_patch.dart",
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index 6c88c97..deff85f 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -128,10 +128,15 @@
     profiler:
       uri: "profiler/profiler.dart"
 
+    cli:
+      uri: "cli/cli.dart"
+      patches:
+        - "../../runtime/bin/cli_patch.dart"
+
     typed_data:
       uri: "typed_data/typed_data.dart"
       patches: "../../runtime/lib/typed_data_patch.dart"
-      
+
     _vmservice:
       uri: "vmservice/vmservice.dart"
 
diff --git a/sdk/lib/mirrors/mirrors.dart b/sdk/lib/mirrors/mirrors.dart
index 794ab91..5f6aca9 100644
--- a/sdk/lib/mirrors/mirrors.dart
+++ b/sdk/lib/mirrors/mirrors.dart
@@ -820,7 +820,7 @@
    *
    * If this class is the result of a mixin application of the form S with M,
    * returns a class mirror on M. Otherwise returns a class mirror on
-   * [reflectee].
+   * the reflectee.
    */
   ClassMirror get mixin;
 
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index d81a4d4..574c8c1 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -180,7 +180,6 @@
 LibTest/core/List/getRange_A03_t01: RuntimeError, OK # Tests that fail because they use the legacy try-catch syntax. co19 issue 184.
 LibTest/core/List/removeAt_A02_t01: RuntimeError # Issue 1533
 LibTest/core/List/sort_A01_t06: Slow, Pass # Slow tests that needs extra time to finish.
-LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Pass, RuntimeError # https://github.com/dart-lang/sdk/issues/29814
 LibTest/core/double/INFINITY_A01_t04: RuntimeError # Expected to fail because double.INFINITY is int.
 LibTest/core/double/NEGATIVE_INFINITY_A01_t04: RuntimeError # Expected to fail because double.NEGATIVE_INFINITY is int.
 LibTest/core/int/hashCode_A01_t01: RuntimeError, OK # co19 issue 308
@@ -981,7 +980,6 @@
 LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xsl/default-html_t01: RuntimeError # Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Pass, RuntimeError # https://github.com/dart-lang/sdk/issues/29814
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
@@ -2031,10 +2029,11 @@
 LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xsl/default-html_t01: RuntimeError # Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # DRT is not on Unicode 6.3 yet.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Please triage this failure
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Please triage this failure
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Fail # DRT is not on Unicode 6.3 yet.
 LibTest/core/int/compareTo_A01_t01: RuntimeError # Please triage this failure
 LibTest/core/int/operator_left_shift_A01_t01: RuntimeError # Please triage this failure
 LibTest/core/int/operator_remainder_A01_t03: RuntimeError # Please triage this failure
@@ -3386,7 +3385,6 @@
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
-LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Fail # co19 issue #90
 LibTest/core/double/roundToDouble_A01_t01: Pass, RuntimeError # Passes on ff 35. Please triage this failure
 LibTest/core/double/round_A01_t01: Pass, RuntimeError # Passes on ff 35. Please triage this failure
 LibTest/core/int/compareTo_A01_t01: RuntimeError # Please triage this failure
@@ -5149,10 +5147,11 @@
 LibTest/async/Stream/Stream.periodic_A01_t01: Pass, RuntimeError # Please triage this failure
 LibTest/async/Timer/Timer.periodic_A01_t01: Pass, RuntimeError # Please triage this failure
 LibTest/async/Timer/Timer_A01_t01: Pass, RuntimeError # Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # IE11 is not on Unicode 6.3 yet.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Fail # IE11 is not on Unicode 6.3 yet.
 LibTest/core/Runes/takeWhile_A01_t01: Skip # Times out. Please triage this failure
 LibTest/core/String/split_A01_t02: Skip # Times out. Please triage this failure
 LibTest/core/String/toLowerCase_A01_t02: Skip # Times out. Please triage this failure
@@ -5648,7 +5647,6 @@
 LibTest/async/Zone/createTimer_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/List/sort_A01_t04: Skip # Must be a bug in jsshell, test sometimes times out.
 LibTest/core/Map/Map_class_A01_t04: Pass, Slow # Issue 8096
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail # co19-roll r706: Please triage this failure.
 LibTest/core/Stopwatch/elapsedInMs_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/Stopwatch/elapsedInUs_A01_t01: RuntimeError # Issue 7728, timer not supported in jsshell
 LibTest/core/Stopwatch/elapsedTicks_A01_t01: RuntimeError # Please triage this failure
@@ -6494,10 +6492,11 @@
 LayoutTests/fast/xpath/py-dom-xpath/paths_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/reverse-axes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xsl/default-html_t01: RuntimeError # Please triage this failure
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Please triage this failure
+LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Safari is not on Unicode 6.3 yet.
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
+LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: Fail # Safari is not on Unicode 6.3 yet.
 LibTest/core/double/roundToDouble_A01_t01: RuntimeError # Please triage this failure
 LibTest/core/double/round_A01_t01: RuntimeError # Please triage this failure
 LibTest/core/int/compareTo_A01_t01: RuntimeError # Please triage this failure
@@ -7068,7 +7067,6 @@
 Language/Types/Function_Types/call_t01: Crash # Issue 28894
 
 [ $compiler == dart2js && $jscl ]
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: Fail, Pass # issue 3333
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError, OK # This is not rejected by V8. Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError # Issue 22200
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index fdc9c63..907d7df 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -7,6 +7,7 @@
 Language/Expressions/Instance_Creation/Const/canonicalized_t05: RuntimeError
 Language/Expressions/Object_Identity/string_t01: RuntimeError
 Language/Expressions/Strings/adjacent_strings_t02: RuntimeError
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t03: CompileTimeError
 Language/Metadata/before_type_param_t01: RuntimeError
 LibTest/isolate/Isolate/spawnUri_A01_t03: Pass, Timeout
 
@@ -24,12 +25,17 @@
 Language/Expressions/Null/extend_or_implement_t03: MissingCompileTimeError # New entries after going from kernel-service to batch-mode compilation. Please investigate.
 Language/Expressions/Null/extend_or_implement_t04: MissingCompileTimeError # New entries after going from kernel-service to batch-mode compilation. Please investigate.
 Language/Expressions/Null/extend_or_implement_t05: MissingCompileTimeError # New entries after going from kernel-service to batch-mode compilation. Please investigate.
+Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t03: CompileTimeError
 Language/Mixins/Mixin_Application/syntax_t16: RuntimeError # New entries after going from kernel-service to batch-mode compilation. Please investigate.
 Language/Overview/Scoping/hiding_declaration_t11: Crash
 Language/Overview/Scoping/hiding_declaration_t11: Pass
 Language/Overview/Scoping/hiding_declaration_t12: Crash
 Language/Overview/Scoping/hiding_declaration_t12: Pass
 
+[ $fasta ]
+Language/Mixins/Mixin_Application/syntax_t20: CompileTimeError
+Language/Types/Interface_Types/subtype_t30: CompileTimeError
+
 # Enabling of dartk for sim{arm,arm64,dbc64} revelaed these test failures, which
 # are to be triaged.  Isolate tests are skipped on purpose due to the usage of
 # batch mode.
@@ -153,8 +159,6 @@
 Language/Functions/External_Functions/not_connected_to_a_body_t01: RuntimeError # Dartk Issue 28565
 Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
 Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
-Language/Functions/Formal_Parameters/Required_Formals/syntax_t06: MissingCompileTimeError
-Language/Functions/Formal_Parameters/Required_Formals/syntax_t07: MissingCompileTimeError
 Language/Libraries_and_Scripts/Exports/reexport_t01: MissingCompileTimeError
 Language/Libraries_and_Scripts/Imports/deferred_import_t01: CompileTimeError # Deferred loading kernel issue 28335.
 Language/Libraries_and_Scripts/Imports/deferred_import_t02: CompileTimeError # Deferred loading kernel issue 28335.
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 0f5f5bf..b350ad7 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -302,11 +302,9 @@
 LibTest/core/Duration/inMinutes_A01_t01: RuntimeError # Large integers
 LibTest/core/Duration/inSeconds_A01_t01: RuntimeError # Large integers
 LibTest/core/List/List_class_A01_t01: RuntimeError # Large integers
-LibTest/core/RegExp/Pattern_semantics/firstMatch_CharacterClassEscape_A03_t01: RuntimeError # Issue 1296
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t01: RuntimeError, Fail # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t05: RuntimeError, Fail # Issue 22200
 LibTest/core/RegExp/Pattern_semantics/firstMatch_NonEmptyClassRanges_A01_t06: RuntimeError, Fail # Issue 22200
-LibTest/core/RegExp/Pattern_semantics/splitQueryString_A02_t01: RuntimeError # Issue 1296
 LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Issue 13596
 LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Issue 13596
 LibTest/core/double/ceil_A01_t04: RuntimeError # Large integers
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 933e5f3..dfa1d84 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -78,7 +78,6 @@
 deferred/deferred_mirrors2_test: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred/reflect_multiple_annotations_test: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred/reflect_multiple_default_arg_test: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
-deferred_custom_loader_test: RuntimeError
 deferred_fail_and_retry_test: RuntimeError
 deferred_fail_and_retry_worker_test: Fail
 dummy_compiler_test: CompileTimeError
@@ -135,7 +134,6 @@
 deferred/deferred_mirrors2_test: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred/reflect_multiple_annotations_test: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred/reflect_multiple_default_arg_test: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
-deferred_custom_loader_test: RuntimeError
 deferred_fail_and_retry_test: RuntimeError
 deferred_fail_and_retry_worker_test: Fail
 dummy_compiler_test: CompileTimeError
@@ -163,7 +161,6 @@
 deferred/deferred_mirrors2_test: CompileTimeError
 deferred/reflect_multiple_annotations_test: CompileTimeError
 deferred/reflect_multiple_default_arg_test: CompileTimeError
-deferred_custom_loader_test: RuntimeError
 deferred_fail_and_retry_test: RuntimeError
 deferred_fail_and_retry_worker_test: Fail
 inference_nsm_mirrors_test: CompileTimeError
@@ -211,7 +208,6 @@
 deferred/deferred_mirrors2_test: CompileTimeError
 deferred/reflect_multiple_annotations_test: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
 deferred/reflect_multiple_default_arg_test: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
-deferred_custom_loader_test: RuntimeError
 deferred_fail_and_retry_test: RuntimeError
 deferred_fail_and_retry_worker_test: Fail
 dummy_compiler_test: CompileTimeError
diff --git a/tests/compiler/dart2js_extra/deferred_custom_loader_test.dart b/tests/compiler/dart2js_extra/deferred_custom_loader_test.dart
index 819635d..d1f358e 100644
--- a/tests/compiler/dart2js_extra/deferred_custom_loader_test.dart
+++ b/tests/compiler/dart2js_extra/deferred_custom_loader_test.dart
@@ -4,24 +4,29 @@
 
 import 'package:async_helper/async_helper.dart';
 import 'package:expect/expect.dart';
+import 'dart:_foreign_helper' show JS;
 
 import 'deferred_custom_loader_lib.dart' deferred as def;
 
-void setup() native """
-// In d8 we don't have any way to load the content of the file, so just use
-// the preamble's loader.
-if (!self.dartDeferredLibraryLoader) {
-  self.dartDeferredLibraryLoader = function(uri, success, error) {
-    var req = new XMLHttpRequest();
-    req.addEventListener("load", function() {
-      eval(this.responseText);
-      success();
-    });
-    req.open("GET", uri);
-    req.send();
-  };
+void setup() {
+  JS('', r"""
+(function(){
+  // In d8 we don't have any way to load the content of the file, so just use
+  // the preamble's loader.
+  if (!self.dartDeferredLibraryLoader) {
+    self.dartDeferredLibraryLoader = function(uri, success, error) {
+      var req = new XMLHttpRequest();
+      req.addEventListener("load", function() {
+        eval(this.responseText);
+        success();
+      });
+      req.open("GET", uri);
+      req.send();
+    };
+ }
+})()
+""");
 }
-""";
 
 runTest() async {
   setup();
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 8a40903..b4055c8 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -57,7 +57,6 @@
 main_test: RuntimeError # Flutter Issue 9111
 string_from_environment2_test: Fail # Flutter Issue 9111
 string_from_environment_test: Fail # Flutter Issue 9111
-string_trimlr_test/02: RuntimeError # Flutter Issue 9111
 
 [ $runtime == jsshell ]
 string_case_test/01: RuntimeError # jsshell does not recognize character 223 aka \xdf
@@ -66,7 +65,7 @@
 [ $runtime == safari ]
 double_round3_test: RuntimeError
 double_round_to_double2_test: Pass, Fail, OK
-string_trimlr_test/02: RuntimeError # Uses Unicode 6.2.0 or earlier.
+string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
 
 [ $strong ]
 *: SkipByDesign # tests/corelib_2 has the strong mode versions of these tests.
@@ -101,10 +100,10 @@
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 list_as_map_test: Pass, Slow # TODO(kasperl): Please triage.
-string_trimlr_test/02: RuntimeError # Uses Unicode 6.2.0 or earlier.
+string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
 
 [ $compiler == dart2js && $runtime == drt ]
-string_trimlr_test/02: RuntimeError # Uses Unicode 6.2.0 or earlier.
+string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
 
 [ $compiler == dart2js && $runtime == drt && $csp && $minified ]
 core_runtime_types_test: Pass, Fail # Issue 27913
@@ -335,9 +334,6 @@
 [ $compiler == dart2js && $fast_startup ]
 apply3_test: Fail # mirrors not supported
 
-[ $compiler == none && ($runtime == flutter || $runtime == vm) ]
-string_trimlr_test/02: RuntimeError # Issue 29060
-
 [ $runtime != d8 && $runtime != dart_precompiled && $runtime != vm ]
 regexp/*: Skip # The regexp tests are not verified to work on non d8/vm platforms yet.
 
@@ -369,7 +365,6 @@
 file_resource_test: Skip # Resolve URI not supported yet in product mode.
 http_resource_test: Skip # Resolve URI not supported yet in product mode.
 package_resource_test: Skip # Resolve URI not supported yet in product mode.
-string_trimlr_test/02: RuntimeError # Issue 29060
 
 # We skip all the Dart 1.0 tests in dartk and dartkp mode as these
 # modes are intended only for Dart 2.0 with strong mode enabled.
diff --git a/tests/corelib/string_trimlr_test.dart b/tests/corelib/string_trimlr_test.dart
index 90eb02d..360b9e0 100644
--- a/tests/corelib/string_trimlr_test.dart
+++ b/tests/corelib/string_trimlr_test.dart
@@ -104,8 +104,9 @@
   Expect.identical(s200B, s200B.trimRight()); //   //# 01: ok
 
   // U+180E ceased to be whitespace in Unicode version 6.3.0
-  // string_trimlr_test/02 fails on implementations using earlier versions.
+  // string_trimlr_test/unicode63 fails on implementations using earlier
+  // versions.
   var s180E = new String.fromCharCode(0x180E);
-  Expect.identical(s180E, s180E.trimLeft()); //    //# 02: ok
-  Expect.identical(s180E, s180E.trimRight()); //   //# 02: ok
+  Expect.identical(s180E, s180E.trimLeft()); //    //# unicode63: ok
+  Expect.identical(s180E, s180E.trimRight()); //   //# unicode63: ok
 }
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index fefc9fc..2021a13 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -66,7 +66,6 @@
 main_test: RuntimeError # Flutter Issue 9111
 string_from_environment2_test: Fail # Flutter Issue 9111
 string_from_environment_test: Fail # Flutter Issue 9111
-string_trimlr_test/02: RuntimeError # Flutter Issue 9111
 
 [ $runtime == jsshell ]
 string_case_test/01: Fail, OK # German double S.
@@ -75,7 +74,7 @@
 [ $runtime == safari ]
 double_round3_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
 double_round_to_double2_test: Fail, OK # Runtime rounds 0.49999999999999994 to 1.
-string_trimlr_test/02: RuntimeError # Uses Unicode 6.2.0 or earlier.
+string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
 
 [ !$strong ]
 cast_test: SkipByDesign # Uses generic method parameters.
@@ -130,10 +129,9 @@
 
 [ $compiler == dart2js && $runtime == chromeOnAndroid ]
 list_as_map_test: Pass, Slow # TODO(kasperl): Please triage.
-string_trimlr_test/02: RuntimeError # Uses Unicode 6.2.0 or earlier.
+string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
 
 [ $compiler == dart2js && $runtime == d8 ]
-string_trimlr_test/02: RuntimeError, Pass # Uses Unicode 6.2.0 or earlier, issue 30279.
 uri_base_test: RuntimeError # D8 uses a custom uri scheme for Uri.base
 
 [ $compiler == dart2js && $runtime == drt && $csp && $minified ]
@@ -148,11 +146,11 @@
 list_test/*: RuntimeError # dart2js doesn't implement strong mode covariance checks
 nan_infinity_test/01: RuntimeError
 regexp/pcre_test: Pass, Slow # Issue 21593
-string_split_test: RuntimeError # Issue 30548: does not return List<String>
 
 [ $compiler == dart2js && $runtime != none && !$checked ]
 growable_list_test: RuntimeError # Concurrent modifications test always runs
 splay_tree_from_iterable_test: RuntimeError
+string_split_test/checkedstore: RuntimeError # Issue 30548: does not check stores into List<String>
 
 [ $compiler == dart2js && $runtime != none && $dart2js_with_kernel ]
 list_concurrent_modify_test: Crash # Issue 30559
@@ -333,7 +331,6 @@
 apply3_test: CompileTimeError # Issue 31402 (Invocation arguments)
 bool_from_environment2_test/03: MissingCompileTimeError
 compare_to2_test: RuntimeError
-iterable_empty_test: RuntimeError
 iterable_fold_test/02: RuntimeError
 iterable_reduce_test/01: CompileTimeError # Issue 31533
 iterable_reduce_test/none: RuntimeError
@@ -344,25 +341,23 @@
 list_set_all_test: RuntimeError
 null_nosuchmethod_test/01: CompileTimeError # Issue 31402 (Invocation arguments)
 null_nosuchmethod_test/none: CompileTimeError # Issue 31402 (Invocation arguments)
-string_from_environment3_test/03: MissingCompileTimeError
-string_trimlr_test/02: RuntimeError
-symbol_operator_test/03: RuntimeError
-symbol_reserved_word_test/04: MissingCompileTimeError
-symbol_reserved_word_test/06: RuntimeError
-symbol_reserved_word_test/07: MissingCompileTimeError
-symbol_reserved_word_test/09: RuntimeError
-symbol_reserved_word_test/10: MissingCompileTimeError
-symbol_reserved_word_test/12: RuntimeError
-symbol_test/02: MissingCompileTimeError
-symbol_test/03: MissingCompileTimeError
-symbol_test/none: RuntimeError
-unicode_test: RuntimeError
+string_from_environment3_test/03: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_operator_test/03: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+symbol_reserved_word_test/04: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_reserved_word_test/06: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+symbol_reserved_word_test/07: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_reserved_word_test/09: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+symbol_reserved_word_test/10: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_reserved_word_test/12: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+symbol_test/02: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_test/03: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+unicode_test: RuntimeError # Issue 18061: German double S.
 
 # ===== dartkp + dart_precompiled status lines =====
 [ $compiler == dartkp && $runtime == dart_precompiled && $strong ]
 bool_from_environment2_test/03: MissingCompileTimeError
 compare_to2_test: RuntimeError
-iterable_empty_test: RuntimeError
 iterable_fold_test/02: RuntimeError
 iterable_reduce_test/01: CompileTimeError # Issue 31533
 iterable_reduce_test/none: RuntimeError
@@ -374,19 +369,18 @@
 null_nosuchmethod_test/01: CompileTimeError # Issue 31402 (Invocation arguments)
 null_nosuchmethod_test/none: CompileTimeError # Issue 31402 (Invocation arguments)
 regexp/stack-overflow_test: RuntimeError
-string_from_environment3_test/03: MissingCompileTimeError
-string_trimlr_test/02: RuntimeError
-symbol_operator_test/03: RuntimeError
-symbol_reserved_word_test/04: MissingCompileTimeError
-symbol_reserved_word_test/06: RuntimeError
-symbol_reserved_word_test/07: MissingCompileTimeError
-symbol_reserved_word_test/09: RuntimeError
-symbol_reserved_word_test/10: MissingCompileTimeError
-symbol_reserved_word_test/12: RuntimeError
-symbol_test/02: MissingCompileTimeError
-symbol_test/03: MissingCompileTimeError
-symbol_test/none: RuntimeError
-unicode_test: RuntimeError
+string_from_environment3_test/03: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_operator_test/03: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+symbol_reserved_word_test/04: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_reserved_word_test/06: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+symbol_reserved_word_test/07: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_reserved_word_test/09: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+symbol_reserved_word_test/10: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_reserved_word_test/12: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+symbol_test/02: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_test/03: MissingCompileTimeError # Issue 31936 - throwing const constructors.
+symbol_test/none: RuntimeError # Issues 11669 and 31936 - throwing const constructors.
+unicode_test: RuntimeError # Issue 18061: German double S.
 
 [ $compiler == none && $runtime == drt ]
 string_from_environment2_test: Skip
@@ -395,7 +389,6 @@
 
 [ $compiler == none && ($runtime == flutter || $runtime == vm) ]
 iterable_to_set_test: RuntimeError # is-checks do not implement strong mode type system
-string_trimlr_test/02: RuntimeError # Issue 29060
 
 [ $compiler == precompiler && $runtime == dart_precompiled && !$checked ]
 iterable_generate_test/01: RuntimeError
@@ -406,7 +399,7 @@
 error_stack_trace1_test: Skip # Expects unobfuscated stack trace
 
 [ $runtime == drt && ($compiler == dart2js || $compiler == dartdevc || $compiler == dartdevk) ]
-string_trimlr_test/02: RuntimeError # Uses Unicode 6.2.0 or earlier.
+string_trimlr_test/unicode63: RuntimeError # Uses Unicode 6.2.0 or earlier.
 
 [ $runtime != drt && ($compiler == app_jit || $compiler == none || $compiler == precompiler) ]
 symbol_test/02: MissingCompileTimeError # Issue 11669
@@ -507,12 +500,6 @@
 symbol_test/none: RuntimeError # Issue 29921
 typed_data_with_limited_ints_test: Skip # dartdevc doesn't know about --limit-ints-to-64-bits
 
-# We no longer expect Dart2 tests to run with the standalone VM without the new
-# common front end, but for now we get better coverage by still running them in
-# checked mode, which is mostly Dart2-compatible.
-[ $runtime == vm && !$checked && ($compiler == app_jit || $compiler == none) ]
-*: Skip
-
 [ !$checked && !$strong ]
 core_runtime_types_static_test: MissingCompileTimeError
 splay_tree_test/01: MissingCompileTimeError
@@ -521,6 +508,12 @@
 string_replace_static_test: MissingCompileTimeError
 string_static_test: MissingCompileTimeError
 
+# We no longer expect Dart2 tests to run with the standalone VM without the new
+# common front end, but for now we get better coverage by still running them in
+# checked mode, which is mostly Dart2-compatible.
+[ !$checked && ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
+*: Skip
+
 [ !$checked && ($compiler == dart2js || $compiler == none && $runtime == vm) ]
 from_environment_const_type_test/02: MissingCompileTimeError
 from_environment_const_type_test/03: MissingCompileTimeError
@@ -605,7 +598,6 @@
 from_environment_const_type_undefined_test/14: MissingCompileTimeError
 from_environment_const_type_undefined_test/16: MissingCompileTimeError
 iterable_to_set_test: RuntimeError # is-checks do not implement strong mode type system
-string_trimlr_test/02: RuntimeError # Issue 29060
 
 [ $compiler == dart2js || $compiler == none && $runtime == vm ]
 from_environment_const_type_undefined_test/09: MissingCompileTimeError
@@ -636,10 +628,6 @@
 regexp/pcre_test: Pass, Slow, Timeout
 
 [ $runtime == dart_precompiled || $runtime == vm ]
-integer_parsed_arith_vm_test/01: RuntimeError # Issue 31346
-integer_parsed_arith_vm_test/02: RuntimeError # Issue 31346
-integer_parsed_div_rem_vm_test/01: RuntimeError # Issue 31346
-integer_to_radix_string_test/01: RuntimeError # Issue 31346
 string_case_test/01: RuntimeError # Issue 18061: German double S.
 
 [ $runtime == ff || $runtime == jsshell ]
diff --git a/tests/corelib_2/integer_parsed_arith_vm_test.dart b/tests/corelib_2/integer_parsed_arith_vm_test.dart
index d3e273d..0ccc6bd 100644
--- a/tests/corelib_2/integer_parsed_arith_vm_test.dart
+++ b/tests/corelib_2/integer_parsed_arith_vm_test.dart
@@ -10,27 +10,25 @@
 
 import "package:expect/expect.dart";
 
+String toHexString(int value) => value >= 0
+    ? "0x${value.toRadixString(16)}"
+    : "-0x${value.toRadixString(16).substring(1)}";
+
 addSubParsed(String a, String b, String sum) {
   int int_a = int.parse(a);
   int int_b = int.parse(b);
   int int_sum = int.parse(sum);
   int computed_sum = int_a + int_b;
   Expect.equals(int_sum, computed_sum);
-  String str_sum = computed_sum >= 0
-      ? "0x${computed_sum.toRadixString(16)}"
-      : "-0x${(-computed_sum).toRadixString(16)}";
+  String str_sum = toHexString(computed_sum);
   Expect.equals(sum.toLowerCase(), str_sum);
   int computed_difference1 = int_sum - int_a;
   Expect.equals(int_b, computed_difference1);
-  String str_difference1 = computed_difference1 >= 0
-      ? "0x${computed_difference1.toRadixString(16)}"
-      : "-0x${(-computed_difference1).toRadixString(16)}";
+  String str_difference1 = toHexString(computed_difference1);
   Expect.equals(b.toLowerCase(), str_difference1);
   int computed_difference2 = int_sum - int_b;
   Expect.equals(int_a, computed_difference2);
-  String str_difference2 = computed_difference2 >= 0
-      ? "0x${computed_difference2.toRadixString(16)}"
-      : "-0x${(-computed_difference2).toRadixString(16)}";
+  String str_difference2 = toHexString(computed_difference2);
   Expect.equals(a.toLowerCase(), str_difference2);
 }
 
@@ -60,14 +58,14 @@
       "0xFFFFFFFFFFFFFF",
       one, // 56 bit overflow.
       "0x100000000000000");
-  addSubParsed( //                                  //# 01: ok
-      "0x7FFFFFFFFFFFFFFF", //                      //# 01: continued
-      one, // 64 bit overflow.                      //# 01: continued
-      "-0x8000000000000000"); //                    //# 01: continued
-  addSubParsed( //                                  //# 02: ok
-      minus_one, //                                 //# 02: continued
-      one, // 64 bit overflow.                      //# 02: continued
-      zero); //                                     //# 02: continued
+  addSubParsed(
+      "0x7FFFFFFFFFFFFFFF",
+      one, // 64 bit overflow.
+      "-0x8000000000000000");
+  addSubParsed(
+      minus_one,
+      one, // 64 bit overflow.
+      zero);
   addSubParsed(
       "0x8000000", // 28 bit overflow.
       "0x8000000",
@@ -80,10 +78,10 @@
       "0x80000000000000", // 56 bit overflow.
       "0x80000000000000",
       "0x100000000000000");
-  addSubParsed( //                                  //# 02: continued
-      "-0x8000000000000000", // 64 bit overflow.    //# 02: continued
-      "-0x8000000000000000", //                     //# 02: continued
-      zero); //                                     //# 02: continued
+  addSubParsed(
+      "-0x8000000000000000", // 64 bit overflow.
+      "-0x8000000000000000",
+      zero);
 
   addSubParsed("-0x123", minus_one, "-0x124");
   addSubParsed(minus_one, "-0x123", "-0x124");
@@ -99,10 +97,10 @@
       "-0xFFFFFFFFFFFFFF",
       minus_one, // 56 bit overflow.
       "-0x100000000000000");
-  addSubParsed( //                                  //# 01: continued
-      "-0x8000000000000000", //                     //# 01: continued
-      minus_one, // 64 bit overflow.                //# 01: continued
-      "0x7FFFFFFFFFFFFFFF"); //                     //# 01: continued
+  addSubParsed(
+      "-0x8000000000000000",
+      minus_one, // 64 bit overflow.
+      "0x7FFFFFFFFFFFFFFF");
   addSubParsed(
       "-0x8000000", // 28 bit overflow.
       "-0x8000000",
@@ -115,10 +113,10 @@
       "-0x80000000000000", // 56 bit overflow.
       "-0x80000000000000",
       "-0x100000000000000");
-  addSubParsed( //                                  //# 01: continued
-      "-0x8000000000000000", // 64 bit overflow.    //# 01: continued
-      "-0x8000000000000000", //                     //# 01: continued
-      "0x0"); //                                    //# 01: continued
+  addSubParsed(
+      "-0x8000000000000000", // 64 bit overflow.
+      "-0x8000000000000000",
+      "0x0");
 
   addSubParsed("0xB", "-0x7", "0x4");
   addSubParsed("-0xB", "-0x7", "-0x12");
@@ -138,15 +136,11 @@
   int int_result_back_shifted = int.parse(result_back_shifted);
   int shifted = int_a << amount;
   Expect.equals(int_result, shifted);
-  String str_shifted = shifted >= 0
-      ? "0x${shifted.toRadixString(16)}"
-      : "-0x${(-shifted).toRadixString(16)}";
+  String str_shifted = toHexString(shifted);
   Expect.equals(result.toLowerCase(), str_shifted);
   int back_shifted = shifted >> amount;
   Expect.equals(int_result_back_shifted, back_shifted);
-  String str_back_shifted = back_shifted >= 0
-      ? "0x${back_shifted.toRadixString(16)}"
-      : "-0x${(-back_shifted).toRadixString(16)}";
+  String str_back_shifted = toHexString(back_shifted);
   Expect.equals(result_back_shifted.toLowerCase(), str_back_shifted);
 }
 
@@ -171,17 +165,15 @@
   shiftLeftParsed("0x5", 27, "0x28000000");
   shiftLeftParsed("0x5", 31, "0x280000000");
   shiftLeftParsed("0x5", 55, "0x280000000000000");
-  shiftLeftParsed("0x5", 63, "-0x8000000000000000",  //     //# 01: continued
-      result_back_shifted: "-0x1"); //                      //# 01: continued
+  shiftLeftParsed("0x5", 63, "-0x8000000000000000",
+      result_back_shifted: "-0x1");
   shiftLeftParsed("0x5", 127, zero, result_back_shifted: zero);
   shiftLeftParsed("0x8000001", 1, "0x10000002");
   shiftLeftParsed("0x80000001", 1, "0x100000002");
-  shiftLeftParsed("0x8000000000000001", 1, "0x2", //        //# 02: continued
-      result_back_shifted: "0x1"); //                       //# 02: continued
+  shiftLeftParsed("0x8000000000000001", 1, "0x2", result_back_shifted: "0x1");
   shiftLeftParsed("0x8000001", 29, "0x100000020000000");
   shiftLeftParsed("0x80000001", 33, "0x200000000", result_back_shifted: "0x1");
-  shiftLeftParsed("0x8000000000000001", 65, zero, //        //# 02: continued
-      result_back_shifted: zero); //                        //# 02: continued
+  shiftLeftParsed("0x8000000000000001", 65, zero, result_back_shifted: zero);
   shiftLeftParsed("0x7fffffffffffffff", 1, "-0x2", result_back_shifted: "-0x1");
   shiftLeftParsed("0x7fffffffffffffff", 29, "-0x20000000",
       result_back_shifted: "-0x1");
@@ -196,7 +188,8 @@
   shiftLeftParsed("-0x5", 64, zero, result_back_shifted: zero);
   shiftLeftParsed("-0x5", 27, "-0x28000000");
   shiftLeftParsed("-0x5", 31, "-0x280000000");
-  shiftLeftParsed("-0x5", 63, "-0x8000000000000000"); //    //# 01: continued
+  shiftLeftParsed("-0x5", 63, "-0x8000000000000000",
+      result_back_shifted: minus_one);
   shiftLeftParsed("-0x8000001", 1, "-0x10000002");
   shiftLeftParsed("-0x80000001", 1, "-0x100000002");
   shiftLeftParsed("-0x8000001", 29, "-0x100000020000000");
@@ -213,9 +206,7 @@
   int int_result = int.parse(result);
   int shifted = int_a >> amount;
   Expect.equals(int_result, shifted);
-  String str_shifted = shifted >= 0
-      ? "0x${shifted.toRadixString(16)}"
-      : "-0x${(-shifted).toRadixString(16)}";
+  String str_shifted = toHexString(shifted);
   Expect.equals(result.toLowerCase(), str_shifted);
 }
 
@@ -257,15 +248,11 @@
   int int_result = int.parse(result);
   int anded = int_a & int_b;
   Expect.equals(int_result, anded);
-  String str_anded = anded >= 0
-      ? "0x${anded.toRadixString(16)}"
-      : "-0x${(-anded).toRadixString(16)}";
+  String str_anded = toHexString(anded);
   Expect.equals(result.toLowerCase(), str_anded);
   int anded2 = int_b & int_a;
   Expect.equals(int_result, anded2);
-  String str_anded2 = anded2 >= 0
-      ? "0x${anded2.toRadixString(16)}"
-      : "-0x${(-anded2).toRadixString(16)}";
+  String str_anded2 = toHexString(anded2);
   Expect.equals(result.toLowerCase(), str_anded2);
 }
 
@@ -298,11 +285,11 @@
   bitAndParsed("-0x10000001", "0x3FFFFFFF", "0x2FFFFFFF");
   bitAndParsed("-0x100000001", "0x3FFFFFFFF", "0x2FFFFFFFF");
   bitAndParsed("-0x100000000000000", "0xFFFFFFFFFFFFFF", "0x0");
-  bitAndParsed("-0x1000000000000000", "0xFFFFFFFFFFFFFFFF", // //# 02: continued
-      "-0x1000000000000000"); //                               //# 02: continued
+  bitAndParsed(
+      "-0x1000000000000000", "0xFFFFFFFFFFFFFFFF", "-0x1000000000000000");
   bitAndParsed("-0x300000000000000", "0xFFFFFFFFFFFFFFF", "0xD00000000000000");
-  bitAndParsed("-0x3000000000000000", "0xFFFFFFFFFFFFFFFF", // //# 02: continued
-      "-0x3000000000000000"); //                               //# 02: continued
+  bitAndParsed(
+      "-0x3000000000000000", "0xFFFFFFFFFFFFFFFF", "-0x3000000000000000");
   bitAndParsed("-0x10000000", "-0x10000000", "-0x10000000");
   bitAndParsed("-0x100000000", "-0x100000000", "-0x100000000");
   bitAndParsed(
@@ -324,15 +311,11 @@
   int int_result = int.parse(result);
   int ored = int_a | int_b;
   Expect.equals(int_result, ored);
-  String str_ored = ored >= 0
-      ? "0x${ored.toRadixString(16)}"
-      : "-0x${(-ored).toRadixString(16)}";
+  String str_ored = toHexString(ored);
   Expect.equals(result.toLowerCase(), str_ored);
   int ored2 = int_b | int_a;
   Expect.equals(int_result, ored2);
-  String str_ored2 = ored2 >= 0
-      ? "0x${ored2.toRadixString(16)}"
-      : "-0x${(-ored2).toRadixString(16)}";
+  String str_ored2 = toHexString(ored2);
   Expect.equals(result.toLowerCase(), str_ored2);
 }
 
@@ -370,7 +353,7 @@
   bitOrParsed("-0x100000000000000", "0xFFFFFFFFFFFFFF", "-0x1");
   bitOrParsed("-0x1000000000000000", "0xFFFFFFFFFFFFFFF", "-0x1");
   bitOrParsed("-0x300000000000000", "0xFFFFFFFFFFFFFFF", "-0x1");
-  bitOrParsed("-0x3000000000000000", "0xFFFFFFFFFFFFFFFF", "-0x1"); // //# 02: continued
+  bitOrParsed("-0x3000000000000000", "0xFFFFFFFFFFFFFFFF", "-0x1");
   bitOrParsed("-0x10000000", "-0x10000000", "-0x10000000");
   bitOrParsed("-0x100000000", "-0x100000000", "-0x100000000");
   bitOrParsed("-0x100000000000000", "-0x100000000000000", "-0x100000000000000");
@@ -389,21 +372,15 @@
   int int_result = int.parse(result);
   int xored = int_a ^ int_b;
   Expect.equals(int_result, xored);
-  String str_xored = xored >= 0
-      ? "0x${xored.toRadixString(16)}"
-      : "-0x${(-xored).toRadixString(16)}";
+  String str_xored = toHexString(xored);
   Expect.equals(result.toLowerCase(), str_xored);
   int xored2 = int_b ^ int_a;
   Expect.equals(int_result, xored2);
-  String str_xored2 = xored2 >= 0
-      ? "0x${xored2.toRadixString(16)}"
-      : "-0x${(-xored2).toRadixString(16)}";
+  String str_xored2 = toHexString(xored2);
   Expect.equals(result.toLowerCase(), str_xored2);
   int xored3 = int_a ^ xored2;
   Expect.equals(int_b, xored3);
-  String str_xored3 = xored3 >= 0
-      ? "0x${xored3.toRadixString(16)}"
-      : "-0x${(-xored3).toRadixString(16)}";
+  String str_xored3 = toHexString(xored3);
   Expect.equals(b.toLowerCase(), str_xored3);
 }
 
@@ -459,15 +436,11 @@
   int int_result = int.parse(result);
   int inverted = ~int_a;
   Expect.equals(int_result, inverted);
-  String str_inverted = inverted >= 0
-      ? "0x${inverted.toRadixString(16)}"
-      : "-0x${(-inverted).toRadixString(16)}";
+  String str_inverted = toHexString(inverted);
   Expect.equals(result.toLowerCase(), str_inverted);
   int back = ~inverted;
   Expect.equals(int_a, back);
-  String str_back = back >= 0
-      ? "0x${back.toRadixString(16)}"
-      : "-0x${(-back).toRadixString(16)}";
+  String str_back = toHexString(back);
   Expect.equals(a.toLowerCase(), str_back);
 }
 
@@ -483,8 +456,7 @@
   bitNotParsed("0xFFFFFFF", "-0x10000000");
   bitNotParsed("0xFFFFFFFF", "-0x100000000");
   bitNotParsed("0xFFFFFFFFFFFFFF", "-0x100000000000000");
-  bitNotParsed( //                                       //# 01: continued
-      "0x7FFFFFFFFFFFFFFF", "-0x8000000000000000"); //   //# 01: continued
+  bitNotParsed("0x7FFFFFFFFFFFFFFF", "-0x8000000000000000");
   bitNotParsed("-0x1", "0x0");
 }
 
diff --git a/tests/corelib_2/string_split_test.dart b/tests/corelib_2/string_split_test.dart
index f15ac1f..a05bced 100644
--- a/tests/corelib_2/string_split_test.dart
+++ b/tests/corelib_2/string_split_test.dart
@@ -23,8 +23,11 @@
 
   // Ensure that the correct type is reified.
   actual = actual as List<String>;
-  Expect.throwsTypeError(() => actual.add(42),
-      'List<String>.add should not accept an int');
+
+  // Check that store of the wrong type throws. Some platforms don't do this,
+  // so it's protected by multitest syntax.
+  Expect.throwsTypeError(() => actual.add(42), //      //# checkedstore: ok
+      'List<String>.add should not accept an int'); // //# checkedstore: ok
 
   Expect.listEquals(expect, actual, '"$string".split($patternString)');
 }
diff --git a/tests/corelib_2/string_trimlr_test.dart b/tests/corelib_2/string_trimlr_test.dart
index 90eb02d..95f6af6 100644
--- a/tests/corelib_2/string_trimlr_test.dart
+++ b/tests/corelib_2/string_trimlr_test.dart
@@ -96,16 +96,15 @@
     Expect.identical(s, s.trimRight());
   }
 
-  // U+200b is currently being treated as whitespace by some JS engines.
-  // string_trimlr_test/01 fails on these engines.
-  // Should be fixed in tip-of-tree V8 per 2014-02-10.
+  // U+200b is not treated as whitespace, though historically, some JS engines
+  // did.
   var s200B = new String.fromCharCode(0x200B);
-  Expect.identical(s200B, s200B.trimLeft()); //    //# 01: ok
-  Expect.identical(s200B, s200B.trimRight()); //   //# 01: ok
+  Expect.identical(s200B, s200B.trimLeft());
+  Expect.identical(s200B, s200B.trimRight());
 
   // U+180E ceased to be whitespace in Unicode version 6.3.0
-  // string_trimlr_test/02 fails on implementations using earlier versions.
+  // string_trimlr_test/unicode63 fails on implementations using earlier versions.
   var s180E = new String.fromCharCode(0x180E);
-  Expect.identical(s180E, s180E.trimLeft()); //    //# 02: ok
-  Expect.identical(s180E, s180E.trimRight()); //   //# 02: ok
+  Expect.identical(s180E, s180E.trimLeft()); //    //# unicode63: ok
+  Expect.identical(s180E, s180E.trimRight()); //   //# unicode63: ok
 }
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index b61f8d0..632499c 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -143,7 +143,6 @@
 constructor_redirect2_test/01: MissingCompileTimeError
 constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(A.named2#x), local(A.named2#y), local(A.named2#z)) for j:constructor(A.named2).
 cyclic_constructor_test/01: Crash # Issue 30856
-deferred_call_empty_before_load_test: RuntimeError
 deferred_constraints_constants_test/default_argument2: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred_constraints_constants_test/none: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred_constraints_constants_test/reference_after_load: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
@@ -384,9 +383,6 @@
 regress_17382_test: RuntimeError
 regress_20394_test/01: MissingCompileTimeError
 regress_22936_test/01: RuntimeError
-regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
 regress_24283_test: RuntimeError
 regress_26133_test: RuntimeError # Issue 26429
 regress_27572_test: RuntimeError
@@ -761,9 +757,6 @@
 regress_17382_test: RuntimeError
 regress_20394_test/01: MissingCompileTimeError
 regress_22936_test/01: RuntimeError
-regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
 regress_24283_test: RuntimeError
 regress_27572_test: RuntimeError
 regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
@@ -840,7 +833,6 @@
 constructor_redirect2_test/01: MissingCompileTimeError
 constructor_redirect_test/01: Crash # Assertion failure: Cannot find value Instance of 'ThisLocal' in (local(A.named2#x), local(A.named2#y), local(A.named2#z)) for j:constructor(A.named2).
 cyclic_constructor_test/01: Crash # Issue 30856
-deferred_call_empty_before_load_test: RuntimeError
 deferred_constraints_constants_test/none: CompileTimeError
 deferred_constraints_constants_test/reference_after_load: CompileTimeError
 deferred_constraints_type_annotation_test/as_operation: RuntimeError
@@ -1078,9 +1070,6 @@
 regress_18535_test: CompileTimeError
 regress_20394_test/01: MissingCompileTimeError
 regress_22936_test/01: RuntimeError
-regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
 regress_24283_test: RuntimeError
 regress_27572_test: RuntimeError
 regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
@@ -1167,7 +1156,6 @@
 cyclic_type_test/02: RuntimeError
 cyclic_type_test/03: RuntimeError
 cyclic_type_test/04: RuntimeError
-deferred_call_empty_before_load_test: RuntimeError
 deferred_constraints_constants_test/none: CompileTimeError
 deferred_constraints_constants_test/reference_after_load: CompileTimeError
 deferred_constraints_type_annotation_test/as_operation: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
@@ -1413,9 +1401,6 @@
 regress_20394_test/01: MissingCompileTimeError
 regress_21795_test: RuntimeError
 regress_22936_test/01: RuntimeError
-regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
 regress_24283_test: RuntimeError
 regress_27572_test: RuntimeError
 regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
diff --git a/tests/language_2/bug31436_test.dart b/tests/language_2/bug31436_test.dart
index 30fec3e..eace48f 100644
--- a/tests/language_2/bug31436_test.dart
+++ b/tests/language_2/bug31436_test.dart
@@ -27,7 +27,7 @@
   }; // No implicit downcast on the assignment, implicit downcast on the return
   assert(g is List<Object> Function());
   assert(g is! List<int> Function());
-  assert(g is! Object Function());
+  assert(g is Object Function());
   g(); // No runtime error;
   o = 3;
   Expect.throwsTypeError(() {
@@ -53,7 +53,7 @@
       o; // No implicit downcast on the assignment, implicit downcast on the return
   assert(g is List<Object> Function());
   assert(g is! List<int> Function());
-  assert(g is! Object Function());
+  assert(g is Object Function());
   g(); // No runtime error;
   o = 3;
   Expect.throwsTypeError(() {
diff --git a/tests/language_2/language_2.status b/tests/language_2/language_2.status
index 146c5dd..1b8fbc9 100644
--- a/tests/language_2/language_2.status
+++ b/tests/language_2/language_2.status
@@ -43,12 +43,6 @@
 [ $compiler == none && $runtime == drt && !$checked ]
 assertion_initializer_const_error_test/01: Fail
 
-# We no longer expect Dart2 tests to run with the standalone VM without the new
-# common front end, but for now we get better coverage by still running them in
-# checked mode, which is mostly Dart2-compatible.
-[ $compiler == none && $runtime == vm && !$checked ]
-*: Skip
-
 [ $compiler != spec_parser && !$checked && !$strong ]
 closure_type_test: RuntimeError
 map_literal1_test/01: MissingCompileTimeError
@@ -176,6 +170,12 @@
 [ $checked && !$strong ]
 type_parameter_test/05: Pass
 
+# We no longer expect Dart2 tests to run with the standalone VM without the new
+# common front end, but for now we get better coverage by still running them in
+# checked mode, which is mostly Dart2-compatible.
+[ !$checked && ($compiler == app_jit || $compiler == none || $compiler == precompiler) && ($runtime == dart_precompiled || $runtime == vm) ]
+*: Skip
+
 [ !$dart2js_with_kernel && $minified ]
 regress_21795_test: RuntimeError # Issue 12605
 stack_trace_test: Fail, OK # Stack trace not preserved in minified code.
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index 803fd57..09d1afc 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -1120,6 +1120,7 @@
 super_bound_closure_test/none: CompileTimeError
 super_setter_test: StaticWarning # Issue 28823
 switch_case_test/none: CompileTimeError
+type_inference_accessor_ref_test/06: MissingCompileTimeError
 type_inference_circularity_test: MissingCompileTimeError
 type_promotion_functions_test/01: Pass
 type_promotion_functions_test/05: Pass
@@ -1570,6 +1571,8 @@
 try_catch_on_syntax_test/07: MissingCompileTimeError
 try_catch_syntax_test/08: MissingCompileTimeError
 type_checks_in_factory_method_test/01: MissingCompileTimeError
+type_inference_accessor_ref_test/03: MissingCompileTimeError
+type_inference_accessor_ref_test/06: MissingCompileTimeError
 type_inference_circularity_test: MissingCompileTimeError
 type_promotion_functions_test/01: MissingCompileTimeError
 type_promotion_functions_test/05: MissingCompileTimeError
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 64b68c3..a753676 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -1197,7 +1197,6 @@
 covariant_override/runtime_check_test: RuntimeError
 covariant_subtyping_test: CompileTimeError
 cyclic_constructor_test/01: Crash # Stack Overflow
-deferred_call_empty_before_load_test: RuntimeError
 deferred_constraints_constants_test/default_argument2: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred_constraints_constants_test/none: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred_constraints_constants_test/reference_after_load: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
@@ -1419,9 +1418,6 @@
 redirecting_factory_long_test: RuntimeError
 redirecting_factory_reflection_test: RuntimeError
 regress_20394_test/01: MissingCompileTimeError
-regress_22976_test/01: RuntimeError
-regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
 regress_24283_test: RuntimeError
 regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
 regress_28217_test/01: MissingCompileTimeError
@@ -1627,6 +1623,8 @@
 object_has_no_call_method_test/02: MissingCompileTimeError
 object_has_no_call_method_test/05: MissingCompileTimeError
 object_has_no_call_method_test/08: MissingCompileTimeError
+type_inference_accessor_ref_test/03: MissingCompileTimeError
+type_inference_accessor_ref_test/06: MissingCompileTimeError
 type_inference_circularity_test: MissingCompileTimeError
 type_inference_inconsistent_inheritance_test: MissingCompileTimeError
 
@@ -1750,7 +1748,6 @@
 covariant_subtyping_unsafe_call2_test: RuntimeError
 covariant_subtyping_unsafe_call3_test: RuntimeError
 cyclic_constructor_test/01: Crash # Stack Overflow
-deferred_call_empty_before_load_test: RuntimeError
 deferred_constraints_constants_test/default_argument2: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred_constraints_constants_test/none: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
 deferred_constraints_constants_test/reference_after_load: Crash # Unsupported operation: KernelDeferredLoadTask.addMirrorElementsForLibrary
@@ -2010,9 +2007,6 @@
 redirecting_factory_long_test: RuntimeError
 redirecting_factory_reflection_test: RuntimeError
 regress_20394_test/01: MissingCompileTimeError
-regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
 regress_24283_test: RuntimeError
 regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
 regress_28217_test/01: MissingCompileTimeError
@@ -2244,7 +2238,6 @@
 covariant_subtyping_unsafe_call3_test: RuntimeError
 crash_6725_test/01: MissingCompileTimeError
 cyclic_constructor_test/01: Crash # Issue 30856
-deferred_call_empty_before_load_test: RuntimeError
 deferred_constraints_constants_test/none: CompileTimeError
 deferred_constraints_constants_test/reference_after_load: CompileTimeError
 deferred_constraints_type_annotation_test/as_operation: MissingCompileTimeError
@@ -2588,9 +2581,6 @@
 regress_13462_1_test: CompileTimeError
 regress_18535_test: CompileTimeError
 regress_20394_test/01: MissingCompileTimeError
-regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
 regress_23408_test: Crash # Assertion failure: Missing scope info for j:method(_loadLibraryWrapper).
 regress_24283_test: RuntimeError
 regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
@@ -3010,7 +3000,6 @@
 covariant_subtyping_unsafe_call3_test: RuntimeError
 crash_6725_test/01: MissingCompileTimeError
 cyclic_constructor_test/01: Crash # Issue 30856
-deferred_call_empty_before_load_test: RuntimeError
 deferred_constraints_constants_test/none: CompileTimeError
 deferred_constraints_constants_test/reference_after_load: CompileTimeError
 deferred_constraints_type_annotation_test/as_operation: MissingCompileTimeError
@@ -3344,9 +3333,6 @@
 regress_18535_test: CompileTimeError
 regress_20394_test/01: MissingCompileTimeError
 regress_21795_test: RuntimeError
-regress_22976_test/01: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/02: Pass # Incorrectly pass, we are ignoring an error due to #31118
-regress_22976_test/none: Pass # Incorrectly pass, we are ignoring an error due to #31118
 regress_23408_test: Crash # NoSuchMethodError: The getter 'closureClassEntity' was called on null.
 regress_24283_test: RuntimeError, OK # Requires 64 bit numbers.
 regress_27617_test/1: Crash # Assertion failure: Unexpected constructor j:constructor(Foo._) in ConstructorDataImpl._getConstructorConstant
@@ -3732,6 +3718,8 @@
 truncdiv_test: RuntimeError # Issue 15246
 try_catch_on_syntax_test/10: Fail # Issue 19823
 try_catch_on_syntax_test/11: Fail # Issue 19823
+type_inference_accessor_ref_test/03: MissingCompileTimeError
+type_inference_accessor_ref_test/06: MissingCompileTimeError
 type_inference_circularity_test: MissingCompileTimeError
 type_inference_inconsistent_inheritance_test: MissingCompileTimeError
 type_variable_conflict_test/01: Fail # Issue 13702
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index 2e88f06..40dd00d 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -18,7 +18,6 @@
 assertion_initializer_const_function_test/01: Crash
 assertion_initializer_test: CompileTimeError
 black_listed_test/none: Fail # Issue 14228
-bug31436_test: RuntimeError
 built_in_identifier_prefix_test: CompileTimeError
 built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Issue 28816
 cascaded_forwarding_stubs_generic_test: RuntimeError
@@ -125,16 +124,6 @@
 additional_interface_adds_optional_args_concrete_subclass_test: MissingCompileTimeError
 additional_interface_adds_optional_args_concrete_test: MissingCompileTimeError
 additional_interface_adds_optional_args_supercall_test: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc01: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc02: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc03: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc05: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc06: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc07: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc08: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc09: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc10: MissingCompileTimeError
-assertion_initializer_const_error2_test/cc11: MissingCompileTimeError
 assertion_initializer_test: CompileTimeError
 async_await_syntax_test/c10a: MissingCompileTimeError
 async_await_syntax_test/d08b: MissingCompileTimeError
@@ -143,8 +132,7 @@
 async_or_generator_return_type_stacktrace_test/02: MissingCompileTimeError
 async_or_generator_return_type_stacktrace_test/03: MissingCompileTimeError
 async_return_types_test/tooManyTypeParameters: MissingCompileTimeError
-async_return_types_test/wrongReturnType: Crash # Maltyped input from Fasta, issue 31414
-await_test: Crash # Issue 31541
+async_return_types_test/wrongReturnType: MissingCompileTimeError
 bad_named_parameters2_test/01: MissingCompileTimeError
 bad_named_parameters_test/01: MissingCompileTimeError
 bad_named_parameters_test/02: MissingCompileTimeError
@@ -156,7 +144,6 @@
 bad_override_test/03: MissingCompileTimeError
 bad_override_test/04: MissingCompileTimeError
 bad_override_test/05: MissingCompileTimeError
-bug31436_test: RuntimeError
 built_in_identifier_type_annotation_test/22: Crash # Crashes in Fasta, issue 31416
 built_in_identifier_type_annotation_test/52: MissingCompileTimeError
 built_in_identifier_type_annotation_test/53: MissingCompileTimeError
@@ -193,7 +180,6 @@
 compile_time_constant_k_test/03: MissingCompileTimeError
 compile_time_constant_o_test/01: MissingCompileTimeError
 compile_time_constant_o_test/02: MissingCompileTimeError
-compile_time_constant_p_test/01: Crash
 compile_time_constant_static2_test/04: MissingCompileTimeError
 compile_time_constant_static3_test/04: MissingCompileTimeError
 compile_time_constant_static4_test/02: MissingCompileTimeError
@@ -208,29 +194,19 @@
 const_constructor2_test/24: MissingCompileTimeError
 const_constructor3_test/04: MissingCompileTimeError
 const_constructor_nonconst_field_test/01: MissingCompileTimeError
-const_constructor_syntax_test/05: Crash
 const_dynamic_type_literal_test/02: MissingCompileTimeError
-const_error_multiply_initialized_test/01: Crash
-const_error_multiply_initialized_test/02: Crash
-const_error_multiply_initialized_test/03: Crash
-const_error_multiply_initialized_test/04: Crash
 const_factory_with_body_test/01: MissingCompileTimeError
 const_instance_field_test/01: MissingCompileTimeError
 const_map2_test/00: MissingCompileTimeError
 const_map3_test/00: MissingCompileTimeError
 const_optional_args_test/01: MissingCompileTimeError
-const_qq_test: Crash
 const_switch2_test/01: MissingCompileTimeError
 const_syntax_test/05: MissingCompileTimeError
-const_syntax_test/09: Crash
 const_types_test/34: MissingCompileTimeError
 const_types_test/35: MissingCompileTimeError
 const_types_test/39: MissingCompileTimeError
 const_types_test/40: MissingCompileTimeError
 constants_test/05: MissingCompileTimeError
-constructor_duplicate_final_test/01: Crash
-constructor_duplicate_final_test/02: Crash
-constructor_duplicate_final_test/03: Crash
 constructor_redirect1_negative_test/01: MissingCompileTimeError
 constructor_redirect2_negative_test: MissingCompileTimeError
 constructor_redirect2_test/01: MissingCompileTimeError
@@ -289,9 +265,6 @@
 field_override4_test/02: MissingCompileTimeError
 field_override_test/00: MissingCompileTimeError
 field_override_test/01: MissingCompileTimeError
-final_attempt_reinitialization_test/01: Crash
-final_attempt_reinitialization_test/02: Crash
-final_syntax_test/09: Crash
 function_propagation_test: CompileTimeError
 function_type/function_type10_test: RuntimeError # Issue 31766
 function_type/function_type11_test: RuntimeError # Issue 31766
@@ -478,57 +451,28 @@
 mixin_invalid_bound_test/08: MissingCompileTimeError
 mixin_invalid_bound_test/09: MissingCompileTimeError
 mixin_invalid_bound_test/10: MissingCompileTimeError
-mixin_lib_extends_field_test: Crash
-mixin_lib_extends_method_test: Crash
-mixin_of_mixin_test/01: Crash
-mixin_of_mixin_test/02: Crash
-mixin_of_mixin_test/03: Crash
-mixin_of_mixin_test/04: Crash
-mixin_of_mixin_test/05: Crash
-mixin_of_mixin_test/06: Crash
-mixin_of_mixin_test/none: Crash
-mixin_super_2_test/01: Crash
-mixin_super_2_test/02: Crash
-mixin_super_2_test/03: Crash
-mixin_super_2_test/04: Crash
-mixin_super_2_test/none: Crash
+mixin_lib_extends_field_test: RuntimeError
+mixin_of_mixin_test/01: MissingCompileTimeError
+mixin_of_mixin_test/02: MissingCompileTimeError
+mixin_of_mixin_test/03: MissingCompileTimeError
+mixin_of_mixin_test/04: MissingCompileTimeError
+mixin_of_mixin_test/05: MissingCompileTimeError
+mixin_of_mixin_test/06: MissingCompileTimeError
+mixin_super_2_test/01: MissingCompileTimeError
+mixin_super_2_test/03: MissingCompileTimeError
 mixin_super_bound_test/01: MissingCompileTimeError
 mixin_super_bound_test/02: MissingCompileTimeError
 mixin_super_constructor_named_test/01: MissingCompileTimeError
 mixin_super_constructor_positionals_test/01: MissingCompileTimeError
-mixin_super_test: Crash
-mixin_super_use_test: Crash
-mixin_superclass_test: Crash
-mixin_supertype_subclass2_test/01: Crash
-mixin_supertype_subclass2_test/02: Crash
-mixin_supertype_subclass2_test/03: Crash
-mixin_supertype_subclass2_test/04: Crash
-mixin_supertype_subclass2_test/05: Crash
-mixin_supertype_subclass2_test/none: Crash
-mixin_supertype_subclass3_test/01: Crash
-mixin_supertype_subclass3_test/02: Crash
-mixin_supertype_subclass3_test/03: Crash
-mixin_supertype_subclass3_test/04: Crash
-mixin_supertype_subclass3_test/05: Crash
-mixin_supertype_subclass3_test/none: Crash
-mixin_supertype_subclass4_test/01: Crash
-mixin_supertype_subclass4_test/02: Crash
-mixin_supertype_subclass4_test/03: Crash
-mixin_supertype_subclass4_test/04: Crash
-mixin_supertype_subclass4_test/05: Crash
-mixin_supertype_subclass4_test/none: Crash
-mixin_supertype_subclass_test/01: Crash
-mixin_supertype_subclass_test/02: Crash
-mixin_supertype_subclass_test/03: Crash
-mixin_supertype_subclass_test/04: Crash
-mixin_supertype_subclass_test/05: Crash
-mixin_supertype_subclass_test/none: Crash
+mixin_super_test: RuntimeError
+mixin_super_use_test: RuntimeError
+mixin_supertype_subclass_test/02: MissingCompileTimeError
+mixin_supertype_subclass_test/05: MissingCompileTimeError
 mixin_type_parameters_errors_test/01: MissingCompileTimeError
 mixin_type_parameters_errors_test/02: MissingCompileTimeError
 mixin_type_parameters_errors_test/03: MissingCompileTimeError
 mixin_type_parameters_errors_test/04: MissingCompileTimeError
 mixin_type_parameters_errors_test/05: MissingCompileTimeError
-mixin_with_named_import_test: Crash
 multiline_newline_test/06: MissingCompileTimeError
 multiline_newline_test/06r: MissingCompileTimeError
 named_constructor_test/01: MissingCompileTimeError
@@ -586,8 +530,7 @@
 redirecting_factory_default_values_test/03: MissingCompileTimeError
 redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
 redirecting_factory_malbounded_test/01: MissingCompileTimeError
-regress_22976_test/01: CompileTimeError
-regress_23089_test: Crash
+regress_23089_test: Crash # Crashes in KernelClassBuilder.buildTypeArguments
 regress_23408_test: CompileTimeError # Issue 31533
 regress_25550_test: CompileTimeError
 regress_29025_test: CompileTimeError
@@ -607,13 +550,7 @@
 string_supertype_checked_test: CompileTimeError # Issue 31616
 super_bound_closure_test/none: CompileTimeError # Issue 31533
 super_call4_test: CompileTimeError
-super_from_constructor_test: Crash
 super_getter_setter_test: CompileTimeError
-super_in_async3_test: Crash
-super_in_async4_test: Crash
-super_in_async6_test: Crash
-super_in_constructor_test: RuntimeError
-super_in_finally_test: Crash
 super_no_such_method1_test: CompileTimeError
 super_no_such_method2_test: CompileTimeError
 super_no_such_method3_test: CompileTimeError
@@ -718,13 +655,6 @@
 conditional_import_test: CompileTimeError # Test is broken
 cyclic_type_test/00: RuntimeError # Expect.equals(expected: <Derived>, actual: <dynamic>) fails.
 cyclic_type_test/01: RuntimeError # Expect.equals(at index 0: Expected <Derived<Derived<int>>...>, Found: <dynamic>) fails.
-enum_duplicate_test/01: RuntimeError # NoSuchMethodError: method not found: '<Unexpected Null Value>'
-enum_duplicate_test/02: RuntimeError # NoSuchMethodError: method not found: '<Unexpected Null Value>'
-enum_duplicate_test/none: RuntimeError # NoSuchMethodError: method not found: '<Unexpected Null Value>'
-enum_mirror_test: RuntimeError # Expect.equals(expected: <Foo.BAR>, actual: <null>) fails.
-enum_private_test/01: RuntimeError # NoSuchMethodError: method not found: '<Unexpected Null Value>'
-enum_private_test/none: RuntimeError # NoSuchMethodError: method not found: '<Unexpected Null Value>'
-enum_test: RuntimeError # NoSuchMethodError: method not found: '<Unexpected Null Value>'
 f_bounded_equality_test: RuntimeError # Expect.equals(expected: <dynamic>, actual: <Real>) fails.
 first_class_types_test: RuntimeError # Expect.equals(expected: <List>, actual: <List<int>>) fails.
 forwarding_stub_tearoff_test: RuntimeError
@@ -786,6 +716,13 @@
 type_literal_test: RuntimeError # Expect.equals(expected: <Func>, actual: <(bool) => int>) fails.
 instantiate_tearoff_test: RuntimeError
 
+[ $compiler == dartdevk && $checked ]
+assertion_initializer_const_error2_test/*: MissingCompileTimeError
+assertion_initializer_const_error2_test/none: Pass
+
+[ $compiler == dartdevk && !$checked ]
+assertion_initializer_const_error2_test/*: SkipByDesign # DDC does not support non-checked mode.
+
 # Compiler tests for dartdevc and dartdevk.  These contain common expectations
 # for all runtimes including $runtime == none.  They are organized by: shared
 # expectations for dartdevc and dartdevk, then expectations for dartdevc, and
@@ -999,3 +936,4 @@
 [ $compiler == dartdevk || $compiler == dartdevc && $runtime == none ]
 instantiate_type_variable_test/01: CompileTimeError
 setter_no_getter_call_test/01: CompileTimeError
+
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 5d9d5ee..dfefc92 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -15,6 +15,9 @@
 mock_writable_final_field_test: RuntimeError # Issue 31424
 no_such_method_subtype_test: RuntimeError # Issue 31424
 
+[ $fasta ]
+regress_22976_test/*: CompileTimeError # Issue 31935
+
 [ $compiler == dartk && $mode == debug && $runtime == vm && $strong ]
 bad_named_parameters_test/01: Crash # Issue(http://dartbug.com/31630)
 bad_named_parameters_test/02: Crash # Issue(http://dartbug.com/31630)
@@ -38,7 +41,7 @@
 deferred_load_constants_test/02: Fail
 deferred_load_constants_test/03: Fail
 deferred_load_constants_test/05: Fail
-deferred_not_loaded_check_test: RuntimeError
+deferred_not_loaded_check_test: CompileTimeError
 vm/causal_async_exception_stack2_test: SkipByDesign
 vm/causal_async_exception_stack_test: SkipByDesign
 vm/regress_27201_test: Fail
@@ -83,7 +86,6 @@
 async_star_take_reyield_test: RuntimeError
 asyncstar_yield_test: RuntimeError
 asyncstar_yieldstar_test: RuntimeError
-bug31436_test: RuntimeError
 compile_time_constant_checked_test/02: MissingCompileTimeError
 const_constructor2_test/20: MissingCompileTimeError
 const_constructor2_test/22: MissingCompileTimeError
@@ -327,11 +329,9 @@
 cyclic_typedef_test/11: Crash
 default_factory2_test/01: MissingCompileTimeError
 default_factory_test/01: MissingCompileTimeError
-deferred_call_empty_before_load_test: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
+deferred_call_empty_before_load_test: CompileTimeError # VM doen't support deserializing load-library checks (issue XXX)
 deferred_closurize_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_closurize_load_library_test: DartkCrash
 deferred_constant_list_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_constant_list_test: RuntimeError
 deferred_constraints_constants_test/default_argument2: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
 deferred_constraints_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_constraints_constants_test/reference_after_load: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
@@ -341,35 +341,27 @@
 deferred_constraints_type_annotation_test/static_method: CompileTimeError # Deferred loading kernel issue 28335.
 deferred_constraints_type_annotation_test/type_annotation_non_deferred: CompileTimeError # Deferred loading kernel issue 28335.
 deferred_function_type_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_function_type_test: RuntimeError
 deferred_global_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_import_core_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
 deferred_inheritance_constraints_test/implements: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
 deferred_inheritance_constraints_test/mixin: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError
-deferred_inheritance_constraints_test/redirecting_constructor: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
+deferred_inheritance_constraints_test/redirecting_constructor: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
 deferred_inlined_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_inlined_test: RuntimeError
 deferred_load_constants_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_load_inval_code_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_load_library_wrong_args_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
 deferred_load_library_wrong_args_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_mixin_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_mixin_test: RuntimeError
 deferred_no_such_method_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_not_loaded_check_test: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
+deferred_not_loaded_check_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
 deferred_only_constant_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_only_constant_test: RuntimeError
 deferred_optimized_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_redirecting_factory_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_redirecting_factory_test: RuntimeError
+deferred_redirecting_factory_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_regression_22995_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_regression_28678_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_shadow_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_shadow_load_library_test: RuntimeError
 deferred_shared_and_unshared_classes_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_shared_and_unshared_classes_test: RuntimeError
 deferred_static_seperate_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_super_dependency_test/01: Pass # Passes by mistake. KernelVM bug: Deferred loading kernel issue 28335.
 deferred_type_dependency_test/as: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
@@ -629,7 +621,6 @@
 redirecting_factory_long_test: RuntimeError # Fasta bug: Bad compilation of type arguments for redirecting factory.
 redirecting_factory_malbounded_test/01: MissingCompileTimeError
 regress_22443_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-regress_22976_test/01: CompileTimeError # Issue 31402 (Variable declaration)
 regress_23089_test: Crash
 regress_23408_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 regress_23408_test: RuntimeError
@@ -863,7 +854,6 @@
 async_star_take_reyield_test: RuntimeError
 asyncstar_yield_test: RuntimeError
 asyncstar_yieldstar_test: RuntimeError
-bug31436_test: RuntimeError
 compile_time_constant_checked_test/02: MissingCompileTimeError
 const_constructor2_test/20: MissingCompileTimeError
 const_constructor2_test/22: MissingCompileTimeError
@@ -1149,7 +1139,7 @@
 deep_nesting2_negative_test: Skip # Issue 31158
 default_factory2_test/01: MissingCompileTimeError
 default_factory_test/01: MissingCompileTimeError
-deferred_call_empty_before_load_test: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
+deferred_call_empty_before_load_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
 deferred_closurize_load_library_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_constant_list_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_constraints_constants_test: SkipByDesign
@@ -1176,7 +1166,7 @@
 deferred_load_library_wrong_args_test/none: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_mixin_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_no_such_method_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-deferred_not_loaded_check_test: RuntimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
+deferred_not_loaded_check_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 28335.
 deferred_only_constant_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_optimized_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 deferred_redirecting_factory_test: CompileTimeError, Fail, Crash # Issue 23408, KernelVM bug: Deferred loading kernel issue 28335.
@@ -1498,7 +1488,6 @@
 regress_13462_1_test: SkipByDesign
 regress_18535_test: SkipByDesign
 regress_22443_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
-regress_22976_test/01: CompileTimeError # Issue 31402 (Variable declaration)
 regress_23089_test: Crash
 regress_23408_test: CompileTimeError # KernelVM bug: Deferred loading kernel issue 28335.
 regress_23408_test: RuntimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index 6bedfa3..e6ce2c6 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -393,9 +393,7 @@
 generic_methods_bounds_test/01: MissingCompileTimeError
 generic_methods_bounds_test/02: MissingRuntimeError
 generic_methods_dynamic_test/01: MissingCompileTimeError
-generic_methods_dynamic_test/02: MissingRuntimeError
 generic_methods_dynamic_test/03: MissingCompileTimeError
-generic_methods_dynamic_test/04: MissingRuntimeError
 generic_methods_generic_class_tearoff_test: RuntimeError
 generic_methods_named_parameters_test: RuntimeError
 generic_methods_optional_parameters_test: RuntimeError
@@ -886,6 +884,8 @@
 try_catch_on_syntax_test/11: MissingCompileTimeError
 try_catch_syntax_test/08: MissingCompileTimeError
 type_checks_in_factory_method_test/01: MissingCompileTimeError
+type_inference_accessor_ref_test/03: MissingCompileTimeError
+type_inference_accessor_ref_test/06: MissingCompileTimeError
 type_inference_circularity_test: MissingCompileTimeError
 type_inference_inconsistent_inheritance_test: MissingCompileTimeError
 type_parameter_test/05: MissingCompileTimeError
@@ -1058,6 +1058,8 @@
 function_type_call_getter2_test/none: RuntimeError
 function_type_test: RuntimeError
 generic_field_mixin6_test/none: RuntimeError
+generic_methods_dynamic_test/02: MissingRuntimeError
+generic_methods_dynamic_test/04: MissingRuntimeError
 implicit_downcast_during_assignment_test: RuntimeError
 implicit_downcast_during_combiner_test: RuntimeError
 implicit_downcast_during_compound_assignment_test: RuntimeError
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index 54520a6..291d6f6 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -842,6 +842,8 @@
 try_catch_on_syntax_test/11: MissingCompileTimeError
 try_catch_syntax_test/08: MissingCompileTimeError
 type_checks_in_factory_method_test/01: MissingCompileTimeError
+type_inference_accessor_ref_test/03: MissingCompileTimeError
+type_inference_accessor_ref_test/06: MissingCompileTimeError
 type_inference_circularity_test: MissingCompileTimeError
 type_inference_inconsistent_inheritance_test: MissingCompileTimeError
 type_promotion_functions_test/01: MissingCompileTimeError
diff --git a/tests/language_2/type_inference_accessor_ref_test.dart b/tests/language_2/type_inference_accessor_ref_test.dart
new file mode 100644
index 0000000..cb72da6
--- /dev/null
+++ b/tests/language_2/type_inference_accessor_ref_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*@testedFeatures=inference*/
+library test;
+
+class A {
+  B b;
+}
+
+class B {
+  C get c => null;
+  void set c(C value) {}
+}
+
+class C {}
+
+class D extends C {}
+
+class E extends C {}
+
+// Inferred type: A
+var a = new A();
+
+// Inferred type: C
+var x = a.b.c;
+
+// Inferred type: C
+var y = a.b.c ??= new D();
+
+test() {
+  // Verify the types of x and y by trying to assign to them.
+  x = new C(); //# 01: ok
+  x = new E(); //# 02: ok
+  x = new B(); //# 03: compile-time error
+  y = new C(); //# 04: ok
+  y = new E(); //# 05: ok
+  y = new B(); //# 06: compile-time error
+}
+
+main() {}
diff --git a/tests/language_2/void_type_usage_test.dart b/tests/language_2/void_type_usage_test.dart
index 64a040b..135e8bd 100644
--- a/tests/language_2/void_type_usage_test.dart
+++ b/tests/language_2/void_type_usage_test.dart
@@ -224,6 +224,8 @@
   void get x => null;
   set x(void y) {}
 
+  void foo() {}
+
   void forInTest() {
     for (x in <void>[]) {}  //# instance3_for_in2: compile-time error
     for (x in [1, 2]) {}  //# instance3_for_in3: ok
@@ -344,7 +346,7 @@
 
 void testReturnToVoid(void x, void f()) {
   void y;
-  final void z;
+  final void z = null;
   A<void> a = new A<void>();
   B b = new B();
   C c = new C();
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index bf9e495..f7b811d 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -422,7 +422,7 @@
 mirrors/library_imports_prefixed_test: RuntimeError
 mirrors/library_imports_shown_test: RuntimeError
 mirrors/library_metadata_test: RuntimeError
-mirrors/load_library_test: RuntimeError
+mirrors/load_library_test: CompileTimeError
 mirrors/metadata_allowed_values_test/13: MissingCompileTimeError
 mirrors/metadata_allowed_values_test/14: MissingCompileTimeError
 mirrors/metadata_allowed_values_test/16: Skip # Flaky, crashes.
diff --git a/tests/lib_2/lib_2_dartdevc.status b/tests/lib_2/lib_2_dartdevc.status
index 8d082b1..17f16aa 100644
--- a/tests/lib_2/lib_2_dartdevc.status
+++ b/tests/lib_2/lib_2_dartdevc.status
@@ -19,20 +19,6 @@
 convert/codec1_test: RuntimeError
 convert/utf82_test: RuntimeError
 html/debugger_test: CompileTimeError
-html/js_typed_interop_anonymous2_exp_test: Crash
-html/js_typed_interop_anonymous2_test: RuntimeError
-html/js_typed_interop_anonymous_exp_test: Crash
-html/js_typed_interop_anonymous_test: RuntimeError
-html/js_typed_interop_anonymous_unreachable_exp_test: Crash
-html/js_typed_interop_dynamic_test: RuntimeError
-html/js_typed_interop_lazy_test/01: RuntimeError
-html/js_typed_interop_lazy_test/none: RuntimeError
-html/js_typed_interop_side_cast_exp_test/01: Crash
-html/js_typed_interop_side_cast_exp_test/none: Crash
-html/js_typed_interop_side_cast_test: RuntimeError
-html/js_typed_interop_test: RuntimeError
-html/js_typed_interop_type2_test/01: RuntimeError
-html/js_typed_interop_type2_test/none: RuntimeError
 js/prototype_access_test: RuntimeError
 
 [ $runtime == chrome && ($compiler == dartdevc || $compiler == dartdevk) ]
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index cebcb02..5373ab3 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -135,7 +135,7 @@
 mirrors/library_metadata_test: RuntimeError
 mirrors/list_constructor_test/01: Crash, RuntimeError
 mirrors/list_constructor_test/none: Crash, RuntimeError
-mirrors/load_library_test: Crash, RuntimeError
+mirrors/load_library_test: CompileTimeError
 mirrors/metadata_allowed_values_test/13: MissingCompileTimeError
 mirrors/metadata_allowed_values_test/14: MissingCompileTimeError
 mirrors/metadata_allowed_values_test/16: Skip # Flaky, crashes.
diff --git a/tests/standalone_2/io/wait_for_error_test.dart b/tests/standalone_2/io/wait_for_error_test.dart
new file mode 100644
index 0000000..a3b71c5
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_error_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  asyncStart();
+  Completer<bool> c = new Completer<bool>();
+  Timer.run(() {
+    c.completeError("Error", StackTrace.current);
+    asyncEnd();
+  });
+  Expect.throws(() => waitFor<bool>(c.future), (e) => e is AsyncError);
+}
diff --git a/tests/standalone_2/io/wait_for_event_helper.dart b/tests/standalone_2/io/wait_for_event_helper.dart
new file mode 100644
index 0000000..e79ff13
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_helper.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:mirrors';
+import 'dart:cli';
+
+void Function({Duration timeout}) waitForEvent;
+
+void initWaitForEvent() {
+  LibraryMirror lib = currentMirrorSystem().findLibrary(#dart.cli);
+  for (Symbol s in lib.declarations.keys) {
+    if (s.toString().contains("_WaitForUtils")) {
+      DeclarationMirror d = lib.declarations[s];
+      ClassMirror utils = (d as ClassMirror);
+      for (Symbol m in utils.staticMembers.keys) {
+        if (m.toString().contains("waitForEvent")) {
+          waitForEvent = utils.getField(m).reflectee;
+        }
+      }
+    }
+  }
+}
diff --git a/tests/standalone_2/io/wait_for_event_isolate_test.dart b/tests/standalone_2/io/wait_for_event_isolate_test.dart
new file mode 100644
index 0000000..e051adc
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_isolate_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:isolate';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that waitForEvent() returns on an Isolate message.
+
+messageSender(SendPort s) {
+  new Timer(const Duration(seconds: 1), () {
+    s.send(true);
+  });
+}
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag1 = false;
+  bool flag2 = false;
+  ReceivePort r = new ReceivePort();
+  Isolate.spawn(messageSender, r.sendPort).then((Isolate i) {
+    r.listen((message) {
+      flag1 = true;
+    });
+    Expect.isFalse(flag1);
+    waitForEvent();
+    Expect.isTrue(flag1);
+    r.close();
+    flag2 = true;
+  });
+  Expect.isFalse(flag1);
+  Expect.isFalse(flag2);
+  waitForEvent();
+  Expect.isTrue(flag1);
+  Expect.isTrue(flag2);
+  asyncEnd();
+}
diff --git a/tests/standalone_2/io/wait_for_event_microtask_test.dart b/tests/standalone_2/io/wait_for_event_microtask_test.dart
new file mode 100644
index 0000000..b707265
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_microtask_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that microtasks are run before waitForEvent() blocks.
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag = false;
+  scheduleMicrotask(() {
+    flag = true;
+    asyncEnd();
+  });
+  Expect.isFalse(flag);
+  waitForEvent(timeout: const Duration(milliseconds: 10));
+  Expect.isTrue(flag);
+}
diff --git a/tests/standalone_2/io/wait_for_event_nested_microtask_test.dart b/tests/standalone_2/io/wait_for_event_nested_microtask_test.dart
new file mode 100644
index 0000000..cb11bf9
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_nested_microtask_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that waitForEvent() drains microtasks before blocking even when
+// called from a microtask.
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag1 = false;
+  bool flag2 = false;
+  scheduleMicrotask(() {
+    scheduleMicrotask(() {
+      flag1 = true;
+      asyncEnd();
+    });
+    Expect.isFalse(flag1);
+    waitForEvent(timeout: const Duration(milliseconds: 10));
+    Expect.isTrue(flag1);
+    flag2 = true;
+  });
+  Expect.isFalse(flag1);
+  Expect.isFalse(flag2);
+  waitForEvent(timeout: const Duration(milliseconds: 10));
+  Expect.isTrue(flag1);
+  Expect.isTrue(flag2);
+}
diff --git a/tests/standalone_2/io/wait_for_event_nested_timer_microtask_test.dart b/tests/standalone_2/io/wait_for_event_nested_timer_microtask_test.dart
new file mode 100644
index 0000000..7fbac17
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_nested_timer_microtask_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that the microtasks for a message handler are run before
+// waitForEvent() returns.
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag = false;
+  Timer.run(() {
+    scheduleMicrotask(() {
+      flag = true;
+      asyncEnd();
+    });
+  });
+  Expect.isFalse(flag);
+  waitForEvent();
+  Expect.isTrue(flag);
+}
diff --git a/tests/standalone_2/io/wait_for_event_nested_timer_test.dart b/tests/standalone_2/io/wait_for_event_nested_timer_test.dart
new file mode 100644
index 0000000..6971952
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_nested_timer_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that all messages are processed before waitForEvent() returns.
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag = false;
+  Timer.run(() {
+    Timer.run(() {
+      Timer.run(() {
+        Timer.run(() {
+          flag = true;
+          asyncEnd();
+        });
+      });
+    });
+  });
+  Expect.isFalse(flag);
+  waitForEvent();
+  Expect.isTrue(flag);
+}
diff --git a/tests/standalone_2/io/wait_for_event_nested_waits_test.dart b/tests/standalone_2/io/wait_for_event_nested_waits_test.dart
new file mode 100644
index 0000000..0701996
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_nested_waits_test.dart
@@ -0,0 +1,71 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that waitForEvent() works when called from a message handler.
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag1 = false;
+  bool flag2 = false;
+  bool flag3 = false;
+  bool flag4 = false;
+  Timer.run(() {
+    Timer.run(() {
+      Timer.run(() {
+        Timer.run(() {
+          flag1 = true;
+          asyncEnd();
+        });
+        Expect.isFalse(flag1);
+        Expect.isFalse(flag2);
+        Expect.isFalse(flag3);
+        Expect.isFalse(flag4);
+        waitForEvent();
+        Expect.isTrue(flag1);
+        Expect.isFalse(flag2);
+        Expect.isFalse(flag3);
+        Expect.isFalse(flag4);
+        flag2 = true;
+      });
+      Expect.isFalse(flag1);
+      Expect.isFalse(flag2);
+      Expect.isFalse(flag3);
+      Expect.isFalse(flag4);
+      waitForEvent();
+      Expect.isTrue(flag1);
+      Expect.isTrue(flag2);
+      Expect.isFalse(flag3);
+      Expect.isFalse(flag4);
+      flag3 = true;
+    });
+    Expect.isFalse(flag1);
+    Expect.isFalse(flag2);
+    Expect.isFalse(flag3);
+    Expect.isFalse(flag4);
+    waitForEvent();
+    Expect.isTrue(flag1);
+    Expect.isTrue(flag2);
+    Expect.isTrue(flag3);
+    Expect.isFalse(flag4);
+    flag4 = true;
+  });
+  Expect.isFalse(flag1);
+  Expect.isFalse(flag2);
+  Expect.isFalse(flag3);
+  Expect.isFalse(flag4);
+  waitForEvent();
+  Expect.isTrue(flag1);
+  Expect.isTrue(flag2);
+  Expect.isTrue(flag3);
+  Expect.isTrue(flag4);
+}
diff --git a/tests/standalone_2/io/wait_for_event_timer_test.dart b/tests/standalone_2/io/wait_for_event_timer_test.dart
new file mode 100644
index 0000000..5ce0a64
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_timer_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that waitForEvent() works in a simple case.
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag = false;
+  Timer.run(() {
+    flag = true;
+    asyncEnd();
+  });
+  Expect.isFalse(flag);
+  waitForEvent();
+  Expect.isTrue(flag);
+}
diff --git a/tests/standalone_2/io/wait_for_event_zone_caught_error_test.dart b/tests/standalone_2/io/wait_for_event_zone_caught_error_test.dart
new file mode 100644
index 0000000..09e60c4
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_zone_caught_error_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that waitForEvent() doesn't cause an error to escape a Zone that
+// has an error handler.
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag = false;
+  runZoned(() {
+    Timer.run(() {
+      asyncEnd();
+      throw "Exception";
+    });
+  }, onError: (e) {
+    flag = true;
+  });
+  Expect.isFalse(flag);
+  waitForEvent();
+  Expect.isTrue(flag);
+}
diff --git a/tests/standalone_2/io/wait_for_event_zone_test.dart b/tests/standalone_2/io/wait_for_event_zone_test.dart
new file mode 100644
index 0000000..b6a7825
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_event_zone_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'wait_for_event_helper.dart';
+
+// Tests that waitForEvent() works even when the message handler is run in
+// a different Zone.
+
+main() {
+  initWaitForEvent();
+  asyncStart();
+  bool flag = false;
+  runZoned(() {
+    Timer.run(() {
+      flag = true;
+      asyncEnd();
+    });
+  });
+  Expect.isFalse(flag);
+  waitForEvent();
+  Expect.isTrue(flag);
+}
diff --git a/tests/standalone_2/io/wait_for_exception_test.dart b/tests/standalone_2/io/wait_for_exception_test.dart
new file mode 100644
index 0000000..f5c207d
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_exception_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  asyncStart();
+  Completer<bool> c = new Completer<bool>();
+  runZoned(() {
+    Timer.run(() {
+      asyncEnd();
+      throw "Error";
+    });
+  }, onError: (e) {
+    Expect.isTrue(e is String);
+    c.complete(true);
+  });
+  Expect.isTrue(waitFor<bool>(c.future));
+}
diff --git a/tests/standalone_2/io/wait_for_test.dart b/tests/standalone_2/io/wait_for_test.dart
new file mode 100644
index 0000000..a8ac543
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:mirrors';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  asyncStart();
+  Completer<bool> c = new Completer<bool>();
+  Timer.run(() {
+    c.complete(true);
+    asyncEnd();
+  });
+  bool result = waitFor<bool>(c.future);
+  Expect.isTrue(result);
+}
diff --git a/tests/standalone_2/io/wait_for_timeout_test.dart b/tests/standalone_2/io/wait_for_timeout_test.dart
new file mode 100644
index 0000000..2b239fa
--- /dev/null
+++ b/tests/standalone_2/io/wait_for_timeout_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:cli';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+main() {
+  asyncStart();
+  Completer<bool> c = new Completer<bool>();
+  Expect.throws(() {
+    waitFor<bool>(c.future, timeout: const Duration(seconds: 1));
+  }, (e) => e is TimeoutException);
+  asyncEnd();
+}
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index 924b2f6..8bde01d 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -51,6 +51,16 @@
 [ $runtime == dart_precompiled ]
 http_launch_test: Skip
 io/addlatexhash_test: Skip
+io/wait_for_event_isolate_test: SkipByDesign # Uses mirrors.
+io/wait_for_event_microtask_test: SkipByDesign # Uses mirrors.
+io/wait_for_event_nested_microtask_test: SkipByDesign # Uses mirrors.
+io/wait_for_event_nested_timer_microtask_test: SkipByDesign # Uses mirrors.
+io/wait_for_event_nested_timer_test: SkipByDesign # Uses mirrors.
+io/wait_for_event_nested_waits_test: SkipByDesign # Uses mirrors.
+io/wait_for_event_timer_test: SkipByDesign # Uses mirrors.
+io/wait_for_event_zone_caught_error_test: SkipByDesign # Uses mirrors.
+io/wait_for_event_zone_test: SkipByDesign # Uses mirrors.
+io/wait_for_test: SkipByDesign # Uses mirrors.
 
 [ !$strong ]
 float_array_static_test: MissingCompileTimeError
diff --git a/tools/VERSION b/tools/VERSION
index f7edf31..82c9caf 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 0
 PATCH 0
-PRERELEASE 18
+PRERELEASE 19
 PRERELEASE_PATCH 0