Version 2.0.0-dev.44.0

Merge commit '374058aa794db4114fd1fdf08456c5a01de70a7c' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d4faca9..1006db6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,14 @@
+## 2.0.0-dev.44.0
+
+### Tool Changes
+
+#### Pub
+
+* Pub has a brand new version solver! It supports all the same features as the
+  old version solver, but it's much less likely to stall out on difficult
+  package graphs, and it's much clearer about why a solution can't be found when
+  version solving fails.
+
 ## 2.0.0-dev.43.0
 
 ## 2.0.0-dev.42.0
@@ -7,6 +18,16 @@
 * `dart:collection`
   * Removed `Maps` class. Extend `MapBase` or mix in `MapMixin` instead to
     provide map method implementations for a class.
+* `dart:html`
+  * Removed deprecated `query` and `queryAll` use `querySelector` and `queryAllSelector`.
+  * Removed experimental `Document` method `getCSSCanvasContext` and property
+    `supportsCssCanvasContext`.
+  * Removed obsolete `Element` property `xtag` no longer supported in browsers.
+  * Exposed `ServiceWorker` class.
+  * Added constructor to `MessageChannel` and `MessagePort` `addEventListener` automatically calls
+    `start` method to receive queued messages.
+* `dart:io`
+  * Added `IOOverrides.socketConnect`.
 
 ### Tool Changes
 
diff --git a/DEPS b/DEPS
index ac24008..3ab4931 100644
--- a/DEPS
+++ b/DEPS
@@ -84,7 +84,7 @@
   # For more details, see https://github.com/dart-lang/sdk/issues/30164
   "dart_style_tag": "@1.0.10",  # Please see the note above before updating.
 
-  "dartdoc_tag" : "@v0.18.0",
+  "dartdoc_tag" : "@v0.18.1",
   "fixnum_tag": "@0.10.5",
   "func_rev": "@25eec48146a58967d75330075ab376b3838b18a8",
   "glob_tag": "@1.1.5",
@@ -108,7 +108,7 @@
   "mockito_tag": "@a92db054fba18bc2d605be7670aee74b7cadc00a",
   "mustache4dart_tag" : "@v2.1.0",
   "oauth2_tag": "@1.1.0",
-  "observatory_pub_packages_rev": "@4c282bb240b68f407c8c7779a65c68eeb0139dc6",
+  "observatory_pub_packages_rev": "@d3a3aebefbd35aa30fe7bbc2889b772b398f7d7f",
   "package_config_tag": "@1.0.3",
   "package_resolver_tag": "@1.0.2+1",
   "path_tag": "@1.5.1",
@@ -116,8 +116,8 @@
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "@1.3.4",
   "protobuf_tag": "@0.7.1",
-  "pub_rev": "@875d35005a7d33f367d70a3e31e9d3bad5d1ebd8",
-  "pub_semver_tag": "@1.3.2",
+  "pub_rev": "@4947e0b3cb3ec77e4e8fe0d3141ce4dc60f43256",
+  "pub_semver_tag": "@1.3.3",
   "quiver_tag": "@5aaa3f58c48608af5b027444d561270b53f15dbf",
   "resource_rev":"@af5a5bf65511943398146cf146e466e5f0b95cb9",
   "root_certificates_rev": "@16ef64be64c7dfdff2b9f4b910726e635ccc519e",
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index c6a313e..e050dc0 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -4797,7 +4797,7 @@
         
         <p>
           The offset to the beginning of the name selected to be
-          renamed.
+          renamed, or -1 if the name does not exist yet.
         </p>
       </dd><dt class="field"><b>length: int</b></dt><dd>
         
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index 6bcff1b..4fffb99 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -14330,12 +14330,14 @@
   String _oldName;
 
   /**
-   * The offset to the beginning of the name selected to be renamed.
+   * The offset to the beginning of the name selected to be renamed, or -1 if
+   * the name does not exist yet.
    */
   int get offset => _offset;
 
   /**
-   * The offset to the beginning of the name selected to be renamed.
+   * The offset to the beginning of the name selected to be renamed, or -1 if
+   * the name does not exist yet.
    */
   void set offset(int value) {
     assert(value != null);
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index d38ee8b..64878c1 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -939,20 +939,44 @@
       AstNode node = await server.getNodeAtOffset(file, offset);
       Element element = server.getElementOfNode(node);
       if (node != null && element != null) {
+        int feedbackOffset = node.offset;
+        int feedbackLength = node.length;
+
         if (element is FieldFormalParameterElement) {
           element = (element as FieldFormalParameterElement).field;
         }
-        // climb from "Class" in "new Class.named()" to "Class.named"
-        if (node.parent is TypeName && node.parent.parent is ConstructorName) {
-          ConstructorName constructor = node.parent.parent;
-          node = constructor;
-          element = constructor.staticElement;
+
+        // Use the prefix offset/length when renaming an import directive.
+        if (node is ImportDirective && element is ImportElement) {
+          if (node.prefix != null) {
+            feedbackOffset = node.prefix.offset;
+            feedbackLength = node.prefix.length;
+          } else {
+            feedbackOffset = -1;
+            feedbackLength = 0;
+          }
         }
+
+        // Canonicalize to ConstructorName.
+        var constructorName = _canonicalizeToConstructorName(node);
+        if (constructorName != null) {
+          node = constructorName;
+          element = constructorName.staticElement;
+          // Use the constructor name offset/length.
+          if (constructorName.name != null) {
+            feedbackOffset = constructorName.name.offset;
+            feedbackLength = constructorName.name.length;
+          } else {
+            feedbackOffset = -1;
+            feedbackLength = 0;
+          }
+        }
+
         // do create the refactoring
         refactoring = new RenameRefactoring(
             searchEngine, server.getAstProvider(file), element);
-        feedback =
-            new RenameFeedback(node.offset, node.length, 'kind', 'oldName');
+        feedback = new RenameFeedback(
+            feedbackOffset, feedbackLength, 'kind', 'oldName');
       }
     }
     if (refactoring == null) {
@@ -1087,6 +1111,32 @@
     }
     return new RefactoringStatus();
   }
+
+  /**
+   * If the [node] is a constructor reference, return the corresponding
+   * [ConstructorName], or `null` otherwise.
+   */
+  static ConstructorName _canonicalizeToConstructorName(AstNode node) {
+    var parent = node.parent;
+    var parent2 = parent?.parent;
+
+    // "named" in "Class.named".
+    if (parent is ConstructorName) {
+      return parent;
+    }
+
+    // "Class" in "Class.named".
+    if (parent is TypeName && parent2 is ConstructorName) {
+      return parent2;
+    }
+
+    // Canonicalize "new Class.named()" to "Class.named".
+    if (node is InstanceCreationExpression) {
+      return node.constructorName;
+    }
+
+    return null;
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
index 89fbbc3..cde471e 100644
--- a/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
+++ b/pkg/analysis_server/lib/src/plugin/plugin_manager.dart
@@ -690,7 +690,8 @@
         ProcessResult result = Process.runSync(pubPath, <String>['get'],
             stderrEncoding: utf8,
             stdoutEncoding: utf8,
-            workingDirectory: pluginFolder.path);
+            workingDirectory: pluginFolder.path,
+            environment: {_pubEnvironmentKey: _getPubEnvironmentValue()});
         if (result.exitCode != 0) {
           StringBuffer buffer = new StringBuffer();
           buffer.writeln('Failed to run pub get');
@@ -829,6 +830,33 @@
         .putIfAbsent(method, () => <int>[])
         .add(time);
   }
+
+  /**
+   * The console environment key used by the pub tool.
+   */
+  static const String _pubEnvironmentKey = 'PUB_ENVIRONMENT';
+
+  /**
+   * Returns the environment value that should be used when running pub.
+   *
+   * Includes any existing environment value, if one exists.
+   */
+  static String _getPubEnvironmentValue() {
+    // DO NOT update this function without contacting kevmoo.
+    // We have server-side tooling that assumes the values are consistent.
+    var values = <String>[];
+
+    var existing = Platform.environment[_pubEnvironmentKey];
+
+    // If there is an existing value for this var, make sure to include it.
+    if ((existing != null) && existing.isNotEmpty) {
+      values.add(existing);
+    }
+
+    values.add('analysis_server.plugin_manager');
+
+    return values.join(':');
+  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
index 315b49c..63d624c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
@@ -6,6 +6,7 @@
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
+import 'package:analysis_server/src/utilities/flutter.dart' as flutter;
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -81,16 +82,17 @@
         skipChildClass: skipChildClass);
   }
 
-  _addSuggestionsForType(InterfaceType type, OpType optype,
+  _addSuggestionsForType(InterfaceType type, DartCompletionRequest request,
       {bool isFunctionalArgument: false}) {
+    OpType opType = request.opType;
     if (!isFunctionalArgument) {
       for (PropertyAccessorElement elem in type.accessors) {
         if (elem.isGetter) {
-          if (optype.includeReturnValueSuggestions) {
+          if (opType.includeReturnValueSuggestions) {
             addSuggestion(elem);
           }
         } else {
-          if (optype.includeVoidReturnSuggestions) {
+          if (opType.includeVoidReturnSuggestions) {
             addSuggestion(elem);
           }
         }
@@ -100,12 +102,13 @@
       if (elem.returnType == null) {
         addSuggestion(elem);
       } else if (!elem.returnType.isVoid) {
-        if (optype.includeReturnValueSuggestions) {
+        if (opType.includeReturnValueSuggestions) {
           addSuggestion(elem);
         }
       } else {
-        if (optype.includeVoidReturnSuggestions) {
-          addSuggestion(elem);
+        if (opType.includeVoidReturnSuggestions) {
+          CompletionSuggestion suggestion = addSuggestion(elem);
+          _updateFlutterSuggestions(request, elem, suggestion);
         }
       }
     }
@@ -118,17 +121,58 @@
     kind = isFunctionalArgument
         ? CompletionSuggestionKind.IDENTIFIER
         : CompletionSuggestionKind.INVOCATION;
-    OpType optype = request.opType;
-
     if (!skipChildClass) {
-      _addSuggestionsForType(classElement.type, optype,
+      _addSuggestionsForType(classElement.type, request,
           isFunctionalArgument: isFunctionalArgument);
     }
 
     for (InterfaceType type in classElement.allSupertypes) {
-      _addSuggestionsForType(type, optype,
+      _addSuggestionsForType(type, request,
           isFunctionalArgument: isFunctionalArgument);
     }
     return suggestions;
   }
+
+  void _updateFlutterSuggestions(DartCompletionRequest request, Element element,
+      CompletionSuggestion suggestion) {
+    if (suggestion == null) {
+      return;
+    }
+    if (element is MethodElement &&
+        element.name == 'setState' &&
+        flutter.isExactState(element.enclosingElement)) {
+      // Find the line indentation.
+      String content = request.result.content;
+      int lineStartOffset = request.offset;
+      int notWhitespaceOffset = request.offset;
+      for (; lineStartOffset > 0; lineStartOffset--) {
+        var char = content.substring(lineStartOffset - 1, lineStartOffset);
+        if (char == '\n') {
+          break;
+        }
+        if (char != ' ' && char != '\t') {
+          notWhitespaceOffset = lineStartOffset - 1;
+        }
+      }
+      String indent = content.substring(lineStartOffset, notWhitespaceOffset);
+
+      // Let the user know that we are going to insert a complete statement.
+      suggestion.displayText = 'setState(() {});';
+
+      // Build the completion and the selection offset.
+      var buffer = new StringBuffer();
+      buffer.writeln('setState(() {');
+      buffer.write('$indent  ');
+      suggestion.selectionOffset = buffer.length;
+      buffer.writeln();
+      buffer.write('$indent});');
+      suggestion.completion = buffer.toString();
+
+      // There are no arguments to fill.
+      suggestion.parameterNames = null;
+      suggestion.parameterTypes = null;
+      suggestion.requiredParameterCount = null;
+      suggestion.hasNamedParameters = null;
+    }
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 5442592..baef690 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -72,9 +72,9 @@
     }
     if (entity == node.rightParenthesis) {
       _addExpressionKeywords(node);
-      Token previous = (entity as Token).previous;
+      Token previous = node.findPrevious(entity as Token);
       if (previous.isSynthetic) {
-        previous = previous.previous;
+        previous = node.findPrevious(previous);
       }
       if (previous.lexeme == ')') {
         _addSuggestion(Keyword.ASYNC);
@@ -129,9 +129,9 @@
       Expression expression = (entity as ExpressionStatement).expression;
       if (expression is SimpleIdentifier) {
         Token token = expression.token;
-        Token previous = token.previous;
+        Token previous = node.findPrevious(token);
         if (previous.isSynthetic) {
-          previous = previous.previous;
+          previous = node.findPrevious(previous);
         }
         Token next = token.next;
         if (next.isSynthetic) {
@@ -283,9 +283,9 @@
   @override
   visitForEachStatement(ForEachStatement node) {
     if (entity == node.inKeyword) {
-      Token previous = node.inKeyword.previous;
+      Token previous = node.findPrevious(node.inKeyword);
       if (previous is SyntheticStringToken && previous.lexeme == 'in') {
-        previous = previous.previous;
+        previous = node.findPrevious(previous);
       }
       if (previous != null && previous.type == TokenType.EQ) {
         _addSuggestions([
@@ -757,7 +757,7 @@
   static bool _isPreviousTokenSynthetic(Object entity, TokenType type) {
     if (entity is AstNode) {
       Token token = entity.beginToken;
-      Token previousToken = token.previous;
+      Token previousToken = entity.findPrevious(token);
       return previousToken.isSynthetic && previousToken.type == type;
     }
     return false;
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
index 23248e4..909345c 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/suggestion_builder.dart
@@ -144,13 +144,13 @@
   /**
    * Add a suggestion based upon the given element.
    */
-  void addSuggestion(Element element,
+  CompletionSuggestion addSuggestion(Element element,
       {String prefix,
       int relevance: DART_RELEVANCE_DEFAULT,
       String elementCompletion}) {
     if (element.isPrivate) {
       if (element.library != containingLibrary) {
-        return;
+        return null;
       }
     }
     String completion = elementCompletion ?? element.displayName;
@@ -162,7 +162,7 @@
       }
     }
     if (completion == null || completion.length <= 0) {
-      return;
+      return null;
     }
     CompletionSuggestion suggestion = createSuggestion(element,
         completion: completion, kind: kind, relevance: relevance);
@@ -195,7 +195,7 @@
                 typeParameters: getter.element.typeParameters,
                 parameters: null,
                 returnType: getter.returnType);
-            return;
+            return existingSuggestion;
           }
 
           // Cache lone getter/setter so that it can be paired
@@ -206,6 +206,7 @@
         suggestions.add(suggestion);
       }
     }
+    return suggestion;
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index a2bfe33..051a72d 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -141,8 +141,6 @@
       const FixKind('CREATE_LOCAL_VARIABLE', 50, "Create local variable '{0}'");
   static const CREATE_METHOD =
       const FixKind('CREATE_METHOD', 50, "Create method '{0}'");
-  static const CREATE_MISSING_METHOD_CALL =
-      const FixKind('CREATE_MISSING_METHOD_CALL', 49, "Create method 'call'.");
   static const CREATE_MISSING_OVERRIDES = const FixKind(
       'CREATE_MISSING_OVERRIDES', 49, "Create {0} missing override(s)");
   static const CREATE_NO_SUCH_METHOD = const FixKind(
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index bb4a3b3..f7d3540 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -27,6 +27,7 @@
 import 'package:analyzer/exception/exception.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/session_helper.dart';
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
@@ -107,6 +108,16 @@
    */
   AnalysisDriver driver;
 
+  /**
+   * The analysis session to be used to create the change builder.
+   */
+  AnalysisSession session;
+
+  /**
+   * The helper wrapper around the [session].
+   */
+  AnalysisSessionHelper sessionHelper;
+
   String file;
   CompilationUnitElement unitElement;
   Source unitSource;
@@ -131,7 +142,11 @@
     resourceProvider = dartContext.resourceProvider;
     astProvider = dartContext.astProvider;
     getTopLevelDeclarations = dartContext.getTopLevelDeclarations;
+
     driver = dartContext.analysisDriver;
+    session = driver.currentSession;
+    sessionHelper = new AnalysisSessionHelper(session);
+
     // unit
     unit = dartContext.unit;
     unitElement = unit.element;
@@ -154,11 +169,6 @@
    */
   String get eol => utils.endOfLine;
 
-  /**
-   * Return the analysis session to be used to create the change builder.
-   */
-  AnalysisSession get session => driver.currentSession;
-
   TypeProvider get typeProvider {
     if (_typeProvider == null) {
       _typeProvider = unitElement.context.typeProvider;
@@ -297,9 +307,6 @@
         errorCode == HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS) {
       await _addFix_addMissingRequiredArgument();
     }
-    if (errorCode == StaticWarningCode.FUNCTION_WITHOUT_CALL) {
-      await _addFix_addMissingMethodCall();
-    }
     if (errorCode == StaticWarningCode.NEW_WITH_UNDEFINED_CONSTRUCTOR) {
       await _addFix_createConstructor_named();
     }
@@ -600,32 +607,6 @@
     }
   }
 
-  Future<Null> _addFix_addMissingMethodCall() async {
-    ClassDeclaration targetClass = node.parent as ClassDeclaration;
-    int insertOffset = targetClass.end - 1;
-    // prepare environment
-    String prefix = utils.getIndent(1);
-    String prefix2 = utils.getIndent(2);
-    DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addInsertion(insertOffset, (DartEditBuilder builder) {
-        builder.selectHere();
-        builder.write(prefix);
-        builder.write('call() {');
-        // TO-DO
-        builder.write(eol);
-        builder.write(prefix2);
-        builder.write('// TODO: implement call');
-        builder.write(eol);
-        // close method
-        builder.write(prefix);
-        builder.write('}');
-        builder.write(eol);
-      });
-    });
-    _addFixFromBuilder(changeBuilder, DartFixKind.CREATE_MISSING_METHOD_CALL);
-  }
-
   Future<Null> _addFix_addMissingParameter() async {
     if (node is ArgumentList && node.parent is MethodInvocation) {
       ArgumentList argumentList = node;
@@ -1110,11 +1091,15 @@
     if (node is! SimpleIdentifier || node.parent is! VariableDeclaration) {
       return;
     }
+
     ClassDeclaration classDeclaration =
         node.getAncestor((node) => node is ClassDeclaration);
     if (classDeclaration == null) {
       return;
     }
+    String className = classDeclaration.name.name;
+    InterfaceType superType = classDeclaration.element.supertype;
+
     // prepare names of uninitialized final fields
     List<String> fieldNames = <String>[];
     for (ClassMember member in classDeclaration.members) {
@@ -1130,15 +1115,50 @@
     // prepare location for a new constructor
     ClassMemberLocation targetLocation =
         utils.prepareNewConstructorLocation(classDeclaration);
+
     DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
-    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
-        builder.write(targetLocation.prefix);
-        builder.writeConstructorDeclaration(classDeclaration.name.name,
-            fieldNames: fieldNames);
-        builder.write(targetLocation.suffix);
+    if (flutter.isExactlyStatelessWidgetType(superType) ||
+        flutter.isExactlyStatefulWidgetType(superType)) {
+      // Specialize for Flutter widgets.
+      ClassElement keyClass =
+          await sessionHelper.getClass(flutter.WIDGETS_LIBRARY_URI, 'Key');
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
+          builder.write(targetLocation.prefix);
+          builder.write('const ');
+          builder.write(className);
+          builder.write('({');
+          builder.writeType(keyClass.type);
+          builder.write(' key');
+
+          List<String> childrenFields = [];
+          for (String fieldName in fieldNames) {
+            if (fieldName == 'child' || fieldName == 'children') {
+              childrenFields.add(fieldName);
+              continue;
+            }
+            builder.write(', this.');
+            builder.write(fieldName);
+          }
+          for (String fieldName in childrenFields) {
+            builder.write(', this.');
+            builder.write(fieldName);
+          }
+
+          builder.write('}) : super(key: key);');
+          builder.write(targetLocation.suffix);
+        });
       });
-    });
+    } else {
+      await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+        builder.addInsertion(targetLocation.offset, (DartEditBuilder builder) {
+          builder.write(targetLocation.prefix);
+          builder.writeConstructorDeclaration(className,
+              fieldNames: fieldNames);
+          builder.write(targetLocation.suffix);
+        });
+      });
+    }
     _addFixFromBuilder(
         changeBuilder, DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS);
   }
@@ -2965,22 +2985,44 @@
       return;
     }
     ConstructorDeclaration constructor = node.parent;
-    // add these fields
+    List<FormalParameter> parameters = constructor.parameters.parameters;
+
+    ClassDeclaration classNode = constructor.parent;
+    InterfaceType superType = classNode.element.supertype;
+
+    // Compute uninitialized final fields.
     List<FieldElement> fields =
         ErrorVerifier.computeNotInitializedFields(constructor);
     fields.retainWhere((FieldElement field) => field.isFinal);
-    // prepare new parameters code
+
+    // Prepare new parameters code.
     fields.sort((a, b) => a.nameOffset - b.nameOffset);
     String fieldParametersCode =
         fields.map((field) => 'this.${field.name}').join(', ');
-    // prepare the last required parameter
+
+    // Specialize for Flutter widgets.
+    if (flutter.isExactlyStatelessWidgetType(superType) ||
+        flutter.isExactlyStatefulWidgetType(superType)) {
+      if (parameters.isNotEmpty && parameters.last.isNamed) {
+        DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
+        await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+          builder.addSimpleInsertion(
+              parameters.last.end, ', $fieldParametersCode');
+        });
+        _addFixFromBuilder(
+            changeBuilder, DartFixKind.ADD_FIELD_FORMAL_PARAMETERS);
+        return;
+      }
+    }
+
+    // Prepare the last required parameter.
     FormalParameter lastRequiredParameter;
-    List<FormalParameter> parameters = constructor.parameters.parameters;
     for (FormalParameter parameter in parameters) {
       if (parameter.isRequired) {
         lastRequiredParameter = parameter;
       }
     }
+
     DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
     await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
       // append new field formal initializers
diff --git a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
index 83a673c..79e14d0 100644
--- a/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
+++ b/pkg/analysis_server/lib/src/services/correction/organize_directives.dart
@@ -19,13 +19,18 @@
   final List<AnalysisError> errors;
   final bool removeUnresolved;
   final bool removeUnused;
+
   String code;
   String endOfLine;
+  bool hasUnresolvedIdentifierError;
 
   DirectiveOrganizer(this.initialCode, this.unit, this.errors,
       {this.removeUnresolved: true, this.removeUnused: true}) {
     this.code = initialCode;
     this.endOfLine = getEOL(code);
+    this.hasUnresolvedIdentifierError = errors.any((error) {
+      return error.errorCode.isUnresolvedIdentifier;
+    });
   }
 
   /**
@@ -68,7 +73,7 @@
   }
 
   /**
-   * Oraganize all [Directive]s.
+   * Organize all [Directive]s.
    */
   void _organizeDirectives() {
     List<_DirectiveInfo> directives = [];
@@ -99,11 +104,14 @@
       StringBuffer sb = new StringBuffer();
       _DirectivePriority currentPriority = null;
       for (_DirectiveInfo directiveInfo in directives) {
-        if (removeUnresolved && _isUnresolvedUri(directiveInfo.directive)) {
-          continue;
-        }
-        if (removeUnused && _isUnusedImport(directiveInfo.directive)) {
-          continue;
+        if (!hasUnresolvedIdentifierError) {
+          UriBasedDirective directive = directiveInfo.directive;
+          if (removeUnresolved && _isUnresolvedUri(directive)) {
+            continue;
+          }
+          if (removeUnused && _isUnusedImport(directive)) {
+            continue;
+          }
         }
         if (currentPriority != directiveInfo.priority) {
           if (sb.length != 0) {
diff --git a/pkg/analysis_server/lib/src/utilities/flutter.dart b/pkg/analysis_server/lib/src/utilities/flutter.dart
index b5c82f1..bb06c05 100644
--- a/pkg/analysis_server/lib/src/utilities/flutter.dart
+++ b/pkg/analysis_server/lib/src/utilities/flutter.dart
@@ -259,6 +259,11 @@
       _isExactWidget(type.element, _STATELESS_WIDGET_NAME, _WIDGET_URI);
 }
 
+/// Return `true` if the given [element] is the Flutter class `State`.
+bool isExactState(ClassElement element) {
+  return _isExactWidget(element, _STATE_NAME, _WIDGET_URI);
+}
+
 /**
  * Return `true` if the given [type] is the Flutter class `Center`.
  */
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index fb7caed..29f95af 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -1562,16 +1562,24 @@
   B() {}
 }
 ''');
-    return assertSuccessfulRefactoring(() {
-      return sendRenameRequest('B;', 'newName');
-    }, '''
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('B;', 'newName');
+      },
+      '''
 class A {
   A() = B.newName;
 }
 class B {
   B.newName() {}
 }
-''');
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, -1);
+        expect(renameFeedback.length, 0);
+      },
+    );
   }
 
   test_constructor_fromInstanceCreation() {
@@ -1583,16 +1591,24 @@
   new A.test();
 }
 ''');
-    return assertSuccessfulRefactoring(() {
-      return sendRenameRequest('test();', 'newName');
-    }, '''
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('test();', 'newName');
+      },
+      '''
 class A {
   A.newName() {}
 }
 main() {
   new A.newName();
 }
-''');
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, 43);
+        expect(renameFeedback.length, 4);
+      },
+    );
   }
 
   test_constructor_fromInstanceCreation_default_onClassName() {
@@ -1604,16 +1620,24 @@
   new A();
 }
 ''');
-    return assertSuccessfulRefactoring(() {
-      return sendRenameRequest('A();', 'newName');
-    }, '''
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('A();', 'newName');
+      },
+      '''
 class A {
   A.newName() {}
 }
 main() {
   new A.newName();
 }
-''');
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, -1);
+        expect(renameFeedback.length, 0);
+      },
+    );
   }
 
   test_constructor_fromInstanceCreation_default_onNew() {
@@ -1625,16 +1649,24 @@
   new A();
 }
 ''');
-    return assertSuccessfulRefactoring(() {
-      return sendRenameRequest('new A();', 'newName');
-    }, '''
+    return assertSuccessfulRefactoring(
+      () {
+        return sendRenameRequest('new A();', 'newName');
+      },
+      '''
 class A {
   A.newName() {}
 }
 main() {
   new A.newName();
 }
-''');
+''',
+      feedbackValidator: (feedback) {
+        RenameFeedback renameFeedback = feedback;
+        expect(renameFeedback.offset, -1);
+        expect(renameFeedback.length, 0);
+      },
+    );
   }
 
   test_feedback() {
@@ -1682,16 +1714,23 @@
   Future f;
 }
 ''');
-    return assertSuccessfulRefactoring(() {
-      return sendRenameRequest("import 'dart:async';", 'new_name');
-    }, '''
+    return assertSuccessfulRefactoring(
+        () {
+          return sendRenameRequest("import 'dart:async';", 'new_name');
+        },
+        '''
 import 'dart:math';
 import 'dart:async' as new_name;
 main() {
   Random r;
   new_name.Future f;
 }
-''');
+''',
+        feedbackValidator: (feedback) {
+          RenameFeedback renameFeedback = feedback;
+          expect(renameFeedback.offset, -1);
+          expect(renameFeedback.length, 0);
+        });
   }
 
   test_importPrefix_remove() {
@@ -1703,16 +1742,23 @@
   test.Future f;
 }
 ''');
-    return assertSuccessfulRefactoring(() {
-      return sendRenameRequest("import 'dart:async' as test;", '');
-    }, '''
+    return assertSuccessfulRefactoring(
+        () {
+          return sendRenameRequest("import 'dart:async' as test;", '');
+        },
+        '''
 import 'dart:math' as test;
 import 'dart:async';
 main() {
   test.Random r;
   Future f;
 }
-''');
+''',
+        feedbackValidator: (feedback) {
+          RenameFeedback renameFeedback = feedback;
+          expect(renameFeedback.offset, 51);
+          expect(renameFeedback.length, 4);
+        });
   }
 
   test_init_fatalError_noElement() {
@@ -1970,9 +2016,13 @@
   }
 
   Future assertSuccessfulRefactoring(
-      Future<Response> requestSender(), String expectedCode) async {
+      Future<Response> requestSender(), String expectedCode,
+      {void Function(RefactoringFeedback) feedbackValidator}) async {
     EditGetRefactoringResult result = await getRefactoringResult(requestSender);
     assertResultProblemsOK(result);
+    if (feedbackValidator != null) {
+      feedbackValidator(result.feedback);
+    }
     assertTestRefactoringResult(result, expectedCode);
   }
 
diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
index bd52c9e..be6cb0a 100644
--- a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
@@ -1,6 +1,7 @@
 // Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
+import 'dart:async';
 
 import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
@@ -125,6 +126,42 @@
     assertSuggestMethod('m2', 'M', 'int');
   }
 
+  test_flutter_setState_hasPrefix() async {
+    var spaces_4 = ' ' * 4;
+    var spaces_6 = ' ' * 6;
+    await _check_flutter_setState(
+        '    setSt',
+        '''
+setState(() {
+$spaces_6
+$spaces_4});''',
+        20);
+  }
+
+  test_flutter_setState_longPrefix() async {
+    var spaces_6 = ' ' * 6;
+    var spaces_8 = ' ' * 8;
+    await _check_flutter_setState(
+        '      setSt',
+        '''
+setState(() {
+$spaces_8
+$spaces_6});''',
+        22);
+  }
+
+  test_flutter_setState_noPrefix() async {
+    var spaces_4 = ' ' * 4;
+    var spaces_6 = ' ' * 6;
+    await _check_flutter_setState(
+        '    ',
+        '''
+setState(() {
+$spaces_6
+$spaces_4});''',
+        20);
+  }
+
   test_inherited() async {
     resolveSource('/testB.dart', '''
 lib libB;
@@ -604,4 +641,37 @@
     assertNotSuggested('x2');
     assertNotSuggested('y2');
   }
+
+  Future<void> _check_flutter_setState(
+      String line, String completion, int selectionOffset) async {
+    addFlutterPackage();
+    addTestSource('''
+import 'package:flutter/widgets.dart';
+
+class TestWidget extends StatefulWidget {
+  @override
+  TestWidgetState createState() {
+    return new TestWidgetState();
+  }
+}
+
+class TestWidgetState extends State<TestWidget> {
+  @override
+  Widget build(BuildContext context) {
+$line^
+  }
+}
+''');
+    await computeSuggestions();
+    CompletionSuggestion cs =
+        assertSuggest(completion, selectionOffset: selectionOffset);
+    expect(cs.selectionLength, 0);
+
+    // It is an invocation, but we don't need any additional info for it.
+    // So, all parameter information is absent.
+    expect(cs.parameterNames, isNull);
+    expect(cs.parameterTypes, isNull);
+    expect(cs.requiredParameterCount, isNull);
+    expect(cs.hasNamedParameters, isNull);
+  }
 }
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 0f23257..9903039 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -596,6 +596,32 @@
 ''');
   }
 
+  test_addFieldFormalParameters_flutter() async {
+    addFlutterPackage();
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  final int a;
+  final int b;
+  final int c;
+
+  MyWidget({Key key, this.a}) : super(key: key);
+}
+''');
+    await assertHasFix(DartFixKind.ADD_FIELD_FORMAL_PARAMETERS, '''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  final int a;
+  final int b;
+  final int c;
+
+  MyWidget({Key key, this.a, this.b, this.c}) : super(key: key);
+}
+''');
+  }
+
   test_addFieldFormalParameters_hasRequiredParameter() async {
     await resolveTestUnit('''
 class Test {
@@ -1623,6 +1649,87 @@
 ''');
   }
 
+  test_createConstructor_forFinalFields_flutter() async {
+    addFlutterPackage();
+    errorFilter = (AnalysisError error) {
+      return error.message.contains("'a'");
+    };
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  final int a;
+  final int b = 2;
+  final int c;
+}
+''');
+    await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  final int a;
+  final int b = 2;
+  final int c;
+
+  const MyWidget({Key key, this.a, this.c}) : super(key: key);
+}
+''');
+  }
+
+  test_createConstructor_forFinalFields_flutter_childLast() async {
+    addFlutterPackage();
+    errorFilter = (AnalysisError error) {
+      return error.message.contains("'a'");
+    };
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  final int a;
+  final Widget child;
+  final int b;
+}
+''');
+    await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  final int a;
+  final Widget child;
+  final int b;
+
+  const MyWidget({Key key, this.a, this.b, this.child}) : super(key: key);
+}
+''');
+  }
+
+  test_createConstructor_forFinalFields_flutter_childrenLast() async {
+    addFlutterPackage();
+    errorFilter = (AnalysisError error) {
+      return error.message.contains("'a'");
+    };
+    await resolveTestUnit('''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  final int a;
+  final List<Widget> children;
+  final int b;
+}
+''');
+    await assertHasFix(DartFixKind.CREATE_CONSTRUCTOR_FOR_FINAL_FIELDS, '''
+import 'package:flutter/widgets.dart';
+
+class MyWidget extends StatelessWidget {
+  final int a;
+  final List<Widget> children;
+  final int b;
+
+  const MyWidget({Key key, this.a, this.b, this.children}) : super(key: key);
+}
+''');
+  }
+
   test_createConstructor_insteadOfSyntheticDefault() async {
     await resolveTestUnit('''
 class A {
@@ -2969,20 +3076,6 @@
 ''');
   }
 
-  test_createMissingMethodCall() async {
-    await resolveTestUnit('''
-class C implements Function {
-}
-''');
-    await assertHasFix(DartFixKind.CREATE_MISSING_METHOD_CALL, '''
-class C implements Function {
-  call() {
-    // TODO: implement call
-  }
-}
-''');
-  }
-
   test_createMissingOverrides_field_untyped() async {
     await resolveTestUnit('''
 class A {
diff --git a/pkg/analysis_server/test/services/correction/organize_directives_test.dart b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
index 665cad6..459b78c 100644
--- a/pkg/analysis_server/test/services/correction/organize_directives_test.dart
+++ b/pkg/analysis_server/test/services/correction/organize_directives_test.dart
@@ -185,6 +185,27 @@
 }''', removeUnresolved: true, removeUnused: true);
   }
 
+  test_remove_unusedImports_hasUnresolvedError() async {
+    Future<void> check(String declaration) async {
+      String code = '''
+import 'dart:async';
+$declaration
+''';
+      await _computeUnitAndErrors(code);
+      _assertOrganize(code, removeUnused: true);
+    }
+
+    await check('main() { Unresolved v; }');
+    await check('main() { new Unresolved(); }');
+    await check('main() { const Unresolved(); }');
+    await check('main() { unresolvedFunction(); }');
+    await check('main() { print(unresolvedVariable); }');
+    await check('main() { unresolvedVariable = 0; }');
+    await check('main() { Unresolved.field = 0; }');
+    await check('class A extends Unresolved {}');
+    await check('List<Unresolved> v;');
+  }
+
   test_sort() async {
     await _computeUnitAndErrors(r'''
 library lib;
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
index c1a54ee..b97a729 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/RenameFeedback.java
@@ -34,7 +34,8 @@
   public static final List<RenameFeedback> EMPTY_LIST = Lists.newArrayList();
 
   /**
-   * The offset to the beginning of the name selected to be renamed.
+   * The offset to the beginning of the name selected to be renamed, or -1 if the name does not exist
+   * yet.
    */
   private final int offset;
 
@@ -113,7 +114,8 @@
   }
 
   /**
-   * The offset to the beginning of the name selected to be renamed.
+   * The offset to the beginning of the name selected to be renamed, or -1 if the name does not exist
+   * yet.
    */
   public int getOffset() {
     return offset;
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index c0fcd8f..49e3cb8 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -4382,7 +4382,7 @@
         <ref>int</ref>
         <p>
           The offset to the beginning of the name selected to be
-          renamed.
+          renamed, or -1 if the name does not exist yet.
         </p>
       </field>
       <field name="length">
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 0c5fbe9..a34bf60 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -533,6 +533,11 @@
   E getProperty<E>(String name);
 
   /**
+   * Return the token before [target] or `null` if it cannot be found.
+   */
+  Token findPrevious(Token target);
+
+  /**
    * Set the value of the property with the given [name] to the given [value].
    * If the value is `null`, the property will effectively be removed.
    */
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 9ef6cdf..1d0416c 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -168,6 +168,7 @@
   CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
   CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL,
   CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL,
+  CompileTimeErrorCode.MISSING_DART_LIBRARY,
   CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
   CompileTimeErrorCode.MIXIN_DEFERRED_CLASS,
   CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
@@ -320,6 +321,7 @@
   ParserErrorCode.ANNOTATION_ON_ENUM_CONSTANT,
   ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER,
   ParserErrorCode.BREAK_OUTSIDE_OF_LOOP,
+  ParserErrorCode.CATCH_SYNTAX,
   ParserErrorCode.CLASS_IN_CLASS,
   ParserErrorCode.COLON_IN_PLACE_OF_IN,
   ParserErrorCode.CONSTRUCTOR_WITH_RETURN_TYPE,
diff --git a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
index ea148c6..034c337 100644
--- a/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
+++ b/pkg/analyzer/lib/src/analysis_options/error/option_codes.dart
@@ -40,8 +40,8 @@
    * Initialize a newly created error code to have the given [name].
    */
   const AnalysisOptionsErrorCode(String name, String message,
-      [String correction])
-      : super(name, message, correction);
+      {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
@@ -117,10 +117,9 @@
    * 2: legal values
    */
   static const AnalysisOptionsWarningCode UNSUPPORTED_OPTION_WITH_LEGAL_VALUES =
-      const AnalysisOptionsWarningCode(
-          'UNSUPPORTED_OPTION_WITH_LEGAL_VALUES',
+      const AnalysisOptionsWarningCode('UNSUPPORTED_OPTION_WITH_LEGAL_VALUES',
           "The option '{1}' isn't supported by '{0}'.",
-          "Try using one of the supported options: {2}.");
+          correction: "Try using one of the supported options: {2}.");
 
   /**
    * An error code indicating that an option entry is being configured with an
@@ -133,16 +132,15 @@
    */
   static const AnalysisOptionsWarningCode UNSUPPORTED_VALUE =
       const AnalysisOptionsWarningCode(
-          'UNSUPPORTED_VALUE',
-          "The value '{1}' isn't supported by '{0}'.",
-          "Try using one of the supported options: {2}.");
+          'UNSUPPORTED_VALUE', "The value '{1}' isn't supported by '{0}'.",
+          correction: "Try using one of the supported options: {2}.");
 
   /**
    * Initialize a newly created warning code to have the given [name].
    */
   const AnalysisOptionsWarningCode(String name, String message,
-      [String correction])
-      : super(name, message, correction);
+      {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
@@ -169,18 +167,18 @@
    * An error code indicating that strong-mode: false is being deprecated.
    */
   static const AnalysisOptionsHintCode SPEC_MODE_DEPRECATED =
-      const AnalysisOptionsHintCode(
-          'SPEC_MODE_DEPRECATED',
+      const AnalysisOptionsHintCode('SPEC_MODE_DEPRECATED',
           "The option 'strong-mode: false' is being deprecated.",
-          "It's recommended to use 'strong-mode: true' and make your code "
-          "strong mode clean.");
+          correction:
+              "It's recommended to use 'strong-mode: true' and make your code "
+              "strong mode clean.");
 
   /**
    * Initialize a newly created hint code to have the given [name].
    */
   const AnalysisOptionsHintCode(String name, String message,
-      [String correction])
-      : super(name, message, correction);
+      {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
diff --git a/pkg/analyzer/lib/src/command_line/arguments.dart b/pkg/analyzer/lib/src/command_line/arguments.dart
index 2703beb..c4f50a40 100644
--- a/pkg/analyzer/lib/src/command_line/arguments.dart
+++ b/pkg/analyzer/lib/src/command_line/arguments.dart
@@ -222,7 +222,7 @@
   parser.addFlag(enableInitializingFormalAccessFlag,
       help:
           'Enable support for allowing access to field formal parameters in a '
-          'constructor\'s initializer list.',
+          'constructor\'s initializer list (deprecated).',
       defaultsTo: false,
       negatable: false,
       hide: hide || ddc);
diff --git a/pkg/analyzer/lib/src/dart/analysis/driver.dart b/pkg/analyzer/lib/src/dart/analysis/driver.dart
index 43a1d47..c3e188f 100644
--- a/pkg/analyzer/lib/src/dart/analysis/driver.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/driver.dart
@@ -28,6 +28,7 @@
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/dart/analysis/status.dart';
 import 'package:analyzer/src/dart/analysis/top_level_declaration.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart'
     show
         AnalysisContext,
@@ -94,7 +95,7 @@
   /**
    * The version of data format, should be incremented on every format change.
    */
-  static const int DATA_VERSION = 53;
+  static const int DATA_VERSION = 54;
 
   /**
    * The number of exception contexts allowed to write. Once this field is
@@ -1201,6 +1202,12 @@
                 useCFE: _analysisOptions.useFastaParser,
                 frontEndCompiler: _frontEndCompiler);
           } else {
+            if (!_fsState.getFileForUri(Uri.parse('dart:core')).exists) {
+              return _newMissingDartLibraryResult(file, 'dart:core');
+            }
+            if (!_fsState.getFileForUri(Uri.parse('dart:async')).exists) {
+              return _newMissingDartLibraryResult(file, 'dart:async');
+            }
             libraryContext = await _createLibraryContext(library);
             analyzer = new LibraryAnalyzer(
                 _logger,
@@ -1236,8 +1243,6 @@
             }
           }
 
-          _currentSession.put(libraryElement: resolvedUnit?.element?.library);
-
           // Return the result, full or partial.
           _logger.writeln('Computed new analysis result.');
           AnalysisResult result = _getAnalysisResultFromBytes(
@@ -1505,6 +1510,30 @@
     return null;
   }
 
+  /**
+   * We detected that one of the required `dart` libraries is missing.
+   * Return the empty analysis result with the error.
+   */
+  AnalysisResult _newMissingDartLibraryResult(
+      FileState file, String missingUri) {
+    // TODO(scheglov) Find a better way to report this.
+    return new AnalysisResult(
+        this,
+        _sourceFactory,
+        file.path,
+        file.uri,
+        file.exists,
+        null,
+        file.lineInfo,
+        null,
+        null,
+        [
+          new AnalysisError(file.source, 0, 0,
+              CompileTimeErrorCode.MISSING_DART_LIBRARY, [missingUri])
+        ],
+        null);
+  }
+
   void _reportException(String path, exception, StackTrace stackTrace) {
     String contextKey = null;
     if (exception is _ExceptionState) {
diff --git a/pkg/analyzer/lib/src/dart/analysis/file_state.dart b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
index c8519de..c6032e3 100644
--- a/pkg/analyzer/lib/src/dart/analysis/file_state.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/file_state.dart
@@ -149,7 +149,8 @@
       : isInExternalSummaries = true,
         path = null,
         fileUri = null,
-        source = null {
+        source = null,
+        _exists = true {
     _apiSignature = new Uint8List(16);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/analysis/session.dart b/pkg/analyzer/lib/src/dart/analysis/session.dart
index 8704035..caadbdb 100644
--- a/pkg/analyzer/lib/src/dart/analysis/session.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/session.dart
@@ -80,7 +80,7 @@
     var libraryElement = _uriToLibraryCache[uri];
     if (libraryElement == null) {
       libraryElement = await _driver.getLibraryByUri(uri);
-      _fillUriToLibraryCache(libraryElement);
+      _uriToLibraryCache[uri] = libraryElement;
     }
     return libraryElement;
   }
@@ -123,18 +123,6 @@
   }
 
   /**
-   * Put information into the session, so it is available even though it is
-   * not yet requested by the user. We want to put only information that is
-   * already available directly, or can be derived from available information
-   * very cheaply.
-   */
-  void put({LibraryElement libraryElement}) {
-    if (libraryElement != null) {
-      _fillUriToLibraryCache(libraryElement);
-    }
-  }
-
-  /**
    * Check to see that results from this session will be consistent, and throw
    * an [InconsistentAnalysisException] if they might not be.
    */
@@ -143,18 +131,4 @@
       throw new InconsistentAnalysisException();
     }
   }
-
-  /**
-   * Fill the [_uriToLibraryCache] with libraries referenced from the
-   * given [library].
-   */
-  void _fillUriToLibraryCache(LibraryElement library) {
-    Source source = library.source;
-    String uri = source.uri.toString();
-    if (_uriToLibraryCache[uri] == null) {
-      _uriToLibraryCache[uri] = library;
-      library.importedLibraries.forEach(_fillUriToLibraryCache);
-      library.exportedLibraries.forEach(_fillUriToLibraryCache);
-    }
-  }
 }
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index f916e4d..9774ad0 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -24,6 +24,7 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart' show LineInfo, Source;
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/fasta/token_utils.dart' as util show findPrevious;
 
 /**
  * Two or more string literals that are implicitly concatenated because of being
@@ -988,6 +989,9 @@
     return _propertyMap[name] as E;
   }
 
+  Token findPrevious(Token target) =>
+      util.findPrevious(beginToken, target) ?? parent?.findPrevious(target);
+
   @override
   void setProperty(String name, Object value) {
     if (value == null) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 9a0e0b1..188ac1d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -197,18 +197,7 @@
 
   @override
   PropertyAccessorElement getSetter(String setterName) {
-    // TODO (jwren) revisit- should we append '=' here or require clients to
-    // include it?
-    // Do we need the check for isSetter below?
-    if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
-      setterName += '=';
-    }
-    for (PropertyAccessorElement accessor in accessors) {
-      if (accessor.isSetter && accessor.name == setterName) {
-        return accessor;
-      }
-    }
-    return null;
+    return getSetterFromAccessors(setterName, accessors);
   }
 
   @override
@@ -394,6 +383,22 @@
     }
     return classElement as AbstractClassElementImpl;
   }
+
+  static PropertyAccessorElement getSetterFromAccessors(
+      String setterName, List<PropertyAccessorElement> accessors) {
+    // TODO (jwren) revisit- should we append '=' here or require clients to
+    // include it?
+    // Do we need the check for isSetter below?
+    if (!StringUtilities.endsWithChar(setterName, 0x3D)) {
+      setterName += '=';
+    }
+    for (PropertyAccessorElement accessor in accessors) {
+      if (accessor.isSetter && accessor.name == setterName) {
+        return accessor;
+      }
+    }
+    return null;
+  }
 }
 
 /**
@@ -1963,12 +1968,7 @@
 
   @override
   ClassElement getType(String className) {
-    for (ClassElement type in types) {
-      if (type.name == className) {
-        return type;
-      }
-    }
-    return null;
+    return getTypeFromTypes(className, types);
   }
 
   /**
@@ -2008,6 +2008,16 @@
     safelyVisitChildren(types, visitor);
     safelyVisitChildren(topLevelVariables, visitor);
   }
+
+  static ClassElement getTypeFromTypes(
+      String className, List<ClassElement> types) {
+    for (ClassElement type in types) {
+      if (type.name == className) {
+        return type;
+      }
+    }
+    return null;
+  }
 }
 
 /**
@@ -4833,8 +4843,8 @@
       if (_kernel != null) {
         fieldName = _kernel.name;
       }
-      if (_unlinkedParam != null) {
-        fieldName = _unlinkedParam.name;
+      if (unlinkedParam != null) {
+        fieldName = unlinkedParam.name;
       }
       if (fieldName != null) {
         Element enclosingConstructor = enclosingElement;
@@ -4853,7 +4863,7 @@
   }
 
   void set field(FieldElement field) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     _field = field;
   }
 
@@ -4862,9 +4872,7 @@
 
   @override
   DartType get type {
-    if (_unlinkedParam != null &&
-        _unlinkedParam.type == null &&
-        field != null) {
+    if (unlinkedParam != null && unlinkedParam.type == null && field != null) {
       _type ??= field?.type ?? DynamicTypeImpl.instance;
     }
     return super.type;
@@ -4872,7 +4880,7 @@
 
   @override
   void set type(DartType type) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     _type = type;
   }
 
@@ -6610,8 +6618,13 @@
   bool get isDartCore => name == "dart.core";
 
   @override
-  bool get isInSdk =>
-      StringUtilities.startsWith5(name, 0, 0x64, 0x61, 0x72, 0x74, 0x2E);
+  bool get isInSdk {
+    Uri uri = definingCompilationUnit.source?.uri;
+    if (uri != null) {
+      return DartUriResolver.isDartUri(uri);
+    }
+    return false;
+  }
 
   /**
    * Return `true` if the receiver directly or indirectly imports the
@@ -6815,13 +6828,8 @@
    * using types provided by [typeProvider].
    */
   void createLoadLibraryFunction(TypeProvider typeProvider) {
-    FunctionElementImpl function =
-        new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1);
-    function.isSynthetic = true;
-    function.enclosingElement = this;
-    function.returnType = typeProvider.futureDynamicType;
-    function.type = new FunctionTypeImpl(function);
-    _loadLibraryFunction = function;
+    _loadLibraryFunction =
+        createLoadLibraryFunctionForLibrary(typeProvider, this);
   }
 
   @override
@@ -6867,30 +6875,12 @@
 
   @override
   List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) {
-    var imports = this.imports;
-    int count = imports.length;
-    List<ImportElement> importList = new List<ImportElement>();
-    for (int i = 0; i < count; i++) {
-      if (identical(imports[i].prefix, prefixElement)) {
-        importList.add(imports[i]);
-      }
-    }
-    return importList;
+    return getImportsWithPrefixFromImports(prefixElement, imports);
   }
 
   @override
   ClassElement getType(String className) {
-    ClassElement type = _definingCompilationUnit.getType(className);
-    if (type != null) {
-      return type;
-    }
-    for (CompilationUnitElement part in _parts) {
-      type = part.getType(className);
-      if (type != null) {
-        return type;
-      }
-    }
-    return null;
+    return getTypeFromParts(className, _definingCompilationUnit, _parts);
   }
 
   /** Given an update to this library which may have added or deleted edges
@@ -6985,6 +6975,17 @@
     return prefixes.toList(growable: false);
   }
 
+  static FunctionElementImpl createLoadLibraryFunctionForLibrary(
+      TypeProvider typeProvider, LibraryElement library) {
+    FunctionElementImpl function =
+        new FunctionElementImpl(FunctionElement.LOAD_LIBRARY_NAME, -1);
+    function.isSynthetic = true;
+    function.enclosingElement = library;
+    function.returnType = typeProvider.futureDynamicType;
+    function.type = new FunctionTypeImpl(function);
+    return function;
+  }
+
   /**
    * Return the [LibraryElementImpl] of the given [element].
    */
@@ -6995,6 +6996,35 @@
     return element as LibraryElementImpl;
   }
 
+  static List<ImportElement> getImportsWithPrefixFromImports(
+      PrefixElement prefixElement, List<ImportElement> imports) {
+    int count = imports.length;
+    List<ImportElement> importList = new List<ImportElement>();
+    for (int i = 0; i < count; i++) {
+      if (identical(imports[i].prefix, prefixElement)) {
+        importList.add(imports[i]);
+      }
+    }
+    return importList;
+  }
+
+  static ClassElement getTypeFromParts(
+      String className,
+      CompilationUnitElement definingCompilationUnit,
+      List<CompilationUnitElement> parts) {
+    ClassElement type = definingCompilationUnit.getType(className);
+    if (type != null) {
+      return type;
+    }
+    for (CompilationUnitElement part in parts) {
+      type = part.getType(className);
+      if (type != null) {
+        return type;
+      }
+    }
+    return null;
+  }
+
   /**
    * Return `true` if the [library] has the given [capability].
    */
@@ -8001,7 +8031,7 @@
   /**
    * The unlinked representation of the parameter in the summary.
    */
-  final UnlinkedParam _unlinkedParam;
+  final UnlinkedParam unlinkedParam;
 
   /**
    * The kernel of the element;
@@ -8036,7 +8066,7 @@
    * [nameOffset].
    */
   ParameterElementImpl(String name, int nameOffset)
-      : _unlinkedParam = null,
+      : unlinkedParam = null,
         _kernel = null,
         super(name, nameOffset);
 
@@ -8045,14 +8075,14 @@
    */
   ParameterElementImpl.forKernel(
       ElementImpl enclosingElement, this._kernel, this._parameterKind)
-      : _unlinkedParam = null,
+      : unlinkedParam = null,
         super.forKernel(enclosingElement);
 
   /**
    * Initialize a newly created parameter element to have the given [name].
    */
   ParameterElementImpl.forNode(Identifier name)
-      : _unlinkedParam = null,
+      : unlinkedParam = null,
         _kernel = null,
         super.forNode(name);
 
@@ -8060,7 +8090,7 @@
    * Initialize using the given serialized information.
    */
   ParameterElementImpl.forSerialized(
-      this._unlinkedParam, ElementImpl enclosingElement)
+      this.unlinkedParam, ElementImpl enclosingElement)
       : _kernel = null,
         super.forSerialized(enclosingElement);
 
@@ -8106,27 +8136,27 @@
 
   @override
   int get codeLength {
-    if (_unlinkedParam != null) {
-      return _unlinkedParam.codeRange?.length;
+    if (unlinkedParam != null) {
+      return unlinkedParam.codeRange?.length;
     }
     return super.codeLength;
   }
 
   @override
   int get codeOffset {
-    if (_unlinkedParam != null) {
-      return _unlinkedParam.codeRange?.offset;
+    if (unlinkedParam != null) {
+      return unlinkedParam.codeRange?.offset;
     }
     return super.codeOffset;
   }
 
   @override
   String get defaultValueCode {
-    if (_unlinkedParam != null) {
-      if (_unlinkedParam.initializer?.bodyExpr == null) {
+    if (unlinkedParam != null) {
+      if (unlinkedParam.initializer?.bodyExpr == null) {
         return null;
       }
-      return _unlinkedParam.defaultValueCode;
+      return unlinkedParam.defaultValueCode;
     }
     return _defaultValueCode;
   }
@@ -8135,21 +8165,21 @@
    * Set Dart code of the default value.
    */
   void set defaultValueCode(String defaultValueCode) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     this._defaultValueCode = StringUtilities.intern(defaultValueCode);
   }
 
   @override
   bool get hasImplicitType {
-    if (_unlinkedParam != null) {
-      return _unlinkedParam.type == null && !_unlinkedParam.isFunctionTyped;
+    if (unlinkedParam != null) {
+      return unlinkedParam.type == null && !unlinkedParam.isFunctionTyped;
     }
     return super.hasImplicitType;
   }
 
   @override
   void set hasImplicitType(bool hasImplicitType) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     super.hasImplicitType = hasImplicitType;
   }
 
@@ -8159,9 +8189,9 @@
    * covariant parameter.
    */
   bool get inheritsCovariant {
-    if (_unlinkedParam != null) {
+    if (unlinkedParam != null) {
       return enclosingUnit.resynthesizerContext
-          .inheritsCovariant(_unlinkedParam.inheritsCovariantSlot);
+          .inheritsCovariant(unlinkedParam.inheritsCovariantSlot);
     } else {
       return _inheritsCovariant;
     }
@@ -8171,7 +8201,7 @@
    * Record whether or not this parameter inherits from a covariant parameter.
    */
   void set inheritsCovariant(bool value) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     _inheritsCovariant = value;
   }
 
@@ -8183,8 +8213,8 @@
           ..enclosingElement = this
           ..isSynthetic = true;
       }
-      if (_unlinkedParam != null) {
-        UnlinkedExecutable unlinkedInitializer = _unlinkedParam.initializer;
+      if (unlinkedParam != null) {
+        UnlinkedExecutable unlinkedInitializer = unlinkedParam.initializer;
         if (unlinkedInitializer != null) {
           _initializer =
               new FunctionElementImpl.forSerialized(unlinkedInitializer, this)
@@ -8202,7 +8232,7 @@
    * [function].
    */
   void set initializer(FunctionElement function) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     super.initializer = function;
   }
 
@@ -8211,7 +8241,7 @@
     if (_kernel != null) {
       return false;
     }
-    if (_unlinkedParam != null) {
+    if (unlinkedParam != null) {
       return false;
     }
     return super.isConst;
@@ -8219,7 +8249,7 @@
 
   @override
   void set isConst(bool isConst) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     super.isConst = isConst;
   }
 
@@ -8243,8 +8273,8 @@
     if (_kernel != null) {
       return _kernel.isCovariant;
     }
-    if (_unlinkedParam != null) {
-      return _unlinkedParam.isExplicitlyCovariant;
+    if (unlinkedParam != null) {
+      return unlinkedParam.isExplicitlyCovariant;
     }
     return hasModifier(Modifier.COVARIANT);
   }
@@ -8253,7 +8283,7 @@
    * Set whether this variable parameter is explicitly marked as being covariant.
    */
   void set isExplicitlyCovariant(bool isCovariant) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     setModifier(Modifier.COVARIANT, isCovariant);
   }
 
@@ -8262,15 +8292,15 @@
     if (_kernel != null) {
       return _kernel.isFinal;
     }
-    if (_unlinkedParam != null) {
-      return _unlinkedParam.isFinal;
+    if (unlinkedParam != null) {
+      return unlinkedParam.isFinal;
     }
     return super.isFinal;
   }
 
   @override
   void set isFinal(bool isFinal) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     super.isFinal = isFinal;
   }
 
@@ -8288,9 +8318,9 @@
 
   @override
   List<ElementAnnotation> get metadata {
-    if (_unlinkedParam != null) {
+    if (unlinkedParam != null) {
       return _metadata ??=
-          _buildAnnotations(enclosingUnit, _unlinkedParam.annotations);
+          _buildAnnotations(enclosingUnit, unlinkedParam.annotations);
     }
     return super.metadata;
   }
@@ -8300,8 +8330,8 @@
     if (_kernel != null) {
       return _kernel.name;
     }
-    if (_unlinkedParam != null) {
-      return _unlinkedParam.name;
+    if (unlinkedParam != null) {
+      return unlinkedParam.name;
     }
     return super.name;
   }
@@ -8309,22 +8339,22 @@
   @override
   int get nameOffset {
     int offset = super.nameOffset;
-    if (offset == 0 && _unlinkedParam != null) {
+    if (offset == 0 && unlinkedParam != null) {
       if (isSynthetic ||
-          (_unlinkedParam.name.isEmpty &&
-              _unlinkedParam.kind != UnlinkedParamKind.named &&
+          (unlinkedParam.name.isEmpty &&
+              unlinkedParam.kind != UnlinkedParamKind.named &&
               enclosingElement is GenericFunctionTypeElement)) {
         return -1;
       }
-      return _unlinkedParam.nameOffset;
+      return unlinkedParam.nameOffset;
     }
     return offset;
   }
 
   @override
   ParameterKind get parameterKind {
-    if (_unlinkedParam != null && _parameterKind == null) {
-      switch (_unlinkedParam.kind) {
+    if (unlinkedParam != null && _parameterKind == null) {
+      switch (unlinkedParam.kind) {
         case UnlinkedParamKind.named:
           _parameterKind = ParameterKind.NAMED;
           break;
@@ -8340,7 +8370,7 @@
   }
 
   void set parameterKind(ParameterKind parameterKind) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     _parameterKind = parameterKind;
   }
 
@@ -8357,9 +8387,9 @@
 
   @override
   TopLevelInferenceError get typeInferenceError {
-    if (_unlinkedParam != null) {
+    if (unlinkedParam != null) {
       return enclosingUnit.resynthesizerContext
-          .getTypeInferenceError(_unlinkedParam.inferredTypeSlot);
+          .getTypeInferenceError(unlinkedParam.inferredTypeSlot);
     }
     // We don't support type inference errors without linking.
     return null;
@@ -8372,12 +8402,12 @@
 
   @override
   SourceRange get visibleRange {
-    if (_unlinkedParam != null) {
-      if (_unlinkedParam.visibleLength == 0) {
+    if (unlinkedParam != null) {
+      if (unlinkedParam.visibleLength == 0) {
         return null;
       }
       return new SourceRange(
-          _unlinkedParam.visibleOffset, _unlinkedParam.visibleLength);
+          unlinkedParam.visibleOffset, unlinkedParam.visibleLength);
     }
     if (_visibleRangeLength < 0) {
       return null;
@@ -8393,7 +8423,7 @@
   /**
    * Subclasses need this getter, see [ConstVariableElement._unlinkedConst].
    */
-  UnlinkedExpr get _unlinkedConst => _unlinkedParam?.initializer?.bodyExpr;
+  UnlinkedExpr get _unlinkedConst => unlinkedParam?.initializer?.bodyExpr;
 
   @override
   T accept<T>(ElementVisitor<T> visitor) => visitor.visitParameterElement(this);
@@ -8426,7 +8456,7 @@
    * [offset] with the given [length].
    */
   void setVisibleRange(int offset, int length) {
-    _assertNotResynthesized(_unlinkedParam);
+    _assertNotResynthesized(unlinkedParam);
     _visibleRangeOffset = offset;
     _visibleRangeLength = length;
   }
@@ -8446,27 +8476,29 @@
       kernel.DartType type = _kernel.type;
       _type = enclosingUnit._kernelContext.getType(this, type);
     }
-    if (_unlinkedParam != null && _declaredType == null && _type == null) {
-      if (_unlinkedParam.isFunctionTyped) {
+    if (unlinkedParam != null && _declaredType == null && _type == null) {
+      if (unlinkedParam.isFunctionTyped) {
         CompilationUnitElementImpl enclosingUnit = this.enclosingUnit;
 
         var typeElement = new GenericFunctionTypeElementImpl.forOffset(-1);
         typeElement.enclosingElement = this;
 
         typeElement.parameters = ParameterElementImpl.resynthesizeList(
-            _unlinkedParam.parameters, typeElement,
+            unlinkedParam.parameters, typeElement,
             synthetic: isSynthetic);
 
         typeElement.returnType = enclosingUnit.resynthesizerContext
-            .resolveTypeRef(this, _unlinkedParam.type);
+            .resolveTypeRef(this, unlinkedParam.type);
 
         _type = new FunctionTypeImpl(typeElement);
         typeElement.type = _type;
       } else {
-        _type = enclosingUnit.resynthesizerContext
-            .resolveLinkedType(this, _unlinkedParam.inferredTypeSlot);
+        if (unlinkedParam.inferredTypeSlot != 0) {
+          _type = enclosingUnit.resynthesizerContext
+              .resolveLinkedType(this, unlinkedParam.inferredTypeSlot);
+        }
         declaredType = enclosingUnit.resynthesizerContext
-            .resolveTypeRef(this, _unlinkedParam.type, declaredType: true);
+            .resolveTypeRef(this, unlinkedParam.type, declaredType: true);
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 2fe2d25..a651d07 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -2251,11 +2251,11 @@
    * In the event that the algorithm fails (which might occur due to a bug in
    * the analyzer), `null` is returned.
    */
-  static InterfaceType computeLeastUpperBound(
-      InterfaceType i, InterfaceType j) {
+  static InterfaceType computeLeastUpperBound(InterfaceType i, InterfaceType j,
+      {bool strong = false}) {
     // compute set of supertypes
-    Set<InterfaceType> si = computeSuperinterfaceSet(i);
-    Set<InterfaceType> sj = computeSuperinterfaceSet(j);
+    Set<InterfaceType> si = computeSuperinterfaceSet(i, strong: strong);
+    Set<InterfaceType> sj = computeSuperinterfaceSet(j, strong: strong);
     // union si with i and sj with j
     si.add(i);
     sj.add(j);
@@ -2279,8 +2279,9 @@
    *
    * See [computeLeastUpperBound].
    */
-  static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type) =>
-      _computeSuperinterfaceSet(type, new HashSet<InterfaceType>());
+  static Set<InterfaceType> computeSuperinterfaceSet(InterfaceType type,
+          {bool strong = false}) =>
+      _computeSuperinterfaceSet(type, new HashSet<InterfaceType>(), strong);
 
   /**
    * Return the type from the [types] list that has the longest inheritance path
@@ -2443,22 +2444,27 @@
    * Add all of the superinterfaces of the given [type] to the given [set].
    * Return the [set] as a convenience.
    *
+   * If [strong] mode is enabled (Dart 2), then the `Function` interface is
+   * ignored and not treated as a superinterface.
+   *
    * See [computeSuperinterfaceSet], and [computeLeastUpperBound].
    */
   static Set<InterfaceType> _computeSuperinterfaceSet(
-      InterfaceType type, HashSet<InterfaceType> set) {
+      InterfaceType type, HashSet<InterfaceType> set, bool strong) {
     Element element = type.element;
     if (element != null) {
       List<InterfaceType> superinterfaces = type.interfaces;
       for (InterfaceType superinterface in superinterfaces) {
-        if (set.add(superinterface)) {
-          _computeSuperinterfaceSet(superinterface, set);
+        if (!strong || !superinterface.isDartCoreFunction) {
+          if (set.add(superinterface)) {
+            _computeSuperinterfaceSet(superinterface, set, strong);
+          }
         }
       }
       InterfaceType supertype = type.superclass;
-      if (supertype != null) {
+      if (supertype != null && (!strong || !supertype.isDartCoreFunction)) {
         if (set.add(supertype)) {
-          _computeSuperinterfaceSet(supertype, set);
+          _computeSuperinterfaceSet(supertype, set, strong);
         }
       }
     }
diff --git a/pkg/analyzer/lib/src/dart/error/hint_codes.dart b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
index 7d315d4..5b1ae8c 100644
--- a/pkg/analyzer/lib/src/dart/error/hint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/hint_codes.dart
@@ -44,17 +44,15 @@
   static const HintCode CAN_BE_NULL_AFTER_NULL_AWARE = const HintCode(
       'CAN_BE_NULL_AFTER_NULL_AWARE',
       "The target expression uses '?.', so its value can be null.",
-      "Replace the '.' with a '?.' in the invocation.");
+      correction: "Replace the '.' with a '?.' in the invocation.");
 
   /**
    * Dead code is code that is never reached, this can happen for instance if a
    * statement follows a return statement.
    */
-  static const HintCode DEAD_CODE = const HintCode(
-      'DEAD_CODE',
-      "Dead code.",
-      "Try removing the code, or "
-      "fixing the code before it so that it can be reached.");
+  static const HintCode DEAD_CODE = const HintCode('DEAD_CODE', "Dead code.",
+      correction: "Try removing the code, or "
+          "fixing the code before it so that it can be reached.");
 
   /**
    * Dead code is code that is never reached. This case covers cases where the
@@ -64,8 +62,9 @@
       'DEAD_CODE_CATCH_FOLLOWING_CATCH',
       "Dead code: catch clauses after a 'catch (e)' or "
       "an 'on Object catch (e)' are never reached.",
-      "Try reordering the catch clauses so that they can be reached, or "
-      "removing the unreachable catch clauses.");
+      correction:
+          "Try reordering the catch clauses so that they can be reached, or "
+          "removing the unreachable catch clauses.");
 
   /**
    * Dead code is code that is never reached. This case covers cases where the
@@ -80,8 +79,9 @@
       'DEAD_CODE_ON_CATCH_SUBTYPE',
       "Dead code: this on-catch block will never be executed because '{0}' is "
       "a subtype of '{1}' and hence will have been caught above.",
-      "Try reordering the catch clauses so that this block can be reached, or "
-      "removing the unreachable catch clause.");
+      correction:
+          "Try reordering the catch clauses so that this block can be reached, or "
+          "removing the unreachable catch clause.");
 
   /**
    * Deprecated members should not be invoked or used.
@@ -90,9 +90,9 @@
    * 0: the name of the member
    */
   static const HintCode DEPRECATED_MEMBER_USE = const HintCode(
-      'DEPRECATED_MEMBER_USE',
-      "'{0}' is deprecated and shouldn't be used.",
-      "Try replacing the use of the deprecated member with the replacement.");
+      'DEPRECATED_MEMBER_USE', "'{0}' is deprecated and shouldn't be used.",
+      correction:
+          "Try replacing the use of the deprecated member with the replacement.");
 
   /**
    * Users should not create a class named `Function` anymore.
@@ -100,23 +100,21 @@
   static const HintCode DEPRECATED_FUNCTION_CLASS_DECLARATION = const HintCode(
       'DEPRECATED_FUNCTION_CLASS_DECLARATION',
       "Declaring a class named 'Function' is deprecated.",
-      "Try renaming the class.");
+      correction: "Try renaming the class.");
 
   /**
    * `Function` should not be extended anymore.
    */
   static const HintCode DEPRECATED_EXTENDS_FUNCTION = const HintCode(
-      'DEPRECATED_EXTENDS_FUNCTION',
-      "Extending 'Function' is deprecated.",
-      "Try removing 'Function' from the 'extends' clause.");
+      'DEPRECATED_EXTENDS_FUNCTION', "Extending 'Function' is deprecated.",
+      correction: "Try removing 'Function' from the 'extends' clause.");
 
   /**
    * `Function` should not be mixed in anymore.
    */
   static const HintCode DEPRECATED_MIXIN_FUNCTION = const HintCode(
-      'DEPRECATED_MIXIN_FUNCTION',
-      "Mixing in 'Function' is deprecated.",
-      "Try removing 'Function' from the 'with' clause.");
+      'DEPRECATED_MIXIN_FUNCTION', "Mixing in 'Function' is deprecated.",
+      correction: "Try removing 'Function' from the 'with' clause.");
 
   /**
    * Hint to use the ~/ operator.
@@ -124,13 +122,14 @@
   static const HintCode DIVISION_OPTIMIZATION = const HintCode(
       'DIVISION_OPTIMIZATION',
       "The operator x ~/ y is more efficient than (x / y).toInt().",
-      "Try re-writing the expression to use the '~/' operator.");
+      correction: "Try re-writing the expression to use the '~/' operator.");
 
   /**
    * Duplicate imports.
    */
-  static const HintCode DUPLICATE_IMPORT = const HintCode('DUPLICATE_IMPORT',
-      "Duplicate import.", "Try removing all but one import of the library.");
+  static const HintCode DUPLICATE_IMPORT = const HintCode(
+      'DUPLICATE_IMPORT', "Duplicate import.",
+      correction: "Try removing all but one import of the library.");
 
   /**
    * It is a bad practice for a source file in a package "lib" directory
@@ -144,8 +143,8 @@
           'FILE_IMPORT_INSIDE_LIB_REFERENCES_FILE_OUTSIDE',
           "A file in the 'lib' directory shouldn't import a file outside the "
           "'lib' directory.",
-          "Try removing the import, or "
-          "moving the imported file inside the 'lib' directory.");
+          correction: "Try removing the import, or "
+              "moving the imported file inside the 'lib' directory.");
 
   /**
    * It is a bad practice for a source file ouside a package "lib" directory
@@ -159,7 +158,7 @@
           'FILE_IMPORT_OUTSIDE_LIB_REFERENCES_FILE_INSIDE',
           "A file outside the 'lib' directory shouldn't reference a file "
           "inside the 'lib' directory using a relative path.",
-          "Try using a package: URI instead.");
+          correction: "Try using a package: URI instead.");
 
   /**
    * Generic type comments (`/*<T>*/` and `/*=T*/`) are no longer necessary and
@@ -168,7 +167,7 @@
   static const HintCode GENERIC_METHOD_COMMENT = const HintCode(
       'GENERIC_METHOD_COMMENT',
       "The generic type comment is being deprecated in favor of the real syntax.",
-      "Try replacing the comment with the actual type annotation.");
+      correction: "Try replacing the comment with the actual type annotation.");
 
   /**
    * Deferred libraries shouldn't define a top level function 'loadLibrary'.
@@ -178,8 +177,8 @@
           'IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION',
           "The library '{0}' defines a top-level function named 'loadLibrary' "
           "which is hidden by deferring this library.",
-          "Try changing the import to not be deferred, or "
-          "rename the function in the imported library.");
+          correction: "Try changing the import to not be deferred, or "
+              "rename the function in the imported library.");
 
   /**
    * This hint is generated anywhere where the
@@ -193,8 +192,8 @@
   static const HintCode INVALID_ASSIGNMENT = const HintCode(
       'INVALID_ASSIGNMENT',
       "A value of type '{0}' can't be assigned to a variable of type '{1}'.",
-      "Try changing the type of the variable, or "
-      "casting the right-hand type to '{1}'.");
+      correction: "Try changing the type of the variable, or "
+          "casting the right-hand type to '{1}'.");
 
   /**
    * This hint is generated anywhere a @factory annotation is associated with
@@ -241,11 +240,13 @@
    * 1: the number of type parameters in the overridden method
    * 2: the name of the class where the overridden method is declared
    */
-  static const HintCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS = const HintCode(
-      'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS',
-      "The method has {0} type parameters, but it is overriding a method "
-      "with {1} type parameters from '{2}'.",
-      "Try changing the number of type parameters so that they are the same.");
+  static const HintCode INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS =
+      const HintCode(
+          'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS',
+          "The method has {0} type parameters, but it is overriding a method "
+          "with {1} type parameters from '{2}'.",
+          correction:
+              "Try changing the number of type parameters so that they are the same.");
 
   /**
    * Generic Method DEP: bounds of type parameters must be compatible.
@@ -263,7 +264,8 @@
           'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND',
           "The type parameter '{0}' extends '{1}', but that is stricter than "
           "'{2}' extends '{3}' in the overridden method from '{4}'.",
-          "Try changing the bounds on the type parameters so that they are compatible.");
+          correction:
+              "Try changing the bounds on the type parameters so that they are compatible.");
 
   /**
    * This hint is generated anywhere where `@required` annotates a non named
@@ -276,7 +278,7 @@
       'INVALID_REQUIRED_PARAM',
       "The type parameter '{0}' is annotated with @required but only named "
       "parameters without default value can be annotated with it.",
-      "Remove @required.");
+      correction: "Remove @required.");
 
   /**
    * This hint is generated anywhere where a member annotated with `@protected`
@@ -308,7 +310,7 @@
       'IS_DOUBLE',
       "When compiled to JS, this test might return true when the left hand "
       "side is an int.",
-      "Try testing for 'num' instead.");
+      correction: "Try testing for 'num' instead.");
 
   /**
    * Hint for the `x is int` type checks.
@@ -317,7 +319,7 @@
       'IS_INT',
       "When compiled to JS, this test might return true when the left hand "
       "side is a double.",
-      "Try testing for 'num' instead.");
+      correction: "Try testing for 'num' instead.");
 
   /**
    * Hint for the `x is! double` type checks.
@@ -326,7 +328,7 @@
       'IS_NOT_DOUBLE',
       "When compiled to JS, this test might return false when the left hand "
       "side is an int.",
-      "Try testing for 'num' instead.");
+      correction: "Try testing for 'num' instead.");
 
   /**
    * Hint for the `x is! int` type checks.
@@ -335,7 +337,7 @@
       'IS_NOT_INT',
       "When compiled to JS, this test might return false when the left hand "
       "side is a double.",
-      "Try testing for 'num' instead.");
+      correction: "Try testing for 'num' instead.");
 
   /**
    * Generate a hint for an element that is annotated with `@JS(...)` whose
@@ -345,7 +347,7 @@
       'MISSING_JS_LIB_ANNOTATION',
       "The @JS() annotation can only be used if it is also declared on the "
       "library directive.",
-      "Try adding the annotation to the library directive.");
+      correction: "Try adding the annotation to the library directive.");
 
   /**
    * Generate a hint for a constructor, function or method invocation where a
@@ -382,7 +384,8 @@
       'MISSING_RETURN',
       "This function declares a return type of '{0}', but doesn't end with a "
       "return statement.",
-      "Try adding a return statement, or changing the return type to 'void'.");
+      correction:
+          "Try adding a return statement, or changing the return type to 'void'.");
 
   /**
    * Generate a hint for classes that inherit from classes annotated with
@@ -421,8 +424,9 @@
       'NULL_AWARE_IN_CONDITION',
       "The value of the '?.' operator can be 'null', which isn't appropriate "
       "in a condition.",
-      "Try replacing the '?.' with a '.', testing the left-hand side for null if "
-      "necessary.");
+      correction:
+          "Try replacing the '?.' with a '.', testing the left-hand side for null if "
+          "necessary.");
 
   /**
    * A condition in operands of a logical operator could evaluate to `null`
@@ -442,7 +446,7 @@
   static const HintCode OVERRIDE_EQUALS_BUT_NOT_HASH_CODE = const HintCode(
       'OVERRIDE_EQUALS_BUT_NOT_HASH_CODE',
       "The class '{0}' overrides 'operator==', but not 'get hashCode'.",
-      "Try implementing 'hashCode'.");
+      correction: "Try implementing 'hashCode'.");
 
   /**
    * A getter with the override annotation does not override an existing getter.
@@ -450,8 +454,8 @@
   static const HintCode OVERRIDE_ON_NON_OVERRIDING_GETTER = const HintCode(
       'OVERRIDE_ON_NON_OVERRIDING_GETTER',
       "Getter doesn't override an inherited getter.",
-      "Try updating this class to match the superclass, or "
-      "removing the override annotation.");
+      correction: "Try updating this class to match the superclass, or "
+          "removing the override annotation.");
 
   /**
    * A field with the override annotation does not override a getter or setter.
@@ -459,8 +463,8 @@
   static const HintCode OVERRIDE_ON_NON_OVERRIDING_FIELD = const HintCode(
       'OVERRIDE_ON_NON_OVERRIDING_FIELD',
       "Field doesn't override an inherited getter or setter.",
-      "Try updating this class to match the superclass, or "
-      "removing the override annotation.");
+      correction: "Try updating this class to match the superclass, or "
+          "removing the override annotation.");
 
   /**
    * A method with the override annotation does not override an existing method.
@@ -468,8 +472,8 @@
   static const HintCode OVERRIDE_ON_NON_OVERRIDING_METHOD = const HintCode(
       'OVERRIDE_ON_NON_OVERRIDING_METHOD',
       "Method doesn't override an inherited method.",
-      "Try updating this class to match the superclass, or "
-      "removing the override annotation.");
+      correction: "Try updating this class to match the superclass, or "
+          "removing the override annotation.");
 
   /**
    * A setter with the override annotation does not override an existing setter.
@@ -477,8 +481,8 @@
   static const HintCode OVERRIDE_ON_NON_OVERRIDING_SETTER = const HintCode(
       'OVERRIDE_ON_NON_OVERRIDING_SETTER',
       "Setter doesn't override an inherited setter.",
-      "Try updating this class to match the superclass, or "
-      "removing the override annotation.");
+      correction: "Try updating this class to match the superclass, or "
+          "removing the override annotation.");
 
   /**
    * It is a bad practice for a package import to reference anything outside the
@@ -496,15 +500,14 @@
   static const HintCode TYPE_CHECK_IS_NOT_NULL = const HintCode(
       'TYPE_CHECK_IS_NOT_NULL',
       "Tests for non-null should be done with '!= null'.",
-      "Try replacing the 'is! Null' check with '!= null'.");
+      correction: "Try replacing the 'is! Null' check with '!= null'.");
 
   /**
    * Type checks of the type `x is Null` should be done with `x == null`.
    */
   static const HintCode TYPE_CHECK_IS_NULL = const HintCode(
-      'TYPE_CHECK_IS_NULL',
-      "Tests for null should be done with '== null'.",
-      "Try replacing the 'is Null' check with '== null'.");
+      'TYPE_CHECK_IS_NULL', "Tests for null should be done with '== null'.",
+      correction: "Try replacing the 'is Null' check with '== null'.");
 
   /**
    * This hint is generated anywhere where the
@@ -517,9 +520,9 @@
    * 1: the name of the enclosing type where the getter is being looked for
    */
   static const HintCode UNDEFINED_GETTER = const HintCode(
-      'UNDEFINED_GETTER',
-      "The getter '{0}' isn't defined for the class '{1}'.",
-      "Try defining a getter or field named '{0}', or invoke a different getter.");
+      'UNDEFINED_GETTER', "The getter '{0}' isn't defined for the class '{1}'.",
+      correction:
+          "Try defining a getter or field named '{0}', or invoke a different getter.");
 
   /**
    * An undefined name hidden in an import or export directive.
@@ -527,7 +530,7 @@
   static const HintCode UNDEFINED_HIDDEN_NAME = const HintCode(
       'UNDEFINED_HIDDEN_NAME',
       "The library '{0}' doesn't export a member with the hidden name '{1}'.",
-      "Try removing the name from the list of hidden members.");
+      correction: "Try removing the name from the list of hidden members.");
 
   /**
    * This hint is generated anywhere where the
@@ -539,10 +542,10 @@
    * 1: the resolved type name that the method lookup is happening on
    */
   static const HintCode UNDEFINED_METHOD = const HintCode(
-      'UNDEFINED_METHOD',
-      "The method '{0}' isn't defined for the class '{1}'.",
-      "Try correcting the name to the name of an existing method, or "
-      "defining a method named '{0}'.");
+      'UNDEFINED_METHOD', "The method '{0}' isn't defined for the class '{1}'.",
+      correction:
+          "Try correcting the name to the name of an existing method, or "
+          "defining a method named '{0}'.");
 
   /**
    * This hint is generated anywhere where the
@@ -556,7 +559,7 @@
   static const HintCode UNDEFINED_OPERATOR = const HintCode(
       'UNDEFINED_OPERATOR',
       "The operator '{0}' isn't defined for the class '{1}'.",
-      "Try defining the operator '{0}'.");
+      correction: "Try defining the operator '{0}'.");
 
   /**
    * This hint is generated anywhere where the
@@ -569,9 +572,9 @@
    * 1: the name of the enclosing type where the setter is being looked for
    */
   static const HintCode UNDEFINED_SETTER = const HintCode(
-      'UNDEFINED_SETTER',
-      "The setter '{0}' isn't defined for the class '{1}'.",
-      "Try defining a setter or field named '{0}', or invoke a different setter.");
+      'UNDEFINED_SETTER', "The setter '{0}' isn't defined for the class '{1}'.",
+      correction:
+          "Try defining a setter or field named '{0}', or invoke a different setter.");
 
   /**
    * An undefined name shown in an import or export directive.
@@ -579,21 +582,21 @@
   static const HintCode UNDEFINED_SHOWN_NAME = const HintCode(
       'UNDEFINED_SHOWN_NAME',
       "The library '{0}' doesn't export a member with the shown name '{1}'.",
-      "Try removing the name from the list of shown members.");
+      correction: "Try removing the name from the list of shown members.");
 
   /**
    * Unnecessary cast.
    */
   static const HintCode UNNECESSARY_CAST = const HintCode(
-      'UNNECESSARY_CAST', "Unnecessary cast.", "Try removing the cast.");
+      'UNNECESSARY_CAST', "Unnecessary cast.",
+      correction: "Try removing the cast.");
 
   /**
    * Unnecessary `noSuchMethod` declaration.
    */
   static const HintCode UNNECESSARY_NO_SUCH_METHOD = const HintCode(
-      'UNNECESSARY_NO_SUCH_METHOD',
-      "Unnecessary 'noSuchMethod' declaration.",
-      "Try removing the declaration of 'noSuchMethod'.");
+      'UNNECESSARY_NO_SUCH_METHOD', "Unnecessary 'noSuchMethod' declaration.",
+      correction: "Try removing the declaration of 'noSuchMethod'.");
 
   /**
    * Unnecessary type checks, the result is always false.
@@ -601,7 +604,7 @@
   static const HintCode UNNECESSARY_TYPE_CHECK_FALSE = const HintCode(
       'UNNECESSARY_TYPE_CHECK_FALSE',
       "Unnecessary type check, the result is always false.",
-      "Try correcting the type check, or removing the type check.");
+      correction: "Try correcting the type check, or removing the type check.");
 
   /**
    * Unnecessary type checks, the result is always true.
@@ -609,7 +612,7 @@
   static const HintCode UNNECESSARY_TYPE_CHECK_TRUE = const HintCode(
       'UNNECESSARY_TYPE_CHECK_TRUE',
       "Unnecessary type check, the result is always true.",
-      "Try correcting the type check, or removing the type check.");
+      correction: "Try correcting the type check, or removing the type check.");
 
   /**
    * Unused catch exception variables.
@@ -620,7 +623,7 @@
       // TODO(brianwilkerson) Split this error code so that we can differentiate
       // between removing the catch clause and replacing the catch clause with
       // an on clause.
-      "Try removing the catch clause.");
+      correction: "Try removing the catch clause.");
 
   /**
    * Unused catch stack trace variables.
@@ -628,21 +631,21 @@
   static const HintCode UNUSED_CATCH_STACK = const HintCode(
       'UNUSED_CATCH_STACK',
       "The stack trace variable '{0}' isn't used and can be removed.",
-      "Try removing the stack trace variable, or using it.");
+      correction: "Try removing the stack trace variable, or using it.");
 
   /**
    * See [Modifier.IS_USED_IN_LIBRARY].
    */
-  static const HintCode UNUSED_ELEMENT = const HintCode('UNUSED_ELEMENT',
-      "The {0} '{1}' isn't used.", "Try removing the declaration of '{1}'.");
+  static const HintCode UNUSED_ELEMENT = const HintCode(
+      'UNUSED_ELEMENT', "The {0} '{1}' isn't used.",
+      correction: "Try removing the declaration of '{1}'.");
 
   /**
    * Unused fields are fields which are never read.
    */
   static const HintCode UNUSED_FIELD = const HintCode(
-      'UNUSED_FIELD',
-      "The value of the field '{0}' isn't used.",
-      "Try removing the field, or using it.");
+      'UNUSED_FIELD', "The value of the field '{0}' isn't used.",
+      correction: "Try removing the field, or using it.");
 
   /**
    * Unused imports are imports which are never used.
@@ -650,18 +653,18 @@
    * Parameters:
    * 0: The content of the unused import's uri
    */
-  static const HintCode UNUSED_IMPORT = const HintCode('UNUSED_IMPORT',
-      "Unused import: '{0}'.", "Try removing the import directive.");
+  static const HintCode UNUSED_IMPORT = const HintCode(
+      'UNUSED_IMPORT', "Unused import: '{0}'.",
+      correction: "Try removing the import directive.");
 
   /**
    * Unused labels are labels that are never referenced in either a 'break' or
    * 'continue' statement.
    */
-  static const HintCode UNUSED_LABEL = const HintCode(
-      'UNUSED_LABEL',
-      "The label '{0}' isn't used.",
-      "Try removing the label, or "
-      "using it in either a 'break' or 'continue' statement.");
+  static const HintCode UNUSED_LABEL =
+      const HintCode('UNUSED_LABEL', "The label '{0}' isn't used.",
+          correction: "Try removing the label, or "
+              "using it in either a 'break' or 'continue' statement.");
 
   /**
    * Unused local variables are local variables that are never read.
@@ -669,15 +672,14 @@
   static const HintCode UNUSED_LOCAL_VARIABLE = const HintCode(
       'UNUSED_LOCAL_VARIABLE',
       "The value of the local variable '{0}' isn't used.",
-      "Try removing the variable, or using it.");
+      correction: "Try removing the variable, or using it.");
 
   /**
    * Unused shown names are names shown on imports which are never used.
    */
   static const HintCode UNUSED_SHOWN_NAME = const HintCode(
-      'UNUSED_SHOWN_NAME',
-      "The name {0} is shown, but not used.",
-      "Try removing the name from the list of shown members.");
+      'UNUSED_SHOWN_NAME', "The name {0} is shown, but not used.",
+      correction: "Try removing the name from the list of shown members.");
 
   /**
    * It will be a static type warning if <i>m</i> is not a generic method with
@@ -692,7 +694,7 @@
       'WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD',
       "The method '{0}' is declared with {1} type parameters, "
       "but {2} type arguments were given.",
-      "Try adjusting the number of type arguments.");
+      correction: "Try adjusting the number of type arguments.");
 
   /**
    * Initialize a newly created error code to have the given [name]. The message
@@ -700,8 +702,8 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const HintCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const HintCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorType.HINT.severity;
diff --git a/pkg/analyzer/lib/src/dart/error/lint_codes.dart b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
index 9faaef6..9fc7d8f 100644
--- a/pkg/analyzer/lib/src/dart/error/lint_codes.dart
+++ b/pkg/analyzer/lib/src/dart/error/lint_codes.dart
@@ -14,8 +14,8 @@
  * might aggregated to define a project's style guide.
  */
 class LintCode extends ErrorCode {
-  const LintCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const LintCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.INFO;
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 489af14..87d69d3 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -21,40 +21,35 @@
   static const ParserErrorCode ABSTRACT_CLASS_MEMBER = const ParserErrorCode(
       'ABSTRACT_CLASS_MEMBER',
       "Members of classes can't be declared to be 'abstract'.",
-      "Try removing the keyword 'abstract'.");
+      correction: "Try removing the keyword 'abstract'.");
 
   static const ParserErrorCode ABSTRACT_ENUM = const ParserErrorCode(
-      'ABSTRACT_ENUM',
-      "Enums can't be declared to be 'abstract'.",
-      "Try removing the keyword 'abstract'.");
+      'ABSTRACT_ENUM', "Enums can't be declared to be 'abstract'.",
+      correction: "Try removing the keyword 'abstract'.");
 
   static const ParserErrorCode ABSTRACT_STATIC_METHOD = const ParserErrorCode(
       'ABSTRACT_STATIC_METHOD',
       "Static methods can't be declared to be 'abstract'.",
-      "Try removing the keyword 'abstract'.");
+      correction: "Try removing the keyword 'abstract'.");
 
   static const ParserErrorCode ABSTRACT_TOP_LEVEL_FUNCTION =
-      const ParserErrorCode(
-          'ABSTRACT_TOP_LEVEL_FUNCTION',
+      const ParserErrorCode('ABSTRACT_TOP_LEVEL_FUNCTION',
           "Top-level functions can't be declared to be 'abstract'.",
-          "Try removing the keyword 'abstract'.");
+          correction: "Try removing the keyword 'abstract'.");
 
   static const ParserErrorCode ABSTRACT_TOP_LEVEL_VARIABLE =
-      const ParserErrorCode(
-          'ABSTRACT_TOP_LEVEL_VARIABLE',
+      const ParserErrorCode('ABSTRACT_TOP_LEVEL_VARIABLE',
           "Top-level variables can't be declared to be 'abstract'.",
-          "Try removing the keyword 'abstract'.");
+          correction: "Try removing the keyword 'abstract'.");
 
   static const ParserErrorCode ABSTRACT_TYPEDEF = const ParserErrorCode(
-      'ABSTRACT_TYPEDEF',
-      "Typedefs can't be declared to be 'abstract'.",
-      "Try removing the keyword 'abstract'.");
+      'ABSTRACT_TYPEDEF', "Typedefs can't be declared to be 'abstract'.",
+      correction: "Try removing the keyword 'abstract'.");
 
   static const ParserErrorCode ANNOTATION_ON_ENUM_CONSTANT =
-      const ParserErrorCode(
-          'ANNOTATION_ON_ENUM_CONSTANT',
+      const ParserErrorCode('ANNOTATION_ON_ENUM_CONSTANT',
           "Enum constants can't have annotations.",
-          "Try removing the annotation.");
+          correction: "Try removing the annotation.");
 
   /**
    * 16.32 Identifier Reference: It is a compile-time error if any of the
@@ -70,201 +65,192 @@
   static const ParserErrorCode BREAK_OUTSIDE_OF_LOOP = const ParserErrorCode(
       'BREAK_OUTSIDE_OF_LOOP',
       "A break statement can't be used outside of a loop or switch statement.",
-      "Try removing the break statement.");
+      correction: "Try removing the break statement.");
+
+  static const ParserErrorCode CATCH_SYNTAX = const ParserErrorCode(
+      'CATCH_SYNTAX',
+      "'catch' must be followed by '(identifier)' or '(identifier, identifier)'.",
+      correction:
+          "No types are needed, the first is given by 'on', the second is always 'StackTrace'.");
 
   static const ParserErrorCode CLASS_IN_CLASS = const ParserErrorCode(
-      'CLASS_IN_CLASS',
-      "Classes can't be declared inside other classes.",
-      "Try moving the class to the top-level.");
+      'CLASS_IN_CLASS', "Classes can't be declared inside other classes.",
+      correction: "Try moving the class to the top-level.");
 
   static const ParserErrorCode COLON_IN_PLACE_OF_IN = const ParserErrorCode(
-      'COLON_IN_PLACE_OF_IN',
-      "For-in loops use 'in' rather than a colon.",
-      "Try replacing the colon with the keyword 'in'.");
+      'COLON_IN_PLACE_OF_IN', "For-in loops use 'in' rather than a colon.",
+      correction: "Try replacing the colon with the keyword 'in'.");
 
   static const ParserErrorCode CONST_AFTER_FACTORY = const ParserErrorCode(
       'CONST_AFTER_FACTORY',
       "The modifier 'const' should be before the modifier 'factory'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode CONST_AND_COVARIANT = const ParserErrorCode(
       'CONST_AND_COVARIANT',
       "Members can't be declared to be both 'const' and 'covariant'.",
-      "Try removing either the 'const' or 'covariant' keyword.");
+      correction: "Try removing either the 'const' or 'covariant' keyword.");
 
   static const ParserErrorCode CONST_AND_FINAL = const ParserErrorCode(
       'CONST_AND_FINAL',
       "Members can't be declared to be both 'const' and 'final'.",
-      "Try removing either the 'const' or 'final' keyword.");
+      correction: "Try removing either the 'const' or 'final' keyword.");
 
   static const ParserErrorCode CONST_AND_VAR = const ParserErrorCode(
       'CONST_AND_VAR',
       "Members can't be declared to be both 'const' and 'var'.",
-      "Try removing either the 'const' or 'var' keyword.");
+      correction: "Try removing either the 'const' or 'var' keyword.");
 
   static const ParserErrorCode CONST_CLASS = const ParserErrorCode(
-      'CONST_CLASS',
-      "Classes can't be declared to be 'const'.",
-      "Try removing the 'const' keyword. If you're trying to indicate that "
-      "instances of the class can be constants, place the 'const' keyword on "
-      "the class' constructor(s).");
+      'CONST_CLASS', "Classes can't be declared to be 'const'.",
+      correction:
+          "Try removing the 'const' keyword. If you're trying to indicate that "
+          "instances of the class can be constants, place the 'const' keyword on "
+          "the class' constructor(s).");
 
   static const ParserErrorCode CONST_CONSTRUCTOR_WITH_BODY =
-      const ParserErrorCode(
-          'CONST_CONSTRUCTOR_WITH_BODY',
+      const ParserErrorCode('CONST_CONSTRUCTOR_WITH_BODY',
           "Const constructors can't have a body.",
-          "Try removing either the 'const' keyword or the body.");
+          correction: "Try removing either the 'const' keyword or the body.");
 
   static const ParserErrorCode CONST_ENUM = const ParserErrorCode(
-      'CONST_ENUM',
-      "Enums can't be declared to be 'const'.",
-      "Try removing the 'const' keyword.");
+      'CONST_ENUM', "Enums can't be declared to be 'const'.",
+      correction: "Try removing the 'const' keyword.");
 
   static const ParserErrorCode CONST_FACTORY = const ParserErrorCode(
       'CONST_FACTORY',
       "Only redirecting factory constructors can be declared to be 'const'.",
-      "Try removing the 'const' keyword, or "
-      "replacing the body with '=' followed by a valid target.");
+      correction: "Try removing the 'const' keyword, or "
+          "replacing the body with '=' followed by a valid target.");
 
   static const ParserErrorCode CONST_METHOD = const ParserErrorCode(
       'CONST_METHOD',
       "Getters, setters and methods can't be declared to be 'const'.",
-      "Try removing the 'const' keyword.");
+      correction: "Try removing the 'const' keyword.");
 
   static const ParserErrorCode CONST_TYPEDEF = const ParserErrorCode(
-      'CONST_TYPEDEF',
-      "Type aliases can't be declared to be 'const'.",
-      "Try removing the 'const' keyword.");
+      'CONST_TYPEDEF', "Type aliases can't be declared to be 'const'.",
+      correction: "Try removing the 'const' keyword.");
 
   static const ParserErrorCode CONSTRUCTOR_WITH_RETURN_TYPE =
-      const ParserErrorCode(
-          'CONSTRUCTOR_WITH_RETURN_TYPE',
+      const ParserErrorCode('CONSTRUCTOR_WITH_RETURN_TYPE',
           "Constructors can't have a return type.",
-          "Try removing the return type.");
+          correction: "Try removing the return type.");
 
   static const ParserErrorCode CONTINUE_OUTSIDE_OF_LOOP = const ParserErrorCode(
       'CONTINUE_OUTSIDE_OF_LOOP',
       "A continue statement can't be used outside of a loop or switch statement.",
-      "Try removing the continue statement.");
+      correction: "Try removing the continue statement.");
 
   static const ParserErrorCode CONTINUE_WITHOUT_LABEL_IN_CASE = const ParserErrorCode(
       'CONTINUE_WITHOUT_LABEL_IN_CASE',
       "A continue statement in a switch statement must have a label as a target.",
-      "Try adding a label associated with one of the case clauses to the continue statement.");
+      correction:
+          "Try adding a label associated with one of the case clauses to the continue statement.");
 
   static const ParserErrorCode COVARIANT_AFTER_FINAL = const ParserErrorCode(
       'COVARIANT_AFTER_FINAL',
       "The modifier 'covariant' should be before the modifier 'final'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode COVARIANT_AFTER_VAR = const ParserErrorCode(
       'COVARIANT_AFTER_VAR',
       "The modifier 'covariant' should be before the modifier 'final'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode COVARIANT_AND_STATIC = const ParserErrorCode(
       'COVARIANT_AND_STATIC',
       "Members can't be declared to be both 'covariant' and 'static'.",
-      "Try removing either the 'covariant' or 'static' keyword.");
+      correction: "Try removing either the 'covariant' or 'static' keyword.");
 
   static const ParserErrorCode COVARIANT_MEMBER = const ParserErrorCode(
       'COVARIANT_MEMBER',
       "Getters, setters and methods can't be declared to be 'covariant'.",
-      "Try removing the 'covariant' keyword.");
+      correction: "Try removing the 'covariant' keyword.");
 
   static const ParserErrorCode COVARIANT_TOP_LEVEL_DECLARATION =
-      const ParserErrorCode(
-          'COVARIANT_TOP_LEVEL_DECLARATION',
+      const ParserErrorCode('COVARIANT_TOP_LEVEL_DECLARATION',
           "Top-level declarations can't be declared to be covariant.",
-          "Try removing the keyword 'covariant'.");
+          correction: "Try removing the keyword 'covariant'.");
 
   static const ParserErrorCode COVARIANT_CONSTRUCTOR = const ParserErrorCode(
       'COVARIANT_CONSTRUCTOR',
       "A constructor can't be declared to be 'covariant'.",
-      "Try removing the keyword 'covariant'.");
+      correction: "Try removing the keyword 'covariant'.");
 
   static const ParserErrorCode DEFERRED_AFTER_PREFIX = const ParserErrorCode(
       'DEFERRED_AFTER_PREFIX',
       "The deferred keyword should come"
       " immediately before the prefix ('as' clause).",
-      "Try moving the deferred keyword before the prefix.");
+      correction: "Try moving the deferred keyword before the prefix.");
 
   static const ParserErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPE =
-      const ParserErrorCode(
-          'DEFAULT_VALUE_IN_FUNCTION_TYPE',
+      const ParserErrorCode('DEFAULT_VALUE_IN_FUNCTION_TYPE',
           "Parameters in a function type cannot have default values",
-          "Try removing the default value.");
+          correction: "Try removing the default value.");
 
   static const ParserErrorCode DIRECTIVE_AFTER_DECLARATION =
-      const ParserErrorCode(
-          'DIRECTIVE_AFTER_DECLARATION',
+      const ParserErrorCode('DIRECTIVE_AFTER_DECLARATION',
           "Directives must appear before any declarations.",
-          "Try moving the directive before any declarations.");
+          correction: "Try moving the directive before any declarations.");
 
   /**
    * Parameters:
    * 0: the label that was duplicated
    */
   static const ParserErrorCode DUPLICATE_LABEL_IN_SWITCH_STATEMENT =
-      const ParserErrorCode(
-          'DUPLICATE_LABEL_IN_SWITCH_STATEMENT',
+      const ParserErrorCode('DUPLICATE_LABEL_IN_SWITCH_STATEMENT',
           "The label '{0}' was already used in this switch statement.",
-          "Try choosing a different name for this label.");
+          correction: "Try choosing a different name for this label.");
 
   static const ParserErrorCode DUPLICATE_DEFERRED = const ParserErrorCode(
       'DUPLICATE_DEFERRED',
       "An import directive can only have one 'deferred' keyword.",
-      "Try removing all but one 'deferred' keyword.");
+      correction: "Try removing all but one 'deferred' keyword.");
 
   /**
    * Parameters:
    * 0: the modifier that was duplicated
    */
   static const ParserErrorCode DUPLICATED_MODIFIER = const ParserErrorCode(
-      'DUPLICATED_MODIFIER',
-      "The modifier '{0}' was already specified.",
-      "Try removing all but one occurance of the modifier.");
+      'DUPLICATED_MODIFIER', "The modifier '{0}' was already specified.",
+      correction: "Try removing all but one occurance of the modifier.");
 
   static const ParserErrorCode DUPLICATE_PREFIX = const ParserErrorCode(
       'DUPLICATE_PREFIX',
       "An import directive can only have one prefix ('as' clause).",
-      "Try removing all but one prefix.");
+      correction: "Try removing all but one prefix.");
 
   static const ParserErrorCode EMPTY_ENUM_BODY = const ParserErrorCode(
-      'EMPTY_ENUM_BODY',
-      "An enum must declare at least one constant name.",
-      "Try declaring a constant.");
+      'EMPTY_ENUM_BODY', "An enum must declare at least one constant name.",
+      correction: "Try declaring a constant.");
 
   static const ParserErrorCode ENUM_IN_CLASS = const ParserErrorCode(
-      'ENUM_IN_CLASS',
-      "Enums can't be declared inside classes.",
-      "Try moving the enum to the top-level.");
+      'ENUM_IN_CLASS', "Enums can't be declared inside classes.",
+      correction: "Try moving the enum to the top-level.");
 
   static const ParserErrorCode EQUALITY_CANNOT_BE_EQUALITY_OPERAND =
-      const ParserErrorCode(
-          'EQUALITY_CANNOT_BE_EQUALITY_OPERAND',
+      const ParserErrorCode('EQUALITY_CANNOT_BE_EQUALITY_OPERAND',
           "An equality expression can't be an operand of another equality expression.",
-          "Try re-writing the expression.");
+          correction: "Try re-writing the expression.");
 
   static const ParserErrorCode EXPECTED_CASE_OR_DEFAULT = const ParserErrorCode(
-      'EXPECTED_CASE_OR_DEFAULT',
-      "Expected 'case' or 'default'.",
-      "Try placing this code inside a case clause.");
+      'EXPECTED_CASE_OR_DEFAULT', "Expected 'case' or 'default'.",
+      correction: "Try placing this code inside a case clause.");
 
   static const ParserErrorCode EXPECTED_CLASS_MEMBER = const ParserErrorCode(
-      'EXPECTED_CLASS_MEMBER',
-      "Expected a class member.",
-      "Try placing this code inside a class member.");
+      'EXPECTED_CLASS_MEMBER', "Expected a class member.",
+      correction: "Try placing this code inside a class member.");
 
   static const ParserErrorCode EXPECTED_EXECUTABLE = const ParserErrorCode(
       'EXPECTED_EXECUTABLE',
       "Expected a method, getter, setter or operator declaration.",
-      "This appears to be incomplete code. Try removing it or completing it.");
+      correction:
+          "This appears to be incomplete code. Try removing it or completing it.");
 
-  static const ParserErrorCode EXPECTED_LIST_OR_MAP_LITERAL =
-      const ParserErrorCode(
-          'EXPECTED_LIST_OR_MAP_LITERAL',
-          "Expected a list or map literal.",
+  static const ParserErrorCode EXPECTED_LIST_OR_MAP_LITERAL = const ParserErrorCode(
+      'EXPECTED_LIST_OR_MAP_LITERAL', "Expected a list or map literal.",
+      correction:
           "Try inserting a list or map literal, or remove the type arguments.");
 
   static const ParserErrorCode EXPECTED_STRING_LITERAL = const ParserErrorCode(
@@ -281,192 +267,178 @@
       const ParserErrorCode('EXPECTED_TYPE_NAME', "Expected a type name.");
 
   static const ParserErrorCode EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
-      const ParserErrorCode(
-          'EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
+      const ParserErrorCode('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
           "Export directives must preceed part directives.",
-          "Try moving the export directives before the part directives.");
+          correction:
+              "Try moving the export directives before the part directives.");
 
   static const ParserErrorCode EXTERNAL_AFTER_CONST = const ParserErrorCode(
       'EXTERNAL_AFTER_CONST',
       "The modifier 'external' should be before the modifier 'const'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode EXTERNAL_AFTER_FACTORY = const ParserErrorCode(
       'EXTERNAL_AFTER_FACTORY',
       "The modifier 'external' should be before the modifier 'factory'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode EXTERNAL_AFTER_STATIC = const ParserErrorCode(
       'EXTERNAL_AFTER_STATIC',
       "The modifier 'external' should be before the modifier 'static'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode EXTERNAL_CLASS = const ParserErrorCode(
-      'EXTERNAL_CLASS',
-      "Classes can't be declared to be 'external'.",
-      "Try removing the keyword 'external'.");
+      'EXTERNAL_CLASS', "Classes can't be declared to be 'external'.",
+      correction: "Try removing the keyword 'external'.");
 
   static const ParserErrorCode EXTERNAL_CONSTRUCTOR_WITH_BODY =
-      const ParserErrorCode(
-          'EXTERNAL_CONSTRUCTOR_WITH_BODY',
+      const ParserErrorCode('EXTERNAL_CONSTRUCTOR_WITH_BODY',
           "External constructors can't have a body.",
-          "Try removing the body of the constructor, or "
-          "removing the keyword 'external'.");
+          correction: "Try removing the body of the constructor, or "
+              "removing the keyword 'external'.");
 
   static const ParserErrorCode EXTERNAL_ENUM = const ParserErrorCode(
-      'EXTERNAL_ENUM',
-      "Enums can't be declared to be 'external'.",
-      "Try removing the keyword 'external'.");
+      'EXTERNAL_ENUM', "Enums can't be declared to be 'external'.",
+      correction: "Try removing the keyword 'external'.");
 
   static const ParserErrorCode EXTERNAL_FIELD = const ParserErrorCode(
-      'EXTERNAL_FIELD',
-      "Fields can't be declared to be 'external'.",
-      "Try removing the keyword 'external'.");
+      'EXTERNAL_FIELD', "Fields can't be declared to be 'external'.",
+      correction: "Try removing the keyword 'external'.");
 
   static const ParserErrorCode EXTERNAL_GETTER_WITH_BODY =
       const ParserErrorCode(
-          'EXTERNAL_GETTER_WITH_BODY',
-          "External getters can't have a body.",
-          "Try removing the body of the getter, or "
-          "removing the keyword 'external'.");
+          'EXTERNAL_GETTER_WITH_BODY', "External getters can't have a body.",
+          correction: "Try removing the body of the getter, or "
+              "removing the keyword 'external'.");
 
   static const ParserErrorCode EXTERNAL_METHOD_WITH_BODY =
-      const ParserErrorCode(
-          'EXTERNAL_METHOD_WITH_BODY',
+      const ParserErrorCode('EXTERNAL_METHOD_WITH_BODY',
           "An external or native method can't have a body.",
-          "Try removing the body of the method, or "
-          "removing the keyword 'external'.");
+          correction: "Try removing the body of the method, or "
+              "removing the keyword 'external'.");
 
   static const ParserErrorCode EXTERNAL_OPERATOR_WITH_BODY =
-      const ParserErrorCode(
-          'EXTERNAL_OPERATOR_WITH_BODY',
+      const ParserErrorCode('EXTERNAL_OPERATOR_WITH_BODY',
           "External operators can't have a body.",
-          "Try removing the body of the operator, or "
-          "removing the keyword 'external'.");
+          correction: "Try removing the body of the operator, or "
+              "removing the keyword 'external'.");
 
   static const ParserErrorCode EXTERNAL_SETTER_WITH_BODY =
       const ParserErrorCode(
-          'EXTERNAL_SETTER_WITH_BODY',
-          "External setters can't have a body.",
-          "Try removing the body of the setter, or "
-          "removing the keyword 'external'.");
+          'EXTERNAL_SETTER_WITH_BODY', "External setters can't have a body.",
+          correction: "Try removing the body of the setter, or "
+              "removing the keyword 'external'.");
 
   static const ParserErrorCode EXTERNAL_TYPEDEF = const ParserErrorCode(
-      'EXTERNAL_TYPEDEF',
-      "Typedefs can't be declared to be 'external'.",
-      "Try removing the keyword 'external'.");
+      'EXTERNAL_TYPEDEF', "Typedefs can't be declared to be 'external'.",
+      correction: "Try removing the keyword 'external'.");
 
   static const ParserErrorCode EXTRANEOUS_MODIFIER = const ParserErrorCode(
-      'EXTRANEOUS_MODIFIER',
-      "Can't have modifier '{0}' here.",
-      "Try removing '{0}'.");
+      'EXTRANEOUS_MODIFIER', "Can't have modifier '{0}' here.",
+      correction: "Try removing '{0}'.");
 
   static const ParserErrorCode FACTORY_TOP_LEVEL_DECLARATION =
-      const ParserErrorCode(
-          'FACTORY_TOP_LEVEL_DECLARATION',
+      const ParserErrorCode('FACTORY_TOP_LEVEL_DECLARATION',
           "Top-level declarations can't be declared to be 'factory'.",
-          "Try removing the keyword 'factory'.");
+          correction: "Try removing the keyword 'factory'.");
 
   static const ParserErrorCode FACTORY_WITH_INITIALIZERS = const ParserErrorCode(
       'FACTORY_WITH_INITIALIZERS',
       "A 'factory' constructor can't have initializers.",
-      "Try removing the 'factory' keyword to make this a generative constructor, or "
-      "removing the initializers.");
+      correction:
+          "Try removing the 'factory' keyword to make this a generative constructor, or "
+          "removing the initializers.");
 
   static const ParserErrorCode FACTORY_WITHOUT_BODY = const ParserErrorCode(
       'FACTORY_WITHOUT_BODY',
       "A non-redirecting 'factory' constructor must have a body.",
-      "Try adding a body to the constructor.");
+      correction: "Try adding a body to the constructor.");
 
   static const ParserErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR =
-      const ParserErrorCode(
-          'FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR',
+      const ParserErrorCode('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR',
           "Field formal parameters can only be used in a constructor.",
-          "Try replacing the field formal parameter with a normal parameter.");
+          correction:
+              "Try replacing the field formal parameter with a normal parameter.");
 
   static const ParserErrorCode FINAL_AND_COVARIANT = const ParserErrorCode(
       'FINAL_AND_COVARIANT',
       "Members can't be declared to be both 'final' and 'covariant'.",
-      "Try removing either the 'final' or 'covariant' keyword.");
+      correction: "Try removing either the 'final' or 'covariant' keyword.");
 
   static const ParserErrorCode FINAL_AND_VAR = const ParserErrorCode(
       'FINAL_AND_VAR',
       "Members can't be declared to be both 'final' and 'var'.",
-      "Try removing the keyword 'var'.");
+      correction: "Try removing the keyword 'var'.");
 
   static const ParserErrorCode FINAL_CLASS = const ParserErrorCode(
-      'FINAL_CLASS',
-      "Classes can't be declared to be 'final'.",
-      "Try removing the keyword 'final'.");
+      'FINAL_CLASS', "Classes can't be declared to be 'final'.",
+      correction: "Try removing the keyword 'final'.");
 
   static const ParserErrorCode FINAL_CONSTRUCTOR = const ParserErrorCode(
-      'FINAL_CONSTRUCTOR',
-      "A constructor can't be declared to be 'final'.",
-      "Try removing the keyword 'final'.");
+      'FINAL_CONSTRUCTOR', "A constructor can't be declared to be 'final'.",
+      correction: "Try removing the keyword 'final'.");
 
   static const ParserErrorCode FINAL_ENUM = const ParserErrorCode(
-      'FINAL_ENUM',
-      "Enums can't be declared to be 'final'.",
-      "Try removing the keyword 'final'.");
+      'FINAL_ENUM', "Enums can't be declared to be 'final'.",
+      correction: "Try removing the keyword 'final'.");
 
   static const ParserErrorCode FINAL_METHOD = const ParserErrorCode(
       'FINAL_METHOD',
       "Getters, setters and methods can't be declared to be 'final'.",
-      "Try removing the keyword 'final'.");
+      correction: "Try removing the keyword 'final'.");
 
   static const ParserErrorCode FINAL_TYPEDEF = const ParserErrorCode(
-      'FINAL_TYPEDEF',
-      "Typedefs can't be declared to be 'final'.",
-      "Try removing the keyword 'final'.");
+      'FINAL_TYPEDEF', "Typedefs can't be declared to be 'final'.",
+      correction: "Try removing the keyword 'final'.");
 
   static const ParserErrorCode FUNCTION_TYPED_PARAMETER_VAR = const ParserErrorCode(
       'FUNCTION_TYPED_PARAMETER_VAR',
       "Function-typed parameters can't specify 'const', 'final' or 'var' in place of a return type.",
-      "Try replacing the keyword with a return type.");
+      correction: "Try replacing the keyword with a return type.");
 
   static const ParserErrorCode GETTER_IN_FUNCTION = const ParserErrorCode(
       'GETTER_IN_FUNCTION',
       "Getters can't be defined within methods or functions.",
-      "Try moving the getter outside the method or function, or "
-      "converting the getter to a function.");
+      correction: "Try moving the getter outside the method or function, or "
+          "converting the getter to a function.");
 
   static const ParserErrorCode GETTER_WITH_PARAMETERS = const ParserErrorCode(
       'GETTER_WITH_PARAMETERS',
       "Getters must be declared without a parameter list.",
-      "Try removing the parameter list, or "
-      "removing the keyword 'get' to define a method rather than a getter.");
+      correction: "Try removing the parameter list, or "
+          "removing the keyword 'get' to define a method rather than a getter.");
 
   static const ParserErrorCode ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE =
       const ParserErrorCode('ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE',
           "Illegal assignment to non-assignable expression.");
 
   static const ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS =
-      const ParserErrorCode(
-          'IMPLEMENTS_BEFORE_EXTENDS',
+      const ParserErrorCode('IMPLEMENTS_BEFORE_EXTENDS',
           "The extends clause must be before the implements clause.",
-          "Try moving the extends clause before the implements clause.");
+          correction:
+              "Try moving the extends clause before the implements clause.");
 
   static const ParserErrorCode IMPLEMENTS_BEFORE_WITH = const ParserErrorCode(
       'IMPLEMENTS_BEFORE_WITH',
       "The with clause must be before the implements clause.",
-      "Try moving the with clause before the implements clause.");
+      correction: "Try moving the with clause before the implements clause.");
 
   static const ParserErrorCode IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
-      const ParserErrorCode(
-          'IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
+      const ParserErrorCode('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
           "Import directives must preceed part directives.",
-          "Try moving the import directives before the part directives.");
+          correction:
+              "Try moving the import directives before the part directives.");
 
   static const ParserErrorCode INITIALIZED_VARIABLE_IN_FOR_EACH =
-      const ParserErrorCode(
-          'INITIALIZED_VARIABLE_IN_FOR_EACH',
+      const ParserErrorCode('INITIALIZED_VARIABLE_IN_FOR_EACH',
           "The loop variable in a for-each loop can't be initialized.",
-          "Try removing the initializer, or using a different kind of loop.");
+          correction:
+              "Try removing the initializer, or using a different kind of loop.");
 
   static const ParserErrorCode INVALID_AWAIT_IN_FOR = const ParserErrorCode(
       'INVALID_AWAIT_IN_FOR',
       "The keyword 'await' isn't allowed for a normal 'for' statement.",
-      "Try removing the keyword, or use a for-each statement.");
+      correction: "Try removing the keyword, or use a for-each statement.");
 
   /**
    * Parameters:
@@ -484,23 +456,22 @@
   static const ParserErrorCode INVALID_CONSTRUCTOR_NAME = const ParserErrorCode(
       'INVALID_CONSTRUCTOR_NAME',
       "The keyword '{0}' cannot be used to name a constructor.",
-      "Try giving the constructor a different name.");
+      correction: "Try giving the constructor a different name.");
 
   static const ParserErrorCode INVALID_GENERIC_FUNCTION_TYPE =
       const ParserErrorCode(
-          'INVALID_GENERIC_FUNCTION_TYPE',
-          "Invalid generic function type.",
-          "Try using a generic function type (returnType 'Function(' parameters ')').");
+          'INVALID_GENERIC_FUNCTION_TYPE', "Invalid generic function type.",
+          correction:
+              "Try using a generic function type (returnType 'Function(' parameters ')').");
 
   static const ParserErrorCode INVALID_HEX_ESCAPE = const ParserErrorCode(
       'INVALID_HEX_ESCAPE',
       "An escape sequence starting with '\\x' must be followed by 2 hexidecimal digits.");
 
   static const ParserErrorCode INVALID_LITERAL_IN_CONFIGURATION =
-      const ParserErrorCode(
-          'INVALID_LITERAL_IN_CONFIGURATION',
+      const ParserErrorCode('INVALID_LITERAL_IN_CONFIGURATION',
           "The literal in a configuration can't contain interpolation.",
-          "Try removing the interpolation expressions.");
+          correction: "Try removing the interpolation expressions.");
 
   /**
    * Parameters:
@@ -520,12 +491,12 @@
   static const ParserErrorCode INVALID_STAR_AFTER_ASYNC = const ParserErrorCode(
       'INVALID_STAR_AFTER_ASYNC',
       "The modifier 'async*' isn't allowed for an expression function body.",
-      "Try converting the body to a block.");
+      correction: "Try converting the body to a block.");
 
   static const ParserErrorCode INVALID_SYNC = const ParserErrorCode(
       'INVALID_SYNC',
       "The modifier 'sync' isn't allowed for an expression function body.",
-      "Try converting the body to a block.");
+      correction: "Try converting the body to a block.");
 
   static const ParserErrorCode INVALID_UNICODE_ESCAPE = const ParserErrorCode(
       'INVALID_UNICODE_ESCAPE',
@@ -533,89 +504,82 @@
       "hexidecimal digits or from 1 to 6 digits between '{' and '}'.");
 
   static const ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST =
-      const ParserErrorCode(
-          'LIBRARY_DIRECTIVE_NOT_FIRST',
+      const ParserErrorCode('LIBRARY_DIRECTIVE_NOT_FIRST',
           "The library directive must appear before all other directives.",
-          "Try moving the library directive before any other directives.");
+          correction:
+              "Try moving the library directive before any other directives.");
 
   static const ParserErrorCode LOCAL_FUNCTION_DECLARATION_MODIFIER =
-      const ParserErrorCode(
-          'LOCAL_FUNCTION_DECLARATION_MODIFIER',
+      const ParserErrorCode('LOCAL_FUNCTION_DECLARATION_MODIFIER',
           "Local function declarations can't specify any modifiers.",
-          "Try removing the modifier.");
+          correction: "Try removing the modifier.");
 
   static const ParserErrorCode MISSING_ASSIGNABLE_SELECTOR =
-      const ParserErrorCode(
-          'MISSING_ASSIGNABLE_SELECTOR',
+      const ParserErrorCode('MISSING_ASSIGNABLE_SELECTOR',
           "Missing selector such as '.<identifier>' or '[0]'.",
-          "Try adding a selector.");
+          correction: "Try adding a selector.");
 
   static const ParserErrorCode MISSING_ASSIGNMENT_IN_INITIALIZER =
-      const ParserErrorCode(
-          'MISSING_ASSIGNMENT_IN_INITIALIZER',
+      const ParserErrorCode('MISSING_ASSIGNMENT_IN_INITIALIZER',
           "Expected an assignment after the field name.",
-          "Try adding an assignment to initialize the field.");
+          correction: "Try adding an assignment to initialize the field.");
 
   static const ParserErrorCode MISSING_CATCH_OR_FINALLY = const ParserErrorCode(
       'MISSING_CATCH_OR_FINALLY',
       "A try statement must have either a catch or finally clause.",
-      "Try adding either a catch or finally clause, or "
-      "remove the try statement.");
+      correction: "Try adding either a catch or finally clause, or "
+          "remove the try statement.");
 
   static const ParserErrorCode MISSING_CLASS_BODY = const ParserErrorCode(
       'MISSING_CLASS_BODY',
       "A class definition must have a body, even if it is empty.",
-      "Try adding a class body.");
+      correction: "Try adding a class body.");
 
   static const ParserErrorCode MISSING_CLOSING_PARENTHESIS =
       const ParserErrorCode(
-          'MISSING_CLOSING_PARENTHESIS',
-          "The closing parenthesis is missing.",
-          "Try adding the closing parenthesis.");
+          'MISSING_CLOSING_PARENTHESIS', "The closing parenthesis is missing.",
+          correction: "Try adding the closing parenthesis.");
 
   static const ParserErrorCode MISSING_CONST_FINAL_VAR_OR_TYPE = const ParserErrorCode(
       'MISSING_CONST_FINAL_VAR_OR_TYPE',
       "Variables must be declared using the keywords 'const', 'final', 'var' or a type name.",
-      "Try adding the name of the type of the variable or the keyword 'var'.");
+      correction:
+          "Try adding the name of the type of the variable or the keyword 'var'.");
 
   static const ParserErrorCode MISSING_ENUM_BODY = const ParserErrorCode(
       'MISSING_ENUM_BODY',
       "An enum definition must have a body with at least one constant name.",
-      "Try adding a body and defining at least one constant.");
+      correction: "Try adding a body and defining at least one constant.");
 
   static const ParserErrorCode MISSING_EXPRESSION_IN_INITIALIZER =
-      const ParserErrorCode(
-          'MISSING_EXPRESSION_IN_INITIALIZER',
+      const ParserErrorCode('MISSING_EXPRESSION_IN_INITIALIZER',
           "Expected an expression after the assignment operator.",
-          "Try adding the value to be assigned, or "
-          "remove the assignment operator.");
+          correction: "Try adding the value to be assigned, or "
+              "remove the assignment operator.");
 
   static const ParserErrorCode MISSING_EXPRESSION_IN_THROW =
       const ParserErrorCode(
-          'MISSING_EXPRESSION_IN_THROW',
-          "Missing expression after 'throw'.",
-          "Try using 'rethrow' to throw the caught exception.");
+          'MISSING_EXPRESSION_IN_THROW', "Missing expression after 'throw'.",
+          correction: "Try using 'rethrow' to throw the caught exception.");
 
   static const ParserErrorCode MISSING_FUNCTION_BODY = const ParserErrorCode(
-      'MISSING_FUNCTION_BODY',
-      "A function body must be provided.",
-      "Try adding a function body.");
+      'MISSING_FUNCTION_BODY', "A function body must be provided.",
+      correction: "Try adding a function body.");
 
   static const ParserErrorCode MISSING_FUNCTION_KEYWORD = const ParserErrorCode(
       'MISSING_FUNCTION_KEYWORD',
       "Function types must have the keyword 'Function' before the parameter list.",
-      "Try adding the keyword 'Function'.");
+      correction: "Try adding the keyword 'Function'.");
 
   static const ParserErrorCode MISSING_FUNCTION_PARAMETERS =
-      const ParserErrorCode(
-          'MISSING_FUNCTION_PARAMETERS',
+      const ParserErrorCode('MISSING_FUNCTION_PARAMETERS',
           "Functions must have an explicit list of parameters.",
-          "Try adding a parameter list.");
+          correction: "Try adding a parameter list.");
 
   static const ParserErrorCode MISSING_GET = const ParserErrorCode(
       'MISSING_GET',
       "Getters must have the keyword 'get' before the getter name.",
-      "Try adding the keyword 'get'.");
+      correction: "Try adding the keyword 'get'.");
 
   static const ParserErrorCode MISSING_IDENTIFIER =
       const ParserErrorCode('MISSING_IDENTIFIER', "Expected an identifier.");
@@ -626,43 +590,40 @@
   static const ParserErrorCode MISSING_KEYWORD_OPERATOR = const ParserErrorCode(
       'MISSING_KEYWORD_OPERATOR',
       "Operator declarations must be preceeded by the keyword 'operator'.",
-      "Try adding the keyword 'operator'.");
+      correction: "Try adding the keyword 'operator'.");
 
   static const ParserErrorCode MISSING_METHOD_PARAMETERS =
-      const ParserErrorCode(
-          'MISSING_METHOD_PARAMETERS',
+      const ParserErrorCode('MISSING_METHOD_PARAMETERS',
           "Methods must have an explicit list of parameters.",
-          "Try adding a parameter list.");
+          correction: "Try adding a parameter list.");
 
   static const ParserErrorCode MISSING_NAME_FOR_NAMED_PARAMETER =
-      const ParserErrorCode(
-          'MISSING_NAME_FOR_NAMED_PARAMETER',
+      const ParserErrorCode('MISSING_NAME_FOR_NAMED_PARAMETER',
           "Named parameters in a function type must have a name",
-          "Try providing a name for the parameter or removing the curly braces.");
+          correction:
+              "Try providing a name for the parameter or removing the curly braces.");
 
   static const ParserErrorCode MISSING_NAME_IN_LIBRARY_DIRECTIVE =
-      const ParserErrorCode(
-          'MISSING_NAME_IN_LIBRARY_DIRECTIVE',
+      const ParserErrorCode('MISSING_NAME_IN_LIBRARY_DIRECTIVE',
           "Library directives must include a library name.",
-          "Try adding a library name after the keyword 'library', or "
-          "remove the library directive if the library doesn't have any parts.");
+          correction:
+              "Try adding a library name after the keyword 'library', or "
+              "remove the library directive if the library doesn't have any parts.");
 
   static const ParserErrorCode MISSING_NAME_IN_PART_OF_DIRECTIVE =
-      const ParserErrorCode(
-          'MISSING_NAME_IN_PART_OF_DIRECTIVE',
+      const ParserErrorCode('MISSING_NAME_IN_PART_OF_DIRECTIVE',
           "Part-of directives must include a library name.",
-          "Try adding a library name after the 'of'.");
+          correction: "Try adding a library name after the 'of'.");
 
   static const ParserErrorCode MISSING_PREFIX_IN_DEFERRED_IMPORT =
-      const ParserErrorCode(
-          'MISSING_PREFIX_IN_DEFERRED_IMPORT',
+      const ParserErrorCode('MISSING_PREFIX_IN_DEFERRED_IMPORT',
           "Deferred imports should have a prefix.",
-          "Try adding a prefix to the import.");
+          correction: "Try adding a prefix to the import.");
 
   static const ParserErrorCode MISSING_STAR_AFTER_SYNC = const ParserErrorCode(
       'MISSING_STAR_AFTER_SYNC',
       "The modifier 'sync' must be followed by a star ('*').",
-      "Try removing the modifier, or add a star.");
+      correction: "Try removing the modifier, or add a star.");
 
   static const ParserErrorCode MISSING_STATEMENT =
       const ParserErrorCode('MISSING_STATEMENT', "Expected a statement.");
@@ -672,61 +633,56 @@
    * 0: the terminator that is missing
    */
   static const ParserErrorCode MISSING_TERMINATOR_FOR_PARAMETER_GROUP =
-      const ParserErrorCode(
-          'MISSING_TERMINATOR_FOR_PARAMETER_GROUP',
+      const ParserErrorCode('MISSING_TERMINATOR_FOR_PARAMETER_GROUP',
           "There is no '{0}' to close the parameter group.",
-          "Try inserting a '{0}' at the end of the group.");
+          correction: "Try inserting a '{0}' at the end of the group.");
 
   static const ParserErrorCode MISSING_TYPEDEF_PARAMETERS =
-      const ParserErrorCode(
-          'MISSING_TYPEDEF_PARAMETERS',
+      const ParserErrorCode('MISSING_TYPEDEF_PARAMETERS',
           "Typedefs must have an explicit list of parameters.",
-          "Try adding a parameter list.");
+          correction: "Try adding a parameter list.");
 
   static const ParserErrorCode MISSING_VARIABLE_IN_FOR_EACH = const ParserErrorCode(
       'MISSING_VARIABLE_IN_FOR_EACH',
       "A loop variable must be declared in a for-each loop before the 'in', but none was found.",
-      "Try declaring a loop variable.");
+      correction: "Try declaring a loop variable.");
 
   static const ParserErrorCode MIXED_PARAMETER_GROUPS = const ParserErrorCode(
       'MIXED_PARAMETER_GROUPS',
       "Can't have both positional and named parameters in a single parameter list.",
-      "Try choosing a single style of optional parameters.");
+      correction: "Try choosing a single style of optional parameters.");
 
   static const ParserErrorCode MULTIPLE_EXTENDS_CLAUSES = const ParserErrorCode(
       'MULTIPLE_EXTENDS_CLAUSES',
       "Each class definition can have at most one extends clause.",
-      "Try choosing one superclass and define your class to implement (or mix in) the others.");
+      correction:
+          "Try choosing one superclass and define your class to implement (or mix in) the others.");
 
-  static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES =
-      const ParserErrorCode(
-          'MULTIPLE_IMPLEMENTS_CLAUSES',
-          "Each class definition can have at most one implements clause.",
+  static const ParserErrorCode MULTIPLE_IMPLEMENTS_CLAUSES = const ParserErrorCode(
+      'MULTIPLE_IMPLEMENTS_CLAUSES',
+      "Each class definition can have at most one implements clause.",
+      correction:
           "Try combining all of the implements clauses into a single clause.");
 
   static const ParserErrorCode MULTIPLE_LIBRARY_DIRECTIVES =
-      const ParserErrorCode(
-          'MULTIPLE_LIBRARY_DIRECTIVES',
+      const ParserErrorCode('MULTIPLE_LIBRARY_DIRECTIVES',
           "Only one library directive may be declared in a file.",
-          "Try removing all but one of the library directives.");
+          correction: "Try removing all but one of the library directives.");
 
   static const ParserErrorCode MULTIPLE_NAMED_PARAMETER_GROUPS =
-      const ParserErrorCode(
-          'MULTIPLE_NAMED_PARAMETER_GROUPS',
+      const ParserErrorCode('MULTIPLE_NAMED_PARAMETER_GROUPS',
           "Can't have multiple groups of named parameters in a single parameter list.",
-          "Try combining all of the groups into a single group.");
+          correction: "Try combining all of the groups into a single group.");
 
   static const ParserErrorCode MULTIPLE_PART_OF_DIRECTIVES =
-      const ParserErrorCode(
-          'MULTIPLE_PART_OF_DIRECTIVES',
+      const ParserErrorCode('MULTIPLE_PART_OF_DIRECTIVES',
           "Only one part-of directive may be declared in a file.",
-          "Try removing all but one of the part-of directives.");
+          correction: "Try removing all but one of the part-of directives.");
 
   static const ParserErrorCode MULTIPLE_POSITIONAL_PARAMETER_GROUPS =
-      const ParserErrorCode(
-          'MULTIPLE_POSITIONAL_PARAMETER_GROUPS',
+      const ParserErrorCode('MULTIPLE_POSITIONAL_PARAMETER_GROUPS',
           "Can't have multiple groups of positional parameters in a single parameter list.",
-          "Try combining all of the groups into a single group.");
+          correction: "Try combining all of the groups into a single group.");
 
   /**
    * Parameters:
@@ -737,74 +693,70 @@
           'MULTIPLE_VARIABLES_IN_FOR_EACH',
           "A single loop variable must be declared in a for-each loop before "
           "the 'in', but {0} were found.",
-          "Try moving all but one of the declarations inside the loop body.");
+          correction:
+              "Try moving all but one of the declarations inside the loop body.");
 
   static const ParserErrorCode MULTIPLE_WITH_CLAUSES = const ParserErrorCode(
       'MULTIPLE_WITH_CLAUSES',
       "Each class definition can have at most one with clause.",
-      "Try combining all of the with clauses into a single clause.");
+      correction:
+          "Try combining all of the with clauses into a single clause.");
 
   static const ParserErrorCode NAMED_FUNCTION_EXPRESSION = const ParserErrorCode(
-      'NAMED_FUNCTION_EXPRESSION',
-      "Function expressions can't be named.",
-      "Try removing the name, or "
-      "moving the function expression to a function declaration statement.");
+      'NAMED_FUNCTION_EXPRESSION', "Function expressions can't be named.",
+      correction: "Try removing the name, or "
+          "moving the function expression to a function declaration statement.");
 
   static const ParserErrorCode NAMED_FUNCTION_TYPE = const ParserErrorCode(
-      'NAMED_FUNCTION_TYPE',
-      "Function types can't be named.",
-      "Try replacing the name with the keyword 'Function'.");
+      'NAMED_FUNCTION_TYPE', "Function types can't be named.",
+      correction: "Try replacing the name with the keyword 'Function'.");
 
   static const ParserErrorCode NAMED_PARAMETER_OUTSIDE_GROUP =
-      const ParserErrorCode(
-          'NAMED_PARAMETER_OUTSIDE_GROUP',
+      const ParserErrorCode('NAMED_PARAMETER_OUTSIDE_GROUP',
           "Named parameters must be enclosed in curly braces ('{' and '}').",
-          "Try surrounding the named parameters in curly braces.");
+          correction: "Try surrounding the named parameters in curly braces.");
 
   static const ParserErrorCode NATIVE_CLAUSE_IN_NON_SDK_CODE =
       const ParserErrorCode(
           'NATIVE_CLAUSE_IN_NON_SDK_CODE',
           "Native clause can only be used in the SDK and code that is loaded "
           "through native extensions.",
-          "Try removing the native clause.");
+          correction: "Try removing the native clause.");
 
   static const ParserErrorCode NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE =
       const ParserErrorCode(
           'NATIVE_FUNCTION_BODY_IN_NON_SDK_CODE',
           "Native functions can only be declared in the SDK and code that is "
           "loaded through native extensions.",
-          "Try removing the word 'native'.");
+          correction: "Try removing the word 'native'.");
 
   static const ParserErrorCode NATIVE_CLAUSE_SHOULD_BE_ANNOTATION =
-      const ParserErrorCode(
-          'NATIVE_CLAUSE_SHOULD_BE_ANNOTATION',
+      const ParserErrorCode('NATIVE_CLAUSE_SHOULD_BE_ANNOTATION',
           "Native clause in this form is deprecated.",
-          "Try removing this native clause and adding @native()"
-          " or @native('native-name') before the declaration.");
+          correction: "Try removing this native clause and adding @native()"
+              " or @native('native-name') before the declaration.");
 
   static const ParserErrorCode NON_CONSTRUCTOR_FACTORY = const ParserErrorCode(
       'NON_CONSTRUCTOR_FACTORY',
       "Only a constructor can be declared to be a factory.",
-      "Try removing the keyword 'factory'.");
+      correction: "Try removing the keyword 'factory'.");
 
   static const ParserErrorCode NON_IDENTIFIER_LIBRARY_NAME =
-      const ParserErrorCode(
-          'NON_IDENTIFIER_LIBRARY_NAME',
+      const ParserErrorCode('NON_IDENTIFIER_LIBRARY_NAME',
           "The name of a library must be an identifier.",
-          "Try using an identifier as the name of the library.");
+          correction: "Try using an identifier as the name of the library.");
 
   static const ParserErrorCode NON_PART_OF_DIRECTIVE_IN_PART =
-      const ParserErrorCode(
-          'NON_PART_OF_DIRECTIVE_IN_PART',
+      const ParserErrorCode('NON_PART_OF_DIRECTIVE_IN_PART',
           "The part-of directive must be the only directive in a part.",
-          "Try removing the other directives, or "
-          "moving them to the library for which this is a part.");
+          correction: "Try removing the other directives, or "
+              "moving them to the library for which this is a part.");
 
   static const ParserErrorCode NON_STRING_LITERAL_AS_URI =
       const ParserErrorCode(
-          'NON_STRING_LITERAL_AS_URI',
-          "The URI must be a string literal.",
-          "Try enclosing the URI in either single or double quotes.");
+          'NON_STRING_LITERAL_AS_URI', "The URI must be a string literal.",
+          correction:
+              "Try enclosing the URI in either single or double quotes.");
 
   /**
    * Parameters:
@@ -815,178 +767,164 @@
           "The operator '{0}' isn't user definable.");
 
   static const ParserErrorCode NORMAL_BEFORE_OPTIONAL_PARAMETERS =
-      const ParserErrorCode(
-          'NORMAL_BEFORE_OPTIONAL_PARAMETERS',
+      const ParserErrorCode('NORMAL_BEFORE_OPTIONAL_PARAMETERS',
           "Normal parameters must occur before optional parameters.",
-          "Try moving all of the normal parameters before the optional parameters.");
+          correction:
+              "Try moving all of the normal parameters before the optional parameters.");
 
   static const ParserErrorCode NULLABLE_TYPE_IN_EXTENDS = const ParserErrorCode(
       'NULLABLE_TYPE_IN_EXTENDS',
       "A nullable type can't be used in an extends clause.",
-      "Try removing the '?' from the type name.");
+      correction: "Try removing the '?' from the type name.");
 
   static const ParserErrorCode NULLABLE_TYPE_IN_IMPLEMENTS =
-      const ParserErrorCode(
-          'NULLABLE_TYPE_IN_IMPLEMENTS',
+      const ParserErrorCode('NULLABLE_TYPE_IN_IMPLEMENTS',
           "A nullable type can't be used in an implements clause.",
-          "Try removing the '?' from the type name.");
+          correction: "Try removing the '?' from the type name.");
 
   static const ParserErrorCode NULLABLE_TYPE_IN_WITH = const ParserErrorCode(
       'NULLABLE_TYPE_IN_WITH',
       "A nullable type can't be used in a with clause.",
-      "Try removing the '?' from the type name.");
+      correction: "Try removing the '?' from the type name.");
 
   static const ParserErrorCode NULLABLE_TYPE_PARAMETER = const ParserErrorCode(
-      'NULLABLE_TYPE_PARAMETER',
-      "Type parameters can't be nullable.",
-      "Try removing the '?' from the type name.");
+      'NULLABLE_TYPE_PARAMETER', "Type parameters can't be nullable.",
+      correction: "Try removing the '?' from the type name.");
 
   static const ParserErrorCode POSITIONAL_AFTER_NAMED_ARGUMENT =
-      const ParserErrorCode(
-          'POSITIONAL_AFTER_NAMED_ARGUMENT',
+      const ParserErrorCode('POSITIONAL_AFTER_NAMED_ARGUMENT',
           "Positional arguments must occur before named arguments.",
-          "Try moving all of the positional arguments before the named arguments.");
+          correction:
+              "Try moving all of the positional arguments before the named arguments.");
 
   static const ParserErrorCode POSITIONAL_PARAMETER_OUTSIDE_GROUP =
-      const ParserErrorCode(
-          'POSITIONAL_PARAMETER_OUTSIDE_GROUP',
+      const ParserErrorCode('POSITIONAL_PARAMETER_OUTSIDE_GROUP',
           "Positional parameters must be enclosed in square brackets ('[' and ']').",
-          "Try surrounding the positional parameters in square brackets.");
+          correction:
+              "Try surrounding the positional parameters in square brackets.");
 
   static const ParserErrorCode PREFIX_AFTER_COMBINATOR = const ParserErrorCode(
       'PREFIX_AFTER_COMBINATOR',
       "The prefix ('as' clause) should come before any show/hide combinators.",
-      "Try moving the prefix before the combinators.");
+      correction: "Try moving the prefix before the combinators.");
 
   static const ParserErrorCode REDIRECTING_CONSTRUCTOR_WITH_BODY =
-      const ParserErrorCode(
-          'REDIRECTING_CONSTRUCTOR_WITH_BODY',
+      const ParserErrorCode('REDIRECTING_CONSTRUCTOR_WITH_BODY',
           "Redirecting constructors can't have a body.",
-          "Try removing the body, or "
-          "not making this a redirecting constructor.");
+          correction: "Try removing the body, or "
+              "not making this a redirecting constructor.");
 
   static const ParserErrorCode REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR =
-      const ParserErrorCode(
-          'REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR',
+      const ParserErrorCode('REDIRECTION_IN_NON_FACTORY_CONSTRUCTOR',
           "Only factory constructor can specify '=' redirection.",
-          "Try making this a factory constructor, or "
-          "not making this a redirecting constructor.");
+          correction: "Try making this a factory constructor, or "
+              "not making this a redirecting constructor.");
 
   static const ParserErrorCode SETTER_IN_FUNCTION = const ParserErrorCode(
       'SETTER_IN_FUNCTION',
       "Setters can't be defined within methods or functions.",
-      "Try moving the setter outside the method or function.");
+      correction: "Try moving the setter outside the method or function.");
 
   static const ParserErrorCode STACK_OVERFLOW = const ParserErrorCode(
       'STACK_OVERFLOW',
       "The file has too many nested expressions or statements.",
-      "Try simplifying the code.");
+      correction: "Try simplifying the code.");
 
   static const ParserErrorCode STATIC_AFTER_CONST = const ParserErrorCode(
       'STATIC_AFTER_CONST',
       "The modifier 'static' should be before the modifier 'const'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode STATIC_AFTER_FINAL = const ParserErrorCode(
       'STATIC_AFTER_FINAL',
       "The modifier 'static' should be before the modifier 'final'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode STATIC_AFTER_VAR = const ParserErrorCode(
       'STATIC_AFTER_VAR',
       "The modifier 'static' should be before the modifier 'var'.",
-      "Try re-ordering the modifiers.");
+      correction: "Try re-ordering the modifiers.");
 
   static const ParserErrorCode STATIC_CONSTRUCTOR = const ParserErrorCode(
-      'STATIC_CONSTRUCTOR',
-      "Constructors can't be static.",
-      "Try removing the keyword 'static'.");
+      'STATIC_CONSTRUCTOR', "Constructors can't be static.",
+      correction: "Try removing the keyword 'static'.");
 
-  static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY =
-      const ParserErrorCode(
-          'STATIC_GETTER_WITHOUT_BODY',
-          "A 'static' getter must have a body.",
+  static const ParserErrorCode STATIC_GETTER_WITHOUT_BODY = const ParserErrorCode(
+      'STATIC_GETTER_WITHOUT_BODY', "A 'static' getter must have a body.",
+      correction:
           "Try adding a body to the getter, or removing the keyword 'static'.");
 
   static const ParserErrorCode STATIC_OPERATOR = const ParserErrorCode(
-      'STATIC_OPERATOR',
-      "Operators can't be static.",
-      "Try removing the keyword 'static'.");
+      'STATIC_OPERATOR', "Operators can't be static.",
+      correction: "Try removing the keyword 'static'.");
 
-  static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY =
-      const ParserErrorCode(
-          'STATIC_SETTER_WITHOUT_BODY',
-          "A 'static' setter must have a body.",
+  static const ParserErrorCode STATIC_SETTER_WITHOUT_BODY = const ParserErrorCode(
+      'STATIC_SETTER_WITHOUT_BODY', "A 'static' setter must have a body.",
+      correction:
           "Try adding a body to the setter, or removing the keyword 'static'.");
 
   static const ParserErrorCode STATIC_TOP_LEVEL_DECLARATION =
-      const ParserErrorCode(
-          'STATIC_TOP_LEVEL_DECLARATION',
+      const ParserErrorCode('STATIC_TOP_LEVEL_DECLARATION',
           "Top-level declarations can't be declared to be static.",
-          "Try removing the keyword 'static'.");
+          correction: "Try removing the keyword 'static'.");
 
   static const ParserErrorCode SWITCH_HAS_CASE_AFTER_DEFAULT_CASE =
-      const ParserErrorCode(
-          'SWITCH_HAS_CASE_AFTER_DEFAULT_CASE',
+      const ParserErrorCode('SWITCH_HAS_CASE_AFTER_DEFAULT_CASE',
           "The default case should be the last case in a switch statement.",
-          "Try moving the default case after the other case clauses.");
+          correction:
+              "Try moving the default case after the other case clauses.");
 
   static const ParserErrorCode SWITCH_HAS_MULTIPLE_DEFAULT_CASES =
-      const ParserErrorCode(
-          'SWITCH_HAS_MULTIPLE_DEFAULT_CASES',
+      const ParserErrorCode('SWITCH_HAS_MULTIPLE_DEFAULT_CASES',
           "The 'default' case can only be declared once.",
-          "Try removing all but one default case.");
+          correction: "Try removing all but one default case.");
 
   static const ParserErrorCode TOP_LEVEL_OPERATOR = const ParserErrorCode(
-      'TOP_LEVEL_OPERATOR',
-      "Operators must be declared within a class.",
-      "Try removing the operator, "
-      "moving it to a class, or "
-      "converting it to be a function.");
+      'TOP_LEVEL_OPERATOR', "Operators must be declared within a class.",
+      correction: "Try removing the operator, "
+          "moving it to a class, or "
+          "converting it to be a function.");
 
   static const ParserErrorCode TYPE_ARGUMENTS_ON_TYPE_VARIABLE =
-      const ParserErrorCode(
-          'TYPE_ARGUMENTS_ON_TYPE_VARIABLE',
+      const ParserErrorCode('TYPE_ARGUMENTS_ON_TYPE_VARIABLE',
           "Can't use type arguments with type variable '{0}'.",
-          "Try removing the type arguments.");
+          correction: "Try removing the type arguments.");
 
   static const ParserErrorCode TYPEDEF_IN_CLASS = const ParserErrorCode(
-      'TYPEDEF_IN_CLASS',
-      "Typedefs can't be declared inside classes.",
-      "Try moving the typedef to the top-level.");
+      'TYPEDEF_IN_CLASS', "Typedefs can't be declared inside classes.",
+      correction: "Try moving the typedef to the top-level.");
 
   /**
    * Parameters:
    * 0: the starting character that was missing
    */
   static const ParserErrorCode UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP =
-      const ParserErrorCode(
-          'UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP',
+      const ParserErrorCode('UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP',
           "There is no '{0}' to open a parameter group.",
-          "Try inserting the '{0}' at the appropriate location.");
+          correction: "Try inserting the '{0}' at the appropriate location.");
 
   /**
    * Parameters:
    * 0: the unexpected text that was found
    */
   static const ParserErrorCode UNEXPECTED_TOKEN = const ParserErrorCode(
-      'UNEXPECTED_TOKEN', "Unexpected text '{0}'.", "Try removing the text.");
+      'UNEXPECTED_TOKEN', "Unexpected text '{0}'.",
+      correction: "Try removing the text.");
 
   static const ParserErrorCode WITH_BEFORE_EXTENDS = const ParserErrorCode(
       'WITH_BEFORE_EXTENDS',
       "The extends clause must be before the with clause.",
-      "Try moving the extends clause before the with clause.");
+      correction: "Try moving the extends clause before the with clause.");
 
   static const ParserErrorCode WITH_WITHOUT_EXTENDS = const ParserErrorCode(
       'WITH_WITHOUT_EXTENDS',
       "The with clause can't be used without an extends clause.",
-      "Try adding an extends clause such as 'extends Object'.");
+      correction: "Try adding an extends clause such as 'extends Object'.");
 
   static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER =
-      const ParserErrorCode(
-          'WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER',
+      const ParserErrorCode('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER',
           "The default value of a positional parameter should be preceeded by '='.",
-          "Try replacing the ':' with '='.");
+          correction: "Try replacing the ':' with '='.");
 
   /**
    * Parameters:
@@ -994,42 +932,36 @@
    * 1: the terminator that was found
    */
   static const ParserErrorCode WRONG_TERMINATOR_FOR_PARAMETER_GROUP =
-      const ParserErrorCode(
-          'WRONG_TERMINATOR_FOR_PARAMETER_GROUP',
+      const ParserErrorCode('WRONG_TERMINATOR_FOR_PARAMETER_GROUP',
           "Expected '{0}' to close parameter group.",
-          "Try replacing '{0}' with '{1}'.");
+          correction: "Try replacing '{0}' with '{1}'.");
 
   static const ParserErrorCode VAR_AND_TYPE = const ParserErrorCode(
       'VAR_AND_TYPE',
       "Variables can't be declared using both 'var' and a type name.",
-      "Try removing the keyword 'var'.");
+      correction: "Try removing the keyword 'var'.");
 
   static const ParserErrorCode VAR_AS_TYPE_NAME = const ParserErrorCode(
-      'VAR_AS_TYPE_NAME',
-      "The keyword 'var' can't be used as a type name.",
-      "Try using 'dynamic' instead of 'var'.");
+      'VAR_AS_TYPE_NAME', "The keyword 'var' can't be used as a type name.",
+      correction: "Try using 'dynamic' instead of 'var'.");
 
   static const ParserErrorCode VAR_CLASS = const ParserErrorCode(
-      'VAR_CLASS',
-      "Classes can't be declared to be 'var'.",
-      "Try removing the keyword 'var'.");
+      'VAR_CLASS', "Classes can't be declared to be 'var'.",
+      correction: "Try removing the keyword 'var'.");
 
   static const ParserErrorCode VAR_ENUM = const ParserErrorCode(
-      'VAR_ENUM',
-      "Enums can't be declared to be 'var'.",
-      "Try removing the keyword 'var'.");
+      'VAR_ENUM', "Enums can't be declared to be 'var'.",
+      correction: "Try removing the keyword 'var'.");
 
   static const ParserErrorCode VAR_RETURN_TYPE = const ParserErrorCode(
-      'VAR_RETURN_TYPE',
-      "The return type can't be 'var'.",
-      "Try removing the keyword 'var', or "
-      "replacing it with the name of the return type.");
+      'VAR_RETURN_TYPE', "The return type can't be 'var'.",
+      correction: "Try removing the keyword 'var', or "
+          "replacing it with the name of the return type.");
 
   static const ParserErrorCode VAR_TYPEDEF = const ParserErrorCode(
-      'VAR_TYPEDEF',
-      "Typedefs can't be declared to be 'var'.",
-      "Try removing the keyword 'var', or "
-      "replacing it with the name of the return type.");
+      'VAR_TYPEDEF', "Typedefs can't be declared to be 'var'.",
+      correction: "Try removing the keyword 'var', or "
+          "replacing it with the name of the return type.");
 
   /**
    * Initialize a newly created error code to have the given [name]. The message
@@ -1037,8 +969,8 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ParserErrorCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const ParserErrorCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 8e812db..77853fc 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -152,8 +152,8 @@
    * given [correction] template.
    */
   const CheckedModeCompileTimeErrorCode(String name, String message,
-      [String correction])
-      : super(name, message, correction);
+      {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity =>
@@ -192,11 +192,10 @@
    * 2: the name of the second library in which the type is found
    */
   static const CompileTimeErrorCode AMBIGUOUS_EXPORT =
-      const CompileTimeErrorCode(
-          'AMBIGUOUS_EXPORT',
+      const CompileTimeErrorCode('AMBIGUOUS_EXPORT',
           "The name '{0}' is defined in the libraries '{1}' and '{2}'.",
-          "Try removing the export of one of the libraries, or "
-          "explicitly hiding the name in one of the export directives.");
+          correction: "Try removing the export of one of the libraries, or "
+              "explicitly hiding the name in one of the export directives.");
 
   /**
    * 15 Metadata: The constant expression given in an annotation is type checked
@@ -216,11 +215,10 @@
    */
   static const CompileTimeErrorCode ANNOTATION_WITH_NON_CLASS =
       const CompileTimeErrorCode(
-          'ANNOTATION_WITH_NON_CLASS',
-          "The name '{0}' isn't a class.",
-          "Try importing the library that declares the class, "
-          "correcting the name to match a defined class, or "
-          "defining a class with the given name.");
+          'ANNOTATION_WITH_NON_CLASS', "The name '{0}' isn't a class.",
+          correction: "Try importing the library that declares the class, "
+              "correcting the name to match a defined class, or "
+              "defining a class with the given name.");
 
   /**
    * 12.33 Argument Definition Test: It is a compile time error if <i>v</i> does
@@ -239,11 +237,11 @@
    * for-in statement appears inside a synchronous function.
    */
   static const CompileTimeErrorCode ASYNC_FOR_IN_WRONG_CONTEXT =
-      const CompileTimeErrorCode(
-          'ASYNC_FOR_IN_WRONG_CONTEXT',
+      const CompileTimeErrorCode('ASYNC_FOR_IN_WRONG_CONTEXT',
           "The asynchronous for-in can only be used in an asynchronous function.",
-          "Try marking the function body with either 'async' or 'async*', or "
-          "removing the 'await' before the for loop.");
+          correction:
+              "Try marking the function body with either 'async' or 'async*', or "
+              "removing the 'await' before the for loop.");
 
   /**
    * 16.30 Await Expressions: It is a compile-time error if the function
@@ -251,10 +249,10 @@
    * await expression.)
    */
   static const CompileTimeErrorCode AWAIT_IN_WRONG_CONTEXT =
-      const CompileTimeErrorCode(
-          'AWAIT_IN_WRONG_CONTEXT',
+      const CompileTimeErrorCode('AWAIT_IN_WRONG_CONTEXT',
           "The await expression can only be used in an asynchronous function.",
-          "Try marking the function body with either 'async' or 'async*'.");
+          correction:
+              "Try marking the function body with either 'async' or 'async*'.");
 
   /**
    * 16.33 Identifier Reference: It is a compile-time error if a built-in
@@ -265,10 +263,9 @@
    * 0: the built-in identifier that is being used
    */
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_PREFIX_NAME =
-      const CompileTimeErrorCode(
-          'BUILT_IN_IDENTIFIER_AS_PREFIX_NAME',
+      const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_PREFIX_NAME',
           "The built-in identifier '{0}' can't be used as a prefix name.",
-          "Try choosing a different name for the prefix.");
+          correction: "Try choosing a different name for the prefix.");
 
   /**
    * 12.30 Identifier Reference: It is a compile-time error to use a built-in
@@ -278,10 +275,9 @@
    * 0: the built-in identifier that is being used
    */
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE =
-      const CompileTimeErrorCode(
-          'BUILT_IN_IDENTIFIER_AS_TYPE',
+      const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPE',
           "The built-in identifier '{0}' can't be used as a type.",
-          "Try correcting the name to match an existing type.");
+          correction: "Try correcting the name to match an existing type.");
 
   /**
    * 16.33 Identifier Reference: It is a compile-time error if a built-in
@@ -292,10 +288,9 @@
    * 0: the built-in identifier that is being used
    */
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_NAME =
-      const CompileTimeErrorCode(
-          'BUILT_IN_IDENTIFIER_AS_TYPE_NAME',
+      const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPE_NAME',
           "The built-in identifier '{0}' can't be used as a type name.",
-          "Try choosing a different name for the type.");
+          correction: "Try choosing a different name for the type.");
 
   /**
    * 16.33 Identifier Reference: It is a compile-time error if a built-in
@@ -306,10 +301,9 @@
    * 0: the built-in identifier that is being used
    */
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME =
-      const CompileTimeErrorCode(
-          'BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME',
+      const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPEDEF_NAME',
           "The built-in identifier '{0}' can't be used as a typedef name.",
-          "Try choosing a different name for the typedef.");
+          correction: "Try choosing a different name for the typedef.");
 
   /**
    * 16.33 Identifier Reference: It is a compile-time error if a built-in
@@ -320,10 +314,9 @@
    * 0: the built-in identifier that is being used
    */
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME =
-      const CompileTimeErrorCode(
-          'BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME',
+      const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_AS_TYPE_PARAMETER_NAME',
           "The built-in identifier '{0}' can't be used as a type parameter name.",
-          "Try choosing a different name for the type parameter.");
+          correction: "Try choosing a different name for the type parameter.");
 
   /**
    * 16.33 Identifier Reference: It is a compile-time error if a built-in
@@ -337,10 +330,9 @@
    * https://github.com/dart-lang/sdk/issues/31811
    */
   static const CompileTimeErrorCode BUILT_IN_IDENTIFIER_IN_DECLARATION =
-      const CompileTimeErrorCode(
-          'BUILT_IN_IDENTIFIER_IN_DECLARATION',
+      const CompileTimeErrorCode('BUILT_IN_IDENTIFIER_IN_DECLARATION',
           "The built-in identifier '{0}' can't be used as a name.",
-          "Try choosing a different name.");
+          correction: "Try choosing a different name.");
 
   /**
    * 13.9 Switch: It is a compile-time error if the class <i>C</i> implements
@@ -369,8 +361,8 @@
           'CONFLICTING_GETTER_AND_METHOD',
           "Class '{0}' can't have both getter '{1}.{2}' and method with the "
           "same name.",
-          "Try converting the method to a getter, or "
-          "renaming the method to a name that doesn't conflit.");
+          correction: "Try converting the method to a getter, or "
+              "renaming the method to a name that doesn't conflit.");
 
   /**
    * 7.2 Getters: It is a compile-time error if a class has both a getter and a
@@ -388,8 +380,8 @@
           'CONFLICTING_METHOD_AND_GETTER',
           "Class '{0}' can't have both method '{1}.{2}' and getter with the "
           "same name.",
-          "Try converting the getter to a method, or "
-          "renaming the getter to a name that doesn't conflit.");
+          correction: "Try converting the getter to a method, or "
+              "renaming the getter to a name that doesn't conflit.");
 
   /**
    * 7.6 Constructors: A constructor name always begins with the name of its
@@ -405,7 +397,7 @@
           'CONFLICTING_CONSTRUCTOR_NAME_AND_FIELD',
           "'{0}' can't be used to name both a constructor and a field in this "
           "class.",
-          "Try renaming either the constructor or the field.");
+          correction: "Try renaming either the constructor or the field.");
 
   /**
    * 7.6 Constructors: A constructor name always begins with the name of its
@@ -421,7 +413,7 @@
           'CONFLICTING_CONSTRUCTOR_NAME_AND_METHOD',
           "'{0}' can't be used to name both a constructor and a method in this "
           "class.",
-          "Try renaming either the constructor or the field.");
+          correction: "Try renaming either the constructor or the field.");
 
   static const CompileTimeErrorCode CONFLICTING_GENERIC_INTERFACES =
       const CompileTimeErrorCode(
@@ -442,7 +434,7 @@
           'CONFLICTING_TYPE_VARIABLE_AND_CLASS',
           "'{0}' can't be used to name both a type variable and the class in "
           "which the type variable is defined.",
-          "Try renaming either the type variable or the class.");
+          correction: "Try renaming either the type variable or the class.");
 
   /**
    * 7. Classes: It is a compile time error if a generic class declares a type
@@ -457,17 +449,17 @@
           'CONFLICTING_TYPE_VARIABLE_AND_MEMBER',
           "'{0}' can't be used to name both a type variable and a member in "
           "this class.",
-          "Try renaming either the type variable or the member.");
+          correction: "Try renaming either the type variable or the member.");
 
   /**
    * 16.12.2 Const: It is a compile-time error if evaluation of a constant
    * object results in an uncaught exception being thrown.
    */
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_THROWS_EXCEPTION =
-      const CompileTimeErrorCode(
-          'CONST_CONSTRUCTOR_THROWS_EXCEPTION',
+      const CompileTimeErrorCode('CONST_CONSTRUCTOR_THROWS_EXCEPTION',
           "Const constructors can't throw exceptions.",
-          "Try removing the throw statement, or removing the keyword 'const'.");
+          correction:
+              "Try removing the throw statement, or removing the keyword 'const'.");
 
   /**
    * 10.6.3 Constant Constructors: It is a compile-time error if a constant
@@ -483,8 +475,8 @@
           'CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST',
           "Can't define the const constructor because the field '{0}' "
           "is initialized with a non-constant value.",
-          "Try initializing the field to a constant value, or "
-          "removing the keyword 'const' from the constructor.");
+          correction: "Try initializing the field to a constant value, or "
+              "removing the keyword 'const' from the constructor.");
 
   /**
    * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -496,11 +488,10 @@
    * constructor named ... is declared.
    */
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN =
-      const CompileTimeErrorCode(
-          'CONST_CONSTRUCTOR_WITH_MIXIN',
+      const CompileTimeErrorCode('CONST_CONSTRUCTOR_WITH_MIXIN',
           "Const constructor can't be declared for a class with a mixin.",
-          "Try removing the 'const' keyword, or "
-          "removing the 'with' clause from the class declaration.");
+          correction: "Try removing the 'const' keyword, or "
+              "removing the 'with' clause from the class declaration.");
 
   /**
    * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -516,8 +507,8 @@
           'CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER',
           "Constant constructor can't call non-constant super constructor of "
           "'{0}'.",
-          "Try calling a const constructor in the superclass, or "
-          "removing the keyword 'const' from the constructor.");
+          correction: "Try calling a const constructor in the superclass, or "
+              "removing the keyword 'const' from the constructor.");
 
   /**
    * 7.6.3 Constant Constructors: It is a compile-time error if a constant
@@ -526,39 +517,38 @@
    * The above refers to both locally declared and inherited instance variables.
    */
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD =
-      const CompileTimeErrorCode(
-          'CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD',
+      const CompileTimeErrorCode('CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD',
           "Can't define a const constructor for a class with non-final fields.",
-          "Try making all of the fields final, or "
-          "removing the keyword 'const' from the constructor.");
+          correction: "Try making all of the fields final, or "
+              "removing the keyword 'const' from the constructor.");
 
   /**
    * 12.12.2 Const: It is a compile-time error if <i>T</i> is a deferred type.
    */
   static const CompileTimeErrorCode CONST_DEFERRED_CLASS =
-      const CompileTimeErrorCode(
-          'CONST_DEFERRED_CLASS',
+      const CompileTimeErrorCode('CONST_DEFERRED_CLASS',
           "Deferred classes can't be created with 'const'.",
-          "Try using 'new' to create the instance, or "
-          "changing the import to not be deferred.");
+          correction: "Try using 'new' to create the instance, or "
+              "changing the import to not be deferred.");
 
   /**
    * 6.2 Formal Parameters: It is a compile-time error if a formal parameter is
    * declared as a constant variable.
    */
   static const CompileTimeErrorCode CONST_FORMAL_PARAMETER =
-      const CompileTimeErrorCode('CONST_FORMAL_PARAMETER',
-          "Parameters can't be const.", "Try removing the 'const' keyword.");
+      const CompileTimeErrorCode(
+          'CONST_FORMAL_PARAMETER', "Parameters can't be const.",
+          correction: "Try removing the 'const' keyword.");
 
   /**
    * 5 Variables: A constant variable must be initialized to a compile-time
    * constant or a compile-time error occurs.
    */
   static const CompileTimeErrorCode CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE =
-      const CompileTimeErrorCode(
-          'CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE',
+      const CompileTimeErrorCode('CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE',
           "Const variables must be initialized with a constant value.",
-          "Try changing the initializer to be a constant expression.");
+          correction:
+              "Try changing the initializer to be a constant expression.");
 
   /**
    * 5 Variables: A constant variable must be initialized to a compile-time
@@ -573,19 +563,20 @@
           'CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used to "
           "initialized a const variable.",
-          "Try initializing the variable without referencing members of the "
-          "deferred library, or "
-          "changing the import to not be deferred.");
+          correction:
+              "Try initializing the variable without referencing members of the "
+              "deferred library, or "
+              "changing the import to not be deferred.");
 
   /**
    * 7.5 Instance Variables: It is a compile-time error if an instance variable
    * is declared to be constant.
    */
   static const CompileTimeErrorCode CONST_INSTANCE_FIELD =
-      const CompileTimeErrorCode(
-          'CONST_INSTANCE_FIELD',
+      const CompileTimeErrorCode('CONST_INSTANCE_FIELD',
           "Only static fields can be declared as const.",
-          "Try declaring the field as final, or adding the keyword 'static'.");
+          correction:
+              "Try declaring the field as final, or adding the keyword 'static'.");
 
   /**
    * 12.8 Maps: It is a compile-time error if the key of an entry in a constant
@@ -601,8 +592,8 @@
           'CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS',
           "The constant map entry key expression type '{0}' can't override "
           "the == operator.",
-          "Try using a different value for the key, or "
-          "removing the keyword 'const' from the map.");
+          correction: "Try using a different value for the key, or "
+              "removing the keyword 'const' from the map.");
 
   /**
    * 5 Variables: A constant variable must be initialized to a compile-time
@@ -612,10 +603,9 @@
    * 0: the name of the uninitialized final variable
    */
   static const CompileTimeErrorCode CONST_NOT_INITIALIZED =
-      const CompileTimeErrorCode(
-          'CONST_NOT_INITIALIZED',
+      const CompileTimeErrorCode('CONST_NOT_INITIALIZED',
           "The const variable '{0}' must be initialized.",
-          "Try adding an initialization to the declaration.");
+          correction: "Try adding an initialization to the declaration.");
 
   /**
    * 16.12.2 Const: An expression of one of the forms !e, e1 && e2 or e1 || e2,
@@ -698,8 +688,9 @@
           'CONST_WITH_INVALID_TYPE_PARAMETERS',
           "The type '{0}' is declared with {1} type parameters, but {2} type "
           "arguments were given.",
-          "Try adjusting the number of type arguments to match the number of "
-          "type parameters.");
+          correction:
+              "Try adjusting the number of type arguments to match the number of "
+              "type parameters.");
 
   /**
    * 16.12.2 Const: If <i>e</i> is of the form <i>const T(a<sub>1</sub>,
@@ -709,10 +700,9 @@
    * the declaration of <i>T</i>.
    */
   static const CompileTimeErrorCode CONST_WITH_NON_CONST =
-      const CompileTimeErrorCode(
-          'CONST_WITH_NON_CONST',
+      const CompileTimeErrorCode('CONST_WITH_NON_CONST',
           "The constructor being called isn't a const constructor.",
-          "Try using 'new' to call the constructor.");
+          correction: "Try using 'new' to call the constructor.");
 
   /**
    * 16.12.2 Const: In all of the above cases, it is a compile-time error if
@@ -720,11 +710,10 @@
    * expression.
    */
   static const CompileTimeErrorCode CONST_WITH_NON_CONSTANT_ARGUMENT =
-      const CompileTimeErrorCode(
-          'CONST_WITH_NON_CONSTANT_ARGUMENT',
+      const CompileTimeErrorCode('CONST_WITH_NON_CONSTANT_ARGUMENT',
           "Arguments of a constant creation must be constant expressions.",
-          "Try making the argument a valid constant, or "
-          "use 'new' to call the constructor.");
+          correction: "Try making the argument a valid constant, or "
+              "use 'new' to call the constructor.");
 
   /**
    * 16.12.2 Const: It is a compile-time error if <i>T</i> is not a class
@@ -741,19 +730,18 @@
    */
   static const CompileTimeErrorCode CONST_WITH_NON_TYPE =
       const CompileTimeErrorCode(
-          'CONST_WITH_NON_TYPE',
-          "The name '{0}' isn't a class.",
-          "Try correcting the name to match an existing class.");
+          'CONST_WITH_NON_TYPE', "The name '{0}' isn't a class.",
+          correction: "Try correcting the name to match an existing class.");
 
   /**
    * 16.12.2 Const: If <i>T</i> is a parameterized type, it is a compile-time
    * error if <i>T</i> includes a type variable among its type arguments.
    */
   static const CompileTimeErrorCode CONST_WITH_TYPE_PARAMETERS =
-      const CompileTimeErrorCode(
-          'CONST_WITH_TYPE_PARAMETERS',
+      const CompileTimeErrorCode('CONST_WITH_TYPE_PARAMETERS',
           "A constant creation can't use a type parameter as a type argument.",
-          "Try replacing the type parameter with a different type.");
+          correction:
+              "Try replacing the type parameter with a different type.");
 
   /**
    * 16.12.2 Const: It is a compile-time error if <i>T.id</i> is not the name of
@@ -764,10 +752,9 @@
    * 1: the name of the requested constant constructor
    */
   static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'CONST_WITH_UNDEFINED_CONSTRUCTOR',
+      const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR',
           "The class '{0}' doesn't have a constant constructor '{1}'.",
-          "Try calling a different contructor.");
+          correction: "Try calling a different contructor.");
 
   /**
    * 16.12.2 Const: It is a compile-time error if <i>T.id</i> is not the name of
@@ -777,20 +764,18 @@
    * 0: the name of the type
    */
   static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT =
-      const CompileTimeErrorCode(
-          'CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT',
+      const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT',
           "The class '{0}' doesn't have a default constant constructor.",
-          "Try calling a different contructor.");
+          correction: "Try calling a different contructor.");
 
   /**
    * 15.3.1 Typedef: It is a compile-time error if any default values are
    * specified in the signature of a function type alias.
    */
   static const CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS =
-      const CompileTimeErrorCode(
-          'DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS',
+      const CompileTimeErrorCode('DEFAULT_VALUE_IN_FUNCTION_TYPE_ALIAS',
           "Default parameter values aren't allowed in typedefs.",
-          "Try removing the default value.");
+          correction: "Try removing the default value.");
 
   /**
    * 6.2.1 Required Formals: By means of a function signature that names the
@@ -799,10 +784,9 @@
    * function type.
    */
   static const CompileTimeErrorCode DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER =
-      const CompileTimeErrorCode(
-          'DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER',
+      const CompileTimeErrorCode('DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER',
           "Default values aren't allowed in function typed parameters.",
-          "Try removing the default value.");
+          correction: "Try removing the default value.");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> explicitly
@@ -814,17 +798,16 @@
           'DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR',
           "Default values aren't allowed in factory constructors that redirect "
           "to another constructor.",
-          "Try removing the default value.");
+          correction: "Try removing the default value.");
 
   /**
    * 3.1 Scoping: It is a compile-time error if there is more than one entity
    * with the same name declared in the same scope.
    */
   static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_DEFAULT =
-      const CompileTimeErrorCode(
-          'DUPLICATE_CONSTRUCTOR_DEFAULT',
+      const CompileTimeErrorCode('DUPLICATE_CONSTRUCTOR_DEFAULT',
           "The default constructor is already defined.",
-          "Try giving one of the constructors a name.");
+          correction: "Try giving one of the constructors a name.");
 
   /**
    * 3.1 Scoping: It is a compile-time error if there is more than one entity
@@ -834,10 +817,9 @@
    * 0: the name of the duplicate entity
    */
   static const CompileTimeErrorCode DUPLICATE_CONSTRUCTOR_NAME =
-      const CompileTimeErrorCode(
-          'DUPLICATE_CONSTRUCTOR_NAME',
+      const CompileTimeErrorCode('DUPLICATE_CONSTRUCTOR_NAME',
           "The constructor with name '{0}' is already defined.",
-          "Try renaming one of the constructors.");
+          correction: "Try renaming one of the constructors.");
 
   /**
    * 3.1 Scoping: It is a compile-time error if there is more than one entity
@@ -854,9 +836,8 @@
    */
   static const CompileTimeErrorCode DUPLICATE_DEFINITION =
       const CompileTimeErrorCode(
-          'DUPLICATE_DEFINITION',
-          "The name '{0}' is already defined.",
-          "Try renaming one of the declarations.");
+          'DUPLICATE_DEFINITION', "The name '{0}' is already defined.",
+          correction: "Try renaming one of the declarations.");
 
   /**
    * 18.3 Parts: It's a compile-time error if the same library contains two part
@@ -868,7 +849,8 @@
   static const CompileTimeErrorCode DUPLICATE_PART = const CompileTimeErrorCode(
       'DUPLICATE_PART',
       "The library already contains a part with the uri '{0}'.",
-      "Try removing all but one of the duplicated part directives.");
+      correction:
+          "Try removing all but one of the duplicated part directives.");
 
   /**
    * 7. Classes: It is a compile-time error if a class has an instance member
@@ -884,10 +866,9 @@
    * See [DUPLICATE_DEFINITION].
    */
   static const CompileTimeErrorCode DUPLICATE_DEFINITION_INHERITANCE =
-      const CompileTimeErrorCode(
-          'DUPLICATE_DEFINITION_INHERITANCE',
+      const CompileTimeErrorCode('DUPLICATE_DEFINITION_INHERITANCE',
           "The name '{0}' is already defined in '{1}'.",
-          "Try renaming one of the declarations.");
+          correction: "Try renaming one of the declarations.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a compile-time error if
@@ -898,11 +879,10 @@
    * 0: the name of the parameter that was duplicated
    */
   static const CompileTimeErrorCode DUPLICATE_NAMED_ARGUMENT =
-      const CompileTimeErrorCode(
-          'DUPLICATE_NAMED_ARGUMENT',
+      const CompileTimeErrorCode('DUPLICATE_NAMED_ARGUMENT',
           "The argument for the named parameter '{0}' was already specified.",
-          "Try removing one of the named arguments, or "
-          "correcting one of the names to reference a different named parameter.");
+          correction: "Try removing one of the named arguments, or "
+              "correcting one of the names to reference a different named parameter.");
 
   /**
    * SDK implementation libraries can be exported only by other SDK libraries.
@@ -922,19 +902,18 @@
    * 0: the uri pointing to a non-library declaration
    */
   static const CompileTimeErrorCode EXPORT_OF_NON_LIBRARY =
-      const CompileTimeErrorCode(
-          'EXPORT_OF_NON_LIBRARY',
+      const CompileTimeErrorCode('EXPORT_OF_NON_LIBRARY',
           "The exported library '{0}' can't have a part-of directive.",
-          "Try exporting the library that the part is a part of.");
+          correction: "Try exporting the library that the part is a part of.");
 
   /**
    * Enum proposal: It is a compile-time error to subclass, mix-in or implement
    * an enum.
    */
   static const CompileTimeErrorCode EXTENDS_ENUM = const CompileTimeErrorCode(
-      'EXTENDS_ENUM',
-      "Classes can't extend an enum.",
-      "Try specifying a different superclass, or removing the extends clause.");
+      'EXTENDS_ENUM', "Classes can't extend an enum.",
+      correction:
+          "Try specifying a different superclass, or removing the extends clause.");
 
   /**
    * 7.9 Superclasses: It is a compile-time error if the extends clause of a
@@ -945,9 +924,9 @@
    * 0: the name of the superclass that was not found
    */
   static const CompileTimeErrorCode EXTENDS_NON_CLASS = const CompileTimeErrorCode(
-      'EXTENDS_NON_CLASS',
-      "Classes can only extend other classes.",
-      "Try specifying a different superclass, or removing the extends clause.");
+      'EXTENDS_NON_CLASS', "Classes can only extend other classes.",
+      correction:
+          "Try specifying a different superclass, or removing the extends clause.");
 
   /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or
@@ -979,10 +958,9 @@
    */
   static const CompileTimeErrorCode EXTENDS_DISALLOWED_CLASS =
       const CompileTimeErrorCode(
-          'EXTENDS_DISALLOWED_CLASS',
-          "Classes can't extend '{0}'.",
-          "Try specifying a different superclass, or "
-          "removing the extends clause.");
+          'EXTENDS_DISALLOWED_CLASS', "Classes can't extend '{0}'.",
+          correction: "Try specifying a different superclass, or "
+              "removing the extends clause.");
 
   /**
    * 7.9 Superclasses: It is a compile-time error if the extends clause of a
@@ -994,11 +972,10 @@
    * See [IMPLEMENTS_DEFERRED_CLASS], and [MIXIN_DEFERRED_CLASS].
    */
   static const CompileTimeErrorCode EXTENDS_DEFERRED_CLASS =
-      const CompileTimeErrorCode(
-          'EXTENDS_DEFERRED_CLASS',
+      const CompileTimeErrorCode('EXTENDS_DEFERRED_CLASS',
           "This class can't extend the deferred class '{0}'.",
-          "Try specifying a different superclass, or "
-          "removing the extends clause.");
+          correction: "Try specifying a different superclass, or "
+              "removing the extends clause.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
@@ -1012,10 +989,9 @@
    * 1: the actual number of positional arguments given
    */
   static const CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS =
-      const CompileTimeErrorCode(
-          'EXTRA_POSITIONAL_ARGUMENTS',
+      const CompileTimeErrorCode('EXTRA_POSITIONAL_ARGUMENTS',
           "Too many positional arguments: {0} expected, but {1} found.",
-          "Try removing the extra arguments.");
+          correction: "Try removing the extra arguments.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
@@ -1031,11 +1007,10 @@
    * See [NOT_ENOUGH_REQUIRED_ARGUMENTS].
    */
   static const CompileTimeErrorCode EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED =
-      const CompileTimeErrorCode(
-          'EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED',
+      const CompileTimeErrorCode('EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED',
           "Too many positional arguments: {0} expected, but {1} found.",
-          "Try removing the extra positional arguments, "
-          "or specifying the name for named arguments.");
+          correction: "Try removing the extra positional arguments, "
+              "or specifying the name for named arguments.");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It
@@ -1046,10 +1021,9 @@
    * 0: the name of the field being initialized multiple times
    */
   static const CompileTimeErrorCode FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS =
-      const CompileTimeErrorCode(
-          'FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS',
+      const CompileTimeErrorCode('FIELD_INITIALIZED_BY_MULTIPLE_INITIALIZERS',
           "The field '{0}' can't be initialized twice in the same constructor.",
-          "Try removing one of the initializations.");
+          correction: "Try removing one of the initializations.");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It
@@ -1063,7 +1037,7 @@
           'FIELD_INITIALIZED_IN_PARAMETER_AND_INITIALIZER',
           "Fields can't be initialized in both the parameter list and the "
           "initializers.",
-          "Try removing one of the initializations.");
+          correction: "Try removing one of the initializations.");
 
   /**
    * 5 Variables: It is a compile-time error if a final instance variable that
@@ -1074,10 +1048,9 @@
    * 0: the name of the field in question
    */
   static const CompileTimeErrorCode FINAL_INITIALIZED_MULTIPLE_TIMES =
-      const CompileTimeErrorCode(
-          'FINAL_INITIALIZED_MULTIPLE_TIMES',
+      const CompileTimeErrorCode('FINAL_INITIALIZED_MULTIPLE_TIMES',
           "'{0}' is a final field and so can only be set once.",
-          "Try removing all but one of the initializations.");
+          correction: "Try removing all but one of the initializations.");
 
   /**
    * 7.6.1 Generative Constructors: It is a compile-time error if an
@@ -1085,10 +1058,9 @@
    * generative constructor.
    */
   static const CompileTimeErrorCode FIELD_INITIALIZER_FACTORY_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'FIELD_INITIALIZER_FACTORY_CONSTRUCTOR',
+      const CompileTimeErrorCode('FIELD_INITIALIZER_FACTORY_CONSTRUCTOR',
           "Initializing formal parameters can't be used in factory constructors.",
-          "Try using a normal parameter.");
+          correction: "Try using a normal parameter.");
 
   /**
    * 7.6.1 Generative Constructors: It is a compile-time error if an
@@ -1096,10 +1068,9 @@
    * generative constructor.
    */
   static const CompileTimeErrorCode FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR',
+      const CompileTimeErrorCode('FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR',
           "Initializing formal parameters can only be used in constructors.",
-          "Try using a normal parameter.");
+          correction: "Try using a normal parameter.");
 
   /**
    * 7.6.1 Generative Constructors: A generative constructor may be redirecting,
@@ -1110,10 +1081,9 @@
    * generative constructor.
    */
   static const CompileTimeErrorCode FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR',
+      const CompileTimeErrorCode('FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR',
           "The redirecting constructor can't have a field initializer.",
-          "Try using a normal parameter.");
+          correction: "Try using a normal parameter.");
 
   /**
    * Temporary error to work around dartbug.com/28515.
@@ -1125,11 +1095,11 @@
    * TODO(paulberry): remove this once dartbug.com/28515 is fixed.
    */
   static const CompileTimeErrorCode GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED =
-      const CompileTimeErrorCode(
-          'GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED',
+      const CompileTimeErrorCode('GENERIC_FUNCTION_TYPED_PARAM_UNSUPPORTED',
           "Analysis of generic function typed parameters is not yet supported.",
-          "Try using an explicit typedef, or changing type parameters to "
-          "`dynamic`.");
+          correction:
+              "Try using an explicit typedef, or changing type parameters to "
+              "`dynamic`.");
 
   /**
    * 7.2 Getters: It is a compile-time error if a class has both a getter and a
@@ -1143,7 +1113,7 @@
           'GETTER_AND_METHOD_WITH_SAME_NAME',
           "'{0}' can't be used to name a getter, there is already a method "
           "with the same name.",
-          "Try renaming either the getter or the method.");
+          correction: "Try renaming either the getter or the method.");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the implements clause
@@ -1156,12 +1126,11 @@
    * See [EXTENDS_DEFERRED_CLASS], and [MIXIN_DEFERRED_CLASS].
    */
   static const CompileTimeErrorCode IMPLEMENTS_DEFERRED_CLASS =
-      const CompileTimeErrorCode(
-          'IMPLEMENTS_DEFERRED_CLASS',
+      const CompileTimeErrorCode('IMPLEMENTS_DEFERRED_CLASS',
           "This class can't implement the deferred class '{0}'.",
-          "Try specifying a different interface, "
-          "removing the class from the list, or "
-          "changing the import to not be deferred.");
+          correction: "Try specifying a different interface, "
+              "removing the class from the list, or "
+              "changing the import to not be deferred.");
 
   /**
    * 12.2 Null: It is a compile-time error for a class to attempt to extend or
@@ -1190,10 +1159,9 @@
    */
   static const CompileTimeErrorCode IMPLEMENTS_DISALLOWED_CLASS =
       const CompileTimeErrorCode(
-          'IMPLEMENTS_DISALLOWED_CLASS',
-          "Classes can't implement '{0}'.",
-          "Try specifying a different interface, or "
-          "remove the class from the list.");
+          'IMPLEMENTS_DISALLOWED_CLASS', "Classes can't implement '{0}'.",
+          correction: "Try specifying a different interface, or "
+              "remove the class from the list.");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the implements clause
@@ -1201,9 +1169,9 @@
    */
   static const CompileTimeErrorCode IMPLEMENTS_DYNAMIC =
       const CompileTimeErrorCode(
-          'IMPLEMENTS_DYNAMIC',
-          "Classes can't implement 'dynamic'.",
-          "Try specifying an interface, or remove 'dynamic' from the list.");
+          'IMPLEMENTS_DYNAMIC', "Classes can't implement 'dynamic'.",
+          correction:
+              "Try specifying an interface, or remove 'dynamic' from the list.");
 
   /**
    * Enum proposal: It is a compile-time error to subclass, mix-in or implement
@@ -1211,9 +1179,9 @@
    */
   static const CompileTimeErrorCode IMPLEMENTS_ENUM =
       const CompileTimeErrorCode(
-          'IMPLEMENTS_ENUM',
-          "Classes can't implement an enum.",
-          "Try specifying an interface, or remove the enum from the list.");
+          'IMPLEMENTS_ENUM', "Classes can't implement an enum.",
+          correction:
+              "Try specifying an interface, or remove the enum from the list.");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the implements clause
@@ -1225,9 +1193,9 @@
    */
   static const CompileTimeErrorCode IMPLEMENTS_NON_CLASS =
       const CompileTimeErrorCode(
-          'IMPLEMENTS_NON_CLASS',
-          "Classes can only implement other classes.",
-          "Try specifying a class, or remove the name from the list.");
+          'IMPLEMENTS_NON_CLASS', "Classes can only implement other classes.",
+          correction:
+              "Try specifying a class, or remove the name from the list.");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if a type <i>T</i> appears
@@ -1238,9 +1206,8 @@
    */
   static const CompileTimeErrorCode IMPLEMENTS_REPEATED =
       const CompileTimeErrorCode(
-          'IMPLEMENTS_REPEATED',
-          "'{0}' can only be implemented once.",
-          "Try removing all but one occurance of the class name.");
+          'IMPLEMENTS_REPEATED', "'{0}' can only be implemented once.",
+          correction: "Try removing all but one occurance of the class name.");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the superclass of a
@@ -1251,10 +1218,9 @@
    *    clauses
    */
   static const CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS =
-      const CompileTimeErrorCode(
-          'IMPLEMENTS_SUPER_CLASS',
+      const CompileTimeErrorCode('IMPLEMENTS_SUPER_CLASS',
           "'{0}' can't be used in both 'extends' and 'implements' clauses.",
-          "Try removing one of the occurances.");
+          correction: "Try removing one of the occurances.");
 
   /**
    * 7.6.1 Generative Constructors: Note that <b>this</b> is not in scope on the
@@ -1289,10 +1255,9 @@
    * See [StaticWarningCode.IMPORT_OF_NON_LIBRARY].
    */
   static const CompileTimeErrorCode IMPORT_OF_NON_LIBRARY =
-      const CompileTimeErrorCode(
-          'IMPORT_OF_NON_LIBRARY',
+      const CompileTimeErrorCode('IMPORT_OF_NON_LIBRARY',
           "The imported library '{0}' can't have a part-of directive.",
-          "Try importing the library that the part is a part of.");
+          correction: "Try importing the library that the part is a part of.");
 
   /**
    * 13.9 Switch: It is a compile-time error if values of the expressions
@@ -1320,11 +1285,10 @@
    * See [INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD].
    */
   static const CompileTimeErrorCode INITIALIZER_FOR_NON_EXISTENT_FIELD =
-      const CompileTimeErrorCode(
-          'INITIALIZER_FOR_NON_EXISTENT_FIELD',
+      const CompileTimeErrorCode('INITIALIZER_FOR_NON_EXISTENT_FIELD',
           "'{0}' isn't a field in the enclosing class.",
-          "Try correcting the name to match an existing field, or "
-          "defining a field named '{0}'.");
+          correction: "Try correcting the name to match an existing field, or "
+              "defining a field named '{0}'.");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor. It
@@ -1343,7 +1307,7 @@
           'INITIALIZER_FOR_STATIC_FIELD',
           "'{0}' is a static field in the enclosing class. Fields initialized "
           "in a constructor can't be static.",
-          "Try removing the initialization.");
+          correction: "Try removing the initialization.");
 
   /**
    * 7.6.1 Generative Constructors: An initializing formal has the form
@@ -1358,11 +1322,10 @@
    * [INITIALIZER_FOR_NON_EXISTENT_FIELD].
    */
   static const CompileTimeErrorCode INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD =
-      const CompileTimeErrorCode(
-          'INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD',
+      const CompileTimeErrorCode('INITIALIZING_FORMAL_FOR_NON_EXISTENT_FIELD',
           "'{0}' isn't a field in the enclosing class.",
-          "Try correcting the name to match an existing field, or "
-          "defining a field named '{0}'.");
+          correction: "Try correcting the name to match an existing field, or "
+              "defining a field named '{0}'.");
 
   /**
    * 7.6.1 Generative Constructors: An initializing formal has the form
@@ -1380,28 +1343,26 @@
           'INITIALIZING_FORMAL_FOR_STATIC_FIELD',
           "'{0}' is a static field in the enclosing class. Fields initialized "
           "in a constructor can't be static.",
-          "Try removing the initialization.");
+          correction: "Try removing the initialization.");
 
   /**
    * 12.30 Identifier Reference: Otherwise, e is equivalent to the property
    * extraction <b>this</b>.<i>id</i>.
    */
   static const CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_FACTORY =
-      const CompileTimeErrorCode(
-          'INSTANCE_MEMBER_ACCESS_FROM_FACTORY',
+      const CompileTimeErrorCode('INSTANCE_MEMBER_ACCESS_FROM_FACTORY',
           "Instance members can't be accessed from a factory constructor.",
-          "Try removing the reference to the instance member.");
+          correction: "Try removing the reference to the instance member.");
 
   /**
    * 12.30 Identifier Reference: Otherwise, e is equivalent to the property
    * extraction <b>this</b>.<i>id</i>.
    */
   static const CompileTimeErrorCode INSTANCE_MEMBER_ACCESS_FROM_STATIC =
-      const CompileTimeErrorCode(
-          'INSTANCE_MEMBER_ACCESS_FROM_STATIC',
+      const CompileTimeErrorCode('INSTANCE_MEMBER_ACCESS_FROM_STATIC',
           "Instance members can't be accessed from a static method.",
-          "Try removing the reference to the instance member, or ."
-          "removing the keyword 'static' from the method.");
+          correction: "Try removing the reference to the instance member, or ."
+              "removing the keyword 'static' from the method.");
 
   /**
    * Enum proposal: It is also a compile-time error to explicitly instantiate an
@@ -1409,16 +1370,15 @@
    */
   static const CompileTimeErrorCode INSTANTIATE_ENUM =
       const CompileTimeErrorCode(
-          'INSTANTIATE_ENUM',
-          "Enums can't be instantiated.",
-          "Try using one of the defined constants.");
+          'INSTANTIATE_ENUM', "Enums can't be instantiated.",
+          correction: "Try using one of the defined constants.");
 
   static const CompileTimeErrorCode INTEGER_LITERAL_OUT_OF_RANGE =
-      const CompileTimeErrorCode(
-          'INTEGER_LITERAL_OUT_OF_RANGE',
+      const CompileTimeErrorCode('INTEGER_LITERAL_OUT_OF_RANGE',
           "The integer literal {0} can't be represented in 64 bits.",
-          "Try using the BigInt class if you need an integer larger than "
-          "9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.");
+          correction:
+              "Try using the BigInt class if you need an integer larger than "
+              "9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.");
 
   /**
    * 15 Metadata: Metadata consists of a series of annotations, each of which
@@ -1442,11 +1402,10 @@
    * not qualified by a deferred prefix.
    */
   static const CompileTimeErrorCode INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY =
-      const CompileTimeErrorCode(
-          'INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY',
+      const CompileTimeErrorCode('INVALID_ANNOTATION_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as annotations.",
-          "Try removing the annotation, or "
-          "changing the import to not be deferred.");
+          correction: "Try removing the annotation, or "
+              "changing the import to not be deferred.");
 
   /**
    * 15.31 Identifier Reference: It is a compile-time error if any of the
@@ -1458,28 +1417,26 @@
           'INVALID_IDENTIFIER_IN_ASYNC',
           "The identifier '{0}' can't be used in a function marked with "
           "'async', 'async*' or 'sync*'.",
-          "Try using a different name, or "
-          "remove the modifier on the function body.");
+          correction: "Try using a different name, or "
+              "remove the modifier on the function body.");
 
   /**
    * 9. Functions: It is a compile-time error if an async, async* or sync*
    * modifier is attached to the body of a setter or constructor.
    */
   static const CompileTimeErrorCode INVALID_MODIFIER_ON_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'INVALID_MODIFIER_ON_CONSTRUCTOR',
+      const CompileTimeErrorCode('INVALID_MODIFIER_ON_CONSTRUCTOR',
           "The modifier '{0}' can't be applied to the body of a constructor.",
-          "Try removing the modifier.");
+          correction: "Try removing the modifier.");
 
   /**
    * 9. Functions: It is a compile-time error if an async, async* or sync*
    * modifier is attached to the body of a setter or constructor.
    */
   static const CompileTimeErrorCode INVALID_MODIFIER_ON_SETTER =
-      const CompileTimeErrorCode(
-          'INVALID_MODIFIER_ON_SETTER',
+      const CompileTimeErrorCode('INVALID_MODIFIER_ON_SETTER',
           "The modifier '{0}' can't be applied to the body of a setter.",
-          "Try removing the modifier.");
+          correction: "Try removing the modifier.");
 
   /**
    * TODO(brianwilkerson) Remove this when we have decided on how to report
@@ -1531,7 +1488,8 @@
           'INVALID_TYPE_ARGUMENT_IN_CONST_LIST',
           "Constant list literals can't include a type parameter as a type "
           "argument, such as '{0}'.",
-          "Try replacing the type parameter with a different type.");
+          correction:
+              "Try replacing the type parameter with a different type.");
 
   /**
    * 12.7 Maps: It is a compile time error if the type arguments of a constant
@@ -1545,7 +1503,8 @@
           'INVALID_TYPE_ARGUMENT_IN_CONST_MAP',
           "Constant map literals can't include a type parameter as a type "
           "argument, such as '{0}'.",
-          "Try replacing the type parameter with a different type.");
+          correction:
+              "Try replacing the type parameter with a different type.");
 
   /**
    * The 'covariant' keyword was found in an inappropriate location.
@@ -1555,7 +1514,7 @@
           'INVALID_USE_OF_COVARIANT',
           "The 'covariant' keyword can only be used for parameters in instance "
           "methods or before non-final instance fields.",
-          "Try removing the 'covariant' keyword.");
+          correction: "Try removing the 'covariant' keyword.");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at
@@ -1605,10 +1564,9 @@
    */
   static const CompileTimeErrorCode LABEL_UNDEFINED =
       const CompileTimeErrorCode(
-          'LABEL_UNDEFINED',
-          "Can't reference undefined label '{0}'.",
-          "Try defining the label, or "
-          "correcting the name to match an existing label.");
+          'LABEL_UNDEFINED', "Can't reference undefined label '{0}'.",
+          correction: "Try defining the label, or "
+              "correcting the name to match an existing label.");
 
   /**
    * 7 Classes: It is a compile time error if a class <i>C</i> declares a member
@@ -1639,7 +1597,7 @@
           'MISSING_CONST_IN_LIST_LITERAL',
           "List literals must be prefixed with 'const' when used as a constant "
           "expression.",
-          "Try adding the keyword 'const' before the literal.");
+          correction: "Try adding the keyword 'const' before the literal.");
 
   /**
    * 12.1 Constants: A constant expression is ... a constant map literal.
@@ -1649,7 +1607,12 @@
           'MISSING_CONST_IN_MAP_LITERAL',
           "Map literals must be prefixed with 'const' when used as a constant "
           "expression.",
-          "Try adding the keyword 'const' before the literal.");
+          correction: "Try adding the keyword 'const' before the literal.");
+
+  static const CompileTimeErrorCode MISSING_DART_LIBRARY =
+      const CompileTimeErrorCode(
+          'MISSING_DART_LIBRARY', "Required library '{0}' is missing.",
+          correction: "Check your Dart SDK installation for completeness.");
 
   /**
    * 9 Mixins: It is a compile-time error if a declared or derived mixin
@@ -1674,10 +1637,9 @@
    * See [EXTENDS_DEFERRED_CLASS], and [IMPLEMENTS_DEFERRED_CLASS].
    */
   static const CompileTimeErrorCode MIXIN_DEFERRED_CLASS =
-      const CompileTimeErrorCode(
-          'MIXIN_DEFERRED_CLASS',
+      const CompileTimeErrorCode('MIXIN_DEFERRED_CLASS',
           "This class can't mixin the deferred class '{0}'.",
-          "Try changing the import to not be deferred.");
+          correction: "Try changing the import to not be deferred.");
 
   /**
    * Not yet in the spec, but consistent with VM behavior.  It is a
@@ -1796,7 +1758,7 @@
       MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS = const CompileTimeErrorCode(
           'MULTIPLE_REDIRECTING_CONSTRUCTOR_INVOCATIONS',
           "Constructors can have at most one 'this' redirection.",
-          "Try removing all but one of the redirections.");
+          correction: "Try removing all but one of the redirections.");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>k</i> be a generative constructor.
@@ -1804,10 +1766,9 @@
    * list or a compile time error occurs.
    */
   static const CompileTimeErrorCode MULTIPLE_SUPER_INITIALIZERS =
-      const CompileTimeErrorCode(
-          'MULTIPLE_SUPER_INITIALIZERS',
+      const CompileTimeErrorCode('MULTIPLE_SUPER_INITIALIZERS',
           "Constructor may have at most one 'super' initializer.",
-          "Try removing all but one of the 'super' initializers.");
+          correction: "Try removing all but one of the 'super' initializers.");
 
   /**
    * 15 Metadata: Metadata consists of a series of annotations, each of which
@@ -1816,10 +1777,9 @@
    * constant constructor.
    */
   static const CompileTimeErrorCode NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS =
-      const CompileTimeErrorCode(
-          'NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS',
+      const CompileTimeErrorCode('NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS',
           "Annotation creation must have arguments.",
-          "Try adding an empty argument list.");
+          correction: "Try adding an empty argument list.");
 
   /**
    * This error is generated if a constructor declaration has an implicit
@@ -1840,11 +1800,10 @@
    *    constructor
    */
   static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT =
-      const CompileTimeErrorCode(
-          'NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT',
+      const CompileTimeErrorCode('NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT',
           "The superclass '{0}' doesn't have a zero argument constructor.",
-          "Try declaring a zero argument constructor in '{0}', or "
-          "explicitly invoking a different constructor in '{0}'.");
+          correction: "Try declaring a zero argument constructor in '{0}', or "
+              "explicitly invoking a different constructor in '{0}'.");
 
   /**
    * This error is generated if a class declaration has an implicit default
@@ -1866,12 +1825,11 @@
    * 1: the name of the subclass that does not contain any explicit constructors
    */
   static const CompileTimeErrorCode NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT =
-      const CompileTimeErrorCode(
-          'NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT',
+      const CompileTimeErrorCode('NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT',
           "The superclass '{0}' doesn't have a zero argument constructor.",
-          "Try declaring a zero argument constructor in '{0}', or "
-          "declaring a constructor in {1} that explicitly invokes a "
-          "constructor in '{0}'.");
+          correction: "Try declaring a zero argument constructor in '{0}', or "
+              "declaring a constructor in {1} that explicitly invokes a "
+              "constructor in '{0}'.");
 
   /**
    * 13.2 Expression Statements: It is a compile-time error if a non-constant
@@ -1919,8 +1877,9 @@
           'NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as a case "
           "expression.",
-          "Try re-writing the switch as a series of if statements, or "
-          "changing the import to not be deferred.");
+          correction:
+              "Try re-writing the switch as a series of if statements, or "
+              "changing the import to not be deferred.");
 
   /**
    * 6.2.2 Optional Formals: It is a compile-time error if the default value of
@@ -1943,18 +1902,18 @@
           'NON_CONSTANT_DEFAULT_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as a default "
           "parameter value.",
-          "Try leaving the default as null and initializing the parameter "
-          "inside the function body.");
+          correction:
+              "Try leaving the default as null and initializing the parameter "
+              "inside the function body.");
 
   /**
    * 12.6 Lists: It is a compile time error if an element of a constant list
    * literal is not a compile-time constant.
    */
   static const CompileTimeErrorCode NON_CONSTANT_LIST_ELEMENT =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_LIST_ELEMENT',
+      const CompileTimeErrorCode('NON_CONSTANT_LIST_ELEMENT',
           "The values in a const list literal must be constants.",
-          "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.");
 
   /**
    * 12.6 Lists: It is a compile time error if an element of a constant list
@@ -1969,17 +1928,17 @@
           'NON_CONSTANT_LIST_ELEMENT_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as values in "
           "a 'const' list.",
-          "Try removing the keyword 'const' from the list literal.");
+          correction:
+              "Try removing the keyword 'const' from the list literal.");
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an
    * entry in a constant map literal is not a compile-time constant.
    */
   static const CompileTimeErrorCode NON_CONSTANT_MAP_KEY =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_MAP_KEY',
+      const CompileTimeErrorCode('NON_CONSTANT_MAP_KEY',
           "The keys in a const map literal must be constant.",
-          "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.");
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an
@@ -1993,17 +1952,16 @@
           'NON_CONSTANT_MAP_KEY_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as keys in a "
           "const map literal.",
-          "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.");
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an
    * entry in a constant map literal is not a compile-time constant.
    */
   static const CompileTimeErrorCode NON_CONSTANT_MAP_VALUE =
-      const CompileTimeErrorCode(
-          'NON_CONSTANT_MAP_VALUE',
+      const CompileTimeErrorCode('NON_CONSTANT_MAP_VALUE',
           "The values in a const map literal must be constant.",
-          "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.");
 
   /**
    * 12.7 Maps: It is a compile time error if either a key or a value of an
@@ -2017,7 +1975,7 @@
           'NON_CONSTANT_MAP_VALUE_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as values in "
           "a const map literal.",
-          "Try removing the keyword 'const' from the map literal.");
+          correction: "Try removing the keyword 'const' from the map literal.");
 
   /**
    * 15 Metadata: Metadata consists of a series of annotations, each of which
@@ -2055,7 +2013,7 @@
           'NON_CONSTANT_VALUE_IN_INITIALIZER_FROM_DEFERRED_LIBRARY',
           "Constant values from a deferred library can't be used as constant "
           "initializers.",
-          "Try changing the import to not be deferred.");
+          correction: "Try changing the import to not be deferred.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m < h</i>
@@ -2069,10 +2027,9 @@
    * 1: the actual number of positional arguments given
    */
   static const CompileTimeErrorCode NOT_ENOUGH_REQUIRED_ARGUMENTS =
-      const CompileTimeErrorCode(
-          'NOT_ENOUGH_REQUIRED_ARGUMENTS',
+      const CompileTimeErrorCode('NOT_ENOUGH_REQUIRED_ARGUMENTS',
           "{0} required argument(s) expected, but {1} found.",
-          "Try adding the missing arguments.");
+          correction: "Try adding the missing arguments.");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the
@@ -2082,11 +2039,11 @@
    * (respectively <i>S.id</i>)
    */
   static const CompileTimeErrorCode NON_GENERATIVE_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'NON_GENERATIVE_CONSTRUCTOR',
+      const CompileTimeErrorCode('NON_GENERATIVE_CONSTRUCTOR',
           "The generative constructor '{0}' expected, but factory found.",
-          "Try calling a different constructor in the superclass, or "
-          "making the called constructor not be a factory constructor.");
+          correction:
+              "Try calling a different constructor in the superclass, or "
+              "making the called constructor not be a factory constructor.");
 
   /**
    * 7.9 Superclasses: It is a compile-time error to specify an extends clause
@@ -2101,10 +2058,9 @@
    * parameter in an operator.
    */
   static const CompileTimeErrorCode OPTIONAL_PARAMETER_IN_OPERATOR =
-      const CompileTimeErrorCode(
-          'OPTIONAL_PARAMETER_IN_OPERATOR',
+      const CompileTimeErrorCode('OPTIONAL_PARAMETER_IN_OPERATOR',
           "Optional parameters aren't allowed when defining an operator.",
-          "Try removing the optional parameters.");
+          correction: "Try removing the optional parameters.");
 
   /**
    * 14.3 Parts: It is a compile time error if the contents of the URI are not a
@@ -2114,10 +2070,9 @@
    * 0: the uri pointing to a non-library declaration
    */
   static const CompileTimeErrorCode PART_OF_NON_PART =
-      const CompileTimeErrorCode(
-          'PART_OF_NON_PART',
+      const CompileTimeErrorCode('PART_OF_NON_PART',
           "The included part '{0}' must have a part-of directive.",
-          "Try adding a part-of directive to '{0}'.");
+          correction: "Try adding a part-of directive to '{0}'.");
 
   /**
    * 14.1 Imports: It is a compile-time error if the current library declares a
@@ -2128,7 +2083,8 @@
           'PREFIX_COLLIDES_WITH_TOP_LEVEL_MEMBER',
           "The name '{0}' is already used as an import prefix and can't be "
           "used to name a top-level element.",
-          "Try renaming either the top-level element or the prefix.");
+          correction:
+              "Try renaming either the top-level element or the prefix.");
 
   /**
    * 16.32 Identifier Reference: If d is a prefix p, a compile-time error
@@ -2139,8 +2095,9 @@
           'PREFIX_IDENTIFIER_NOT_FOLLOWED_BY_DOT',
           "The name '{0}' refers to an import prefix, so it must be followed "
           "by '.'.",
-          "Try correcting the name to refer to something other than a prefix, or "
-          "renaming the prefix.");
+          correction:
+              "Try correcting the name to refer to something other than a prefix, or "
+              "renaming the prefix.");
 
   /**
    * It is an error for a mixin to add a private name that conflicts with a
@@ -2151,7 +2108,7 @@
           'PRIVATE_COLLISION_IN_MIXIN_APPLICATION',
           "The private name {0}, defined by {1}, conflicts with the same name "
           "defined by {2}.",
-          "Try removing {1} from the 'with' clause.");
+          correction: "Try removing {1} from the 'with' clause.");
 
   /**
    * 6.2.2 Optional Formals: It is a compile-time error if the name of a named
@@ -2272,11 +2229,10 @@
    * the const modifier but <i>k'</i> is not a constant constructor.
    */
   static const CompileTimeErrorCode REDIRECT_TO_MISSING_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'REDIRECT_TO_MISSING_CONSTRUCTOR',
+      const CompileTimeErrorCode('REDIRECT_TO_MISSING_CONSTRUCTOR',
           "The constructor '{0}' couldn't be found in '{1}'.",
-          "Try redirecting to a different constructor, or "
-          "define the constructor named '{0}'.");
+          correction: "Try redirecting to a different constructor, or "
+              "define the constructor named '{0}'.");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with
@@ -2287,7 +2243,7 @@
           'REDIRECT_TO_NON_CLASS',
           "The name '{0}' isn't a type and can't be used in a redirected "
           "constructor.",
-          "Try redirecting to a different constructor.");
+          correction: "Try redirecting to a different constructor.");
 
   /**
    * 7.6.2 Factories: It is a compile-time error if <i>k</i> is prefixed with
@@ -2298,7 +2254,7 @@
           'REDIRECT_TO_NON_CONST_CONSTRUCTOR',
           "Constant factory constructor can't delegate to a non-constant "
           "constructor.",
-          "Try redirecting to a different constructor.");
+          correction: "Try redirecting to a different constructor.");
 
   /**
    * 7.6.1 Generative constructors: A generative constructor may be
@@ -2306,11 +2262,10 @@
    * generative constructor.
    */
   static const CompileTimeErrorCode REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR',
+      const CompileTimeErrorCode('REDIRECT_GENERATIVE_TO_MISSING_CONSTRUCTOR',
           "The constructor '{0}' couldn't be found in '{1}'.",
-          "Try redirecting to a different constructor, or "
-          "defining the constructor named '{0}'.");
+          correction: "Try redirecting to a different constructor, or "
+              "defining the constructor named '{0}'.");
 
   /**
    * 7.6.1 Generative constructors: A generative constructor may be
@@ -2322,7 +2277,7 @@
       const CompileTimeErrorCode(
           'REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR',
           "Generative constructor can't redirect to a factory constructor.",
-          "Try redirecting to a different constructor.");
+          correction: "Try redirecting to a different constructor.");
 
   /**
    * 5 Variables: A local variable may only be referenced at a source code
@@ -2330,12 +2285,11 @@
    * compile-time error occurs.
    */
   static const CompileTimeErrorCode REFERENCED_BEFORE_DECLARATION =
-      const CompileTimeErrorCode(
-          'REFERENCED_BEFORE_DECLARATION',
+      const CompileTimeErrorCode('REFERENCED_BEFORE_DECLARATION',
           "Local variable '{0}' can't be referenced before it is declared.",
-          "Try moving the declaration to before the first use, or "
-          "renaming the local variable so that it doesn't hide a name from an "
-          "enclosing scope.");
+          correction: "Try moving the declaration to before the first use, or "
+              "renaming the local variable so that it doesn't hide a name from an "
+              "enclosing scope.");
 
   /**
    * 12.8.1 Rethrow: It is a compile-time error if an expression of the form
@@ -2343,20 +2297,20 @@
    */
   static const CompileTimeErrorCode RETHROW_OUTSIDE_CATCH =
       const CompileTimeErrorCode(
-          'RETHROW_OUTSIDE_CATCH',
-          "Rethrow must be inside of catch clause.",
-          "Try moving the expression into a catch clause, or using a 'throw' "
-          "expression.");
+          'RETHROW_OUTSIDE_CATCH', "Rethrow must be inside of catch clause.",
+          correction:
+              "Try moving the expression into a catch clause, or using a 'throw' "
+              "expression.");
 
   /**
    * 13.12 Return: It is a compile-time error if a return statement of the form
    * <i>return e;</i> appears in a generative constructor.
    */
   static const CompileTimeErrorCode RETURN_IN_GENERATIVE_CONSTRUCTOR =
-      const CompileTimeErrorCode(
-          'RETURN_IN_GENERATIVE_CONSTRUCTOR',
+      const CompileTimeErrorCode('RETURN_IN_GENERATIVE_CONSTRUCTOR',
           "Constructors can't return values.",
-          "Try removing the return statement or using a factory constructor.");
+          correction:
+              "Try removing the return statement or using a factory constructor.");
 
   /**
    * 13.12 Return: It is a compile-time error if a return statement of the form
@@ -2365,8 +2319,9 @@
   static const CompileTimeErrorCode RETURN_IN_GENERATOR = const CompileTimeErrorCode(
       'RETURN_IN_GENERATOR',
       "Can't return a value from a generator function (using the '{0}' modifier).",
-      "Try removing the value, replacing 'return' with 'yield' or changing the "
-      "method body modifier.");
+      correction:
+          "Try removing the value, replacing 'return' with 'yield' or changing the "
+          "method body modifier.");
 
   /**
    * 14.1 Imports: It is a compile-time error if a prefix used in a deferred
@@ -2377,7 +2332,7 @@
           'SHARED_DEFERRED_PREFIX',
           "The prefix of a deferred import can't be used in other import "
           "directives.",
-          "Try renaming one of the prefixes.");
+          correction: "Try renaming one of the prefixes.");
 
   /**
    * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -2430,9 +2385,8 @@
    */
   static const CompileTimeErrorCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS =
       const CompileTimeErrorCode(
-          'TYPE_ARGUMENT_NOT_MATCHING_BOUNDS',
-          "'{0}' doesn't extend '{1}'.",
-          "Try using a type that is or is a subclass of '{1}'.");
+          'TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', "'{0}' doesn't extend '{1}'.",
+          correction: "Try using a type that is or is a subclass of '{1}'.");
 
   /**
    * 15.3.1 Typedef: Any self reference, either directly, or recursively via
@@ -2450,7 +2404,7 @@
    */
   static const CompileTimeErrorCode UNDEFINED_CLASS =
       const CompileTimeErrorCode('UNDEFINED_CLASS', "Undefined class '{0}'.",
-          "Try defining the class.");
+          correction: "Try defining the class.", isUnresolvedIdentifier: true);
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the
@@ -2464,11 +2418,10 @@
    * 1: the name of the constructor being invoked
    */
   static const CompileTimeErrorCode UNDEFINED_CONSTRUCTOR_IN_INITIALIZER =
-      const CompileTimeErrorCode(
-          'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
+      const CompileTimeErrorCode('UNDEFINED_CONSTRUCTOR_IN_INITIALIZER',
           "The class '{0}' doesn't have a constructor named '{1}'.",
-          "Try defining a constructor named '{1}' in '{0}', or "
-          "invoking a different constructor.");
+          correction: "Try defining a constructor named '{1}' in '{0}', or "
+              "invoking a different constructor.");
 
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the
@@ -2484,8 +2437,8 @@
       UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT = const CompileTimeErrorCode(
           'UNDEFINED_CONSTRUCTOR_IN_INITIALIZER_DEFAULT',
           "The class '{0}' doesn't have an unnamed constructor.",
-          "Try defining an unnamed constructor in '{0}', or "
-          "invoking a different constructor.");
+          correction: "Try defining an unnamed constructor in '{0}', or "
+              "invoking a different constructor.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>,
@@ -2500,11 +2453,11 @@
    * 0: the name of the requested named parameter
    */
   static const CompileTimeErrorCode UNDEFINED_NAMED_PARAMETER =
-      const CompileTimeErrorCode(
-          'UNDEFINED_NAMED_PARAMETER',
+      const CompileTimeErrorCode('UNDEFINED_NAMED_PARAMETER',
           "The named parameter '{0}' isn't defined.",
-          "Try correcting the name to an existing named parameter's name, or "
-          "defining a named parameter with the name '{0}'.");
+          correction:
+              "Try correcting the name to an existing named parameter's name, or "
+              "defining a named parameter with the name '{0}'.");
 
   /**
    * 14.2 Exports: It is a compile-time error if the compilation unit found at
@@ -2523,10 +2476,9 @@
    */
   static const CompileTimeErrorCode URI_DOES_NOT_EXIST =
       const CompileTimeErrorCode(
-          'URI_DOES_NOT_EXIST',
-          "Target of URI doesn't exist: '{0}'.",
-          "Try creating the file referenced by the URI, or "
-          "try using a URI for a file that does exist.");
+          'URI_DOES_NOT_EXIST', "Target of URI doesn't exist: '{0}'.",
+          correction: "Try creating the file referenced by the URI, or "
+              "Try using a URI for a file that does exist.");
 
   /**
    * Just like [URI_DOES_NOT_EXIST], but used when the URI refers to a file that
@@ -2538,11 +2490,11 @@
    * See [INVALID_URI], [URI_DOES_NOT_EXIST].
    */
   static const CompileTimeErrorCode URI_HAS_NOT_BEEN_GENERATED =
-      const CompileTimeErrorCode(
-          'URI_HAS_NOT_BEEN_GENERATED',
+      const CompileTimeErrorCode('URI_HAS_NOT_BEEN_GENERATED',
           "Target of URI hasn't been generated: '{0}'.",
-          "Try running the generator that will generate the file referenced by "
-          "the URI.");
+          correction:
+              "Try running the generator that will generate the file referenced by "
+              "the URI.");
 
   /**
    * 14.1 Imports: It is a compile-time error if <i>x</i> is not a compile-time
@@ -2607,7 +2559,8 @@
           'YIELD_EACH_IN_NON_GENERATOR',
           "Yield-each statements must be in a generator function "
           "(one marked with either 'async*' or 'sync*').",
-          "Try adding 'async*' or 'sync*' to the enclosing function.");
+          correction:
+              "Try adding 'async*' or 'sync*' to the enclosing function.");
 
   /**
    * ?? Yield: It is a compile-time error if a yield statement appears in a
@@ -2618,7 +2571,8 @@
           'YIELD_IN_NON_GENERATOR',
           "Yield statements must be in a generator function "
           "(one marked with either 'async*' or 'sync*').",
-          "Try adding 'async*' or 'sync*' to the enclosing function.");
+          correction:
+              "Try adding 'async*' or 'sync*' to the enclosing function.");
 
   /**
    * Initialize a newly created error code to have the given [name]. The message
@@ -2626,8 +2580,11 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const CompileTimeErrorCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const CompileTimeErrorCode(String name, String message,
+      {String correction, bool isUnresolvedIdentifier: false})
+      : super(name, message,
+            correction: correction,
+            isUnresolvedIdentifier: isUnresolvedIdentifier);
 
   @override
   ErrorSeverity get errorSeverity => ErrorType.COMPILE_TIME_ERROR.severity;
@@ -2655,7 +2612,7 @@
           'EXPECTED_ONE_LIST_TYPE_ARGUMENTS',
           "List literals require exactly one type argument or none, "
           "but {0} found.",
-          "Try adjusting the number of type arguments.");
+          correction: "Try adjusting the number of type arguments.");
 
   /**
    * 12.8 Maps: A fresh instance (7.6.1) <i>m</i>, of size <i>n</i>, whose class
@@ -2669,7 +2626,7 @@
           'EXPECTED_TWO_MAP_TYPE_ARGUMENTS',
           "Map literals require exactly two type arguments or none, "
           "but {0} found.",
-          "Try adjusting the number of type arguments.");
+          correction: "Try adjusting the number of type arguments.");
 
   /**
    * 9 Functions: It is a static warning if the declared return type of a
@@ -2680,8 +2637,8 @@
           'ILLEGAL_ASYNC_GENERATOR_RETURN_TYPE',
           "Functions marked 'async*' must have a return type assignable to "
           "'Stream'.",
-          "Try fixing the return type of the function, or "
-          "removing the modifier 'async*' from the function body.");
+          correction: "Try fixing the return type of the function, or "
+              "removing the modifier 'async*' from the function body.");
 
   /**
    * 9 Functions: It is a static warning if the declared return type of a
@@ -2692,19 +2649,18 @@
           'ILLEGAL_ASYNC_RETURN_TYPE',
           "Functions marked 'async' must have a return type assignable to "
           "'Future'.",
-          "Try fixing the return type of the function, or "
-          "removing the modifier 'async' from the function body.");
+          correction: "Try fixing the return type of the function, or "
+              "removing the modifier 'async' from the function body.");
 
   /**
    * 9 Functions: It is a static warning if the declared return type of a
    * function marked sync* may not be assigned to Iterable.
    */
   static const StaticTypeWarningCode ILLEGAL_SYNC_GENERATOR_RETURN_TYPE =
-      const StaticTypeWarningCode(
-          'ILLEGAL_SYNC_GENERATOR_RETURN_TYPE',
+      const StaticTypeWarningCode('ILLEGAL_SYNC_GENERATOR_RETURN_TYPE',
           "Functions marked 'sync*' must have a return type assignable to 'Iterable'.",
-          "Try fixing the return type of the function, or "
-          "removing the modifier 'sync*' from the function body.");
+          correction: "Try fixing the return type of the function, or "
+              "removing the modifier 'sync*' from the function body.");
 
   /**
    * 8.1.1 Inheritance and Overriding: However, if the above rules would cause
@@ -2735,11 +2691,11 @@
    *   m<sub>k</sub></i> is inherited.
    */
   static const StaticTypeWarningCode INCONSISTENT_METHOD_INHERITANCE =
-      const StaticTypeWarningCode(
-          'INCONSISTENT_METHOD_INHERITANCE',
+      const StaticTypeWarningCode('INCONSISTENT_METHOD_INHERITANCE',
           "Inconsistent declarations of '{0}' are inherited from {1}.",
-          "Try adjusting the supertypes of this class to remove the "
-          "inconsistency.");
+          correction:
+              "Try adjusting the supertypes of this class to remove the "
+              "inconsistency.");
 
   /**
    * 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does
@@ -2753,10 +2709,9 @@
    * See [UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER].
    */
   static const StaticTypeWarningCode INSTANCE_ACCESS_TO_STATIC_MEMBER =
-      const StaticTypeWarningCode(
-          'INSTANCE_ACCESS_TO_STATIC_MEMBER',
+      const StaticTypeWarningCode('INSTANCE_ACCESS_TO_STATIC_MEMBER',
           "Static {1} '{0}' can't be accessed through an instance.",
-          "Try using the class '{2}' to access the {1}.");
+          correction: "Try using the class '{2}' to access the {1}.");
 
   /**
    * 12.18 Assignment: It is a static type warning if the static type of
@@ -2776,11 +2731,10 @@
    * 1: the name of the left hand side type
    */
   static const StaticTypeWarningCode INVALID_ASSIGNMENT =
-      const StaticTypeWarningCode(
-          'INVALID_ASSIGNMENT',
+      const StaticTypeWarningCode('INVALID_ASSIGNMENT',
           "A value of type '{0}' can't be assigned to a variable of type '{1}'.",
-          "Try changing the type of the variable, or "
-          "casting the right-hand type to '{1}'.");
+          correction: "Try changing the type of the variable, or "
+              "casting the right-hand type to '{1}'.");
 
   /**
    * 12.15.1 Ordinary Invocation: An ordinary method invocation <i>i</i> has the
@@ -2808,12 +2762,12 @@
    */
   static const StaticTypeWarningCode INVOCATION_OF_NON_FUNCTION =
       const StaticTypeWarningCode(
-          'INVOCATION_OF_NON_FUNCTION',
-          "'{0}' isn't a function.",
+          'INVOCATION_OF_NON_FUNCTION', "'{0}' isn't a function.",
           // TODO(brianwilkerson) Split this error code so that we can provide
           // better error and correction messages.
-          "Try correcting the name to match an existing function, or "
-          "define a method or function named '{0}'.");
+          correction:
+              "Try correcting the name to match an existing function, or "
+              "define a method or function named '{0}'.");
 
   /**
    * 12.14.4 Function Expression Invocation: A function expression invocation
@@ -2843,19 +2797,17 @@
    */
   static const StaticTypeWarningCode NON_BOOL_CONDITION =
       const StaticTypeWarningCode(
-          'NON_BOOL_CONDITION',
-          "Conditions must have a static type of 'bool'.",
-          "Try changing the condition.");
+          'NON_BOOL_CONDITION', "Conditions must have a static type of 'bool'.",
+          correction: "Try changing the condition.");
 
   /**
    * 17.17 Assert: It is a static type warning if the type of <i>e</i> may not
    * be assigned to bool.
    */
   static const StaticTypeWarningCode NON_BOOL_EXPRESSION =
-      const StaticTypeWarningCode(
-          'NON_BOOL_EXPRESSION',
+      const StaticTypeWarningCode('NON_BOOL_EXPRESSION',
           "The expression in an assert must be of type 'bool'.",
-          "Try changing the expression.");
+          correction: "Try changing the expression.");
 
   /**
    * 12.28 Unary Expressions: The expression !<i>e</i> is equivalent to the
@@ -2865,10 +2817,9 @@
    * <i>e<sub>1</sub></i> may not be assigned to bool.
    */
   static const StaticTypeWarningCode NON_BOOL_NEGATION_EXPRESSION =
-      const StaticTypeWarningCode(
-          'NON_BOOL_NEGATION_EXPRESSION',
+      const StaticTypeWarningCode('NON_BOOL_NEGATION_EXPRESSION',
           "Negation argument must have a static type of 'bool'.",
-          "Try changing the argument to the '!' operator.");
+          correction: "Try changing the argument to the '!' operator.");
 
   /**
    * 12.21 Logical Boolean Expressions: It is a static type warning if the
@@ -2888,22 +2839,21 @@
    * 1: the type of the variable
    */
   static const StaticTypeWarningCode NON_NULLABLE_FIELD_NOT_INITIALIZED =
-      const StaticTypeWarningCode(
-          'NON_NULLABLE_FIELD_NOT_INITIALIZED',
+      const StaticTypeWarningCode('NON_NULLABLE_FIELD_NOT_INITIALIZED',
           "Variable '{0}' of non-nullable type '{1}' must be initialized.",
-          "Try adding an initializer to the declaration, or "
-          "making the variable nullable by adding a '?' after the type name.");
+          correction: "Try adding an initializer to the declaration, or "
+              "making the variable nullable by adding a '?' after the type name.");
 
   /**
    * 15.8 Parameterized Types: It is a static type warning if <i>A<sub>i</sub>,
    * 1 &lt;= i &lt;= n</i> does not denote a type in the enclosing lexical scope.
    */
   static const StaticTypeWarningCode NON_TYPE_AS_TYPE_ARGUMENT =
-      const StaticTypeWarningCode(
-          'NON_TYPE_AS_TYPE_ARGUMENT',
+      const StaticTypeWarningCode('NON_TYPE_AS_TYPE_ARGUMENT',
           "The name '{0}' isn't a type so it can't be used as a type argument.",
-          "Try correcting the name to an existing type, or "
-          "defining a type named '{0}'.");
+          correction: "Try correcting the name to an existing type, or "
+              "defining a type named '{0}'.",
+          isUnresolvedIdentifier: true);
 
   /**
    * 13.11 Return: It is a static type warning if the type of <i>e</i> may not
@@ -2962,9 +2912,8 @@
    */
   static const StaticTypeWarningCode TYPE_ARGUMENT_NOT_MATCHING_BOUNDS =
       const StaticTypeWarningCode(
-          'TYPE_ARGUMENT_NOT_MATCHING_BOUNDS',
-          "'{0}' doesn't extend '{1}'.",
-          "Try using a type that is or is a subclass of '{1}'.");
+          'TYPE_ARGUMENT_NOT_MATCHING_BOUNDS', "'{0}' doesn't extend '{1}'.",
+          correction: "Try using a type that is or is a subclass of '{1}'.");
 
   /**
    * 10 Generics: It is a static type warning if a type parameter is a supertype
@@ -2977,10 +2926,9 @@
    * See [TYPE_ARGUMENT_NOT_MATCHING_BOUNDS].
    */
   static const StaticTypeWarningCode TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND =
-      const StaticTypeWarningCode(
-          'TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND',
+      const StaticTypeWarningCode('TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND',
           "'{0}' can't be a supertype of its upper bound.",
-          "Try using a type that is or is a subclass of '{1}'.");
+          correction: "Try using a type that is or is a subclass of '{1}'.");
 
   /**
    * 12.17 Getter Invocation: It is a static warning if there is no class
@@ -2992,11 +2940,11 @@
    * 1: the name of the enumeration used to access the constant
    */
   static const StaticTypeWarningCode UNDEFINED_ENUM_CONSTANT =
-      const StaticTypeWarningCode(
-          'UNDEFINED_ENUM_CONSTANT',
+      const StaticTypeWarningCode('UNDEFINED_ENUM_CONSTANT',
           "There is no constant named '{0}' in '{1}'.",
-          "Try correcting the name to the name of an existing constant, or "
-          "defining a constant named '{0}'.");
+          correction:
+              "Try correcting the name to the name of an existing constant, or "
+              "defining a constant named '{0}'.");
 
   /**
    * 12.15.3 Unqualified Invocation: If there exists a lexically visible
@@ -3012,11 +2960,11 @@
    */
   static const StaticTypeWarningCode UNDEFINED_FUNCTION =
       const StaticTypeWarningCode(
-          'UNDEFINED_FUNCTION',
-          "The function '{0}' isn't defined.",
-          "Try importing the library that defines '{0}', "
-          "correcting the name to the name of an existing function, or "
-          "defining a function named '{0}'.");
+          'UNDEFINED_FUNCTION', "The function '{0}' isn't defined.",
+          correction: "Try importing the library that defines '{0}', "
+              "correcting the name to the name of an existing function, or "
+              "defining a function named '{0}'.",
+          isUnresolvedIdentifier: true);
 
   /**
    * 12.17 Getter Invocation: Let <i>T</i> be the static type of <i>e</i>. It is
@@ -3027,12 +2975,11 @@
    * 1: the name of the enclosing type where the getter is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_GETTER =
-      const StaticTypeWarningCode(
-          'UNDEFINED_GETTER',
+      const StaticTypeWarningCode('UNDEFINED_GETTER',
           "The getter '{0}' isn't defined for the class '{1}'.",
-          "Try importing the library that defines '{0}', "
-          "correcting the name to the name of an existing getter, or "
-          "defining a getter or field named '{0}'.");
+          correction: "Try importing the library that defines '{0}', "
+              "correcting the name to the name of an existing getter, or "
+              "defining a getter or field named '{0}'.");
 
   /**
    * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
@@ -3044,11 +2991,11 @@
    * 1: the resolved type name that the method lookup is happening on
    */
   static const StaticTypeWarningCode UNDEFINED_METHOD =
-      const StaticTypeWarningCode(
-          'UNDEFINED_METHOD',
+      const StaticTypeWarningCode('UNDEFINED_METHOD',
           "The method '{0}' isn't defined for the class '{1}'.",
-          "Try correcting the name to the name of an existing method, or "
-          "defining a method named '{0}'.");
+          correction:
+              "Try correcting the name to the name of an existing method, or "
+              "defining a method named '{0}'.");
 
   /**
    * 12.15.1 Ordinary Invocation: Let <i>T</i> be the static type of <i>o</i>.
@@ -3060,11 +3007,11 @@
    * 1: the resolved type name that the method lookup is happening on
    */
   static const StaticTypeWarningCode UNDEFINED_METHOD_WITH_CONSTRUCTOR =
-      const StaticTypeWarningCode(
-          'UNDEFINED_METHOD_WITH_CONSTRUCTOR',
+      const StaticTypeWarningCode('UNDEFINED_METHOD_WITH_CONSTRUCTOR',
           "The method '{0}' isn't defined for the class '{1}', but a constructor with that name is defined.",
-          "Try adding 'new' or 'const' to invoke the constructor, or "
-          "correcting the name to the name of an existing method.");
+          correction:
+              "Try adding 'new' or 'const' to invoke the constructor, or "
+              "correcting the name to the name of an existing method.");
 
   /**
    * 12.18 Assignment: Evaluation of an assignment of the form
@@ -3087,10 +3034,9 @@
    * 1: the name of the enclosing type where the operator is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_OPERATOR =
-      const StaticTypeWarningCode(
-          'UNDEFINED_OPERATOR',
+      const StaticTypeWarningCode('UNDEFINED_OPERATOR',
           "The operator '{0}' isn't defined for the class '{1}'.",
-          "Try defining the operator '{0}'.");
+          correction: "Try defining the operator '{0}'.");
 
   /**
    * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>.
@@ -3102,12 +3048,11 @@
    * 1: the name of the enclosing type where the setter is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_SETTER =
-      const StaticTypeWarningCode(
-          'UNDEFINED_SETTER',
+      const StaticTypeWarningCode('UNDEFINED_SETTER',
           "The setter '{0}' isn't defined for the class '{1}'.",
-          "Try importing the library that defines '{0}', "
-          "correcting the name to the name of an existing setter, or "
-          "defining a setter or field named '{0}'.");
+          correction: "Try importing the library that defines '{0}', "
+              "correcting the name to the name of an existing setter, or "
+              "defining a setter or field named '{0}'.");
 
   /**
    * 12.17 Getter Invocation: Let <i>T</i> be the static type of <i>e</i>. It is
@@ -3118,11 +3063,11 @@
    * 1: the name of the enclosing type where the getter is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_SUPER_GETTER =
-      const StaticTypeWarningCode(
-          'UNDEFINED_SUPER_GETTER',
+      const StaticTypeWarningCode('UNDEFINED_SUPER_GETTER',
           "The getter '{0}' isn't defined in a superclass of '{1}'.",
-          "Try correcting the name to the name of an existing getter, or "
-          "defining a getter or field named '{0}' in a superclass.");
+          correction:
+              "Try correcting the name to the name of an existing getter, or "
+              "defining a getter or field named '{0}' in a superclass.");
 
   /**
    * 12.15.4 Super Invocation: A super method invocation <i>i</i> has the form
@@ -3136,11 +3081,11 @@
    * 1: the resolved type name that the method lookup is happening on
    */
   static const StaticTypeWarningCode UNDEFINED_SUPER_METHOD =
-      const StaticTypeWarningCode(
-          'UNDEFINED_SUPER_METHOD',
+      const StaticTypeWarningCode('UNDEFINED_SUPER_METHOD',
           "The method '{0}' isn't defined in a superclass of '{1}'.",
-          "Try correcting the name to the name of an existing method, or "
-          "defining a method named '{0}' in a superclass.");
+          correction:
+              "Try correcting the name to the name of an existing method, or "
+              "defining a method named '{0}' in a superclass.");
 
   /**
    * 12.18 Assignment: Evaluation of an assignment of the form
@@ -3163,10 +3108,9 @@
    * 1: the name of the enclosing type where the operator is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_SUPER_OPERATOR =
-      const StaticTypeWarningCode(
-          'UNDEFINED_SUPER_OPERATOR',
+      const StaticTypeWarningCode('UNDEFINED_SUPER_OPERATOR',
           "The operator '{0}' isn't defined in a superclass of '{1}'.",
-          "Try defining the operator '{0}' in a superclass.");
+          correction: "Try defining the operator '{0}' in a superclass.");
 
   /**
    * 12.18 Assignment: Let <i>T</i> be the static type of <i>e<sub>1</sub></i>.
@@ -3178,11 +3122,11 @@
    * 1: the name of the enclosing type where the setter is being looked for
    */
   static const StaticTypeWarningCode UNDEFINED_SUPER_SETTER =
-      const StaticTypeWarningCode(
-          'UNDEFINED_SUPER_SETTER',
+      const StaticTypeWarningCode('UNDEFINED_SUPER_SETTER',
           "The setter '{0}' isn't defined in a superclass of '{1}'.",
-          "Try correcting the name to the name of an existing setter, or "
-          "defining a setter or field named '{0}' in a superclass.");
+          correction:
+              "Try correcting the name to the name of an existing setter, or "
+              "defining a setter or field named '{0}' in a superclass.");
 
   /**
    * 12.15.1 Ordinary Invocation: It is a static type warning if <i>T</i> does
@@ -3200,7 +3144,7 @@
       const StaticTypeWarningCode(
           'UNQUALIFIED_REFERENCE_TO_NON_LOCAL_STATIC_MEMBER',
           "Static members from supertypes must be qualified by the name of the defining type.",
-          "Try adding '{0}.' before the name.");
+          correction: "Try adding '{0}.' before the name.");
 
   /**
    * 15.8 Parameterized Types: It is a static type warning if <i>G</i> is not a
@@ -3219,7 +3163,7 @@
           'WRONG_NUMBER_OF_TYPE_ARGUMENTS',
           "The type '{0}' is declared with {1} type parameters, "
           "but {2} type arguments were given.",
-          "Try adjusting the number of type arguments.");
+          correction: "Try adjusting the number of type arguments.");
 
   /**
    * It will be a static type warning if <i>m</i> is not a generic method with
@@ -3235,7 +3179,7 @@
           'WRONG_NUMBER_OF_TYPE_ARGUMENTS_METHOD',
           "The method '{0}' is declared with {1} type parameters, "
           "but {2} type arguments were given.",
-          "Try adjusting the number of type arguments.");
+          correction: "Try adjusting the number of type arguments.");
 
   /**
    * 17.16.1 Yield: Let T be the static type of e [the expression to the right
@@ -3295,8 +3239,11 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const StaticTypeWarningCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const StaticTypeWarningCode(String name, String message,
+      {String correction, bool isUnresolvedIdentifier: false})
+      : super(name, message,
+            correction: correction,
+            isUnresolvedIdentifier: isUnresolvedIdentifier);
 
   @override
   ErrorSeverity get errorSeverity => ErrorType.STATIC_TYPE_WARNING.severity;
@@ -3327,10 +3274,9 @@
    * 2: the name of the second library that the type is found
    */
   static const StaticWarningCode AMBIGUOUS_IMPORT = const StaticWarningCode(
-      'AMBIGUOUS_IMPORT',
-      "The name '{0}' is defined in the libraries {1}.",
-      "Try using 'as prefix' for one of the import directives, or "
-      "hiding the name from all but one of the imports.");
+      'AMBIGUOUS_IMPORT', "The name '{0}' is defined in the libraries {1}.",
+      correction: "Try using 'as prefix' for one of the import directives, or "
+          "hiding the name from all but one of the imports.");
 
   /**
    * 12.11.1 New: It is a static warning if the static type of <i>a<sub>i</sub>,
@@ -3373,10 +3319,9 @@
    * A constant variable is always implicitly final.
    */
   static const StaticWarningCode ASSIGNMENT_TO_CONST = const StaticWarningCode(
-      'ASSIGNMENT_TO_CONST',
-      "Constant variables can't be assigned a value.",
-      "Try removing the assignment, or "
-      "remove the modifier 'const' from the variable.");
+      'ASSIGNMENT_TO_CONST', "Constant variables can't be assigned a value.",
+      correction: "Try removing the assignment, or "
+          "remove the modifier 'const' from the variable.");
 
   /**
    * 5 Variables: Attempting to assign to a final variable elsewhere will cause
@@ -3386,7 +3331,7 @@
   static const StaticWarningCode ASSIGNMENT_TO_FINAL = const StaticWarningCode(
       'ASSIGNMENT_TO_FINAL',
       "'{0}' can't be used as a setter because it is final.",
-      "Try finding a different setter, or making '{0}' non-final.");
+      correction: "Try finding a different setter, or making '{0}' non-final.");
 
   /**
    * 5 Variables: Attempting to assign to a final variable elsewhere will cause
@@ -3394,10 +3339,9 @@
    * assignment will also give rise to a static warning for the same reason.
    */
   static const StaticWarningCode ASSIGNMENT_TO_FINAL_LOCAL =
-      const StaticWarningCode(
-          'ASSIGNMENT_TO_FINAL_LOCAL',
+      const StaticWarningCode('ASSIGNMENT_TO_FINAL_LOCAL',
           "'{0}', a final variable, can only be set once.",
-          "Try making '{0}' non-final.");
+          correction: "Try making '{0}' non-final.");
 
   /**
    * 5 Variables: Attempting to assign to a final variable elsewhere will cause
@@ -3405,11 +3349,11 @@
    * assignment will also give rise to a static warning for the same reason.
    */
   static const StaticWarningCode ASSIGNMENT_TO_FINAL_NO_SETTER =
-      const StaticWarningCode(
-          'ASSIGNMENT_TO_FINAL_NO_SETTER',
+      const StaticWarningCode('ASSIGNMENT_TO_FINAL_NO_SETTER',
           "No setter named '{0}' in class '{1}'.",
-          "Try correcting the name to reference an existing setter, or "
-          "declare the setter.");
+          correction:
+              "Try correcting the name to reference an existing setter, or "
+              "declare the setter.");
 
   /**
    * 12.18 Assignment: It is as static warning if an assignment of the form
@@ -3450,7 +3394,7 @@
           'CASE_BLOCK_NOT_TERMINATED',
           "The last statement of the 'case' should be 'break', 'continue', "
           "'rethrow', 'return' or 'throw'.",
-          "Try adding one of the required statements.");
+          correction: "Try adding one of the required statements.");
 
   /**
    * 12.32 Type Cast: It is a static warning if <i>T</i> does not denote a type
@@ -3459,8 +3403,8 @@
   static const StaticWarningCode CAST_TO_NON_TYPE = const StaticWarningCode(
       'CAST_TO_NON_TYPE',
       "The name '{0}' isn't a type, so it can't be used in an 'as' expression.",
-      "Try changing the name to the name of an existing type, or "
-      "creating a type with the name '{0}'.");
+      correction: "Try changing the name to the name of an existing type, or "
+          "creating a type with the name '{0}'.");
 
   /**
    * 7.4 Abstract Instance Members: It is a static warning if an abstract member
@@ -3471,10 +3415,9 @@
    * 1: the name of the enclosing class
    */
   static const StaticWarningCode CONCRETE_CLASS_WITH_ABSTRACT_MEMBER =
-      const StaticWarningCode(
-          'CONCRETE_CLASS_WITH_ABSTRACT_MEMBER',
+      const StaticWarningCode('CONCRETE_CLASS_WITH_ABSTRACT_MEMBER',
           "'{0}' must have a method body because '{1}' isn't abstract.",
-          "Try making '{1}' abstract, or adding a body to '{0}'.");
+          correction: "Try making '{1}' abstract, or adding a body to '{0}'.");
 
   /**
    * 14.1 Imports: If a name <i>N</i> is referenced by a library <i>L</i> and
@@ -3490,11 +3433,10 @@
    * 2: the name of the non-dart: library in which the element is found
    */
   static const StaticWarningCode CONFLICTING_DART_IMPORT =
-      const StaticWarningCode(
-          'CONFLICTING_DART_IMPORT',
+      const StaticWarningCode('CONFLICTING_DART_IMPORT',
           "Element '{0}' from SDK library '{1}' is implicitly hidden by '{2}'.",
-          "Try adding an explicit hide combinator.",
-          false);
+          correction: "Try adding an explicit hide combinator.",
+          isStrongModeError: false);
 
   /**
    * 7.2 Getters: It is a static warning if a class <i>C</i> declares an
@@ -3509,7 +3451,7 @@
       const StaticWarningCode(
           'CONFLICTING_INSTANCE_GETTER_AND_SUPERCLASS_MEMBER',
           "Superclass '{0}' declares static member with the same name.",
-          "Try renaming either the getter or the static member.");
+          correction: "Try renaming either the getter or the static member.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if a class <i>C</i> declares
@@ -3520,7 +3462,7 @@
           'CONFLICTING_INSTANCE_METHOD_SETTER',
           "Class '{0}' declares instance method '{1}', "
           "but also has a setter with the same name from '{2}'.",
-          "Try renaming either the method or the setter.");
+          correction: "Try renaming either the method or the setter.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if a class <i>C</i> declares
@@ -3531,7 +3473,7 @@
           'CONFLICTING_INSTANCE_METHOD_SETTER2',
           "Class '{0}' declares the setter '{1}', "
           "but also has an instance method in the same class.",
-          "Try renaming either the method or the setter.");
+          correction: "Try renaming either the method or the setter.");
 
   /**
    * 7.3 Setters: It is a static warning if a class <i>C</i> declares an
@@ -3546,27 +3488,27 @@
       const StaticWarningCode(
           'CONFLICTING_INSTANCE_SETTER_AND_SUPERCLASS_MEMBER',
           "Superclass '{0}' declares a static member with the same name.",
-          "Try renaming either the setter or the inherited member.");
+          correction:
+              "Try renaming either the setter or the inherited member.");
 
   /**
    * 7.2 Getters: It is a static warning if a class declares a static getter
    * named <i>v</i> and also has a non-static setter named <i>v=</i>.
    */
   static const StaticWarningCode CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER =
-      const StaticWarningCode(
-          'CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER',
+      const StaticWarningCode('CONFLICTING_STATIC_GETTER_AND_INSTANCE_SETTER',
           "Class '{0}' declares non-static setter with the same name.",
-          "Try renaming either the getter or the setter.");
+          correction: "Try renaming either the getter or the setter.");
 
   /**
    * 7.3 Setters: It is a static warning if a class declares a static setter
    * named <i>v=</i> and also has a non-static member named <i>v</i>.
    */
   static const StaticWarningCode CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER =
-      const StaticWarningCode(
-          'CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER',
+      const StaticWarningCode('CONFLICTING_STATIC_SETTER_AND_INSTANCE_MEMBER',
           "Class '{0}' declares non-static member with the same name.",
-          "Try renaming either the inherited member or the setter.");
+          correction:
+              "Try renaming either the inherited member or the setter.");
 
   /**
    * 16.12.2 Const: Given an instance creation expression of the form <i>const
@@ -3575,10 +3517,9 @@
    * factory constructor.
    */
   static const StaticWarningCode CONST_WITH_ABSTRACT_CLASS =
-      const StaticWarningCode(
-          'CONST_WITH_ABSTRACT_CLASS',
+      const StaticWarningCode('CONST_WITH_ABSTRACT_CLASS',
           "Abstract classes can't be created with a 'const' expression.",
-          "Try creating an instance of a subtype.");
+          correction: "Try creating an instance of a subtype.");
 
   /**
    * 12.7 Maps: It is a static warning if the values of any two keys in a map
@@ -3597,10 +3538,10 @@
    * 2:e the shared name of the exported libraries
    */
   static const StaticWarningCode EXPORT_DUPLICATED_LIBRARY_NAMED =
-      const StaticWarningCode(
-          'EXPORT_DUPLICATED_LIBRARY_NAMED',
+      const StaticWarningCode('EXPORT_DUPLICATED_LIBRARY_NAMED',
           "The exported libraries '{0}' and '{1}' can't have the same name '{2}'.",
-          "Try adding a hide clause to one of the export directives.");
+          correction:
+              "Try adding a hide clause to one of the export directives.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
@@ -3613,10 +3554,9 @@
    * See [NOT_ENOUGH_REQUIRED_ARGUMENTS].
    */
   static const StaticWarningCode EXTRA_POSITIONAL_ARGUMENTS =
-      const StaticWarningCode(
-          'EXTRA_POSITIONAL_ARGUMENTS',
+      const StaticWarningCode('EXTRA_POSITIONAL_ARGUMENTS',
           "Too many positional arguments: {0} expected, but {1} found.",
-          "Try removing the extra positional arguments.");
+          correction: "Try removing the extra positional arguments.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
@@ -3629,11 +3569,10 @@
    * See [NOT_ENOUGH_REQUIRED_ARGUMENTS].
    */
   static const StaticWarningCode EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED =
-      const StaticWarningCode(
-          'EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED',
+      const StaticWarningCode('EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED',
           "Too many positional arguments: {0} expected, but {1} found.",
-          "Try removing the extra positional arguments, "
-          "or specifying the name for named arguments.");
+          correction: "Try removing the extra positional arguments, "
+              "or specifying the name for named arguments.");
 
   /**
    * 5. Variables: It is a static warning if a final instance variable that has
@@ -3646,7 +3585,7 @@
           'FIELD_INITIALIZED_IN_INITIALIZER_AND_DECLARATION',
           "Fields can't be initialized in the constructor if they are final "
           "and have already been initialized at their declaration.",
-          "Try removing one of the initializations.");
+          correction: "Try removing one of the initializations.");
 
   /**
    * 5. Variables: It is a static warning if a final instance variable that has
@@ -3662,7 +3601,7 @@
           'FINAL_INITIALIZED_IN_DECLARATION_AND_CONSTRUCTOR',
           "'{0}' is final and was given a value when it was declared, "
           "so it can't be set to a new value.",
-          "Try removing one of the initializations.");
+          correction: "Try removing one of the initializations.");
 
   /**
    * 7.6.1 Generative Constructors: Execution of an initializer of the form
@@ -3695,11 +3634,10 @@
    * 1: the name of the type of the field
    */
   static const StaticWarningCode FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE =
-      const StaticWarningCode(
-          'FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE',
+      const StaticWarningCode('FIELD_INITIALIZING_FORMAL_NOT_ASSIGNABLE',
           "The parameter type '{0}' is incompatible with the field type '{1}'.",
-          "Try changing or removing the parameter's type, or "
-          "changing the field's type.");
+          correction: "Try changing or removing the parameter's type, or "
+              "changing the field's type.");
 
   /**
    * 5 Variables: It is a static warning if a library, static or local variable
@@ -3710,14 +3648,13 @@
    * 0: the name of the uninitialized final variable
    */
   static const StaticWarningCode FINAL_NOT_INITIALIZED =
-      const StaticWarningCode(
-          'FINAL_NOT_INITIALIZED',
+      const StaticWarningCode('FINAL_NOT_INITIALIZED',
           "The final variable '{0}' must be initialized.",
           // TODO(brianwilkerson) Split this error code so that we can suggest
           // initializing fields in constructors (FINAL_FIELD_NOT_INITIALIZED
           // and FINAL_VARIABLE_NOT_INITIALIZED).
-          "Try initializing the variable.",
-          false);
+          correction: "Try initializing the variable.",
+          isStrongModeError: false);
 
   /**
    * 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
@@ -3732,11 +3669,10 @@
    * 0: the name of the uninitialized final variable
    */
   static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_1 =
-      const StaticWarningCode(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
+      const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_1',
           "The final variable '{0}' must be initialized.",
-          "Try adding an initializer for the field.",
-          false);
+          correction: "Try adding an initializer for the field.",
+          isStrongModeError: false);
 
   /**
    * 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
@@ -3752,11 +3688,10 @@
    * 1: the name of the uninitialized final variable
    */
   static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_2 =
-      const StaticWarningCode(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
+      const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_2',
           "The final variables '{0}' and '{1}' must be initialized.",
-          "Try adding initializers for the fields.",
-          false);
+          correction: "Try adding initializers for the fields.",
+          isStrongModeError: false);
 
   /**
    * 7.6.1 Generative Constructors: Each final instance variable <i>f</i>
@@ -3773,11 +3708,10 @@
    * 2: the number of additional not initialized variables that aren't listed
    */
   static const StaticWarningCode FINAL_NOT_INITIALIZED_CONSTRUCTOR_3_PLUS =
-      const StaticWarningCode(
-          'FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
+      const StaticWarningCode('FINAL_NOT_INITIALIZED_CONSTRUCTOR_3',
           "The final variables '{0}', '{1}' and '{2}' more must be initialized.",
-          "Try adding initializers for the fields.",
-          false);
+          correction: "Try adding initializers for the fields.",
+          isStrongModeError: false);
 
   /**
    * 15.5 Function Types: It is a static warning if a concrete class implements
@@ -3786,7 +3720,8 @@
   static const StaticWarningCode FUNCTION_WITHOUT_CALL = const StaticWarningCode(
       'FUNCTION_WITHOUT_CALL',
       "Concrete classes that implement 'Function' must implement the method 'call'.",
-      "Try implementing a 'call' method, or don't implement 'Function'.");
+      correction:
+          "Try implementing a 'call' method, or don't implement 'Function'.");
 
   /**
    * 14.1 Imports: It is a static warning to import two different libraries with
@@ -3798,10 +3733,9 @@
    * 2: the shared name of the imported libraries
    */
   static const StaticWarningCode IMPORT_DUPLICATED_LIBRARY_NAMED =
-      const StaticWarningCode(
-          'IMPORT_DUPLICATED_LIBRARY_NAMED',
+      const StaticWarningCode('IMPORT_DUPLICATED_LIBRARY_NAMED',
           "The imported libraries '{0}' and '{1}' can't have the same name '{2}'.",
-          "Try adding a hide clause to one of the imports.");
+          correction: "Try adding a hide clause to one of the imports.");
 
   /**
    * 14.1 Imports: It is a static warning if the specified URI of a deferred
@@ -3813,10 +3747,9 @@
    * See [CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY].
    */
   static const StaticWarningCode IMPORT_OF_NON_LIBRARY =
-      const StaticWarningCode(
-          'IMPORT_OF_NON_LIBRARY',
+      const StaticWarningCode('IMPORT_OF_NON_LIBRARY',
           "The imported library '{0}' can't have a part-of directive.",
-          "Try importing the library that the part is a part of.");
+          correction: "Try importing the library that the part is a part of.");
 
   /**
    * 8.1.1 Inheritance and Overriding: However, if the above rules would cause
@@ -3834,8 +3767,9 @@
       const StaticWarningCode(
           'INCONSISTENT_METHOD_INHERITANCE_GETTER_AND_METHOD',
           "'{0}' is inherited as a getter and also a method.",
-          "Try adjusting the supertypes of this class to remove the "
-          "inconsistency.");
+          correction:
+              "Try adjusting the supertypes of this class to remove the "
+              "inconsistency.");
 
   /**
    * 7.2 Getters: It is a static warning if a getter <i>m1</i> overrides a
@@ -3855,7 +3789,8 @@
           'INVALID_GETTER_OVERRIDE_RETURN_TYPE',
           "The return type '{0}' isn't assignable to '{1}' as required by the "
           "getter it is overriding from '{2}'.",
-          "Try changing the return types so that they are compatible.");
+          correction:
+              "Try changing the return types so that they are compatible.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -3873,7 +3808,8 @@
           'INVALID_METHOD_OVERRIDE_NAMED_PARAM_TYPE',
           "The parameter type '{0}' isn't assignable to '{1}' as required by "
           "the method it is overriding from '{2}'.",
-          "Try changing the parameter types so that they are compatible.");
+          correction:
+              "Try changing the parameter types so that they are compatible.");
 
   /**
    * Generic Method DEP: number of type parameters must match.
@@ -3889,7 +3825,8 @@
           'INVALID_METHOD_OVERRIDE_TYPE_PARAMETERS',
           "The method has {0} type parameters, but it is overriding a method "
           "with {1} type parameters from '{2}'.",
-          "Try changing the number of type parameters so that they are the same.");
+          correction:
+              "Try changing the number of type parameters so that they are the same.");
 
   /**
    * Generic Method DEP: bounds of type parameters must be compatible.
@@ -3907,7 +3844,8 @@
           'INVALID_METHOD_OVERRIDE_TYPE_PARAMETER_BOUND',
           "The type parameter '{0}' extends '{1}', but that is stricter than "
           "'{2}' extends '{3}' in the overridden method from '{4}'.",
-          "Try changing the bounds on the type parameters so that they are compatible.");
+          correction:
+              "Try changing the bounds on the type parameters so that they are compatible.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -3926,7 +3864,8 @@
           'INVALID_METHOD_OVERRIDE_NORMAL_PARAM_TYPE',
           "The parameter type '{0}' isn't assignable to '{1}' as required by "
           "the method it is overriding from '{2}'.",
-          "Try changing the parameter types so that they are compatible.");
+          correction:
+              "Try changing the parameter types so that they are compatible.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -3944,7 +3883,8 @@
           'INVALID_METHOD_OVERRIDE_OPTIONAL_PARAM_TYPE',
           "The parameter type '{0}' isn't assignable to '{1}' as required by "
           "the method it is overriding from '{2}'.",
-          "Try changing the parameter types so that they are compatible.");
+          correction:
+              "Try changing the parameter types so that they are compatible.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -3964,7 +3904,8 @@
           'INVALID_METHOD_OVERRIDE_RETURN_TYPE',
           "The return type '{0}' isn't assignable to '{1}' as required by the "
           "method it is overriding from '{2}'.",
-          "Try changing the return types so that they are compatible.");
+          correction:
+              "Try changing the return types so that they are compatible.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -3978,7 +3919,7 @@
           'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED',
           "Parameters can't override default values, "
           "this method overrides '{0}.{1}' where '{2}' has a different value.",
-          "Try using the same default value in both methods.");
+          correction: "Try using the same default value in both methods.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -3993,7 +3934,7 @@
           'INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_POSITIONAL',
           "Parameters can't override default values, this method overrides "
           "'{0}.{1}' where this positional parameter has a different value.",
-          "Try using the same default value in both methods.");
+          correction: "Try using the same default value in both methods.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -4010,8 +3951,8 @@
           'INVALID_OVERRIDE_NAMED',
           "Missing the named parameter '{0}' "
           "to match the overridden method from '{1}' from '{2}'.",
-          "Try adding the named parameter to this method, or "
-          "removing it from the overridden method.");
+          correction: "Try adding the named parameter to this method, or "
+              "removing it from the overridden method.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -4028,7 +3969,7 @@
           'INVALID_OVERRIDE_POSITIONAL',
           "Must have at least {0} parameters "
           "to match the overridden method '{1}' from '{2}'.",
-          "Try adding the necessary parameters.");
+          correction: "Try adding the necessary parameters.");
 
   /**
    * 7.1 Instance Methods: It is a static warning if an instance method
@@ -4045,7 +3986,7 @@
           'INVALID_OVERRIDE_REQUIRED',
           "Must have {0} required parameters or less "
           "to match the overridden method '{1}' from '{2}'.",
-          "Try removing the extra parameters.");
+          correction: "Try removing the extra parameters.");
 
   /**
    * 7.3 Setters: It is a static warning if a setter <i>m1</i> overrides a
@@ -4065,7 +4006,8 @@
           'INVALID_SETTER_OVERRIDE_NORMAL_PARAM_TYPE',
           "The parameter type '{0}' isn't assignable to '{1}' as required by "
           "the setter it is overriding from '{2}'.",
-          "Try changing the parameter types so that they are compatible.");
+          correction:
+              "Try changing the parameter types so that they are compatible.");
 
   /**
    * 12.6 Lists: A run-time list literal &lt;<i>E</i>&gt; [<i>e<sub>1</sub></i>
@@ -4132,8 +4074,8 @@
           'MISMATCHED_GETTER_AND_SETTER_TYPES',
           "The parameter type for setter '{0}' is '{1}' which isn't assignable "
           "to its getter (of type '{2}').",
-          "Try changing the types so that they are compatible.",
-          false);
+          correction: "Try changing the types so that they are compatible.",
+          isStrongModeError: false);
 
   /**
    * 7.3 Setters: It is a static warning if a class has a setter named <i>v=</i>
@@ -4146,8 +4088,8 @@
           'MISMATCHED_GETTER_AND_SETTER_TYPES_FROM_SUPERTYPE',
           "The parameter type for setter '{0}' is '{1}' which isn't assignable "
           "to its getter (of type '{2}'), from superclass '{3}'.",
-          "Try changing the types so that they are compatible.",
-          false);
+          correction: "Try changing the types so that they are compatible.",
+          isStrongModeError: false);
 
   /**
    * 17.9 Switch: It is a static warning if all of the following conditions
@@ -4164,11 +4106,10 @@
    */
   static const StaticWarningCode MISSING_ENUM_CONSTANT_IN_SWITCH =
       const StaticWarningCode(
-          'MISSING_ENUM_CONSTANT_IN_SWITCH',
-          "Missing case clause for '{0}'.",
-          "Try adding a case clause for the missing constant, or "
-          "adding a default clause.",
-          false);
+          'MISSING_ENUM_CONSTANT_IN_SWITCH', "Missing case clause for '{0}'.",
+          correction: "Try adding a case clause for the missing constant, or "
+              "adding a default clause.",
+          isStrongModeError: false);
 
   /**
    * 13.12 Return: It is a static warning if a function contains both one or
@@ -4180,19 +4121,18 @@
       "Functions can't include return statements both with and without values.",
       // TODO(brianwilkerson) Split this error code depending on whether the
       // function declares a return type.
-      "Try making all the return statements consistent "
-      "(either include a value or not).",
-      false);
+      correction: "Try making all the return statements consistent "
+          "(either include a value or not).",
+      isStrongModeError: false);
 
   /**
    * 12.11.1 New: It is a static warning if <i>q</i> is a constructor of an
    * abstract class and <i>q</i> is not a factory constructor.
    */
   static const StaticWarningCode NEW_WITH_ABSTRACT_CLASS =
-      const StaticWarningCode(
-          'NEW_WITH_ABSTRACT_CLASS',
+      const StaticWarningCode('NEW_WITH_ABSTRACT_CLASS',
           "Abstract classes can't be created with a 'new' expression.",
-          "Try creating an instance of a subtype.");
+          correction: "Try creating an instance of a subtype.");
 
   /**
    * 15.8 Parameterized Types: Any use of a malbounded type gives rise to a
@@ -4211,7 +4151,7 @@
           'NEW_WITH_INVALID_TYPE_PARAMETERS',
           "The type '{0}' is declared with {1} type parameters, "
           "but {2} type arguments were given.",
-          "Try adjusting the number of type arguments.");
+          correction: "Try adjusting the number of type arguments.");
 
   /**
    * 12.11.1 New: It is a static warning if <i>T</i> is not a class accessible
@@ -4221,9 +4161,8 @@
    * 0: the name of the non-type element
    */
   static const StaticWarningCode NEW_WITH_NON_TYPE = const StaticWarningCode(
-      'NEW_WITH_NON_TYPE',
-      "The name '{0}' isn't a class.",
-      "Try correcting the name to match an existing class.");
+      'NEW_WITH_NON_TYPE', "The name '{0}' isn't a class.",
+      correction: "Try correcting the name to match an existing class.");
 
   /**
    * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the
@@ -4239,11 +4178,10 @@
    * declare a constructor with the same name as the declaration of <i>T</i>.
    */
   static const StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR =
-      const StaticWarningCode(
-          'NEW_WITH_UNDEFINED_CONSTRUCTOR',
+      const StaticWarningCode('NEW_WITH_UNDEFINED_CONSTRUCTOR',
           "The class '{0}' doesn't have a constructor named '{1}'.",
-          "Try invoking a different constructor, or "
-          "define a constructor named '{1}'.");
+          correction: "Try invoking a different constructor, or "
+              "define a constructor named '{1}'.");
 
   /**
    * 12.11.1 New: If <i>T</i> is a class or parameterized type accessible in the
@@ -4258,10 +4196,10 @@
    * same name as the declaration of <i>T</i>.
    */
   static const StaticWarningCode NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT =
-      const StaticWarningCode(
-          'NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT',
+      const StaticWarningCode('NEW_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT',
           "The class '{0}' doesn't have a default constructor.",
-          "Try using one of the named constructors defined in '{0}'.");
+          correction:
+              "Try using one of the named constructors defined in '{0}'.");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract
@@ -4289,7 +4227,8 @@
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FIVE_PLUS',
           "Missing concrete implementations of {0}, {1}, {2}, {3} and {4} more.",
-          "Try implementing the missing methods, or make the class abstract.");
+          correction:
+              "Try implementing the missing methods, or make the class abstract.");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract
@@ -4316,7 +4255,8 @@
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_FOUR',
           "Missing concrete implementations of {0}, {1}, {2} and {3}.",
-          "Try implementing the missing methods, or make the class abstract.");
+          correction:
+              "Try implementing the missing methods, or make the class abstract.");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract
@@ -4339,7 +4279,8 @@
       NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE = const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE',
           "Missing concrete implementation of {0}.",
-          "Try implementing the missing method, or make the class abstract.");
+          correction:
+              "Try implementing the missing method, or make the class abstract.");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract
@@ -4365,7 +4306,8 @@
       const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_THREE',
           "Missing concrete implementations of {0}, {1} and {2}.",
-          "Try implementing the missing methods, or make the class abstract.");
+          correction:
+              "Try implementing the missing methods, or make the class abstract.");
 
   /**
    * 7.9.1 Inheritance and Overriding: It is a static warning if a non-abstract
@@ -4389,7 +4331,8 @@
       NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO = const StaticWarningCode(
           'NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO',
           "Missing concrete implementations of {0} and {1}.",
-          "Try implementing the missing methods, or make the class abstract.");
+          correction:
+              "Try implementing the missing methods, or make the class abstract.");
 
   /**
    * 13.11 Try: An on-catch clause of the form <i>on T catch (p<sub>1</sub>,
@@ -4402,33 +4345,30 @@
    * 0: the name of the non-type element
    */
   static const StaticWarningCode NON_TYPE_IN_CATCH_CLAUSE =
-      const StaticWarningCode(
-          'NON_TYPE_IN_CATCH_CLAUSE',
+      const StaticWarningCode('NON_TYPE_IN_CATCH_CLAUSE',
           "The name '{0}' isn't a type and can't be used in an on-catch clause.",
-          "Try correcting the name to match an existing class.");
+          correction: "Try correcting the name to match an existing class.");
 
   /**
    * 7.1.1 Operators: It is a static warning if the return type of the
    * user-declared operator []= is explicitly declared and not void.
    */
   static const StaticWarningCode NON_VOID_RETURN_FOR_OPERATOR =
-      const StaticWarningCode(
-          'NON_VOID_RETURN_FOR_OPERATOR',
+      const StaticWarningCode('NON_VOID_RETURN_FOR_OPERATOR',
           "The return type of the operator []= must be 'void'.",
-          "Try changing the return type to 'void'.",
-          false);
+          correction: "Try changing the return type to 'void'.",
+          isStrongModeError: false);
 
   /**
    * 7.3 Setters: It is a static warning if a setter declares a return type
    * other than void.
    */
   static const StaticWarningCode NON_VOID_RETURN_FOR_SETTER =
-      const StaticWarningCode(
-          'NON_VOID_RETURN_FOR_SETTER',
+      const StaticWarningCode('NON_VOID_RETURN_FOR_SETTER',
           "The return type of the setter must be 'void' or absent.",
-          "Try removing the return type, or "
-          "define a method rather than a setter.",
-          false);
+          correction: "Try removing the return type, or "
+              "define a method rather than a setter.",
+          isStrongModeError: false);
 
   /**
    * 15.1 Static Types: A type <i>T</i> is malformed iff:
@@ -4446,9 +4386,8 @@
    * 0: the name that is not a type
    */
   static const StaticWarningCode NOT_A_TYPE = const StaticWarningCode(
-      'NOT_A_TYPE',
-      "{0} isn't a type.",
-      "Try correcting the name to match an existing type.");
+      'NOT_A_TYPE', "{0} isn't a type.",
+      correction: "Try correcting the name to match an existing type.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: It is a static warning if <i>m &lt;
@@ -4461,10 +4400,9 @@
    * See [EXTRA_POSITIONAL_ARGUMENTS].
    */
   static const StaticWarningCode NOT_ENOUGH_REQUIRED_ARGUMENTS =
-      const StaticWarningCode(
-          'NOT_ENOUGH_REQUIRED_ARGUMENTS',
+      const StaticWarningCode('NOT_ENOUGH_REQUIRED_ARGUMENTS',
           "{0} required argument(s) expected, but {1} found.",
-          "Try adding the additional required arguments.");
+          correction: "Try adding the additional required arguments.");
 
   /**
    * 14.3 Parts: It is a static warning if the referenced part declaration
@@ -4476,11 +4414,10 @@
    * 1: the non-matching actual library name from the "part of" declaration
    */
   static const StaticWarningCode PART_OF_DIFFERENT_LIBRARY =
-      const StaticWarningCode(
-          'PART_OF_DIFFERENT_LIBRARY',
+      const StaticWarningCode('PART_OF_DIFFERENT_LIBRARY',
           "Expected this library to be part of '{0}', not '{1}'.",
-          "Try including a different part, or "
-          "changing the name of the library in the part's part-of directive.");
+          correction: "Try including a different part, or "
+              "changing the name of the library in the part's part-of directive.");
 
   /**
    * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i>
@@ -4491,11 +4428,10 @@
    * 1: the name of the redirecting constructor
    */
   static const StaticWarningCode REDIRECT_TO_INVALID_FUNCTION_TYPE =
-      const StaticWarningCode(
-          'REDIRECT_TO_INVALID_FUNCTION_TYPE',
+      const StaticWarningCode('REDIRECT_TO_INVALID_FUNCTION_TYPE',
           "The redirected constructor '{0}' has incompatible parameters with '{1}'.",
-          "Try redirecting to a different constructor, or "
-          "directly invoking the desired constructor rather than redirecting to it.");
+          correction: "Try redirecting to a different constructor, or "
+              "directly invoking the desired constructor rather than redirecting to it.");
 
   /**
    * 7.6.2 Factories: It is a static warning if the function type of <i>k'</i>
@@ -4506,11 +4442,10 @@
    * 1: the name of the redirecting constructor's return type
    */
   static const StaticWarningCode REDIRECT_TO_INVALID_RETURN_TYPE =
-      const StaticWarningCode(
-          'REDIRECT_TO_INVALID_RETURN_TYPE',
+      const StaticWarningCode('REDIRECT_TO_INVALID_RETURN_TYPE',
           "The return type '{0}' of the redirected constructor isn't assignable to '{1}'.",
-          "Try redirecting to a different constructor, or "
-          "directly invoking the desired constructor rather than redirecting to it.");
+          correction: "Try redirecting to a different constructor, or "
+              "directly invoking the desired constructor rather than redirecting to it.");
 
   /**
    * 7.6.2 Factories: It is a static warning if type does not denote a class
@@ -4519,11 +4454,11 @@
    * <i>type.id</i>) is not a constructor of <i>C</i>.
    */
   static const StaticWarningCode REDIRECT_TO_MISSING_CONSTRUCTOR =
-      const StaticWarningCode(
-          'REDIRECT_TO_MISSING_CONSTRUCTOR',
+      const StaticWarningCode('REDIRECT_TO_MISSING_CONSTRUCTOR',
           "The constructor '{0}' couldn't be found in '{1}'.",
-          "Try correcting the constructor name to an existing constructor, or "
-          "defining the constructor in '{1}'.");
+          correction:
+              "Try correcting the constructor name to an existing constructor, or "
+              "defining the constructor in '{1}'.");
 
   /**
    * 7.6.2 Factories: It is a static warning if type does not denote a class
@@ -4534,7 +4469,7 @@
   static const StaticWarningCode REDIRECT_TO_NON_CLASS = const StaticWarningCode(
       'REDIRECT_TO_NON_CLASS',
       "The name '{0}' isn't a type and can't be used in a redirected constructor.",
-      "Try correcting the name to match an existing class.");
+      correction: "Try correcting the name to match an existing class.");
 
   /**
    * 13.12 Return: Let <i>f</i> be the function immediately enclosing a return
@@ -4544,10 +4479,8 @@
    * * The return type of <i>f</i> may not be assigned to void.
    */
   static const StaticWarningCode RETURN_WITHOUT_VALUE = const StaticWarningCode(
-      'RETURN_WITHOUT_VALUE',
-      "Missing return value after 'return'.",
-      null,
-      false);
+      'RETURN_WITHOUT_VALUE', "Missing return value after 'return'.",
+      correction: null, isStrongModeError: false);
 
   /**
    * 12.16.3 Static Invocation: It is a static warning if <i>C</i> does not
@@ -4579,32 +4512,30 @@
    *    annotation
    */
   static const StaticWarningCode TYPE_ANNOTATION_DEFERRED_CLASS =
-      const StaticWarningCode(
-          'TYPE_ANNOTATION_DEFERRED_CLASS',
+      const StaticWarningCode('TYPE_ANNOTATION_DEFERRED_CLASS',
           "The deferred type '{0}' can't be used in a declaration, cast or type test.",
-          "Try using a different type, or "
-          "changing the import to not be deferred.");
+          correction: "Try using a different type, or "
+              "changing the import to not be deferred.");
 
   /**
    * 12.31 Type Test: It is a static warning if <i>T</i> does not denote a type
    * available in the current lexical scope.
    */
   static const StaticWarningCode TYPE_TEST_WITH_NON_TYPE =
-      const StaticWarningCode(
-          'TYPE_TEST_WITH_NON_TYPE',
+      const StaticWarningCode('TYPE_TEST_WITH_NON_TYPE',
           "The name '{0}' isn't a type and can't be used in an 'is' expression.",
-          "Try correcting the name to match an existing type.");
+          correction: "Try correcting the name to match an existing type.");
 
   /**
    * 12.31 Type Test: It is a static warning if <i>T</i> does not denote a type
    * available in the current lexical scope.
    */
   static const StaticWarningCode TYPE_TEST_WITH_UNDEFINED_NAME =
-      const StaticWarningCode(
-          'TYPE_TEST_WITH_UNDEFINED_NAME',
+      const StaticWarningCode('TYPE_TEST_WITH_UNDEFINED_NAME',
           "The name '{0}' isn't defined, so it can't be used in an 'is' expression.",
-          "Try changing the name to the name of an existing type, or "
-          "creating a type with the name '{0}'.");
+          correction:
+              "Try changing the name to the name of an existing type, or "
+              "creating a type with the name '{0}'.");
 
   /**
    * 10 Generics: However, a type parameter is considered to be a malformed type
@@ -4615,11 +4546,10 @@
    * checker and the runtime.
    */
   static const StaticWarningCode TYPE_PARAMETER_REFERENCED_BY_STATIC =
-      const StaticWarningCode(
-          'TYPE_PARAMETER_REFERENCED_BY_STATIC',
+      const StaticWarningCode('TYPE_PARAMETER_REFERENCED_BY_STATIC',
           "Static members can't reference type parameters of the class.",
-          "Try removing the reference to the type parameter, or "
-          "making the member an instance member.");
+          correction: "Try removing the reference to the type parameter, or "
+              "making the member an instance member.");
 
   /**
    * 12.16.3 Static Invocation: A static method invocation <i>i</i> has the form
@@ -4631,17 +4561,18 @@
    * 0: the name of the undefined class
    */
   static const StaticWarningCode UNDEFINED_CLASS = const StaticWarningCode(
-      'UNDEFINED_CLASS',
-      "Undefined class '{0}'.",
-      "Try changing the name to the name of an existing class, or "
-      "creating a class with the name '{0}'.");
+      'UNDEFINED_CLASS', "Undefined class '{0}'.",
+      correction: "Try changing the name to the name of an existing class, or "
+          "creating a class with the name '{0}'.",
+      isUnresolvedIdentifier: true);
 
   /**
    * Same as [UNDEFINED_CLASS], but to catch using "boolean" instead of "bool".
    */
   static const StaticWarningCode UNDEFINED_CLASS_BOOLEAN =
-      const StaticWarningCode('UNDEFINED_CLASS_BOOLEAN',
-          "Undefined class 'boolean'.", "Try using the type 'bool'.");
+      const StaticWarningCode(
+          'UNDEFINED_CLASS_BOOLEAN', "Undefined class 'boolean'.",
+          correction: "Try using the type 'bool'.");
 
   /**
    * 12.17 Getter Invocation: It is a static warning if there is no class
@@ -4653,9 +4584,9 @@
    * 1: the name of the enclosing type where the getter is being looked for
    */
   static const StaticWarningCode UNDEFINED_GETTER = const StaticWarningCode(
-      'UNDEFINED_GETTER',
-      "The getter '{0}' isn't defined for the class '{1}'.",
-      "Try defining a getter or field named '{0}', or invoke a different getter.");
+      'UNDEFINED_GETTER', "The getter '{0}' isn't defined for the class '{1}'.",
+      correction:
+          "Try defining a getter or field named '{0}', or invoke a different getter.");
 
   /**
    * 12.30 Identifier Reference: It is as static warning if an identifier
@@ -4667,22 +4598,21 @@
    * Parameters:
    * 0: the name of the identifier
    */
-  static const StaticWarningCode UNDEFINED_IDENTIFIER = const StaticWarningCode(
-      'UNDEFINED_IDENTIFIER',
-      "Undefined name '{0}'.",
-      "Try correcting the name to one that is defined, or "
-      "defining the name.");
+  static const StaticWarningCode UNDEFINED_IDENTIFIER =
+      const StaticWarningCode('UNDEFINED_IDENTIFIER', "Undefined name '{0}'.",
+          correction: "Try correcting the name to one that is defined, or "
+              "defining the name.",
+          isUnresolvedIdentifier: true);
 
   /**
    * If the identifier is 'await', be helpful about it.
    */
   static const StaticWarningCode UNDEFINED_IDENTIFIER_AWAIT =
-      const StaticWarningCode(
-          'UNDEFINED_IDENTIFIER_AWAIT',
+      const StaticWarningCode('UNDEFINED_IDENTIFIER_AWAIT',
           "Undefined name 'await' in function body not marked with 'async'.",
-          "Try correcting the name to one that is defined, "
-          "defining the name, or "
-          "adding 'async' to the enclosing function body.");
+          correction: "Try correcting the name to one that is defined, "
+              "defining the name, or "
+              "adding 'async' to the enclosing function body.");
 
   /**
    * 12.14.2 Binding Actuals to Formals: Furthermore, each <i>q<sub>i</sub></i>,
@@ -4694,11 +4624,11 @@
    * 0: the name of the requested named parameter
    */
   static const StaticWarningCode UNDEFINED_NAMED_PARAMETER =
-      const StaticWarningCode(
-          'UNDEFINED_NAMED_PARAMETER',
+      const StaticWarningCode('UNDEFINED_NAMED_PARAMETER',
           "The named parameter '{0}' isn't defined.",
-          "Try correcting the name to an existing named parameter, or "
-          "defining a new parameter with this name.");
+          correction:
+              "Try correcting the name to an existing named parameter, or "
+              "defining a new parameter with this name.");
 
   /**
    * 12.18 Assignment: It is as static warning if an assignment of the form
@@ -4716,9 +4646,9 @@
    * 1: the name of the enclosing type where the setter is being looked for
    */
   static const StaticWarningCode UNDEFINED_SETTER = const StaticWarningCode(
-      'UNDEFINED_SETTER',
-      "The setter '{0}' isn't defined for the class '{1}'.",
-      "Try defining a setter or field named '{0}', or invoke a different setter.");
+      'UNDEFINED_SETTER', "The setter '{0}' isn't defined for the class '{1}'.",
+      correction:
+          "Try defining a setter or field named '{0}', or invoke a different setter.");
 
   /**
    * 12.16.3 Static Invocation: It is a static warning if <i>C</i> does not
@@ -4729,11 +4659,10 @@
    * 1: the name of the enclosing type where the method is being looked for
    */
   static const StaticWarningCode UNDEFINED_STATIC_METHOD_OR_GETTER =
-      const StaticWarningCode(
-          'UNDEFINED_STATIC_METHOD_OR_GETTER',
+      const StaticWarningCode('UNDEFINED_STATIC_METHOD_OR_GETTER',
           "The static method, getter or setter '{0}' isn't defined for the class '{1}'.",
-          "Try correcting the name to an existing member, or "
-          "defining the member in '{1}'.");
+          correction: "Try correcting the name to an existing member, or "
+              "defining the member in '{1}'.");
 
   /**
    * 12.17 Getter Invocation: It is a static warning if there is no class
@@ -4745,11 +4674,10 @@
    * 1: the name of the enclosing type where the getter is being looked for
    */
   static const StaticWarningCode UNDEFINED_SUPER_GETTER =
-      const StaticWarningCode(
-          'UNDEFINED_SUPER_GETTER',
+      const StaticWarningCode('UNDEFINED_SUPER_GETTER',
           "The getter '{0}' isn't defined in a superclass of '{1}'.",
-          "Try correcting the name to an existing getter, or "
-          "defining the getter in a superclass of '{1}'.");
+          correction: "Try correcting the name to an existing getter, or "
+              "defining the getter in a superclass of '{1}'.");
 
   /**
    * 12.18 Assignment: It is as static warning if an assignment of the form
@@ -4767,11 +4695,10 @@
    * 1: the name of the enclosing type where the setter is being looked for
    */
   static const StaticWarningCode UNDEFINED_SUPER_SETTER =
-      const StaticWarningCode(
-          'UNDEFINED_SUPER_SETTER',
+      const StaticWarningCode('UNDEFINED_SUPER_SETTER',
           "The setter '{0}' isn't defined in a superclass of '{1}'.",
-          "Try correcting the name to an existing setter, or "
-          "defining the setter in a superclass of '{1}'.");
+          correction: "Try correcting the name to an existing setter, or "
+              "defining the setter in a superclass of '{1}'.");
 
   /**
    * It is a static warning to assign void to any non-void type in dart.
@@ -4783,9 +4710,10 @@
   static const StaticWarningCode USE_OF_VOID_RESULT = const StaticWarningCode(
       'USE_OF_VOID_RESULT',
       "The expression here has a type of 'void', and therefore cannot be used.",
-      'Check if you are using the correct API; there may be a function or'
-      " call that returns void you didn't expect. Also check type parameters"
-      ' and variables which, in rare cases, may be void as well.');
+      correction:
+          'Check if you are using the correct API; there may be a function or'
+          " call that returns void you didn't expect. Also check type parameters"
+          ' and variables which, in rare cases, may be void as well.');
 
   /**
    * A flag indicating whether this warning is an error when running with strong
@@ -4800,8 +4728,12 @@
    * given [correction] template.
    */
   const StaticWarningCode(String name, String message,
-      [String correction, this.isStrongModeError = true])
-      : super(name, message, correction);
+      {String correction,
+      this.isStrongModeError = true,
+      bool isUnresolvedIdentifier: false})
+      : super(name, message,
+            correction: correction,
+            isUnresolvedIdentifier: isUnresolvedIdentifier);
 
   @override
   ErrorSeverity get errorSeverity => ErrorType.STATIC_WARNING.severity;
@@ -4844,34 +4776,24 @@
   static const String _inferredTypeMessage = "'{0}' has inferred type '{1}'.";
 
   static const StrongModeCode DOWN_CAST_COMPOSITE = const StrongModeCode(
-      ErrorType.HINT,
-      'DOWN_CAST_COMPOSITE',
-      _implicitCastMessage,
-      _implicitCastCorrection);
+      ErrorType.HINT, 'DOWN_CAST_COMPOSITE', _implicitCastMessage,
+      correction: _implicitCastCorrection);
 
   static const StrongModeCode DOWN_CAST_IMPLICIT = const StrongModeCode(
-      ErrorType.HINT,
-      'DOWN_CAST_IMPLICIT',
-      _implicitCastMessage,
-      _implicitCastCorrection);
+      ErrorType.HINT, 'DOWN_CAST_IMPLICIT', _implicitCastMessage,
+      correction: _implicitCastCorrection);
 
   static const StrongModeCode DOWN_CAST_IMPLICIT_ASSIGN = const StrongModeCode(
-      ErrorType.HINT,
-      'DOWN_CAST_IMPLICIT_ASSIGN',
-      _implicitCastMessage,
-      _implicitCastCorrection);
+      ErrorType.HINT, 'DOWN_CAST_IMPLICIT_ASSIGN', _implicitCastMessage,
+      correction: _implicitCastCorrection);
 
   static const StrongModeCode DYNAMIC_CAST = const StrongModeCode(
-      ErrorType.HINT,
-      'DYNAMIC_CAST',
-      _implicitCastMessage,
-      _implicitCastCorrection);
+      ErrorType.HINT, 'DYNAMIC_CAST', _implicitCastMessage,
+      correction: _implicitCastCorrection);
 
   static const StrongModeCode ASSIGNMENT_CAST = const StrongModeCode(
-      ErrorType.HINT,
-      'ASSIGNMENT_CAST',
-      _implicitCastMessage,
-      _implicitCastCorrection);
+      ErrorType.HINT, 'ASSIGNMENT_CAST', _implicitCastMessage,
+      correction: _implicitCastCorrection);
 
   static const StrongModeCode INVALID_PARAMETER_DECLARATION =
       const StrongModeCode(
@@ -4981,75 +4903,75 @@
       ErrorType.COMPILE_TIME_ERROR,
       'IMPLICIT_DYNAMIC_PARAMETER',
       "Missing parameter type for '{0}'.",
-      _implicitDynamicCorrection);
+      correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_RETURN = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'IMPLICIT_DYNAMIC_RETURN',
       "Missing return type for '{0}'.",
-      _implicitDynamicCorrection);
+      correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_VARIABLE = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'IMPLICIT_DYNAMIC_VARIABLE',
       "Missing variable type for '{0}'.",
-      _implicitDynamicCorrection);
+      correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_FIELD = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'IMPLICIT_DYNAMIC_FIELD',
       "Missing field type for '{0}'.",
-      _implicitDynamicCorrection);
+      correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_TYPE = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'IMPLICIT_DYNAMIC_TYPE',
       "Missing type arguments for generic type '{0}'.",
-      _implicitDynamicCorrection);
+      correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_LIST_LITERAL =
       const StrongModeCode(
           ErrorType.COMPILE_TIME_ERROR,
           'IMPLICIT_DYNAMIC_LIST_LITERAL',
           "Missing type argument for list literal.",
-          _implicitDynamicCorrection);
+          correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_MAP_LITERAL =
       const StrongModeCode(
           ErrorType.COMPILE_TIME_ERROR,
           'IMPLICIT_DYNAMIC_MAP_LITERAL',
           "Missing type arguments for map literal.",
-          _implicitDynamicCorrection);
+          correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_FUNCTION = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'IMPLICIT_DYNAMIC_FUNCTION',
       "Missing type arguments for generic function '{0}<{1}>'.",
-      _implicitDynamicCorrection);
+      correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_METHOD = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'IMPLICIT_DYNAMIC_METHOD',
       "Missing type arguments for generic method '{0}<{1}>'.",
-      _implicitDynamicCorrection);
+      correction: _implicitDynamicCorrection);
 
   static const StrongModeCode IMPLICIT_DYNAMIC_INVOKE = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'IMPLICIT_DYNAMIC_INVOKE',
       "Missing type arguments for calling generic function type '{0}'.",
-      _implicitDynamicCorrection);
+      correction: _implicitDynamicCorrection);
 
   static const StrongModeCode NO_DEFAULT_BOUNDS = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'NO_DEFAULT_BOUNDS',
       "Type has no default bounds",
-      "Try adding explicit type arguments to type");
+      correction: "Try adding explicit type arguments to type");
 
   static const StrongModeCode NOT_INSTANTIATED_BOUND = const StrongModeCode(
       ErrorType.COMPILE_TIME_ERROR,
       'NOT_INSTANTIATED_BOUND',
       "Type parameter bound types must be instantiated.",
-      "Try adding type arguments.");
+      correction: "Try adding type arguments.");
 
   /*
    * TODO(brianwilkerson) Make the TOP_LEVEL_ error codes be errors rather than
@@ -5062,47 +4984,48 @@
       ErrorType.COMPILE_TIME_ERROR,
       'TOP_LEVEL_CYCLE',
       "The type of '{0}' can't be inferred because it depends on itself through the cycle: {1}.",
-      "Try adding an explicit type to one or more of the variables in the cycle in order to break the cycle.");
+      correction:
+          "Try adding an explicit type to one or more of the variables in the cycle in order to break the cycle.");
 
   static const StrongModeCode TOP_LEVEL_FUNCTION_LITERAL_BLOCK =
-      const StrongModeCode(
-          ErrorType.HINT,
-          'TOP_LEVEL_FUNCTION_LITERAL_BLOCK',
+      const StrongModeCode(ErrorType.HINT, 'TOP_LEVEL_FUNCTION_LITERAL_BLOCK',
           "The type of the function literal can't be inferred because the literal has a block as its body.",
-          "Try adding an explicit type to the variable.");
+          correction: "Try adding an explicit type to the variable.");
 
   static const StrongModeCode TOP_LEVEL_FUNCTION_LITERAL_PARAMETER =
       const StrongModeCode(
           ErrorType.HINT,
           'TOP_LEVEL_FUNCTION_LITERAL_PARAMETER',
           "The type of '{0}' can't be inferred because the parameter '{1}' does not have an explicit type.",
-          "Try adding an explicit type to the parameter '{1}', or add an explicit type for '{0}'.");
+          correction:
+              "Try adding an explicit type to the parameter '{1}', or add an explicit type for '{0}'.");
 
   static const StrongModeCode TOP_LEVEL_IDENTIFIER_NO_TYPE = const StrongModeCode(
       ErrorType.HINT,
       'TOP_LEVEL_IDENTIFIER_NO_TYPE',
       "The type of '{0}' can't be inferred because the type of '{1}' couldn't be inferred.",
-      "Try adding an explicit type to either the variable '{0}' or the variable '{1}'.");
+      correction:
+          "Try adding an explicit type to either the variable '{0}' or the variable '{1}'.");
 
   static const StrongModeCode TOP_LEVEL_INSTANCE_GETTER = const StrongModeCode(
       ErrorType.STATIC_WARNING,
       'TOP_LEVEL_INSTANCE_GETTER',
       "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}'.");
+      correction: "Add an explicit type for either '{0}' or '{1}'.");
 
   static const StrongModeCode TOP_LEVEL_INSTANCE_METHOD = const StrongModeCode(
       ErrorType.STATIC_WARNING,
       'TOP_LEVEL_INSTANCE_METHOD',
       "The type of '{0}' can't be inferred because it refers to an instance "
       "method, '{1}', which has an implicit type.",
-      "Add an explicit type for either '{0}' or '{1}'.");
+      correction: "Add an explicit type for either '{0}' or '{1}'.");
 
   static const StrongModeCode TOP_LEVEL_UNSUPPORTED = const StrongModeCode(
       ErrorType.HINT,
       'TOP_LEVEL_UNSUPPORTED',
       "The type of '{0}' can't be inferred because {1} expressions aren't supported.",
-      "Try adding an explicit type for '{0}'.");
+      correction: "Try adding an explicit type for '{0}'.");
 
   /**
    * This warning is generated when a function type is assigned to a function
@@ -5114,8 +5037,8 @@
       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.");
+      correction: "Try changing the parameter types of the function or of the "
+          " receiving location.");
 
   @override
   final ErrorType type;
@@ -5128,9 +5051,9 @@
    * created from the optional [correction] template.
    */
   const StrongModeCode(ErrorType type, String name, String message,
-      [String correction])
+      {String correction})
       : type = type,
-        super('STRONG_MODE_$name', message, correction);
+        super('STRONG_MODE_$name', message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 14b817f..408b911 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -1004,6 +1004,14 @@
         popTypedList(count), leftDelimeter, rightDelimeter));
   }
 
+  @override
+  void beginFormalParameterDefaultValueExpression() {}
+
+  @override
+  void endFormalParameterDefaultValueExpression() {
+    debugEvent("FormalParameterDefaultValueExpression");
+  }
+
   void handleValuedFormalParameter(Token equals, Token token) {
     assert(optional('=', equals) || optional(':', equals));
     debugEvent("ValuedFormalParameter");
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index c517b31..8fe08ec 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -52,6 +52,10 @@
             length,
             [lexeme()]);
         return;
+      case "CATCH_SYNTAX":
+        errorReporter?.reportErrorForOffset(
+            ParserErrorCode.CATCH_SYNTAX, offset, length);
+        return;
       case "CLASS_IN_CLASS":
         errorReporter?.reportErrorForOffset(
             ParserErrorCode.CLASS_IN_CLASS, offset, length);
diff --git a/pkg/analyzer/lib/src/fasta/token_utils.dart b/pkg/analyzer/lib/src/fasta/token_utils.dart
index 47cf5d2..790d04a 100644
--- a/pkg/analyzer/lib/src/fasta/token_utils.dart
+++ b/pkg/analyzer/lib/src/fasta/token_utils.dart
@@ -4,7 +4,7 @@
 
 library fasta.analyzer.token_utils;
 
-import 'package:front_end/src/scanner/token.dart' show Token;
+import 'package:front_end/src/scanner/token.dart' show CommentToken, Token;
 
 import 'package:front_end/src/fasta/scanner/token_constants.dart';
 
@@ -47,3 +47,21 @@
   void reportError(analyzer.ScannerErrorCode errorCode, int offset,
       List<Object> arguments) {}
 }
+
+/// Search for the token before [target] starting the search with [start].
+/// Return `null` if [target] is a comment token
+/// or the previous token cannot be found.
+Token findPrevious(Token start, Token target) {
+  if (start == target || target is CommentToken) {
+    return null;
+  }
+  Token token = start is CommentToken ? start.parent : start;
+  do {
+    Token next = token.next;
+    if (next == target) {
+      return token;
+    }
+    token = next;
+  } while (!token.isEof);
+  return null;
+}
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 7b3f436..30d1a57 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -120,11 +120,14 @@
    */
   TypePromotionManager _promoteManager;
 
+  /// Whether constant evaluation errors should be reported during resolution.
+  final bool reportConstEvaluationErrors;
+
   /**
    * Initialize a newly created visitor to work for the given [_resolver] to
    * resolve the nodes in a compilation unit.
    */
-  ElementResolver(this._resolver) {
+  ElementResolver(this._resolver, {this.reportConstEvaluationErrors: true}) {
     this._definingLibrary = _resolver.definingLibrary;
     AnalysisOptions options = _definingLibrary.context.analysisOptions;
     _enableHints = options.hint;
@@ -578,7 +581,9 @@
     node.staticElement = invokedConstructor;
     ArgumentList argumentList = node.argumentList;
     List<ParameterElement> parameters = _resolveArgumentsToFunction(
-        node.isConst, argumentList, invokedConstructor);
+        reportConstEvaluationErrors && node.isConst,
+        argumentList,
+        invokedConstructor);
     if (parameters != null) {
       argumentList.correspondingStaticParameters = parameters;
     }
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index b8c90da..4382091 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -6211,11 +6211,12 @@
    * See [StaticWarningCode.FUNCTION_WITHOUT_CALL].
    */
   void _checkImplementsFunctionWithoutCall(AstNode className) {
-    ClassElement classElement = _enclosingClass;
-    if (classElement == null) {
+    if (_options.strongMode) {
+      // `implements Function` is ignored in strong mode/Dart 2.
       return;
     }
-    if (classElement.isAbstract) {
+    ClassElement classElement = _enclosingClass;
+    if (classElement == null || classElement.isAbstract) {
       return;
     }
     if (!_typeSystem.isSubtypeOf(
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 8592273..824a7ee 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -4869,8 +4869,9 @@
           'PART_OF_UNNAMED_LIBRARY',
           "Library is unnamed. Expected a URI not a library name '{0}' in the "
           "part-of directive.",
-          "Try changing the part-of directive to a URI, or try including a"
-          " different part.");
+          correction:
+              "Try changing the part-of directive to a URI, or try including a"
+              " different part.");
 
   /**
    * Initialize a newly created error code to have the given [name]. The message
@@ -4878,8 +4879,8 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ResolverErrorCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const ResolverErrorCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => type.severity;
@@ -4983,12 +4984,15 @@
    */
   ResolverVisitor(LibraryElement definingLibrary, Source source,
       TypeProvider typeProvider, AnalysisErrorListener errorListener,
-      {Scope nameScope})
+      {Scope nameScope,
+      bool propagateTypes: true,
+      reportConstEvaluationErrors: true})
       : super(definingLibrary, source, typeProvider, errorListener,
             nameScope: nameScope) {
     AnalysisOptions options = definingLibrary.context.analysisOptions;
     this.strongMode = options.strongMode;
-    this.elementResolver = new ElementResolver(this);
+    this.elementResolver = new ElementResolver(this,
+        reportConstEvaluationErrors: reportConstEvaluationErrors);
     this.typeSystem = definingLibrary.context.typeSystem;
     bool strongModeHints = false;
     if (options is AnalysisOptionsImpl) {
@@ -4996,7 +5000,8 @@
     }
     this.inferenceContext = new InferenceContext._(
         typeProvider, typeSystem, strongModeHints, errorReporter);
-    this.typeAnalyzer = new StaticTypeAnalyzer(this);
+    this.typeAnalyzer =
+        new StaticTypeAnalyzer(this, propagateTypes: propagateTypes);
   }
 
   /**
@@ -5720,7 +5725,8 @@
     }
     // Clone the ASTs for default formal parameters, so that we can use them
     // during constant evaluation.
-    if (!_hasSerializedConstantInitializer(element)) {
+    if (element is ConstVariableElement &&
+        !_hasSerializedConstantInitializer(element)) {
       (element as ConstVariableElement).constantInitializer =
           _createCloner().cloneNode(node.defaultValue);
     }
@@ -6597,15 +6603,12 @@
    * serialized.
    */
   bool _hasSerializedConstantInitializer(ParameterElement parameter) {
-    if (LibraryElementImpl.hasResolutionCapability(
-        definingLibrary, LibraryResolutionCapability.constantExpressions)) {
-      Element executable = parameter.enclosingElement;
-      if (executable is MethodElement) {
-        return true;
-      }
-      if (executable is FunctionElement) {
-        return executable.enclosingElement is CompilationUnitElement;
-      }
+    Element executable = parameter.enclosingElement;
+    if (executable is MethodElement ||
+        executable is FunctionElement &&
+            executable.enclosingElement is CompilationUnitElement) {
+      return LibraryElementImpl.hasResolutionCapability(
+          definingLibrary, LibraryResolutionCapability.constantExpressions);
     }
     return false;
   }
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 34ddfb2..3754221 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -63,7 +63,7 @@
       identical(t, UnknownInferredType.instance);
 }
 
-typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<TypeImpl> visitedTypes);
+typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<DartType> visitedTypes);
 
 /**
  * Implementation of [TypeSystem] using the strong mode rules.
@@ -111,11 +111,9 @@
   FunctionType functionTypeToFuzzyType(FunctionType t) =>
       _replaceDynamicParameters(t, typeProvider.nullType);
 
-  /**
-   * Given a type t, if t is an interface type with a call method
-   * defined, return the function type for the call method, otherwise
-   * return null.
-   */
+  /// Given a type t, if t is an interface type with a call method
+  /// defined, return the function type for the call method, otherwise
+  /// return null.
   FunctionType getCallMethodType(DartType t) {
     if (t is InterfaceType) {
       return t.lookUpInheritedMethod("call")?.type;
@@ -123,6 +121,23 @@
     return null;
   }
 
+  /// Returns true iff the type [t] accepts function types, and requires an
+  /// implicit coercion if interface types with a `call` method are passed in.
+  ///
+  /// This is true for:
+  /// - all function types
+  /// - the special type `Function` that is a supertype of all function types
+  /// - `FutureOr<T>` where T is one of the two cases above.
+  ///
+  /// Note that this returns false if [t] is a top type such as Object.
+  bool acceptsFunctionType(DartType t) {
+    if (t == null) return false;
+    if (t.isDartAsyncFutureOr) {
+      return acceptsFunctionType((t as InterfaceType).typeArguments[0]);
+    }
+    return t is FunctionType || t.isDartCoreFunction;
+  }
+
   /// Computes the greatest lower bound of [type1] and [type2].
   DartType getGreatestLowerBound(DartType type1, DartType type2) {
     // The greatest lower bound relation is reflexive.
@@ -182,7 +197,7 @@
   DartType getLeastNullableSupertype(InterfaceType type) {
     // compute set of supertypes
     List<InterfaceType> s = InterfaceTypeImpl
-        .computeSuperinterfaceSet(type)
+        .computeSuperinterfaceSet(type, strong: true)
         .where(isNullableType)
         .toList();
     return InterfaceTypeImpl.computeTypeAtMaxUniqueDepth(s);
@@ -419,6 +434,13 @@
   @override
   bool isAssignableTo(DartType fromType, DartType toType,
       {bool isDeclarationCast = false}) {
+    if (fromType is InterfaceType) {
+      var callMethodType = getCallMethodType(fromType);
+      if (callMethodType != null && isAssignableTo(callMethodType, toType)) {
+        return true;
+      }
+    }
+
     // An actual subtype
     if (isSubtypeOf(fromType, toType)) {
       return true;
@@ -739,15 +761,11 @@
     return "${type?.element?.library?.identifier},$type";
   }
 
-  /**
-   * Guard against loops in the class hierarchy
-   */
-  _GuardedSubtypeChecker<DartType> _guard(
-      _GuardedSubtypeChecker<DartType> check) {
-    return (DartType t1, DartType t2, Set<TypeImpl> visitedTypes) {
-      if (visitedTypes == null) {
-        visitedTypes = new HashSet<TypeImpl>();
-      }
+  /// Guard against loops in the class hierarchy.
+  _GuardedSubtypeChecker<T> _guard<T extends DartType>(
+      _GuardedSubtypeChecker<T> check) {
+    return (T t1, T t2, Set<DartType> visitedTypes) {
+      visitedTypes ??= new HashSet<DartType>();
       if (t1 == null || !visitedTypes.add(t1)) {
         return false;
       }
@@ -802,7 +820,8 @@
       lub.typeArguments = tArgs;
       return lub;
     }
-    return InterfaceTypeImpl.computeLeastUpperBound(type1, type2) ??
+    return InterfaceTypeImpl.computeLeastUpperBound(type1, type2,
+            strong: isStrong) ??
         typeProvider.dynamicType;
   }
 
@@ -811,22 +830,24 @@
   /// This will always assume function types use fuzzy arrows, in other words
   /// that dynamic parameters of f1 and f2 are treated as bottom.
   bool _isFunctionSubtypeOf(
-      FunctionType f1, FunctionType f2, Set<TypeImpl> visitedTypes) {
+      FunctionType f1, FunctionType f2, Set<DartType> visitedTypes) {
     return FunctionTypeImpl.relate(f1, f2, isSubtypeOf, instantiateToBounds,
         parameterRelation: (p1, p2) =>
             _isSubtypeOf(p2.type, p1.type, visitedTypes));
   }
 
   bool _isInterfaceSubtypeOf(
-      InterfaceType i1, InterfaceType i2, Set<TypeImpl> visitedTypes) {
-    if (identical(i1, i2)) {
+      InterfaceType i1, InterfaceType i2, Set<DartType> visitedTypes) {
+    // Note: we should never reach `_isInterfaceSubtypeOf` with `i2 == Object`,
+    // because top types are eliminated before `isSubtypeOf` calls this.
+    if (identical(i1, i2) || i2.isObject) {
       return true;
     }
 
-    // Guard recursive calls
-    _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype = _guard(
-        (DartType i1, DartType i2, Set<TypeImpl> visitedTypes) =>
-            _isInterfaceSubtypeOf(i1, i2, visitedTypes));
+    // Object cannot subtype anything but itself (handled above).
+    if (i1.isObject) {
+      return false;
+    }
 
     if (i1.element == i2.element) {
       List<DartType> tArgs1 = i1.typeArguments;
@@ -844,15 +865,15 @@
       return true;
     }
 
-    if (i2.isDartCoreFunction &&
-        i1.element.getMethod("call")?.isStatic == false) {
-      return true;
-    }
-
-    if (i1.isObject) {
+    // Classes types cannot subtype `Function` or vice versa.
+    if (i1.isDartCoreFunction || i2.isDartCoreFunction) {
       return false;
     }
 
+    // Guard recursive calls
+    _GuardedSubtypeChecker<InterfaceType> guardedInterfaceSubtype =
+        _guard(_isInterfaceSubtypeOf);
+
     if (guardedInterfaceSubtype(i1.superclass, i2, visitedTypes)) {
       return true;
     }
@@ -872,7 +893,7 @@
     return false;
   }
 
-  bool _isSubtypeOf(DartType t1, DartType t2, Set<TypeImpl> visitedTypes) {
+  bool _isSubtypeOf(DartType t1, DartType t2, Set<DartType> visitedTypes) {
     if (identical(t1, t2)) {
       return true;
     }
@@ -947,19 +968,10 @@
     }
 
     // Guard recursive calls
-    _GuardedSubtypeChecker<FunctionType> guardedIsFunctionSubtype = _guard(
-        (DartType t1, DartType t2, Set<TypeImpl> visitedTypes) =>
-            _isFunctionSubtypeOf(
-                t1 as FunctionType, t2 as FunctionType, visitedTypes));
+    _GuardedSubtypeChecker<FunctionType> guardedIsFunctionSubtype =
+        _guard(_isFunctionSubtypeOf);
 
-    // An interface type can only subtype a function type if
-    // the interface type declares a call method with a type
-    // which is a super type of the function type.
-    if (t1 is InterfaceType && t2 is FunctionType) {
-      var callType = getCallMethodType(t1);
-      return callType != null &&
-          guardedIsFunctionSubtype(callType, t2, visitedTypes);
-    }
+    if (t1 is InterfaceType && t2 is FunctionType) return false;
 
     // Two interface types
     if (t1 is InterfaceType && t2 is InterfaceType) {
@@ -1194,12 +1206,21 @@
       return _typeParameterLeastUpperBound(type1, type2);
     }
 
-    // The least upper bound of a function type and an interface type T is the
-    // least upper bound of Function and T.
+    // In Dart 1, the least upper bound of a function type and an interface type
+    // T is the least upper bound of Function and T.
+    //
+    // In Dart 2, the result is `Function` iff T is `Function`, otherwise the
+    // result is `Object`.
     if (type1 is FunctionType && type2 is InterfaceType) {
+      if (isStrong) {
+        return type2.isDartCoreFunction ? type2 : typeProvider.objectType;
+      }
       type1 = typeProvider.functionType;
     }
     if (type2 is FunctionType && type1 is InterfaceType) {
+      if (isStrong) {
+        return type1.isDartCoreFunction ? type1 : typeProvider.objectType;
+      }
       type2 = typeProvider.functionType;
     }
 
@@ -2080,10 +2101,6 @@
       }
       return;
     }
-    if (i2.isDartCoreFunction &&
-        i1.element.getMethod("call")?.isStatic == false) {
-      return;
-    }
     if (i1.isObject) {
       return;
     }
@@ -2218,14 +2235,6 @@
       return;
     }
 
-    // An interface type can only subtype a function type if
-    // the interface type declares a call method with a type
-    // which is a super type of the function type.
-    if (t1 is InterfaceType) {
-      t1 = _typeSystem.getCallMethodType(t1);
-      if (t1 == null) return;
-    }
-
     if (t1 is FunctionType && t2 is FunctionType) {
       FunctionTypeImpl.relate(
           t1,
diff --git a/pkg/analyzer/lib/src/html/error/html_codes.dart b/pkg/analyzer/lib/src/html/error/html_codes.dart
index 1af2fcf..9644fb1 100644
--- a/pkg/analyzer/lib/src/html/error/html_codes.dart
+++ b/pkg/analyzer/lib/src/html/error/html_codes.dart
@@ -28,8 +28,8 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const HtmlErrorCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const HtmlErrorCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
@@ -71,8 +71,8 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const HtmlWarningCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const HtmlWarningCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
index 6629300..133d6dd 100644
--- a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
@@ -19,9 +19,8 @@
    */
   static const PubspecWarningCode ASSET_DOES_NOT_EXIST =
       const PubspecWarningCode(
-          'ASSET_DOES_NOT_EXIST',
-          "The asset {0} does not exist.",
-          "Try creating the file or fixing the path to the file.");
+          'ASSET_DOES_NOT_EXIST', "The asset {0} does not exist.",
+          correction: "Try creating the file or fixing the path to the file.");
 
   /**
    * A code indicating that the value of the asset field is not a list.
@@ -29,41 +28,38 @@
   static const PubspecWarningCode ASSET_FIELD_NOT_LIST = const PubspecWarningCode(
       'ASSET_FIELD_NOT_LIST',
       "The value of the 'asset' field is expected to be a list of relative file paths.",
-      "Try converting the value to be a list of relative file paths.");
+      correction:
+          "Try converting the value to be a list of relative file paths.");
 
   /**
    * A code indicating that an element in the asset list is not a string.
    */
   static const PubspecWarningCode ASSET_NOT_STRING = const PubspecWarningCode(
-      'ASSET_NOT_STRING',
-      "Assets are expected to be a file paths (strings).",
-      "Try converting the value to be a string.");
+      'ASSET_NOT_STRING', "Assets are expected to be a file paths (strings).",
+      correction: "Try converting the value to be a string.");
 
   /**
    * A code indicating that the value of a dependencies field is not a map.
    */
   static const PubspecWarningCode DEPENDENCIES_FIELD_NOT_MAP =
-      const PubspecWarningCode(
-          'DEPENDENCIES_FIELD_NOT_MAP',
+      const PubspecWarningCode('DEPENDENCIES_FIELD_NOT_MAP',
           "The value of the '{0}' field is expected to be a map.",
-          "Try converting the value to be a map.");
+          correction: "Try converting the value to be a map.");
 
   /**
    * A code indicating that the value of the flutter field is not a map.
    */
   static const PubspecWarningCode FLUTTER_FIELD_NOT_MAP =
-      const PubspecWarningCode(
-          'FLUTTER_FIELD_NOT_MAP',
+      const PubspecWarningCode('FLUTTER_FIELD_NOT_MAP',
           "The value of the 'flutter' field is expected to be a map.",
-          "Try converting the value to be a map.");
+          correction: "Try converting the value to be a map.");
 
   /**
    * A code indicating that the name field is missing.
    */
   static const PubspecWarningCode MISSING_NAME = const PubspecWarningCode(
-      'MISSING_NAME',
-      "The name field is required but missing.",
-      "Try adding a field named 'name'.");
+      'MISSING_NAME', "The name field is required but missing.",
+      correction: "Try adding a field named 'name'.");
 
   /**
    * A code indicating that the name field is not a string.
@@ -71,7 +67,7 @@
   static const PubspecWarningCode NAME_NOT_STRING = const PubspecWarningCode(
       'NAME_NOT_STRING',
       "The value of the name field is expected to be a string.",
-      "Try converting the value to be a string.");
+      correction: "Try converting the value to be a string.");
 
   /**
    * A code indicating that a package listed as a dev dependency is also listed
@@ -85,14 +81,14 @@
           'UNNECESSARY_DEV_DEPENDENCY',
           "The dev dependency on {0} is unnecessary because there is also a "
           "normal dependency on that package.",
-          "Try removing the dev dependency.");
+          correction: "Try removing the dev dependency.");
 
   /**
    * Initialize a newly created warning code to have the given [name], [message]
    * and [correction].
    */
-  const PubspecWarningCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const PubspecWarningCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
diff --git a/pkg/analyzer/lib/src/summary/expr_builder.dart b/pkg/analyzer/lib/src/summary/expr_builder.dart
index 09bd56b..1a57d3c 100644
--- a/pkg/analyzer/lib/src/summary/expr_builder.dart
+++ b/pkg/analyzer/lib/src/summary/expr_builder.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
@@ -33,21 +34,14 @@
 
   final List<UnlinkedExecutable> localFunctions;
 
-  ExprBuilder(this.resynthesizer, this.context, this.uc,
-      {this.requireValidConst: true, this.localFunctions});
+  final Map<String, ParameterElement> parametersInScope;
 
-  /**
-   * Return the [ConstructorElement] enclosing [context].
-   */
-  ConstructorElement get _enclosingConstructor {
-    for (Element e = context; e != null; e = e.enclosingElement) {
-      if (e is ConstructorElement) {
-        return e;
-      }
-    }
-    throw new StateError(
-        'Unable to find the enclosing constructor of $context');
-  }
+  ExprBuilder(this.resynthesizer, this.context, this.uc,
+      {this.requireValidConst: true,
+      this.localFunctions,
+      Map<String, ParameterElement> parametersInScope})
+      : this.parametersInScope =
+            parametersInScope ?? _parametersInScope(context);
 
   Expression build() {
     if (requireValidConst && !uc.isValidConst) {
@@ -220,17 +214,13 @@
           case UnlinkedExprOperation.pushParameter:
             String name = uc.strings[stringPtr++];
             SimpleIdentifier identifier = AstTestFactory.identifier3(name);
-            identifier.staticElement = _enclosingConstructor.parameters
-                .firstWhere((parameter) => parameter.name == name,
-                    orElse: () => throw new StateError(
-                        'Unable to resolve constructor parameter: $name'));
+            identifier.staticElement = parametersInScope[name];
             _push(identifier);
             break;
           case UnlinkedExprOperation.ifNull:
             _pushBinary(TokenType.QUESTION_QUESTION);
             break;
           case UnlinkedExprOperation.await:
-            // TODO(scheglov) No test, requires closures.
             Expression expression = _pop();
             _push(AstTestFactory.awaitExpression(expression));
             break;
@@ -333,7 +323,7 @@
         ..staticElement = element;
       return AstTestFactory.identifier(enclosing, identifier);
     }
-    if (element == null) {
+    if (requireValidConst && element == null) {
       throw const _InvalidConstantException();
     }
     SimpleIdentifier property = AstTestFactory.identifier3(info.name)
@@ -341,6 +331,19 @@
     return AstTestFactory.propertyAccess(enclosing, property);
   }
 
+  TypeArgumentList _buildTypeArguments() {
+    int numTypeArguments = uc.ints[intPtr++];
+    if (numTypeArguments == 0) {
+      return null;
+    }
+
+    var typeNames = new List<TypeAnnotation>(numTypeArguments);
+    for (int i = 0; i < numTypeArguments; i++) {
+      typeNames[i] = _newTypeName();
+    }
+    return AstTestFactory.typeArgumentList(typeNames);
+  }
+
   TypeAnnotation _buildTypeAst(DartType type) {
     List<TypeAnnotation> argumentNodes;
     if (type is ParameterizedType) {
@@ -405,6 +408,8 @@
         return postfix(TokenType.PLUS_PLUS);
       case UnlinkedExprAssignOperator.postfixDecrement:
         return postfix(TokenType.MINUS_MINUS);
+      default:
+        throw new UnimplementedError('Unexpected UnlinkedExprAssignOperator');
     }
   }
 
@@ -421,11 +426,15 @@
   PropertyAccessorElement _getStringLengthElement() =>
       resynthesizer.typeProvider.stringType.getGetter('length');
 
-  FormalParameter _makeParameter(UnlinkedParam param) {
-    var simpleParam = AstTestFactory.simpleFormalParameter(null, param.name);
-    if (param.kind == UnlinkedParamKind.positional) {
+  FormalParameter _makeParameter(ParameterElementImpl param) {
+    SimpleFormalParameterImpl simpleParam =
+        AstTestFactory.simpleFormalParameter(null, param.name);
+    simpleParam.identifier.staticElement = param;
+    simpleParam.element = param;
+    var unlinkedParam = param.unlinkedParam;
+    if (unlinkedParam.kind == UnlinkedParamKind.positional) {
       return AstTestFactory.positionalFormalParameter(simpleParam, null);
-    } else if (param.kind == UnlinkedParamKind.named) {
+    } else if (unlinkedParam.kind == UnlinkedParamKind.named) {
       return AstTestFactory.namedFormalParameter(simpleParam, null);
     } else {
       return simpleParam;
@@ -560,31 +569,22 @@
     ReferenceInfo info = resynthesizer.getReferenceInfo(ref.reference);
     Expression node = _buildIdentifierSequence(info);
     TypeArgumentList typeArguments = _buildTypeArguments();
+    var period = TokenFactory.tokenFromType(TokenType.PERIOD);
+    var argumentList = AstTestFactory.argumentList(arguments);
     if (node is SimpleIdentifier) {
       _push(astFactory.methodInvocation(
-          null,
-          TokenFactory.tokenFromType(TokenType.PERIOD),
-          node,
-          typeArguments,
-          AstTestFactory.argumentList(arguments)));
+          null, period, node, typeArguments, argumentList));
+    } else if (node is PropertyAccess) {
+      _push(astFactory.methodInvocation(
+          node.target, period, node.propertyName, typeArguments, argumentList));
+    } else if (node is PrefixedIdentifier) {
+      _push(astFactory.methodInvocation(
+          node.prefix, period, node.identifier, typeArguments, argumentList));
     } else {
       throw new UnimplementedError('For ${node?.runtimeType}: $node');
     }
   }
 
-  TypeArgumentList _buildTypeArguments() {
-    int numTypeArguments = uc.ints[intPtr++];
-    if (numTypeArguments == 0) {
-      return null;
-    }
-
-    var typeNames = new List<TypeAnnotation>(numTypeArguments);
-    for (int i = 0; i < numTypeArguments; i++) {
-      typeNames[i] = _newTypeName();
-    }
-    return AstTestFactory.typeArgumentList(typeNames);
-  }
-
   void _pushList(TypeArgumentList typeArguments) {
     int count = uc.ints[intPtr++];
     List<Expression> elements = <Expression>[];
@@ -601,18 +601,45 @@
     assert(popCount == 0);
     int functionIndex = uc.ints[intPtr++];
     var localFunction = localFunctions[functionIndex];
-    // TODO(paulberry): need to create a sub-element for the local function;
-    // don't just pass along context.
-    var bodyExpr = new ExprBuilder(
-            resynthesizer, context, localFunction.bodyExpr,
-            requireValidConst: requireValidConst)
-        .build();
-    var parameters = localFunction.parameters.map(_makeParameter).toList();
-    _push(astFactory.functionExpression(
-        null,
-        AstTestFactory.formalParameterList(parameters),
-        astFactory.expressionFunctionBody(null,
-            TokenFactory.tokenFromType(TokenType.FUNCTION), bodyExpr, null)));
+    var parametersInScope =
+        new Map<String, ParameterElement>.from(this.parametersInScope);
+    var functionElement =
+        new FunctionElementImpl.forSerialized(localFunction, context);
+    for (ParameterElementImpl parameter in functionElement.parameters) {
+      parametersInScope[parameter.name] = parameter;
+      if (parameter.unlinkedParam.type == null) {
+        // Store a type of `dynamic` for the parameter; this prevents
+        // resynthesis from trying to read a type out of the summary (which
+        // wouldn't work anyway, since nested functions don't have their
+        // parameter types stored in the summary anyhow).
+        parameter.type = resynthesizer.typeProvider.dynamicType;
+      }
+    }
+    var parameters = functionElement.parameters.map(_makeParameter).toList();
+    var asyncKeyword = localFunction.isAsynchronous
+        ? TokenFactory.tokenFromKeyword(Keyword.ASYNC)
+        : null;
+    FunctionBody functionBody;
+    if (localFunction.bodyExpr == null) {
+      // Most likely the original source code contained a block function body
+      // here.  Block function bodies aren't supported by the summary mechanism.
+      // But they are tolerated when their presence doesn't affect inferred
+      // types.
+      functionBody = AstTestFactory.blockFunctionBody(AstTestFactory.block());
+    } else {
+      var bodyExpr = new ExprBuilder(
+              resynthesizer, functionElement, localFunction.bodyExpr,
+              requireValidConst: requireValidConst,
+              parametersInScope: parametersInScope,
+              localFunctions: localFunction.localFunctions)
+          .build();
+      functionBody = astFactory.expressionFunctionBody(asyncKeyword,
+          TokenFactory.tokenFromType(TokenType.FUNCTION), bodyExpr, null);
+    }
+    var functionExpression = astFactory.functionExpression(
+        null, AstTestFactory.formalParameterList(parameters), functionBody);
+    functionExpression.element = functionElement;
+    _push(functionExpression);
   }
 
   void _pushMap(TypeArgumentList typeArguments) {
@@ -648,6 +675,23 @@
       throw const _InvalidConstantException();
     }
   }
+
+  /// Figures out the default value of [parametersInScope] based on [context].
+  ///
+  /// If [context] is (or contains) a constructor, then its parameters are used.
+  /// Otherwise, no parameters are considered to be in scope.
+  static Map<String, ParameterElement> _parametersInScope(Element context) {
+    var result = <String, ParameterElement>{};
+    for (Element e = context; e != null; e = e.enclosingElement) {
+      if (e is ConstructorElement) {
+        for (var parameter in e.parameters) {
+          result[parameter.name] = parameter;
+        }
+        return result;
+      }
+    }
+    return result;
+  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 928a170..dd3ff8a 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -58,23 +58,29 @@
  *   checks.  E.g. see [ReferenceableElementForLink.asConstructor].
  */
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/token.dart' show TokenType;
+import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/constant/value.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/generated/static_type_analyzer.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/expr_builder.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
 import 'package:analyzer/src/summary/prelink.dart';
+import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/task/strong_mode.dart';
 import 'package:front_end/src/dependency_walker.dart';
 
+final _typesWithImplicitArguments = new Expando();
+
 bool isIncrementOrDecrement(UnlinkedExprAssignOperator operator) {
   switch (operator) {
     case UnlinkedExprAssignOperator.prefixDecrement:
@@ -185,7 +191,8 @@
     return result;
   } else if (type is TypeParameterType) {
     TypeParameterElementImpl element = type.element;
-    if (typeParameterContext.isTypeParameterInScope(element)) {
+    if (typeParameterContext != null &&
+        typeParameterContext.isTypeParameterInScope(element)) {
       result.paramReference =
           typeParameterContext.typeParameterNestingLevel - element.nestingLevel;
     } else {
@@ -229,7 +236,7 @@
       // TODO(paulberry): do I need to store type arguments?
       return result;
     }
-    if (element is GenericFunctionTypeElementForLink) {
+    if (element is GenericFunctionTypeElementImpl) {
       // Function types are their own type parameter context
       typeParameterContext = element;
       result.entityKind = EntityRefKind.genericFunctionType;
@@ -389,6 +396,12 @@
   AnalysisOptionsForLink(this._linker);
 
   @override
+  bool get hint => false;
+
+  @override
+  bool get previewDart2 => true;
+
+  @override
   bool get strongMode => _linker.strongMode;
 
   @override
@@ -410,6 +423,8 @@
   /// TODO(brianwilkerson) This appears to be unused and might be removable.
   bool hasBeenInferred;
 
+  DartType _typeWithDefaultBounds;
+
   ClassElementForLink(CompilationUnitElementForLink enclosingElement)
       : enclosingElement = enclosingElement,
         hasBeenInferred = !enclosingElement.isInBuildUnit;
@@ -450,6 +465,9 @@
   @override
   String get name;
 
+  DartType get typeWithDefaultBounds => _typeWithDefaultBounds ??=
+      enclosingElement.library._linker.typeSystem.instantiateToBounds(type);
+
   @override
   ConstructorElementForLink get unnamedConstructor;
 
@@ -782,6 +800,10 @@
       ClassElementImpl.getNamedConstructorFromList(name, constructors);
 
   @override
+  PropertyAccessorElement getSetter(String setterName) =>
+      AbstractClassElementImpl.getSetterFromAccessors(setterName, accessors);
+
+  @override
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     // Force mixins to be inferred by calling this.mixins.  We don't need the
     // return value from the getter; we just need it to execute and record the
@@ -940,6 +962,9 @@
       type;
 
   @override
+  ConstructorElement getNamedConstructor(String name) => null;
+
+  @override
   void link(CompilationUnitElementInBuildUnit compilationUnit) {}
 
   @override
@@ -952,6 +977,8 @@
  */
 abstract class CompilationUnitElementForLink
     implements CompilationUnitElementImpl, ResynthesizerContext {
+  final _UnitResynthesizer _unitResynthesizer;
+
   /**
    * The unlinked representation of the compilation unit in the
    * summary.
@@ -962,7 +989,7 @@
    * For each entry in [UnlinkedUnit.references], the element referred
    * to by the reference, or `null` if it hasn't been located yet.
    */
-  final List<ReferenceableElementForLink> _references;
+  final List<_ReferenceInfo> _references;
 
   /**
    * The absolute URI of this compilation unit.
@@ -982,10 +1009,17 @@
    */
   final int unitNum;
 
+  @override
+  final Source source;
+
   CompilationUnitElementForLink(UnlinkedUnit unlinkedUnit, this.unitNum,
       int numReferences, this._absoluteUri)
-      : _references = new List<ReferenceableElementForLink>(numReferences),
-        _unlinkedUnit = unlinkedUnit;
+      : _references = new List<_ReferenceInfo>(numReferences),
+        _unlinkedUnit = unlinkedUnit,
+        source = new InSummarySource(Uri.parse(_absoluteUri), null),
+        _unitResynthesizer = new _UnitResynthesizer() {
+    _unitResynthesizer._unit = this;
+  }
 
   @override
   List<PropertyAccessorElementForLink> get accessors {
@@ -1159,6 +1193,10 @@
   DartType getLinkedType(ElementImpl context, int slot);
 
   @override
+  ClassElement getType(String className) =>
+      CompilationUnitElementImpl.getTypeFromTypes(className, types);
+
+  @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
   /**
@@ -1183,7 +1221,10 @@
    * [UnlinkedUnit.references].  If the reference is unresolved,
    * return [UndefinedElementForLink.instance].
    */
-  ReferenceableElementForLink resolveRef(int index) {
+  ReferenceableElementForLink resolveRef(int index) =>
+      resolveRefToInfo(index).element;
+
+  _ReferenceInfo resolveRefToInfo(int index) {
     if (_references[index] == null) {
       UnlinkedReference unlinkedReference =
           index < _unlinkedUnit.references.length
@@ -1196,28 +1237,33 @@
       int containingReference = unlinkedReference == null
           ? linkedReference.containingReference
           : unlinkedReference.prefixReference;
+      _ReferenceInfo enclosingInfo = containingReference != 0
+          ? resolveRefToInfo(containingReference)
+          : null;
+      ReferenceableElementForLink element;
       if (containingReference != 0 &&
           _linkedUnit.references[containingReference].kind !=
               ReferenceKind.prefix) {
-        _references[index] =
-            resolveRef(containingReference).getContainedName(name);
+        element = enclosingInfo.element.getContainedName(name);
       } else if (linkedReference.dependency == 0) {
         if (linkedReference.kind == ReferenceKind.unresolved) {
-          _references[index] = UndefinedElementForLink.instance;
+          element = UndefinedElementForLink.instance;
         } else if (name == 'void') {
-          _references[index] = enclosingElement._linker.voidElement;
+          element = enclosingElement._linker.voidElement;
         } else if (name == '*bottom*') {
-          _references[index] = enclosingElement._linker.bottomElement;
+          element = enclosingElement._linker.bottomElement;
         } else if (name == 'dynamic') {
-          _references[index] = enclosingElement._linker.dynamicElement;
+          element = enclosingElement._linker.dynamicElement;
         } else {
-          _references[index] = enclosingElement.getContainedName(name);
+          element = enclosingElement.getContainedName(name);
         }
       } else {
         LibraryElementForLink dependency =
-            enclosingElement._getDependency(linkedReference.dependency);
-        _references[index] = dependency.getContainedName(name);
+            enclosingElement.buildImportedLibrary(linkedReference.dependency);
+        element = dependency.getContainedName(name);
       }
+      _references[index] = new _ReferenceInfo(
+          enclosingInfo, element, name, linkedReference.numTypeParameters != 0);
     }
     return _references[index];
   }
@@ -1251,20 +1297,28 @@
       return type;
     } else {
       ReferenceableElementForLink element = resolveRef(entity.reference);
+      bool implicitTypeArgumentsInUse = false;
 
       DartType getTypeArgument(int i) {
         if (i < entity.typeArguments.length) {
           return resolveTypeRef(context, entity.typeArguments[i]);
-        } else if (!instantiateToBoundsAllowed) {
-          // Do not allow buildType to instantiate the bounds; force dynamic.
-          return DynamicTypeImpl.instance;
         } else {
-          return null;
+          implicitTypeArgumentsInUse = true;
+          if (!instantiateToBoundsAllowed) {
+            // Do not allow buildType to instantiate the bounds; force dynamic.
+            return DynamicTypeImpl.instance;
+          } else {
+            return null;
+          }
         }
       }
 
-      return element.buildType(
+      var type = element.buildType(
           getTypeArgument, entity.implicitFunctionTypeIndices);
+      if (implicitTypeArgumentsInUse) {
+        _typesWithImplicitArguments[type] = true;
+      }
+      return type;
     }
   }
 
@@ -1367,7 +1421,7 @@
     } else if (element is ExecutableElementForLink_NonLocal) {
       ClassElementForLink_Class enclosingClass = element.enclosingClass;
       ReferenceKind kind;
-      switch (element._unlinkedExecutable.kind) {
+      switch (element.serializedExecutable.kind) {
         case UnlinkedExecutableKind.functionOrMethod:
           kind = enclosingClass != null
               ? ReferenceKind.method
@@ -1378,7 +1432,7 @@
           break;
         default:
           // TODO(paulberry): implement other cases as necessary
-          throw new UnimplementedError('${element._unlinkedExecutable.kind}');
+          throw new UnimplementedError('${element.serializedExecutable.kind}');
       }
       if (enclosingClass == null) {
         return addRawReference(element.name,
@@ -1587,7 +1641,7 @@
     }
 
     UnlinkedExecutable unlinkedExecutable =
-        constructorElement._unlinkedExecutable;
+        constructorElement.serializedExecutable;
     ClassElementForLink_Class enclosingClass =
         constructorElement.enclosingElement;
     ConstructorElementForLink redirectedConstructor =
@@ -1608,7 +1662,7 @@
       ClassElementForLink superClass = enclosingClass.supertype?.element;
       bool defaultSuperInvocationNeeded = true;
       for (UnlinkedConstructorInitializer constructorInitializer
-          in constructorElement._unlinkedExecutable.constantInitializers) {
+          in constructorElement.serializedExecutable.constantInitializers) {
         if (constructorInitializer.kind ==
             UnlinkedConstructorInitializerKind.superInvocation) {
           defaultSuperInvocationNeeded = false;
@@ -1666,7 +1720,7 @@
    */
   ConstructorElementForLink _getFactoryRedirectedConstructor() {
     EntityRef redirectedConstructor =
-        constructorElement._unlinkedExecutable.redirectedConstructor;
+        constructorElement.serializedExecutable.redirectedConstructor;
     if (redirectedConstructor != null) {
       return constructorElement.compilationUnit
           .resolveRef(redirectedConstructor.reference)
@@ -1816,7 +1870,7 @@
     List<ConstNode> dependencies = <ConstNode>[];
     collectDependencies(
         dependencies,
-        parameterElement._unlinkedParam.initializer?.bodyExpr,
+        parameterElement.unlinkedParam.initializer?.bodyExpr,
         parameterElement.compilationUnit);
     return dependencies;
   }
@@ -1841,8 +1895,8 @@
       : super(enclosingClass.enclosingElement, enclosingClass,
             unlinkedExecutable) {
     if (enclosingClass.enclosingElement.isInBuildUnit &&
-        _unlinkedExecutable != null &&
-        _unlinkedExecutable.constCycleSlot != 0) {
+        serializedExecutable != null &&
+        serializedExecutable.constCycleSlot != 0) {
       _constNode = new ConstConstructorNode(this);
     }
   }
@@ -1857,6 +1911,9 @@
   String get identifier => name;
 
   @override
+  bool get isConst => serializedExecutable.isConst;
+
+  @override
   bool get isCycleFree {
     if (!_constNode.isEvaluated) {
       new ConstDependencyWalker().walk(_constNode);
@@ -1875,7 +1932,7 @@
    */
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     if (_constNode != null && !isCycleFree) {
-      compilationUnit._storeConstCycle(_unlinkedExecutable.constCycleSlot);
+      compilationUnit._storeConstCycle(serializedExecutable.constCycleSlot);
     }
     // TODO(paulberry): call super.
   }
@@ -1952,7 +2009,7 @@
   /**
    * The unlinked representation of the method in the summary.
    */
-  final UnlinkedExecutable _unlinkedExecutable;
+  final UnlinkedExecutable serializedExecutable;
 
   DartType _declaredReturnType;
   DartType _inferredReturnType;
@@ -1962,7 +2019,7 @@
 
   final CompilationUnitElementForLink compilationUnit;
 
-  ExecutableElementForLink(this.compilationUnit, this._unlinkedExecutable);
+  ExecutableElementForLink(this.compilationUnit, this.serializedExecutable);
 
   @override
   ContextForLink get context => compilationUnit.context;
@@ -1972,19 +2029,19 @@
    * it.  Otherwise return `null`.
    */
   DartType get declaredReturnType {
-    if (_unlinkedExecutable.returnType == null) {
+    if (serializedExecutable.returnType == null) {
       return null;
     } else {
       return _declaredReturnType ??=
-          compilationUnit.resolveTypeRef(this, _unlinkedExecutable.returnType);
+          compilationUnit.resolveTypeRef(this, serializedExecutable.returnType);
     }
   }
 
   @override
   String get displayName {
     if (_displayName == null) {
-      _displayName = _unlinkedExecutable.name;
-      if (_unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
+      _displayName = serializedExecutable.name;
+      if (serializedExecutable.kind == UnlinkedExecutableKind.setter) {
         _displayName = _displayName.substring(0, _displayName.length - 1);
       }
     }
@@ -2003,7 +2060,7 @@
   }
 
   @override
-  bool get hasImplicitReturnType => _unlinkedExecutable.returnType == null;
+  bool get hasImplicitReturnType => serializedExecutable.returnType == null;
 
   @override
   List<int> get implicitFunctionTypeIndices => const <int>[];
@@ -2015,7 +2072,7 @@
   DartType get inferredReturnType {
     // We should only try to infer a return type when none is explicitly
     // declared.
-    assert(_unlinkedExecutable.returnType == null);
+    assert(serializedExecutable.returnType == null);
     if (Linker._initializerTypeInferenceCycle != null &&
         Linker._initializerTypeInferenceCycle ==
             compilationUnit.library.libraryCycleForLink) {
@@ -2024,21 +2081,24 @@
       return _computeDefaultReturnType();
     }
     if (_inferredReturnType == null) {
-      if (_unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) {
+      if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) {
         // TODO(paulberry): implement.
         throw new UnimplementedError();
       } else if (compilationUnit.isInBuildUnit) {
         _inferredReturnType = _computeDefaultReturnType();
       } else {
         _inferredReturnType = compilationUnit.getLinkedType(
-            this, _unlinkedExecutable.inferredReturnTypeSlot);
+            this, serializedExecutable.inferredReturnTypeSlot);
       }
     }
     return _inferredReturnType;
   }
 
   @override
-  bool get isStatic => _unlinkedExecutable.isStatic;
+  bool get isGenerator => serializedExecutable.isGenerator;
+
+  @override
+  bool get isStatic => serializedExecutable.isStatic;
 
   @override
   bool get isSynthetic => false;
@@ -2049,8 +2109,8 @@
   @override
   String get name {
     if (_name == null) {
-      _name = _unlinkedExecutable.name;
-      if (_name == '-' && _unlinkedExecutable.parameters.isEmpty) {
+      _name = serializedExecutable.name;
+      if (_name == '-' && serializedExecutable.parameters.isEmpty) {
         _name = 'unary-';
       }
     }
@@ -2062,7 +2122,6 @@
 
   @override
   void set returnType(DartType inferredType) {
-    assert(_inferredReturnType == null);
     _inferredReturnType = inferredType;
   }
 
@@ -2073,11 +2132,11 @@
   TypeParameterizedElementMixin get typeParameterContext => this;
 
   @override
-  List<UnlinkedParam> get unlinkedParameters => _unlinkedExecutable.parameters;
+  List<UnlinkedParam> get unlinkedParameters => serializedExecutable.parameters;
 
   @override
   List<UnlinkedTypeParam> get unlinkedTypeParams =>
-      _unlinkedExecutable.typeParameters;
+      serializedExecutable.typeParameters;
 
   @override
   bool isAccessibleIn(LibraryElement library) =>
@@ -2089,10 +2148,10 @@
    * better return type).
    */
   DartType _computeDefaultReturnType() {
-    var kind = _unlinkedExecutable.kind;
+    var kind = serializedExecutable.kind;
     var isMethod = kind == UnlinkedExecutableKind.functionOrMethod;
     var isSetter = kind == UnlinkedExecutableKind.setter;
-    if ((isSetter || isMethod && _unlinkedExecutable.name == '[]=') &&
+    if ((isSetter || isMethod && serializedExecutable.name == '[]=') &&
         (library as LibraryElementForLink)._linker.strongMode) {
       // In strong mode, setters and `[]=` operators without an explicit
       // return type are considered to return `void`.
@@ -2132,9 +2191,11 @@
    * Store the results of type inference for this method in [compilationUnit].
    */
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    if (_unlinkedExecutable.returnType == null) {
+    if (serializedExecutable.returnType == null) {
       compilationUnit._storeLinkedType(
-          _unlinkedExecutable.inferredReturnTypeSlot, inferredReturnType, this);
+          serializedExecutable.inferredReturnTypeSlot,
+          inferredReturnType,
+          this);
     }
     for (ParameterElementForLink parameterElement in parameters) {
       parameterElement.link(compilationUnit);
@@ -2143,759 +2204,71 @@
 }
 
 class ExprTypeComputer {
-  final FunctionElementForLink_Local function;
-  final CompilationUnitElementForLink unit;
-  final LibraryElementForLink library;
-  final Linker linker;
-  final TypeProvider typeProvider;
-  final UnlinkedExpr unlinkedConst;
+  final ExprBuilder _builder;
 
-  final List<DartType> stack = <DartType>[];
-  int intPtr = 0;
-  int refPtr = 0;
-  int strPtr = 0;
-  int assignmentOperatorPtr = 0;
+  final AstRewriteVisitor _astRewriteVisitor;
 
-  TopLevelInferenceErrorKind errorKind;
+  final ResolverVisitor _resolverVisitor;
 
   factory ExprTypeComputer(FunctionElementForLink_Local functionElement) {
     CompilationUnitElementForLink unit = functionElement.compilationUnit;
     LibraryElementForLink library = unit.enclosingElement;
     Linker linker = library._linker;
     TypeProvider typeProvider = linker.typeProvider;
-    UnlinkedExpr unlinkedConst = functionElement._unlinkedExecutable.bodyExpr;
+    var unlinkedExecutable = functionElement.serializedExecutable;
+    UnlinkedExpr unlinkedConst = unlinkedExecutable.bodyExpr;
+    var errorListener = AnalysisErrorListener.NULL_LISTENER;
+    var astRewriteVisitor = new AstRewriteVisitor(
+        library, unit.source, typeProvider, errorListener);
+    // TODO(paulberry): Do we need to pass a nameScope to
+    // resolverVisitor to get type variables to resolve properly?
+    var resolverVisitor = new ResolverVisitor(
+        library, unit.source, typeProvider, errorListener,
+        propagateTypes: false, reportConstEvaluationErrors: false);
     return new ExprTypeComputer._(
-        functionElement, unit, library, linker, typeProvider, unlinkedConst);
+        unit._unitResynthesizer,
+        astRewriteVisitor,
+        resolverVisitor,
+        errorListener,
+        functionElement,
+        unlinkedConst,
+        unlinkedExecutable.localFunctions);
   }
 
-  ExprTypeComputer._(this.function, this.unit, this.library, this.linker,
-      this.typeProvider, this.unlinkedConst);
+  ExprTypeComputer._(
+      UnitResynthesizer unitResynthesizer,
+      this._astRewriteVisitor,
+      this._resolverVisitor,
+      AnalysisErrorListener _errorListener,
+      ElementImpl context,
+      UnlinkedExpr unlinkedConst,
+      List<UnlinkedExecutable> localFunctions)
+      : _builder = new ExprBuilder(unitResynthesizer, context, unlinkedConst,
+            requireValidConst: false, localFunctions: localFunctions);
+
+  TopLevelInferenceErrorKind get errorKind {
+    // TODO(paulberry): should we return TopLevelInferenceErrorKind.assignment
+    // sometimes?
+    return null;
+  }
 
   DartType compute() {
-    if (unlinkedConst == null) {
+    if (_builder.uc == null) {
       // No function body was stored for this function, so we can't infer its
       // return type.  Assume `dynamic`.
       return DynamicTypeImpl.instance;
     }
     // If no operations, we cannot compute the type.  Assume `dynamic`.
-    if (unlinkedConst.operations.isEmpty) {
+    if (_builder.uc.operations.isEmpty) {
       return DynamicTypeImpl.instance;
     }
-    // Perform RPN evaluation of the constant, using a stack of inferred types.
-    for (UnlinkedExprOperation operation in unlinkedConst.operations) {
-      switch (operation) {
-        case UnlinkedExprOperation.pushInt:
-          intPtr++;
-          stack.add(typeProvider.intType);
-          break;
-        case UnlinkedExprOperation.pushLongInt:
-          int numInts = _getNextInt();
-          intPtr += numInts;
-          stack.add(typeProvider.intType);
-          break;
-        case UnlinkedExprOperation.pushDouble:
-          stack.add(typeProvider.doubleType);
-          break;
-        case UnlinkedExprOperation.pushTrue:
-        case UnlinkedExprOperation.pushFalse:
-          stack.add(typeProvider.boolType);
-          break;
-        case UnlinkedExprOperation.pushString:
-          strPtr++;
-          stack.add(typeProvider.stringType);
-          break;
-        case UnlinkedExprOperation.concatenate:
-          stack.length -= _getNextInt();
-          stack.add(typeProvider.stringType);
-          break;
-        case UnlinkedExprOperation.makeSymbol:
-          strPtr++;
-          stack.add(typeProvider.symbolType);
-          break;
-        case UnlinkedExprOperation.pushNull:
-          stack.add(typeProvider.nullType);
-          break;
-        case UnlinkedExprOperation.pushSuper:
-          stack.add(DynamicTypeImpl.instance);
-          break;
-        case UnlinkedExprOperation.pushThis:
-          stack.add(DynamicTypeImpl.instance);
-          break;
-        case UnlinkedExprOperation.pushReference:
-          _doPushReference();
-          break;
-        case UnlinkedExprOperation.extractProperty:
-          _doExtractProperty();
-          break;
-        case UnlinkedExprOperation.invokeConstructor:
-          _doInvokeConstructor();
-          break;
-        case UnlinkedExprOperation.makeUntypedList:
-          _doMakeUntypedList();
-          break;
-        case UnlinkedExprOperation.makeUntypedMap:
-          _doMakeUntypedMap();
-          break;
-        case UnlinkedExprOperation.makeTypedList:
-          _doMakeTypedList();
-          break;
-        case UnlinkedExprOperation.makeTypedMap:
-          _doMakeTypeMap();
-          break;
-        case UnlinkedExprOperation.not:
-          stack.length -= 1;
-          stack.add(typeProvider.boolType);
-          break;
-        case UnlinkedExprOperation.complement:
-          _computePrefixExpressionType('~');
-          break;
-        case UnlinkedExprOperation.negate:
-          _computePrefixExpressionType('unary-');
-          break;
-        case UnlinkedExprOperation.and:
-        case UnlinkedExprOperation.or:
-        case UnlinkedExprOperation.equal:
-        case UnlinkedExprOperation.notEqual:
-          stack.length -= 2;
-          stack.add(typeProvider.boolType);
-          break;
-        case UnlinkedExprOperation.bitXor:
-          _computeBinaryExpressionType(TokenType.CARET);
-          break;
-        case UnlinkedExprOperation.bitAnd:
-          _computeBinaryExpressionType(TokenType.AMPERSAND);
-          break;
-        case UnlinkedExprOperation.bitOr:
-          _computeBinaryExpressionType(TokenType.BAR);
-          break;
-        case UnlinkedExprOperation.bitShiftRight:
-          _computeBinaryExpressionType(TokenType.GT_GT);
-          break;
-        case UnlinkedExprOperation.bitShiftLeft:
-          _computeBinaryExpressionType(TokenType.LT_LT);
-          break;
-        case UnlinkedExprOperation.add:
-          _computeBinaryExpressionType(TokenType.PLUS);
-          break;
-        case UnlinkedExprOperation.subtract:
-          _computeBinaryExpressionType(TokenType.MINUS);
-          break;
-        case UnlinkedExprOperation.multiply:
-          _computeBinaryExpressionType(TokenType.STAR);
-          break;
-        case UnlinkedExprOperation.divide:
-          _computeBinaryExpressionType(TokenType.SLASH);
-          break;
-        case UnlinkedExprOperation.floorDivide:
-          _computeBinaryExpressionType(TokenType.TILDE_SLASH);
-          break;
-        case UnlinkedExprOperation.greater:
-          _computeBinaryExpressionType(TokenType.GT);
-          break;
-        case UnlinkedExprOperation.less:
-          _computeBinaryExpressionType(TokenType.LT);
-          break;
-        case UnlinkedExprOperation.greaterEqual:
-          _computeBinaryExpressionType(TokenType.GT_EQ);
-          break;
-        case UnlinkedExprOperation.lessEqual:
-          _computeBinaryExpressionType(TokenType.LT_EQ);
-          break;
-        case UnlinkedExprOperation.modulo:
-          _computeBinaryExpressionType(TokenType.PERCENT);
-          break;
-        case UnlinkedExprOperation.conditional:
-          _doConditional();
-          break;
-        case UnlinkedExprOperation.assignToIndex:
-          _doAssignToIndex();
-          break;
-        case UnlinkedExprOperation.assignToProperty:
-          _doAssignToProperty();
-          break;
-        case UnlinkedExprOperation.assignToRef:
-          _doAssignToRef();
-          break;
-        case UnlinkedExprOperation.await:
-          _doAwait();
-          break;
-        case UnlinkedExprOperation.extractIndex:
-          _doExtractIndex();
-          break;
-        case UnlinkedExprOperation.invokeMethodRef:
-          _doInvokeMethodRef();
-          break;
-        case UnlinkedExprOperation.invokeMethod:
-          _doInvokeMethod();
-          break;
-        case UnlinkedExprOperation.cascadeSectionBegin:
-          stack.add(stack.last);
-          break;
-        case UnlinkedExprOperation.cascadeSectionEnd:
-          stack.removeLast();
-          break;
-        case UnlinkedExprOperation.typeCast:
-          stack.removeLast();
-          DartType type = _getNextTypeRef();
-          stack.add(type);
-          break;
-        case UnlinkedExprOperation.typeCheck:
-          stack.removeLast();
-          refPtr++;
-          stack.add(typeProvider.boolType);
-          break;
-        case UnlinkedExprOperation.throwException:
-          stack.removeLast();
-          stack.add(BottomTypeImpl.instance);
-          break;
-        case UnlinkedExprOperation.pushLocalFunctionReference:
-          int popCount = _getNextInt();
-          assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
-          stack.add(function.functions[_getNextInt()].type);
-          break;
-        case UnlinkedExprOperation.pushParameter:
-          stack.add(_findParameterType(_getNextString()));
-          break;
-        case UnlinkedExprOperation.ifNull:
-          _doIfNull();
-          break;
-        default:
-          // TODO(paulberry): implement.
-          throw new UnimplementedError('$operation');
-      }
-    }
-    assert(intPtr == unlinkedConst.ints.length);
-    assert(refPtr == unlinkedConst.references.length);
-    assert(strPtr == unlinkedConst.strings.length);
-    assert(assignmentOperatorPtr == unlinkedConst.assignmentOperators.length);
-    assert(stack.length == 1);
-    return stack[0];
-  }
-
-  void _computeBinaryExpressionType(TokenType operator) {
-    DartType right = stack.removeLast();
-    DartType left = stack.removeLast();
-    _pushBinaryOperatorType(left, operator, right);
-  }
-
-  void _computePrefixExpressionType(String operatorName) {
-    DartType operand = stack.removeLast();
-    if (operand is InterfaceType) {
-      MethodElement method =
-          operand.lookUpInheritedMethod(operatorName, library: library);
-      if (method != null) {
-        DartType type = method.returnType;
-        stack.add(type);
-        return;
-      }
-    }
-    stack.add(DynamicTypeImpl.instance);
-  }
-
-  void _doAssignment() {
-    UnlinkedExprAssignOperator operator =
-        unlinkedConst.assignmentOperators[assignmentOperatorPtr++];
-    if (isIncrementOrDecrement(operator)) {
-      _doIncrementOrDecrement(operator);
-      return;
-    }
-    if (operator == UnlinkedExprAssignOperator.assign) {
-      stack.removeLast();
-      return; // type is on the stack
-    }
-    TokenType binaryOperator = _convertAssignOperatorToTokenType(operator);
-    _computeBinaryExpressionType(binaryOperator);
-  }
-
-  void _doAssignToIndex() {
-    _doExtractIndex();
-    _doAssignment();
-  }
-
-  void _doAssignToProperty() {
-    _doExtractProperty();
-    _doAssignment();
-  }
-
-  void _doAssignToRef() {
-    EntityRef ref = _getNextRef();
-    ReferenceableElementForLink element = unit.resolveRef(ref.reference);
-    stack.add(element.asStaticType);
-    _doAssignment();
-  }
-
-  void _doAwait() {
-    DartType type = stack.removeLast();
-    DartType typeArgument = type?.flattenFutures(linker.typeSystem);
-    typeArgument = _dynamicIfNull(typeArgument);
-    stack.add(typeArgument);
-  }
-
-  void _doConditional() {
-    DartType elseType = stack.removeLast();
-    DartType thenType = stack.removeLast();
-    stack.removeLast();
-    DartType type = _leastUpperBound(thenType, elseType);
-    type = _dynamicIfNull(type);
-    stack.add(type);
-  }
-
-  void _doExtractIndex() {
-    stack.removeLast(); // index
-    DartType target = stack.removeLast();
-    stack.add(() {
-      if (target is InterfaceType) {
-        MethodElement method =
-            target.lookUpInheritedMethod('[]', library: library);
-        if (method != null) {
-          return method.returnType;
-        }
-      }
-      return DynamicTypeImpl.instance;
-    }());
-  }
-
-  void _doExtractProperty() {
-    DartType target = stack.removeLast();
-    if (target.isDynamic) {
-      target = typeProvider.objectType;
-    }
-    String propertyName = _getNextString();
-    stack.add(() {
-      if (target is InterfaceType) {
-        ExecutableElement element = target
-            .lookUpInheritedGetterOrMethod(propertyName, library: library);
-        if (element != null) {
-          if (element is PropertyAccessorElement) {
-            return element.returnType;
-          } else {
-            // Method tear-off
-            return element.type;
-          }
-        }
-      }
-      return DynamicTypeImpl.instance;
-    }());
-  }
-
-  void _doIfNull() {
-    DartType secondType = stack.removeLast();
-    DartType firstType = stack.removeLast();
-    DartType type = _leastUpperBound(firstType, secondType);
-    type = _dynamicIfNull(type);
-    stack.add(type);
-  }
-
-  void _doIncrementOrDecrement(UnlinkedExprAssignOperator operator) {
-    switch (operator) {
-      case UnlinkedExprAssignOperator.prefixDecrement:
-        stack.add(typeProvider.intType);
-        _computeBinaryExpressionType(TokenType.MINUS);
-        return;
-      case UnlinkedExprAssignOperator.prefixIncrement:
-        stack.add(typeProvider.intType);
-        _computeBinaryExpressionType(TokenType.PLUS);
-        return;
-      case UnlinkedExprAssignOperator.postfixDecrement:
-      case UnlinkedExprAssignOperator.postfixIncrement:
-        return; // Return the operand type
-      default:
-        stack.removeLast();
-        stack.add(DynamicTypeImpl.instance);
-        return;
-    }
-  }
-
-  void _doInvokeConstructor() {
-    int numNamed = unlinkedConst.ints[intPtr++];
-    int numPositional = unlinkedConst.ints[intPtr++];
-    List<String> namedArgNames = _getNextStrings(numNamed);
-    List<DartType> namedArgTypeList = _popList(numNamed);
-    List<DartType> positionalArgTypes = _popList(numPositional);
-
-    EntityRef ref = _getNextRef();
-
-    var typeArguments = new List<DartType>(ref.typeArguments.length);
-    for (int i = 0; i < ref.typeArguments.length; i++) {
-      typeArguments[i] = unit.resolveTypeRef(function, ref.typeArguments[i]);
-    }
-
-    _doInvokeConstructorImpl(ref, typeArguments, numNamed, numPositional,
-        namedArgNames, namedArgTypeList, positionalArgTypes);
-  }
-
-  /**
-   * Implements constructor invocation inference, and accepts the reference,
-   * type arguments, and types of arguments. It is used for explicit instance
-   * creation, and also for implicit creation, that looks like
-   * [UnlinkedExprOperation.invokeMethodRef].
-   */
-  void _doInvokeConstructorImpl(
-      EntityRef ref,
-      List<DartType> typeArguments,
-      int numNamed,
-      int numPositional,
-      List<String> namedArgNames,
-      List<DartType> namedArgTypeList,
-      List<DartType> positionalArgTypes) {
-    ReferenceableElementForLink refElement = unit.resolveRef(ref.reference);
-    ConstructorElementForLink constructorElement = refElement.asConstructor;
-
-    if (constructorElement != null) {
-      stack.add(() {
-        if (typeArguments.isNotEmpty) {
-          return constructorElement.enclosingClass.buildType((int i) {
-            if (i < typeArguments.length) {
-              return typeArguments[i];
-            } else {
-              return null;
-            }
-          }, const <int>[]);
-        } else {
-          FunctionType rawType = StaticTypeAnalyzer
-              .constructorToGenericFunctionType(constructorElement);
-          FunctionType inferredType = _inferExecutableType(
-              rawType,
-              numNamed,
-              numPositional,
-              namedArgNames,
-              namedArgTypeList,
-              positionalArgTypes, const <DartType>[]);
-          if (inferredType == null || identical(inferredType, rawType)) {
-            inferredType = linker.typeSystem.instantiateToBounds(rawType);
-          }
-          return inferredType.returnType;
-        }
-      }());
-    } else {
-      ClassElementForLink classElement =
-          unit.resolveConstructorClassRef(ref.reference).asClass;
-      DartType inferredType;
-      if (classElement != null) {
-        InterfaceType rawType = classElement.type;
-        inferredType = linker.typeSystem.instantiateToBounds(rawType);
-      } else {
-        inferredType = DynamicTypeImpl.instance;
-      }
-      stack.add(inferredType);
-    }
-  }
-
-  void _doInvokeMethod() {
-    int numNamed = unlinkedConst.ints[intPtr++];
-    int numPositional = unlinkedConst.ints[intPtr++];
-    List<String> namedArgNames = _getNextStrings(numNamed);
-    List<DartType> namedArgTypeList = _popList(numNamed);
-    List<DartType> positionalArgTypes = _popList(numPositional);
-    // TODO(scheglov) if we pushed target and method name first, we might be
-    // able to move work with arguments in _inferExecutableType()
-    String methodName = _getNextString();
-    List<DartType> typeArguments = _getTypeArguments();
-    DartType target = stack.removeLast();
-    if (target.isDynamic) {
-      target = typeProvider.objectType;
-    }
-    stack.add(() {
-      if (target is InterfaceType) {
-        MethodElement method =
-            target.lookUpInheritedMethod(methodName, library: library);
-        FunctionType rawType = method?.type;
-        FunctionType inferredType = _inferExecutableType(
-            rawType,
-            numNamed,
-            numPositional,
-            namedArgNames,
-            namedArgTypeList,
-            positionalArgTypes,
-            typeArguments);
-        if (inferredType != null) {
-          return inferredType.returnType;
-        }
-      }
-      return DynamicTypeImpl.instance;
-    }());
-  }
-
-  void _doInvokeMethodRef() {
-    int numNamed = _getNextInt();
-    int numPositional = _getNextInt();
-    List<String> namedArgNames = _getNextStrings(numNamed);
-    List<DartType> namedArgTypeList = _popList(numNamed);
-    List<DartType> positionalArgTypes = _popList(numPositional);
-
-    EntityRef ref = _getNextRef();
-    ReferenceableElementForLink element = unit.resolveRef(ref.reference);
-
-    List<DartType> typeArguments = _getTypeArguments();
-
-    // Check for implicit instance creation.
-    if (element.asClass != null || element.asConstructor != null) {
-      _doInvokeConstructorImpl(ref, typeArguments, numNamed, numPositional,
-          namedArgNames, namedArgTypeList, positionalArgTypes);
-      return;
-    }
-
-    stack.add(() {
-      DartType rawType = element.asStaticType;
-      if (rawType is FunctionType) {
-        FunctionType inferredType = _inferExecutableType(
-            rawType,
-            numNamed,
-            numPositional,
-            namedArgNames,
-            namedArgTypeList,
-            positionalArgTypes,
-            typeArguments);
-        if (inferredType != null) {
-          return inferredType.returnType;
-        }
-      }
-      return DynamicTypeImpl.instance;
-    }());
-  }
-
-  void _doMakeTypedList() {
-    DartType itemType = _getNextTypeRef();
-    stack.length -= _getNextInt();
-    stack.add(typeProvider.listType.instantiate(<DartType>[itemType]));
-  }
-
-  void _doMakeTypeMap() {
-    DartType keyType = _getNextTypeRef();
-    DartType valueType = _getNextTypeRef();
-    stack.length -= 2 * _getNextInt();
-    stack.add(typeProvider.mapType.instantiate(<DartType>[keyType, valueType]));
-  }
-
-  void _doMakeUntypedList() {
-    int numItems = _getNextInt();
-    DartType itemType = numItems == 0
-        ? DynamicTypeImpl.instance
-        : _popList(numItems).reduce(_leastUpperBound);
-    itemType ??= DynamicTypeImpl.instance;
-    stack.add(typeProvider.listType.instantiate(<DartType>[itemType]));
-  }
-
-  void _doMakeUntypedMap() {
-    int numEntries = _getNextInt();
-    List<DartType> keysValues = _popList(2 * numEntries);
-    DartType keyType = null;
-    DartType valueType = null;
-    for (int i = 0; i < 2 * numEntries; i++) {
-      DartType type = keysValues[i];
-      if (i.isEven) {
-        keyType = keyType == null ? type : _leastUpperBound(keyType, type);
-      } else {
-        valueType =
-            valueType == null ? type : _leastUpperBound(valueType, type);
-      }
-    }
-    keyType ??= DynamicTypeImpl.instance;
-    valueType ??= DynamicTypeImpl.instance;
-    stack.add(typeProvider.mapType.instantiate(<DartType>[keyType, valueType]));
-  }
-
-  void _doPushReference() {
-    EntityRef ref = _getNextRef();
-    if (ref.paramReference != 0) {
-      stack.add(typeProvider.typeType);
-    } else {
-      // Synthetic function types can't be directly referred
-      // to by expressions.
-      assert(ref.syntheticReturnType == null);
-      // Nor can implicit function types derived from
-      // function-typed parameters.
-      assert(ref.implicitFunctionTypeIndices.isEmpty);
-      ReferenceableElementForLink element = unit.resolveRef(ref.reference);
-      stack.add(element.asStaticType);
-    }
-  }
-
-  /**
-   * Find the parameter in scope called [parameterName] and return its type.
-   */
-  DartType _findParameterType(String parameterName) {
-    FunctionElementForLink_Local f = this.function;
-    while (true) {
-      for (ParameterElement parameter in f.parameters) {
-        if (parameter.name == parameterName) {
-          return parameter.type;
-        }
-      }
-      Element parent = f.enclosingElement;
-      if (parent is FunctionElementForLink_Local) {
-        f = parent;
-      } else {
-        // Parameter not found.  This should never happen in a well-formed
-        // summary.
-        assert(false);
-        return DynamicTypeImpl.instance;
-      }
-    }
-  }
-
-  int _getNextInt() {
-    return unlinkedConst.ints[intPtr++];
-  }
-
-  EntityRef _getNextRef() => unlinkedConst.references[refPtr++];
-
-  String _getNextString() {
-    return unlinkedConst.strings[strPtr++];
-  }
-
-  List<String> _getNextStrings(int n) {
-    List<String> result = new List<String>(n);
-    for (int i = 0; i < n; i++) {
-      result[i] = _getNextString();
-    }
-    return result;
-  }
-
-  DartType _getNextTypeRef() {
-    EntityRef ref = _getNextRef();
-    return unit.resolveTypeRef(function, ref);
-  }
-
-  List<DartType> _getTypeArguments() {
-    int numTypeArguments = _getNextInt();
-    List<DartType> typeArguments = new List<DartType>(numTypeArguments);
-    for (int i = 0; i < numTypeArguments; i++) {
-      typeArguments[i] = _getNextTypeRef();
-    }
-    return typeArguments;
-  }
-
-  FunctionType _inferExecutableType(
-      FunctionType rawMethodType,
-      int numNamedArguments,
-      int numPositionalArguments,
-      List<String> namedArgNames,
-      List<DartType> namedArgTypeList,
-      List<DartType> positionalArgTypes,
-      List<DartType> typeArguments) {
-    TypeSystem ts = linker.typeSystem;
-    if (rawMethodType != null) {
-      if (rawMethodType.typeFormals.isNotEmpty && typeArguments.isNotEmpty) {
-        Element methodElement = rawMethodType.element;
-        if (methodElement is TypeParameterizedElement &&
-            methodElement.typeParameters.length == typeArguments.length) {
-          return rawMethodType.instantiate(typeArguments);
-        }
-      } else if (rawMethodType.typeFormals.isNotEmpty &&
-          ts is StrongTypeSystemImpl) {
-        // Prepare the named argument types map.
-        Map<String, DartType> namedArgTypes = <String, DartType>{};
-        for (int i = 0; i < numNamedArguments; i++) {
-          String name = namedArgNames[i];
-          DartType type = namedArgTypeList[i];
-          namedArgTypes[name] = type;
-        }
-
-        // Fill parameters and the corresponding arguments.
-        List<ParameterElement> parameters = <ParameterElement>[];
-        List<DartType> argumentTypes = <DartType>[];
-        int positionalIndex = 0;
-        int numRequiredParameters = 0;
-        for (ParameterElement parameter in rawMethodType.parameters) {
-          if (parameter.isNotOptional) {
-            numRequiredParameters++;
-            if (numRequiredParameters > numPositionalArguments) {
-              return null;
-            }
-            parameters.add(parameter);
-            argumentTypes.add(positionalArgTypes[positionalIndex]);
-            positionalIndex++;
-          } else if (parameter.isOptionalPositional) {
-            if (positionalIndex < numPositionalArguments) {
-              parameters.add(parameter);
-              argumentTypes.add(positionalArgTypes[positionalIndex]);
-              positionalIndex++;
-            }
-          } else if (parameter.isNamed) {
-            DartType namedArgumentType = namedArgTypes[parameter.name];
-            if (namedArgumentType != null) {
-              parameters.add(parameter);
-              argumentTypes.add(namedArgumentType);
-            }
-          }
-        }
-
-        // Perform inference.
-        FunctionType inferred = ts.inferGenericFunctionOrType(
-            rawMethodType, parameters, argumentTypes, null);
-        return inferred;
-      }
-    }
-    // Not a generic function type, use the raw type.
-    return rawMethodType;
-  }
-
-  DartType _leastUpperBound(DartType s, DartType t) {
-    return linker.typeSystem.getLeastUpperBound(s, t);
-  }
-
-  List<DartType> _popList(int n) {
-    List<DartType> result = stack.sublist(stack.length - n, stack.length);
-    stack.length -= n;
-    return result;
-  }
-
-  void _pushBinaryOperatorType(
-      DartType left, TokenType operator, DartType right) {
-    if (left is InterfaceType) {
-      MethodElement method =
-          left.lookUpInheritedMethod(operator.lexeme, library: library);
-      if (method != null) {
-        DartType type = method.returnType;
-        type = linker.typeSystem
-            .refineBinaryExpressionType(left, operator, right, type);
-        stack.add(type);
-        return;
-      }
-    }
-    stack.add(DynamicTypeImpl.instance);
-  }
-
-  static TokenType _convertAssignOperatorToTokenType(
-      UnlinkedExprAssignOperator o) {
-    switch (o) {
-      case UnlinkedExprAssignOperator.assign:
-        return null;
-      case UnlinkedExprAssignOperator.ifNull:
-        return TokenType.QUESTION_QUESTION;
-      case UnlinkedExprAssignOperator.multiply:
-        return TokenType.STAR;
-      case UnlinkedExprAssignOperator.divide:
-        return TokenType.SLASH;
-      case UnlinkedExprAssignOperator.floorDivide:
-        return TokenType.TILDE_SLASH;
-      case UnlinkedExprAssignOperator.modulo:
-        return TokenType.PERCENT;
-      case UnlinkedExprAssignOperator.plus:
-        return TokenType.PLUS;
-      case UnlinkedExprAssignOperator.minus:
-        return TokenType.MINUS;
-      case UnlinkedExprAssignOperator.shiftLeft:
-        return TokenType.LT_LT;
-      case UnlinkedExprAssignOperator.shiftRight:
-        return TokenType.GT_GT;
-      case UnlinkedExprAssignOperator.bitAnd:
-        return TokenType.AMPERSAND;
-      case UnlinkedExprAssignOperator.bitXor:
-        return TokenType.CARET;
-      case UnlinkedExprAssignOperator.bitOr:
-        return TokenType.BAR;
-      case UnlinkedExprAssignOperator.prefixIncrement:
-        return TokenType.PLUS_PLUS;
-      case UnlinkedExprAssignOperator.prefixDecrement:
-        return TokenType.MINUS_MINUS;
-      case UnlinkedExprAssignOperator.postfixIncrement:
-        return TokenType.PLUS_PLUS;
-      case UnlinkedExprAssignOperator.postfixDecrement:
-        return TokenType.MINUS_MINUS;
-    }
-    return null;
+    var expression = _builder.build();
+    var container =
+        astFactory.expressionFunctionBody(null, null, expression, null);
+    expression.accept(_astRewriteVisitor);
+    expression = container.expression;
+    expression.accept(_resolverVisitor);
+    return expression.staticType;
   }
 }
 
@@ -3083,7 +2456,7 @@
       if (enclosingConstructor is ConstructorElement) {
         Element enclosingClass = enclosingConstructor.enclosingElement;
         if (enclosingClass is ClassElement) {
-          FieldElement field = enclosingClass.getField(_unlinkedParam.name);
+          FieldElement field = enclosingClass.getField(unlinkedParam.name);
           if (field != null && !field.isSynthetic) {
             _field = field;
           }
@@ -3141,11 +2514,11 @@
   @override
   DartType get returnType {
     if (_returnType == null) {
-      if (enclosingElement._unlinkedParam.type == null) {
+      if (enclosingElement.unlinkedParam.type == null) {
         _returnType = DynamicTypeImpl.instance;
       } else {
         _returnType = enclosingElement.compilationUnit.resolveTypeRef(
-            enclosingElement, enclosingElement._unlinkedParam.type);
+            enclosingElement, enclosingElement.unlinkedParam.type);
       }
     }
     return _returnType;
@@ -3212,7 +2585,7 @@
   String get identifier => '';
 
   @override
-  bool get isAsynchronous => _unlinkedExecutable.isAsynchronous;
+  bool get isAsynchronous => serializedExecutable.isAsynchronous;
 
   @override
   DartType get returnType {
@@ -3236,6 +2609,10 @@
   }
 
   @override
+  UnlinkedExecutable get serializedExecutable =>
+      _variable.unlinkedVariable.initializer;
+
+  @override
   TypeParameterizedElementMixin get typeParameterContext => this;
 
   @override
@@ -3245,10 +2622,6 @@
   bool get _hasTypeBeenInferred => _inferredReturnType != null;
 
   @override
-  UnlinkedExecutable get _unlinkedExecutable =>
-      _variable.unlinkedVariable.initializer;
-
-  @override
   FunctionElementForLink_Local getLocalFunction(int index) {
     List<FunctionElementForLink_Local_NonSynthetic> functions = this.functions;
     return index < functions.length ? functions[index] : null;
@@ -3259,8 +2632,10 @@
    * [compilationUnit].
    */
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    compilationUnit._storeLinkedType(_unlinkedExecutable.inferredReturnTypeSlot,
-        _inferredReturnType, typeParameterContext);
+    compilationUnit._storeLinkedType(
+        serializedExecutable.inferredReturnTypeSlot,
+        _inferredReturnType,
+        typeParameterContext);
     for (FunctionElementForLink_Local_NonSynthetic function in functions) {
       function.link(compilationUnit);
     }
@@ -3346,7 +2721,7 @@
 
   @override
   List<FunctionElementForLink_Local_NonSynthetic> get functions =>
-      _functions ??= _unlinkedExecutable.localFunctions
+      _functions ??= serializedExecutable.localFunctions
           .map((UnlinkedExecutable ex) =>
               new FunctionElementForLink_Local_NonSynthetic(
                   compilationUnit, this, ex))
@@ -3354,7 +2729,7 @@
 
   @override
   String get identifier {
-    String identifier = _unlinkedExecutable.name;
+    String identifier = serializedExecutable.name;
     Element enclosing = this.enclosingElement;
     if (enclosing is ExecutableElementForLink) {
       int id =
@@ -3365,7 +2740,7 @@
   }
 
   @override
-  bool get isAsynchronous => _unlinkedExecutable.isAsynchronous;
+  bool get isAsynchronous => serializedExecutable.isAsynchronous;
 
   @override
   bool get _hasTypeBeenInferred => _inferredReturnType != null;
@@ -3387,9 +2762,11 @@
    * Store the results of type inference for this function in [compilationUnit].
    */
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
-    if (_unlinkedExecutable.returnType == null) {
+    if (serializedExecutable.returnType == null) {
       compilationUnit._storeLinkedType(
-          _unlinkedExecutable.inferredReturnTypeSlot, inferredReturnType, this);
+          serializedExecutable.inferredReturnTypeSlot,
+          inferredReturnType,
+          this);
     }
     for (FunctionElementForLink_Local_NonSynthetic function in functions) {
       function.link(compilationUnit);
@@ -3554,7 +2931,7 @@
         TypeParameterizedElementMixin,
         ParameterParentElementForLink,
         ReferenceableElementForLink
-    implements GenericFunctionTypeElement, ElementImpl {
+    implements GenericFunctionTypeElementImpl, ElementImpl {
   @override
   final CompilationUnitElementForLink enclosingUnit;
 
@@ -3687,8 +3064,11 @@
       _unlinkedTypedef.returnType.syntheticParams;
 
   @override
-  List<UnlinkedTypeParam> get unlinkedTypeParams =>
-      _unlinkedTypedef.typeParameters;
+  List<UnlinkedTypeParam> get unlinkedTypeParams {
+    var result = _unlinkedTypedef.typeParameters.toList();
+    result.addAll(_unlinkedTypedef.returnType.typeParameters);
+    return result;
+  }
 
   @override
   DartType buildType(
@@ -3839,7 +3219,9 @@
  */
 abstract class LibraryElementForLink<
         UnitElement extends CompilationUnitElementForLink>
-    implements LibraryElementImpl {
+    extends LibraryResynthesizerContextMixin implements LibraryElementImpl {
+  final _LibraryResynthesizer resynthesizer;
+
   /**
    * Pointer back to the linker.
    */
@@ -3851,14 +3233,23 @@
   final Uri _absoluteUri;
 
   List<UnitElement> _units;
+  List<UnitElement> _parts;
   final Map<String, ReferenceableElementForLink> _containedNames =
       <String, ReferenceableElementForLink>{};
   final List<LibraryElementForLink> _dependencies = <LibraryElementForLink>[];
-  UnlinkedUnit _definingUnlinkedUnit;
+  UnlinkedUnit _unlinkedDefiningUnit;
   List<LibraryElementForLink> _importedLibraries;
   List<LibraryElementForLink> _exportedLibraries;
 
-  LibraryElementForLink(this._linker, this._absoluteUri) {
+  Namespace _exportNamespace;
+
+  Namespace _publicNamespace;
+
+  FunctionElement _loadLibraryFunction;
+
+  LibraryElementForLink(this._linker, this._absoluteUri)
+      : resynthesizer = new _LibraryResynthesizer() {
+    resynthesizer._library = this;
     if (_linkedLibrary != null) {
       _dependencies.length = _linkedLibrary.dependencies.length;
     }
@@ -3867,11 +3258,8 @@
   @override
   ContextForLink get context => _linker.context;
 
-  /**
-   * Get the [UnlinkedUnit] for the defining compilation unit of this library.
-   */
-  UnlinkedUnit get definingUnlinkedUnit =>
-      _definingUnlinkedUnit ??= _linker.getUnit(_absoluteUri.toString());
+  @override
+  UnitElement get definingCompilationUnit => units[0];
 
   @override
   Element get enclosingElement => null;
@@ -3879,16 +3267,20 @@
   @override
   List<LibraryElementForLink> get exportedLibraries =>
       _exportedLibraries ??= _linkedLibrary.exportDependencies
-          .map(_getDependency)
+          .map(buildImportedLibrary)
           .where((library) => library != null)
           .toList();
 
   @override
+  Namespace get exportNamespace =>
+      _exportNamespace ??= resynthesizerContext.buildExportNamespace();
+
+  @override
   String get identifier => _absoluteUri.toString();
 
   @override
   List<LibraryElementForLink> get importedLibraries => _importedLibraries ??=
-      _linkedLibrary.importDependencies.map(_getDependency).toList();
+      _linkedLibrary.importDependencies.map(buildImportedLibrary).toList();
 
   @override
   bool get isDartAsync => _absoluteUri.toString() == 'dart:async';
@@ -3896,6 +3288,12 @@
   @override
   bool get isDartCore => _absoluteUri.toString() == 'dart:core';
 
+  @override
+  bool get isInSdk => _absoluteUri.scheme == 'dart';
+
+  @override
+  bool get isSynthetic => _linkedLibrary == null;
+
   /**
    * If this library is part of the build unit being linked, return the library
    * cycle it is part of.  Otherwise return `null`.
@@ -3903,14 +3301,31 @@
   LibraryCycleForLink get libraryCycleForLink;
 
   @override
+  FunctionElement get loadLibraryFunction =>
+      _loadLibraryFunction ??= LibraryElementImpl
+          .createLoadLibraryFunctionForLibrary(_linker.typeProvider, this);
+
+  @override
   String get name {
-    return _definingUnlinkedUnit.libraryName;
+    return _unlinkedDefiningUnit.libraryName;
   }
 
+  List<UnitElement> get parts => _parts ??= units.sublist(1);
+
+  @override
+  Namespace get publicNamespace =>
+      _publicNamespace ??= resynthesizerContext.buildPublicNamespace();
+
+  @override
+  LibraryResynthesizerContext get resynthesizerContext => this;
+
+  @override
+  Source get source => definingCompilationUnit.source;
+
   @override
   List<UnitElement> get units {
     if (_units == null) {
-      UnlinkedUnit definingUnit = definingUnlinkedUnit;
+      UnlinkedUnit definingUnit = unlinkedDefiningUnit;
       _units = <UnitElement>[
         _makeUnitElement(definingUnit, 0, _absoluteUri.toString())
       ];
@@ -3939,37 +3354,22 @@
     return _units;
   }
 
+  @override
+  UnlinkedUnit get unlinkedDefiningUnit => _unlinkedDefiningUnit ??=
+      _linker.getUnit(_absoluteUri.toString()) ?? new UnlinkedUnitBuilder();
+
+  List<LinkedExportName> get _linkedExportNames =>
+      _linkedLibrary == null ? [] : _linkedLibrary.exportNames;
+
   /**
    * The linked representation of the library in the summary.
    */
   LinkedLibrary get _linkedLibrary;
 
   /**
-   * Search all the units for a top level element with the given
-   * [name].  If no name is found, return the singleton instance of
-   * [UndefinedElementForLink].
-   */
-  ReferenceableElementForLink getContainedName(String name) =>
-      _containedNames.putIfAbsent(name, () {
-        for (UnitElement unit in units) {
-          ReferenceableElementForLink element = unit.getContainedName(name);
-          if (!identical(element, UndefinedElementForLink.instance)) {
-            return element;
-          }
-        }
-        return UndefinedElementForLink.instance;
-      });
-
-  @override
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() => _absoluteUri.toString();
-
-  /**
    * Return the [LibraryElement] corresponding to the given dependency [index].
    */
-  LibraryElementForLink _getDependency(int index) {
+  LibraryElementForLink buildImportedLibrary(int index) {
     LibraryElementForLink result = _dependencies[index];
     if (result == null) {
       Uri uri;
@@ -3991,6 +3391,37 @@
   }
 
   /**
+   * Search all the units for a top level element with the given
+   * [name].  If no name is found, return the singleton instance of
+   * [UndefinedElementForLink].
+   */
+  ReferenceableElementForLink getContainedName(String name) =>
+      _containedNames.putIfAbsent(name, () {
+        for (UnitElement unit in units) {
+          ReferenceableElementForLink element = unit.getContainedName(name);
+          if (!identical(element, UndefinedElementForLink.instance)) {
+            return element;
+          }
+        }
+        return UndefinedElementForLink.instance;
+      });
+
+  @override
+  List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) =>
+      LibraryElementImpl.getImportsWithPrefixFromImports(
+          prefixElement, imports);
+
+  @override
+  ClassElement getType(String className) => LibraryElementImpl.getTypeFromParts(
+      className, definingCompilationUnit, parts);
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() => _absoluteUri.toString();
+
+  /**
    * Create a [UnitElement] for one of the library's compilation
    * units.
    */
@@ -4015,11 +3446,20 @@
 
   InheritanceManager _inheritanceManager;
 
+  List<ImportElement> _imports;
+
+  List<PrefixElement> _prefixes;
+
   LibraryElementInBuildUnit(Linker linker, Uri absoluteUri, this._linkedLibrary)
       : super(linker, absoluteUri) {
     _libraryNode = new LibraryNode(this);
   }
 
+  @override
+  List<ImportElement> get imports =>
+      _imports ??= LibraryElementImpl.buildImportsFromSummary(this,
+          _unlinkedDefiningUnit.imports, _linkedLibrary.importDependencies);
+
   /**
    * Get the inheritance manager for this library (creating it if necessary).
    */
@@ -4034,6 +3474,10 @@
     return _libraryNode._libraryCycle;
   }
 
+  @override
+  List<PrefixElement> get prefixes =>
+      _prefixes ??= LibraryElementImpl.buildPrefixesFromImports(imports);
+
   /**
    * If this library already has a dependency in its dependencies table matching
    * [library], return its index.  Otherwise add a new dependency to table and
@@ -4041,14 +3485,14 @@
    */
   int addDependency(LibraryElementForLink library) {
     for (int i = 0; i < _linkedLibrary.dependencies.length; i++) {
-      if (identical(_getDependency(i), library)) {
+      if (identical(buildImportedLibrary(i), library)) {
         return i;
       }
     }
     int result = _linkedLibrary.dependencies.length;
     Uri libraryUri = library._absoluteUri;
     List<String> partsRelativeToDependency =
-        library.definingUnlinkedUnit.publicNamespace.parts;
+        library.unlinkedDefiningUnit.publicNamespace.parts;
     List<String> partsAbsolute = partsRelativeToDependency
         .map((partUri) =>
             resolveRelativeUri(libraryUri, Uri.parse(partUri)).toString())
@@ -4107,7 +3551,13 @@
   CompilationUnitElementInDependency _makeUnitElement(
           UnlinkedUnit unlinkedUnit, int i, String absoluteUri) =>
       new CompilationUnitElementInDependency(
-          this, unlinkedUnit, _linkedLibrary.units[i], i, absoluteUri);
+          this,
+          unlinkedUnit,
+          _linkedLibrary == null
+              ? new LinkedUnitBuilder()
+              : _linkedLibrary.units[i],
+          i,
+          absoluteUri);
 }
 
 /**
@@ -4443,7 +3893,7 @@
   /**
    * The unlinked representation of the parameter in the summary.
    */
-  final UnlinkedParam _unlinkedParam;
+  final UnlinkedParam unlinkedParam;
 
   /**
    * The innermost enclosing element that can declare type parameters.
@@ -4475,16 +3925,16 @@
   DartType _declaredType;
   bool _inheritsCovariant = false;
 
-  ParameterElementForLink(this.enclosingElement, this._unlinkedParam,
+  ParameterElementForLink(this.enclosingElement, this.unlinkedParam,
       this._typeParameterContext, this.compilationUnit, this._parameterIndex) {
-    if (_unlinkedParam.initializer?.bodyExpr != null) {
+    if (unlinkedParam.initializer?.bodyExpr != null) {
       _constNode = new ConstParameterNode(this);
     }
     if (compilationUnit is CompilationUnitElementInDependency) {
       _inheritsCovariant =
           (compilationUnit as CompilationUnitElementInDependency)
               .parametersInheritingCovariant
-              .contains(_unlinkedParam.inheritsCovariantSlot);
+              .contains(unlinkedParam.inheritsCovariantSlot);
     }
   }
 
@@ -4514,11 +3964,11 @@
   }
 
   @override
-  String get displayName => _unlinkedParam.name;
+  String get displayName => unlinkedParam.name;
 
   @override
   bool get hasImplicitType =>
-      !_unlinkedParam.isFunctionTyped && _unlinkedParam.type == null;
+      !unlinkedParam.isFunctionTyped && unlinkedParam.type == null;
 
   @override
   String get identifier => name;
@@ -4532,11 +3982,14 @@
   }
 
   @override
+  FunctionElement get initializer => null;
+
+  @override
   bool get isCovariant {
     if (isExplicitlyCovariant || inheritsCovariant) {
       return true;
     }
-    for (UnlinkedExpr annotation in _unlinkedParam.annotations) {
+    for (UnlinkedExpr annotation in unlinkedParam.annotations) {
       if (annotation.operations.length == 1 &&
           annotation.operations[0] == UnlinkedExprOperation.pushReference) {
         ReferenceableElementForLink element =
@@ -4552,7 +4005,10 @@
   }
 
   @override
-  bool get isExplicitlyCovariant => _unlinkedParam.isExplicitlyCovariant;
+  bool get isExplicitlyCovariant => unlinkedParam.isExplicitlyCovariant;
+
+  @override
+  bool get isInitializingFormal => unlinkedParam.isInitializingFormal;
 
   @override
   bool get isNamed => parameterKind == ParameterKind.NAMED;
@@ -4574,11 +4030,11 @@
       parameterKind == ParameterKind.REQUIRED;
 
   @override
-  String get name => _unlinkedParam.name;
+  String get name => unlinkedParam.name;
 
   @override
   ParameterKind get parameterKind {
-    switch (_unlinkedParam.kind) {
+    switch (unlinkedParam.kind) {
       case UnlinkedParamKind.required:
         return ParameterKind.REQUIRED;
       case UnlinkedParamKind.positional:
@@ -4594,21 +4050,21 @@
     if (_inferredType != null) {
       return _inferredType;
     } else if (_declaredType == null) {
-      if (_unlinkedParam.isFunctionTyped) {
+      if (unlinkedParam.isFunctionTyped) {
         _declaredType = new FunctionTypeImpl(
             new FunctionElementForLink_FunctionTypedParam(
-                this, _typeParameterContext, _unlinkedParam.parameters));
-      } else if (_unlinkedParam.type == null) {
+                this, _typeParameterContext, unlinkedParam.parameters));
+      } else if (unlinkedParam.type == null) {
         if (!compilationUnit.isInBuildUnit) {
           _inferredType = compilationUnit.getLinkedType(
-              this, _unlinkedParam.inferredTypeSlot);
+              this, unlinkedParam.inferredTypeSlot);
           return _inferredType;
         } else {
           _declaredType = DynamicTypeImpl.instance;
         }
       } else {
         _declaredType =
-            compilationUnit.resolveTypeRef(this, _unlinkedParam.type);
+            compilationUnit.resolveTypeRef(this, unlinkedParam.type);
       }
     }
     return _declaredType;
@@ -4631,12 +4087,12 @@
    */
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     compilationUnit._storeLinkedType(
-        _unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext);
+        unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext);
     compilationUnit._storeLinkedTypeError(
-        _unlinkedParam.inferredTypeSlot, _inferenceError);
+        unlinkedParam.inferredTypeSlot, _inferenceError);
     if (inheritsCovariant) {
       compilationUnit
-          ._storeInheritsCovariant(_unlinkedParam.inheritsCovariantSlot);
+          ._storeInheritsCovariant(unlinkedParam.inheritsCovariantSlot);
     }
   }
 
@@ -4850,18 +4306,18 @@
 
   @override
   bool get isGetter =>
-      _unlinkedExecutable.kind == UnlinkedExecutableKind.getter;
+      serializedExecutable.kind == UnlinkedExecutableKind.getter;
 
   @override
   bool get isSetter =>
-      _unlinkedExecutable.kind == UnlinkedExecutableKind.setter;
+      serializedExecutable.kind == UnlinkedExecutableKind.setter;
 
   @override
   bool get isStatic => enclosingClass == null || super.isStatic;
 
   @override
   ElementKind get kind =>
-      _unlinkedExecutable.kind == UnlinkedExecutableKind.getter
+      serializedExecutable.kind == UnlinkedExecutableKind.getter
           ? ElementKind.GETTER
           : ElementKind.SETTER;
 
@@ -5143,7 +4599,7 @@
   DartType get asStaticType => type;
 
   @override
-  String get identifier => _unlinkedExecutable.name;
+  String get identifier => serializedExecutable.name;
 
   @override
   bool get isStatic => true;
@@ -5340,7 +4796,7 @@
   @override
   List<TypeInferenceNode> computeDependencies() {
     List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
-    collectDependencies(dependencies, functionElement._unlinkedExecutable,
+    collectDependencies(dependencies, functionElement.serializedExecutable,
         functionElement.compilationUnit);
     return dependencies;
   }
@@ -5720,3 +5176,77 @@
   @override
   String toString() => '$enclosingElement.$name';
 }
+
+/// Specialization of [LibraryResynthesizer] for resynthesis during linking.
+class _LibraryResynthesizer extends LibraryResynthesizerMixin {
+  LibraryElementForLink _library;
+
+  @override
+  LibraryElement get library => _library;
+
+  @override
+  List<LinkedExportName> get linkedExportNames => _library._linkedExportNames;
+
+  @override
+  Element buildExportName(LinkedExportName exportName) {
+    LibraryElementForLink dependency =
+        _library.buildImportedLibrary(exportName.dependency);
+    return dependency.getContainedName(exportName.name);
+  }
+}
+
+/// Specialization of [ReferenceInfo] for resynthesis during linking.
+class _ReferenceInfo extends ReferenceInfo {
+  @override
+  final ReferenceableElementForLink element;
+
+  @override
+  final ReferenceInfo enclosing;
+
+  @override
+  final String name;
+
+  @override
+  final bool hasTypeParameters;
+
+  _ReferenceInfo(
+      this.enclosing, this.element, this.name, this.hasTypeParameters);
+
+  /// TODO(paulberry): this method doesn't seem to be used.  Investigate whether
+  /// it is needed.
+  @override
+  DartType get type => throw new UnimplementedError();
+}
+
+/// Specialization of [UnitResynthesizer] for resynthesis during linking.
+class _UnitResynthesizer extends UnitResynthesizer with UnitResynthesizerMixin {
+  CompilationUnitElementForLink _unit;
+
+  @override
+  TypeProvider get typeProvider => _unit.library._linker.typeProvider;
+
+  @override
+  DartType buildType(ElementImpl context, EntityRef type) =>
+      _unit.resolveTypeRef(context, type);
+
+  @override
+  DartType buildTypeForClassInfo(
+      info, int numTypeArguments, DartType Function(int i) getTypeArgument) {
+    ClassElementForLink class_ = info.element;
+    if (numTypeArguments == 0) {
+      DartType type = class_.typeWithDefaultBounds;
+      _typesWithImplicitArguments[type] = true;
+      return type;
+    }
+    return class_.buildType(getTypeArgument, const []);
+  }
+
+  @override
+  bool doesTypeHaveImplicitArguments(ParameterizedType type) =>
+      _typesWithImplicitArguments[type] != null;
+
+  @override
+  _ReferenceInfo getReferenceInfo(int index) {
+    return _unit.resolveRefToInfo(index);
+  }
+}
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 6d21ed4..b6f3d3e 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -77,19 +77,6 @@
   return element is FunctionElement || element is MethodElement;
 }
 
-/// Summarizes the assignability relationship between two types
-/// considering both the fuzzy arrow semantics and the sound
-/// semantics.  Summary indicates whether 1) a cast is needed
-/// on assignment, and 2) whether a fuzzy arrow warning should
-/// be emitted.
-enum _FuzzyStatus {
-  needsCastFuzzy, // Needs a cast, relies on fuzzy arrows
-  needsCastSound, // Needs a cast, no fuzzy arrows
-  noCastFuzzy, // No cast, but uses fuzzy arrows
-  noCastSound, // No cast, not fuzzy arrows
-  unrelated // Not assignable as function types
-}
-
 /// Given a generic class [element] find its covariant upper bound, using
 /// the type system [rules].
 ///
@@ -1111,13 +1098,16 @@
     return rules.anyParameterType(ft, (pt) => pt.isDynamic);
   }
 
-  /// Given an expression [expr] of type [fromType], summarize what casts
-  /// and fuzzy arrow hints (if any) should be emitted when assigning to
-  /// a location of type [to]
-  _FuzzyStatus _checkFuzzyStatus(
+  /// Given an expression [expr] of type [fromType], returns true if an implicit
+  /// downcast is required, false if it is not, or null if the types are
+  /// unrelated.
+  ///
+  /// This also issues fuzzy arrow hints (if any).
+  bool _checkFunctionTypeCasts(
       Expression expr, FunctionType to, DartType fromType) {
     var strict = hasStrictArrow(expr);
     var toFuzzy = rules.functionTypeToFuzzyType(to);
+    bool callTearoff = false;
     FunctionType from;
     if (fromType is FunctionType) {
       from = fromType;
@@ -1125,48 +1115,50 @@
       from = rules.getCallMethodType(fromType);
       // Methods are always strict
       strict = true;
+      callTearoff = true;
     }
     if (from == null) {
-      return _FuzzyStatus.unrelated;
+      return null; // unrelated
     }
 
     var fromFuzzy = strict ? from : rules.functionTypeToFuzzyType(from);
 
     if (rules.isSubtypeOf(from, to)) {
-      // Sound subtype, so no fuzzy arrow warning
-      if (rules.isSubtypeOf(fromFuzzy, toFuzzy)) {
-        // No cast needed for fuzzy arrows
-        return _FuzzyStatus.noCastSound;
-      } else {
-        // Sound, but need cast because the from type
-        // is fuzzy, and the to type isn't.
-        return _FuzzyStatus.needsCastSound;
-      }
+      // Sound subtype, so no fuzzy arrow warning.
+      //
+      // However we may still need cast, because the from type is fuzzy and the
+      // to type isn't. Or if we have an call tearoff.
+      return callTearoff || !rules.isSubtypeOf(fromFuzzy, toFuzzy);
     }
 
     // If it's a subtype in the fuzzy system, don't cast, since we do
     // dynamic calls for the check.
     if (rules.isSubtypeOf(fromFuzzy, toFuzzy)) {
-      // A subtype in the fuzzy system, but reverse subtype in sound system
+      // A subtype in the fuzzy system, but reverse subtype in sound system.
       // This will eventually become a downcast (which will probably fail).
       // But for the transition, it is better to issue a fuzzy arrow hint
-      // since we still do the dynamic calls anyway
-      return _FuzzyStatus.noCastFuzzy;
+      // since we still do the dynamic calls anyway.
+      _recordMessage(
+          expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [fromType, to]);
+      return callTearoff;
     }
 
     if (rules.isSubtypeOf(to, from)) {
-      // Assignable in the sound system, but needs cast
+      // Assignable in the sound system, but needs cast.
+      //
       // Either unrelated in fuzzy system, or already a cast, so just cast
-      // and don't warn
-      return _FuzzyStatus.needsCastSound;
+      // and don't warn.
+      return true;
     }
 
     // Only assignable with fuzzy arrows, and it needs a cast
     if (rules.isSubtypeOf(toFuzzy, fromFuzzy)) {
-      return _FuzzyStatus.needsCastFuzzy;
+      _recordMessage(
+          expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [fromType, to]);
+      return true;
     }
 
-    return _FuzzyStatus.unrelated;
+    return null;
   }
 
   /// Returns true if we need an implicit cast of [expr] from [from] type to
@@ -1186,22 +1178,8 @@
     if (from.isVoid) return null;
 
     if (to is FunctionType) {
-      switch (_checkFuzzyStatus(expr, to, from)) {
-        case _FuzzyStatus.noCastFuzzy:
-          _recordMessage(
-              expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [from, to]);
-          return false;
-        case _FuzzyStatus.needsCastFuzzy:
-          _recordMessage(
-              expr, StrongModeCode.USES_DYNAMIC_AS_BOTTOM, [from, to]);
-          return true;
-        case _FuzzyStatus.noCastSound:
-          return false;
-        case _FuzzyStatus.needsCastSound:
-          return true;
-        default:
-          break;
-      }
+      bool needsCast = _checkFunctionTypeCasts(expr, to, from);
+      if (needsCast != null) return needsCast;
     }
 
     // fromT <: toT, no coercion needed.
@@ -1210,12 +1188,13 @@
     }
 
     // Down cast or legal sideways cast, coercion needed.
-    if (rules.isAssignableTo(from, to, isDeclarationCast: isDeclarationCast))
+    if (rules.isAssignableTo(from, to, isDeclarationCast: isDeclarationCast)) {
       return true;
+    }
 
     // Special case for FutureOr to handle returned values from async functions.
     // In this case, we're more permissive than assignability.
-    if (to.element == typeProvider.futureOrType.element) {
+    if (to.isDartAsyncFutureOr) {
       var to1 = (to as InterfaceType).typeArguments[0];
       var to2 = typeProvider.futureType.instantiate([to1]);
       return _needsImplicitCast(expr, to1, from: from) == true ||
@@ -1259,6 +1238,16 @@
       return;
     }
 
+    // If this is an implicit tearoff, we need to mark the cast, but we don't
+    // want to warn if it's a legal subtype.
+    if (from is InterfaceType && rules.acceptsFunctionType(to)) {
+      var type = rules.getCallMethodType(from);
+      if (type != null && rules.isSubtypeOf(type, to)) {
+        _markImplicitCast(expr, to, opAssign: opAssign);
+        return;
+      }
+    }
+
     // Inference "casts":
     if (expr is Literal) {
       // fromT should be an exact type - this will almost certainly fail at
diff --git a/pkg/analyzer/lib/src/task/yaml.dart b/pkg/analyzer/lib/src/task/yaml.dart
index 2ac731d..acbb550 100644
--- a/pkg/analyzer/lib/src/task/yaml.dart
+++ b/pkg/analyzer/lib/src/task/yaml.dart
@@ -144,8 +144,8 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const YamlErrorCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const YamlErrorCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/analyzer/test/dart/ast/ast_test.dart b/pkg/analyzer/test/dart/ast/ast_test.dart
index 122f18d..9ba443a 100644
--- a/pkg/analyzer/test/dart/ast/ast_test.dart
+++ b/pkg/analyzer/test/dart/ast/ast_test.dart
@@ -8,8 +8,11 @@
 import 'package:analyzer/dart/ast/standard_ast_factory.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
+import 'package:analyzer/src/dart/scanner/scanner.dart';
+import 'package:analyzer/src/generated/parser.dart';
 import 'package:analyzer/src/generated/testing/ast_test_factory.dart';
 import 'package:analyzer/src/generated/testing/token_factory.dart';
+import 'package:analyzer/src/string_source.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -25,6 +28,7 @@
     defineReflectiveTests(IndexExpressionTest);
     defineReflectiveTests(MethodDeclarationTest);
     defineReflectiveTests(NodeListTest);
+    defineReflectiveTests(PreviousTokenTest);
     defineReflectiveTests(SimpleIdentifierTest);
     defineReflectiveTests(SimpleStringLiteralTest);
     defineReflectiveTests(StringInterpolationTest);
@@ -604,6 +608,105 @@
 }
 
 @reflectiveTest
+class PreviousTokenTest {
+  static final String contents = '''
+class A {
+  B foo(C c) {
+    return bar;
+  }
+  D get baz => null;
+}
+E f() => g;
+''';
+
+  CompilationUnit _unit;
+
+  CompilationUnit get unit {
+    if (_unit == null) {
+      GatheringErrorListener listener =
+          new GatheringErrorListener(checkRanges: true);
+      var source =
+          new StringSource(contents, 'PreviousTokenTest_findPrevious.dart');
+      Token tokens = new Scanner.fasta(source, listener).tokenize();
+      _unit = new Parser(source, listener, useFasta: true)
+          .parseCompilationUnit(tokens);
+    }
+    return _unit;
+  }
+
+  Token findToken(String lexeme) {
+    Token token = unit.beginToken;
+    while (!token.isEof) {
+      if (token.lexeme == lexeme) {
+        return token;
+      }
+      token = token.next;
+    }
+    fail('Failed to find $lexeme');
+  }
+
+  void test_findPrevious_basic_class() {
+    ClassDeclaration clazz = unit.declarations[0];
+    expect(clazz.findPrevious(findToken('A')).lexeme, 'class');
+  }
+
+  void test_findPrevious_basic_method() {
+    ClassDeclaration clazz = unit.declarations[0];
+    MethodDeclaration method = clazz.members[0];
+    expect(method.findPrevious(findToken('foo')).lexeme, 'B');
+  }
+
+  void test_findPrevious_basic_statement() {
+    ClassDeclaration clazz = unit.declarations[0];
+    MethodDeclaration method = clazz.members[0];
+    BlockFunctionBody body = method.body;
+    Statement statement = body.block.statements[0];
+    expect(statement.findPrevious(findToken('bar')).lexeme, 'return');
+    expect(statement.findPrevious(findToken(';')).lexeme, 'bar');
+  }
+
+  void test_findPrevious_missing() {
+    ClassDeclaration clazz = unit.declarations[0];
+    MethodDeclaration method = clazz.members[0];
+    BlockFunctionBody body = method.body;
+    Statement statement = body.block.statements[0];
+
+    GatheringErrorListener listener =
+        new GatheringErrorListener(checkRanges: true);
+    var source = new StringSource('missing', 'PreviousTokenTest_missing.dart');
+    Token missing = new Scanner.fasta(source, listener).tokenize();
+
+    expect(statement.findPrevious(missing), null);
+    expect(statement.findPrevious(null), null);
+  }
+
+  void test_findPrevious_parent_method() {
+    ClassDeclaration clazz = unit.declarations[0];
+    MethodDeclaration method = clazz.members[0];
+    expect(method.findPrevious(findToken('B')).lexeme, '{');
+  }
+
+  void test_findPrevious_parent_statement() {
+    ClassDeclaration clazz = unit.declarations[0];
+    MethodDeclaration method = clazz.members[0];
+    BlockFunctionBody body = method.body;
+    Statement statement = body.block.statements[0];
+    expect(statement.findPrevious(findToken('return')).lexeme, '{');
+  }
+
+  void test_findPrevious_sibling_method() {
+    ClassDeclaration clazz = unit.declarations[0];
+    MethodDeclaration method = clazz.members[1];
+    expect(method.findPrevious(findToken('D')).lexeme, '}');
+  }
+
+  void test_findPrevious_sibling_class() {
+    CompilationUnitMember declaration = unit.declarations[1];
+    expect(declaration.findPrevious(findToken('E')).lexeme, '}');
+  }
+}
+
+@reflectiveTest
 class SimpleIdentifierTest extends ParserTestCase {
   void test_inGetterContext() {
     for (_WrapperKind wrapper in _WrapperKind.values) {
diff --git a/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
index d02bde0..270773f 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_driver_test.dart
@@ -31,4 +31,7 @@
   @override // Passes with driver
   test_infer_mixin_with_substitution_functionType() =>
       super.test_infer_mixin_with_substitution_functionType();
+
+  @override // Passes with driver
+  test_issue_32394() => super.test_issue_32394();
 }
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index 14a43d8..6ef150d 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -3619,6 +3619,26 @@
     verify([source]);
   }
 
+  @failingTest // Fails with the old task model
+  test_issue_32394() async {
+    Source source = addSource('''
+var x = y.map((a) => a.toString());
+var y = [3];
+var z = x.toList();
+
+void main() {
+  String p = z;
+}
+''');
+    var result = await computeAnalysisResult(source);
+    var z = result.unit.element.topLevelVariables
+        .where((e) => e.name == 'z')
+        .single;
+    expect(z.type.toString(), 'List<String>');
+    assertErrors(source, [StaticTypeWarningCode.INVALID_ASSIGNMENT]);
+    verify([source]);
+  }
+
   test_listElementTypeNotAssignable() async {
     Source source = addSource(r'''
 var v1 = <int> [42];
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 18fa2ba..ef46fe2 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -15196,6 +15196,77 @@
     expect(statement.finallyBlock, isNull);
   }
 
+  void test_parseTryStatement_catch_error_missingCatchParam() {
+    var statement = parseStatement('try {} catch () {}') as TryStatement;
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.CATCH_SYNTAX, 14, 1)]
+        : [
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 14, 1),
+          ]);
+    expect(statement.tryKeyword, isNotNull);
+    expect(statement.body, isNotNull);
+    NodeList<CatchClause> catchClauses = statement.catchClauses;
+    expect(catchClauses, hasLength(1));
+    CatchClause clause = catchClauses[0];
+    expect(clause.onKeyword, isNull);
+    expect(clause.exceptionType, isNull);
+    expect(clause.catchKeyword, isNotNull);
+    expect(clause.exceptionParameter, isNotNull);
+    expect(clause.comma, isNull);
+    expect(clause.stackTraceParameter, isNull);
+    expect(clause.body, isNotNull);
+    expect(statement.finallyKeyword, isNull);
+    expect(statement.finallyBlock, isNull);
+  }
+
+  void test_parseTryStatement_catch_error_missingCatchTrace() {
+    var statement = parseStatement('try {} catch (e,) {}') as TryStatement;
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.CATCH_SYNTAX, 14, 1)]
+        : [
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 14, 1),
+          ]);
+    expect(statement.tryKeyword, isNotNull);
+    expect(statement.body, isNotNull);
+    NodeList<CatchClause> catchClauses = statement.catchClauses;
+    expect(catchClauses, hasLength(1));
+    CatchClause clause = catchClauses[0];
+    expect(clause.onKeyword, isNull);
+    expect(clause.exceptionType, isNull);
+    expect(clause.catchKeyword, isNotNull);
+    expect(clause.exceptionParameter, isNotNull);
+    expect(clause.comma, isNotNull);
+    expect(clause.stackTraceParameter, isNotNull);
+    expect(clause.body, isNotNull);
+    expect(statement.finallyKeyword, isNull);
+    expect(statement.finallyBlock, isNull);
+  }
+
+  void test_parseTryStatement_catch_error_missingCatchParen() {
+    var statement = parseStatement('try {} catch {}') as TryStatement;
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.CATCH_SYNTAX, 13, 1)]
+        : [
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 13, 1),
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 13, 1),
+            expectedError(ParserErrorCode.EXPECTED_TOKEN, 13, 1)
+          ]);
+    expect(statement.tryKeyword, isNotNull);
+    expect(statement.body, isNotNull);
+    NodeList<CatchClause> catchClauses = statement.catchClauses;
+    expect(catchClauses, hasLength(1));
+    CatchClause clause = catchClauses[0];
+    expect(clause.onKeyword, isNull);
+    expect(clause.exceptionType, isNull);
+    expect(clause.catchKeyword, isNotNull);
+    expect(clause.exceptionParameter, isNotNull);
+    expect(clause.comma, isNull);
+    expect(clause.stackTraceParameter, isNull);
+    expect(clause.body, isNotNull);
+    expect(statement.finallyKeyword, isNull);
+    expect(statement.finallyBlock, isNull);
+  }
+
   void test_parseTryStatement_catch_finally() {
     var statement =
         parseStatement('try {} catch (e, s) {} finally {}') as TryStatement;
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index df74bd4..da90947 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -189,6 +189,15 @@
     _checkLeastUpperBound(type1, type2, expected);
   }
 
+  void test_typeParam_class_implements_Function() {
+    DartType typeA = ElementFactory.classElement('A', functionType).type;
+    TypeParameterElementImpl typeParamElement =
+        ElementFactory.typeParameterElement('T');
+    typeParamElement.bound = typeA;
+    DartType typeParam = typeParamElement.type;
+    _checkLeastUpperBound(typeParam, simpleFunctionType, functionType);
+  }
+
   /// Check least upper bound of the same class with different type parameters.
   void test_typeParameters_different() {
     // class List<int>
@@ -501,10 +510,9 @@
   }
 
   void test_typeParam_function_bounded() {
-    DartType typeA = ElementFactory.classElement('A', functionType).type;
     TypeParameterElementImpl typeParamElement =
         ElementFactory.typeParameterElement('T');
-    typeParamElement.bound = typeA;
+    typeParamElement.bound = functionType;
     DartType typeParam = typeParamElement.type;
     _checkLeastUpperBound(typeParam, simpleFunctionType, functionType);
   }
@@ -1551,6 +1559,15 @@
     _checkLeastUpperBound(typeParamT, typeParamS, typeParamS);
   }
 
+  void test_typeParam_class_implements_Function_ignored() {
+    DartType typeA = ElementFactory.classElement('A', functionType).type;
+    TypeParameterElementImpl typeParamElement =
+        ElementFactory.typeParameterElement('T');
+    typeParamElement.bound = typeA;
+    DartType typeParam = typeParamElement.type;
+    _checkLeastUpperBound(typeParam, simpleFunctionType, objectType);
+  }
+
   void test_typeParam_fBounded() {
     ClassElementImpl AClass = ElementFactory.classElement2('A', ["Q"]);
     InterfaceType AType = AClass.type;
@@ -1602,9 +1619,10 @@
   InterfaceType get objectType => typeProvider.objectType;
   InterfaceType get stringType => typeProvider.stringType;
   DartType get voidType => VoidTypeImpl.instance;
+  InterfaceType get futureOrType => typeProvider.futureOrType;
 
   void setUp() {
-    typeProvider = new TestTypeProvider();
+    typeProvider = AnalysisContextFactory.contextWithCore().typeProvider;
     typeSystem = new StrongTypeSystemImpl(typeProvider);
   }
 
@@ -1634,7 +1652,7 @@
         TypeBuilder.function(required: <DartType>[intType], result: objectType);
     InterfaceType bottom = classBottom.type;
 
-    _checkIsStrictSubtypeOf(bottom, top);
+    _checkIsNotSubtypeOf(bottom, top);
   }
 
   void test_classes() {
@@ -1689,6 +1707,26 @@
     _checkGroups(voidType, equivalents: equivalents, subtypes: subtypes);
   }
 
+  void test_function_subtypes_itself_top_types() {
+    var tops = [dynamicType, objectType, voidType];
+    // Add FutureOr<T> for T := dynamic, object, void
+    tops.addAll(tops.map((t) => futureOrType.instantiate([t])).toList());
+    // Add FutureOr<FutureOr<T>> for T := dynamic, object, void
+    tops.addAll(
+        tops.skip(3).map((t) => futureOrType.instantiate([t])).toList());
+
+    // Function should subtype all of those top types.
+    _checkGroups(functionType, supertypes: [
+      dynamicType,
+      objectType,
+      voidType,
+    ]);
+
+    // Create a non-identical but equal copy of Function, and verify subtyping
+    var copyOfFunction = new InterfaceTypeImpl(functionType.element, null);
+    _checkEquivalent(functionType, copyOfFunction);
+  }
+
   void test_genericFunction_generic_monomorphic() {
     DartType s = TypeBuilder.variable("S");
     DartType t = TypeBuilder.variable("T", bound: s);
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 32df76a..887b208 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -7844,6 +7844,28 @@
     expect(driver.knownFiles, isNot(contains(b)));
   }
 
+  test_missingDartLibrary_async() async {
+    provider.getFile(_p(MockSdk.FULL_URI_MAP['dart:async'])).delete();
+    addTestFile('class C {}');
+
+    ErrorsResult result = await driver.getErrors(testFile);
+    expect(result.errors, hasLength(1));
+
+    AnalysisError error = result.errors[0];
+    expect(error.errorCode, CompileTimeErrorCode.MISSING_DART_LIBRARY);
+  }
+
+  test_missingDartLibrary_core() async {
+    provider.getFile(_p(MockSdk.FULL_URI_MAP['dart:core'])).delete();
+    addTestFile('class C {}');
+
+    ErrorsResult result = await driver.getErrors(testFile);
+    expect(result.errors, hasLength(1));
+
+    AnalysisError error = result.errors[0];
+    expect(error.errorCode, CompileTimeErrorCode.MISSING_DART_LIBRARY);
+  }
+
   test_parseFile_notAbsolutePath() async {
     try {
       await driver.parseFile('not_absolute.dart');
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
index 8b7046d..af85dc1 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
@@ -53,23 +53,19 @@
           new TestDescriptor(
               'catch',
               'try {} catch',
-              [
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
+              [ParserErrorCode.CATCH_SYNTAX, ParserErrorCode.EXPECTED_TOKEN],
               "try {} catch (e) {}",
-              allFailing: true),
+              failing: ['block']),
           new TestDescriptor(
               'catch_leftParen',
               'try {} catch (',
               [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
+                ScannerErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.CATCH_SYNTAX,
                 ParserErrorCode.EXPECTED_TOKEN
               ],
               "try {} catch (e) {}",
-              allFailing: true),
+              failing: allExceptEof),
           new TestDescriptor(
               'catch_identifier',
               'try {} catch (e',
@@ -80,12 +76,12 @@
               'catch_identifierComma',
               'try {} catch (e, ',
               [
-                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.CATCH_SYNTAX,
                 ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN
+                ScannerErrorCode.EXPECTED_TOKEN
               ],
               "try {} catch (e, _s_) {}",
-              allFailing: true),
+              failing: allExceptEof),
           new TestDescriptor(
               'catch_identifierCommaIdentifier',
               'try {} catch (e, s',
@@ -101,23 +97,19 @@
           new TestDescriptor(
               'on_catch',
               'try {} on A catch',
-              [
-                ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ],
+              [ParserErrorCode.CATCH_SYNTAX, ParserErrorCode.EXPECTED_TOKEN],
               "try {} on A catch (e) {}",
-              allFailing: true),
+              failing: ['block']),
           new TestDescriptor(
               'on_catch_leftParen',
               'try {} on A catch (',
               [
-                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.CATCH_SYNTAX,
                 ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN
+                ScannerErrorCode.EXPECTED_TOKEN
               ],
               "try {} on A catch (e) {}",
-              allFailing: true),
+              failing: allExceptEof),
           new TestDescriptor(
               'on_catch_identifier',
               'try {} on A catch (e',
@@ -128,12 +120,12 @@
               'on_catch_identifierComma',
               'try {} on A catch (e, ',
               [
-                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.CATCH_SYNTAX,
                 ParserErrorCode.EXPECTED_TOKEN,
-                ParserErrorCode.EXPECTED_TOKEN
+                ScannerErrorCode.EXPECTED_TOKEN
               ],
               "try {} on A catch (e, _s_) {}",
-              allFailing: true),
+              failing: allExceptEof),
           new TestDescriptor(
               'on_catch_identifierCommaIdentifier',
               'try {} on A catch (e, s',
diff --git a/pkg/analyzer/test/src/fasta/token_utils_test.dart b/pkg/analyzer/test/src/fasta/token_utils_test.dart
new file mode 100644
index 0000000..03f057d
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/token_utils_test.dart
@@ -0,0 +1,37 @@
+// 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 'package:analyzer/src/fasta/token_utils.dart';
+import 'package:front_end/src/fasta/scanner.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PreviousTokenTest);
+  });
+}
+
+@reflectiveTest
+class PreviousTokenTest {
+  void test_findPrevious() {
+    Token a =
+        scanString('a b c /* comment */ d e', includeComments: true).tokens;
+    Token b = a.next;
+    Token c = b.next;
+    Token d = c.next;
+    Token e = d.next;
+
+    expect(findPrevious(a, b), a);
+    expect(findPrevious(a, c), b);
+    expect(findPrevious(a, d), c);
+    expect(findPrevious(d.precedingComments, e), d);
+
+    Token x = scanString('x').tokens;
+    expect(findPrevious(a, x), null);
+    expect(findPrevious(b, b), null);
+    expect(findPrevious(d, b), null);
+    expect(findPrevious(a, null), null);
+  }
+}
diff --git a/pkg/analyzer/test/src/summary/expr_builder_test.dart b/pkg/analyzer/test/src/summary/expr_builder_test.dart
index 9e8237f..7382339 100644
--- a/pkg/analyzer/test/src/summary/expr_builder_test.dart
+++ b/pkg/analyzer/test/src/summary/expr_builder_test.dart
@@ -93,20 +93,21 @@
         requireValidConst: true);
   }
 
-  void checkSimpleExpression(String expressionText,
+  Expression checkSimpleExpression(String expressionText,
       {String expectedText,
       String extraDeclarations: '',
       bool requireValidConst: false}) {
-    checkTopLevelVariable('var x = $expressionText;\n$extraDeclarations',
+    return checkTopLevelVariable('var x = $expressionText;\n$extraDeclarations',
         expectedText ?? expressionText,
         requireValidConst: requireValidConst);
   }
 
-  void checkTopLevelVariable(String sourceText, String expectedText,
+  Expression checkTopLevelVariable(String sourceText, String expectedText,
       {String variableName: 'x', bool requireValidConst: false}) {
     Expression expr = buildTopLevelVariable(sourceText,
         variableName: variableName, requireValidConst: requireValidConst);
     expect(expr.toString(), expectedText);
+    return expr;
   }
 
   TestSummaryResynthesizer encodeSource(String text) {
@@ -160,6 +161,10 @@
     checkSimpleExpression('y = 0', extraDeclarations: 'var y;');
   }
 
+  void test_await() {
+    checkSimpleExpression('() async => await 0');
+  }
+
   void test_bitAnd() {
     checkSimpleExpression('0 & 1');
   }
@@ -322,6 +327,14 @@
         requireValidConst: true);
   }
 
+  void test_invokeConstructor_generic_hasTypeArguments() {
+    checkSimpleExpression('new Map<int, List<String>>()');
+  }
+
+  void test_invokeConstructor_generic_noTypeArguments() {
+    checkSimpleExpression('new Map()');
+  }
+
   void test_invokeMethod() {
     checkSimpleExpression('new C().foo(1, 2)', extraDeclarations: r'''
 class C {
@@ -330,6 +343,14 @@
 ''');
   }
 
+  void test_invokeMethod_namedArguments() {
+    checkSimpleExpression('new C().foo(a: 1, c: 3)', extraDeclarations: r'''
+class C {
+  int foo({int a, int b, int c}) => 0;
+}
+''');
+  }
+
   void test_invokeMethod_typeArguments() {
     checkSimpleExpression('new C().foo<int, double>(1, 2.3)',
         extraDeclarations: r'''
@@ -412,14 +433,68 @@
     checkSimpleExpression('() => 0');
   }
 
+  void test_pushLocalFunctionReference_async() {
+    checkSimpleExpression('() async => 0');
+  }
+
+  void test_pushLocalFunctionReference_block() {
+    checkSimpleExpression('() {}');
+  }
+
   void test_pushLocalFunctionReference_namedParam_untyped() {
     checkSimpleExpression('({x}) => 0');
   }
 
+  void test_pushLocalFunctionReference_nested() {
+    var expr =
+        checkSimpleExpression('(x) => (y) => x + y') as FunctionExpression;
+    var outerFunctionElement = expr.element;
+    var xElement = outerFunctionElement.parameters[0];
+    var x = expr.parameters.parameters[0];
+    expect(x.element, same(xElement));
+    var outerBody = expr.body as ExpressionFunctionBody;
+    var outerBodyExpr = outerBody.expression as FunctionExpression;
+    var innerFunctionElement = outerBodyExpr.element;
+    var yElement = innerFunctionElement.parameters[0];
+    var y = outerBodyExpr.parameters.parameters[0];
+    expect(y.element, same(yElement));
+    var innerBody = outerBodyExpr.body as ExpressionFunctionBody;
+    var innerBodyExpr = innerBody.expression as BinaryExpression;
+    var xRef = innerBodyExpr.leftOperand as SimpleIdentifier;
+    var yRef = innerBodyExpr.rightOperand as SimpleIdentifier;
+    expect(xRef.staticElement, same(xElement));
+    expect(yRef.staticElement, same(yElement));
+  }
+
+  void test_pushLocalFunctionReference_paramReference() {
+    var expr = checkSimpleExpression('(x, y) => x + y') as FunctionExpression;
+    var localFunctionElement = expr.element;
+    var xElement = localFunctionElement.parameters[0];
+    var yElement = localFunctionElement.parameters[1];
+    var x = expr.parameters.parameters[0];
+    var y = expr.parameters.parameters[1];
+    expect(x.element, same(xElement));
+    expect(y.element, same(yElement));
+    var body = expr.body as ExpressionFunctionBody;
+    var bodyExpr = body.expression as BinaryExpression;
+    var xRef = bodyExpr.leftOperand as SimpleIdentifier;
+    var yRef = bodyExpr.rightOperand as SimpleIdentifier;
+    expect(xRef.staticElement, same(xElement));
+    expect(yRef.staticElement, same(yElement));
+  }
+
   void test_pushLocalFunctionReference_positionalParam_untyped() {
     checkSimpleExpression('([x]) => 0');
   }
 
+  void test_pushLocalFunctionReference_requiredParam_typed() {
+    var expr = checkSimpleExpression('(int x) => 0', expectedText: '(x) => 0')
+        as FunctionExpression;
+    var functionElement = expr.element;
+    var xElement = functionElement.parameters[0] as ParameterElementImpl;
+    expect(xElement.type.toString(), 'int');
+  }
+
   void test_pushLocalFunctionReference_requiredParam_untyped() {
     checkSimpleExpression('(x) => 0');
   }
@@ -445,6 +520,18 @@
     checkSimpleExpression('int');
   }
 
+  void test_pushReference_sequence() {
+    checkSimpleExpression('a.b.f', extraDeclarations: r'''
+var a = new A();
+class A {
+  B b = new B();
+}
+class B {
+  int f = 0;
+}
+''');
+  }
+
   void test_pushString() {
     checkSimpleExpression("'foo'");
   }
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index 6d5ba24..c2d48fe 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -339,7 +339,7 @@
 ''');
     LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
     expect(_getVariable(library.getContainedName('y')).inferredType.toString(),
-        '() → dynamic');
+        '() → Null');
   }
 
   void test_inferredType_closure_fromBundle_identifierSequence() {
@@ -399,7 +399,7 @@
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.fields, hasLength(1));
     var field = cls.fields[0];
-    expect(field.type.toString(), '(<bottom>) → dynamic');
+    expect(field.type.toString(), '(<bottom>) → int');
   }
 
   void test_inferredType_instanceField_dynamic() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 3763f67..a0c0970 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -2919,25 +2919,11 @@
 class C {}
 const V = const C.named();
 ''', allowErrors: true);
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C {
 }
 const dynamic V = #invalidConst;
 ''');
-    } else if (isStrongMode) {
-      checkElementText(library, r'''
-class C {
-}
-const C V = #invalidConst;
-''');
-    } else {
-      checkElementText(library, r'''
-class C {
-}
-const dynamic V = #invalidConst;
-''');
-    }
   }
 
   test_const_invokeConstructor_named_unresolved2() async {
@@ -2960,22 +2946,10 @@
 import 'a.dart' as p;
 const V = const p.C.named();
 ''', allowErrors: true);
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 import 'a.dart' as p;
 const dynamic V = #invalidConst;
 ''');
-    } else if (isStrongMode) {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const C V = #invalidConst;
-''');
-    } else {
-      checkElementText(library, r'''
-import 'a.dart' as p;
-const dynamic V = #invalidConst;
-''');
-    }
   }
 
   test_const_invokeConstructor_named_unresolved4() async {
@@ -3007,25 +2981,11 @@
 class C<T> {}
 const V = const C.named();
 ''', allowErrors: true);
-    if (isSharedFrontEnd) {
-      checkElementText(library, r'''
+    checkElementText(library, r'''
 class C<T> {
 }
 const dynamic V = #invalidConst;
 ''');
-    } else if (isStrongMode) {
-      checkElementText(library, r'''
-class C<T> {
-}
-const C<dynamic> V = #invalidConst;
-''');
-    } else {
-      checkElementText(library, r'''
-class C<T> {
-}
-const dynamic V = #invalidConst;
-''');
-    }
   }
 
   test_const_invokeConstructor_unnamed() async {
@@ -6455,6 +6415,19 @@
 ''');
   }
 
+  @failingTest
+  test_implicitConstructor_named_const() async {
+    // TODO(paulberry, scheglov): get this to pass
+    var library = await checkLibrary('''
+class C {
+  final Object x;
+  const C.named(this.x);
+}
+const x = C.named(42);
+''');
+    checkElementText(library, 'TODO(paulberry, scheglov)');
+  }
+
   test_implicitTopLevelVariable_getterFirst() async {
     var library =
         await checkLibrary('int get x => 0; void set x(int value) {}');
@@ -6633,6 +6606,195 @@
 ''');
   }
 
+  @failingTest
+  void test_infer_generic_typedef_complex() async {
+    // TODO(paulberry, scheglov): get this test to pass.
+    var library = await checkLibrary('''
+typedef F<T> = D<T,U> Function<U>();
+class C<V> {
+  const C(F<V> f);
+}
+class D<T,U> {}
+D<int,U> f<U>() => null;
+const x = const C(f);
+''');
+    checkElementText(library, '''TODO(paulberry, scheglov)''');
+  }
+
+  void test_infer_generic_typedef_simple() async {
+    var library = await checkLibrary('''
+typedef F = D<T> Function<T>();
+class C {
+  const C(F f);
+}
+class D<T> {}
+D<T> f<T>() => null;
+const x = const C(f);
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+typedef F = D<T> Function<T>();
+class C {
+  const C(<T>() → D<T> f);
+}
+class D<T> {
+}
+const C x = const
+        C/*location: test.dart;C*/(
+        f/*location: test.dart;f*/);
+D<T> f<T>() {}
+''');
+    } else {
+      checkElementText(library, '''
+typedef F = D<T> Function<T>();
+class C {
+  const C(<T>() → D<T> f);
+}
+class D<T> {
+}
+const dynamic x = const
+        C/*location: test.dart;C*/(
+        f/*location: test.dart;f*/);
+D<T> f<T>() {}
+''');
+    }
+  }
+
+  test_infer_instanceCreation_fromArguments() async {
+    var library = await checkLibrary('''
+class A {}
+
+class B extends A {}
+
+class S<T extends A> {
+  S(T _);
+}
+
+var s = new S(new B());
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+class A {
+}
+class B extends A {
+}
+class S<T extends A> {
+  S(T _);
+}
+S<B> s;
+''');
+    } else {
+      checkElementText(library, '''
+class A {
+}
+class B extends A {
+}
+class S<T extends A> {
+  S(T _);
+}
+dynamic s;
+''');
+    }
+  }
+
+  test_infer_property_set() async {
+    var library = await checkLibrary('''
+class A {
+  B b;
+}
+class B {
+  C get c => null;
+  void set c(C value) {}
+}
+class C {}
+class D extends C {}
+var a = new A();
+var x = a.b.c ??= new D();
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+class A {
+  B b;
+}
+class B {
+  C get c {}
+  void set c(C value) {}
+}
+class C {
+}
+class D extends C {
+}
+A a;
+C x;
+''');
+    } else {
+      checkElementText(library, '''
+class A {
+  B b;
+}
+class B {
+  C get c {}
+  void set c(C value) {}
+}
+class C {
+}
+class D extends C {
+}
+dynamic a;
+dynamic x;
+''');
+    }
+  }
+
+  test_inference_issue_32394() async {
+    // Test the type inference involed in dartbug.com/32394
+    var library = await checkLibrary('''
+var x = y.map((a) => a.toString());
+var y = [3];
+var z = x.toList();
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+Iterable<String> x;
+List<int> y;
+List<String> z;
+''');
+    } else {
+      checkElementText(library, '''
+dynamic x;
+dynamic y;
+dynamic z;
+''');
+    }
+  }
+
+  test_inference_map() async {
+    var library = await checkLibrary('''
+class C {
+  int p;
+}
+var x = <C>[];
+var y = x.map((c) => c.p);
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+class C {
+  int p;
+}
+List<C> x;
+Iterable<int> y;
+''');
+    } else {
+      checkElementText(library, '''
+class C {
+  int p;
+}
+dynamic x;
+dynamic y;
+''');
+    }
+  }
+
   test_inferred_function_type_for_variable_in_generic_function() async {
     // In the code below, `x` has an inferred type of `() => int`, with 2
     // (unused) type parameters from the enclosing top level function.
@@ -9178,6 +9340,120 @@
 ''');
   }
 
+  test_type_inference_based_on_loadLibrary() async {
+    addLibrarySource('/a.dart', '');
+    var library = await checkLibrary('''
+import 'a.dart' deferred as a;
+var x = a.loadLibrary;
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+import 'a.dart' deferred as a;
+() → Future<dynamic> x;
+''');
+    } else {
+      checkElementText(library, '''
+import 'a.dart' deferred as a;
+dynamic x;
+''');
+    }
+  }
+
+  test_type_inference_closure_with_function_typed_parameter() async {
+    var library = await checkLibrary('''
+var x = (int f(String x)) => 0;
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+((String) → int) → int x;
+''');
+    } else {
+      checkElementText(library, '''
+dynamic x;
+''');
+    }
+  }
+
+  test_type_inference_closure_with_function_typed_parameter_new() async {
+    var library = await checkLibrary('''
+var x = (int Function(String) f) => 0;
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+((String) → int) → int x;
+''');
+    } else {
+      checkElementText(library, '''
+dynamic x;
+''');
+    }
+  }
+
+  test_type_inference_depends_on_exported_variable() async {
+    addLibrarySource('/a.dart', 'export "b.dart";');
+    addLibrarySource('/b.dart', 'var x = 0;');
+    var library = await checkLibrary('''
+import 'a.dart';
+var y = x;
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+import 'a.dart';
+int y;
+''');
+    } else {
+      checkElementText(library, '''
+import 'a.dart';
+dynamic y;
+''');
+    }
+  }
+
+  test_type_inference_nested_function() async {
+    var library = await checkLibrary('''
+var x = (t) => (u) => t + u;
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+(dynamic) → (dynamic) → dynamic x;
+''');
+    } else {
+      checkElementText(library, '''
+dynamic x;
+''');
+    }
+  }
+
+  test_type_inference_nested_function_with_parameter_types() async {
+    var library = await checkLibrary('''
+var x = (int t) => (int u) => t + u;
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+(int) → (int) → int x;
+''');
+    } else {
+      checkElementText(library, '''
+dynamic x;
+''');
+    }
+  }
+
+  test_type_inference_of_closure_with_default_value() async {
+    var library = await checkLibrary('''
+var x = ([y: 0]) => y;
+''');
+    if (isStrongMode) {
+      checkElementText(library, '''
+([dynamic]) → dynamic x;
+''');
+    } else {
+      checkElementText(library, '''
+dynamic x;
+''');
+    }
+  }
+
   test_type_invalid_topLevelVariableElement_asType() async {
     var library = await checkLibrary('''
 class C<T extends V> {}
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 50c157d..dc58944 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -673,7 +673,9 @@
     /*info:DYNAMIC_INVOKE*/f./*error:UNDEFINED_METHOD*/col(3);
   }
   {
-    A f = /*warning:USES_DYNAMIC_AS_BOTTOM*/new B();
+    A f = /*warning:USES_DYNAMIC_AS_BOTTOM,error:INVALID_CAST_NEW_EXPR*/new B();
+    B b = new B();
+    f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/b;
     int x;
     double y;
     x = /*info:DYNAMIC_CAST, info:DYNAMIC_INVOKE*/f(3);
@@ -686,7 +688,9 @@
     /*info:DYNAMIC_INVOKE*/g.col(42.0);
     /*info:DYNAMIC_INVOKE*/g.foo(42.0);
     /*info:DYNAMIC_INVOKE*/g.x;
-    A f = /*warning:USES_DYNAMIC_AS_BOTTOM*/new B();
+    A f = /*warning:USES_DYNAMIC_AS_BOTTOM, error:INVALID_CAST_NEW_EXPR*/new B();
+    B b = new B();
+    f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/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;
@@ -1335,9 +1339,9 @@
         f = d2i;
         f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2d;
         f = d2d;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/ci2i;
+        f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/ci2i;
         f = cd2i;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/ci2d;
+        f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/ci2d;
         f = cd2d;
       }
       {
@@ -1348,8 +1352,8 @@
         f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/d2d; // Fuzzy downcast
         f = ci2i;
         f = cd2i;
-        f = /*error:INVALID_ASSIGNMENT, info:DOWN_CAST_COMPOSITE*/ci2d;
-        f = /*error:INVALID_ASSIGNMENT*/cd2d;
+        f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
+        f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
       }
     }
   ''');
@@ -1391,8 +1395,8 @@
         f = /*warning:USES_DYNAMIC_AS_BOTTOM, info:DOWN_CAST_COMPOSITE*/d2d;
         f = ci2i;
         f = cd2i;
-        f = /*error:INVALID_ASSIGNMENT, info:DOWN_CAST_COMPOSITE*/ci2d;
-        f = /*error:INVALID_ASSIGNMENT*/cd2d;
+        f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
+        f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
       }
       { 
         int Function(dynamic) f;
@@ -1400,10 +1404,10 @@
         f = d2i;
         f = /*info:DOWN_CAST_COMPOSITE*/i2d;
         f = /*info:DOWN_CAST_COMPOSITE*/d2d;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/ci2i;
+        f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2i;
         f = cd2i;
-        f = /*error:INVALID_ASSIGNMENT, info:DOWN_CAST_COMPOSITE*/ci2d;
-        f = /*error:INVALID_ASSIGNMENT, info:DOWN_CAST_COMPOSITE*/cd2d;
+        f = /*info:DOWN_CAST_COMPOSITE*/ci2d;
+        f = /*info:DOWN_CAST_COMPOSITE*/cd2d;
       }
       { 
         dynamic Function(int) f;
@@ -1422,9 +1426,9 @@
         f = d2i;
         f = /*warning:USES_DYNAMIC_AS_BOTTOM*/i2d;
         f = d2d;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/ci2i;
+        f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2i;
         f = cd2i;
-        f = /*warning:USES_DYNAMIC_AS_BOTTOM*/ci2d;
+        f = /*warning:USES_DYNAMIC_AS_BOTTOM,info:DOWN_CAST_COMPOSITE*/ci2d;
         f = cd2d;
       }
     }
@@ -2031,7 +2035,7 @@
      f = /*error:INVALID_ASSIGNMENT*/i2i;
      f = /*error:INVALID_ASSIGNMENT*/n2n;
      f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/i2i as Object;
-     f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/n2n as Function;
+     f = /*info:UNNECESSARY_CAST,error:INVALID_ASSIGNMENT*/n2n as Function;
    }
    {
      B f;
@@ -2040,7 +2044,7 @@
      f = /*error:INVALID_ASSIGNMENT*/i2i;
      f = /*error:INVALID_ASSIGNMENT*/n2n;
      f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/i2i as Object;
-     f = /*info:UNNECESSARY_CAST,info:DOWN_CAST_IMPLICIT*/n2n as Function;
+     f = /*info:UNNECESSARY_CAST,error:INVALID_ASSIGNMENT*/n2n as Function;
    }
    {
      Function f;
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 9b51a72..f1c59c2 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -5,6 +5,7 @@
 // TODO(jmesserly): this file needs to be refactored, it's a port from
 // package:dev_compiler's tests
 import 'dart:async';
+import 'dart:collection';
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/standard_resolution_map.dart';
@@ -79,45 +80,45 @@
     List<AnalysisError> actualErrors) {
   var expectedErrors = _findExpectedErrors(unit.beginToken);
 
-  // Sort both lists: by offset, then level, then name.
-  actualErrors.sort((x, y) {
-    int delta = x.offset.compareTo(y.offset);
-    if (delta != 0) return delta;
-
-    delta = _errorSeverity(analysisOptions, x)
-        .compareTo(_errorSeverity(analysisOptions, y));
-    if (delta != 0) return delta;
-
-    return _errorCodeName(x.errorCode).compareTo(_errorCodeName(y.errorCode));
-  });
-  expectedErrors.sort((x, y) {
-    int delta = x.offset.compareTo(y.offset);
-    if (delta != 0) return delta;
-
-    delta = x.severity.compareTo(y.severity);
-    if (delta != 0) return delta;
-
-    return x.typeName.compareTo(y.typeName);
-  });
+  var actualMap = new SplayTreeMap<int, List<AnalysisError>>();
+  for (var e in actualErrors) {
+    actualMap.putIfAbsent(e.offset, () => []).add(e);
+  }
+  var expectedMap = new SplayTreeMap<int, List<_ErrorExpectation>>();
+  for (var e in expectedErrors) {
+    expectedMap.putIfAbsent(e.offset, () => []).add(e);
+  }
 
   // Categorize the differences, if any.
   var unreported = <_ErrorExpectation>[];
-  var different = <_ErrorExpectation, AnalysisError>{};
+  var different = <List<_ErrorExpectation>, List<AnalysisError>>{};
 
-  for (var expected in expectedErrors) {
-    AnalysisError actual = expected._removeMatchingActual(actualErrors);
-    if (actual != null) {
-      if (_errorSeverity(analysisOptions, actual) != expected.severity ||
-          _errorCodeName(actual.errorCode) != expected.typeName) {
-        different[expected] = actual;
+  expectedMap.forEach((offset, expectedList) {
+    var actualList = actualMap[offset] ?? [];
+
+    var unmatched = <_ErrorExpectation>[];
+    for (var expected in expectedList) {
+      var match = actualList.firstWhere(
+          (a) => expected.matches(analysisOptions, a),
+          orElse: () => null);
+      if (match != null) {
+        actualList.remove(match);
+        if (actualList.isEmpty) actualMap.remove(offset);
+      } else {
+        unmatched.add(expected);
       }
-    } else {
-      unreported.add(expected);
     }
-  }
+
+    if (actualList.isEmpty) {
+      unreported.addAll(unmatched);
+    } else if (unmatched.isNotEmpty) {
+      different[unmatched] = actualList;
+      actualMap.remove(offset);
+    }
+  });
 
   // Whatever is left was an unexpected error.
-  List<AnalysisError> unexpected = actualErrors;
+  List<AnalysisError> unexpected = actualMap.values.expand((a) => a).toList();
 
   if (unreported.isNotEmpty || unexpected.isNotEmpty || different.isNotEmpty) {
     _reportFailure(analysisOptions, unit, unreported, unexpected, different);
@@ -178,7 +179,7 @@
     CompilationUnit unit,
     List<_ErrorExpectation> unreported,
     List<AnalysisError> unexpected,
-    Map<_ErrorExpectation, AnalysisError> different) {
+    Map<List<_ErrorExpectation>, List<AnalysisError>> different) {
   // Get the source code. This reads the data again, but it's safe because
   // all tests use memory file system.
   var sourceCode =
@@ -195,15 +196,17 @@
         span.message(error.message);
   }
 
-  String formatExpectedError(_ErrorExpectation error) {
+  String formatExpectedError(_ErrorExpectation error, {bool showSource: true}) {
     int offset = error.offset;
+    var severity = error.severity.displayName;
+    var result = '@$offset $severity:${error.typeName}';
+    if (!showSource) return result;
     var span = _createSpanHelper(
         unit.lineInfo,
         offset,
         resolutionMap.elementDeclaredByCompilationUnit(unit).source,
         sourceCode);
-    var severity = error.severity.displayName;
-    return '@$offset $severity:${error.typeName}\n' + span.message('');
+    return '$result\n${span.message('')}';
   }
 
   var message = new StringBuffer();
@@ -220,8 +223,13 @@
   if (different.isNotEmpty) {
     message.writeln('Errors that were reported, but different than expected:');
     different.forEach((expected, actual) {
-      message.writeln('Expected: ' + formatExpectedError(expected));
-      message.writeln('Actual: ' + formatActualError(actual));
+      // The source location is the same for the expected and actual, so we only
+      // print it once.
+      message.writeln('Expected: ' +
+          expected
+              .map((e) => formatExpectedError(e, showSource: false))
+              .join(', '));
+      message.writeln('Actual: ' + actual.map(formatActualError).join(', '));
     });
     message.writeln();
   }
@@ -426,18 +434,13 @@
 
   _ErrorExpectation(this.offset, this.severity, this.typeName);
 
-  String toString() => '@$offset ${severity.displayName}: [$typeName]';
-
-  AnalysisError _removeMatchingActual(List<AnalysisError> actualErrors) {
-    for (var actual in actualErrors) {
-      if (actual.offset == offset) {
-        actualErrors.remove(actual);
-        return actual;
-      }
-    }
-    return null;
+  bool matches(AnalysisOptions options, AnalysisError e) {
+    return _errorSeverity(options, e) == severity &&
+        _errorCodeName(e.errorCode) == typeName;
   }
 
+  String toString() => '@$offset ${severity.displayName}: [$typeName]';
+
   static _ErrorExpectation parse(int offset, String descriptor) {
     descriptor = descriptor.trim();
     var tokens = descriptor.split(' ');
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 285f328..a901ed4 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -451,7 +451,7 @@
           hide: hide)
       ..addOption('x-package-warnings-prefix',
           help:
-              'Show warnings from package: imports that match the given prefix.',
+              'Show warnings from package: imports that match the given prefix (deprecated).',
           hide: hide)
       ..addFlag('enable-conditional-directives',
           help:
@@ -465,7 +465,7 @@
           negatable: false,
           hide: hide)
       ..addFlag('sdk-warnings',
-          help: 'Show warnings from SDK imports.',
+          help: 'Show warnings from SDK imports (deprecated).',
           defaultsTo: false,
           negatable: false,
           hide: hide)
@@ -482,7 +482,8 @@
       // TODO(brianwilkerson) Remove the following option after we're sure that
       // it's no longer being used.
       ..addFlag('enable-assert-initializers',
-          help: 'Enable parsing of asserts in constructor initializers.',
+          help:
+              'Enable parsing of asserts in constructor initializers (deprecated).',
           defaultsTo: null,
           negatable: false,
           hide: hide)
@@ -502,7 +503,7 @@
           negatable: false,
           hide: hide)
       ..addFlag('package-warnings',
-          help: 'Show warnings from package: imports.',
+          help: 'Show warnings from package: imports (deprecated).',
           defaultsTo: false,
           negatable: false,
           hide: hide)
@@ -513,7 +514,8 @@
           splitCommas: false,
           hide: hide)
       ..addFlag('use-cfe',
-          help: 'Enable the Dart 2.0 Common Front End implementation.',
+          help:
+              'Enable the Dart 2.0 Common Front End implementation (experimental).',
           defaultsTo: false,
           negatable: false,
           hide: hide)
diff --git a/pkg/analyzer_cli/test/mocks.dart b/pkg/analyzer_cli/test/mocks.dart
index 4231d3c..84bd9a3 100644
--- a/pkg/analyzer_cli/test/mocks.dart
+++ b/pkg/analyzer_cli/test/mocks.dart
@@ -70,6 +70,9 @@
   }
 
   @override
+  bool get isUnresolvedIdentifier => false;
+
+  @override
   String get message {
     throw new StateError('Unexpected invocation of message');
   }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 93f221e..8579f0e 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -165,7 +165,7 @@
       }
       for (var entity in containingNode.childEntities) {
         if (entity is Token) {
-          if (_isCandidateToken(entity, offset)) {
+          if (_isCandidateToken(containingNode, entity, offset)) {
             // Try to replace with a comment token.
             Token commentToken = _getContainingCommentToken(entity, offset);
             if (commentToken != null) {
@@ -184,7 +184,7 @@
           // If the last token in the node isn't a candidate target, then
           // neither the node nor any of its descendants can possibly be the
           // completion target, so we can skip the node entirely.
-          if (!_isCandidateToken(entity.endToken, offset)) {
+          if (!_isCandidateToken(containingNode, entity.endToken, offset)) {
             continue;
           }
 
@@ -278,14 +278,14 @@
     Token token = droppedToken ??
         (entity is AstNode ? (entity as AstNode).beginToken : entity);
     if (token != null && requestOffset < token.offset) {
-      token = token.previous;
+      token = containingNode.findPrevious(token);
     }
     if (token != null) {
       if (requestOffset == token.offset && !isKeywordOrIdentifier(token)) {
         // If the insertion point is at the beginning of the current token
         // and the current token is not an identifier
         // then check the previous token to see if it should be replaced
-        token = token.previous;
+        token = containingNode.findPrevious(token);
       }
       if (token != null && isKeywordOrIdentifier(token)) {
         if (token.offset <= requestOffset && requestOffset <= token.end) {
@@ -296,7 +296,7 @@
       if (token is StringToken) {
         SimpleStringLiteral uri =
             astFactory.simpleStringLiteral(token, token.lexeme);
-        Keyword keyword = token.previous?.keyword;
+        Keyword keyword = containingNode.findPrevious(token)?.keyword;
         if (keyword == Keyword.IMPORT ||
             keyword == Keyword.EXPORT ||
             keyword == Keyword.PART) {
@@ -318,7 +318,7 @@
   bool isDoubleOrIntLiteral() {
     var entity = this.entity;
     if (entity is Token) {
-      TokenType previousTokenType = entity.previous?.type;
+      TokenType previousTokenType = containingNode.findPrevious(entity)?.type;
       return previousTokenType == TokenType.DOUBLE ||
           previousTokenType == TokenType.INT;
     }
@@ -405,7 +405,8 @@
       }
       if (entity == argList.rightParenthesis) {
         // Parser ignores trailing commas
-        if (argList.rightParenthesis.previous?.lexeme == ',') {
+        Token previous = containingNode.findPrevious(argList.rightParenthesis);
+        if (previous?.lexeme == ',') {
           return args.length;
         }
         return args.length - 1;
@@ -508,7 +509,7 @@
     // candidate entity if its first token is.
     Token beginToken = node.beginToken;
     if (beginToken.type.isKeyword || beginToken.type == TokenType.IDENTIFIER) {
-      return _isCandidateToken(beginToken, offset);
+      return _isCandidateToken(node, beginToken, offset);
     }
 
     // Otherwise, the node is a candidate entity only if the offset is before
@@ -522,7 +523,7 @@
    * Determine whether [token] could possibly be the [entity] for a
    * [CompletionTarget] associated with the given [offset].
    */
-  static bool _isCandidateToken(Token token, int offset) {
+  static bool _isCandidateToken(AstNode node, Token token, int offset) {
     if (token == null) {
       return false;
     }
@@ -541,7 +542,7 @@
     }
     // If the current token is synthetic, then check the previous token
     // because it may have been dropped from the parse tree
-    Token previous = token.previous;
+    Token previous = node.findPrevious(token);
     if (offset < previous.end) {
       return true;
     } else if (offset == previous.end) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
index 8dc738c..acc3c41 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/optype.dart
@@ -335,7 +335,8 @@
         index = 0;
       } else if (entity == node.rightParenthesis) {
         // Parser ignores trailing commas
-        if (node.rightParenthesis.previous?.lexeme == ',') {
+        Token previous = node.findPrevious(node.rightParenthesis);
+        if (previous?.lexeme == ',') {
           index = node.arguments.length;
         } else {
           index = node.arguments.length - 1;
@@ -598,10 +599,13 @@
   @override
   void visitFormalParameterList(FormalParameterList node) {
     dynamic entity = this.entity;
-    if (entity is Token && entity.previous != null) {
-      TokenType type = entity.previous.type;
-      if (type == TokenType.OPEN_PAREN || type == TokenType.COMMA) {
-        optype.includeTypeNameSuggestions = true;
+    if (entity is Token) {
+      Token previous = node.findPrevious(entity);
+      if (previous != null) {
+        TokenType type = previous.type;
+        if (type == TokenType.OPEN_PAREN || type == TokenType.COMMA) {
+          optype.includeTypeNameSuggestions = true;
+        }
       }
     }
     // Handle default normal parameter just as a normal parameter.
@@ -844,7 +848,7 @@
         // identifier to be a keyword and inserts a synthetic identifier
         (node.identifier != null &&
             node.identifier.isSynthetic &&
-            identical(entity, node.identifier.beginToken.previous))) {
+            identical(entity, node.findPrevious(node.identifier.beginToken)))) {
       optype.isPrefixed = true;
       if (node.parent is TypeName && node.parent.parent is ConstructorName) {
         optype.includeConstructorSuggestions = true;
@@ -1031,9 +1035,11 @@
 
   bool _isEntityPrevTokenSynthetic() {
     Object entity = this.entity;
-    if (entity is AstNode &&
-        (entity.beginToken.previous?.isSynthetic ?? false)) {
-      return true;
+    if (entity is AstNode) {
+      Token previous = entity.findPrevious(entity.beginToken);
+      if (previous?.isSynthetic ?? false) {
+        return true;
+      }
     }
     return false;
   }
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 1c0c8d8..199973f 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -42,6 +42,9 @@
   /// front-end is the default.
   static const String useOldFrontend = '--use-old-frontend';
   static const String strongMode = '--strong';
+  static const String previewDart2 = '--preview-dart-2';
+  static const String omitImplicitChecks = '--omit-implicit-checks';
+
   static const String platformBinaries = '--platform-binaries=.+';
 
   static const String minify = '--minify';
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 1d15833..c1d77eb 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -127,6 +127,7 @@
   bool analyzeOnly = false;
   bool trustTypeAnnotations = false;
   bool checkedMode = false;
+  bool strongMode = false;
   List<String> hints = <String>[];
   bool verbose;
   bool throwOnError;
@@ -222,6 +223,11 @@
     passThrough(argument);
   }
 
+  void setStrongMode(_) {
+    strongMode = true;
+    passThrough(Flags.strongMode);
+  }
+
   void addInEnvironment(String argument) {
     int eqIndex = argument.indexOf('=');
     String name = argument.substring(2, eqIndex);
@@ -355,7 +361,9 @@
     new OptionHandler(Flags.useContentSecurityPolicy, passThrough),
     new OptionHandler(Flags.enableExperimentalMirrors, passThrough),
     new OptionHandler(Flags.enableAssertMessage, passThrough),
-    new OptionHandler(Flags.strongMode, passThrough),
+    new OptionHandler(Flags.strongMode, setStrongMode),
+    new OptionHandler(Flags.previewDart2, setStrongMode),
+    new OptionHandler(Flags.omitImplicitChecks, passThrough),
 
     // TODO(floitsch): remove conditional directives flag.
     // We don't provide the info-message yet, since we haven't publicly
@@ -433,9 +441,14 @@
     helpAndFail('Extra arguments: ${extra.join(" ")}');
   }
 
-  if (checkedMode && trustTypeAnnotations) {
-    helpAndFail("Option '${Flags.trustTypeAnnotations}' may not be used in "
-        "checked mode.");
+  if (trustTypeAnnotations) {
+    if (checkedMode) {
+      helpAndFail("Option '${Flags.trustTypeAnnotations}' may not be used in "
+          "checked mode.");
+    } else if (strongMode) {
+      hints.add("Option '--trust-type-annotations' is not available "
+          "in strong mode. Try usign '--omit-implicit-checks' instead.");
+    }
   }
 
   if (packageRoot != null && packageConfig != null) {
@@ -588,12 +601,12 @@
   -o <file>, --out=<file>
     Generate the output into <file>.
 
-  -c, --enable-checked-mode, --checked
-    Insert runtime type checks and enable assertions (checked mode).
-
   -m, --minify
     Generate minified output.
 
+  --enable-asserts
+    Enable assertions.
+
   -h, /h, /?, --help
     Display this message (add -v for information about all options).
 
@@ -656,16 +669,25 @@
     usually results in larger JavaScript files with faster startup.
     Note: the dart:mirrors library is not supported with this option.
 
+  --preview-dart-2
+    Preview of all Dart 2.0 semantics, this includes generic methods and strong
+    mode type checks.
+
+    This flag is mainly for early dogfooding and will be removed when all
+    features are shipped.
+
 The following advanced options can help reduce the size of the generated code,
 but they may cause programs to behave unexpectedly if assumptions are not met.
 Only turn on these flags if you have enough test coverage to ensure they are
 safe to use:
 
-  --trust-type-annotations
-    Assume that all types are correct. This option allows the compiler to drop
-    type checks and to rely on local type information for optimizations. Use
-    this option only if you have enough testing to ensure that your program
-    works in strong mode or checked mode.
+  --omit-implicit-checks
+    Omit implicit runtime checks, such as parameter checks and implicit
+    downcasts. These checks are included by default in strong mode. By
+    using this flag the checks are removed, however the compiler will assume
+    that all such checks were valid and may use this information for
+    optimizations. Use this option only if you have enough testing to ensure
+    that your program works with the checks.
 
   --trust-primitives
     Assume that operations on numbers, strings, and lists have valid inputs.
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 94bc615..dbe005f 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -342,13 +342,17 @@
               _collectTypeDependencies(type, elements);
               break;
             case TypeUseKind.IMPLICIT_CAST:
-              // TODO(johnniwinther): Collect implicit casts conditionally on
-              // `enableTypeAssertions`.
-              _collectTypeDependencies(type, elements);
+              if (compiler.options.implicitDowncastCheckPolicy.isEmitted) {
+                _collectTypeDependencies(type, elements);
+              }
               break;
             case TypeUseKind.PARAMETER_CHECK:
+              if (compiler.options.parameterCheckPolicy.isEmitted) {
+                _collectTypeDependencies(type, elements);
+              }
+              break;
             case TypeUseKind.CHECKED_MODE_CHECK:
-              if (compiler.options.enableTypeAssertions) {
+              if (compiler.options.assignmentCheckPolicy.isEmitted) {
                 _collectTypeDependencies(type, elements);
               }
               break;
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 753a4af..d91d8b3 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -77,8 +77,8 @@
   /// Is `true` if this type is the 'Object' type defined in 'dart:core'.
   bool get isObject => false;
 
-  /// Applies [f] to each occurence of a [ResolutionTypeVariableType] within
-  /// this type.
+  /// Applies [f] to each occurence of a [TypeVariableType] within this
+  /// type. This excludes function type variables, whether free or bound.
   void forEachTypeVariable(f(TypeVariableType variable)) {}
 
   /// Performs the substitution `[arguments[i]/parameters[i]]this`.
@@ -525,13 +525,15 @@
       this.typedefType);
 
   bool get containsTypeVariables {
-    return returnType.containsTypeVariables ||
+    return typeVariables.any((type) => type.bound.containsTypeVariables) ||
+        returnType.containsTypeVariables ||
         parameterTypes.any((type) => type.containsTypeVariables) ||
         optionalParameterTypes.any((type) => type.containsTypeVariables) ||
         namedParameterTypes.any((type) => type.containsTypeVariables);
   }
 
   void forEachTypeVariable(f(TypeVariableType variable)) {
+    typeVariables.forEach((type) => type.bound.forEachTypeVariable(f));
     returnType.forEachTypeVariable(f);
     parameterTypes.forEach((type) => type.forEachTypeVariable(f));
     optionalParameterTypes.forEach((type) => type.forEachTypeVariable(f));
@@ -1283,7 +1285,7 @@
           TypeVariableType typeVariable, DartType bound));
 
   /// Returns the [ClassEntity] which declares the type variables occurring in
-  // [type], or `null` if [type] does not contain type variables.
+  // [type], or `null` if [type] does not contain class type variables.
   static ClassEntity getClassContext(DartType type) {
     ClassEntity contextClass;
     type.forEachTypeVariable((TypeVariableType typeVariable) {
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index 0c2ff92..6fa0f01 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -357,13 +357,17 @@
         _registerIsCheck(type);
         break;
       case TypeUseKind.IMPLICIT_CAST:
-        // TODO(johnniwinther): Register implicit casts conditionally on
-        // `enableTypeAssertions`.
-        _registerIsCheck(type);
+        if (_options.implicitDowncastCheckPolicy.isEmitted) {
+          _registerIsCheck(type);
+        }
         break;
       case TypeUseKind.PARAMETER_CHECK:
+        if (_options.parameterCheckPolicy.isEmitted) {
+          _registerIsCheck(type);
+        }
+        break;
       case TypeUseKind.CHECKED_MODE_CHECK:
-        if (_options.enableTypeAssertions) {
+        if (_options.assignmentCheckPolicy.isEmitted) {
           _registerIsCheck(type);
         }
         break;
diff --git a/pkg/compiler/lib/src/inferrer/locals_handler.dart b/pkg/compiler/lib/src/inferrer/locals_handler.dart
index ac4592b..7b0736a 100644
--- a/pkg/compiler/lib/src/inferrer/locals_handler.dart
+++ b/pkg/compiler/lib/src/inferrer/locals_handler.dart
@@ -307,7 +307,7 @@
   void update(Local local, TypeInformation type, T node, DartType staticType,
       {bool isSetIfNull: false}) {
     assert(type != null);
-    if (options.trustTypeAnnotations || options.enableTypeAssertions) {
+    if (!options.assignmentCheckPolicy.isIgnored) {
       type = types.narrowType(type, staticType);
     }
     updateLocal() {
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index 725b37a..1ad7fc5 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -479,12 +479,12 @@
   }
 
   TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
-    if (!inferrer.options.trustTypeAnnotations &&
-        !inferrer.options.enableTypeAssertions &&
-        !inferrer.trustTypeAnnotations(_member)) {
-      return mask;
+    if (inferrer.options.assignmentCheckPolicy.isTrusted ||
+        inferrer.options.assignmentCheckPolicy.isEmitted ||
+        inferrer.trustTypeAnnotations(_member)) {
+      return _potentiallyNarrowType(mask, inferrer);
     }
-    return _potentiallyNarrowType(mask, inferrer);
+    return mask;
   }
 
   TypeMask _potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer);
@@ -787,15 +787,17 @@
   }
 
   TypeMask potentiallyNarrowType(TypeMask mask, InferrerEngine inferrer) {
-    if (!inferrer.options.trustTypeAnnotations &&
-        !inferrer.trustTypeAnnotations(_method)) {
-      return mask;
+    if (inferrer.options.parameterCheckPolicy.isTrusted ||
+        inferrer.trustTypeAnnotations(_method)) {
+      // When type assertions are enabled (aka checked mode), we have to always
+      // ignore type annotations to ensure that the checks are actually inserted
+      // into the function body and retained until runtime.
+      // TODO(sigmund): is this still applicable? investigate if we can use also
+      // narrow when isChecked is true.
+      assert(!inferrer.options.enableTypeAssertions);
+      return _narrowType(inferrer.closedWorld, mask, _type);
     }
-    // When type assertions are enabled (aka checked mode), we have to always
-    // ignore type annotations to ensure that the checks are actually inserted
-    // into the function body and retained until runtime.
-    assert(!inferrer.options.enableTypeAssertions);
-    return _narrowType(inferrer.closedWorld, mask, _type);
+    return mask;
   }
 
   TypeMask computeType(InferrerEngine inferrer) {
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 2cb5fcf..798fd5c 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -979,10 +979,8 @@
     _namer = determineNamer(closedWorld, codegenWorldBuilder);
     tracer = new Tracer(closedWorld, namer, compiler.outputProvider);
     _rtiEncoder = _namer.rtiEncoder = new RuntimeTypesEncoderImpl(
-        namer,
-        closedWorld.elementEnvironment,
-        closedWorld.commonElements,
-        compiler.options.strongMode);
+        namer, closedWorld.elementEnvironment, closedWorld.commonElements,
+        strongMode: compiler.options.strongMode);
     emitter.createEmitter(namer, closedWorld, codegenWorldBuilder, sorter);
     // TODO(johnniwinther): Share the impact object created in
     // createCodegenEnqueuer.
diff --git a/pkg/compiler/lib/src/js_backend/enqueuer.dart b/pkg/compiler/lib/src/js_backend/enqueuer.dart
index 92fa232..ae9ab20 100644
--- a/pkg/compiler/lib/src/js_backend/enqueuer.dart
+++ b/pkg/compiler/lib/src/js_backend/enqueuer.dart
@@ -187,13 +187,17 @@
         _registerIsCheck(type);
         break;
       case TypeUseKind.IMPLICIT_CAST:
-        // TODO(johnniwinther): Register implicit casts conditionally on
-        // `enableTypeAssertions`.
-        _registerIsCheck(type);
+        if (_options.implicitDowncastCheckPolicy.isEmitted) {
+          _registerIsCheck(type);
+        }
         break;
       case TypeUseKind.PARAMETER_CHECK:
+        if (_options.parameterCheckPolicy.isEmitted) {
+          _registerIsCheck(type);
+        }
+        break;
       case TypeUseKind.CHECKED_MODE_CHECK:
-        if (_options.enableTypeAssertions) {
+        if (_options.assignmentCheckPolicy.isEmitted) {
           _registerIsCheck(type);
         }
         break;
diff --git a/pkg/compiler/lib/src/js_backend/impact_transformer.dart b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
index 21b3be9..32282b9 100644
--- a/pkg/compiler/lib/src/js_backend/impact_transformer.dart
+++ b/pkg/compiler/lib/src/js_backend/impact_transformer.dart
@@ -170,13 +170,17 @@
           hasAsCast = true;
           break;
         case TypeUseKind.IMPLICIT_CAST:
-          // TODO(johnniwinther): Register implicit casts conditionally on
-          // `enableTypeAssertions`.
-          onIsCheck(type, transformed);
+          if (_options.implicitDowncastCheckPolicy.isEmitted) {
+            onIsCheck(type, transformed);
+          }
           break;
         case TypeUseKind.PARAMETER_CHECK:
+          if (_options.parameterCheckPolicy.isEmitted) {
+            onIsCheck(type, transformed);
+          }
+          break;
         case TypeUseKind.CHECKED_MODE_CHECK:
-          if (_options.enableTypeAssertions) {
+          if (_options.assignmentCheckPolicy.isEmitted) {
             onIsCheck(type, transformed);
           }
           break;
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index ff8e492..9cfe111 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -620,6 +620,14 @@
   /// is a FutureOr type.
   jsAst.Template get templateForIsFutureOrType;
 
+  /// Returns the JavaScript template to determine at runtime if a type object
+  /// is the void type.
+  jsAst.Template get templateForIsVoidType;
+
+  /// Returns the JavaScript template to determine at runtime if a type object
+  /// is the dynamic type.
+  jsAst.Template get templateForIsDynamicType;
+
   jsAst.Name get getFunctionThatReturnsNullName;
 
   /// Returns a [jsAst.Expression] representing the given [type]. Type variables
@@ -1792,10 +1800,11 @@
   final CommonElements commonElements;
   final TypeRepresentationGenerator _representationGenerator;
 
-  RuntimeTypesEncoderImpl(this.namer, this._elementEnvironment,
-      this.commonElements, bool strongMode)
+  RuntimeTypesEncoderImpl(
+      this.namer, this._elementEnvironment, this.commonElements,
+      {bool strongMode})
       : _representationGenerator =
-            new TypeRepresentationGenerator(namer, strongMode);
+            new TypeRepresentationGenerator(namer, strongMode: strongMode);
 
   @override
   bool isSimpleFunctionType(FunctionType type) {
@@ -1822,6 +1831,20 @@
     return _representationGenerator.templateForIsFutureOrType;
   }
 
+  /// Returns the JavaScript template to determine at runtime if a type object
+  /// is the void type.
+  @override
+  jsAst.Template get templateForIsVoidType {
+    return _representationGenerator.templateForIsVoidType;
+  }
+
+  /// Returns the JavaScript template to determine at runtime if a type object
+  /// is the dynamic type.
+  @override
+  jsAst.Template get templateForIsDynamicType {
+    return _representationGenerator.templateForIsDynamicType;
+  }
+
   @override
   jsAst.Expression getTypeRepresentation(
       Emitter emitter, DartType type, OnVariableCallback onVariable,
@@ -1986,7 +2009,8 @@
   Map<TypeVariableType, jsAst.Expression> typedefBindings;
   List<FunctionTypeVariable> functionTypeVariables = <FunctionTypeVariable>[];
 
-  TypeRepresentationGenerator(this.namer, this._strongMode);
+  TypeRepresentationGenerator(this.namer, {bool strongMode})
+      : _strongMode = strongMode;
 
   /**
    * Creates a type representation for [type]. [onVariable] is called to provide
@@ -2015,6 +2039,8 @@
 
   jsAst.Expression getDynamicValue() => js('null');
 
+  jsAst.Expression getVoidValue() => js('-1');
+
   @override
   jsAst.Expression visit(DartType type, Emitter emitter) =>
       type.accept(this, emitter);
@@ -2078,6 +2104,18 @@
     return jsAst.js.expressionTemplateFor("'${namer.futureOrTag}' in #");
   }
 
+  /// Returns the JavaScript template to determine at runtime if a type object
+  /// is the void type.
+  jsAst.Template get templateForIsVoidType {
+    return jsAst.js.expressionTemplateFor("# === -1");
+  }
+
+  /// Returns the JavaScript template to determine at runtime if a type object
+  /// is the dynamic type.
+  jsAst.Template get templateForIsDynamicType {
+    return jsAst.js.expressionTemplateFor("# == null");
+  }
+
   jsAst.Expression visitFunctionType(FunctionType type, Emitter emitter) {
     List<jsAst.Property> properties = <jsAst.Property>[];
 
@@ -2102,7 +2140,7 @@
           visitList(type.typeVariables.map((v) => v.bound).toList(), emitter));
     }
 
-    if (type.returnType.isVoid) {
+    if (!_strongMode && type.returnType.isVoid) {
       addProperty(namer.functionTypeVoidReturnTag, js('true'));
     } else if (!type.returnType.treatAsDynamic) {
       addProperty(
@@ -2140,12 +2178,11 @@
 
   jsAst.Expression visitMalformedType(MalformedType type, Emitter emitter) {
     // Treat malformed types as dynamic at runtime.
-    return js('null');
+    return getDynamicValue();
   }
 
   jsAst.Expression visitVoidType(VoidType type, Emitter emitter) {
-    // TODO(ahe): Reify void type ("null" means "dynamic").
-    return js('null');
+    return _strongMode ? getVoidValue() : getDynamicValue();
   }
 
   jsAst.Expression visitTypedefType(
@@ -2295,7 +2332,7 @@
     visit(type, inFunctionType);
   }
 
-  collectAll(List<DartType> types, {bool inFunctionType: false}) {
+  collectAll(Iterable<DartType> types, {bool inFunctionType: false}) {
     for (DartType type in types) {
       visit(type, inFunctionType);
     }
@@ -2317,6 +2354,8 @@
     collectAll(type.parameterTypes, inFunctionType: true);
     collectAll(type.optionalParameterTypes, inFunctionType: true);
     collectAll(type.namedParameterTypes, inFunctionType: true);
+    collectAll(type.typeVariables.map((type) => type.bound),
+        inFunctionType: true);
   }
 }
 
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
index 192736b..2ded0af 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/container_builder.dart
@@ -42,6 +42,11 @@
     bool needStructuredInfo =
         canTearOff || canBeReflected || canBeApplied || hasSuperAlias;
 
+    bool isIntercepted = false;
+    if (method is InstanceMethod) {
+      isIntercepted = method.isIntercepted;
+    }
+
     emitter.interceptorEmitter.recordMangledNameOfMemberMethod(member, name);
 
     if (!needStructuredInfo) {
@@ -73,7 +78,8 @@
     // M+1. Call name of first stub.
     // ...
     // N.   Getter name for tearOff.
-    // N+1. (Required parameter count << 1) + (member.isAccessor ? 1 : 0).
+    // N+1. (Required parameter count << 2) + (member.isAccessor ? 2 : 0) +
+    //        (isIntercepted ? 1 : 0)
     // N+2. (Optional parameter count << 1) +
     //                      (parameters.optionalParametersAreNamed ? 1 : 0).
     // N+3. Index to function type in constant pool.
@@ -116,8 +122,9 @@
 
     // On [requiredParameterCount], the lower bit is set if this method can be
     // called reflectively.
-    int requiredParameterCount = parameters.requiredParameters << 1;
-    if (member.isGetter || member.isSetter) requiredParameterCount++;
+    int requiredParameterCount = parameters.requiredParameters << 2;
+    if (member.isGetter || member.isSetter) requiredParameterCount += 2;
+    if (isIntercepted) requiredParameterCount += 1;
 
     int optionalParameterCount = parameters.optionalParameters << 1;
     if (parameters.namedParameters.isNotEmpty) optionalParameterCount++;
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
index bc177a0..7939804 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -339,6 +339,12 @@
       case JsBuiltin.isFutureOrType:
         return backend.rtiEncoder.templateForIsFutureOrType;
 
+      case JsBuiltin.isVoidType:
+        return backend.rtiEncoder.templateForIsVoidType;
+
+      case JsBuiltin.isDynamicType:
+        return backend.rtiEncoder.templateForIsDynamicType;
+
       case JsBuiltin.rawRtiToJsConstructorName:
         return jsAst.js.expressionTemplateFor("#.$typeNameProperty");
 
@@ -1956,6 +1962,7 @@
     if (compiler.options.strongMode) flavor.write(', strong');
     if (compiler.options.trustPrimitives) flavor.write(', trust primitives');
     if (compiler.options.trustTypeAnnotations) flavor.write(', trust types');
+    if (compiler.options.omitImplicitChecks) flavor.write(', omit checks');
     flavor.write(', full emitter');
     if (compiler.options.useContentSecurityPolicy) flavor.write(', CSP');
     if (_closedWorld.backendUsage.isMirrorsUsed) flavor.write(', mirrors');
diff --git a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
index c26a15c..e734b9d 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/setup_program_builder.dart
@@ -689,6 +689,8 @@
       var getterStubName = ${readString("array", "index")};
       array = array.slice(++index);
       var requiredParameterInfo = ${readInt("array", "0")};
+      var isIntercepted = (requiredParameterInfo & 1) === 1;
+      requiredParameterInfo = requiredParameterInfo >> 1;
       var requiredParameterCount = requiredParameterInfo >> 1;
       var isAccessor = (requiredParameterInfo & 1) === 1;
       var isSetter = requiredParameterInfo === 3;
@@ -697,7 +699,6 @@
       var optionalParameterCount = optionalParameterInfo >> 1;
       var optionalParametersAreNamed = (optionalParameterInfo & 1) === 1;
       var totalParameterCount = requiredParameterCount + optionalParameterCount;
-      var isIntercepted = totalParameterCount != funcs[0].length;
       var functionTypeIndex = ${readFunctionType("array", "2")};
       if (typeof functionTypeIndex == "number")
         ${readFunctionType("array", "2")} = functionTypeIndex + typesOffset;
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index d21e5e7..ef1ffd3 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -97,17 +97,15 @@
   _ForwardingMetadataEntry([this.debug]);
 
   _MetadataEntry get forwardTo {
-    assert(isBound);
+    assert(isBound, 'unbound $this $debug');
     return _forwardTo;
   }
 
   jsAst.Expression get entry {
-    assert(isBound);
     return forwardTo.entry;
   }
 
   int get value {
-    assert(isBound);
     return forwardTo.value;
   }
 
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index bebb3ac..3634ee2 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -486,6 +486,9 @@
   /// functions that can be torn off.
   final bool isClosureCallMethod;
 
+  /// True if the interceptor calling convention is used for this method.
+  final bool isIntercepted;
+
   InstanceMethod(FunctionEntity element, js.Name name, js.Expression code,
       List<ParameterStubMethod> parameterStubs, js.Name callName,
       {bool needsTearOff,
@@ -496,6 +499,7 @@
       int requiredParameterCount,
       /* List | Map */ optionalParameterDefaultValues,
       this.isClosureCallMethod,
+      this.isIntercepted,
       js.Expression functionType})
       : super(element, name, code, parameterStubs, callName,
             needsTearOff: needsTearOff,
diff --git a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
index 525d31b..2561648 100644
--- a/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
+++ b/pkg/compiler/lib/src/js_emitter/program_builder/program_builder.dart
@@ -922,6 +922,9 @@
       assert(element is! ConstructorBodyEntity, failedAt(element));
     }
 
+    bool isIntercepted =
+        _closedWorld.interceptorData.isInterceptedMethod(element);
+
     js.Name callName = null;
     if (canTearOff) {
       Selector callSelector =
@@ -951,6 +954,7 @@
         needsTearOff: canTearOff,
         tearOffName: tearOffName,
         isClosureCallMethod: isClosureCallMethod,
+        isIntercepted: isIntercepted,
         aliasName: aliasName,
         canBeApplied: canBeApplied,
         canBeReflected: canBeReflected,
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
index 19b685b..18541ce 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -129,6 +129,12 @@
       case JsBuiltin.isFutureOrType:
         return _backend.rtiEncoder.templateForIsFutureOrType;
 
+      case JsBuiltin.isVoidType:
+        return _backend.rtiEncoder.templateForIsVoidType;
+
+      case JsBuiltin.isDynamicType:
+        return _backend.rtiEncoder.templateForIsDynamicType;
+
       case JsBuiltin.rawRtiToJsConstructorName:
         return js.js.expressionTemplateFor("#.name");
 
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index 0462d15..144e302 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -483,8 +483,6 @@
   FragmentEmitter(this.compiler, this.namer, this.backend, this.constantEmitter,
       this.modelEmitter, this._closedWorld);
 
-  InterceptorData get _interceptorData => _closedWorld.interceptorData;
-
   js.Expression generateEmbeddedGlobalAccess(String global) =>
       modelEmitter.generateEmbeddedGlobalAccess(global);
 
@@ -1110,8 +1108,7 @@
 
     bool isIntercepted = false;
     if (method is InstanceMethod) {
-      FunctionEntity element = method.element;
-      isIntercepted = _interceptorData.isInterceptedMethod(element);
+      isIntercepted = method.isIntercepted;
     }
     int requiredParameterCount = 0;
     js.Expression optionalParameterDefaultValues = new js.LiteralNull();
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 0509d2e..5c5933a 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -46,7 +46,6 @@
 import '../../js/js.dart' as js;
 import '../../js_backend/js_backend.dart'
     show JavaScriptBackend, Namer, ConstantEmitter, StringBackedName;
-import '../../js_backend/interceptor_data.dart';
 import '../../world.dart';
 import '../code_emitter_task.dart';
 import '../constant_ordering.dart' show ConstantOrdering;
@@ -233,6 +232,7 @@
     if (compiler.options.strongMode) flavor.write(', strong');
     if (compiler.options.trustPrimitives) flavor.write(', trust primitives');
     if (compiler.options.trustTypeAnnotations) flavor.write(', trust types');
+    if (compiler.options.omitImplicitChecks) flavor.write(', omit checks');
     flavor.write(', fast startup emitter');
     if (compiler.options.useContentSecurityPolicy) flavor.write(', CSP');
     return new js.Comment(generatedBy(compiler, flavor: '$flavor'));
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 4a40348..1f1d3c3 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -214,6 +214,24 @@
   /// Whether to trust type annotations during inference and optimizations.
   bool trustTypeAnnotations = false;
 
+  /// Whether to omit implicit strong mode checks.
+  bool omitImplicitChecks = false;
+
+  /// What should the compiler do with type assertions of assignments.
+  ///
+  /// This is an internal configuration option derived from other flags.
+  CheckPolicy assignmentCheckPolicy;
+
+  /// What should the compiler do with parameter type assertions.
+  ///
+  /// This is an internal configuration option derived from other flags.
+  CheckPolicy parameterCheckPolicy;
+
+  /// What should the compiler do with implicit downcasts.
+  ///
+  /// This is an internal configuration option derived from other flags.
+  CheckPolicy implicitDowncastCheckPolicy;
+
   /// Whether to generate code compliant with content security policy (CSP).
   bool useContentSecurityPolicy = false;
 
@@ -324,6 +342,7 @@
       ..resolveOnly = _hasOption(options, Flags.resolveOnly)
       ..sourceMapUri = _extractUriOption(options, '--source-map=')
       ..strongMode = _hasOption(options, Flags.strongMode)
+      ..omitImplicitChecks = _hasOption(options, Flags.omitImplicitChecks)
       ..testMode = _hasOption(options, Flags.testMode)
       ..trustJSInteropTypeAnnotations =
           _hasOption(options, Flags.trustJSInteropTypeAnnotations)
@@ -371,6 +390,33 @@
       platformConfigUri = _resolvePlatformConfig(libraryRoot, null, const []);
     }
     librariesSpecificationUri = _resolveLibrariesSpecification(libraryRoot);
+
+    if (strongMode) {
+      // Strong mode represents implicit downcasts explicitly, so assignments
+      // checks provide no additional value.
+      assignmentCheckPolicy = CheckPolicy.ignored;
+      if (omitImplicitChecks) {
+        parameterCheckPolicy = CheckPolicy.trusted;
+        implicitDowncastCheckPolicy = CheckPolicy.trusted;
+      } else {
+        parameterCheckPolicy = CheckPolicy.checked;
+        implicitDowncastCheckPolicy = CheckPolicy.checked;
+      }
+    } else {
+      // The implicit-downcast representation is a strong-mode only feature.
+      implicitDowncastCheckPolicy = CheckPolicy.ignored;
+
+      if (enableTypeAssertions) {
+        assignmentCheckPolicy = CheckPolicy.checked;
+        parameterCheckPolicy = CheckPolicy.checked;
+      } else if (trustTypeAnnotations) {
+        assignmentCheckPolicy = CheckPolicy.trusted;
+        parameterCheckPolicy = CheckPolicy.trusted;
+      } else {
+        assignmentCheckPolicy = CheckPolicy.ignored;
+        parameterCheckPolicy = CheckPolicy.ignored;
+      }
+    }
   }
 
   /// Returns `true` if warnings and hints are shown for all packages.
@@ -394,6 +440,28 @@
   }
 }
 
+/// Policy for what to do with a type assertion check.
+///
+/// This enum-like class is used to configure how the compiler treats type
+/// assertions during global type inference and codegen.
+class CheckPolicy {
+  /// Whether the type assertion should be trusted.
+  final bool isTrusted;
+
+  /// Whether the type assertion should be emitted and checked.
+  final bool isEmitted;
+
+  /// Whether the type assertion should be ignored.
+  final bool isIgnored;
+
+  const CheckPolicy(
+      {this.isTrusted: false, this.isEmitted: false, this.isIgnored: false});
+
+  static const trusted = const CheckPolicy(isTrusted: true);
+  static const checked = const CheckPolicy(isEmitted: true);
+  static const ignored = const CheckPolicy(isIgnored: true);
+}
+
 String _extractStringOption(
     List<String> options, String prefix, String defaultValue) {
   for (String option in options) {
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 847a3e6..757b81d 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -794,8 +794,8 @@
     // If the method is intercepted, we want the actual receiver
     // to be the first parameter.
     graph.entry.addBefore(graph.entry.last, parameter);
-    HInstruction value =
-        typeBuilder.potentiallyCheckOrTrustType(parameter, field.type);
+    HInstruction value = typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
+        parameter, field.type);
     add(new HFieldSet(field, thisInstruction, value));
     return closeFunction();
   }
@@ -813,7 +813,8 @@
     openFunction(variable, node);
     visit(initializer);
     HInstruction value = pop();
-    value = typeBuilder.potentiallyCheckOrTrustType(value, variable.type);
+    value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
+        value, variable.type);
     // In the case of multiple declarations (and some definitions) on the same
     // line, the source pointer needs to point to the right initialized
     // variable. So find the specific initialized variable we are referring to.
@@ -1298,8 +1299,8 @@
       } else {
         fields.add(member);
         ResolutionDartType type = localsHandler.substInContext(member.type);
-        constructorArguments
-            .add(typeBuilder.potentiallyCheckOrTrustType(value, type));
+        constructorArguments.add(
+            typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type));
       }
     }, includeSuperAndInjectedMembers: true);
 
@@ -1519,7 +1520,7 @@
           //       new A("foo");  // invalid in checked mode.
           //
           // Only the final target is allowed to check for the argument types.
-          newParameter = typeBuilder.potentiallyCheckOrTrustType(
+          newParameter = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
               newParameter, parameterElement.type);
         }
         localsHandler.directLocals[parameterElement] = newParameter;
@@ -1604,7 +1605,8 @@
     HInstruction value = pop();
     if (typeBuilder.checkOrTrustTypes) {
       ResolutionInterfaceType boolType = commonElements.boolType;
-      return typeBuilder.potentiallyCheckOrTrustType(value, boolType,
+      return typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
+          value, boolType,
           kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
     }
     HInstruction result = new HBoolify(value, commonMasks.boolType)
@@ -2417,7 +2419,8 @@
         pop();
       } else {
         FieldElement field = element;
-        value = typeBuilder.potentiallyCheckOrTrustType(value, field.type);
+        value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
+            value, field.type);
         addWithPosition(new HStaticStore(field, value), location);
       }
       stack.add(value);
@@ -2433,8 +2436,8 @@
       if (value.sourceElement == null) {
         value.sourceElement = local;
       }
-      HInstruction checkedOrTrusted =
-          typeBuilder.potentiallyCheckOrTrustType(value, local.type);
+      HInstruction checkedOrTrusted = typeBuilder
+          .potentiallyCheckOrTrustTypeOfAssignment(value, local.type);
       if (!identical(checkedOrTrusted, value)) {
         pop();
         stack.add(checkedOrTrusted);
@@ -3643,8 +3646,8 @@
 
     // Finally, if we called a redirecting factory constructor, check the type.
     if (isRedirected) {
-      HInstruction checked =
-          typeBuilder.potentiallyCheckOrTrustType(newInstance, type);
+      HInstruction checked = typeBuilder
+          .potentiallyCheckOrTrustTypeOfAssignment(newInstance, type);
       if (checked != newInstance) {
         pop();
         stack.add(checked);
@@ -5326,7 +5329,8 @@
           return;
         }
       } else {
-        value = typeBuilder.potentiallyCheckOrTrustType(value, returnType);
+        value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
+            value, returnType);
       }
     }
 
@@ -7088,7 +7092,7 @@
     signature.forEachParameter((_parameter) {
       ParameterElement parameter = _parameter;
       HInstruction argument = builder.localsHandler.readLocal(parameter);
-      potentiallyCheckOrTrustType(argument, parameter.type);
+      potentiallyCheckOrTrustTypeOfParameter(argument, parameter.type);
     });
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 44b5a21..1d1b98d 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -320,15 +320,16 @@
       // If the method is intercepted, we want the actual receiver
       // to be the first parameter.
       graph.entry.addBefore(graph.entry.last, parameter);
-      HInstruction value = typeBuilder.potentiallyCheckOrTrustType(
+      HInstruction value = typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
           parameter, _getDartTypeIfValid(node.type));
       add(new HFieldSet(field, thisInstruction, value));
     } else {
       if (node.initializer != null) {
         node.initializer.accept(this);
         HInstruction fieldValue = pop();
-        HInstruction checkInstruction = typeBuilder.potentiallyCheckOrTrustType(
-            fieldValue, _getDartTypeIfValid(node.type));
+        HInstruction checkInstruction =
+            typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
+                fieldValue, _getDartTypeIfValid(node.type));
         stack.add(checkInstruction);
       } else {
         stack.add(graph.addConstantNull(closedWorld));
@@ -353,7 +354,7 @@
     HInstruction value = pop();
     if (typeBuilder.checkOrTrustTypes) {
       InterfaceType type = commonElements.boolType;
-      return typeBuilder.potentiallyCheckOrTrustType(value, type,
+      return typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type,
           kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
     }
     HInstruction result = new HBoolify(value, commonMasks.boolType);
@@ -475,8 +476,8 @@
         fields.add(member);
         DartType type = _elementMap.elementEnvironment.getFieldType(member);
         type = localsHandler.substInContext(type);
-        constructorArguments
-            .add(typeBuilder.potentiallyCheckOrTrustType(value, type));
+        constructorArguments.add(
+            typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type));
       }
     });
 
@@ -982,7 +983,7 @@
         return;
       }
       HInstruction newParameter = localsHandler.directLocals[local];
-      newParameter = typeBuilder.potentiallyCheckOrTrustType(
+      newParameter = typeBuilder.potentiallyCheckOrTrustTypeOfParameter(
           newParameter, _getDartTypeIfValid(variable.type));
       localsHandler.directLocals[local] = newParameter;
     }
@@ -1268,9 +1269,8 @@
           return;
         }
       } else {
-        if (!options.strongMode) {
-          value = typeBuilder.potentiallyCheckOrTrustType(value, _returnType);
-        }
+        value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
+            value, _returnType);
       }
     }
     handleInTryStatement();
@@ -1519,7 +1519,7 @@
           const <DartType>[], sourceInformation);
 
       Local loopVariableLocal = localsMap.getLocalVariable(node.variable);
-      HInstruction value = typeBuilder.potentiallyCheckOrTrustType(
+      HInstruction value = typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
           pop(), _getDartTypeIfValid(node.variable.type));
       localsHandler.updateLocal(loopVariableLocal, value,
           sourceInformation: sourceInformation);
@@ -1839,7 +1839,8 @@
         assert(type is MethodTypeVariableType);
         stack.add(expressionInstruction);
       }
-    } else {
+    } else if (!node.isTypeError ||
+        options.implicitDowncastCheckPolicy.isEmitted) {
       HInstruction converted = typeBuilder.buildTypeConversion(
           expressionInstruction,
           localsHandler.substInContext(type),
@@ -1851,6 +1852,8 @@
         add(converted);
       }
       stack.add(converted);
+    } else {
+      stack.add(expressionInstruction);
     }
   }
 
@@ -2697,7 +2700,7 @@
     } else {
       add(new HStaticStore(
           _elementMap.getMember(staticTarget),
-          typeBuilder.potentiallyCheckOrTrustType(
+          typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
               value, _getDartTypeIfValid(staticTarget.setterType))));
     }
     stack.add(value);
@@ -2837,7 +2840,7 @@
     stack.add(value);
     localsHandler.updateLocal(
         local,
-        typeBuilder.potentiallyCheckOrTrustType(
+        typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(
             value, _getDartTypeIfValid(variable.type)),
         sourceInformation: sourceInformation);
   }
@@ -4318,7 +4321,6 @@
       return;
     }
 
-    // TODO(sra): For JS-interop targets, process arguments differently.
     List<HInstruction> arguments = <HInstruction>[];
     if (constructor.isGenerativeConstructor &&
         nativeData.isNativeOrExtendsNative(constructor.enclosingClass) &&
@@ -4328,8 +4330,10 @@
     }
     List<DartType> typeArguments =
         _getConstructorTypeArguments(constructor, node.arguments);
-    arguments.addAll(_visitArgumentsForStaticTarget(
-        target.function, node.arguments, typeArguments, sourceInformation));
+    arguments.addAll(closedWorld.nativeData.isJsInteropMember(constructor)
+        ? _visitArgumentsForNativeStaticTarget(target.function, node.arguments)
+        : _visitArgumentsForStaticTarget(
+            target.function, node.arguments, typeArguments, sourceInformation));
     if (commonElements.isSymbolConstructor(constructor)) {
       constructor = commonElements.symbolValidatedConstructor;
     }
@@ -5594,7 +5598,7 @@
     forEachOrderedParameter(_globalLocalsMap, _elementMap, function,
         (Local parameter) {
       HInstruction argument = builder.localsHandler.readLocal(parameter);
-      potentiallyCheckOrTrustType(
+      potentiallyCheckOrTrustTypeOfParameter(
           argument, localsMap.getLocalType(_elementMap, parameter));
     });
   }
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index 5e3c51f..3e93ba2 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -60,10 +60,16 @@
     if (kind != null && !type.isDynamic) {
       switch (kind) {
         case TypeUseKind.CHECKED_MODE_CHECK:
-          impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type));
+          if (!_options.strongMode) {
+            impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type));
+          }
           break;
         case TypeUseKind.PARAMETER_CHECK:
-          impactBuilder.registerTypeUse(new TypeUse.parameterCheck(type));
+          if (!_options.strongMode) {
+            impactBuilder.registerTypeUse(new TypeUse.checkedModeCheck(type));
+          } else {
+            impactBuilder.registerTypeUse(new TypeUse.parameterCheck(type));
+          }
           break;
         case TypeUseKind.IMPLICIT_CAST:
           impactBuilder.registerTypeUse(new TypeUse.implicitCast(type));
@@ -83,11 +89,7 @@
   /// Add checked-mode type use for the parameter type and constant for the
   /// default value of [parameter].
   void handleParameter(ir.VariableDeclaration parameter) {
-    checkType(
-        parameter.type,
-        _options.strongMode
-            ? TypeUseKind.PARAMETER_CHECK
-            : TypeUseKind.CHECKED_MODE_CHECK);
+    checkType(parameter.type, TypeUseKind.PARAMETER_CHECK);
     registerSeenClasses(parameter.type);
     visitNode(parameter.initializer);
   }
@@ -95,7 +97,7 @@
   /// Add checked-mode type use for parameter and return types, and add
   /// constants for default values.
   void handleSignature(ir.FunctionNode node, {bool checkReturnType: true}) {
-    if (checkReturnType && !_options.strongMode) {
+    if (checkReturnType) {
       checkType(node.returnType, TypeUseKind.CHECKED_MODE_CHECK);
     }
     registerSeenClasses(node.returnType);
@@ -104,11 +106,7 @@
   }
 
   ResolutionImpact buildField(ir.Field field) {
-    checkType(
-        field.type,
-        _options.strongMode
-            ? TypeUseKind.PARAMETER_CHECK
-            : TypeUseKind.CHECKED_MODE_CHECK);
+    checkType(field.type, TypeUseKind.PARAMETER_CHECK);
     registerSeenClasses(field.type);
     if (field.initializer != null) {
       visitNode(field.initializer);
@@ -243,8 +241,8 @@
   @override
   void visitListLiteral(ir.ListLiteral literal) {
     visitNodes(literal.expressions);
-    DartType elementType = checkType(literal.typeArgument,
-        _options.strongMode ? null : TypeUseKind.CHECKED_MODE_CHECK);
+    DartType elementType =
+        checkType(literal.typeArgument, TypeUseKind.CHECKED_MODE_CHECK);
     registerSeenClasses(literal.typeArgument);
 
     impactBuilder.registerListLiteral(new ListLiteralUse(
@@ -256,10 +254,10 @@
   @override
   void visitMapLiteral(ir.MapLiteral literal) {
     visitNodes(literal.entries);
-    DartType keyType = checkType(literal.keyType,
-        _options.strongMode ? null : TypeUseKind.CHECKED_MODE_CHECK);
-    DartType valueType = checkType(literal.valueType,
-        _options.strongMode ? null : TypeUseKind.CHECKED_MODE_CHECK);
+    DartType keyType =
+        checkType(literal.keyType, TypeUseKind.CHECKED_MODE_CHECK);
+    DartType valueType =
+        checkType(literal.valueType, TypeUseKind.CHECKED_MODE_CHECK);
     registerSeenClasses(literal.keyType);
     registerSeenClasses(literal.valueType);
     impactBuilder.registerMapLiteral(new MapLiteralUse(
@@ -594,9 +592,7 @@
 
   @override
   void visitVariableDeclaration(ir.VariableDeclaration node) {
-    if (!_options.strongMode) {
-      checkType(node.type, TypeUseKind.CHECKED_MODE_CHECK);
-    }
+    checkType(node.type, TypeUseKind.CHECKED_MODE_CHECK);
     registerSeenClasses(node.type);
     if (node.initializer != null) {
       visitNode(node.initializer);
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 58b5b3d..eb334b9 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -55,7 +55,6 @@
 
   /// Create an instruction to simply trust the provided type.
   HInstruction _trustType(HInstruction original, DartType type) {
-    assert(builder.options.trustTypeAnnotations);
     assert(type != null);
     TypeMask mask = trustTypeMask(type);
     if (mask == null) return original;
@@ -65,7 +64,6 @@
   /// Produces code that checks the runtime type is actually the type specified
   /// by attempting a type conversion.
   HInstruction _checkType(HInstruction original, DartType type, int kind) {
-    assert(builder.options.enableTypeAssertions);
     assert(type != null);
     type = builder.localsHandler.substInContext(type);
     HInstruction other = buildTypeConversion(original, type, kind);
@@ -78,16 +76,33 @@
     return other;
   }
 
+  HInstruction potentiallyCheckOrTrustTypeOfParameter(
+      HInstruction original, DartType type) {
+    if (type == null) return original;
+    HInstruction checkedOrTrusted = original;
+    if (builder.options.parameterCheckPolicy.isTrusted) {
+      checkedOrTrusted = _trustType(original, type);
+    } else if (builder.options.parameterCheckPolicy.isEmitted) {
+      checkedOrTrusted =
+          _checkType(original, type, HTypeConversion.CHECKED_MODE_CHECK);
+    }
+    if (checkedOrTrusted == original) return original;
+    builder.add(checkedOrTrusted);
+    return checkedOrTrusted;
+  }
+
   /// Depending on the context and the mode, wrap the given type in an
   /// instruction that checks the type is what we expect or automatically
   /// trusts the written type.
-  HInstruction potentiallyCheckOrTrustType(HInstruction original, DartType type,
+  HInstruction potentiallyCheckOrTrustTypeOfAssignment(
+      HInstruction original, DartType type,
       {int kind: HTypeConversion.CHECKED_MODE_CHECK}) {
     if (type == null) return original;
+    if (builder.options.strongMode) return original;
     HInstruction checkedOrTrusted = original;
-    if (builder.options.trustTypeAnnotations) {
+    if (builder.options.assignmentCheckPolicy.isTrusted) {
       checkedOrTrusted = _trustType(original, type);
-    } else if (builder.options.enableTypeAssertions) {
+    } else if (builder.options.assignmentCheckPolicy.isEmitted) {
       checkedOrTrusted = _checkType(original, type, kind);
     }
     if (checkedOrTrusted == original) return original;
@@ -240,6 +255,7 @@
   void potentiallyCheckInlinedParameterTypes(FunctionEntity function);
 
   bool get checkOrTrustTypes =>
+      builder.options.strongMode ||
       builder.options.enableTypeAssertions ||
       builder.options.trustTypeAnnotations;
 
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 0a871b8..17aa6ac 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -755,8 +755,32 @@
     // `C<T>.add` check in CoercionReifier, so it does not reach this point;
     // rather we check for it explicitly when emitting methods and fields.
     // However we do reify the `c.f` check, so we must not eliminate it.
-    var isRequiredForSoundness = CoercionReifier.isRequiredForSoundness(node);
-    if (!isRequiredForSoundness && rules.isSubtypeOf(from, to)) return jsFrom;
+    var isImplicit = CoercionReifier.isImplicit(node);
+    if (!isImplicit && rules.isSubtypeOf(from, to)) return jsFrom;
+
+    // Handle implicit tearoff of the `.call` method.
+    //
+    // TODO(jmesserly): this is handled here rather than in CoercionReifier, in
+    // hopes that we can remove that extra visit and tree cloning step (which
+    // has been error prone because AstCloner isn't used much, and making
+    // synthetic resolved Analyzer ASTs is difficult).
+    if (isImplicit &&
+        from is InterfaceType &&
+        rules.acceptsFunctionType(to) &&
+        !_usesJSInterop(from.element)) {
+      // Dart allows an implicit coercion from an interface type to a function
+      // type, via a tearoff of the `call` method.
+      var callMethod = from.lookUpInheritedMethod('call');
+      if (callMethod != null) {
+        var callName = _emitMemberName('call', type: from, element: callMethod);
+        var callTearoff = _callHelper('bindCall(#, #)', [jsFrom, callName]);
+        if (rules.isSubtypeOf(callMethod.type, to)) return callTearoff;
+
+        // We may still need an implicit coercion as well, if another downcast
+        // is involved.
+        return js.call('#._check(#)', [_emitType(to), callTearoff]);
+      }
+    }
 
     // All Dart number types map to a JS double.
     if (_typeRep.isNumber(from) && _typeRep.isNumber(to)) {
@@ -772,7 +796,7 @@
       return jsFrom;
     }
 
-    var code = isRequiredForSoundness ? '#._check(#)' : '#.as(#)';
+    var code = isImplicit ? '#._check(#)' : '#.as(#)';
     return js.call(code, [_emitType(to), jsFrom]);
   }
 
@@ -1033,7 +1057,7 @@
             '}',
             [className, _runtimeModule, className]));
         body.add(js.statement(
-            '#._check = function check_String(o) {'
+            '#._check = function check_Function(o) {'
             '  if (typeof o == "function" || o == null) return o;'
             '  return #.as(o, #, true);'
             '}',
@@ -1318,7 +1342,6 @@
 
     var supertype = classElem.supertype;
     var hasUnnamedSuper = _hasUnnamedConstructor(supertype.element);
-    var isCallable = isCallableClass(classElem);
 
     void emitMixinConstructors(JS.Expression className, [InterfaceType mixin]) {
       var supertype = classElem.supertype;
@@ -1340,11 +1363,8 @@
           ctorBody
               .add(_emitSuperConstructorCall(className, ctor.name, jsParams));
         }
-        body.add(_addConstructorToClass(
-            className,
-            ctor.name,
-            _finishConstructorFunction(
-                jsParams, new JS.Block(ctorBody), isCallable)));
+        body.add(_addConstructorToClass(className, ctor.name,
+            new JS.Fun(jsParams, new JS.Block(ctorBody))));
       }
     }
 
@@ -1902,17 +1922,7 @@
       JS.Expression className,
       Map<Element, Declaration> memberMap,
       Declaration classNode) {
-    var isCallable = isCallableClass(classElem);
-
     var body = <JS.Statement>[];
-    if (isCallable) {
-      // Our class instances will have JS `typeof this == "function"`,
-      // so make sure to attach the runtime type information the same way
-      // we would do it for function types.
-      body.add(js.statement('#.prototype[#] = #;',
-          [className, _callHelper('_runtimeType'), className]));
-    }
-
     if (classElem.isMixinApplication) {
       // We already handled this when we defined the class.
       return body;
@@ -1923,7 +1933,6 @@
     }
 
     if (classElem.isEnum) {
-      assert(!isCallable, 'enums should not be callable');
       addConstructor('', js.call('function(x) { this.index = x; }'));
       return body;
     }
@@ -1944,7 +1953,7 @@
 
       addConstructor(
           '',
-          _finishConstructorFunction([], new JS.Block(ctorBody), isCallable)
+          new JS.Fun([], new JS.Block(ctorBody))
             ..sourceInformation = _functionEnd(classNode));
       return body;
     }
@@ -1956,8 +1965,7 @@
       var ctor = memberMap[element] as ConstructorDeclaration;
       if (ctor.body is NativeFunctionBody) continue;
 
-      addConstructor(
-          element.name, _emitConstructor(ctor, fields, isCallable, className));
+      addConstructor(element.name, _emitConstructor(ctor, fields, className));
     }
 
     // If classElement has only factory constructors, and it can be mixed in,
@@ -2286,11 +2294,8 @@
     }
   }
 
-  JS.Expression _emitConstructor(
-      ConstructorDeclaration node,
-      List<VariableDeclaration> fields,
-      bool isCallable,
-      JS.Expression className) {
+  JS.Expression _emitConstructor(ConstructorDeclaration node,
+      List<VariableDeclaration> fields, JS.Expression className) {
     var params = _emitFormalParameters(node.parameters?.parameters);
 
     var savedFunction = _currentFunction;
@@ -2302,27 +2307,7 @@
     _superAllowed = savedSuperAllowed;
     _currentFunction = savedFunction;
 
-    return _finishConstructorFunction(params, body, isCallable)
-      ..sourceInformation = _functionEnd(node);
-  }
-
-  JS.Expression _finishConstructorFunction(
-      List<JS.Parameter> params, JS.Block body, bool isCallable) {
-    // We consider a class callable if it inherits from anything with a `call`
-    // method. As a result, we can know the callable JS function was created
-    // at the first constructor that was hit.
-    if (!isCallable) return new JS.Fun(params, body);
-    return js.call(r'''function callableClass(#) {
-          if (typeof this !== "function") {
-            function self(...args) {
-              return self.call.apply(self, args);
-            }
-            self.__proto__ = this.__proto__;
-            callableClass.call(self, #);
-            return self;
-          }
-          #
-        }''', [params, params, body]);
+    return new JS.Fun(params, body)..sourceInformation = _functionEnd(node);
   }
 
   FunctionType _getMemberRuntimeType(ExecutableElement element) {
@@ -3669,20 +3654,11 @@
     if (target == null || isLibraryPrefix(target)) {
       return _emitFunctionCall(node);
     }
-    if (node.methodName.name == 'call') {
-      var targetType = resolutionMap.staticTypeForExpression(target);
-      if (targetType is FunctionType) {
-        // Call methods on function types should be handled as regular function
-        // invocations.
-        return _emitFunctionCall(node, node.target);
-      }
-      if (targetType.isDartCoreFunction || targetType.isDynamic) {
-        // TODO(vsm): Can a call method take generic type parameters?
-        return _emitDynamicInvoke(
-            _visitExpression(target),
-            _emitInvokeTypeArguments(node),
-            _emitArgumentList(node.argumentList));
-      }
+    if (node.methodName.name == 'call' &&
+        _isDirectCallable(target.staticType)) {
+      // Call methods on function types should be handled as regular function
+      // invocations.
+      return _emitFunctionCall(node, node.target);
     }
 
     return _emitMethodCall(target, node);
@@ -3807,6 +3783,16 @@
       return _callHelper('#(#, #)', [name, jsTarget, args]);
     }
     jsTarget = _emitTargetAccess(jsTarget, jsName, element, node.methodName);
+    // Handle `o.m(a)` where `o.m` is a getter returning a class with `call`.
+    if (element is PropertyAccessorElement) {
+      var fromType = element.returnType;
+      if (fromType is InterfaceType) {
+        var callName = _getImplicitCallTarget(fromType);
+        if (callName != null) {
+          jsTarget = new JS.PropertyAccess(jsTarget, callName);
+        }
+      }
+    }
     var castTo = getImplicitOperationCast(node);
     if (castTo != null) {
       jsTarget = js.call('#._check(#)', [_emitType(castTo), jsTarget]);
@@ -3893,6 +3879,15 @@
       return _emitDynamicInvoke(fn, typeArgs, args);
     }
     if (typeArgs != null) args.insertAll(0, typeArgs);
+
+    var targetType = function.staticType;
+    if (targetType is InterfaceType) {
+      var callName = _getImplicitCallTarget(targetType);
+      if (callName != null) {
+        return js.call('#.#(#)', [fn, callName, args]);
+      }
+    }
+
     return new JS.Call(fn, args);
   }
 
@@ -5143,7 +5138,7 @@
     if (isLibraryPrefix(node.prefix)) {
       return visitSimpleIdentifier(node.identifier, node.prefix);
     } else {
-      return _emitAccess(node.prefix, node.identifier, node.staticType);
+      return _emitPropertyGet(node.prefix, node.identifier, node.staticType);
     }
   }
 
@@ -5152,7 +5147,8 @@
     if (node.operator.lexeme == '?.' && isNullable(node.target)) {
       return _emitNullSafe(node);
     }
-    return _emitAccess(_getTarget(node), node.propertyName, node.staticType);
+    return _emitPropertyGet(
+        _getTarget(node), node.propertyName, node.staticType);
   }
 
   JS.Expression _emitNullSafe(Expression node) {
@@ -5202,27 +5198,30 @@
   }
 
   /// Shared code for [PrefixedIdentifier] and [PropertyAccess].
-  JS.Expression _emitAccess(
-      Expression target, SimpleIdentifier memberId, DartType resultType) {
+  JS.Expression _emitPropertyGet(
+      Expression receiver, SimpleIdentifier memberId, DartType resultType) {
     var accessor = memberId.staticElement;
+    var memberName = memberId.name;
+    var receiverType = getStaticType(receiver);
+    if (memberName == 'call' && _isDirectCallable(receiverType)) {
+      // Tearoff of `call` on a function type is a no-op;
+      return _visitExpression(receiver);
+    }
+
     // If `member` is a getter/setter, get the corresponding
     var field = _getNonAccessorElement(accessor);
-    String memberName = memberId.name;
-    var typeArgs = _getTypeArgs(accessor, resultType);
-
     bool isStatic = field is ClassMemberElement && field.isStatic;
     var jsName = _emitMemberName(memberName,
-        type: getStaticType(target), isStatic: isStatic, element: accessor);
-    if (isDynamicInvoke(target)) {
+        type: receiverType, isStatic: isStatic, element: accessor);
+    if (isDynamicInvoke(receiver)) {
       return _callHelper('#(#, #)', [
         _emitDynamicOperationName('dload'),
-        _visitExpression(target),
+        _visitExpression(receiver),
         jsName
       ]);
     }
 
-    var jsTarget = _emitTarget(target, accessor, isStatic);
-
+    var jsTarget = _emitTarget(receiver, accessor, isStatic);
     var isSuper = jsTarget is JS.Super;
     if (isSuper &&
         accessor.isSynthetic &&
@@ -5234,7 +5233,7 @@
     }
 
     JS.Expression result;
-    if (_isObjectMemberCall(target, memberName)) {
+    if (_isObjectMemberCall(receiver, memberName)) {
       if (_isObjectMethod(memberName)) {
         result = _callHelper('bind(#, #)', [jsTarget, jsName]);
       } else {
@@ -5253,11 +5252,22 @@
     } else {
       result = _emitTargetAccess(jsTarget, jsName, accessor, memberId);
     }
+
+    var typeArgs = _getTypeArgs(accessor, resultType);
     return typeArgs == null
         ? result
         : _callHelper('gbind(#, #)', [result, typeArgs]);
   }
 
+  bool _isDirectCallable(DartType t) =>
+      t is FunctionType || t is InterfaceType && _usesJSInterop(t.element);
+
+  JS.Expression _getImplicitCallTarget(InterfaceType fromType) {
+    var callMethod = fromType.lookUpInheritedMethod('call');
+    if (callMethod == null || _usesJSInterop(fromType.element)) return null;
+    return _emitMemberName('call', type: fromType, element: callMethod);
+  }
+
   JS.LiteralString _emitDynamicOperationName(String name) =>
       js.string(options.replCompile ? '${name}Repl' : name);
 
@@ -5898,7 +5908,7 @@
       if (op == '&&') return shortCircuit('# && #');
       if (op == '||') return shortCircuit('# || #');
     }
-    if (node is AsExpression && CoercionReifier.isRequiredForSoundness(node)) {
+    if (node is AsExpression && CoercionReifier.isImplicit(node)) {
       assert(node.staticType == types.boolType);
       return _callHelper('dtest(#)', _visitExpression(node.expression));
     }
diff --git a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
index 1a0658c..ec95501 100644
--- a/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/element_helpers.dart
@@ -15,10 +15,9 @@
         ExecutableElement,
         FunctionElement,
         LibraryElement,
-        PropertyAccessorElement,
         TypeParameterizedElement;
 import 'package:analyzer/dart/element/type.dart'
-    show DartType, InterfaceType, ParameterizedType, FunctionType;
+    show DartType, InterfaceType, ParameterizedType;
 import 'package:analyzer/src/dart/element/type.dart' show DynamicTypeImpl;
 import 'package:analyzer/src/generated/constant.dart'
     show DartObject, DartObjectImpl;
@@ -184,26 +183,6 @@
   return c.isMixinApplication && c.supertype.isObject && c.mixins.length == 1;
 }
 
-bool isCallableClass(ClassElement c) {
-  // See if we have a "call" with a statically known function type:
-  //
-  // - if it's a method, then it does because all methods do,
-  // - if it's a getter, check the return type.
-  //
-  // Other cases like a getter returning dynamic/Object/Function will be
-  // handled at runtime by the dynamic call mechanism. So we only
-  // concern ourselves with statically known function types.
-  //
-  // We can ignore `noSuchMethod` because:
-  // * `dynamic d; d();` without a declared `call` method is handled by dcall.
-  // * for `class C implements Callable { noSuchMethod(i) { ... } }` we find
-  //   the `call` method on the `Callable` interface.
-  var callMethod = c.type.lookUpInheritedGetterOrMethod('call');
-  return callMethod is PropertyAccessorElement
-      ? callMethod.returnType is FunctionType
-      : callMethod != null;
-}
-
 Uri uriForCompilationUnit(CompilationUnitElement unit) {
   if (unit.source.isInSystemLibrary) {
     return unit.source.uri;
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index 6c7f005..b4343f9 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -113,12 +113,14 @@
           new InputPackagesResultProvider(context, summaryData);
     }
     options.declaredVariables.forEach(context.declaredVariables.define);
-    context.declaredVariables.define('dart.isVM', 'false');
-
-    // TODO(vsm): Should this be hardcoded?
-    context.declaredVariables.define('dart.library.html', 'true');
-    context.declaredVariables.define('dart.library.io', 'false');
-    context.declaredVariables.define('dart.library.ui', 'false');
+    context.declaredVariables
+      ..define('dart.isVM', 'false')
+      // TODO(vsm): Should this be hardcoded?
+      ..define('dart.library.html', 'true')
+      ..define('dart.library.io', 'false')
+      ..define('dart.library.ui', 'false')
+      ..define('dart.library.mirrors', 'false')
+      ..define('dart.library.isolate', 'false');
 
     if (!context.analysisOptions.strongMode) {
       throw new ArgumentError('AnalysisContext must be strong mode');
diff --git a/pkg/dev_compiler/lib/src/analyzer/reify_coercions.dart b/pkg/dev_compiler/lib/src/analyzer/reify_coercions.dart
index d2604bc..8c774bb 100644
--- a/pkg/dev_compiler/lib/src/analyzer/reify_coercions.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/reify_coercions.dart
@@ -32,8 +32,7 @@
   /// True if the `as` [node] is a required runtime check for soundness.
   // TODO(sra): Find a better way to recognize reified coercion, since we
   // can't set the isSynthetic attribute.
-  static bool isRequiredForSoundness(AsExpression node) =>
-      node.asOperator.offset == 0;
+  static bool isImplicit(AsExpression node) => node.asOperator.offset == 0;
 
   /// Creates an implicit cast for expression [e] to [toType].
   static Expression castExpression(Expression e, DartType toType) {
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 810aa8e..f597ece 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -367,12 +367,15 @@
   }
 
   // Add platform defined variables
-  declaredVariables['dart.isVM'] = 'false';
-
-  // TODO(vsm): Should this be hardcoded?
-  declaredVariables['dart.library.html'] = 'true';
-  declaredVariables['dart.library.io'] = 'false';
-  declaredVariables['dart.library.ui'] = 'false';
+  declaredVariables.addAll({
+    'dart.isVM': 'false',
+    // TODO(vsm): Should this be hardcoded?
+    'dart.library.html': 'true',
+    'dart.library.io': 'false',
+    'dart.library.ui': 'false',
+    'dart.library.mirrors': 'false',
+    'dart.library.isolate': 'false'
+  });
 
   return declaredVariables;
 }
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index a5f1b25..d603efe 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -705,7 +705,6 @@
     }
 
     var hasUnnamedSuper = _hasUnnamedConstructor(superclass);
-    var isCallable = isCallableClass(c);
 
     void emitMixinConstructors(JS.Expression className, InterfaceType mixin) {
       JS.Statement mixinCtor;
@@ -727,10 +726,7 @@
           ctorBody.add(_emitSuperConstructorCall(className, name, jsParams));
         }
         body.add(_addConstructorToClass(
-            className,
-            name,
-            _finishConstructorFunction(
-                jsParams, new JS.Block(ctorBody), isCallable)));
+            className, name, new JS.Fun(jsParams, new JS.Block(ctorBody))));
       }
     }
 
@@ -823,17 +819,7 @@
 
   /// Defines all constructors for this class as ES5 constructors.
   List<JS.Statement> _defineConstructors(Class c, JS.Expression className) {
-    var isCallable = isCallableClass(c);
-
     var body = <JS.Statement>[];
-    if (isCallable) {
-      // Our class instances will have JS `typeof this == "function"`,
-      // so make sure to attach the runtime type information the same way
-      // we would do it for function types.
-      body.add(js.statement('#.prototype[#] = #;',
-          [className, _callHelper('_runtimeType'), className]));
-    }
-
     if (c.isSyntheticMixinImplementation || isMixinAliasClass(c)) {
       // We already handled this when we defined the class.
       return body;
@@ -846,8 +832,7 @@
     var fields = c.fields;
     for (var ctor in c.constructors) {
       if (ctor.isExternal) continue;
-      addConstructor(ctor.name.name,
-          _emitConstructor(ctor, fields, isCallable, className));
+      addConstructor(ctor.name.name, _emitConstructor(ctor, fields, className));
     }
 
     // If classElement has only factory constructors, and it can be mixed in,
@@ -1353,15 +1338,15 @@
         .substituteType(type);
   }
 
-  JS.Expression _emitConstructor(Constructor node, List<Field> fields,
-      bool isCallable, JS.Expression className) {
+  JS.Expression _emitConstructor(
+      Constructor node, List<Field> fields, JS.Expression className) {
     var params = _emitFormalParameters(node.function);
     var body = _withCurrentFunction(
         node.function,
         () => _superDisallowed(
             () => _emitConstructorBody(node, fields, className)));
 
-    return _finishConstructorFunction(params, new JS.Block(body), isCallable)
+    return new JS.Fun(params, new JS.Block(body))
       ..sourceInformation = _nodeEnd(node.fileEndOffset) ??
           _nodeEnd(node.enclosingClass.fileEndOffset);
   }
@@ -1472,25 +1457,6 @@
     return _hasUnnamedSuperConstructor(c);
   }
 
-  JS.Expression _finishConstructorFunction(
-      List<JS.Parameter> params, JS.Block body, bool isCallable) {
-    // We consider a class callable if it inherits from anything with a `call`
-    // method. As a result, we can know the callable JS function was created
-    // at the first constructor that was hit.
-    if (!isCallable) return new JS.Fun(params, body);
-    return js.call(r'''function callableClass(#) {
-          if (typeof this !== "function") {
-            function self(...args) {
-              return self.call.apply(self, args);
-            }
-            self.__proto__ = this.__proto__;
-            callableClass.call(self, #);
-            return self;
-          }
-          #
-        }''', [params, params, body]);
-  }
-
   /// Initialize fields. They follow the sequence:
   ///
   ///   1. field declaration initializer if non-const,
@@ -3788,8 +3754,17 @@
 
   JS.Expression _emitPropertyGet(Expression receiver, Member member,
       [String memberName]) {
-    var jsName = _emitMemberName(memberName ?? member.name.name,
-        type: receiver.getStaticType(types), member: member);
+    memberName ??= member.name.name;
+    var receiverType = receiver.getStaticType(types);
+    // TODO(jmesserly): should tearoff of `.call` on a function type be
+    // encoded as a different node, or possibly eliminated?
+    // (Regardless, we'll still need to handle the callable JS interop classes.)
+    if (memberName == 'call' && _isDirectCallable(receiverType)) {
+      // Tearoff of `call` on a function type is a no-op;
+      return _visitExpression(receiver);
+    }
+    var jsName =
+        _emitMemberName(memberName, type: receiverType, member: member);
     var jsReceiver = _visitExpression(receiver);
 
     // TODO(jmesserly): we need to mark an end span for property accessors so
@@ -3891,27 +3866,23 @@
     var receiverType = receiver.getStaticType(types);
     var typeArgs = arguments.types;
 
-    isDynamicOrFunction(DartType t) =>
-        t == coreTypes.functionClass.rawType || t == const DynamicType();
     bool isCallingDynamicField = target is Member &&
         target.hasGetter &&
-        isDynamicOrFunction(target.getterType);
+        _isDynamicOrFunction(target.getterType);
     if (name == 'call') {
-      if (isCallingDynamicField || isDynamicOrFunction(receiverType)) {
+      if (isCallingDynamicField || _isDynamicOrFunction(receiverType)) {
         if (typeArgs.isNotEmpty) {
           return _callHelper('dgcall(#, [#], #)', [
             jsReceiver,
             args.take(typeArgs.length),
             args.skip(typeArgs.length)
           ]);
-        } else {
-          return _callHelper('dcall(#, #)', [jsReceiver, args]);
         }
+        return _callHelper('dcall(#, #)', [jsReceiver, args]);
+      } else if (_isDirectCallable(receiverType)) {
+        // Call methods on function types should be handled as function calls.
+        return new JS.Call(jsReceiver, args);
       }
-
-      // Call methods on function types or interface types should be handled as
-      // regular function invocations.
-      return new JS.Call(jsReceiver, args);
     }
 
     var jsName = _emitMemberName(name, type: receiverType, member: target);
@@ -3933,9 +3904,35 @@
       assert(typeArgs.isEmpty); // Object methods don't take type args.
       return _callHelper('#(#, #)', [name, jsReceiver, args]);
     }
+    // TODO(jmesserly): remove when Kernel desugars this for us.
+    // Handle `o.m(a)` where `o.m` is a getter returning a class with `call`.
+    if (target is Field || target is Procedure && target.isAccessor) {
+      var fromType = target.getterType;
+      if (fromType is InterfaceType) {
+        var callName = _getImplicitCallTarget(fromType);
+        if (callName != null) {
+          return js.call('#.#.#(#)', [jsReceiver, jsName, callName, args]);
+        }
+      }
+    }
     return js.call('#.#(#)', [jsReceiver, jsName, args]);
   }
 
+  bool _isDirectCallable(DartType t) =>
+      t is FunctionType || t is InterfaceType && usesJSInterop(t.classNode);
+
+  JS.Expression _getImplicitCallTarget(InterfaceType from) {
+    var c = from.classNode;
+    var member = hierarchy.getInterfaceMember(c, new Name("call"));
+    if (member is Procedure && !member.isAccessor && !usesJSInterop(c)) {
+      return _emitMemberName('call', type: from, member: member);
+    }
+    return null;
+  }
+
+  _isDynamicOrFunction(DartType t) =>
+      t == coreTypes.functionClass.rawType || t == const DynamicType();
+
   JS.Expression _emitUnaryOperator(
       Expression expr, Member target, InvocationExpression node) {
     var op = node.name.name;
@@ -5000,24 +4997,6 @@
   @override
   visitClosureCreation(ClosureCreation node) => defaultExpression(node);
 
-  bool isCallableClass(Class c) {
-    // See if we have a "call" with a statically known function type:
-    //
-    // - if it's a method, then it does because all methods do,
-    // - if it's a getter, check the return type.
-    //
-    // Other cases like a getter returning dynamic/Object/Function will be
-    // handled at runtime by the dynamic call mechanism. So we only
-    // concern ourselves with statically known function types.
-    //
-    // We can ignore `noSuchMethod` because:
-    // * `dynamic d; d();` without a declared `call` method is handled by dcall.
-    // * for `class C implements Callable { noSuchMethod(i) { ... } }` we find
-    //   the `call` method on the `Callable` interface.
-    var member = hierarchy.getInterfaceMember(c, new Name("call"));
-    return member != null && member.getterType is FunctionType;
-  }
-
   bool _reifyFunctionType(FunctionNode f) {
     if (_currentLibrary.importUri.scheme != 'dart') return true;
     var parent = f.parent;
diff --git a/pkg/dev_compiler/lib/src/kernel/target.dart b/pkg/dev_compiler/lib/src/kernel/target.dart
index 1e1277a..b1888c6 100644
--- a/pkg/dev_compiler/lib/src/kernel/target.dart
+++ b/pkg/dev_compiler/lib/src/kernel/target.dart
@@ -20,7 +20,6 @@
         'dart:_interceptors',
         'dart:_internal',
         'dart:_isolate_helper',
-        'dart:_js_embedded_names',
         'dart:_js_helper',
         'dart:_js_mirrors',
         'dart:_js_primitives',
diff --git a/pkg/dev_compiler/test/sourcemap/ddc_common.dart b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
index 03bf73c..4efd79a 100644
--- a/pkg/dev_compiler/test/sourcemap/ddc_common.dart
+++ b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
@@ -2,7 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+library dev_compiler.test.sourcemap.ddc_common;
+
 import 'dart:io';
+import 'dart:mirrors' show currentMirrorSystem;
 
 import 'package:front_end/src/api_unstable/ddc.dart' as fe;
 import 'package:path/path.dart' as path;
@@ -127,10 +130,14 @@
   return """
     import { dart, _isolate_helper } from '${uriPathForwardSlashed(jsSdkPath)}';
     import { $inputFileNameNoExt } from '$outputFilename';
+
+    let global = new Function('return this;')();
+    $d8Preambles
+
     let main = $inputFileNameNoExt.main;
     dart.ignoreWhitelistedErrors(false);
     try {
-      _isolate_helper.startRootIsolate(main, []);
+      dartMainRunner(main, []);
     } catch(e) {
       console.error(e.toString(), dart.stackTrace(e).toString());
     }
@@ -181,3 +188,10 @@
 </html>
 """;
 }
+
+Uri selfUri = currentMirrorSystem()
+    .findLibrary(#dev_compiler.test.sourcemap.ddc_common)
+    .uri;
+String d8Preambles = new File.fromUri(
+        selfUri.resolve('../../tool/input_sdk/private/preambles/d8.js'))
+    .readAsStringSync();
diff --git a/pkg/dev_compiler/tool/build_sdk.dart b/pkg/dev_compiler/tool/build_sdk.dart
index 31473dd..efac28d 100644
--- a/pkg/dev_compiler/tool/build_sdk.dart
+++ b/pkg/dev_compiler/tool/build_sdk.dart
@@ -23,7 +23,6 @@
     'dart:_interceptors',
     'dart:_internal',
     'dart:_isolate_helper',
-    'dart:_js_embedded_names',
     'dart:_js_helper',
     'dart:_js_mirrors',
     'dart:_js_primitives',
diff --git a/pkg/dev_compiler/tool/input_sdk/lib/libraries.json b/pkg/dev_compiler/tool/input_sdk/lib/libraries.json
index 4c3c787..74a20ef 100644
--- a/pkg/dev_compiler/tool/input_sdk/lib/libraries.json
+++ b/pkg/dev_compiler/tool/input_sdk/lib/libraries.json
@@ -23,9 +23,6 @@
       "_isolate_helper": {
         "uri": "../private/isolate_helper.dart"
       },
-      "_js_embedded_names": {
-        "uri": "../private/shared/embedded_names.dart"
-      },
       "_js_helper": {
         "uri": "../private/js_helper.dart"
       },
diff --git a/pkg/dev_compiler/tool/input_sdk/libraries.dart b/pkg/dev_compiler/tool/input_sdk/libraries.dart
index cd7a447..6009d0c 100644
--- a/pkg/dev_compiler/tool/input_sdk/libraries.dart
+++ b/pkg/dev_compiler/tool/input_sdk/libraries.dart
@@ -162,11 +162,6 @@
       categories: "",
       documented: false,
       platforms: DART2JS_PLATFORM),
-  "_js_embedded_names": const LibraryInfo(
-      "_internal/js_runtime/lib/shared/embedded_names.dart",
-      categories: "",
-      documented: false,
-      platforms: DART2JS_PLATFORM),
   "_metadata": const LibraryInfo("html/html_common/metadata.dart",
       categories: "", documented: false, platforms: DART2JS_PLATFORM),
   "_debugger": const LibraryInfo("_internal/js_runtime/lib/debugger.dart",
diff --git a/pkg/dev_compiler/tool/input_sdk/libraries.json b/pkg/dev_compiler/tool/input_sdk/libraries.json
index 96f5163..e629fc7 100644
--- a/pkg/dev_compiler/tool/input_sdk/libraries.json
+++ b/pkg/dev_compiler/tool/input_sdk/libraries.json
@@ -22,9 +22,6 @@
       "_isolate_helper": {
         "uri": "_internal/js_runtime/lib/isolate_helper.dart"
       },
-      "_js_embedded_names": {
-        "uri": "_internal/js_runtime/lib/shared/embedded_names.dart"
-      },
       "_js_helper": {
         "uri": "_internal/js_runtime/lib/js_helper.dart"
       },
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
index a4889fd..da1c67b 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/async_patch.dart
@@ -4,16 +4,9 @@
 
 // Patch file for the dart:async library.
 
-import 'dart:_js_helper'
-    show patch, Primitives, ReifyFunctionTypes, DartIterator;
+import 'dart:_js_helper' show patch, ReifyFunctionTypes;
 import 'dart:_isolate_helper'
-    show
-        IsolateNatives,
-        TimerImpl,
-        global,
-        leaveJsAsync,
-        enterJsAsync,
-        isWorker;
+    show TimerImpl, global, leaveJsAsync, enterJsAsync;
 
 import 'dart:_foreign_helper' show JS, JSExportName;
 
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 048f13f..d180abd 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/core_patch.dart
@@ -189,7 +189,7 @@
   }
 
   @patch
-  StackTrace get stackTrace => Primitives.extractStackTrace(this);
+  StackTrace get stackTrace => getTraceFromException(this);
 }
 
 @patch
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
index 853bed9..de914a5 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/io_patch.dart
@@ -460,7 +460,8 @@
 @patch
 class Socket {
   @patch
-  static Future<Socket> connect(host, int port, {sourceAddress}) {
+  static Future<Socket> _connect(host, int port,
+      {sourceAddress, Duration timeout}) {
     throw new UnsupportedError("Socket constructor");
   }
 }
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart
index 07293e6..a0464f3 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/isolate_patch.dart
@@ -4,30 +4,22 @@
 
 // Patch file for the dart:isolate library.
 
-import 'dart:_js_helper' show patch;
-import 'dart:_isolate_helper'
-    show CapabilityImpl, IsolateNatives, ReceivePortImpl, RawReceivePortImpl;
+import 'dart:_js_helper' show patch, NoReifyGeneric;
 
 @patch
 class Isolate {
-  static final _currentIsolateCache = IsolateNatives.currentIsolate;
-
   // `current` must be a getter, not just a final field,
   // to match the external declaration.
   @patch
-  static Isolate get current => _currentIsolateCache;
+  static Isolate get current => _unsupported();
 
   @patch
-  static Future<Uri> get packageRoot {
-    throw new UnsupportedError("Isolate.packageRoot");
-  }
+  static Future<Uri> get packageRoot => _unsupported();
 
   @patch
-  static Future<Uri> get packageConfig {
-    throw new UnsupportedError("Isolate.packageConfig");
-  }
+  static Future<Uri> get packageConfig => _unsupported();
 
-  static Uri _packageBase = Uri.base.resolve(IsolateNatives.packagesBase);
+  static Uri _packageBase = Uri.base.resolve('packages/');
 
   @patch
   static Future<Uri> resolvePackageUri(Uri packageUri) async {
@@ -37,199 +29,90 @@
 
   @patch
   static Future<Isolate> spawn<T>(void entryPoint(T message), T message,
-      {bool paused: false,
-      bool errorsAreFatal,
-      SendPort onExit,
-      SendPort onError}) {
-    bool forcePause =
-        (errorsAreFatal != null) || (onExit != null) || (onError != null);
-    try {
-      // TODO: Consider passing the errorsAreFatal/onExit/onError values
-      //       as arguments to the internal spawnUri instead of setting
-      //       them after the isolate has been created.
-      return IsolateNatives
-          .spawnFunction(entryPoint, message, paused || forcePause)
-          .then((msg) {
-        var isolate = new Isolate(msg[1],
-            pauseCapability: msg[2], terminateCapability: msg[3]);
-        if (forcePause) {
-          if (errorsAreFatal != null) {
-            isolate.setErrorsFatal(errorsAreFatal);
-          }
-          if (onExit != null) {
-            isolate.addOnExitListener(onExit);
-          }
-          if (onError != null) {
-            isolate.addErrorListener(onError);
-          }
-          if (!paused) {
-            isolate.resume(isolate.pauseCapability);
-          }
-        }
-        return isolate;
-      });
-    } catch (e, st) {
-      return new Future<Isolate>.error(e, st);
-    }
-  }
+          {bool paused: false,
+          bool errorsAreFatal,
+          SendPort onExit,
+          SendPort onError}) =>
+      _unsupported();
 
   @patch
   static Future<Isolate> spawnUri(Uri uri, List<String> args, var message,
-      {bool paused: false,
-      SendPort onExit,
-      SendPort onError,
-      bool errorsAreFatal,
-      bool checked,
-      Map<String, String> environment,
-      Uri packageRoot,
-      Uri packageConfig,
-      bool automaticPackageResolution: false}) {
-    if (environment != null) throw new UnimplementedError("environment");
-    if (packageRoot != null) throw new UnimplementedError("packageRoot");
-    if (packageConfig != null) throw new UnimplementedError("packageConfig");
-    // TODO(lrn): Figure out how to handle the automaticPackageResolution
-    // parameter.
-    bool forcePause =
-        (errorsAreFatal != null) || (onExit != null) || (onError != null);
-    try {
-      if (args is List<String>) {
-        for (int i = 0; i < args.length; i++) {
-          if (args[i] is! String) {
-            throw new ArgumentError("Args must be a list of Strings $args");
-          }
-        }
-      } else if (args != null) {
-        throw new ArgumentError("Args must be a list of Strings $args");
-      }
-      // TODO: Handle [packageRoot] somehow, possibly by throwing.
-      // TODO: Consider passing the errorsAreFatal/onExit/onError values
-      //       as arguments to the internal spawnUri instead of setting
-      //       them after the isolate has been created.
-      return IsolateNatives
-          .spawnUri(uri, args, message, paused || forcePause)
-          .then((msg) {
-        var isolate = new Isolate(msg[1],
-            pauseCapability: msg[2], terminateCapability: msg[3]);
-        if (forcePause) {
-          if (errorsAreFatal != null) {
-            isolate.setErrorsFatal(errorsAreFatal);
-          }
-          if (onExit != null) {
-            isolate.addOnExitListener(onExit);
-          }
-          if (onError != null) {
-            isolate.addErrorListener(onError);
-          }
-          if (!paused) {
-            isolate.resume(isolate.pauseCapability);
-          }
-        }
-        return isolate;
-      });
-    } catch (e, st) {
-      return new Future<Isolate>.error(e, st);
-    }
-  }
+          {bool paused: false,
+          SendPort onExit,
+          SendPort onError,
+          bool errorsAreFatal,
+          bool checked,
+          Map<String, String> environment,
+          Uri packageRoot,
+          Uri packageConfig,
+          bool automaticPackageResolution: false}) =>
+      _unsupported();
 
   @patch
-  void _pause(Capability resumeCapability) {
-    var message = new List(3)
-      ..[0] = "pause"
-      ..[1] = pauseCapability
-      ..[2] = resumeCapability;
-    controlPort.send(message);
-  }
+  void _pause(Capability resumeCapability) => _unsupported();
 
   @patch
-  void resume(Capability resumeCapability) {
-    var message = new List(2)
-      ..[0] = "resume"
-      ..[1] = resumeCapability;
-    controlPort.send(message);
-  }
+  void resume(Capability resumeCapability) => _unsupported();
 
   @patch
-  void addOnExitListener(SendPort responsePort, {Object response}) {
-    // TODO(lrn): Can we have an internal method that checks if the receiving
-    // isolate of a SendPort is still alive?
-    var message = new List(3)
-      ..[0] = "add-ondone"
-      ..[1] = responsePort
-      ..[2] = response;
-    controlPort.send(message);
-  }
+  void addOnExitListener(SendPort responsePort, {Object response}) =>
+      _unsupported();
 
   @patch
-  void removeOnExitListener(SendPort responsePort) {
-    var message = new List(2)
-      ..[0] = "remove-ondone"
-      ..[1] = responsePort;
-    controlPort.send(message);
-  }
+  void removeOnExitListener(SendPort responsePort) => _unsupported();
 
   @patch
-  void setErrorsFatal(bool errorsAreFatal) {
-    var message = new List(3)
-      ..[0] = "set-errors-fatal"
-      ..[1] = terminateCapability
-      ..[2] = errorsAreFatal;
-    controlPort.send(message);
-  }
+  void setErrorsFatal(bool errorsAreFatal) => _unsupported();
 
   @patch
-  void kill({int priority: beforeNextEvent}) {
-    controlPort.send(["kill", terminateCapability, priority]);
-  }
+  void kill({int priority: beforeNextEvent}) => _unsupported();
+  @patch
+  void ping(SendPort responsePort,
+          {Object response, int priority: immediate}) =>
+      _unsupported();
 
   @patch
-  void ping(SendPort responsePort, {Object response, int priority: immediate}) {
-    var message = new List(4)
-      ..[0] = "ping"
-      ..[1] = responsePort
-      ..[2] = priority
-      ..[3] = response;
-    controlPort.send(message);
-  }
+  void addErrorListener(SendPort port) => _unsupported();
 
   @patch
-  void addErrorListener(SendPort port) {
-    var message = new List(2)
-      ..[0] = "getErrors"
-      ..[1] = port;
-    controlPort.send(message);
-  }
-
-  @patch
-  void removeErrorListener(SendPort port) {
-    var message = new List(2)
-      ..[0] = "stopErrors"
-      ..[1] = port;
-    controlPort.send(message);
-  }
+  void removeErrorListener(SendPort port) => _unsupported();
 }
 
 /** Default factory for receive ports. */
 @patch
 class ReceivePort {
   @patch
-  factory ReceivePort() = ReceivePortImpl;
+  factory ReceivePort() = _ReceivePort;
 
   @patch
-  factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) {
-    return new ReceivePortImpl.fromRawReceivePort(rawPort);
-  }
+  factory ReceivePort.fromRawReceivePort(RawReceivePort rawPort) =>
+      _unsupported();
+}
+
+/// ReceivePort is supported by dev_compiler because async test packages
+/// (async_helper, unittest) create a dummy receive port to keep the Dart VM
+/// alive.
+class _ReceivePort extends Stream implements ReceivePort {
+  close() {}
+
+  get sendPort => _unsupported();
+
+  listen(onData, {onError, onDone, cancelOnError}) => _unsupported();
 }
 
 @patch
 class RawReceivePort {
   @patch
-  factory RawReceivePort([void handler(event)]) {
-    return new RawReceivePortImpl(handler);
-  }
+  factory RawReceivePort([void handler(event)]) => _unsupported();
 }
 
 @patch
 class Capability {
   @patch
-  factory Capability() = CapabilityImpl;
+  factory Capability() => _unsupported();
+}
+
+@NoReifyGeneric()
+T _unsupported<T>() {
+  throw new UnsupportedError('dart:isolate is not supported on dart4web');
 }
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
index db047d4..b742f40 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/classes.dart
@@ -196,7 +196,7 @@
   if (obj == null) return false;
   if (JS('bool', 'typeof # === "function"', obj)) {
     // A function is a Dart function if it has runtime type information.
-    return _getRuntimeType(obj) == null;
+    return JS('bool', '#[#] == null', obj, _runtimeType);
   }
   // Primitive types are not JS interop types.
   if (JS('bool', 'typeof # !== "object"', obj)) return false;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
index 9f59400..ecdc27c 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/operations.dart
@@ -57,6 +57,28 @@
   return f;
 }
 
+/// Binds the `call` method of an interface type, handling null.
+///
+/// Essentially this works like `obj?.call`. It also handles the needs of
+/// [dsend]/[dcall], returning `null` if no method was found with the given
+/// canonical member [name].
+///
+/// [name] is typically `"call"` but it could be the [extensionSymbol] for
+/// `call`, if we define it on a native type, and [obj] is known statially to be
+/// a native type/interface with `call`.
+bindCall(obj, name) {
+  if (obj == null) return null;
+  var ftype = getMethodType(getType(obj), name);
+  if (ftype == null) return null;
+  var method = JS('', '#[#]', obj, name);
+  var f = JS('', '#.bind(#)', method, obj);
+  // TODO(jmesserly): canonicalize tearoffs.
+  JS('', '#._boundObject = #', f, obj);
+  JS('', '#._boundMethod = #', f, method);
+  JS('', '#[#] = #', f, _runtimeType, ftype);
+  return f;
+}
+
 tagStatic(type, name) {
   var f = JS('', '#.#', type, name);
   if (JS('', '#[#]', f, _runtimeType) == null) {
@@ -72,7 +94,7 @@
 gbind(f, @rest typeArgs) {
   var result =
       JS('', '(...args) => #.apply(null, #.concat(args))', f, typeArgs);
-  var sig = JS('', '#.instantiate(#)', _getRuntimeType(f), typeArgs);
+  var sig = JS('', '#[#].instantiate(#)', f, _runtimeType, typeArgs);
   tag(result, sig);
   return result;
 }
@@ -80,7 +102,10 @@
 // Warning: dload, dput, and dsend assume they are never called on methods
 // implemented by the Object base class as those methods can always be
 // statically resolved.
-dload(obj, field) {
+dload(obj, field, [mirrors = undefined]) {
+  if (JS('bool', 'typeof # == "function" && # == "call"', obj, field)) {
+    return obj;
+  }
   var f = _canonicalMember(obj, field);
 
   trackCall(obj);
@@ -91,28 +116,16 @@
     if (hasMethod(type, f)) return bind(obj, f, null);
 
     // Always allow for JS interop objects.
-    if (isJsInterop(obj)) return JS('', '#[#]', obj, f);
+    if (!JS('bool', '#', mirrors) && isJsInterop(obj)) {
+      return JS('', '#[#]', obj, f);
+    }
   }
   return noSuchMethod(
       obj, new InvocationImpl(field, JS('', '[]'), isGetter: true));
 }
 
 // Version of dload that matches legacy mirrors behavior for JS types.
-dloadMirror(obj, field) {
-  var f = _canonicalMember(obj, field);
-
-  trackCall(obj);
-  if (f != null) {
-    var type = getType(obj);
-
-    if (hasField(type, f) || hasGetter(type, f)) return JS('', '#[#]', obj, f);
-    if (hasMethod(type, f)) return bind(obj, f, JS('', 'void 0'));
-
-    // Do not support calls on JS interop objects to match Dart2JS behavior.
-  }
-  return noSuchMethod(
-      obj, new InvocationImpl(field, JS('', '[]'), isGetter: true));
-}
+dloadMirror(obj, field) => dload(obj, field, true);
 
 _stripGenericArguments(type) {
   var genericClass = getGenericClass(type);
@@ -124,31 +137,20 @@
 // behavior for JS types.
 // TODO(jacobr): remove the type checking rules workaround when mirrors based
 // PageLoader code can generate the correct reified generic types.
-dputMirror(obj, field, value) {
-  var f = _canonicalMember(obj, field);
-  trackCall(obj);
-  if (f != null) {
-    var setterType = getSetterType(getType(obj), f);
-    if (setterType != null) {
-      setterType = _stripGenericArguments(setterType);
-      return JS('', '#[#] = #._check(#)', obj, f, setterType, value);
-    }
-  }
-  noSuchMethod(
-      obj, new InvocationImpl(field, JS('', '[#]', value), isSetter: true));
-  return value;
-}
+dputMirror(obj, field, value) => dput(obj, field, value, true);
 
-dput(obj, field, value) {
+dput(obj, field, value, [mirrors = undefined]) {
   var f = _canonicalMember(obj, field);
   trackCall(obj);
   if (f != null) {
     var setterType = getSetterType(getType(obj), f);
     if (setterType != null) {
+      if (JS('bool', '#', mirrors))
+        setterType = _stripGenericArguments(setterType);
       return JS('', '#[#] = #._check(#)', obj, f, setterType, value);
     }
     // Always allow for JS interop objects.
-    if (isJsInterop(obj)) {
+    if (!JS('bool', '#', mirrors) && isJsInterop(obj)) {
       return JS('', '#[#] = #', obj, f, value);
     }
   }
@@ -260,7 +262,7 @@
   function callNSM() {
     return $noSuchMethod(originalTarget, new $InvocationImpl.new(
         $name, $args, {
-          namedArguments: $extractNamedArgs($args),
+          namedArguments: ${extractNamedArgs(args)},
           typeArguments: $typeArgs,
           isMethod: true
         }));
@@ -269,19 +271,15 @@
     // We're not a function (and hence not a method either)
     // Grab the `call` method if it's not a function.
     if ($f != null) {
-      $ftype = $getMethodType($getType($f), 'call');
-      $f = f.call ? $bind($f, 'call') : void 0;
+      $f = ${bindCall(f, _canonicalMember(f, 'call'))};
+      $ftype = null;
     }
-    if (!($f instanceof Function)) {
-      return callNSM();
-    }
+    if ($f == null) return callNSM();
   }
   // If f is a function, but not a method (no method type)
   // then it should have been a function valued field, so
   // get the type from the function.
-  if ($ftype == null) {
-    $ftype = $_getRuntimeType($f);
-  }
+  if ($ftype == null) $ftype = $f[$_runtimeType];
 
   if ($ftype == null) {
     // TODO(leafp): Allow JS objects to go through?
@@ -322,11 +320,13 @@
   return callNSM();
 })()''');
 
-dcall(f, @rest args) =>
-    _checkAndCall(f, _getRuntimeType(f), JS('', 'void 0'), null, args, 'call');
+dcall(f, @rest args) => callFunction(f, null, args);
 
-dgcall(f, typeArgs, @rest args) => _checkAndCall(
-    f, _getRuntimeType(f), JS('', 'void 0'), typeArgs, args, 'call');
+dgcall(f, typeArgs, @rest args) => callFunction(f, typeArgs, args);
+
+callFunction(f, typeArgs, args) {
+  return _checkAndCall(f, null, JS('', 'void 0'), typeArgs, args, 'call');
+}
 
 /// Helper for REPL dynamic invocation variants that make a best effort to
 /// enable accessing private members across library boundaries.
@@ -368,14 +368,13 @@
   return $callback(rawField);
 })()''');
 
-dloadRepl(obj, field) =>
-    _dhelperRepl(obj, field, (resolvedField) => dload(obj, resolvedField));
+dloadRepl(obj, field) => _dhelperRepl(obj, field, (f) => dload(obj, f, false));
 
-dputRepl(obj, field, value) => _dhelperRepl(
-    obj, field, (resolvedField) => dput(obj, resolvedField, value));
+dputRepl(obj, field, value) =>
+    _dhelperRepl(obj, field, (f) => dput(obj, f, value, false));
 
-callMethodRepl(obj, method, typeArgs, args) => _dhelperRepl(obj, method,
-    (resolvedField) => callMethod(obj, resolvedField, typeArgs, args, method));
+callMethodRepl(obj, method, typeArgs, args) => _dhelperRepl(
+    obj, method, (f) => callMethod(obj, f, typeArgs, args, method));
 
 dsendRepl(obj, method, @rest args) => callMethodRepl(obj, method, null, args);
 
@@ -384,6 +383,9 @@
 
 /// Shared code for dsend, dindex, and dsetindex.
 callMethod(obj, name, typeArgs, args, displayName) {
+  if (JS('bool', 'typeof # == "function" && # == "call"', obj, name)) {
+    return callFunction(obj, typeArgs, args);
+  }
   var symbol = _canonicalMember(obj, name);
   if (symbol == null) {
     return noSuchMethod(
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
index c9f32dd..feb98ad 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/rtti.dart
@@ -129,9 +129,6 @@
 /// Given a WrappedType, return the internal runtime type object.
 unwrapType(WrappedType obj) => obj._wrappedType;
 
-/// Assumes that value is non-null
-_getRuntimeType(value) => JS('', '#[#]', value, _runtimeType);
-
 /// Return the module name for a raw library object.
 getModuleName(value) => JS('', '#[#]', value, _moduleName);
 
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
index 08464ee..3352609 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/types.dart
@@ -692,7 +692,7 @@
   return type;
 }
 
-bool isType(obj) => JS('', '# === #', _getRuntimeType(obj), Type);
+bool isType(obj) => JS('', '#[#] === #', obj, _runtimeType, Type);
 
 void checkTypeBound(type, bound, name) {
   if (JS('bool', '#', isSubtype(type, bound))) return;
@@ -715,7 +715,7 @@
   }
 
   // Instance types
-  let tag = $_getRuntimeType($type);
+  let tag = $type[$_runtimeType];
   if (tag === $Type) {
     let name = $type.name;
     let args = $getGenericArgs($type);
@@ -744,11 +744,6 @@
   return "JSObject<" + $type.name + ">";
 })()''');
 
-/// Returns `true` if we have a non-generic function type representation or the
-/// type for `Function`, which is a supertype of all functions in Dart.
-bool _isFunctionType(type) => JS('bool', '# instanceof # || # === #', type,
-    AbstractFunctionType, type, Function);
-
 /// Returns true if [ft1] <: [ft2].
 /// Returns false if [ft1] </: [ft2] in both spec and strong mode
 /// Returns null if [ft1] </: [ft2] in strong mode, but spec mode
@@ -757,14 +752,6 @@
 /// position, and hence the direction of the check for function types
 /// corresponds to the direction of the check according to the Dart spec.
 isFunctionSubtype(ft1, ft2, isCovariant) => JS('', '''(() => {
-  if ($ft2 === $Function) {
-    return true;
-  }
-
-  if ($ft1 === $Function) {
-    return false;
-  }
-
   let ret1 = $ft1.returnType;
   let ret2 = $ft2.returnType;
 
@@ -915,25 +902,24 @@
   // "Traditional" name-based subtype check.  Avoid passing
   // function types to the class subtype checks, since we don't
   // currently distinguish between generic typedefs and classes.
-  if (!($t1 instanceof $AbstractFunctionType) &&
-      !($t2 instanceof $AbstractFunctionType)) {
-    let result = $isClassSubType($t1, $t2, $isCovariant);
-    if (result === true || result === null) return result;
-  }
+  if (!($t2 instanceof $AbstractFunctionType)) {
+    // t2 is an interface type.
 
-  if ($t2 instanceof $AnonymousJSType) {
+    if ($t1 instanceof $AbstractFunctionType) {
+      // Function types are only subtypes of interface types `Function` (and top
+      // types, handled already above).
+      return $t2 === $Function;
+    }
+
     // All JS types are subtypes of anonymous JS types.
-    return $t1 === $jsobject;
+    if ($t1 === $jsobject && $t2 instanceof $AnonymousJSType) return true;
+
+    // Compare two interface types:
+    return $isClassSubType($t1, $t2, $isCovariant);
   }
 
   // Function subtyping.
-
-  // Handle Objects with call methods.  Those are functions
-  // even if they do not *nominally* subtype core.Function.
-  if (!$_isFunctionType($t1)) {
-    $t1 = $getMethodType($t1, 'call');
-    if ($t1 == null) return false;
-  }
+  if (!($t1 instanceof $AbstractFunctionType)) return false;
 
   // Unwrap typedefs.
   if ($t1 instanceof $Typedef) $t1 = $t1.functionType;
@@ -949,7 +935,8 @@
     //
     // where TFresh is a list of fresh type variables that both g1 and g2 will
     // be instantiated with.
-    if ($t1.formalCount !== $t2.formalCount) return false;
+    let formalCount = $t1.formalCount;
+    if (formalCount !== $t2.formalCount) return false;
 
     // Using either function's type formals will work as long as they're both
     // instantiated with the same ones. The instantiate operation is guaranteed
@@ -969,24 +956,20 @@
     let t1Bounds = $t1.instantiateTypeBounds(fresh);
     let t2Bounds = $t2.instantiateTypeBounds(fresh);
     // TODO(jmesserly): we could optimize for the common case of no bounds.
-    for (let i = 0; i < $t1.formalCount; i++) {
+    for (let i = 0; i < formalCount; i++) {
       if (!$_isSubtype(t2Bounds[i], t1Bounds[i], !$isCovariant)) {
         return false;
       }
     }
 
-    return $isFunctionSubtype(
-        $t1.instantiate(fresh), $t2.instantiate(fresh), $isCovariant);
+    $t1 = $t1.instantiate(fresh);
+    $t2 = $t2.instantiate(fresh);
+  } else if ($t2 instanceof $GenericFunctionType) {
+    return false;
   }
 
-  if ($t2 instanceof $GenericFunctionType) return false;
-
   // Handle non-generic functions.
-  if ($_isFunctionType($t1) && $_isFunctionType($t2)) {
-    return $isFunctionSubtype($t1, $t2, $isCovariant);
-  }
-
-  return false;
+  return $isFunctionSubtype($t1, $t2, $isCovariant);
 })()''');
 
 isClassSubType(t1, t2, isCovariant) => JS('', '''(() => {
@@ -1001,9 +984,11 @@
   if ($t1 instanceof $LazyJSType) $t1 = $t1.rawJSTypeForCheck();
   if ($t2 instanceof $LazyJSType) $t2 = $t2.rawJSTypeForCheck();
 
-  if ($t1 == $t2) return true;
+  if ($t1 === $t2) return true;
+  if ($t1 === $Object) return false;
 
-  if ($t1 == $Object) return false;
+  // Classes cannot subtype `Function` or vice versa.
+  if ($t1 === $Function || $t2 === $Function) return false;
 
   // If t1 is a JS Object, we may not hit core.Object.
   if ($t1 == null) return $t2 == $Object || $t2 == $dynamic;
@@ -1085,8 +1070,7 @@
   // The signature of this method guarantees that instance is a T, so we
   // should have a valid non-empty list at this point.
   assert(typeArgs != null && typeArgs.isNotEmpty);
-  return _checkAndCall(
-      f, _getRuntimeType(f), JS('', 'void 0'), typeArgs, [], 'call');
+  return callFunction(f, typeArgs, []);
 }
 
 // Let t2 = T<T1, ..., Tn>
diff --git a/pkg/dev_compiler/tool/input_sdk/private/foreign_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/foreign_helper.dart
index c5e77b7..bcb2736 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/foreign_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/foreign_helper.dart
@@ -138,32 +138,6 @@
 }
 
 /**
- * Returns the isolate in which this code is running.
- */
-IsolateContext JS_CURRENT_ISOLATE_CONTEXT() {}
-
-abstract class IsolateContext {
-  /// Holds a (native) JavaScript instance of Isolate, see
-  /// finishIsolateConstructorFunction in emitter.dart.
-  get isolateStatics;
-}
-
-/**
- * Invokes [function] in the context of [isolate].
- */
-JS_CALL_IN_ISOLATE(isolate, Function function) {}
-
-/**
- * Sets the current isolate to [isolate].
- */
-void JS_SET_CURRENT_ISOLATE(isolate) {}
-
-/**
- * Creates an isolate and returns it.
- */
-JS_CREATE_ISOLATE() {}
-
-/**
  * Returns the JavaScript constructor function for Dart's Object class.
  * This can be used for type tests, as in
  *
@@ -205,11 +179,6 @@
  */
 String JS_IS_INDEXABLE_FIELD_NAME() {}
 
-/**
- * Returns the object corresponding to Namer.CURRENT_ISOLATE.
- */
-JS_CURRENT_ISOLATE() {}
-
 /// Returns the name used for generated function types on classes and methods.
 String JS_SIGNATURE_NAME() {}
 
@@ -252,11 +221,6 @@
 /// Returns the JS name for [name] from the Namer.
 String JS_GET_NAME(String name) {}
 
-/// Reads an embedded global.
-///
-/// The [name] should be a constant defined in the `_embedded_names` library.
-JS_EMBEDDED_GLOBAL(String typeDescription, String name) {}
-
 /// Returns the state of a flag that is determined by the state of the compiler
 /// when the program has been analyzed.
 bool JS_GET_FLAG(String name) {}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
index 7de9168..32da1d3 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/interceptors.dart
@@ -100,7 +100,7 @@
 // it to be picked up as an extension type.
 @JsPeerInterface(name: 'TypeError')
 class NullError extends Interceptor implements NoSuchMethodError {
-  StackTrace get stackTrace => Primitives.extractStackTrace(this);
+  StackTrace get stackTrace => getTraceFromException(this);
 
   String toString() {
     // TODO(vsm): Distinguish between null reference errors and other
@@ -161,7 +161,7 @@
 // it to be picked up as an extension type.
 @JsPeerInterface(name: 'RangeError')
 class JSRangeError extends Interceptor implements ArgumentError {
-  StackTrace get stackTrace => Primitives.extractStackTrace(this);
+  StackTrace get stackTrace => getTraceFromException(this);
 
   get invalidValue => null;
   get name => null;
diff --git a/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
index 15ee787..3facf9e 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/isolate_helper.dart
@@ -5,53 +5,8 @@
 library dart._isolate_helper;
 
 import 'dart:_runtime' as dart;
-import 'dart:_js_embedded_names'
-    show
-        CLASS_ID_EXTRACTOR,
-        CLASS_FIELDS_EXTRACTOR,
-        CURRENT_SCRIPT,
-        GLOBAL_FUNCTIONS,
-        INITIALIZE_EMPTY_INSTANCE,
-        INSTANCE_FROM_CLASS_ID;
-
 import 'dart:async';
-import 'dart:collection' show Queue, HashMap;
-import 'dart:isolate';
-import 'dart:_native_typed_data' show NativeByteBuffer, NativeTypedData;
-
-import 'dart:_js_helper' show InternalMap, Null, Primitives, random64;
-
-import 'dart:_foreign_helper'
-    show
-        JS,
-        JS_CREATE_ISOLATE,
-        JS_CURRENT_ISOLATE_CONTEXT,
-        JS_CURRENT_ISOLATE,
-        JS_EMBEDDED_GLOBAL,
-        JS_SET_CURRENT_ISOLATE,
-        IsolateContext;
-
-import 'dart:_interceptors'
-    show
-        Interceptor,
-        JSArray,
-        JSExtendableArray,
-        JSFixedArray,
-        JSIndexable,
-        JSMutableArray,
-        JSObject;
-
-part 'isolate_serialization.dart';
-
-/**
- * Called by the compiler to support switching
- * between isolates when we get a callback from the DOM.
- */
-_callInIsolate(_IsolateContext isolate, Function function) {
-  var result = isolate.eval(function);
-  _globalState.topEventLoop.run();
-  return result;
-}
+import 'dart:_foreign_helper' show JS;
 
 /// Marks entering a JavaScript async operation to keep the worker alive.
 ///
@@ -63,638 +18,34 @@
 ///
 /// These functions only has to be called for code that can be run from a
 /// worker-isolate (so not for general dom operations).
-enterJsAsync() {
-  _globalState.topEventLoop._activeJsAsyncCount++;
-}
+///
+// TODO(jmesserly): we could potentially use this to track when all async
+// operations have completed, for example, to run a bunch of test `main()`
+// methods in batch mode the same V8 process.
+enterJsAsync() {}
 
 /// Marks leaving a javascript async operation.
 ///
 /// See [enterJsAsync].
-leaveJsAsync() {
-  _globalState.topEventLoop._activeJsAsyncCount--;
-  assert(_globalState.topEventLoop._activeJsAsyncCount >= 0);
-}
+leaveJsAsync() {}
 
-/// Returns true if we are currently in a worker context.
-bool isWorker() => _globalState.isWorker;
-
-/**
- * Called by the compiler to fetch the current isolate context.
- */
-_IsolateContext _currentIsolate() => _globalState.currentContext;
-
-/**
- * Wrapper that takes the dart entry point and runs it within an isolate. The
- * dart2js compiler will inject a call of the form
- * [: startRootIsolate(main); :] when it determines that this wrapping
- * is needed. For single-isolate applications (e.g. hello world), this
- * call is not emitted.
- */
-void startRootIsolate(entry, args) {
-  // The dartMainRunner can inject a new arguments array. We pass the arguments
-  // through a "JS", so that the type-inferrer loses track of it.
-  args = JS("", "#", args);
-  if (args == null) args = [];
-  if (args is! List) {
-    throw new ArgumentError("Arguments to main must be a List: $args");
-  }
-  _globalState = new _Manager(entry);
-
-  // Don't start the main loop again, if we are in a worker.
-  if (_globalState.isWorker) return;
-  final rootContext = new _IsolateContext();
-  _globalState.rootContext = rootContext;
-
-  // BUG(5151491): Setting currentContext should not be necessary, but
-  // because closures passed to the DOM as event handlers do not bind their
-  // isolate automatically we try to give them a reasonable context to live in
-  // by having a "default" isolate (the first one created).
-  _globalState.currentContext = rootContext;
-  if (entry is _MainFunctionArgs) {
-    rootContext.eval(() {
-      (entry as dynamic)(args);
-    });
-  } else if (entry is _MainFunctionArgsMessage) {
-    rootContext.eval(() {
-      (entry as dynamic)(args, null);
-    });
+/// Deprecated way of initializing `main()` in DDC, typically called from JS.
+@deprecated
+void startRootIsolate(main, args) {
+  if (args == null) args = <String>[];
+  if (args is List) {
+    if (args is! List<String>) args = new List<String>.from(args);
+    if (main is _MainFunction) {
+      main();
+    } else if (main is _MainFunctionArgs) {
+      main(args);
+    } else if (main is _MainFunctionArgsMessage) {
+      main(args, null);
+    } else {
+      (main as dynamic)(args);
+    }
   } else {
-    rootContext.eval(entry);
-  }
-  _globalState.topEventLoop.run();
-}
-
-/********************************************************
-  Inserted from lib/isolate/dart2js/isolateimpl.dart
- ********************************************************/
-
-/**
- * Concepts used here:
- *
- * "manager" - A manager contains one or more isolates, schedules their
- * execution, and performs other plumbing on their behalf.  The isolate
- * present at the creation of the manager is designated as its "root isolate".
- * A manager may, for example, be implemented on a web Worker.
- *
- * [_Manager] - State present within a manager (exactly once, as a global).
- *
- * [_ManagerStub] - A handle held within one manager that allows interaction
- * with another manager.  A target manager may be addressed by zero or more
- * [_ManagerStub]s.
- * TODO(ahe): The _ManagerStub concept is broken.  It was an attempt
- * to create a common interface between the native Worker class and
- * _MainManagerStub.
- */
-
-/**
- * A native object that is shared across isolates. This object is visible to all
- * isolates running under the same manager (either UI or background web worker).
- *
- * This is code that is intended to 'escape' the isolate boundaries in order to
- * implement the semantics of isolates in JavaScript. Without this we would have
- * been forced to implement more code (including the top-level event loop) in
- * JavaScript itself.
- */
-// TODO(eub, sigmund): move the "manager" to be entirely in JS.
-// Running any Dart code outside the context of an isolate gives it
-// the chance to break the isolate abstraction.
-// TODO(vsm): This was changed from init.globalState.
-// See: https://github.com/dart-lang/dev_compiler/issues/164
-_Manager get _globalState => JS("_Manager", "dart.globalState");
-
-set _globalState(_Manager val) {
-  // TODO(vsm): This was changed from init.globalState.
-  // See: https://github.com/dart-lang/dev_compiler/issues/164
-  JS("void", "dart.globalState = #", val);
-}
-
-/** State associated with the current manager. See [globalState]. */
-// TODO(sigmund): split in multiple classes: global, thread, main-worker states?
-class _Manager {
-  /** Next available isolate id within this [_Manager]. */
-  int nextIsolateId = 0;
-
-  /** id assigned to this [_Manager]. */
-  int currentManagerId = 0;
-
-  /**
-   * Next available manager id. Only used by the main manager to assign a unique
-   * id to each manager created by it.
-   */
-  int nextManagerId = 1;
-
-  /** Context for the currently running [Isolate]. */
-  _IsolateContext currentContext = null;
-
-  /** Context for the root [Isolate] that first run in this [_Manager]. */
-  _IsolateContext rootContext = null;
-
-  /** The top-level event loop. */
-  _EventLoop topEventLoop;
-
-  /** Whether this program is running from the command line. */
-  bool fromCommandLine;
-
-  /** Whether this [_Manager] is running as a web worker. */
-  bool isWorker;
-
-  /** Whether we support spawning web workers. */
-  bool supportsWorkers;
-
-  /**
-   * Whether to use web workers when implementing isolates. Set to false for
-   * debugging/testing.
-   */
-  bool get useWorkers => supportsWorkers;
-
-  /**
-   * Registry of isolates. Isolates must be registered if, and only if, receive
-   * ports are alive.  Normally no open receive-ports means that the isolate is
-   * dead, but DOM callbacks could resurrect it.
-   */
-  Map<int, _IsolateContext> isolates;
-
-  /** Reference to the main [_Manager].  Null in the main [_Manager] itself. */
-  _MainManagerStub mainManager;
-
-  /// Registry of active Web Workers.  Only used in the main [_Manager].
-  Map<int, dynamic /* Worker */ > managers;
-
-  /** The entry point given by [startRootIsolate]. */
-  final Function entry;
-
-  _Manager(this.entry) {
-    _nativeDetectEnvironment();
-    topEventLoop = new _EventLoop();
-    isolates = new Map<int, _IsolateContext>();
-    managers = new Map<int, dynamic>();
-    if (isWorker) {
-      // "if we are not the main manager ourself" is the intent.
-      mainManager = new _MainManagerStub();
-      _nativeInitWorkerMessageHandler();
-    }
-  }
-
-  void _nativeDetectEnvironment() {
-    bool isWindowDefined = globalWindow != null;
-    bool isWorkerDefined = globalWorker != null;
-
-    isWorker = !isWindowDefined && globalPostMessageDefined;
-    supportsWorkers =
-        isWorker || (isWorkerDefined && IsolateNatives.thisScript != null);
-    fromCommandLine = !isWindowDefined && !isWorker;
-  }
-
-  void _nativeInitWorkerMessageHandler() {
-    var function = JS(
-        '',
-        "(function (f, a) { return function (e) { f(a, e); }})(#, #)",
-        IsolateNatives._processWorkerMessage,
-        mainManager);
-    JS("void", r"#.onmessage = #", global, function);
-    // We ensure dartPrint is defined so that the implementation of the Dart
-    // print method knows what to call.
-    JS(
-        '',
-        '''#.dartPrint = #.dartPrint || (function(serialize) {
-  return function (object) {
-    var _self = #;
-    if (_self.console && _self.console.log) {
-      _self.console.log(object)
-    } else {
-      _self.postMessage(serialize(object));
-    }
-  }
-})(#)''',
-        global,
-        global,
-        global,
-        _serializePrintMessage);
-  }
-
-  static _serializePrintMessage(object) {
-    return _serializeMessage({"command": "print", "msg": object});
-  }
-
-  /**
-   * Close the worker running this code if all isolates are done and
-   * there are no active async JavaScript tasks still running.
-   */
-  void maybeCloseWorker() {
-    if (isWorker && isolates.isEmpty && topEventLoop._activeJsAsyncCount == 0) {
-      mainManager.postMessage(_serializeMessage({'command': 'close'}));
-    }
-  }
-}
-
-/** Context information tracked for each isolate. */
-class _IsolateContext implements IsolateContext {
-  /** Current isolate id. */
-  final int id = _globalState.nextIsolateId++;
-
-  /** Registry of receive ports currently active on this isolate. */
-  final Map<int, RawReceivePortImpl> ports = new Map<int, RawReceivePortImpl>();
-
-  /** Registry of weak receive ports currently active on this isolate. */
-  final Set<int> weakPorts = new Set<int>();
-
-  /** Holds isolate globals (statics and top-level properties). */
-  // native object containing all globals of an isolate.
-  final isolateStatics = JS_CREATE_ISOLATE();
-
-  final RawReceivePortImpl controlPort = new RawReceivePortImpl._controlPort();
-
-  final Capability pauseCapability = new Capability();
-  final Capability terminateCapability = new Capability(); // License to kill.
-
-  /// Boolean flag set when the initial method of the isolate has been executed.
-  ///
-  /// Used to avoid considering the isolate dead when it has no open
-  /// receive ports and no scheduled timers, because it hasn't had time to
-  /// create them yet.
-  bool initialized = false;
-
-  // TODO(lrn): Store these in single "PauseState" object, so they don't take
-  // up as much room when not pausing.
-  bool isPaused = false;
-  List<_IsolateEvent> delayedEvents = [];
-  Set<Capability> pauseTokens = new Set();
-
-  // Container with the "on exit" handler send-ports.
-  var doneHandlers;
-
-  /**
-   * Queue of functions to call when the current event is complete.
-   *
-   * These events are not just put at the front of the event queue, because
-   * they represent control messages, and should be handled even if the
-   * event queue is paused.
-   */
-  var _scheduledControlEvents;
-  bool _isExecutingEvent = false;
-
-  /** Whether uncaught errors are considered fatal. */
-  bool errorsAreFatal = true;
-
-  // Set of ports that listen to uncaught errors.
-  Set<SendPort> errorPorts = new Set();
-
-  _IsolateContext() {
-    this.registerWeak(controlPort._id, controlPort);
-  }
-
-  void addPause(Capability authentification, Capability resume) {
-    if (pauseCapability != authentification) return;
-    if (pauseTokens.add(resume) && !isPaused) {
-      isPaused = true;
-    }
-    _updateGlobalState();
-  }
-
-  void removePause(Capability resume) {
-    if (!isPaused) return;
-    pauseTokens.remove(resume);
-    if (pauseTokens.isEmpty) {
-      while (delayedEvents.isNotEmpty) {
-        _IsolateEvent event = delayedEvents.removeLast();
-        _globalState.topEventLoop.prequeue(event);
-      }
-      isPaused = false;
-    }
-    _updateGlobalState();
-  }
-
-  void addDoneListener(SendPort responsePort) {
-    if (doneHandlers == null) {
-      doneHandlers = [];
-    }
-    // If necessary, we can switch doneHandlers to a Set if it gets larger.
-    // That is not expected to happen in practice.
-    if (doneHandlers.contains(responsePort)) return;
-    doneHandlers.add(responsePort);
-  }
-
-  void removeDoneListener(SendPort responsePort) {
-    if (doneHandlers == null) return;
-    doneHandlers.remove(responsePort);
-  }
-
-  void setErrorsFatal(Capability authentification, bool errorsAreFatal) {
-    if (terminateCapability != authentification) return;
-    this.errorsAreFatal = errorsAreFatal;
-  }
-
-  void handlePing(SendPort responsePort, int pingType) {
-    if (pingType == Isolate.immediate ||
-        (pingType == Isolate.beforeNextEvent && !_isExecutingEvent)) {
-      responsePort.send(null);
-      return;
-    }
-    void respond() {
-      responsePort.send(null);
-    }
-
-    assert(pingType == Isolate.beforeNextEvent);
-    if (_scheduledControlEvents == null) {
-      _scheduledControlEvents = new Queue();
-    }
-    _scheduledControlEvents.addLast(respond);
-  }
-
-  void handleKill(Capability authentification, int priority) {
-    if (this.terminateCapability != authentification) return;
-    if (priority == Isolate.immediate ||
-        (priority == Isolate.beforeNextEvent && !_isExecutingEvent)) {
-      kill();
-      return;
-    }
-    assert(priority == Isolate.beforeNextEvent);
-    if (_scheduledControlEvents == null) {
-      _scheduledControlEvents = new Queue();
-    }
-    _scheduledControlEvents.addLast(kill);
-  }
-
-  void addErrorListener(SendPort port) {
-    errorPorts.add(port);
-  }
-
-  void removeErrorListener(SendPort port) {
-    errorPorts.remove(port);
-  }
-
-  /** Function called with an uncaught error. */
-  void handleUncaughtError(error, StackTrace stackTrace) {
-    // Just print the error if there is no error listener registered.
-    if (errorPorts.isEmpty) {
-      // An uncaught error in the root isolate will terminate the program?
-      if (errorsAreFatal && identical(this, _globalState.rootContext)) {
-        // The error will be rethrown to reach the global scope, so
-        // don't print it.
-        return;
-      }
-      if (JS('bool', '#.console && #.console.error', global, global)) {
-        JS('void', '#.console.error(#, #)', global, error, stackTrace);
-      } else {
-        print(error);
-        if (stackTrace != null) print(stackTrace);
-      }
-      return;
-    }
-    List message = new List(2)
-      ..[0] = error.toString()
-      ..[1] = (stackTrace == null) ? null : stackTrace.toString();
-    for (SendPort port in errorPorts) port.send(message);
-  }
-
-  /**
-   * Run [code] in the context of the isolate represented by [this].
-   */
-  dynamic eval(Function code) {
-    var old = _globalState.currentContext;
-    _globalState.currentContext = this;
-    this._setGlobals();
-    var result = null;
-    _isExecutingEvent = true;
-    try {
-      result = code();
-    } catch (e, s) {
-      handleUncaughtError(e, s);
-      if (errorsAreFatal) {
-        kill();
-        // An uncaught error in the root context terminates all isolates.
-        if (identical(this, _globalState.rootContext)) {
-          rethrow;
-        }
-      }
-    } finally {
-      _isExecutingEvent = false;
-      _globalState.currentContext = old;
-      if (old != null) old._setGlobals();
-      if (_scheduledControlEvents != null) {
-        while (_scheduledControlEvents.isNotEmpty) {
-          (_scheduledControlEvents.removeFirst())();
-        }
-      }
-    }
-    return result;
-  }
-
-  void _setGlobals() {
-    JS_SET_CURRENT_ISOLATE(isolateStatics);
-  }
-
-  /**
-   * Handle messages coming in on the control port.
-   *
-   * These events do not go through the event queue.
-   * The `_globalState.currentContext` context is not set to this context
-   * during the handling.
-   */
-  void handleControlMessage(message) {
-    switch (message[0]) {
-      case "pause":
-        addPause(message[1], message[2]);
-        break;
-      case "resume":
-        removePause(message[1]);
-        break;
-      case 'add-ondone':
-        addDoneListener(message[1]);
-        break;
-      case 'remove-ondone':
-        removeDoneListener(message[1]);
-        break;
-      case 'set-errors-fatal':
-        setErrorsFatal(message[1], message[2]);
-        break;
-      case "ping":
-        handlePing(message[1], message[2]);
-        break;
-      case "kill":
-        handleKill(message[1], message[2]);
-        break;
-      case "getErrors":
-        addErrorListener(message[1]);
-        break;
-      case "stopErrors":
-        removeErrorListener(message[1]);
-        break;
-      default:
-    }
-  }
-
-  /** Looks up a port registered for this isolate. */
-  RawReceivePortImpl lookup(int portId) => ports[portId];
-
-  void _addRegistration(int portId, RawReceivePortImpl port) {
-    if (ports.containsKey(portId)) {
-      throw new Exception("Registry: ports must be registered only once.");
-    }
-    ports[portId] = port;
-  }
-
-  /** Registers a port on this isolate. */
-  void register(int portId, RawReceivePortImpl port) {
-    _addRegistration(portId, port);
-    _updateGlobalState();
-  }
-
-  /**
-   * Registers a weak port on this isolate.
-   *
-   * The port does not keep the isolate active.
-   */
-  void registerWeak(int portId, RawReceivePortImpl port) {
-    weakPorts.add(portId);
-    _addRegistration(portId, port);
-  }
-
-  void _updateGlobalState() {
-    if (ports.length - weakPorts.length > 0 || isPaused || !initialized) {
-      _globalState.isolates[id] = this; // indicate this isolate is active
-    } else {
-      kill();
-    }
-  }
-
-  void kill() {
-    if (_scheduledControlEvents != null) {
-      // Kill all pending events.
-      _scheduledControlEvents.clear();
-    }
-    // Stop listening on all ports.
-    // This should happen before sending events to done handlers, in case
-    // we are listening on ourselves.
-    // Closes all ports, including control port.
-    for (var port in ports.values) {
-      port._close();
-    }
-    ports.clear();
-    weakPorts.clear();
-    _globalState.isolates.remove(id); // indicate this isolate is not active
-    errorPorts.clear();
-    if (doneHandlers != null) {
-      for (SendPort port in doneHandlers) {
-        port.send(null);
-      }
-      doneHandlers = null;
-    }
-  }
-
-  /** Unregister a port on this isolate. */
-  void unregister(int portId) {
-    ports.remove(portId);
-    weakPorts.remove(portId);
-    _updateGlobalState();
-  }
-}
-
-/** Represent the event loop on a javascript thread (DOM or worker). */
-class _EventLoop {
-  final Queue<_IsolateEvent> events = new Queue<_IsolateEvent>();
-
-  /// The number of waiting callbacks not controlled by the dart event loop.
-  ///
-  /// This could be timers or http requests. The worker will only be killed if
-  /// this count reaches 0.
-  /// Access this by using [enterJsAsync] before starting a JavaScript async
-  /// operation and [leaveJsAsync] when the callback has fired.
-  int _activeJsAsyncCount = 0;
-
-  _EventLoop();
-
-  void enqueue(isolate, fn, msg) {
-    events.addLast(new _IsolateEvent(isolate, fn, msg));
-  }
-
-  void prequeue(_IsolateEvent event) {
-    events.addFirst(event);
-  }
-
-  _IsolateEvent dequeue() {
-    if (events.isEmpty) return null;
-    return events.removeFirst();
-  }
-
-  void checkOpenReceivePortsFromCommandLine() {
-    if (_globalState.rootContext != null &&
-        _globalState.isolates.containsKey(_globalState.rootContext.id) &&
-        _globalState.fromCommandLine &&
-        _globalState.rootContext.ports.isEmpty) {
-      // We want to reach here only on the main [_Manager] and only
-      // on the command-line.  In the browser the isolate might
-      // still be alive due to DOM callbacks, but the presumption is
-      // that on the command-line, no future events can be injected
-      // into the event queue once it's empty.  Node has setTimeout
-      // so this presumption is incorrect there.  We think(?) that
-      // in d8 this assumption is valid.
-      throw new Exception("Program exited with open ReceivePorts.");
-    }
-  }
-
-  /** Process a single event, if any. */
-  bool runIteration() {
-    final event = dequeue();
-    if (event == null) {
-      checkOpenReceivePortsFromCommandLine();
-      _globalState.maybeCloseWorker();
-      return false;
-    }
-    event.process();
-    return true;
-  }
-
-  /**
-   * Runs multiple iterations of the run-loop. If possible, each iteration is
-   * run asynchronously.
-   */
-  void _runHelper() {
-    if (globalWindow != null) {
-      // Run each iteration from the browser's top event loop.
-      next() {
-        if (!runIteration()) return;
-        Timer.run(next);
-      }
-
-      next();
-    } else {
-      // Run synchronously until no more iterations are available.
-      while (runIteration()) {}
-    }
-  }
-
-  /**
-   * Call [_runHelper] but ensure that worker exceptions are propragated.
-   */
-  void run() {
-    if (!_globalState.isWorker) {
-      _runHelper();
-    } else {
-      try {
-        _runHelper();
-      } catch (e, trace) {
-        _globalState.mainManager.postMessage(
-            _serializeMessage({'command': 'error', 'msg': '$e\n$trace'}));
-      }
-    }
-  }
-}
-
-/** An event in the top-level event queue. */
-class _IsolateEvent {
-  _IsolateContext isolate;
-  Function fn;
-  String message;
-
-  _IsolateEvent(this.isolate, this.fn, this.message);
-
-  void process() {
-    if (isolate.isPaused) {
-      isolate.delayedEvents.add(this);
-      return;
-    }
-    isolate.eval(fn);
+    throw new ArgumentError("Arguments to main must be a List: $args");
   }
 }
 
@@ -702,679 +53,17 @@
 // those uses to just refer to the one in dart:runtime.
 final global = dart.global_;
 
-/** A stub for interacting with the main manager. */
-class _MainManagerStub {
-  void postMessage(msg) {
-    JS("void", r"#.postMessage(#)", global, msg);
-  }
-}
-
-const String _SPAWNED_SIGNAL = "spawned";
-const String _SPAWN_FAILED_SIGNAL = "spawn failed";
-
-get globalWindow {
-  return JS('', "#.window", global);
-}
-
-get globalWorker {
-  return JS('', "#.Worker", global);
-}
-
-bool get globalPostMessageDefined {
-  return JS('bool', "!!#.postMessage", global);
-}
-
 typedef _MainFunction();
-typedef _MainFunctionArgs(Null args);
-typedef _MainFunctionArgsMessage(Null args, Null message);
-
-/// Note: IsolateNatives depends on _globalState which is only set up correctly
-/// when 'dart:isolate' has been imported.
-class IsolateNatives {
-  // We set [enableSpawnWorker] to true (not null) when calling isolate
-  // primitives that require support for spawning workers. The field starts out
-  // by being null, and dart2js' type inference will track if it can have a
-  // non-null value. So by testing if this value is not null, we generate code
-  // that dart2js knows is dead when worker support isn't needed.
-  // TODO(herhut): Initialize this to false when able to track compile-time
-  // constants.
-  static var enableSpawnWorker;
-
-  static String thisScript = computeThisScript();
-
-  /// Returns the base path added to Uri.base to resolve `package:` Uris.
-  ///
-  /// This is used by `Isolate.resolvePackageUri` to load resources. The default
-  /// value is `packages/` but users can override this by using the
-  /// `defaultPackagesBase` hook.
-  static String get packagesBase =>
-      JS('String', r'#.defaultPackagesBase || "packages/"', global);
-
-  /// Associates an ID with a native worker object.
-  static final Expando<int> workerIds = new Expando<int>();
-
-  /**
-   * The src url for the script tag that loaded this Used to create
-   * JavaScript workers.
-   */
-  static String computeThisScript() {
-    // See: https://github.com/dart-lang/dev_compiler/issues/164
-    // var currentScript = JS_EMBEDDED_GLOBAL('', CURRENT_SCRIPT);
-    var currentScript = JS(
-        'var', '#.document ? #.document.currentScript : null', global, global);
-    if (currentScript != null) {
-      return JS('String', 'String(#.src)', currentScript);
-    }
-    if (Primitives.isD8) return computeThisScriptD8();
-    if (Primitives.isJsshell) return computeThisScriptJsshell();
-    // A worker has no script tag - so get an url from a stack-trace.
-    if (_globalState != null && _globalState.isWorker) {
-      return computeThisScriptFromTrace();
-    }
-    return null;
-  }
-
-  static String computeThisScriptJsshell() {
-    return JS('String|Null', 'thisFilename()');
-  }
-
-  // TODO(ahe): The following is for supporting D8.  We should move this code
-  // to a helper library that is only loaded when testing on D8.
-  static String computeThisScriptD8() => computeThisScriptFromTrace();
-
-  static String computeThisScriptFromTrace() {
-    var stack = JS('String|Null', 'new Error().stack');
-    if (stack == null) {
-      // According to Internet Explorer documentation, the stack
-      // property is not set until the exception is thrown. The stack
-      // property was not provided until IE10.
-      stack = JS(
-          'String|Null',
-          '(function() {'
-          'try { throw new Error() } catch(e) { return e.stack }'
-          '})()');
-      if (stack == null) throw new UnsupportedError('No stack trace');
-    }
-    var pattern, matches;
-
-    // This pattern matches V8, Chrome, and Internet Explorer stack
-    // traces that look like this:
-    // Error
-    //     at methodName (URI:LINE:COLUMN)
-    pattern =
-        JS('', r'new RegExp("^ *at [^(]*\\((.*):[0-9]*:[0-9]*\\)$", "m")');
-
-    matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
-    if (matches != null) return JS('String', '#[1]', matches);
-
-    // This pattern matches Firefox stack traces that look like this:
-    // methodName@URI:LINE
-    pattern = JS('', r'new RegExp("^[^@]*@(.*):[0-9]*$", "m")');
-
-    matches = JS('JSExtendableArray|Null', '#.match(#)', stack, pattern);
-    if (matches != null) return JS('String', '#[1]', matches);
-
-    throw new UnsupportedError('Cannot extract URI from "$stack"');
-  }
-
-  /**
-   * Assume that [e] is a browser message event and extract its message data.
-   * We don't import the dom explicitly so, when workers are disabled, this
-   * library can also run on top of nodejs.
-   */
-  static _getEventData(e) => JS("", "#.data", e);
-
-  /**
-   * Process messages on a worker, either to control the worker instance or to
-   * pass messages along to the isolate running in the worker.
-   */
-  static void _processWorkerMessage(/* Worker */ sender, e) {
-    var msg = _deserializeMessage(_getEventData(e));
-    switch (msg['command']) {
-      case 'start':
-        _globalState.currentManagerId = msg['id'];
-        String functionName = msg['functionName'];
-        Function entryPoint = (functionName == null)
-            ? _globalState.entry
-            : _getJSFunctionFromName(functionName);
-        var args = msg['args'];
-        var message = _deserializeMessage(msg['msg']);
-        var isSpawnUri = msg['isSpawnUri'];
-        var startPaused = msg['startPaused'];
-        var replyTo = _deserializeMessage(msg['replyTo']);
-        var context = new _IsolateContext();
-        _globalState.topEventLoop.enqueue(context, () {
-          _startIsolate(
-              entryPoint, args, message, isSpawnUri, startPaused, replyTo);
-        }, 'worker-start');
-        // Make sure we always have a current context in this worker.
-        // TODO(7907): This is currently needed because we're using
-        // Timers to implement Futures, and this isolate library
-        // implementation uses Futures. We should either stop using
-        // Futures in this library, or re-adapt if Futures get a
-        // different implementation.
-        _globalState.currentContext = context;
-        _globalState.topEventLoop.run();
-        break;
-      case 'spawn-worker':
-        if (enableSpawnWorker != null) handleSpawnWorkerRequest(msg);
-        break;
-      case 'message':
-        SendPort port = msg['port'];
-        // If the port has been closed, we ignore the message.
-        if (port != null) {
-          msg['port'].send(msg['msg']);
-        }
-        _globalState.topEventLoop.run();
-        break;
-      case 'close':
-        _globalState.managers.remove(workerIds[sender]);
-        JS('void', '#.terminate()', sender);
-        _globalState.topEventLoop.run();
-        break;
-      case 'log':
-        _log(msg['msg']);
-        break;
-      case 'print':
-        if (_globalState.isWorker) {
-          _globalState.mainManager
-              .postMessage(_serializeMessage({'command': 'print', 'msg': msg}));
-        } else {
-          print(msg['msg']);
-        }
-        break;
-      case 'error':
-        throw msg['msg'];
-    }
-  }
-
-  static handleSpawnWorkerRequest(msg) {
-    var replyPort = msg['replyPort'];
-    spawn(msg['functionName'], msg['uri'], msg['args'], msg['msg'], false,
-        msg['isSpawnUri'], msg['startPaused']).then((msg) {
-      replyPort.send(msg);
-    }, onError: (String errorMessage) {
-      replyPort.send([_SPAWN_FAILED_SIGNAL, errorMessage]);
-    });
-  }
-
-  /** Log a message, forwarding to the main [_Manager] if appropriate. */
-  static _log(msg) {
-    if (_globalState.isWorker) {
-      _globalState.mainManager
-          .postMessage(_serializeMessage({'command': 'log', 'msg': msg}));
-    } else {
-      try {
-        _consoleLog(msg);
-      } catch (e, trace) {
-        throw new Exception(trace);
-      }
-    }
-  }
-
-  static void _consoleLog(msg) {
-    JS("void", r"#.console.log(#)", global, msg);
-  }
-
-  static _getJSFunctionFromName(String functionName) {
-    var globalFunctionsContainer = JS_EMBEDDED_GLOBAL("", GLOBAL_FUNCTIONS);
-    return JS("", "#[#]()", globalFunctionsContainer, functionName);
-  }
-
-  /**
-   * Get a string name for the function, if possible.  The result for
-   * anonymous functions is browser-dependent -- it may be "" or "anonymous"
-   * but you should probably not count on this.
-   */
-  static String _getJSFunctionName(Function f) {
-    return JS("String|Null", r'#.$name', f);
-  }
-
-  /** Create a new JavaScript object instance given its constructor. */
-  static dynamic _allocate(var ctor) {
-    return JS("", "new #()", ctor);
-  }
-
-  static Future<List> spawnFunction(
-      void topLevelFunction(Null message), var message, bool startPaused) {
-    IsolateNatives.enableSpawnWorker = true;
-    final name = _getJSFunctionName(topLevelFunction);
-    if (name == null) {
-      throw new UnsupportedError("only top-level functions can be spawned.");
-    }
-    bool isLight = false;
-    bool isSpawnUri = false;
-    return spawn(name, null, null, message, isLight, isSpawnUri, startPaused);
-  }
-
-  static Future<List> spawnUri(
-      Uri uri, List<String> args, var message, bool startPaused) {
-    IsolateNatives.enableSpawnWorker = true;
-    bool isLight = false;
-    bool isSpawnUri = true;
-    return spawn(
-        null, uri.toString(), args, message, isLight, isSpawnUri, startPaused);
-  }
-
-  // TODO(sigmund): clean up above, after we make the new API the default:
-
-  /// If [uri] is `null` it is replaced with the current script.
-  static Future<List> spawn(String functionName, String uri, List<String> args,
-      message, bool isLight, bool isSpawnUri, bool startPaused) {
-    // Assume that the compiled version of the Dart file lives just next to the
-    // dart file.
-    // TODO(floitsch): support precompiled version of dart2js output.
-    if (uri != null && uri.endsWith(".dart")) uri += ".js";
-
-    ReceivePort port = new ReceivePort();
-    Completer<List> completer = new Completer();
-    port.first.then((msg) {
-      if (msg[0] == _SPAWNED_SIGNAL) {
-        completer.complete(msg);
-      } else {
-        assert(msg[0] == _SPAWN_FAILED_SIGNAL);
-        completer.completeError(msg[1]);
-      }
-    });
-
-    SendPort signalReply = port.sendPort;
-
-    if (_globalState.useWorkers && !isLight) {
-      _startWorker(functionName, uri, args, message, isSpawnUri, startPaused,
-          signalReply, (String message) => completer.completeError(message));
-    } else {
-      _startNonWorker(functionName, uri, args, message, isSpawnUri, startPaused,
-          signalReply);
-    }
-    return completer.future;
-  }
-
-  static void _startWorker(
-      String functionName,
-      String uri,
-      List<String> args,
-      message,
-      bool isSpawnUri,
-      bool startPaused,
-      SendPort replyPort,
-      void onError(String message)) {
-    // Make sure that the args list is a fresh generic list. A newly spawned
-    // isolate should be able to assume that the arguments list is an
-    // extendable list.
-    if (args != null) args = new List<String>.from(args);
-    if (_globalState.isWorker) {
-      _globalState.mainManager.postMessage(_serializeMessage({
-        'command': 'spawn-worker',
-        'functionName': functionName,
-        'args': args,
-        'msg': message,
-        'uri': uri,
-        'isSpawnUri': isSpawnUri,
-        'startPaused': startPaused,
-        'replyPort': replyPort
-      }));
-    } else {
-      _spawnWorker(functionName, uri, args, message, isSpawnUri, startPaused,
-          replyPort, onError);
-    }
-  }
-
-  static void _startNonWorker(
-      String functionName,
-      String uri,
-      List<String> args,
-      var message,
-      bool isSpawnUri,
-      bool startPaused,
-      SendPort replyPort) {
-    // TODO(eub): support IE9 using an iframe -- Dart issue 1702.
-    if (uri != null) {
-      throw new UnsupportedError(
-          "Currently spawnUri is not supported without web workers.");
-    }
-    // Clone the message to enforce the restrictions we have on isolate
-    // messages.
-    message = _clone(message);
-    // Make sure that the args list is a fresh generic list. A newly spawned
-    // isolate should be able to assume that the arguments list is an
-    // extendable list.
-    if (args != null) args = new List<String>.from(args);
-    _globalState.topEventLoop.enqueue(new _IsolateContext(), () {
-      final func = _getJSFunctionFromName(functionName);
-      _startIsolate(func, args, message, isSpawnUri, startPaused, replyPort);
-    }, 'nonworker start');
-  }
-
-  static Isolate get currentIsolate {
-    _IsolateContext context = JS_CURRENT_ISOLATE_CONTEXT();
-    return new Isolate(context.controlPort.sendPort,
-        pauseCapability: context.pauseCapability,
-        terminateCapability: context.terminateCapability);
-  }
-
-  static void _startIsolate(Function topLevel, List<String> args, message,
-      bool isSpawnUri, bool startPaused, SendPort replyTo) {
-    _IsolateContext context = JS_CURRENT_ISOLATE_CONTEXT();
-    Primitives.initializeStatics(context.id);
-    // The isolate's port does not keep the isolate open.
-    replyTo.send([
-      _SPAWNED_SIGNAL,
-      context.controlPort.sendPort,
-      context.pauseCapability,
-      context.terminateCapability
-    ]);
-
-    void runStartFunction() {
-      context.initialized = true;
-      if (!isSpawnUri) {
-        topLevel(message);
-      } else if (topLevel is _MainFunctionArgsMessage) {
-        (topLevel as dynamic)(args, message);
-      } else if (topLevel is _MainFunctionArgs) {
-        (topLevel as dynamic)(args);
-      } else {
-        topLevel();
-      }
-    }
-
-    if (startPaused) {
-      context.addPause(context.pauseCapability, context.pauseCapability);
-      _globalState.topEventLoop
-          .enqueue(context, runStartFunction, 'start isolate');
-    } else {
-      runStartFunction();
-    }
-  }
-
-  /**
-   * Spawns an isolate in a worker. [factoryName] is the Javascript constructor
-   * name for the isolate entry point class.
-   */
-  static void _spawnWorker(
-      functionName,
-      String uri,
-      List<String> args,
-      message,
-      bool isSpawnUri,
-      bool startPaused,
-      SendPort replyPort,
-      void onError(String message)) {
-    if (uri == null) uri = thisScript;
-    final worker = JS('var', 'new Worker(#)', uri);
-    // Trampolines are used when wanting to call a Dart closure from
-    // JavaScript.  The helper function DART_CLOSURE_TO_JS only accepts
-    // top-level or static methods, and the trampoline allows us to capture
-    // arguments and values which can be passed to a static method.
-    final onerrorTrampoline = JS(
-        '',
-        '''
-(function (f, u, c) {
-  return function(e) {
-    return f(e, u, c)
-  }
-})(#, #, #)''',
-        workerOnError,
-        uri,
-        onError);
-    JS('void', '#.onerror = #', worker, onerrorTrampoline);
-
-    var processWorkerMessageTrampoline = JS(
-        '',
-        """
-(function (f, a) {
-  return function (e) {
-    // We can stop listening for errors when the first message is received as
-    // we only listen for messages to determine if the uri was bad.
-    e.onerror = null;
-    return f(a, e);
-  }
-})(#, #)""",
-        _processWorkerMessage,
-        worker);
-    JS('void', '#.onmessage = #', worker, processWorkerMessageTrampoline);
-    var workerId = _globalState.nextManagerId++;
-    // We also store the id on the worker itself so that we can unregister it.
-    workerIds[worker] = workerId;
-    _globalState.managers[workerId] = worker;
-    JS(
-        'void',
-        '#.postMessage(#)',
-        worker,
-        _serializeMessage({
-          'command': 'start',
-          'id': workerId,
-          // Note: we serialize replyPort twice because the child worker needs to
-          // first deserialize the worker id, before it can correctly deserialize
-          // the port (port deserialization is sensitive to what is the current
-          // workerId).
-          'replyTo': _serializeMessage(replyPort),
-          'args': args,
-          'msg': _serializeMessage(message),
-          'isSpawnUri': isSpawnUri,
-          'startPaused': startPaused,
-          'functionName': functionName
-        }));
-  }
-
-  static bool workerOnError(
-      /* Event */ event,
-      String uri,
-      void onError(String message)) {
-    // Attempt to shut up the browser, as the error has been handled.  Chrome
-    // ignores this :-(
-    JS('void', '#.preventDefault()', event);
-    String message = JS('String|Null', '#.message', event);
-    if (message == null) {
-      // Some browsers, including Chrome, fail to provide a proper error
-      // event.
-      message = 'Error spawning worker for $uri';
-    } else {
-      message = 'Error spawning worker for $uri ($message)';
-    }
-    onError(message);
-    return true;
-  }
-}
-
-/********************************************************
-  Inserted from lib/isolate/dart2js/ports.dart
- ********************************************************/
-
-/** Common functionality to all send ports. */
-abstract class _BaseSendPort implements SendPort {
-  /** Id for the destination isolate. */
-  final int _isolateId;
-
-  const _BaseSendPort(this._isolateId);
-
-  void _checkReplyTo(SendPort replyTo) {
-    if (replyTo != null &&
-        replyTo is! _NativeJsSendPort &&
-        replyTo is! _WorkerSendPort) {
-      throw new Exception("SendPort.send: Illegal replyTo port type");
-    }
-  }
-
-  void send(var message);
-  bool operator ==(var other);
-  int get hashCode;
-}
-
-/** A send port that delivers messages in-memory via native JavaScript calls. */
-class _NativeJsSendPort extends _BaseSendPort implements SendPort {
-  final RawReceivePortImpl _receivePort;
-
-  const _NativeJsSendPort(this._receivePort, int isolateId) : super(isolateId);
-
-  void send(var message) {
-    // Check that the isolate still runs and the port is still open
-    final isolate = _globalState.isolates[_isolateId];
-    if (isolate == null) return;
-    if (_receivePort._isClosed) return;
-    // Clone the message to enforce the restrictions we have on isolate
-    // messages.
-    var msg = _clone(message);
-    if (isolate.controlPort == _receivePort) {
-      isolate.handleControlMessage(msg);
-      return;
-    }
-    _globalState.topEventLoop.enqueue(isolate, () {
-      if (!_receivePort._isClosed) {
-        _receivePort._add(msg);
-      }
-    }, 'receive $message');
-  }
-
-  bool operator ==(var other) =>
-      (other is _NativeJsSendPort) && (_receivePort == other._receivePort);
-
-  int get hashCode => _receivePort._id;
-}
-
-/** A send port that delivers messages via worker.postMessage. */
-// TODO(eub): abstract this for iframes.
-class _WorkerSendPort extends _BaseSendPort implements SendPort {
-  final int _workerId;
-  final int _receivePortId;
-
-  const _WorkerSendPort(this._workerId, int isolateId, this._receivePortId)
-      : super(isolateId);
-
-  void send(var message) {
-    final workerMessage =
-        _serializeMessage({'command': 'message', 'port': this, 'msg': message});
-
-    if (_globalState.isWorker) {
-      // Communication from one worker to another go through the
-      // main worker.
-      _globalState.mainManager.postMessage(workerMessage);
-    } else {
-      // Deliver the message only if the worker is still alive.
-      /* Worker */ var manager = _globalState.managers[_workerId];
-      if (manager != null) {
-        JS('void', '#.postMessage(#)', manager, workerMessage);
-      }
-    }
-  }
-
-  bool operator ==(var other) {
-    return (other is _WorkerSendPort) &&
-        (_workerId == other._workerId) &&
-        (_isolateId == other._isolateId) &&
-        (_receivePortId == other._receivePortId);
-  }
-
-  int get hashCode {
-    // TODO(sigmund): use a standard hash when we get one available in corelib.
-    return (_workerId << 16) ^ (_isolateId << 8) ^ _receivePortId;
-  }
-}
-
-class RawReceivePortImpl implements RawReceivePort {
-  static int _nextFreeId = 1;
-
-  final int _id;
-  Function _handler;
-  bool _isClosed = false;
-
-  RawReceivePortImpl(this._handler) : _id = _nextFreeId++ {
-    _globalState.currentContext.register(_id, this);
-  }
-
-  RawReceivePortImpl.weak(this._handler) : _id = _nextFreeId++ {
-    _globalState.currentContext.registerWeak(_id, this);
-  }
-
-  // Creates the control port of an isolate.
-  // This is created before the isolate context object itself,
-  // so it cannot access the static _nextFreeId field.
-  RawReceivePortImpl._controlPort()
-      : _handler = null,
-        _id = 0;
-
-  void set handler(Function newHandler) {
-    _handler = newHandler;
-  }
-
-  // Close the port without unregistering it.
-  // Used by an isolate context to close all ports when shutting down.
-  void _close() {
-    _isClosed = true;
-    _handler = null;
-  }
-
-  void close() {
-    if (_isClosed) return;
-    _isClosed = true;
-    _handler = null;
-    _globalState.currentContext.unregister(_id);
-  }
-
-  void _add(dataEvent) {
-    if (_isClosed) return;
-    _handler(dataEvent);
-  }
-
-  SendPort get sendPort {
-    return new _NativeJsSendPort(this, _globalState.currentContext.id);
-  }
-}
-
-class ReceivePortImpl extends Stream implements ReceivePort {
-  final RawReceivePort _rawPort;
-  StreamController _controller;
-
-  ReceivePortImpl() : this.fromRawReceivePort(new RawReceivePortImpl(null));
-
-  ReceivePortImpl.weak()
-      : this.fromRawReceivePort(new RawReceivePortImpl.weak(null));
-
-  ReceivePortImpl.fromRawReceivePort(this._rawPort) {
-    _controller = new StreamController(onCancel: close, sync: true);
-    _rawPort.handler = _controller.add;
-  }
-
-  StreamSubscription listen(void onData(var event),
-      {Function onError, void onDone(), bool cancelOnError}) {
-    return _controller.stream.listen(onData,
-        onError: onError, onDone: onDone, cancelOnError: cancelOnError);
-  }
-
-  void close() {
-    _rawPort.close();
-    _controller.close();
-  }
-
-  SendPort get sendPort => _rawPort.sendPort;
-}
+typedef _MainFunctionArgs(List<String> args);
+typedef _MainFunctionArgsMessage(List<String> args, Null message);
 
 class TimerImpl implements Timer {
   final bool _once;
-  bool _inEventLoop = false;
   int _handle;
   int _tick = 0;
 
   TimerImpl(int milliseconds, void callback()) : _once = true {
-    if (milliseconds == 0 && (!hasTimer() || _globalState.isWorker)) {
-      void internalCallback() {
-        _handle = null;
-        callback();
-      }
-
-      // Setting _handle to something different from null indicates that the
-      // callback has not been run. Hence, the choice of 1 is arbitrary.
-      _handle = 1;
-
-      // This makes a dependency between the async library and the
-      // event loop of the isolate library. The compiler makes sure
-      // that the event loop is compiled if [Timer] is used.
-      // TODO(7907): In case of web workers, we need to use the event
-      // loop instead of setTimeout, to make sure the futures get executed in
-      // order.
-      _globalState.topEventLoop
-          .enqueue(_globalState.currentContext, internalCallback, 'timer');
-      _inEventLoop = true;
-    } else if (hasTimer()) {
+    if (hasTimer()) {
       void internalCallback() {
         _handle = null;
         leaveJsAsync();
@@ -1387,8 +76,7 @@
       _handle = JS(
           'int', '#.setTimeout(#, #)', global, internalCallback, milliseconds);
     } else {
-      assert(milliseconds > 0);
-      throw new UnsupportedError("Timer greater than 0.");
+      throw new UnsupportedError("`setTimeout()` not found.");
     }
   }
 
@@ -1417,9 +105,6 @@
 
   void cancel() {
     if (hasTimer()) {
-      if (_inEventLoop) {
-        throw new UnsupportedError("Timer in event loop cannot be canceled.");
-      }
       if (_handle == null) return;
       leaveJsAsync();
       if (_once) {
@@ -1439,40 +124,3 @@
 bool hasTimer() {
   return JS('', '#.setTimeout', global) != null;
 }
-
-/**
- * Implementation class for [Capability].
- *
- * It has the same name to make it harder for users to distinguish.
- */
-class CapabilityImpl implements Capability {
-  /** Internal random secret identifying the capability. */
-  final int _id;
-
-  CapabilityImpl() : this._internal(random64());
-
-  CapabilityImpl._internal(this._id);
-
-  int get hashCode {
-    // Thomas Wang 32 bit Mix.
-    // http://www.concentric.net/~Ttwang/tech/inthash.htm
-    // (via https://gist.github.com/badboy/6267743)
-    int hash = _id;
-    hash = (hash >> 0) ^ (hash ~/ 0x100000000); // To 32 bit from ~64.
-    hash = (~hash + (hash << 15)) & 0xFFFFFFFF;
-    hash ^= hash >> 12;
-    hash = (hash * 5) & 0xFFFFFFFF;
-    hash ^= hash >> 4;
-    hash = (hash * 2057) & 0xFFFFFFFF;
-    hash ^= hash >> 16;
-    return hash;
-  }
-
-  bool operator ==(Object other) {
-    if (identical(other, this)) return true;
-    if (other is CapabilityImpl) {
-      return identical(_id, other._id);
-    }
-    return false;
-  }
-}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/isolate_serialization.dart b/pkg/dev_compiler/tool/input_sdk/private/isolate_serialization.dart
deleted file mode 100644
index 67b2cc4..0000000
--- a/pkg/dev_compiler/tool/input_sdk/private/isolate_serialization.dart
+++ /dev/null
@@ -1,377 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart._isolate_helper;
-
-/// Serialize [message].
-_serializeMessage(message) {
-  return new _Serializer().serialize(message);
-}
-
-/// Deserialize [message].
-_deserializeMessage(message) {
-  return new _Deserializer().deserialize(message);
-}
-
-/// Clones the message.
-///
-/// Contrary to a `_deserializeMessage(_serializeMessage(x))` the `_clone`
-/// function will not try to adjust SendPort values and pass them through.
-_clone(message) {
-  _Serializer serializer = new _Serializer(serializeSendPorts: false);
-  _Deserializer deserializer = new _Deserializer();
-  return deserializer.deserialize(serializer.serialize(message));
-}
-
-class _Serializer {
-  final bool _serializeSendPorts;
-  Map<dynamic, int> serializedObjectIds = new Map<dynamic, int>.identity();
-
-  _Serializer({serializeSendPorts: true})
-      : _serializeSendPorts = serializeSendPorts;
-
-  /// Returns a message that can be transmitted through web-worker channels.
-  serialize(x) {
-    if (isPrimitive(x)) return serializePrimitive(x);
-
-    int serializationId = serializedObjectIds[x];
-    if (serializationId != null) return makeRef(serializationId);
-
-    serializationId = serializedObjectIds.length;
-    serializedObjectIds[x] = serializationId;
-
-    if (x is NativeByteBuffer) return serializeByteBuffer(x);
-    if (x is NativeTypedData) return serializeTypedData(x);
-    if (x is JSIndexable) return serializeJSIndexable(x);
-    if (x is InternalMap) return serializeMap(x);
-
-    if (x is JSObject) return serializeJSObject(x);
-
-    // We should not have any interceptors any more.
-    if (x is Interceptor) unsupported(x);
-
-    if (x is RawReceivePort) {
-      unsupported(x, "RawReceivePorts can't be transmitted:");
-    }
-
-    // SendPorts need their workerIds adjusted (either during serialization or
-    // deserialization).
-    if (x is _NativeJsSendPort) return serializeJsSendPort(x);
-    if (x is _WorkerSendPort) return serializeWorkerSendPort(x);
-
-    if (x is Function) return serializeClosure(x);
-
-    return serializeDartObject(x);
-  }
-
-  void unsupported(x, [String message]) {
-    if (message == null) message = "Can't transmit:";
-    throw new UnsupportedError("$message $x");
-  }
-
-  makeRef(int serializationId) => ["ref", serializationId];
-
-  bool isPrimitive(x) => x == null || x is String || x is num || x is bool;
-  serializePrimitive(primitive) => primitive;
-
-  serializeByteBuffer(NativeByteBuffer buffer) {
-    return ["buffer", buffer];
-  }
-
-  serializeTypedData(NativeTypedData data) {
-    return ["typed", data];
-  }
-
-  serializeJSIndexable(JSIndexable indexable) {
-    // Strings are JSIndexable but should have been treated earlier.
-    assert(indexable is! String);
-    List serialized = serializeArray(indexable);
-    if (indexable is JSFixedArray) return ["fixed", serialized];
-    if (indexable is JSExtendableArray) return ["extendable", serialized];
-    // MutableArray check must be last, since JSFixedArray and JSExtendableArray
-    // extend JSMutableArray.
-    if (indexable is JSMutableArray) return ["mutable", serialized];
-    // The only JSArrays left are the const Lists (as in `const [1, 2]`).
-    if (indexable is JSArray) return ["const", serialized];
-    unsupported(indexable, "Can't serialize indexable: ");
-    return null;
-  }
-
-  serializeArray(JSArray x) {
-    List serialized = [];
-    serialized.length = x.length;
-    for (int i = 0; i < x.length; i++) {
-      serialized[i] = serialize(x[i]);
-    }
-    return serialized;
-  }
-
-  serializeArrayInPlace(JSArray x) {
-    for (int i = 0; i < x.length; i++) {
-      x[i] = serialize(x[i]);
-    }
-    return x;
-  }
-
-  serializeMap(InternalMap x) {
-    Function serializeTearOff = serialize;
-    return [
-      'map',
-      x.keys.map(serializeTearOff).toList(),
-      x.values.map(serializeTearOff).toList()
-    ];
-  }
-
-  serializeJSObject(JSObject x) {
-    // Don't serialize objects if their `constructor` property isn't `Object`
-    // or undefined/null.
-    // A different constructor is taken as a sign that the object has complex
-    // internal state, or that it is a function, and won't be serialized.
-    if (JS('bool', '!!(#.constructor)', x) &&
-        JS('bool', 'x.constructor !== Object')) {
-      unsupported(x, "Only plain JS Objects are supported:");
-    }
-    List keys = JS('JSArray', 'Object.keys(#)', x);
-    List values = [];
-    values.length = keys.length;
-    for (int i = 0; i < keys.length; i++) {
-      values[i] = serialize(JS('', '#[#]', x, keys[i]));
-    }
-    return ['js-object', keys, values];
-  }
-
-  serializeWorkerSendPort(_WorkerSendPort x) {
-    if (_serializeSendPorts) {
-      return ['sendport', x._workerId, x._isolateId, x._receivePortId];
-    }
-    return ['raw sendport', x];
-  }
-
-  serializeJsSendPort(_NativeJsSendPort x) {
-    if (_serializeSendPorts) {
-      int workerId = _globalState.currentManagerId;
-      return ['sendport', workerId, x._isolateId, x._receivePort._id];
-    }
-    return ['raw sendport', x];
-  }
-
-  serializeCapability(CapabilityImpl x) => ['capability', x._id];
-
-  serializeClosure(Function x) {
-    final name = IsolateNatives._getJSFunctionName(x);
-    if (name == null) {
-      unsupported(x, "Closures can't be transmitted:");
-    }
-    return ['function', name];
-  }
-
-  serializeDartObject(x) {
-    var classExtractor = JS_EMBEDDED_GLOBAL('', CLASS_ID_EXTRACTOR);
-    var fieldsExtractor = JS_EMBEDDED_GLOBAL('', CLASS_FIELDS_EXTRACTOR);
-    String classId = JS('String', '#(#)', classExtractor, x);
-    List fields = JS('JSArray', '#(#)', fieldsExtractor, x);
-    return ['dart', classId, serializeArrayInPlace(fields)];
-  }
-}
-
-class _Deserializer {
-  /// When `true`, encodes sendports specially so that they can be adjusted on
-  /// the receiving end.
-  ///
-  /// When `false`, sendports are cloned like any other object.
-  final bool _adjustSendPorts;
-
-  List<dynamic> deserializedObjects = new List<dynamic>();
-
-  _Deserializer({adjustSendPorts: true}) : _adjustSendPorts = adjustSendPorts;
-
-  /// Returns a message that can be transmitted through web-worker channels.
-  deserialize(x) {
-    if (isPrimitive(x)) return deserializePrimitive(x);
-
-    if (x is! JSArray) throw new ArgumentError("Bad serialized message: $x");
-
-    switch (x.first) {
-      case "ref":
-        return deserializeRef(x);
-      case "buffer":
-        return deserializeByteBuffer(x);
-      case "typed":
-        return deserializeTypedData(x);
-      case "fixed":
-        return deserializeFixed(x);
-      case "extendable":
-        return deserializeExtendable(x);
-      case "mutable":
-        return deserializeMutable(x);
-      case "const":
-        return deserializeConst(x);
-      case "map":
-        return deserializeMap(x);
-      case "sendport":
-        return deserializeSendPort(x);
-      case "raw sendport":
-        return deserializeRawSendPort(x);
-      case "js-object":
-        return deserializeJSObject(x);
-      case "function":
-        return deserializeClosure(x);
-      case "dart":
-        return deserializeDartObject(x);
-      default:
-        throw "couldn't deserialize: $x";
-    }
-  }
-
-  bool isPrimitive(x) => x == null || x is String || x is num || x is bool;
-  deserializePrimitive(x) => x;
-
-  // ['ref', id].
-  deserializeRef(x) {
-    assert(x[0] == 'ref');
-    int serializationId = x[1];
-    return deserializedObjects[serializationId];
-  }
-
-  // ['buffer', <byte buffer>].
-  NativeByteBuffer deserializeByteBuffer(x) {
-    assert(x[0] == 'buffer');
-    NativeByteBuffer result = x[1];
-    deserializedObjects.add(result);
-    return result;
-  }
-
-  // ['typed', <typed array>].
-  NativeTypedData deserializeTypedData(x) {
-    assert(x[0] == 'typed');
-    NativeTypedData result = x[1];
-    deserializedObjects.add(result);
-    return result;
-  }
-
-  // Updates the given array in place with its deserialized content.
-  List deserializeArrayInPlace(JSArray x) {
-    for (int i = 0; i < x.length; i++) {
-      x[i] = deserialize(x[i]);
-    }
-    return x;
-  }
-
-  // ['fixed', <array>].
-  List deserializeFixed(x) {
-    assert(x[0] == 'fixed');
-    List result = x[1];
-    deserializedObjects.add(result);
-    return new JSArray.fixed(deserializeArrayInPlace(result));
-  }
-
-  // ['extendable', <array>].
-  List deserializeExtendable(x) {
-    assert(x[0] == 'extendable');
-    List result = x[1];
-    deserializedObjects.add(result);
-    return new JSArray.of(deserializeArrayInPlace(result));
-  }
-
-  // ['mutable', <array>].
-  List deserializeMutable(x) {
-    assert(x[0] == 'mutable');
-    List result = x[1];
-    deserializedObjects.add(result);
-    return deserializeArrayInPlace(result);
-  }
-
-  // ['const', <array>].
-  List deserializeConst(x) {
-    assert(x[0] == 'const');
-    List result = x[1];
-    deserializedObjects.add(result);
-    // TODO(floitsch): need to mark list as non-changeable.
-    return new JSArray.unmodifiable(deserializeArrayInPlace(result));
-  }
-
-  // ['map', <key-list>, <value-list>].
-  Map deserializeMap(InternalMap x) {
-    assert(x[0] == 'map');
-    List keys = x[1];
-    List values = x[2];
-    Map result = {};
-    deserializedObjects.add(result);
-    // We need to keep the order of how objects were serialized.
-    // First deserialize all keys, and then only deserialize the values.
-    keys = keys.map(deserialize).toList();
-
-    for (int i = 0; i < keys.length; i++) {
-      result[keys[i]] = deserialize(values[i]);
-    }
-    return result;
-  }
-
-  // ['sendport', <managerId>, <isolateId>, <receivePortId>].
-  SendPort deserializeSendPort(x) {
-    assert(x[0] == 'sendport');
-    int managerId = x[1];
-    int isolateId = x[2];
-    int receivePortId = x[3];
-    SendPort result;
-    // If two isolates are in the same manager, we use NativeJsSendPorts to
-    // deliver messages directly without using postMessage.
-    if (managerId == _globalState.currentManagerId) {
-      var isolate = _globalState.isolates[isolateId];
-      if (isolate == null) return null; // Isolate has been closed.
-      var receivePort = isolate.lookup(receivePortId);
-      if (receivePort == null) return null; // Port has been closed.
-      result = new _NativeJsSendPort(receivePort, isolateId);
-    } else {
-      result = new _WorkerSendPort(managerId, isolateId, receivePortId);
-    }
-    deserializedObjects.add(result);
-    return result;
-  }
-
-  // ['raw sendport', <sendport>].
-  SendPort deserializeRawSendPort(x) {
-    assert(x[0] == 'raw sendport');
-    SendPort result = x[1];
-    deserializedObjects.add(result);
-    return result;
-  }
-
-  // ['js-object', <key-list>, <value-list>].
-  deserializeJSObject(x) {
-    assert(x[0] == 'js-object');
-    List keys = x[1];
-    List values = x[2];
-    var o = JS('', '{}');
-    deserializedObjects.add(o);
-    for (int i = 0; i < keys.length; i++) {
-      JS('', '#[#]=#', o, keys[i], deserialize(values[i]));
-    }
-    return o;
-  }
-
-  // ['function', <name>].
-  Function deserializeClosure(x) {
-    assert(x[0] == 'function');
-    String name = x[1];
-    Function result = IsolateNatives._getJSFunctionFromName(name);
-    deserializedObjects.add(result);
-    return result;
-  }
-
-  // ['dart', <class-id>, <field-list>].
-  deserializeDartObject(x) {
-    assert(x[0] == 'dart');
-    String classId = x[1];
-    List fields = x[2];
-    var instanceFromClassId = JS_EMBEDDED_GLOBAL('', INSTANCE_FROM_CLASS_ID);
-    var initializeObject = JS_EMBEDDED_GLOBAL('', INITIALIZE_EMPTY_INSTANCE);
-
-    var emptyInstance = JS('', '#(#)', instanceFromClassId, classId);
-    deserializedObjects.add(emptyInstance);
-    deserializeArrayInPlace(fields);
-    return JS(
-        '', '#(#, #, #)', initializeObject, classId, emptyInstance, fields);
-  }
-}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
index 2a7689e..5187db0 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
@@ -66,25 +66,6 @@
 }
 
 class Primitives {
-  /// Isolate-unique ID for caching [JsClosureMirror.function].
-  /// Note the initial value is used by the first isolate (or if there are no
-  /// isolates), new isolates will update this value to avoid conflicts by
-  /// calling [initializeStatics].
-  static String mirrorFunctionCacheName = '\$cachedFunction';
-
-  /// Isolate-unique ID for caching [JsInstanceMirror._invoke].
-  static String mirrorInvokeCacheName = '\$cachedInvocation';
-
-  /// Called when creating a new isolate (see _IsolateContext constructor in
-  /// isolate_helper.dart).
-  /// Please don't add complicated code to this method, as it will impact
-  /// start-up performance.
-  static void initializeStatics(int id) {
-    // Benchmarking shows significant performance improvements if this is a
-    // fixed value.
-    mirrorFunctionCacheName += '_$id';
-    mirrorInvokeCacheName += '_$id';
-  }
 
   @NoInline()
   static int _parseIntError(String source, int handleError(String source)) {
@@ -196,7 +177,7 @@
     return result;
   }
 
-  /** [: r"$".codeUnitAt(0) :] */
+  /** `r"$".codeUnitAt(0)` */
   static const int DOLLAR_CHAR_VALUE = 36;
 
   static int dateNow() => JS('int', r'Date.now()');
@@ -485,9 +466,6 @@
     }
     JS('void', '#[#] = #', object, key, value);
   }
-
-  static StackTrace extractStackTrace(Error error) =>
-      getTraceFromException(error);
 }
 
 /**
diff --git a/pkg/dev_compiler/tool/input_sdk/private/shared/embedded_names.dart b/pkg/dev_compiler/tool/input_sdk/private/shared/embedded_names.dart
deleted file mode 100644
index bd72f09..0000000
--- a/pkg/dev_compiler/tool/input_sdk/private/shared/embedded_names.dart
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-/// Contains the names of globals that are embedded into the output by the
-/// compiler.
-///
-/// Variables embedded this way should be access with `JS_EMBEDDED_GLOBAL` from
-/// the `_foreign_helper` library.
-///
-/// This library is shared between the compiler and the runtime system.
-library dart2js._embedded_names;
-
-const DISPATCH_PROPERTY_NAME = "dispatchPropertyName";
-const TYPE_INFORMATION = 'typeInformation';
-const GLOBAL_FUNCTIONS = 'globalFunctions';
-const STATICS = 'statics';
-
-/**
- * If [JSInvocationMirror._invokeOn] is being used, this embedded global
- * contains a JavaScript map with the names of methods that are
- * intercepted.
- */
-const INTERCEPTED_NAMES = 'interceptedNames';
-
-const MANGLED_GLOBAL_NAMES = 'mangledGlobalNames';
-const MANGLED_NAMES = 'mangledNames';
-const LIBRARIES = 'libraries';
-const FINISHED_CLASSES = 'finishedClasses';
-const ALL_CLASSES = 'allClasses';
-const METADATA = 'metadata';
-const INTERCEPTORS_BY_TAG = 'interceptorsByTag';
-const LEAF_TAGS = 'leafTags';
-const LAZIES = 'lazies';
-const GET_ISOLATE_TAG = 'getIsolateTag';
-const ISOLATE_TAG = 'isolateTag';
-const CURRENT_SCRIPT = 'currentScript';
-const DEFERRED_LIBRARY_URIS = 'deferredLibraryUris';
-const DEFERRED_LIBRARY_HASHES = 'deferredLibraryHashes';
-const INITIALIZE_LOADED_HUNK = 'initializeLoadedHunk';
-const IS_HUNK_LOADED = 'isHunkLoaded';
-const IS_HUNK_INITIALIZED = 'isHunkInitialized';
-const DEFERRED_INITIALIZED = 'deferredInitialized';
-const CLASS_ID_EXTRACTOR = 'classIdExtractor';
-const CLASS_FIELDS_EXTRACTOR = 'classFieldsExtractor';
-const INSTANCE_FROM_CLASS_ID = "instanceFromClassId";
-const INITIALIZE_EMPTY_INSTANCE = "initializeEmptyInstance";
-const TYPEDEF_TYPE_PROPERTY_NAME = r"$typedefType";
-const TYPEDEF_PREDICATE_PROPERTY_NAME = r"$$isTypedef";
-const NATIVE_SUPERCLASS_TAG_NAME = r"$nativeSuperclassTag";
-
-const MAP_TYPE_TO_INTERCEPTOR = "mapTypeToInterceptor";
diff --git a/pkg/front_end/lib/src/base/errors.dart b/pkg/front_end/lib/src/base/errors.dart
index 2f9884a..e6ebedf 100644
--- a/pkg/front_end/lib/src/base/errors.dart
+++ b/pkg/front_end/lib/src/base/errors.dart
@@ -26,12 +26,18 @@
   final String correction;
 
   /**
+   * Whether this error is caused by an unresolved identifier.
+   */
+  final bool isUnresolvedIdentifier;
+
+  /**
    * Initialize a newly created error code to have the given [name]. The message
    * associated with the error will be created from the given [message]
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ErrorCode(this.name, this.message, [this.correction]);
+  const ErrorCode(this.name, this.message,
+      {this.correction, this.isUnresolvedIdentifier: false});
 
   /**
    * The severity of the error.
diff --git a/pkg/front_end/lib/src/fasta/constant_context.dart b/pkg/front_end/lib/src/fasta/constant_context.dart
index a4d646a..a6dac50 100644
--- a/pkg/front_end/lib/src/fasta/constant_context.dart
+++ b/pkg/front_end/lib/src/fasta/constant_context.dart
@@ -23,4 +23,19 @@
   /// This means that `Object()` and `[]` are equivalent to `const Object()` and
   /// `const []` respectively. `new Object()` is a compile-time error.
   inferred,
+
+  /// In a context that allows only constant values, but requires them to be
+  /// defined as `const` explicitly.  For example, in default values of optional
+  /// and named parameters.
+  ///
+  /// The following code should emit a compile-time error:
+  ///
+  ///     class Bar { const Bar(); }
+  ///     class Foo { void foo({Bar bar: Bar()}) {} }
+  ///
+  /// The following code should compile without errors:
+  ///
+  ///     class Bar { const Bar(); }
+  ///     class Foo { void foo({Bar bar: const Bar()}) {} }
+  needsExplicitConst,
 }
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 d351d58..725203e 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -480,6 +480,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageCatchSyntax = const MessageCode("CatchSyntax",
+    analyzerCode: "CATCH_SYNTAX",
     dart2jsCode: "*ignored*",
     message:
         r"""'catch' must be followed by '(identifier)' or '(identifier, identifier)'.""",
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 542a791..01482b9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -76,6 +76,8 @@
 
 import '../names.dart';
 
+import 'constness_evaluator.dart' show evaluateConstness, ConstnessEffect;
+
 import 'fasta_accessors.dart';
 
 import 'kernel_api.dart';
@@ -183,6 +185,12 @@
   /// and where that was.
   Map<String, int> initializedFields;
 
+  /// Constructor invocations (either generative or factory) with not specified
+  /// `new` or `const` keywords.  The constness for these should be inferred
+  /// based on the subexpressions.
+  List<Expression> constructorInvocationsWithImplicitConstness =
+      new List<Expression>();
+
   BodyBuilder(
       KernelLibraryBuilder library,
       this.member,
@@ -685,6 +693,50 @@
       unhandled("${builder.runtimeType}", "finishFunction", builder.charOffset,
           builder.fileUri);
     }
+
+    inferConstness();
+  }
+
+  // Infers constness of the constructor invocations collected so far in
+  // [constructorInvocationsWithImplicitConstness], then clears out the list.
+  void inferConstness() {
+    // The algorithm below takes advantage of the fact that for each expression
+    // that needs constness inference comes after all its subexpressions that
+    // also need constness inference in
+    // [constructorInvocationsWithImplicitConstness].
+    for (Expression invocation in constructorInvocationsWithImplicitConstness) {
+      if (invocation is ConstructorInvocation) {
+        ConstnessEffect constness =
+            evaluateConstness(invocation, coreTypes).effect;
+        if (constness == ConstnessEffect.taintedConst) {
+          // TODO(dmitryas): Find a better way to unwrap the error node.
+          ShadowSyntheticExpression errorMessage = buildCompileTimeError(
+              fasta.messageCantDetermineConstness,
+              invocation.fileOffset,
+              noLength);
+          invocation.replaceWith(errorMessage.desugared);
+        } else {
+          invocation.isConst = constness == ConstnessEffect.allowedConst;
+        }
+      } else if (invocation is StaticInvocation) {
+        ConstnessEffect constness =
+            evaluateConstness(invocation, coreTypes).effect;
+        if (constness == ConstnessEffect.taintedConst) {
+          // TODO(dmitryas): Find a better way to unwrap the error node.
+          ShadowSyntheticExpression errorMessage = buildCompileTimeError(
+              fasta.messageCantDetermineConstness,
+              invocation.fileOffset,
+              noLength);
+          invocation.replaceWith(errorMessage.desugared);
+        } else {
+          invocation.isConst = constness == ConstnessEffect.allowedConst;
+        }
+      } else {
+        unhandled("${invocation.runtimeType}", "inferConstness",
+            invocation.fileOffset, invocation.location.file);
+      }
+    }
+    constructorInvocationsWithImplicitConstness.clear();
   }
 
   @override
@@ -2133,6 +2185,20 @@
   }
 
   @override
+  void beginFormalParameterDefaultValueExpression() {
+    super.push(constantContext);
+    constantContext = ConstantContext.needsExplicitConst;
+  }
+
+  @override
+  void endFormalParameterDefaultValueExpression() {
+    debugEvent("FormalParameterDefaultValueExpression");
+    var defaultValueExpression = pop();
+    constantContext = pop();
+    push(defaultValueExpression);
+  }
+
+  @override
   void handleValuedFormalParameter(Token equals, Token token) {
     debugEvent("ValuedFormalParameter");
     Expression initializer = popForValue();
@@ -2448,38 +2514,57 @@
           argMessage: argMessage);
     }
     if (target is Constructor) {
-      isConst =
-          isConst || constantContext != ConstantContext.none && target.isConst;
-      if (constness == Constness.implicit &&
-          target.isConst &&
-          constantContext != ConstantContext.inferred) {
+      if (constantContext == ConstantContext.needsExplicitConst &&
+          constness == Constness.implicit) {
         return buildCompileTimeError(
             fasta.messageCantDetermineConstness, charOffset, noLength);
-      } else if (isConst && !target.isConst) {
+      }
+      isConst =
+          isConst || constantContext != ConstantContext.none && target.isConst;
+      if ((isConst || constantContext == ConstantContext.inferred) &&
+          !target.isConst) {
         return deprecated_buildCompileTimeError(
             "Not a const constructor.", charOffset);
       }
-      return new ShadowConstructorInvocation(target, targetTypeArguments,
-          initialTarget, forest.castArguments(arguments),
+      ShadowConstructorInvocation invocation = new ShadowConstructorInvocation(
+          target,
+          targetTypeArguments,
+          initialTarget,
+          forest.castArguments(arguments),
           isConst: isConst)
         ..fileOffset = charOffset;
+      if (constness == Constness.implicit &&
+          target.isConst &&
+          constantContext != ConstantContext.inferred) {
+        constructorInvocationsWithImplicitConstness.add(invocation);
+      }
+      return invocation;
     } else {
       Procedure procedure = target;
-      isConst = isConst ||
-          constantContext != ConstantContext.none && procedure.isConst;
-      if (constness == Constness.implicit &&
-          procedure.isConst &&
-          constantContext != ConstantContext.inferred) {
-        return buildCompileTimeError(
-            fasta.messageCantDetermineConstness, charOffset, noLength);
-      } else if (isConst && !procedure.isConst) {
-        return deprecated_buildCompileTimeError(
-            "Not a const factory.", charOffset);
-      } else if (procedure.isFactory) {
-        return new ShadowFactoryConstructorInvocation(target,
-            targetTypeArguments, initialTarget, forest.castArguments(arguments),
-            isConst: isConst)
-          ..fileOffset = charOffset;
+      if (procedure.isFactory) {
+        isConst = isConst ||
+            constantContext != ConstantContext.none && procedure.isConst;
+        if ((isConst || constantContext == ConstantContext.inferred) &&
+            !procedure.isConst) {
+          return deprecated_buildCompileTimeError(
+              "Not a const factory.", charOffset);
+        }
+        if (constantContext == ConstantContext.needsExplicitConst &&
+            constness == Constness.implicit) {
+          return buildCompileTimeError(
+              fasta.messageCantDetermineConstness, charOffset, noLength);
+        }
+        ShadowFactoryConstructorInvocation invocation =
+            new ShadowFactoryConstructorInvocation(target, targetTypeArguments,
+                initialTarget, forest.castArguments(arguments),
+                isConst: isConst)
+              ..fileOffset = charOffset;
+        if (constness == Constness.implicit &&
+            procedure.isConst &&
+            constantContext != ConstantContext.inferred) {
+          constructorInvocationsWithImplicitConstness.add(invocation);
+        }
+        return invocation;
       } else {
         return new ShadowStaticInvocation(
             target, forest.castArguments(arguments),
@@ -3435,7 +3520,8 @@
   void beginTypeVariables(Token token) {
     debugEvent("beginTypeVariables");
     OutlineBuilder listener = new OutlineBuilder(library);
-    new ClassMemberParser(listener).parseTypeVariablesOpt(token.previous);
+    new ClassMemberParser(listener)
+        .parseTypeVariablesOpt(new Token.eof(-1)..next = token);
     enterFunctionTypeScope(listener.pop());
   }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart
new file mode 100644
index 0000000..54371b0
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/constness_evaluator.dart
@@ -0,0 +1,467 @@
+// 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 'package:kernel/ast.dart' hide MapEntry;
+
+import 'package:kernel/core_types.dart' show CoreTypes;
+
+import 'package:kernel/visitor.dart' show RecursiveVisitor;
+
+import '../names.dart'
+    show
+        ampersandName,
+        barName,
+        caretName,
+        divisionName,
+        doubleAmpersandName,
+        doubleBarName,
+        doubleQuestionName,
+        equalsName,
+        greaterThanName,
+        greaterThanOrEqualsName,
+        identicalName,
+        leftShiftName,
+        lessThanName,
+        lessThanOrEqualsName,
+        minusName,
+        multiplyName,
+        mustacheName,
+        negationName,
+        percentName,
+        plusName,
+        rightShiftName,
+        tildaName,
+        unaryMinusName;
+
+import '../problems.dart' show unhandled;
+
+enum ConstnessEffect {
+  decidedNew,
+  allowedConst,
+  taintedConst,
+}
+
+enum ConstantKind {
+  nullConstant,
+  boolConstant,
+  intConstant,
+  doubleConstant,
+  stringConstant,
+  symbolConstant,
+  typeConstant,
+  listConstant,
+  mapConstant,
+  interfaceConstant,
+}
+
+class ConstnessInfo {
+  final ConstnessEffect effect;
+  final ConstantKind kind;
+  final Map<Reference, ConstnessInfo> fields;
+
+  // TODO(dmitryas): Find a way to impose the following restrictions:
+  //   * `kind == null || effect != ConstnessEffect.decidedNew`
+  //   * `fields == null || kind == ConstantKind.interfaceConstant`.
+  const ConstnessInfo(this.effect, [this.kind, this.fields]);
+
+  const ConstnessInfo.decidedNew()
+      : this(ConstnessEffect.decidedNew, null, null);
+
+  const ConstnessInfo.allowedConst(ConstantKind kind,
+      [Map<Reference, ConstnessInfo> fields])
+      : this(ConstnessEffect.allowedConst, kind, fields);
+
+  const ConstnessInfo.taintedConst(ConstantKind kind,
+      [Map<Reference, ConstnessInfo> fields])
+      : this(ConstnessEffect.taintedConst, kind, fields);
+
+  bool get isConst => effect != ConstnessEffect.decidedNew;
+
+  bool get isPrimitiveConstant => kind != ConstantKind.interfaceConstant;
+
+  bool get isInterfaceConstant => kind == ConstantKind.interfaceConstant;
+}
+
+/// Evaluates constness of the given constructor invocation.
+///
+/// TODO(dmitryas): Share code with the constant evaluator from
+/// pkg/kernel/lib/transformations/constants.dart.
+class ConstnessEvaluator extends RecursiveVisitor<ConstnessInfo> {
+  final Map<Expression, ConstnessInfo> constnesses =
+      <Expression, ConstnessInfo>{};
+
+  final CoreTypes coreTypes;
+
+  ConstnessEvaluator(this.coreTypes);
+
+  ConstnessInfo evaluate(Expression node) {
+    return node.accept(this);
+  }
+
+  List<ConstnessInfo> evaluateList(List<Expression> nodes) {
+    List<ConstnessInfo> result = new List<ConstnessInfo>(nodes.length);
+    for (int i = 0; i < nodes.length; ++i) {
+      result[i] = nodes[i].accept(this);
+    }
+    return result;
+  }
+
+  @override
+  defaultTreeNode(TreeNode node) {
+    unhandled(
+        "${node}", "defaultTreeNode", node.fileOffset, node.location.file);
+    return null;
+  }
+
+  visitNullLiteral(NullLiteral node) {
+    return const ConstnessInfo.allowedConst(ConstantKind.nullConstant);
+  }
+
+  visitBoolLiteral(BoolLiteral node) {
+    return const ConstnessInfo.allowedConst(ConstantKind.boolConstant);
+  }
+
+  visitIntLiteral(IntLiteral node) {
+    return const ConstnessInfo.allowedConst(ConstantKind.intConstant);
+  }
+
+  visitDoubleLiteral(DoubleLiteral node) {
+    return const ConstnessInfo.allowedConst(ConstantKind.doubleConstant);
+  }
+
+  visitStringLiteral(StringLiteral node) {
+    return const ConstnessInfo.allowedConst(ConstantKind.stringConstant);
+  }
+
+  visitSymbolLiteral(SymbolLiteral node) {
+    return const ConstnessInfo.allowedConst(ConstantKind.symbolConstant);
+  }
+
+  visitTypeLiteral(TypeLiteral node) {
+    return const ConstnessInfo.allowedConst(ConstantKind.typeConstant);
+  }
+
+  visitListLiteral(ListLiteral node) {
+    if (node.isConst) {
+      return const ConstnessInfo.allowedConst(ConstantKind.listConstant);
+    }
+    return const ConstnessInfo.decidedNew();
+  }
+
+  visitMapLiteral(MapLiteral node) {
+    if (node.isConst) {
+      return const ConstnessInfo.allowedConst(ConstantKind.mapConstant);
+    }
+    return const ConstnessInfo.decidedNew();
+  }
+
+  visitConstructorInvocation(ConstructorInvocation node) {
+    if (constnesses[node] != null) return constnesses[node];
+
+    if (!node.target.isConst) {
+      return const ConstnessInfo.decidedNew();
+    }
+
+    List<ConstnessInfo> positionalArgumentsInfos =
+        new List<ConstnessInfo>(node.arguments.positional.length);
+    for (int i = 0; i < positionalArgumentsInfos.length; ++i) {
+      positionalArgumentsInfos[i] = node.arguments.positional[i].accept(this);
+    }
+
+    Map<String, ConstnessInfo> namedArgumentsInfos = <String, ConstnessInfo>{};
+    for (NamedExpression namedArgument in node.arguments.named) {
+      namedArgumentsInfos[namedArgument.name] =
+          namedArgument.value.accept(this);
+    }
+
+    ConstnessEffect resultEffect =
+        minConstnessEffectOnInfos(positionalArgumentsInfos);
+    if (resultEffect != null) {
+      resultEffect = minConstnessEffectOnPair(
+          resultEffect, minConstnessEffectOnInfos(namedArgumentsInfos.values));
+    } else {
+      resultEffect = minConstnessEffectOnInfos(namedArgumentsInfos.values);
+    }
+    resultEffect ??= ConstnessEffect.allowedConst;
+
+    if (resultEffect == ConstnessEffect.decidedNew) {
+      return const ConstnessInfo.decidedNew();
+    }
+
+    return constnesses[node] =
+        new ConstnessInfo(resultEffect, ConstantKind.interfaceConstant);
+  }
+
+  visitMethodInvocation(MethodInvocation node) {
+    Expression receiver = node.receiver;
+    ConstnessInfo receiverConstness = receiver.accept(this);
+    List<ConstnessInfo> positionalArgumentConstness =
+        new List<ConstnessInfo>(node.arguments.positional.length);
+    for (int i = 0; i < positionalArgumentConstness.length; ++i) {
+      positionalArgumentConstness[i] =
+          node.arguments.positional[i].accept(this);
+    }
+    Map<String, ConstnessInfo> namedArgumentConstness =
+        <String, ConstnessInfo>{};
+    for (NamedExpression namedArgument in node.arguments.named) {
+      namedArgumentConstness[namedArgument.name] =
+          namedArgument.value.accept(this);
+    }
+
+    ConstnessEffect minimumConstnessEffect = receiverConstness.effect;
+    minimumConstnessEffect = minConstnessEffectOnPair(minimumConstnessEffect,
+        minConstnessEffectOnInfos(positionalArgumentConstness));
+    minimumConstnessEffect = minConstnessEffectOnPair(minimumConstnessEffect,
+        minConstnessEffectOnInfos(namedArgumentConstness.values));
+
+    if (minimumConstnessEffect == ConstnessEffect.decidedNew) {
+      return const ConstnessInfo.decidedNew();
+    }
+
+    // Special case: ==.
+    if (node.name == equalsName) {
+      assert(node.arguments.positional.length == 1);
+      return new ConstnessInfo(
+          minimumConstnessEffect, ConstantKind.boolConstant);
+    }
+
+    // Check for operations that are known to yield a constant value, like the
+    // addition of two integer constants.
+    if (node.arguments.named.length == 0) {
+      List<ConstantKind> argumentsKinds =
+          new List<ConstantKind>(positionalArgumentConstness.length);
+      for (int i = 0; i < argumentsKinds.length; ++i) {
+        argumentsKinds[i] = positionalArgumentConstness[i].kind;
+      }
+      ConstantKind resultKind = evaluateConstantMethodInvocationKind(
+          receiverConstness.kind, node.name, argumentsKinds);
+      if (resultKind != null) {
+        return new ConstnessInfo(minimumConstnessEffect, resultKind);
+      }
+    }
+
+    return const ConstnessInfo.decidedNew();
+  }
+
+  visitLogicalExpression(LogicalExpression node) {
+    ConstnessInfo left = node.left.accept(this);
+    if (node.operator == doubleBarName) {
+      ConstnessInfo right = node.right.accept(this);
+      if (left.isConst && right.isConst) {
+        return new ConstnessInfo(
+            minConstnessEffectOnPair(left.effect, right.effect),
+            ConstantKind.boolConstant);
+      }
+      // TODO(dmitryas): Handle the case where [left] is `true`.
+    } else if (node.operator == doubleAmpersandName) {
+      ConstnessInfo right = node.right.accept(this);
+      if (left.isConst && right.isConst) {
+        return new ConstnessInfo(
+            minConstnessEffectOnPair(left.effect, right.effect),
+            ConstantKind.boolConstant);
+      }
+      // TODO(dmitryas): Handle the case when [left] is `false`.
+    } else if (node.operator == doubleQuestionName) {
+      ConstnessInfo right = node.right.accept(this);
+      if (left.isConst && left.kind == ConstantKind.nullConstant) {
+        if (right.isConst) {
+          return right;
+        }
+      } else {
+        if (left.isConst) {
+          return left;
+        }
+      }
+    }
+    return const ConstnessInfo.decidedNew();
+  }
+
+  visitConditionalExpression(ConditionalExpression node) {
+    // TODO(dmitryas): Handle this case after boolean constants are handled.
+    return const ConstnessInfo.taintedConst(null);
+  }
+
+  visitPropertyGet(PropertyGet node) {
+    // TODO(dmitryas): Handle this case after fields are handled.
+    ConstnessInfo receiverInfo = node.receiver.accept(this);
+    if (receiverInfo.isConst &&
+        receiverInfo.kind == ConstantKind.stringConstant) {
+      return new ConstnessInfo(receiverInfo.effect, ConstantKind.intConstant);
+    }
+    return const ConstnessInfo.taintedConst(null);
+  }
+
+  visitLet(Let node) {
+    return node.body.accept(this);
+  }
+
+  visitVariableGet(VariableGet node) {
+    if (!node.variable.isConst) return const ConstnessInfo.decidedNew();
+    // TODO(dmitryas): Handle the case of recursive dependencies.
+    return node.variable.initializer.accept(this);
+  }
+
+  visitStaticGet(StaticGet node) {
+    // TODO(dmitryas): Handle this case.
+    return const ConstnessInfo.taintedConst(null);
+  }
+
+  visitStringConcatenation(StringConcatenation node) {
+    List<ConstnessInfo> infos =
+        new List<ConstnessInfo>(node.expressions.length);
+    bool isPrimitiveConstant = true;
+    for (int i = 0; i < infos.length; ++i) {
+      infos[i] = node.expressions[i].accept(this);
+      isPrimitiveConstant = isPrimitiveConstant && infos[i].isPrimitiveConstant;
+    }
+    ConstnessEffect effect = minConstnessEffectOnInfos(infos);
+
+    // Only primitive constants are allowed during const string interpolation.
+    if (effect == ConstnessEffect.decidedNew || !isPrimitiveConstant) {
+      return const ConstnessInfo.decidedNew();
+    }
+
+    return new ConstnessInfo(effect, ConstantKind.stringConstant);
+  }
+
+  visitStaticInvocation(StaticInvocation node) {
+    // TODO(dmitryas): Handle this case better.
+    Member target = node.target;
+    if (target.name == identicalName) {
+      final TreeNode parent = target.parent;
+      if (parent is Library && parent == coreTypes.coreLibrary) {
+        assert(node.arguments.positional.length == 2);
+        ConstnessEffect effect = minConstnessEffectOnPair(
+            node.arguments.positional[0].accept(this).effect,
+            node.arguments.positional[1].accept(this).effect);
+        if (effect == ConstnessEffect.decidedNew) {
+          return const ConstnessInfo.decidedNew();
+        }
+        return new ConstnessInfo(effect, ConstantKind.boolConstant);
+      }
+    }
+    return const ConstnessInfo.taintedConst(null);
+  }
+
+  visitAsExpression(AsExpression node) {
+    // TODO(dmitryas): Handle this case.
+    return const ConstnessInfo.taintedConst(null);
+  }
+
+  visitNot(Not node) {
+    return node.operand.accept(this);
+  }
+
+  /// Tells the minimum constness effect assuming the following:
+  ///   * [ConstnessEffect.allowedConst] > [ConstnessEffect.taintedConst]
+  ///   * [ConstnessEffect.taintedConst] > [ConstnessEffect.decidedNew]
+  static ConstnessEffect minConstnessEffectOnPair(
+      ConstnessEffect x, ConstnessEffect y) {
+    if (x == ConstnessEffect.decidedNew) {
+      return x;
+    }
+    if (x == ConstnessEffect.allowedConst) {
+      return y;
+    }
+    // x == ConstnessEffect.taintedConst.
+    if (y == ConstnessEffect.decidedNew) {
+      return y;
+    }
+    return x;
+  }
+
+  /// Calculates minimum constness effect in [effects] using
+  /// [minConstnessEffectOnPair].  Returns null if [effects] is null or empty.
+  static ConstnessEffect minConstnessEffect(Iterable<ConstnessEffect> effects) {
+    if (effects == null || effects.isEmpty) return null;
+
+    ConstnessEffect result = ConstnessEffect.allowedConst;
+    for (ConstnessEffect effect in effects) {
+      result = minConstnessEffectOnPair(result, effect);
+    }
+    return result;
+  }
+
+  /// Calculates minimum constness effect in [infos] using
+  /// [minConstnessEffectOnPair].  Returns null if [infos] is null or empty.
+  static ConstnessEffect minConstnessEffectOnInfos(
+      Iterable<ConstnessInfo> infos) {
+    if (infos == null || infos.isEmpty) return null;
+
+    ConstnessEffect result = ConstnessEffect.allowedConst;
+    for (ConstnessInfo info in infos) {
+      result = minConstnessEffectOnPair(result, info.effect);
+    }
+    return result;
+  }
+
+  /// Returns null if `receiver.name(arguments)` is not a constant.
+  static ConstantKind evaluateConstantMethodInvocationKind(
+      ConstantKind receiver, Name name, List<ConstantKind> arguments) {
+    if (receiver == ConstantKind.stringConstant) {
+      if (arguments.length == 1) {
+        if (arguments[0] == ConstantKind.stringConstant) {
+          if (name == plusName) return ConstantKind.intConstant;
+        }
+      }
+    } else if (receiver == ConstantKind.boolConstant) {
+      if (arguments.length == 1) {
+        if (name == negationName) return ConstantKind.boolConstant;
+      } else if (arguments.length == 2) {
+        // TODO(dmitryas): Figure out if `&&` and `||` can be methods.
+      }
+    } else if (receiver == ConstantKind.intConstant) {
+      if (arguments.length == 0) {
+        if (name == unaryMinusName) return ConstantKind.intConstant;
+        if (name == tildaName) return ConstantKind.intConstant;
+      } else if (arguments.length == 1) {
+        if (arguments[0] == ConstantKind.intConstant) {
+          if (name == barName) return ConstantKind.intConstant;
+          if (name == ampersandName) return ConstantKind.intConstant;
+          if (name == caretName) return ConstantKind.intConstant;
+          if (name == leftShiftName) return ConstantKind.intConstant;
+          if (name == rightShiftName) return ConstantKind.intConstant;
+        }
+        if (arguments[0] == ConstantKind.intConstant ||
+            arguments[0] == ConstantKind.doubleConstant) {
+          if (name == plusName) return arguments[0];
+          if (name == minusName) return arguments[0];
+          if (name == multiplyName) return arguments[0];
+          if (name == divisionName) return arguments[0];
+          if (name == mustacheName) return arguments[0];
+          if (name == percentName) return arguments[0];
+          if (name == lessThanName) return ConstantKind.boolConstant;
+          if (name == lessThanOrEqualsName) return ConstantKind.boolConstant;
+          if (name == greaterThanOrEqualsName) return ConstantKind.boolConstant;
+          if (name == greaterThanName) return ConstantKind.boolConstant;
+        }
+      }
+    } else if (receiver == ConstantKind.doubleConstant) {
+      if (arguments.length == 0) {
+        if (name == unaryMinusName) return ConstantKind.doubleConstant;
+      } else if (arguments.length == 1) {
+        if (arguments[0] == ConstantKind.intConstant ||
+            arguments[0] == ConstantKind.doubleConstant) {
+          if (name == plusName) return ConstantKind.doubleConstant;
+          if (name == minusName) return ConstantKind.doubleConstant;
+          if (name == multiplyName) return ConstantKind.doubleConstant;
+          if (name == divisionName) return ConstantKind.doubleConstant;
+          if (name == mustacheName) return ConstantKind.doubleConstant;
+          if (name == percentName) return ConstantKind.doubleConstant;
+          if (name == lessThanName) return ConstantKind.boolConstant;
+          if (name == lessThanOrEqualsName) return ConstantKind.boolConstant;
+          if (name == greaterThanOrEqualsName) return ConstantKind.boolConstant;
+          if (name == greaterThanName) return ConstantKind.boolConstant;
+        }
+      }
+    }
+
+    return null;
+  }
+}
+
+// TODO(32717): Remove this helper function when the issue is resolved.
+ConstnessInfo evaluateConstness(Expression expression, CoreTypes coreTypes) {
+  return new ConstnessEvaluator(coreTypes).evaluate(expression);
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index c340ea7..6b91235 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -45,6 +45,7 @@
         ReturnStatement,
         Statement,
         StaticGet,
+        StaticInvocation,
         StringConcatenation,
         SuperInitializer,
         SwitchCase,
diff --git a/pkg/front_end/lib/src/fasta/names.dart b/pkg/front_end/lib/src/fasta/names.dart
index 7e3b346..d58c171 100644
--- a/pkg/front_end/lib/src/fasta/names.dart
+++ b/pkg/front_end/lib/src/fasta/names.dart
@@ -16,10 +16,22 @@
 
 final Name divisionName = new Name("/");
 
+final Name doubleAmpersandName = new Name("&&");
+
+final Name doubleBarName = new Name("||");
+
+final Name doubleQuestionName = new Name("??");
+
 final Name emptyName = new Name("");
 
 final Name equalsName = new Name('==');
 
+final Name greaterThanName = new Name(">");
+
+final Name greaterThanOrEqualsName = new Name(">=");
+
+final Name identicalName = new Name("identical");
+
 final Name indexGetName = new Name("[]");
 
 final Name indexSetName = new Name("[]=");
@@ -28,12 +40,18 @@
 
 final Name lengthName = new Name("length");
 
+final Name lessThanName = new Name("<");
+
+final Name lessThanOrEqualsName = new Name("<=");
+
 final Name minusName = new Name("-");
 
 final Name multiplyName = new Name("*");
 
 final Name mustacheName = new Name("~/");
 
+final Name negationName = new Name("!");
+
 final Name noSuchMethodName = new Name("noSuchMethod");
 
 final Name percentName = new Name("%");
@@ -41,3 +59,7 @@
 final Name plusName = new Name("+");
 
 final Name rightShiftName = new Name(">>");
+
+final Name tildaName = new Name("~");
+
+final Name unaryMinusName = new Name("unary-");
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index 17fb305..353a654 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -1292,6 +1292,16 @@
   }
 
   @override
+  void beginFormalParameterDefaultValueExpression() {
+    listener?.beginFormalParameterDefaultValueExpression();
+  }
+
+  @override
+  void endFormalParameterDefaultValueExpression() {
+    listener?.endFormalParameterDefaultValueExpression();
+  }
+
+  @override
   void handleValuedFormalParameter(Token equals, Token token) {
     listener?.handleValuedFormalParameter(equals, token);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 2b4d876..e71259c 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1164,6 +1164,12 @@
     logEvent("UnaryPrefixAssignmentExpression");
   }
 
+  void beginFormalParameterDefaultValueExpression() {}
+
+  void endFormalParameterDefaultValueExpression() {
+    logEvent("FormalParameterDefaultValueExpression");
+  }
+
   void handleValuedFormalParameter(Token equals, Token token) {
     logEvent("ValuedFormalParameter");
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index d0e1de3..8f72afc 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -2713,7 +2713,9 @@
         String value = token.stringValue;
         if ((identical('=', value)) || (identical(':', value))) {
           Token equal = token;
+          listener.beginFormalParameterDefaultValueExpression();
           beforeToken = parseExpression(token);
+          listener.endFormalParameterDefaultValueExpression();
           token = beforeToken.next;
           listener.handleValuedFormalParameter(equal, token);
           if (isMandatoryFormalParameterKind(parameterKind)) {
@@ -6007,29 +6009,51 @@
       Token comma = null;
       if (identical(value, 'catch')) {
         catchKeyword = token;
+
         Token openParens = catchKeyword.next;
-        Token exceptionName = openParens.next;
-        Token commaOrCloseParens = exceptionName.next;
-        Token traceName = commaOrCloseParens.next;
-        Token closeParens = traceName.next;
         if (!optional("(", openParens)) {
-          // Handled below by parseFormalParameters.
-        } else if (!exceptionName.isIdentifier) {
+          reportRecoverableError(openParens, fasta.messageCatchSyntax);
+          BeginToken open = new SyntheticBeginToken(
+              TokenType.OPEN_PAREN, openParens.charOffset);
+          Token identifier = open.setNext(new SyntheticStringToken(
+              TokenType.IDENTIFIER, '', openParens.charOffset));
+          Token close = identifier.setNext(
+              new SyntheticToken(TokenType.CLOSE_PAREN, openParens.charOffset));
+          open.endGroup = close;
+          rewriter.insertTokenAfter(catchKeyword, open);
+          openParens = open;
+        }
+
+        Token exceptionName = openParens.next;
+        if (!exceptionName.isIdentifier) {
           reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
-        } else if (optional(")", commaOrCloseParens)) {
+          if (!exceptionName.isKeywordOrIdentifier) {
+            exceptionName = new SyntheticStringToken(
+                TokenType.IDENTIFIER, '', exceptionName.charOffset, 0);
+            rewriter.insertTokenAfter(openParens, exceptionName);
+          }
+        }
+
+        Token commaOrCloseParens = exceptionName.next;
+        if (optional(")", commaOrCloseParens)) {
           // OK: `catch (identifier)`.
         } else if (!optional(",", commaOrCloseParens)) {
           reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
         } else {
           comma = commaOrCloseParens;
+          Token traceName = comma.next;
           if (!traceName.isIdentifier) {
             reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
-          } else if (!optional(")", closeParens)) {
+            if (!traceName.isKeywordOrIdentifier) {
+              traceName = new SyntheticStringToken(
+                  TokenType.IDENTIFIER, '', traceName.charOffset, 0);
+              rewriter.insertTokenAfter(comma, traceName);
+            }
+          } else if (!optional(")", traceName.next)) {
             reportRecoverableError(exceptionName, fasta.messageCatchSyntax);
           }
         }
-        lastConsumed =
-            parseFormalParametersRequiredOpt(token, MemberKind.Catch);
+        lastConsumed = parseFormalParameters(catchKeyword, MemberKind.Catch);
         token = lastConsumed.next;
       }
       listener.endCatchClause(token);
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index 1637a9f..36be86a 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -780,6 +780,17 @@
   }
 
   @override
+  void beginFormalParameterDefaultValueExpression() {
+    // Ignored for now.
+  }
+
+  @override
+  void endFormalParameterDefaultValueExpression() {
+    debugEvent("FormalParameterDefaultValueExpression");
+    // Ignored for now.
+  }
+
+  @override
   void handleValuedFormalParameter(Token equals, Token token) {
     debugEvent("ValuedFormalParameter");
     // Ignored for now.
diff --git a/pkg/front_end/lib/src/scanner/errors.dart b/pkg/front_end/lib/src/scanner/errors.dart
index 0e77ee52..b9fa104 100644
--- a/pkg/front_end/lib/src/scanner/errors.dart
+++ b/pkg/front_end/lib/src/scanner/errors.dart
@@ -47,10 +47,9 @@
 
   static const ScannerErrorCode UNTERMINATED_MULTI_LINE_COMMENT =
       const ScannerErrorCode(
-          'UNTERMINATED_MULTI_LINE_COMMENT',
-          "Unterminated multi-line comment.",
-          "Try terminating the comment with '*/', or "
-          "removing any unbalanced occurances of '/*' (because comments nest in Dart).");
+          'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.",
+          correction: "Try terminating the comment with '*/', or "
+              "removing any unbalanced occurances of '/*' (because comments nest in Dart).");
 
   static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
       const ScannerErrorCode(
@@ -62,8 +61,8 @@
    * template. The correction associated with the error will be created from the
    * given [correction] template.
    */
-  const ScannerErrorCode(String name, String message, [String correction])
-      : super(name, message, correction);
+  const ScannerErrorCode(String name, String message, {String correction})
+      : super(name, message, correction: correction);
 
   @override
   ErrorSeverity get errorSeverity => ErrorSeverity.ERROR;
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index e93ba87..01a8aa0 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -40,8 +40,6 @@
 CantInferTypeDueToInconsistentOverrides/example: Fail
 CantUseSuperBoundedTypeForInstanceCreation/analyzerCode: Fail
 CantUseSuperBoundedTypeForInstanceCreation/example: Fail
-CatchSyntax/analyzerCode: Fail
-CatchSyntax/example: Fail
 ColonInPlaceOfIn/example: Fail
 ConflictsWithConstructor/analyzerCode: Fail
 ConflictsWithConstructor/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 86381e1..dcdc6d1 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -927,7 +927,12 @@
 CatchSyntax:
   template: "'catch' must be followed by '(identifier)' or '(identifier, identifier)'."
   tip: "No types are needed, the first is given by 'on', the second is always 'StackTrace'."
+  analyzerCode: CATCH_SYNTAX
   dart2jsCode: "*ignored*"
+  statement:
+    - "try {} catch {}"
+    - "try {} catch () {}"
+    - "try {} catch (e,) {}"
 
 SuperNullAware:
   template: "'super' can't be null."
@@ -2037,5 +2042,4 @@
   template: "The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here."
   severity: ERROR
   expression:
-    - "Object()"
     - "bool.fromEnvironment('fisk')"
diff --git a/pkg/front_end/testcases/magic_const.dart.direct.expect b/pkg/front_end/testcases/magic_const.dart.direct.expect
index f5152ff..8595e97 100644
--- a/pkg/front_end/testcases/magic_const.dart.direct.expect
+++ b/pkg/front_end/testcases/magic_const.dart.direct.expect
@@ -21,9 +21,7 @@
   invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
   const NotConstant();
         ^";
-  invalid-expression "pkg/front_end/testcases/magic_const.dart:19:3: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-  Constant();
-  ^";
+  const self::Constant::•();
   const dynamic x = const self::Constant::•();
   invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
   bool.fromEnvironment(\"fisk\");
diff --git a/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect b/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect
index f5152ff..8595e97 100644
--- a/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/magic_const.dart.direct.transformed.expect
@@ -21,9 +21,7 @@
   invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
   const NotConstant();
         ^";
-  invalid-expression "pkg/front_end/testcases/magic_const.dart:19:3: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-  Constant();
-  ^";
+  const self::Constant::•();
   const dynamic x = const self::Constant::•();
   invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
   bool.fromEnvironment(\"fisk\");
diff --git a/pkg/front_end/testcases/magic_const.dart.strong.expect b/pkg/front_end/testcases/magic_const.dart.strong.expect
index 6648bbe..f3197ea 100644
--- a/pkg/front_end/testcases/magic_const.dart.strong.expect
+++ b/pkg/front_end/testcases/magic_const.dart.strong.expect
@@ -21,9 +21,7 @@
   invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
   const NotConstant();
         ^";
-  invalid-expression "pkg/front_end/testcases/magic_const.dart:19:3: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-  Constant();
-  ^";
+  const self::Constant::•();
   const self::Constant x = const self::Constant::•();
   invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
   bool.fromEnvironment(\"fisk\");
diff --git a/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect b/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
index 6648bbe..f3197ea 100644
--- a/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/magic_const.dart.strong.transformed.expect
@@ -21,9 +21,7 @@
   invalid-expression "pkg/front_end/testcases/magic_const.dart:18:9: Error: Not a const constructor.
   const NotConstant();
         ^";
-  invalid-expression "pkg/front_end/testcases/magic_const.dart:19:3: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
-  Constant();
-  ^";
+  const self::Constant::•();
   const self::Constant x = const self::Constant::•();
   invalid-expression "pkg/front_end/testcases/magic_const.dart:21:8: Error: The keyword 'const' or 'new' is required here. Due to an implementation limit, the compiler isn't able to infer 'const' or 'new' here.
   bool.fromEnvironment(\"fisk\");
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart b/pkg/front_end/testcases/new_const_insertion/simple.dart
new file mode 100644
index 0000000..9243884
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// This test checks that new/const insertion works for some simple cases.
+
+class A {
+  final int x;
+  const A(this.x);
+}
+
+main() {
+  int foo = 42;
+  A(5);
+  A(5 + 5);
+  A(foo);
+  A(5 + foo);
+}
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.expect
new file mode 100644
index 0000000..de2c44c
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x;
+  const constructor •(core::int x) → void
+    : self::A::x = x, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::int foo = 42;
+  const self::A::•(5);
+  const self::A::•(5.+(5));
+  new self::A::•(foo);
+  new self::A::•(5.+(foo));
+}
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.transformed.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.transformed.expect
new file mode 100644
index 0000000..de2c44c
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.direct.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x;
+  const constructor •(core::int x) → void
+    : self::A::x = x, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::int foo = 42;
+  const self::A::•(5);
+  const self::A::•(5.+(5));
+  new self::A::•(foo);
+  new self::A::•(5.+(foo));
+}
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.outline.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.outline.expect
new file mode 100644
index 0000000..61d4856
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.outline.expect
@@ -0,0 +1,11 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x;
+  const constructor •(core::int x) → void
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.expect
new file mode 100644
index 0000000..4ee5522
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x;
+  const constructor •(core::int x) → void
+    : self::A::x = x, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::int foo = 42;
+  const self::A::•(5);
+  const self::A::•(5.{core::num::+}(5));
+  new self::A::•(foo);
+  new self::A::•(5.{core::num::+}(foo));
+}
diff --git a/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.transformed.expect b/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.transformed.expect
new file mode 100644
index 0000000..4ee5522
--- /dev/null
+++ b/pkg/front_end/testcases/new_const_insertion/simple.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  final field core::int x;
+  const constructor •(core::int x) → void
+    : self::A::x = x, super core::Object::•()
+    ;
+}
+static method main() → dynamic {
+  core::int foo = 42;
+  const self::A::•(5);
+  const self::A::•(5.{core::num::+}(5));
+  new self::A::•(foo);
+  new self::A::•(5.{core::num::+}(foo));
+}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index bdc3645..6f767dc 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -106,6 +106,7 @@
 inference/mixin_inference_outwards_4: TypeCheckError
 inference/mixin_inference_unification_1: TypeCheckError
 inference/mixin_inference_unification_2: TypeCheckError
+inference/override_equals: RuntimeError
 inference/unresolved_super: TypeCheckError
 inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr1: Fail # Issue #25824
 inference/unsafe_block_closure_inference_function_call_explicit_dynamic_param_via_expr2: Fail # Issue #25824
diff --git a/pkg/js_ast/lib/src/builder.dart b/pkg/js_ast/lib/src/builder.dart
index dfebe7a..8366dd0 100644
--- a/pkg/js_ast/lib/src/builder.dart
+++ b/pkg/js_ast/lib/src/builder.dart
@@ -466,7 +466,7 @@
   }
 
   Iterable<Literal> joinLiterals(Iterable<Literal> list, Literal separator) {
-    return new _InterleaveIterable(list, separator);
+    return new _InterleaveIterable<Literal>(list, separator);
   }
 
   LiteralString quoteName(Name name, {allowNull: false}) {
@@ -1574,9 +1574,9 @@
   }
 }
 
-class _InterleaveIterator implements Iterator<Node> {
-  Iterator<Node> source;
-  Node separator;
+class _InterleaveIterator<T extends Node> implements Iterator<T> {
+  Iterator<T> source;
+  T separator;
   bool isNextSeparator = false;
   bool isInitialized = false;
 
@@ -1594,19 +1594,19 @@
     }
   }
 
-  Node get current {
+  T get current {
     if (isNextSeparator) return separator;
     return source.current;
   }
 }
 
-class _InterleaveIterable extends IterableBase {
-  Iterable<Node> source;
-  Node separator;
+class _InterleaveIterable<T extends Node> extends IterableBase<T> {
+  Iterable<T> source;
+  T separator;
 
   _InterleaveIterable(this.source, this.separator);
 
-  Iterator<Node> get iterator {
-    return new _InterleaveIterator(source.iterator, separator);
+  Iterator<T> get iterator {
+    return new _InterleaveIterator<T>(source.iterator, separator);
   }
 }
diff --git a/pkg/js_ast/lib/src/nodes.dart b/pkg/js_ast/lib/src/nodes.dart
index 480ab21..9b933ae 100644
--- a/pkg/js_ast/lib/src/nodes.dart
+++ b/pkg/js_ast/lib/src/nodes.dart
@@ -979,6 +979,8 @@
   R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
       visitor.visitName(this, arg);
 
+  Name _clone();
+
   /// Returns a unique [key] for this name.
   ///
   /// The key is unrelated to the actual name and is not intended for human
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index 82edc93..21f94bd 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -1297,7 +1297,7 @@
 
   bool visitProgram(Program node) => false;
 
-  bool visitNode(Statement node) {
+  bool visitNode(Node node) {
     context.error("Forgot node: $node");
     return null;
   }
diff --git a/pkg/js_ast/lib/src/template.dart b/pkg/js_ast/lib/src/template.dart
index 1c09529..9c055db 100644
--- a/pkg/js_ast/lib/src/template.dart
+++ b/pkg/js_ast/lib/src/template.dart
@@ -130,7 +130,7 @@
  * trees. [arguments] is a List for positional templates, or Map for
  * named templates.
  */
-typedef Node Instantiator(var arguments);
+typedef /*Node|Iterable<Node>*/ Instantiator(var arguments);
 
 /**
  * InstantiatorGeneratorVisitor compiles a template.  This class compiles a tree
@@ -300,7 +300,8 @@
   }
 
   Instantiator visitProgram(Program node) {
-    List instantiators = node.body.map(visitSplayableStatement).toList();
+    List<Instantiator> instantiators =
+        node.body.map(visitSplayableStatement).toList();
     return (arguments) {
       List<Statement> statements = <Statement>[];
       void add(node) {
@@ -320,7 +321,8 @@
   }
 
   Instantiator visitBlock(Block node) {
-    List instantiators = node.statements.map(visitSplayableStatement).toList();
+    List<Instantiator> instantiators =
+        node.statements.map(visitSplayableStatement).toList();
     return (arguments) {
       List<Statement> statements = <Statement>[];
       void add(node) {
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 6179db3..6a577c3 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -1200,6 +1200,7 @@
   List<Expression> annotations;
   StringReference name; // Cosmetic, may be empty, not unique.
   DartType bound; // 'dynamic' if no explicit bound was given.
+  Option<DartType> defaultType; // type used when the parameter is not passed
 }
 
 ```
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 099307e..c2fa92f 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -5220,6 +5220,13 @@
   /// be set to the root class for type parameters without an explicit bound.
   DartType bound;
 
+  /// The default value of the type variable. It is used to provide the
+  /// corresponding missing type argument in type annotations and as the
+  /// fall-back type value in type inference at compile time. At run time,
+  /// [defaultType] is used by the backends in place of the missing type
+  /// argument of a dynamic invocation of a generic function.
+  DartType defaultType;
+
   TypeParameter([this.name, this.bound]);
 
   // Must match serialized bit positions.
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 4869901..951aedd 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1750,6 +1750,7 @@
     node.annotations = readAnnotationList(node);
     node.name = readStringOrNullIfEmpty();
     node.bound = readDartType();
+    node.defaultType = readDartTypeOption();
   }
 
   Arguments readArguments() {
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index a71ec32..a050b72 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1716,6 +1716,7 @@
     writeAnnotationList(node.annotations);
     writeStringReference(node.name ?? '');
     writeNode(node.bound);
+    writeOptionalNode(node.defaultType);
   }
 
   // ================================================================
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 3901902..22dbf96 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -470,6 +470,9 @@
     var newNode = new TypeParameter(node.name);
     typeSubstitution[node] = new TypeParameterType(newNode);
     newNode.bound = visitType(node.bound);
+    if (node.defaultType != null) {
+      newNode.defaultType = visitType(node.defaultType);
+    }
     return newNode..flags = node.flags;
   }
 
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index ade2e8e..1a19346 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1842,6 +1842,10 @@
     writeWord(getTypeParameterName(node));
     writeSpaced('extends');
     writeType(node.bound);
+    if (node.defaultType != null) {
+      writeSpaced('=');
+      writeType(node.defaultType);
+    }
   }
 
   visitConstantExpression(ConstantExpression node) {
diff --git a/pkg/vm/bin/frontend_server_starter.dart b/pkg/vm/bin/frontend_server_starter.dart
index 229410b..f81d98b 100644
--- a/pkg/vm/bin/frontend_server_starter.dart
+++ b/pkg/vm/bin/frontend_server_starter.dart
@@ -1,7 +1,10 @@
 library frontend_server;
 
+import 'dart:async';
+import 'dart:io';
+
 import '../lib/frontend_server.dart';
 
-void main(List<String> args) {
-  starter(args);
+Future<Null> main(List<String> args) async {
+  exit(await starter(args));
 }
diff --git a/pkg/vm/lib/frontend_server.dart b/pkg/vm/lib/frontend_server.dart
index 15ee47f..0b96037 100644
--- a/pkg/vm/lib/frontend_server.dart
+++ b/pkg/vm/lib/frontend_server.dart
@@ -17,6 +17,7 @@
 import 'package:front_end/src/api_prototype/compiler_options.dart';
 import 'package:front_end/src/api_prototype/file_system.dart'
     show FileSystemEntity;
+import 'package:front_end/src/api_prototype/front_end.dart';
 // Use of multi_root_file_system.dart directly from front_end package is a
 // temporarily solution while we are looking for better home for that
 // functionality.
@@ -119,7 +120,8 @@
   /// `options`. When `generator` parameter is omitted, new instance of
   /// `IncrementalKernelGenerator` is created by this method. Main use for this
   /// parameter is for mocking in tests.
-  Future<Null> compile(
+  /// Returns [true] if compilation was successful and produced no errors.
+  Future<bool> compile(
     String filename,
     ArgResults options, {
     IncrementalCompiler generator,
@@ -175,13 +177,15 @@
 
   final ProgramTransformer transformer;
 
+  final List<String> errors = new List<String>();
+
   void setMainSourceFilename(String filename) {
     final Uri filenameUri = _getFileOrUri(filename);
     _mainSource = filenameUri;
   }
 
   @override
-  Future<Null> compile(
+  Future<bool> compile(
     String filename,
     ArgResults options, {
     IncrementalCompiler generator,
@@ -204,7 +208,23 @@
       ..packagesFileUri = _getFileOrUri(_options['packages'])
       ..strongMode = options['strong']
       ..sdkSummary = sdkRoot.resolve(platformKernelDill)
-      ..reportMessages = true;
+      ..onProblem =
+          (message, Severity severity, String formatted, int line, int column) {
+        switch (severity) {
+          case Severity.error:
+          case Severity.errorLegacyWarning:
+          case Severity.internalProblem:
+            _outputStream.writeln(formatted);
+            errors.add(formatted);
+            break;
+          case Severity.nit:
+            break;
+          case Severity.warning:
+          case Severity.context:
+            _outputStream.writeln(formatted);
+            break;
+        }
+      };
     if (options.wasParsed('filesystem-root')) {
       List<Uri> rootUris = <Uri>[];
       for (String root in options['filesystem-root']) {
@@ -217,7 +237,7 @@
         print("When --filesystem-root is specified it is required to specify"
             " --output-dill option that points to physical file system location"
             " of a target dill file.");
-        exit(1);
+        return false;
       }
     }
 
@@ -265,7 +285,7 @@
       _kernelBinaryFilename = _kernelBinaryFilenameIncremental;
     } else
       _outputStream.writeln(boundaryKey);
-    return null;
+    return errors.isEmpty;
   }
 
   Future<Null> invalidateIfBootstrapping() async {
@@ -516,8 +536,10 @@
   );
 
   if (options.rest.isNotEmpty) {
-    await compiler.compile(options.rest[0], options, generator: generator);
-    return 0;
+    return await compiler.compile(options.rest[0], options,
+            generator: generator)
+        ? 0
+        : 254;
   }
 
   listenAndCompile(compiler, input ?? stdin, options, () {
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index aae78b5..84a8c4f 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -19,6 +19,8 @@
 
 import 'transformations/devirtualization.dart' as devirtualization
     show transformComponent;
+import 'transformations/mixin_deduplication.dart' as mixin_deduplication
+    show transformComponent;
 import 'transformations/no_dynamic_invocations_annotator.dart'
     as no_dynamic_invocations_annotator show transformComponent;
 import 'transformations/type_flow/transformer.dart' as globalTypeFlow
@@ -57,6 +59,14 @@
   if (strongMode) {
     final coreTypes = new CoreTypes(component);
 
+    // TODO(alexmarkov, dmitryas): Consider doing canonicalization of identical
+    // mixin applications when creating mixin applications in frontend,
+    // so all backends (and all transformation passes from the very beginning)
+    // can benefit from mixin de-duplication.
+    // At least, in addition to VM/AOT case we should run this transformation
+    // when building a platform dill file for VM/JIT case.
+    mixin_deduplication.transformComponent(component);
+
     if (useGlobalTypeFlowAnalysis) {
       globalTypeFlow.transformComponent(coreTypes, component, entryPoints);
     } else {
diff --git a/pkg/vm/lib/transformations/mixin_deduplication.dart b/pkg/vm/lib/transformations/mixin_deduplication.dart
new file mode 100644
index 0000000..2daf9a0
--- /dev/null
+++ b/pkg/vm/lib/transformations/mixin_deduplication.dart
@@ -0,0 +1,142 @@
+// 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.
+
+library vm.transformations.mixin_deduplication;
+
+import 'package:kernel/ast.dart';
+
+/// De-duplication of identical mixin applications.
+void transformComponent(Component component) {
+  final deduplicateMixins = new DeduplicateMixinsTransformer();
+  component.libraries.forEach(deduplicateMixins.visitLibrary);
+}
+
+class _DeduplicateMixinKey {
+  final Class _class;
+  _DeduplicateMixinKey(this._class);
+
+  @override
+  bool operator ==(Object other) {
+    if (other is _DeduplicateMixinKey) {
+      final thisClass = _class;
+      final otherClass = other._class;
+      if (identical(thisClass, otherClass)) {
+        return true;
+      }
+      // Do not deduplicate parameterized mixin applications.
+      if (thisClass.typeParameters.isNotEmpty ||
+          otherClass.typeParameters.isNotEmpty) {
+        return false;
+      }
+      // Deduplicate mixin applications with matching supertype, mixed-in type
+      // and implemented interfaces.
+      return thisClass.supertype == otherClass.supertype &&
+          thisClass.mixedInType == otherClass.mixedInType &&
+          listEquals(thisClass.implementedTypes, otherClass.implementedTypes);
+    }
+    return false;
+  }
+
+  @override
+  int get hashCode {
+    if (_class.typeParameters.isNotEmpty) {
+      return _class.hashCode;
+    }
+    int hash = 31;
+    hash = 0x3fffffff & (hash * 31 + _class.supertype.hashCode);
+    hash = 0x3fffffff & (hash * 31 + _class.mixedInType.hashCode);
+    for (var i in _class.implementedTypes) {
+      hash = 0x3fffffff & (hash * 31 + i.hashCode);
+    }
+    return hash;
+  }
+}
+
+class DeduplicateMixinsTransformer extends Transformer {
+  final _canonicalMixins = new Map<_DeduplicateMixinKey, Class>();
+  final _duplicatedMixins = new Map<Class, Class>();
+
+  @override
+  TreeNode visitLibrary(Library node) {
+    if (!node.isExternal) {
+      transformList(node.classes, this, node);
+    }
+    return node;
+  }
+
+  @override
+  TreeNode visitClass(Class c) {
+    if (c.enclosingLibrary.isExternal) {
+      return c;
+    }
+
+    if (_duplicatedMixins.containsKey(c)) {
+      return null; // Class was de-duplicated already, just remove it.
+    }
+
+    if (c.supertype != null) {
+      _transformSupertype(c);
+    }
+
+    if (!c.isSyntheticMixinImplementation) {
+      return c;
+    }
+
+    Class canonical =
+        _canonicalMixins.putIfAbsent(new _DeduplicateMixinKey(c), () => c);
+    assert(canonical != null);
+
+    if (canonical != c) {
+      c.canonicalName?.unbind();
+      _duplicatedMixins[c] = canonical;
+      // print('Replacing $c with $canonical');
+      return null; // Remove class.
+    }
+
+    return c;
+  }
+
+  void _transformSupertype(Class c) {
+    Class oldSuper = c.superclass;
+    if (oldSuper == null) {
+      return;
+    }
+    Class newSuper = visitClass(oldSuper);
+    if (newSuper == null) {
+      Class canonicalSuper = _duplicatedMixins[oldSuper];
+      assert(canonicalSuper != null);
+      c.supertype = new Supertype(canonicalSuper, c.supertype.typeArguments);
+      _correctForwardingConstructors(c, oldSuper, canonicalSuper);
+    }
+  }
+
+  @override
+  TreeNode defaultTreeNode(TreeNode node) =>
+      throw 'Unexpected node ${node.runtimeType}: $node';
+}
+
+/// Corrects synthetic forwarding constructors inserted by mixin resolution
+/// after replacing superclass.
+void _correctForwardingConstructors(Class c, Class oldSuper, Class newSuper) {
+  for (var constructor in c.constructors) {
+    if (constructor.isSynthetic) {
+      for (var initializer in constructor.initializers) {
+        if ((initializer is SuperInitializer) &&
+            initializer.target.enclosingClass == oldSuper) {
+          Constructor replacement = null;
+          for (var c in newSuper.constructors) {
+            if (c.name == initializer.target.name) {
+              replacement = c;
+              break;
+            }
+          }
+          if (replacement == null) {
+            throw 'Unable to find a replacement for $c in $newSuper';
+          }
+          initializer.target = replacement;
+        }
+      }
+    }
+  }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/analysis.dart b/pkg/vm/lib/transformations/type_flow/analysis.dart
index 13e0739..227ba12 100644
--- a/pkg/vm/lib/transformations/type_flow/analysis.dart
+++ b/pkg/vm/lib/transformations/type_flow/analysis.dart
@@ -1087,6 +1087,8 @@
     }
   }
 
+  bool isClassAllocated(Class c) => hierarchyCache.allocatedClasses.contains(c);
+
   Call callSite(TreeNode node) => summaryCollector.callSites[node];
 
   Type fieldType(Field field) => _fieldValues[field]?.value;
diff --git a/pkg/vm/lib/transformations/type_flow/entry_points_extra.json b/pkg/vm/lib/transformations/type_flow/entry_points_extra.json
index 892b058..4d4ce33 100644
--- a/pkg/vm/lib/transformations/type_flow/entry_points_extra.json
+++ b/pkg/vm/lib/transformations/type_flow/entry_points_extra.json
@@ -8,6 +8,18 @@
     },
     {
       "library": "dart:core",
+      "class": "Object",
+      "name": "_haveSameRuntimeType",
+      "action": "call"
+    },
+    {
+      "library": "dart:core",
+      "class": "Object",
+      "name": "_instanceOf",
+      "action": "call"
+    },
+    {
+      "library": "dart:core",
       "class": "List",
       "name": "_fromLiteral",
       "action": "call"
@@ -30,6 +42,12 @@
     },
     {
       "library": "dart:core",
+      "class": "_ImmutableMap",
+      "name": "_create",
+      "action": "call"
+    },
+    {
+      "library": "dart:core",
       "class": "_StringBase",
       "name": "_interpolate",
       "action": "call"
@@ -51,11 +69,6 @@
       "action": "call"
     },
     {
-      "library": "dart:_internal",
-      "name": "_classRangeCheck",
-      "action": "call"
-    },
-    {
       "library": "dart:core",
       "class": "_AssertionError",
       "name": "_evaluateAssertion",
@@ -68,6 +81,94 @@
       "action": "call"
     },
     {
+      "library": "dart:core",
+      "class": "_Closure",
+      "name": "_instantiator_type_arguments",
+      "action": "get"
+    },
+    {
+      "library": "dart:core",
+      "class": "_Closure",
+      "name": "_function_type_arguments",
+      "action": "get"
+    },
+    {
+      "library": "dart:core",
+      "class": "_Closure",
+      "name": "_function",
+      "action": "get"
+    },
+    {
+      "library": "dart:core",
+      "class": "_Closure",
+      "name": "_context",
+      "action": "get"
+    },
+    {
+      "library": "dart:core",
+      "class": "_Closure",
+      "name": "_hash",
+      "action": "get"
+    },
+    {
+      "library": "dart:core",
+      "class": "_CompileTimeError",
+      "action": "create-instance"
+    },
+    {
+      "library": "dart:core",
+      "class": "Object",
+      "name": "_simpleInstanceOf",
+      "action": "call"
+    },
+    {
+      "library": "dart:core",
+      "class": "Object",
+      "name": "_simpleInstanceOfTrue",
+      "action": "call"
+    },
+    {
+      "library": "dart:core",
+      "class": "Object",
+      "name": "_simpleInstanceOfFalse",
+      "action": "call"
+    },
+    {
+      "library": "dart:_internal",
+      "name": "_classRangeCheck",
+      "action": "call"
+    },
+    {
+      "library": "dart:_internal",
+      "name": "_prependTypeArguments",
+      "action": "call"
+    },
+    {
+      "library": "dart:async",
+      "name": "_setAsyncThreadStackTrace",
+      "action": "call"
+    },
+    {
+      "library": "dart:async",
+      "name": "_clearAsyncThreadStackTrace",
+      "action": "call"
+    },
+    {
+      "library": "dart:async",
+      "name": "_asyncStarMoveNextHelper",
+      "action": "call"
+    },
+    {
+      "library": "dart:async",
+      "name": "_completeOnAsyncReturn",
+      "action": "call"
+    },
+    {
+      "library": "dart:async",
+      "class": "_AsyncStarStreamController",
+      "action": "create-instance"
+    },
+    {
       "library": "dart:math",
       "class": "_Random",
       "name": "_A",
diff --git a/pkg/vm/lib/transformations/type_flow/native_code.dart b/pkg/vm/lib/transformations/type_flow/native_code.dart
index 4fa8d46..e01aed4 100644
--- a/pkg/vm/lib/transformations/type_flow/native_code.dart
+++ b/pkg/vm/lib/transformations/type_flow/native_code.dart
@@ -33,9 +33,13 @@
   final Map<String, List<Map<String, dynamic>>> _nativeMethods =
       <String, List<Map<String, dynamic>>>{};
   final LibraryIndex _libraryIndex;
+  final Set<Member> _membersReferencedFromNativeCode = new Set<Member>();
 
   NativeCodeOracle(this._libraryIndex);
 
+  bool isMemberReferencedFromNativeCode(Member member) =>
+      _membersReferencedFromNativeCode.contains(member);
+
   /// Simulate the execution of a native method by adding its entry points
   /// using [entryPointsListener]. Returns result type of the native method.
   Type handleNativeProcedure(
@@ -171,6 +175,8 @@
 
         entryPointsListener.addRawCall(selector);
       }
+
+      _membersReferencedFromNativeCode.add(member);
     } else {
       throw 'Bad entry point: unrecognized action "$action" in $rootDesc';
     }
diff --git a/pkg/vm/lib/transformations/type_flow/summary_collector.dart b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
index 493eaf2..276470b 100644
--- a/pkg/vm/lib/transformations/type_flow/summary_collector.dart
+++ b/pkg/vm/lib/transformations/type_flow/summary_collector.dart
@@ -959,9 +959,11 @@
 
   @override
   TypeExpr visitAssertStatement(AssertStatement node) {
-    _visit(node.condition);
-    if (node.message != null) {
-      _visit(node.message);
+    if (!kRemoveAsserts) {
+      _visit(node.condition);
+      if (node.message != null) {
+        _visit(node.message);
+      }
     }
     return null;
   }
@@ -974,7 +976,9 @@
 
   @override
   TypeExpr visitAssertBlock(AssertBlock node) {
-    node.statements.forEach(_visit);
+    if (!kRemoveAsserts) {
+      node.statements.forEach(_visit);
+    }
     return null;
   }
 
@@ -1146,7 +1150,9 @@
 
   @override
   visitAssertInitializer(AssertInitializer node) {
-    _visit(node.statement);
+    if (!kRemoveAsserts) {
+      _visit(node.statement);
+    }
   }
 
   @override
diff --git a/pkg/vm/lib/transformations/type_flow/transformer.dart b/pkg/vm/lib/transformations/type_flow/transformer.dart
index 52f1055..73e1194 100644
--- a/pkg/vm/lib/transformations/type_flow/transformer.dart
+++ b/pkg/vm/lib/transformations/type_flow/transformer.dart
@@ -67,7 +67,7 @@
 
   final transformsStopWatch = new Stopwatch()..start();
 
-  new DropMethodBodiesVisitor(typeFlowAnalysis).visitComponent(component);
+  new TreeShaker(component, typeFlowAnalysis).transformComponent(component);
 
   new TFADevirtualization(component, typeFlowAnalysis)
       .visitComponent(component);
@@ -107,32 +107,6 @@
   }
 }
 
-/// Drop method bodies using results of type flow analysis.
-class DropMethodBodiesVisitor extends RecursiveVisitor<Null> {
-  final TypeFlowAnalysis _typeFlowAnalysis;
-
-  DropMethodBodiesVisitor(this._typeFlowAnalysis);
-
-  @override
-  defaultMember(Member m) {
-    if (!m.isAbstract && !_typeFlowAnalysis.isMemberUsed(m)) {
-      if (m.function != null && m.function.body != null) {
-        m.function.body = new ExpressionStatement(
-            new Throw(new StringLiteral("TFA Error: $m")))
-          ..parent = m.function;
-        debugPrint("Dropped $m");
-      } else if ((m is Field) &&
-          (m.initializer != null) &&
-          (m.initializer is! NullLiteral)) {
-        m.isConst = false;
-        m.initializer = new Throw(new StringLiteral("TFA Error: $m"))
-          ..parent = m;
-        debugPrint("Dropped $m");
-      }
-    }
-  }
-}
-
 /// Annotates kernel AST with metadata using results of type flow analysis.
 class AnnotateKernel extends RecursiveVisitor<Null> {
   final TypeFlowAnalysis _typeFlowAnalysis;
@@ -298,3 +272,610 @@
     super.visitStaticGet(node);
   }
 }
+
+/// Tree shaking based on results of type flow analysis (TFA).
+///
+/// TFA provides information about allocated classes and reachable member
+/// bodies. However, it is not enough to perform tree shaking in one pass:
+/// we need to figure out which classes, members and typedefs are used
+/// in types, interface targets and annotations.
+///
+/// So, tree shaking is performed in 2 passes:
+///
+/// * Pass 1 visits declarations of classes and members, and dives deep into
+///   bodies of reachable members. It collects sets of used classes, members
+///   and typedefs. Also, while visiting bodies of reachable members, it
+///   transforms unreachable calls into 'throw' expressions.
+///
+/// * Pass 2 removes unused classes and members, and replaces bodies of
+///   used but unreachable members.
+///
+class TreeShaker {
+  final TypeFlowAnalysis typeFlowAnalysis;
+  final Set<Class> _usedClasses = new Set<Class>();
+  final Set<Class> _classesUsedInType = new Set<Class>();
+  final Set<Member> _usedMembers = new Set<Member>();
+  final Set<Typedef> _usedTypedefs = new Set<Typedef>();
+  _TreeShakerTypeVisitor typeVisitor;
+  _TreeShakerPass1 _pass1;
+  _TreeShakerPass2 _pass2;
+
+  TreeShaker(Component component, this.typeFlowAnalysis) {
+    typeVisitor = new _TreeShakerTypeVisitor(this);
+    _pass1 = new _TreeShakerPass1(this);
+    _pass2 = new _TreeShakerPass2(this);
+  }
+
+  transformComponent(Component component) {
+    _pass1.transform(component);
+    _pass2.transform(component);
+  }
+
+  bool isClassUsed(Class c) => _usedClasses.contains(c);
+  bool isClassUsedInType(Class c) => _classesUsedInType.contains(c);
+  bool isClassAllocated(Class c) => typeFlowAnalysis.isClassAllocated(c);
+  bool isMemberUsed(Member m) => _usedMembers.contains(m);
+  bool isMemberBodyReachable(Member m) => typeFlowAnalysis.isMemberUsed(m);
+  bool isMemberReferencedFromNativeCode(Member m) =>
+      typeFlowAnalysis.nativeCodeOracle.isMemberReferencedFromNativeCode(m);
+  bool isTypedefUsed(Typedef t) => _usedTypedefs.contains(t);
+
+  void addClassUsedInType(Class c) {
+    if (_classesUsedInType.add(c)) {
+      if (kPrintDebug) {
+        debugPrint('Class ${c.name} used in type');
+      }
+      _usedClasses.add(c);
+      visitIterable(c.supers, typeVisitor);
+      visitList(c.typeParameters, typeVisitor);
+      transformList(c.annotations, _pass1, c);
+      // Preserve NSM forwarders. They are overlooked by TFA / tree shaker
+      // as they are abstract and don't have a body.
+      for (Procedure p in c.procedures) {
+        if (p.isAbstract && p.isNoSuchMethodForwarder) {
+          addUsedMember(p);
+        }
+      }
+    }
+  }
+
+  void addUsedMember(Member m) {
+    if (_usedMembers.add(m)) {
+      final enclosingClass = m.enclosingClass;
+      if (enclosingClass != null) {
+        if (kPrintDebug) {
+          debugPrint('Member $m from class ${enclosingClass.name} is used');
+        }
+        _usedClasses.add(enclosingClass);
+      }
+
+      FunctionNode func = null;
+      if (m is Field) {
+        m.type.accept(typeVisitor);
+      } else if (m is Procedure) {
+        func = m.function;
+        if (m.forwardingStubSuperTarget != null) {
+          addUsedMember(m.forwardingStubSuperTarget);
+        }
+        if (m.forwardingStubInterfaceTarget != null) {
+          addUsedMember(m.forwardingStubInterfaceTarget);
+        }
+      } else if (m is Constructor) {
+        func = m.function;
+      } else {
+        throw 'Unexpected member ${m.runtimeType}: $m';
+      }
+
+      if (func != null) {
+        visitList(func.typeParameters, typeVisitor);
+        visitList(func.positionalParameters, typeVisitor);
+        visitList(func.namedParameters, typeVisitor);
+        func.returnType.accept(typeVisitor);
+      }
+
+      transformList(m.annotations, _pass1, m);
+    }
+  }
+
+  void addUsedTypedef(Typedef typedef) {
+    if (_usedTypedefs.add(typedef)) {
+      typedef.visitChildren(typeVisitor);
+    }
+  }
+}
+
+/// Visits Dart types and collects all classes and typedefs used in types.
+/// This visitor is used during pass 1 of tree shaking. It is a separate
+/// visitor because [Transformer] does not provide a way to traverse types.
+class _TreeShakerTypeVisitor extends RecursiveVisitor<Null> {
+  final TreeShaker shaker;
+
+  _TreeShakerTypeVisitor(this.shaker);
+
+  @override
+  visitInterfaceType(InterfaceType node) {
+    shaker.addClassUsedInType(node.classNode);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitSupertype(Supertype node) {
+    shaker.addClassUsedInType(node.classNode);
+    node.visitChildren(this);
+  }
+
+  @override
+  visitTypedefType(TypedefType node) {
+    shaker.addUsedTypedef(node.typedefNode);
+  }
+
+  @override
+  visitFunctionType(FunctionType node) {
+    node.visitChildren(this);
+    final typedef = node.typedef;
+    if (typedef != null) {
+      shaker.addUsedTypedef(typedef);
+    }
+  }
+}
+
+/// The first pass of [TreeShaker].
+/// Visits all classes, members and bodies of reachable members.
+/// Collects all used classes, members and types, and
+/// transforms unreachable calls into 'throw' expressions.
+class _TreeShakerPass1 extends Transformer {
+  final TreeShaker shaker;
+
+  _TreeShakerPass1(this.shaker);
+
+  void transform(Component component) {
+    component.transformChildren(this);
+  }
+
+  bool _isUnreachable(TreeNode node) {
+    final callSite = shaker.typeFlowAnalysis.callSite(node);
+    return (callSite != null) && !callSite.isReachable;
+  }
+
+  List<Expression> _flattenArguments(Arguments arguments,
+      {Expression receiver}) {
+    final args = <Expression>[];
+    if (receiver != null) {
+      args.add(receiver);
+    }
+    args.addAll(arguments.positional);
+    args.addAll(arguments.named.map((a) => a.value));
+    return args;
+  }
+
+  bool _isThrowExpression(Expression expr) {
+    while (expr is Let) {
+      expr = (expr as Let).body;
+    }
+    return expr is Throw;
+  }
+
+  TreeNode _makeUnreachableCall(List<Expression> args) {
+    TreeNode node;
+    final int last = args.indexWhere(_isThrowExpression);
+    if (last >= 0) {
+      // One of the arguments is a Throw expression.
+      // Ignore the rest of the arguments.
+      node = args[last];
+      args = args.sublist(0, last);
+      Statistics.throwExpressionsPruned++;
+    } else {
+      node = new Throw(new StringLiteral(
+          'Attempt to execute code removed by Dart AOT compiler (TFA)'));
+    }
+    for (var arg in args.reversed) {
+      node = new Let(new VariableDeclaration(null, initializer: arg), node);
+    }
+    Statistics.callsDropped++;
+    return node;
+  }
+
+  TreeNode _makeUnreachableInitializer(List<Expression> args) {
+    return new LocalInitializer(
+        new VariableDeclaration(null, initializer: _makeUnreachableCall(args)));
+  }
+
+  TreeNode _visitAssertNode(TreeNode node) {
+    if (kRemoveAsserts) {
+      return null;
+    } else {
+      node.transformChildren(this);
+      return node;
+    }
+  }
+
+  @override
+  DartType visitDartType(DartType node) {
+    node.accept(shaker.typeVisitor);
+    return node;
+  }
+
+  @override
+  Supertype visitSupertype(Supertype node) {
+    node.accept(shaker.typeVisitor);
+    return node;
+  }
+
+  @override
+  TreeNode visitTypedef(Typedef node) {
+    return node; // Do not go deeper.
+  }
+
+  @override
+  TreeNode visitClass(Class node) {
+    if (shaker.isClassAllocated(node)) {
+      shaker.addClassUsedInType(node);
+    }
+    transformList(node.constructors, this, node);
+    transformList(node.procedures, this, node);
+    transformList(node.fields, this, node);
+    transformList(node.redirectingFactoryConstructors, this, node);
+    return node;
+  }
+
+  @override
+  TreeNode defaultMember(Member node) {
+    if (shaker.isMemberBodyReachable(node)) {
+      if (kPrintTrace) {
+        tracePrint("Visiting $node");
+      }
+      shaker.addUsedMember(node);
+      node.transformChildren(this);
+    } else if (shaker.isMemberReferencedFromNativeCode(node)) {
+      // Preserve members referenced from native code to satisfy lookups, even
+      // if they are not reachable. An instance member could be added via
+      // native code entry point but still unreachable if no instances of
+      // its enclosing class are allocated.
+      shaker.addUsedMember(node);
+    }
+    return node;
+  }
+
+  @override
+  TreeNode visitMethodInvocation(MethodInvocation node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall(
+          _flattenArguments(node.arguments, receiver: node.receiver));
+    } else {
+      if (node.interfaceTarget != null) {
+        shaker.addUsedMember(node.interfaceTarget);
+      }
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitPropertyGet(PropertyGet node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall([node.receiver]);
+    } else {
+      if (node.interfaceTarget != null) {
+        shaker.addUsedMember(node.interfaceTarget);
+      }
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitPropertySet(PropertySet node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall([node.receiver, node.value]);
+    } else {
+      if (node.interfaceTarget != null) {
+        shaker.addUsedMember(node.interfaceTarget);
+      }
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitSuperMethodInvocation(SuperMethodInvocation node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall(_flattenArguments(node.arguments));
+    } else {
+      if (node.interfaceTarget != null) {
+        shaker.addUsedMember(node.interfaceTarget);
+      }
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitSuperPropertyGet(SuperPropertyGet node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall([]);
+    } else {
+      if (node.interfaceTarget != null) {
+        shaker.addUsedMember(node.interfaceTarget);
+      }
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitSuperPropertySet(SuperPropertySet node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall([node.value]);
+    } else {
+      if (node.interfaceTarget != null) {
+        shaker.addUsedMember(node.interfaceTarget);
+      }
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitStaticInvocation(StaticInvocation node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall(_flattenArguments(node.arguments));
+    } else {
+      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitStaticGet(StaticGet node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall([]);
+    } else {
+      if (!shaker.isMemberBodyReachable(node.target)) {
+        // Annotations could contain references to constant fields.
+        assertx((node.target is Field) && (node.target as Field).isConst);
+        shaker.addUsedMember(node.target);
+      }
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitStaticSet(StaticSet node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall([node.value]);
+    } else {
+      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitDirectMethodInvocation(DirectMethodInvocation node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall(
+          _flattenArguments(node.arguments, receiver: node.receiver));
+    } else {
+      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitDirectPropertyGet(DirectPropertyGet node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall([node.receiver]);
+    } else {
+      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitDirectPropertySet(DirectPropertySet node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall([node.receiver, node.value]);
+    } else {
+      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitConstructorInvocation(ConstructorInvocation node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableCall(_flattenArguments(node.arguments));
+    } else {
+      if (!shaker.isMemberBodyReachable(node.target)) {
+        // Annotations could contain references to const constructors.
+        assertx(node.isConst);
+        shaker.addUsedMember(node.target);
+      }
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitRedirectingInitializer(RedirectingInitializer node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableInitializer(_flattenArguments(node.arguments));
+    } else {
+      assertx(shaker.isMemberBodyReachable(node.target), details: node.target);
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitSuperInitializer(SuperInitializer node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableInitializer(_flattenArguments(node.arguments));
+    } else {
+      // Can't assert that node.target is used due to partial mixin resolution.
+      return node;
+    }
+  }
+
+  @override
+  visitFieldInitializer(FieldInitializer node) {
+    node.transformChildren(this);
+    if (_isUnreachable(node)) {
+      return _makeUnreachableInitializer([node.value]);
+    } else {
+      assertx(shaker.isMemberBodyReachable(node.field), details: node.field);
+      return node;
+    }
+  }
+
+  @override
+  TreeNode visitAssertStatement(AssertStatement node) {
+    return _visitAssertNode(node);
+  }
+
+  @override
+  TreeNode visitAssertBlock(AssertBlock node) {
+    return _visitAssertNode(node);
+  }
+
+  @override
+  TreeNode visitAssertInitializer(AssertInitializer node) {
+    return _visitAssertNode(node);
+  }
+}
+
+/// The second pass of [TreeShaker]. It is called after set of used
+/// classes, members and typedefs is determined during the first pass.
+/// This pass visits classes and members and removes unused classes and member.
+/// Bodies of unreachable but used members are replaced with 'throw'
+/// expressions. This pass does not dive deeper than member level.
+class _TreeShakerPass2 extends Transformer {
+  final TreeShaker shaker;
+
+  _TreeShakerPass2(this.shaker);
+
+  void transform(Component component) {
+    component.transformChildren(this);
+  }
+
+  @override
+  TreeNode visitLibrary(Library node) {
+    node.transformChildren(this);
+    // The transformer API does not iterate over `Library.additionalExports`,
+    // so we manually delete the references to shaken nodes.
+    node.additionalExports.removeWhere((Reference reference) {
+      final node = reference.node;
+      if (node is Class) {
+        return !shaker.isClassUsed(node);
+      } else if (node is Typedef) {
+        return !shaker.isTypedefUsed(node);
+      } else {
+        return !shaker.isMemberUsed(node as Member);
+      }
+    });
+    return node;
+  }
+
+  @override
+  Typedef visitTypedef(Typedef node) {
+    return shaker.isTypedefUsed(node) ? node : null;
+  }
+
+  @override
+  Class visitClass(Class node) {
+    if (!shaker.isClassUsed(node)) {
+      debugPrint('Dropped class ${node.name}');
+      node.canonicalName?.unbind();
+      Statistics.classesDropped++;
+      return null; // Remove the class.
+    }
+
+    if (!shaker.isClassUsedInType(node)) {
+      debugPrint('Dropped supers from class ${node.name}');
+      // The class is only a namespace for static members.  Remove its
+      // hierarchy information.   This is mandatory, since these references
+      // might otherwise become dangling.
+      node.supertype = shaker
+          .typeFlowAnalysis.environment.coreTypes.objectClass.asRawSupertype;
+      node.implementedTypes.clear();
+      node.typeParameters.clear();
+      node.isAbstract = true;
+      // Mixin applications cannot have static members.
+      assertx(node.mixedInType == null);
+      node.annotations = const <Expression>[];
+    }
+
+    if (!shaker.isClassAllocated(node)) {
+      debugPrint('Class ${node.name} converted to abstract');
+      node.isAbstract = true;
+    }
+
+    node.transformChildren(this);
+
+    return node;
+  }
+
+  /// Preserve instance fields of enums as VM relies on their existence.
+  bool _preserveSpecialMember(Member node) =>
+      node is Field &&
+      !node.isStatic &&
+      node.enclosingClass != null &&
+      node.enclosingClass.isEnum;
+
+  @override
+  Member defaultMember(Member node) {
+    if (!shaker.isMemberUsed(node) && !_preserveSpecialMember(node)) {
+      node.canonicalName?.unbind();
+      Statistics.membersDropped++;
+      return null;
+    }
+
+    if (!shaker.isMemberBodyReachable(node)) {
+      if (node is Procedure) {
+        // Remove body of unused member.
+        if (!node.isStatic && node.enclosingClass.isAbstract) {
+          node.isAbstract = true;
+          node.function.body = null;
+        } else {
+          // If the enclosing class is not abstract, the method should still
+          // have a body even if it can never be called.
+          _makeUnreachableBody(node.function);
+        }
+        node.function.asyncMarker = AsyncMarker.Sync;
+        node.forwardingStubSuperTargetReference = null;
+        node.forwardingStubInterfaceTargetReference = null;
+        Statistics.methodBodiesDropped++;
+      } else if (node is Field) {
+        node.initializer = null;
+        Statistics.fieldInitializersDropped++;
+      } else if (node is Constructor) {
+        _makeUnreachableBody(node.function);
+        node.initializers = const <Initializer>[];
+        Statistics.constructorBodiesDropped++;
+      } else {
+        throw 'Unexpected member ${node.runtimeType}: $node';
+      }
+    }
+
+    return node;
+  }
+
+  void _makeUnreachableBody(FunctionNode function) {
+    if (function.body != null) {
+      function.body = new ExpressionStatement(new Throw(new StringLiteral(
+          "Attempt to execute method removed by Dart AOT compiler (TFA)")))
+        ..parent = function;
+    }
+  }
+
+  @override
+  TreeNode defaultTreeNode(TreeNode node) {
+    return node; // Do not traverse into other nodes.
+  }
+}
diff --git a/pkg/vm/lib/transformations/type_flow/utils.dart b/pkg/vm/lib/transformations/type_flow/utils.dart
index 75dd3dc..95e4467 100644
--- a/pkg/vm/lib/transformations/type_flow/utils.dart
+++ b/pkg/vm/lib/transformations/type_flow/utils.dart
@@ -18,6 +18,9 @@
 const bool kPrintStats =
     const bool.fromEnvironment('global.type.flow.print.stats');
 
+const bool kRemoveAsserts =
+    const bool.fromEnvironment('global.type.flow.remove.asserts');
+
 /// Extended 'assert': always checks condition.
 assertx(bool cond, {details}) {
   if (!cond) {
@@ -74,6 +77,13 @@
   static int invocationsInvalidated = 0;
   static int recursiveInvocationsApproximated = 0;
   static int typeConeSpecializations = 0;
+  static int classesDropped = 0;
+  static int membersDropped = 0;
+  static int methodBodiesDropped = 0;
+  static int fieldInitializersDropped = 0;
+  static int constructorBodiesDropped = 0;
+  static int callsDropped = 0;
+  static int throwExpressionsPruned = 0;
 
   /// Resets statistic counters.
   static void reset() {
@@ -84,6 +94,14 @@
     usedCachedResultsOfInvocations = 0;
     invocationsInvalidated = 0;
     recursiveInvocationsApproximated = 0;
+    typeConeSpecializations = 0;
+    classesDropped = 0;
+    membersDropped = 0;
+    methodBodiesDropped = 0;
+    fieldInitializersDropped = 0;
+    constructorBodiesDropped = 0;
+    callsDropped = 0;
+    throwExpressionsPruned = 0;
   }
 
   static void print(String caption) {
@@ -96,6 +114,13 @@
     ${invocationsInvalidated} invocations invalidated
     ${recursiveInvocationsApproximated} recursive invocations approximated
     ${typeConeSpecializations} type cones specialized
+    ${classesDropped} classes dropped
+    ${membersDropped} members dropped
+    ${methodBodiesDropped} method bodies dropped
+    ${fieldInitializersDropped} field initializers dropped
+    ${constructorBodiesDropped} constructor bodies dropped
+    ${callsDropped} calls dropped
+    ${throwExpressionsPruned} throw expressions pruned
     """);
   }
 }
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index 3279881..7109a00 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -32,6 +32,7 @@
 
   group('batch compile with mocked compiler', () {
     final CompilerInterface compiler = new _MockedCompiler();
+    when(compiler.compile(any, any, generator: any)).thenReturn(true);
 
     test('compile from command line', () async {
       final List<String> args = <String>[
@@ -212,6 +213,7 @@
 
   group('interactive incremental compile with mocked compiler', () {
     final CompilerInterface compiler = new _MockedCompiler();
+    when(compiler.compile(any, any, generator: any)).thenReturn(true);
 
     final List<String> args = <String>[
       '--sdk-root',
@@ -405,6 +407,7 @@
 
     group('compile with output path', () {
       final CompilerInterface compiler = new _MockedCompiler();
+      when(compiler.compile(any, any, generator: any)).thenReturn(true);
 
       test('compile from command line', () async {
         final List<String> args = <String>[
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
index 87c7282..2513602 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/bench_vector.dart.expect
@@ -10,13 +10,10 @@
   constructor •([@vm.inferred-type.metadata=!] 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::•()
     ;
-[@vm.unreachable.metadata=]  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 []=([@vm.inferred-type.metadata=!] core::int i, core::double value) → void {
-    [@vm.unreachable.metadata=] [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements}.{core::List::[]=}([@vm.unreachable.metadata=] i.{core::num::+}([@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=!] this.{self::_Vector::_offset}), value);
+    let dynamic #t1 = [@vm.direct-call.metadata=#lib::_Vector::_elements] [@vm.inferred-type.metadata=dart.typed_data::_Float64List] this.{self::_Vector::_elements} in let dynamic #t2 = i in let dynamic #t3 = [@vm.direct-call.metadata=#lib::_Vector::_offset] [@vm.inferred-type.metadata=!] this.{self::_Vector::_offset} in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
   }
   operator *([@vm.inferred-type.metadata=#lib::_Vector?] self::_Vector a) → core::double {
     core::double result = 0.0;
@@ -28,7 +25,7 @@
 [@vm.inferred-type.metadata=#lib::_Vector?]static field self::_Vector v = new self::_Vector::•(10);
 [@vm.inferred-type.metadata=dart.core::_Double?]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;
+  core::Stopwatch timer = let final core::Stopwatch #t4 = new core::Stopwatch::•() in let final dynamic #t5 = [@vm.direct-call.metadata=dart.core::Stopwatch::start] #t4.{core::Stopwatch::start}() in #t4;
   for (core::int i = 0; 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));
   }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
index f86761e..f58857b 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/future_or.dart.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
-class A extends core::Object {
+abstract class A extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
index 9fa579c..740d76d 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_field_initializer.dart.expect
@@ -13,9 +13,6 @@
     ;
 }
 abstract class A extends core::Object {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::A::";
   abstract method foo() → core::Object;
 }
 class B extends core::Object implements self::A {
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
index d0b8b49..bee0c8e 100644
--- 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
@@ -7,11 +7,6 @@
     : super core::Object::•()
     ;
 }
-class T2 extends core::Object {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::T2::";
-}
 abstract class A extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
@@ -25,13 +20,6 @@
   method foo() → dynamic
     return new self::T1::•();
 }
-class C extends core::Object implements self::B {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::C::";
-[@vm.unreachable.metadata=]  method foo() → dynamic
-    throw "TFA Error: #lib::C::foo";
-}
 class Intermediate extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
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
index 977c750..2a40057 100644
--- 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
@@ -26,11 +26,8 @@
     return new self::T1::•();
 }
 abstract class C extends core::Object implements self::B {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::C::";
 }
-class D extends core::Object {
+abstract class D extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
index 0a02ddf..2d95c84 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/invalidation_while_processing.dart.expect
@@ -3,9 +3,6 @@
 import "dart:core" as core;
 
 abstract class I extends core::Object {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::I::";
   abstract method foo() → void;
 }
 class T1 extends core::Object implements self::I {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
index 9971701..aef2831 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/no_such_method.dart.expect
@@ -12,11 +12,6 @@
     : super core::Object::•()
     ;
 }
-class T3 extends core::Object {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::T3::";
-}
 class T4 extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
@@ -56,7 +51,7 @@
   abstract no-such-method-forwarder method foo() → dynamic;
   abstract no-such-method-forwarder method bazz(dynamic a1, dynamic a2, dynamic a3, [dynamic a4, dynamic a5]) → dynamic;
 }
-class C extends core::Object {
+abstract class C extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
@@ -76,8 +71,6 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-[@vm.unreachable.metadata=]  method foo() → dynamic
-    throw "TFA Error: #lib::E::foo";
   method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T4::•();
   }
@@ -88,8 +81,6 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-[@vm.unreachable.metadata=]  method twoArg(dynamic a1, dynamic a2) → dynamic
-    throw "TFA Error: #lib::F::twoArg";
   method noSuchMethod(core::Invocation invocation) → dynamic {
     return new self::T2::•();
   }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
index baf82e2..3ea010c 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/param_types_before_strong_mode_checks.dart.expect
@@ -8,13 +8,6 @@
     ;
   abstract method foo() → void;
 }
-class T1 extends self::T0 {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super self::T0::•()
-    throw "TFA Error: #lib::T1::";
-[@vm.unreachable.metadata=]  method foo() → void
-    throw "TFA Error: #lib::T1::foo";
-}
 class T2 extends self::T0 {
   synthetic constructor •() → void
     : super self::T0::•()
@@ -30,9 +23,6 @@
   }
 }
 abstract class B extends core::Object {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::B::";
   abstract method method2(covariant dynamic arg) → void;
 }
 class C extends core::Object implements self::B {
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
index 0f87c2a..3bbe8aa 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/tear_off_dynamic_method.dart.expect
@@ -6,7 +6,6 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract method foo() → core::int;
 }
 class B extends self::A {
   synthetic constructor •() → void
@@ -15,13 +14,6 @@
   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 {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::C::";
-[@vm.unreachable.metadata=]  method foo() → core::int
-    throw "TFA Error: #lib::C::foo";
-}
 class TearOffDynamicMethod extends core::Object {
   field dynamic bazz;
   constructor •(dynamic arg) → void
@@ -29,7 +21,6 @@
     this.{self::TearOffDynamicMethod::bazz}();
   }
 }
-[@vm.unreachable.metadata=]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 {
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
index cc9876d..fb289be 100644
--- 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
@@ -15,20 +15,12 @@
   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 {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::C::";
-[@vm.unreachable.metadata=]  method foo() → core::int
-    throw "TFA Error: #lib::C::foo";
-}
 class TearOffInterfaceMethod extends core::Object {
   field dynamic bazz;
   constructor •([@vm.inferred-type.metadata=#lib::B] self::A arg) → void
     : self::TearOffInterfaceMethod::bazz = arg.{self::A::foo}, super core::Object::•()
     ;
 }
-[@vm.unreachable.metadata=]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 {
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
index 24ea90c..2bb45cc 100644
--- 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
@@ -15,14 +15,7 @@
   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 {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::C::";
-[@vm.unreachable.metadata=]  method foo() → core::int
-    throw "TFA Error: #lib::C::foo";
-}
-class Base extends core::Object {
+abstract class Base extends core::Object {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
@@ -35,8 +28,6 @@
   synthetic constructor •() → void
     : super self::Base::•()
     ;
-[@vm.unreachable.metadata=]  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});
 }
diff --git a/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect b/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
index 8ff3030..393e004 100644
--- a/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
+++ b/pkg/vm/testcases/transformations/type_flow/transformer/unreachable.dart.expect
@@ -3,29 +3,18 @@
 import "dart:core" as core;
 
 abstract class I extends core::Object {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::I::";
-  abstract method foo(dynamic x) → void;
 }
-class A extends core::Object implements self::I {
-[@vm.unreachable.metadata=]  synthetic constructor •() → void
-    : super core::Object::•()
-    throw "TFA Error: #lib::A::";
-[@vm.unreachable.metadata=]  method foo(dynamic x) → void
-    throw "TFA Error: #lib::A::foo";
+abstract class A extends core::Object implements self::I {
 }
 class B extends core::Object implements self::I {
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-[@vm.unreachable.metadata=]  method foo(dynamic x) → void
-    throw "TFA Error: #lib::B::foo";
 }
 [@vm.inferred-type.metadata=#lib::B?]static field self::I ii = new self::B::•();
 static method bar([@vm.inferred-type.metadata=#lib::B?] self::I i) → void {
   if(i is self::A) {
-    [@vm.unreachable.metadata=] i{self::A}.{self::A::foo}(42);
+    let dynamic #t1 = i{self::A} in let dynamic #t2 = 42 in throw "Attempt to execute code removed by Dart AOT compiler (TFA)";
   }
 }
 static method main(core::List<core::String> args) → dynamic {
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index 823a47e..6fd1c76 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -81,6 +81,13 @@
   }
 }
 
+# We need to build gen_snapshot targeting Fuchsia during a build of the SDK
+# targeting Mac and Linux. This configuration is used to unconditionally target
+# Fuchsia. It should not be combined with dart_os_config.
+config("dart_os_fuchsia_config") {
+  defines = [ "TARGET_OS_FUCHSIA" ]
+}
+
 config("dart_arch_config") {
   defines = []
 
@@ -194,7 +201,6 @@
     configs += [
                  ":dart_arch_config",
                  ":dart_config",
-                 ":dart_os_config",
                ] + extra_configs
     if (is_fuchsia) {
       configs -= [ "//build/config:symbol_visibility_hidden" ]
@@ -221,7 +227,10 @@
 }
 
 libdart_library("libdart_jit") {
-  extra_configs = [ ":dart_maybe_product_config" ]
+  extra_configs = [
+    ":dart_maybe_product_config",
+    ":dart_os_config",
+  ]
   extra_deps = [
     "platform:libdart_platform",
     "vm:libdart_lib_jit",
@@ -230,7 +239,10 @@
 }
 
 libdart_library("libdart_jit_product") {
-  extra_configs = [ ":dart_product_config" ]
+  extra_configs = [
+    ":dart_product_config",
+    ":dart_os_config",
+  ]
   extra_deps = [
     "platform:libdart_platform_product",
     "vm:libdart_lib_jit_product",
@@ -242,6 +254,7 @@
   extra_configs = [
     ":dart_maybe_product_config",
     ":dart_precompiled_runtime_config",
+    ":dart_os_config",
   ]
   extra_deps = [
     "platform:libdart_platform",
@@ -254,6 +267,7 @@
   extra_configs = [
     ":dart_product_config",
     ":dart_precompiled_runtime_config",
+    ":dart_os_config",
   ]
   extra_deps = [
     "platform:libdart_platform_product",
@@ -267,6 +281,7 @@
     ":dart_maybe_product_config",
     ":dart_no_snapshot_config",
     ":dart_precompiler_config",
+    ":dart_os_config",
   ]
   extra_deps = [
     "platform:libdart_platform",
@@ -280,6 +295,7 @@
     ":dart_product_config",
     ":dart_no_snapshot_config",
     ":dart_precompiler_config",
+    ":dart_os_config",
   ]
   extra_deps = [
     "platform:libdart_platform_product",
@@ -288,10 +304,39 @@
   ]
 }
 
+libdart_library("libdart_nosnapshot_with_precompiler_fuchsia") {
+  extra_configs = [
+    ":dart_maybe_product_config",
+    ":dart_no_snapshot_config",
+    ":dart_precompiler_config",
+    ":dart_os_fuchsia_config",
+  ]
+  extra_deps = [
+    "platform:libdart_platform_fuchsia",
+    "vm:libdart_lib_nosnapshot_with_precompiler_fuchsia",
+    "vm:libdart_vm_nosnapshot_with_precompiler_fuchsia",
+  ]
+}
+
+libdart_library("libdart_nosnapshot_with_precompiler_product_fuchsia") {
+  extra_configs = [
+    ":dart_product_config",
+    ":dart_no_snapshot_config",
+    ":dart_precompiler_config",
+    ":dart_os_fuchsia_config",
+  ]
+  extra_deps = [
+    "platform:libdart_platform_product_fuchsia",
+    "vm:libdart_lib_nosnapshot_with_precompiler_product_fuchsia",
+    "vm:libdart_vm_nosnapshot_with_precompiler_product_fuchsia",
+  ]
+}
+
 libdart_library("libdart_with_precompiler") {
   extra_configs = [
     ":dart_maybe_product_config",
     ":dart_precompiler_config",
+    ":dart_os_config",
   ]
   extra_deps = [
     "platform:libdart_platform",
@@ -304,6 +349,7 @@
   extra_configs = [
     ":dart_product_config",
     ":dart_precompiler_config",
+    ":dart_os_config",
   ]
   extra_deps = [
     "platform:libdart_platform_product",
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 4442c92..4c8d954 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -247,7 +247,6 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
-                 "..:dart_os_config",
                ] + extra_configs
     if (is_fuchsia) {
       configs -= [ "//build/config:symbol_visibility_hidden" ]
@@ -293,11 +292,31 @@
 }
 
 build_libdart_builtin("libdart_builtin") {
-  extra_configs = [ "..:dart_maybe_product_config" ]
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_config",
+  ]
 }
 
 build_libdart_builtin("libdart_builtin_product") {
-  extra_configs = [ "..:dart_product_config" ]
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_config",
+  ]
+}
+
+build_libdart_builtin("libdart_builtin_fuchsia") {
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_fuchsia_config",
+  ]
+}
+
+build_libdart_builtin("libdart_builtin_product_fuchsia") {
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_fuchsia_config",
+  ]
 }
 
 template("build_gen_snapshot") {
@@ -313,7 +332,6 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
-                 "..:dart_os_config",
                  "..:dart_precompiler_config",
                ] + extra_configs
     if (is_fuchsia) {
@@ -391,7 +409,10 @@
 }
 
 build_gen_snapshot("gen_snapshot") {
-  extra_configs = [ "..:dart_maybe_product_config" ]
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_config",
+  ]
   extra_deps = [
     ":gen_snapshot_dart_io",
     ":libdart_builtin",
@@ -400,7 +421,10 @@
 }
 
 build_gen_snapshot("gen_snapshot_product") {
-  extra_configs = [ "..:dart_product_config" ]
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_config",
+  ]
   extra_deps = [
     ":gen_snapshot_dart_io_product",
     ":libdart_builtin_product",
@@ -408,6 +432,30 @@
   ]
 }
 
+build_gen_snapshot("gen_snapshot_fuchsia") {
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_fuchsia_config",
+  ]
+  extra_deps = [
+    ":gen_snapshot_dart_io_fuchsia",
+    ":libdart_builtin_fuchsia",
+    "..:libdart_nosnapshot_with_precompiler_fuchsia",
+  ]
+}
+
+build_gen_snapshot("gen_snapshot_product_fuchsia") {
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_fuchsia_config",
+  ]
+  extra_deps = [
+    ":gen_snapshot_dart_io_product_fuchsia",
+    ":libdart_builtin_product_fuchsia",
+    "..:libdart_nosnapshot_with_precompiler_product_fuchsia",
+  ]
+}
+
 # A source set for the implementation of 'dart:io' library
 # (without secure sockets) suitable for linking with gen_snapshot.
 template("build_gen_snapshot_dart_io") {
@@ -419,7 +467,6 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
-                 "..:dart_os_config",
                  "..:dart_precompiler_config",
                ] + extra_configs
     deps = []
@@ -466,11 +513,31 @@
 }
 
 build_gen_snapshot_dart_io("gen_snapshot_dart_io") {
-  extra_configs = [ "..:dart_maybe_product_config" ]
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_config",
+  ]
 }
 
 build_gen_snapshot_dart_io("gen_snapshot_dart_io_product") {
-  extra_configs = [ "..:dart_product_config" ]
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_config",
+  ]
+}
+
+build_gen_snapshot_dart_io("gen_snapshot_dart_io_fuchsia") {
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_fuchsia_config",
+  ]
+}
+
+build_gen_snapshot_dart_io("gen_snapshot_dart_io_product_fuchsia") {
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_fuchsia_config",
+  ]
 }
 
 # A source set for the implementation of 'dart:io' library.
@@ -1066,9 +1133,11 @@
       ":hello_fuchsia",
     ]
 
-    binaries = [ {
-          name = "hello_fuchsia.dart"
-        } ]
+    binaries = [
+      {
+        name = "hello_fuchsia.dart"
+      },
+    ]
   }
 }
 
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index 3d205b9..c60823d 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -10,10 +10,6 @@
 #include "bin/dartutils.h"
 #include "bin/platform.h"
 
-#include "vm/dart_api_impl.h"
-#include "vm/object.h"
-#include "vm/object_store.h"
-
 namespace dart {
 namespace bin {
 
diff --git a/runtime/bin/directory_test.cc b/runtime/bin/directory_test.cc
index 4a11eef..7173d1c 100644
--- a/runtime/bin/directory_test.cc
+++ b/runtime/bin/directory_test.cc
@@ -5,8 +5,6 @@
 #include "bin/directory.h"
 #include "include/dart_api.h"
 #include "platform/assert.h"
-#include "vm/isolate.h"
-#include "vm/thread.h"
 #include "vm/unit_test.h"
 
 namespace dart {
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index bf1737a..2a79347 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -63,10 +63,14 @@
 CB_OPTIONS_LIST(CB_OPTION_DEFINITION)
 #undef CB_OPTION_DEFINITION
 
+static bool checked_set = false;
+static bool preview_dart_2_set = false;
+
 static void SetPreviewDart2Options(CommandLineOptions* vm_options) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
   Options::dfe()->set_use_dfe();
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  preview_dart_2_set = true;
   vm_options->AddArgument("--strong");
   vm_options->AddArgument("--reify-generic-functions");
   vm_options->AddArgument("--limit-ints-to-64-bits");
@@ -125,7 +129,10 @@
     Log::PrintErr(
 "Common options:\n"
 "--checked or -c\n"
-"  Insert runtime type checks and enable assertions (checked mode).\n"
+"  Insert runtime type checks and enable assertions (checked mode, not\n"
+"  compatible with --preview-dart-2).\n"
+"--enable-asserts\n"
+"  Enable assert statements.\n"
 "--help or -h\n"
 "  Display this message (add -v or --verbose for information about\n"
 "  all VM options).\n"
@@ -156,7 +163,10 @@
     Log::PrintErr(
 "Supported options:\n"
 "--checked or -c\n"
-"  Insert runtime type checks and enable assertions (checked mode).\n"
+"  Insert runtime type checks and enable assertions (checked mode, not\n"
+"  compatible with --preview-dart-2).\n"
+"--enable-asserts\n"
+"  Enable assert statements.\n"
 "--help or -h\n"
 "  Display this message (add -v or --verbose for information about\n"
 "  all VM options).\n"
@@ -339,6 +349,7 @@
     } else {
       // Check if this flag is a potentially valid VM flag.
       const char* kChecked = "-c";
+      const char* kCheckedFull = "--checked";
       const char* kPackageRoot = "-p";
       if (strncmp(argv[i], kPackageRoot, strlen(kPackageRoot)) == 0) {
         // If argv[i] + strlen(kPackageRoot) is \0, then look in argv[i + 1]
@@ -356,8 +367,10 @@
         package_root_ = opt;
         i++;
         continue;  // '-p' is not a VM flag so don't add to vm options.
-      } else if (strncmp(argv[i], kChecked, strlen(kChecked)) == 0) {
-        vm_options->AddArgument("--checked");
+      } else if ((strncmp(argv[i], kChecked, strlen(kChecked)) == 0) ||
+                 (strncmp(argv[i], kCheckedFull, strlen(kCheckedFull)) == 0)) {
+        checked_set = true;
+        vm_options->AddArgument(kCheckedFull);
         i++;
         continue;  // '-c' is not a VM flag so don't add to vm options.
       } else if (!OptionProcessor::IsValidFlag(argv[i], kPrefix, kPrefixLen)) {
@@ -434,6 +447,10 @@
         " run using a snapshot is invalid.\n");
     return -1;
   }
+  if (checked_set && preview_dart_2_set) {
+    Log::PrintErr("Flags --checked and --preview-dart-2 are not compatible.\n");
+    return -1;
+  }
 
   // If --snapshot is given without --snapshot-kind, default to script snapshot.
   if ((snapshot_filename_ != NULL) && (gen_snapshot_kind_ == kNone)) {
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index 6471168..b14fb90 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -47,6 +47,17 @@
     return false;
   }
 
+  // tcsetattr raises SIGTTOU if we try to set console attributes when
+  // backgrounded, which suspends the process. Ignoring the signal prevents
+  // us from being suspended and lets us fail gracefully instead.
+  sigset_t signal_mask;
+  sigemptyset(&signal_mask);
+  sigaddset(&signal_mask, SIGTTOU);
+  if (sigprocmask(SIG_BLOCK, &signal_mask, NULL) < 0) {
+    perror("Setting signal handler failed");
+    return false;
+  }
+
   act.sa_flags = SA_SIGINFO;
   act.sa_sigaction = &segv_handler;
   if (sigemptyset(&act.sa_mask) != 0) {
diff --git a/runtime/bin/platform_linux.cc b/runtime/bin/platform_linux.cc
index afd8cac..9cd4f71 100644
--- a/runtime/bin/platform_linux.cc
+++ b/runtime/bin/platform_linux.cc
@@ -47,6 +47,17 @@
     return false;
   }
 
+  // tcsetattr raises SIGTTOU if we try to set console attributes when
+  // backgrounded, which suspends the process. Ignoring the signal prevents
+  // us from being suspended and lets us fail gracefully instead.
+  sigset_t signal_mask;
+  sigemptyset(&signal_mask);
+  sigaddset(&signal_mask, SIGTTOU);
+  if (sigprocmask(SIG_BLOCK, &signal_mask, NULL) < 0) {
+    perror("Setting signal handler failed");
+    return false;
+  }
+
   act.sa_flags = SA_SIGINFO;
   act.sa_sigaction = &segv_handler;
   if (sigemptyset(&act.sa_mask) != 0) {
diff --git a/runtime/bin/platform_macos.cc b/runtime/bin/platform_macos.cc
index 5c148b1..3dfe9e5 100644
--- a/runtime/bin/platform_macos.cc
+++ b/runtime/bin/platform_macos.cc
@@ -54,6 +54,18 @@
     perror("Setting signal handler failed");
     return false;
   }
+
+  // tcsetattr raises SIGTTOU if we try to set console attributes when
+  // backgrounded, which suspends the process. Ignoring the signal prevents
+  // us from being suspended and lets us fail gracefully instead.
+  sigset_t signal_mask;
+  sigemptyset(&signal_mask);
+  sigaddset(&signal_mask, SIGTTOU);
+  if (sigprocmask(SIG_BLOCK, &signal_mask, NULL) < 0) {
+    perror("Setting signal handler failed");
+    return false;
+  }
+
   act.sa_flags = SA_SIGINFO;
   act.sa_sigaction = &segv_handler;
   if (sigemptyset(&act.sa_mask) != 0) {
diff --git a/runtime/bin/reference_counting.h b/runtime/bin/reference_counting.h
index 1cc88f1..436f2ae 100644
--- a/runtime/bin/reference_counting.h
+++ b/runtime/bin/reference_counting.h
@@ -5,7 +5,7 @@
 #ifndef RUNTIME_BIN_REFERENCE_COUNTING_H_
 #define RUNTIME_BIN_REFERENCE_COUNTING_H_
 
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 
 namespace dart {
 namespace bin {
diff --git a/runtime/bin/socket_patch.dart b/runtime/bin/socket_patch.dart
index bf098c3..ac7dc37 100644
--- a/runtime/bin/socket_patch.dart
+++ b/runtime/bin/socket_patch.dart
@@ -1414,7 +1414,7 @@
 @patch
 class Socket {
   @patch
-  static Future<Socket> connect(host, int port,
+  static Future<Socket> _connect(host, int port,
       {sourceAddress, Duration timeout}) {
     return RawSocket
         .connect(host, port, sourceAddress: sourceAddress, timeout: timeout)
diff --git a/runtime/observatory/pubspec.yaml b/runtime/observatory/pubspec.yaml
index e405aac..4ed0d1f 100644
--- a/runtime/observatory/pubspec.yaml
+++ b/runtime/observatory/pubspec.yaml
@@ -1,6 +1,5 @@
 # Generated file DO NOT EDIT
 name: observatory
-version: 1.6.0-dev.1
 transformers:
 - dart_to_js_script_rewriter
 - $dart2js:
@@ -11,11 +10,8 @@
   charted: ^0.4.8
   unittest: < 0.12.0
   usage: ^1.2.0
-  web_components: ^0.12.5
   dart_to_js_script_rewriter: 1.0.3
 dependency_overrides:
-  analyzer:
-    path: ../../third_party/observatory_pub_packages/packages/analyzer
   args:
     path: ../../third_party/observatory_pub_packages/packages/args
   async:
@@ -28,32 +24,16 @@
     path: ../../third_party/observatory_pub_packages/packages/charcode
   charted:
     path: ../../third_party/observatory_pub_packages/packages/charted
-  cli_util:
-    path: ../../third_party/observatory_pub_packages/packages/cli_util
-  code_transformers:
-    path: ../../third_party/observatory_pub_packages/packages/code_transformers
   collection:
     path: ../../third_party/observatory_pub_packages/packages/collection
-  convert:
-    path: ../../third_party/observatory_pub_packages/packages/convert
-  crypto:
-    path: ../../third_party/observatory_pub_packages/packages/crypto
   csslib:
     path: ../../third_party/observatory_pub_packages/packages/csslib
-  dart_style:
-    path: ../../third_party/observatory_pub_packages/packages/dart_style
   dart_to_js_script_rewriter:
     path: ../../third_party/observatory_pub_packages/packages/dart_to_js_script_rewriter
-  glob:
-    path: ../../third_party/observatory_pub_packages/packages/glob
   html:
     path: ../../third_party/observatory_pub_packages/packages/html
-  initialize:
-    path: ../../third_party/observatory_pub_packages/packages/initialize
   intl:
     path: ../../third_party/observatory_pub_packages/packages/intl
-  isolate:
-    path: ../../third_party/observatory_pub_packages/packages/isolate
   logging:
     path: ../../third_party/observatory_pub_packages/packages/logging
   matcher:
@@ -62,35 +42,19 @@
     path: ../../third_party/observatory_pub_packages/packages/meta
   observable:
     path: ../../third_party/observatory_pub_packages/packages/observable
-  package_config:
-    path: ../../third_party/observatory_pub_packages/packages/package_config
   path:
     path: ../../third_party/observatory_pub_packages/packages/path
-  plugin:
-    path: ../../third_party/observatory_pub_packages/packages/plugin
   pool:
     path: ../../third_party/observatory_pub_packages/packages/pool
   quiver:
     path: ../../third_party/observatory_pub_packages/packages/quiver
-  source_maps:
-    path: ../../third_party/observatory_pub_packages/packages/source_maps
   source_span:
     path: ../../third_party/observatory_pub_packages/packages/source_span
   stack_trace:
     path: ../../third_party/observatory_pub_packages/packages/stack_trace
-  string_scanner:
-    path: ../../third_party/observatory_pub_packages/packages/string_scanner
-  typed_data:
-    path: ../../third_party/observatory_pub_packages/packages/typed_data
   unittest:
     path: ../../third_party/observatory_pub_packages/packages/unittest
   usage:
     path: ../../third_party/observatory_pub_packages/packages/usage
   utf:
     path: ../../third_party/observatory_pub_packages/packages/utf
-  watcher:
-    path: ../../third_party/observatory_pub_packages/packages/watcher
-  web_components:
-    path: ../../third_party/observatory_pub_packages/packages/web_components
-  yaml:
-    path: ../../third_party/observatory_pub_packages/packages/yaml
diff --git a/runtime/observatory/tests/service/get_flag_list_rpc_test.dart b/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
index c44b017..cdb35b5 100644
--- a/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_flag_list_rpc_test.dart
@@ -17,27 +17,35 @@
 
   // Modify a flag which does not exist.
   (VM vm) async {
-    // Modify a flag.
     var params = {
       'name': 'does_not_really_exist',
       'value': 'true',
     };
-    var result = await vm.invokeRpcNoUpgrade('_setFlag', params);
+    var result = await vm.invokeRpcNoUpgrade('setFlag', params);
     expect(result['type'], equals('Error'));
     expect(result['message'], equals('Cannot set flag: flag not found'));
   },
 
   // Modify a flag with the wrong value type.
   (VM vm) async {
-    // Modify a flag.
     var params = {
-      'name': 'trace_profiler',
-      'value': '123',
+      'name': 'pause_isolates_on_start',
+      'value': 'not-a-boolean',
     };
-    var result = await vm.invokeRpcNoUpgrade('_setFlag', params);
+    var result = await vm.invokeRpcNoUpgrade('setFlag', params);
     expect(result['type'], equals('Error'));
     expect(result['message'], equals('Cannot set flag: invalid value'));
   },
+
+  // Modify a flag with the right value type.
+  (VM vm) async {
+    var params = {
+      'name': 'pause_isolates_on_start',
+      'value': 'false',
+    };
+    var result = await vm.invokeRpcNoUpgrade('setFlag', params);
+    expect(result['type'], equals('Success'));
+  },
 ];
 
 main(args) async => runVMTests(args, tests);
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index c12b767..59485c1 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -13,7 +13,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(5));
+    expect(result['minor'], equals(7));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/pause_on_start_and_exit_with_child_test.dart b/runtime/observatory/tests/service/pause_on_start_and_exit_with_child_test.dart
new file mode 100644
index 0000000..e59ac17
--- /dev/null
+++ b/runtime/observatory/tests/service/pause_on_start_and_exit_with_child_test.dart
@@ -0,0 +1,113 @@
+// 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.
+// VMOptions=--error_on_bad_type --error_on_bad_override
+
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'test_helper.dart';
+import 'dart:async';
+import 'dart:isolate' as isolate;
+
+void child(message) {
+  print("Child got initial message");
+  message.send(null);
+}
+
+void testMain() {
+  var port = new isolate.RawReceivePort();
+  port.handler = (message) {
+    print("Parent got response");
+    port.close();
+  };
+
+  isolate.Isolate.spawn(child, port.sendPort);
+}
+
+var tests = <IsolateTest>[
+  (Isolate isolate) async {
+    VM vm = isolate.vm;
+
+    print('Getting stream...');
+    Completer completer = new Completer();
+    var stream = await vm.getEventStream(VM.kDebugStream);
+    print('Subscribing...');
+    var subscription;
+    subscription = stream.listen((ServiceEvent event) {
+      if (event.isolate == isolate && event.kind == ServiceEvent.kPauseStart) {
+        print('Received $event');
+        subscription.cancel();
+        completer.complete();
+      } else {
+        print('Ignoring event $event');
+      }
+    });
+    print('Subscribed.  Pause event is ${isolate.pauseEvent}');
+
+    if (isolate.pauseEvent != null && isolate.pauseEvent is M.PauseStartEvent) {
+      // Wait for the isolate to hit PauseStart.
+      subscription.cancel();
+      print('Subscription cancelled.');
+    } else {
+      print('Waiting for pause start event.');
+      await completer.future;
+    }
+    print('Done waiting for pause event.');
+
+    expect(isolate.pauseEvent, isNotNull);
+    expect(isolate.pauseEvent is M.PauseStartEvent, isTrue);
+
+    print("Disabling pause_isolates_on_start");
+    var params = {
+      'name': 'pause_isolates_on_start',
+      'value': 'false',
+    };
+    var result = await vm.invokeRpcNoUpgrade('setFlag', params);
+    expect(result['type'], equals('Success'));
+
+    print("Disabling pause_isolates_on_exit");
+    params = {
+      'name': 'pause_isolates_on_exit',
+      'value': 'false',
+    };
+    result = await vm.invokeRpcNoUpgrade('setFlag', params);
+    expect(result['type'], equals('Success'));
+
+    completer = new Completer();
+    stream = await vm.getEventStream(VM.kDebugStream);
+    subscription = stream.listen((ServiceEvent event) {
+      if (event.isolate == isolate && event.kind == ServiceEvent.kPauseExit) {
+        print('Received PauseExit');
+        subscription.cancel();
+        completer.complete();
+      }
+    });
+
+    print('Resuming at start...');
+    isolate.resume();
+
+    // Wait for the isolate to hit PauseExit.
+    await completer.future;
+
+    expect(isolate.pauseEvent, isNotNull);
+    expect(isolate.pauseEvent is M.PauseExitEvent, isTrue);
+
+    print('Resuming at exit...');
+    isolate.resume();
+
+    // Nothing else keeping the VM around. In particular, the child isolate
+    // won't pause on exit.
+    await vm.onDisconnect;
+  },
+];
+
+main(args) => runIsolateTests(args, tests,
+        testeeConcurrent: testMain,
+        pause_on_start: true,
+        pause_on_exit: true,
+        verbose_vm: true,
+        extraArgs: [
+          '--trace-service',
+          '--trace-service-verbose',
+        ]);
diff --git a/runtime/observatory/web/index.html b/runtime/observatory/web/index.html
index 391c95e..2662c85 100644
--- a/runtime/observatory/web/index.html
+++ b/runtime/observatory/web/index.html
@@ -6,8 +6,7 @@
   <link rel="stylesheet" href="packages/charted/charts/themes/quantum_theme.css">
   <link rel="stylesheet" href="packages/observatory/src/elements/css/shared.css">
   <script src="packages/web_components/webcomponents-lite.min.js"></script>
-  <script async type="application/dart" src="main.dart"></script>
-  <script async src="packages/browser/dart.js"></script>
+  <script defer src="main.dart.js"></script>
 </head>
 <body style="height: 100%">
 </body>
diff --git a/runtime/platform/BUILD.gn b/runtime/platform/BUILD.gn
index ae4e1df..32a9339 100644
--- a/runtime/platform/BUILD.gn
+++ b/runtime/platform/BUILD.gn
@@ -11,10 +11,9 @@
   }
   static_library(target_name) {
     configs += [
-      "..:dart_arch_config",
-      "..:dart_config",
-      "..:dart_os_config",
-    ] + extra_configs
+                 "..:dart_arch_config",
+                 "..:dart_config",
+               ] + extra_configs
     if (is_fuchsia) {
       configs -= [ "//build/config:symbol_visibility_hidden" ]
     }
@@ -27,9 +26,29 @@
 }
 
 build_libdart_platform("libdart_platform") {
-  extra_configs = [ "..:dart_maybe_product_config" ]
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_config",
+  ]
 }
 
 build_libdart_platform("libdart_platform_product") {
-  extra_configs = [ "..:dart_product_config" ]
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_config",
+  ]
+}
+
+build_libdart_platform("libdart_platform_fuchsia") {
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_fuchsia_config",
+  ]
+}
+
+build_libdart_platform("libdart_platform_product_fuchsia") {
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_fuchsia_config",
+  ]
 }
diff --git a/runtime/vm/atomic.h b/runtime/platform/atomic.h
similarity index 86%
rename from runtime/vm/atomic.h
rename to runtime/platform/atomic.h
index 1d18a2c..4a468e5 100644
--- a/runtime/vm/atomic.h
+++ b/runtime/platform/atomic.h
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#ifndef RUNTIME_VM_ATOMIC_H_
-#define RUNTIME_VM_ATOMIC_H_
+#ifndef RUNTIME_PLATFORM_ATOMIC_H_
+#define RUNTIME_PLATFORM_ATOMIC_H_
 
 #include "platform/globals.h"
 
-#include "vm/allocation.h"
+#include "platform/allocation.h"
 
 namespace dart {
 
@@ -55,17 +55,17 @@
 }  // namespace dart
 
 #if defined(HOST_OS_ANDROID)
-#include "vm/atomic_android.h"
+#include "platform/atomic_android.h"
 #elif defined(HOST_OS_FUCHSIA)
-#include "vm/atomic_fuchsia.h"
+#include "platform/atomic_fuchsia.h"
 #elif defined(HOST_OS_LINUX)
-#include "vm/atomic_linux.h"
+#include "platform/atomic_linux.h"
 #elif defined(HOST_OS_MACOS)
-#include "vm/atomic_macos.h"
+#include "platform/atomic_macos.h"
 #elif defined(HOST_OS_WINDOWS)
-#include "vm/atomic_win.h"
+#include "platform/atomic_win.h"
 #else
 #error Unknown target os.
 #endif
 
-#endif  // RUNTIME_VM_ATOMIC_H_
+#endif  // RUNTIME_PLATFORM_ATOMIC_H_
diff --git a/runtime/vm/atomic_android.h b/runtime/platform/atomic_android.h
similarity index 90%
rename from runtime/vm/atomic_android.h
rename to runtime/platform/atomic_android.h
index b5fb34d..8178d6e 100644
--- a/runtime/vm/atomic_android.h
+++ b/runtime/platform/atomic_android.h
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#ifndef RUNTIME_VM_ATOMIC_ANDROID_H_
-#define RUNTIME_VM_ATOMIC_ANDROID_H_
+#ifndef RUNTIME_PLATFORM_ATOMIC_ANDROID_H_
+#define RUNTIME_PLATFORM_ATOMIC_ANDROID_H_
 
-#if !defined RUNTIME_VM_ATOMIC_H_
+#if !defined RUNTIME_PLATFORM_ATOMIC_H_
 #error Do not include atomic_android.h directly. Use atomic.h instead.
 #endif
 
@@ -57,4 +57,4 @@
 
 }  // namespace dart
 
-#endif  // RUNTIME_VM_ATOMIC_ANDROID_H_
+#endif  // RUNTIME_PLATFORM_ATOMIC_ANDROID_H_
diff --git a/runtime/vm/atomic_fuchsia.h b/runtime/platform/atomic_fuchsia.h
similarity index 90%
rename from runtime/vm/atomic_fuchsia.h
rename to runtime/platform/atomic_fuchsia.h
index 2076487..5434fb7 100644
--- a/runtime/vm/atomic_fuchsia.h
+++ b/runtime/platform/atomic_fuchsia.h
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#ifndef RUNTIME_VM_ATOMIC_FUCHSIA_H_
-#define RUNTIME_VM_ATOMIC_FUCHSIA_H_
+#ifndef RUNTIME_PLATFORM_ATOMIC_FUCHSIA_H_
+#define RUNTIME_PLATFORM_ATOMIC_FUCHSIA_H_
 
-#if !defined RUNTIME_VM_ATOMIC_H_
+#if !defined RUNTIME_PLATFORM_ATOMIC_H_
 #error Do not include atomic_fuchsia.h directly. Use atomic.h instead.
 #endif
 
@@ -57,4 +57,4 @@
 
 }  // namespace dart
 
-#endif  // RUNTIME_VM_ATOMIC_FUCHSIA_H_
+#endif  // RUNTIME_PLATFORM_ATOMIC_FUCHSIA_H_
diff --git a/runtime/vm/atomic_linux.h b/runtime/platform/atomic_linux.h
similarity index 91%
rename from runtime/vm/atomic_linux.h
rename to runtime/platform/atomic_linux.h
index 722deed..627bc9f 100644
--- a/runtime/vm/atomic_linux.h
+++ b/runtime/platform/atomic_linux.h
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#ifndef RUNTIME_VM_ATOMIC_LINUX_H_
-#define RUNTIME_VM_ATOMIC_LINUX_H_
+#ifndef RUNTIME_PLATFORM_ATOMIC_LINUX_H_
+#define RUNTIME_PLATFORM_ATOMIC_LINUX_H_
 
-#if !defined RUNTIME_VM_ATOMIC_H_
+#if !defined RUNTIME_PLATFORM_ATOMIC_H_
 #error Do not include atomic_linux.h directly. Use atomic.h instead.
 #endif
 
@@ -57,4 +57,4 @@
 
 }  // namespace dart
 
-#endif  // RUNTIME_VM_ATOMIC_LINUX_H_
+#endif  // RUNTIME_PLATFORM_ATOMIC_LINUX_H_
diff --git a/runtime/vm/atomic_macos.h b/runtime/platform/atomic_macos.h
similarity index 91%
rename from runtime/vm/atomic_macos.h
rename to runtime/platform/atomic_macos.h
index b60dfed..e8c1545 100644
--- a/runtime/vm/atomic_macos.h
+++ b/runtime/platform/atomic_macos.h
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#ifndef RUNTIME_VM_ATOMIC_MACOS_H_
-#define RUNTIME_VM_ATOMIC_MACOS_H_
+#ifndef RUNTIME_PLATFORM_ATOMIC_MACOS_H_
+#define RUNTIME_PLATFORM_ATOMIC_MACOS_H_
 
-#if !defined RUNTIME_VM_ATOMIC_H_
+#if !defined RUNTIME_PLATFORM_ATOMIC_H_
 #error Do not include atomic_macos.h directly. Use atomic.h instead.
 #endif
 
@@ -57,4 +57,4 @@
 
 }  // namespace dart
 
-#endif  // RUNTIME_VM_ATOMIC_MACOS_H_
+#endif  // RUNTIME_PLATFORM_ATOMIC_MACOS_H_
diff --git a/runtime/vm/atomic_win.h b/runtime/platform/atomic_win.h
similarity index 96%
rename from runtime/vm/atomic_win.h
rename to runtime/platform/atomic_win.h
index 55e4756..f7fc322 100644
--- a/runtime/vm/atomic_win.h
+++ b/runtime/platform/atomic_win.h
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#ifndef RUNTIME_VM_ATOMIC_WIN_H_
-#define RUNTIME_VM_ATOMIC_WIN_H_
+#ifndef RUNTIME_PLATFORM_ATOMIC_WIN_H_
+#define RUNTIME_PLATFORM_ATOMIC_WIN_H_
 
-#if !defined RUNTIME_VM_ATOMIC_H_
+#if !defined RUNTIME_PLATFORM_ATOMIC_H_
 #error Do not include atomic_win.h directly. Use atomic.h instead.
 #endif
 
@@ -131,4 +131,4 @@
 
 }  // namespace dart
 
-#endif  // RUNTIME_VM_ATOMIC_WIN_H_
+#endif  // RUNTIME_PLATFORM_ATOMIC_WIN_H_
diff --git a/runtime/platform/platform_sources.gni b/runtime/platform/platform_sources.gni
index f61930c..cf85469 100644
--- a/runtime/platform/platform_sources.gni
+++ b/runtime/platform/platform_sources.gni
@@ -9,6 +9,12 @@
   "allocation.h",
   "assert.cc",
   "assert.h",
+  "atomic.h",
+  "atomic_android.h",
+  "atomic_fuchsia.h",
+  "atomic_linux.h",
+  "atomic_macos.h",
+  "atomic_win.h",
   "c99_support_win.h",
   "floating_point.h",
   "floating_point_win.cc",
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index aab86f8..80613e4 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -156,21 +156,11 @@
 cc/Service_TokenStream: Fail
 
 [ $compiler == dartk && $runtime == vm ]
-cc/CanonicalizationInScriptSnapshots: Fail
 cc/Class_ComputeEndTokenPos: Crash
 cc/DartAPI_InvokeNoSuchMethod: Fail
-cc/DartAPI_IsolateSetCheckedMode: Skip # Checked mode is not relevant for dart 2?
 cc/DartAPI_IsolateShutdownRunDartCode: Skip # Flaky
 cc/DartAPI_LazyLoadDeoptimizes: Fail
 cc/DartAPI_LoadLibrary: Crash
-cc/DartAPI_LoadLibraryPatch_Error1: Fail
-cc/DartAPI_LoadLibraryPatch_Error2: Fail
-cc/DartAPI_LoadLibraryPatch_Error3: Fail
-cc/DartAPI_LoadPatch: Crash
-cc/DartAPI_LoadPatchSignatureMismatch: Crash
-cc/DartAPI_LoadSource: Crash
-cc/DartAPI_LoadSource_LateLoad: Crash
-cc/DartAPI_ParsePatchLibrary: Crash
 cc/DebuggerAPI_BreakpointStubPatching: Fail
 cc/DebuggerAPI_GetClosureInfo: Fail
 cc/DebuggerAPI_InterruptIsolate: SkipSlow
@@ -181,7 +171,6 @@
 cc/Debugger_Rewind_Optimized: SkipSlow
 cc/Debugger_SetBreakpointInPartOfLibrary: Crash
 cc/FunctionSourceFingerprint: Fail # Issue 30756
-cc/GenerateSource: Skip # Cannot generate source from a kernel binary.
 cc/IsolateReload_NotTypedefToTypedef: Fail
 cc/IsolateReload_TypedefToNotTypedef: Fail
 cc/Profiler_BasicSourcePositionOptimized: Skip
@@ -189,21 +178,6 @@
 cc/Profiler_GetSourceReport: Fail
 cc/Profiler_SourcePositionOptimized: Fail
 cc/Profiler_SourcePositionOptimized: Skip
-cc/ScriptSnapshot: Crash
-cc/ScriptSnapshot2: Crash
-cc/SourcePosition_Async: Crash
-cc/SourcePosition_BitwiseOperations: Crash
-cc/SourcePosition_ForLoop: Crash
-cc/SourcePosition_If: Crash
-cc/SourcePosition_IfElse: Crash
-cc/SourcePosition_InstanceCalls: Crash
-cc/SourcePosition_InstanceFields: Crash
-cc/SourcePosition_LoadIndexed: Crash
-cc/SourcePosition_StoreIndexed: Crash
-cc/SourcePosition_Switch: Crash
-cc/SourcePosition_TryCatchFinally: Crash
-cc/SourcePosition_While: Crash
-cc/SourcePosition_WhileContinueBreak: Crash
 cc/SourceReport_CallSites_PolymorphicCall: Fail
 cc/SourceReport_CallSites_SimpleCall: Fail
 cc/SourceReport_Coverage_AllFunctions: Fail
@@ -335,14 +309,40 @@
 [ $compiler == dart2analyzer || $compiler == dart2js ]
 dart/data_uri*test: Skip # Data uri's not supported by dart2js or the analyzer.
 
-# Tests for VM parser aren't valid for Dart 2.
+# Tests that use functionality not supported in Dart 2.
 [ $compiler == dartk || $compiler == dartkp ]
-cc/Parser_AllocateVariables_CaptureLoopVar: SkipByDesign
+cc/CanonicalizationInScriptSnapshots: SkipByDesign # Script snapshots unsupported.
+cc/DartAPI_IsolateSetCheckedMode: SkipByDesign # Checked mode is not relevant for dart 2?
+cc/DartAPI_LoadLibraryPatch_Error1: SkipByDesign # Dart_LibraryLoadPatch unsupported.
+cc/DartAPI_LoadLibraryPatch_Error2: SkipByDesign
+cc/DartAPI_LoadLibraryPatch_Error3: SkipByDesign
+cc/DartAPI_LoadPatch: SkipByDesign
+cc/DartAPI_LoadPatchSignatureMismatch: SkipByDesign
+cc/DartAPI_LoadSource: SkipByDesign # Dart_LoadSource unsupported.
+cc/DartAPI_LoadSource_LateLoad: SkipByDesign
+cc/DartAPI_ParsePatchLibrary: SkipByDesign
+cc/GenerateSource: Skip # Cannot generate source from a kernel binary.
+cc/Parser_AllocateVariables_CaptureLoopVar: SkipByDesign # VM parser tests.
 cc/Parser_AllocateVariables_CapturedVar: SkipByDesign
 cc/Parser_AllocateVariables_Issue7681: SkipByDesign
 cc/Parser_AllocateVariables_MiddleChain: SkipByDesign
 cc/Parser_AllocateVariables_NestedCapturedVar: SkipByDesign
 cc/Parser_AllocateVariables_TwoChains: SkipByDesign
+cc/ScriptSnapshot: SkipByDesign # Script snapshots unsupported.
+cc/ScriptSnapshot2: SkipByDesign
+cc/SourcePosition_Async: SkipByDesign # VM parser tests (Issue 32704)
+cc/SourcePosition_BitwiseOperations: SkipByDesign
+cc/SourcePosition_ForLoop: SkipByDesign
+cc/SourcePosition_If: SkipByDesign
+cc/SourcePosition_IfElse: SkipByDesign
+cc/SourcePosition_InstanceCalls: SkipByDesign
+cc/SourcePosition_InstanceFields: SkipByDesign
+cc/SourcePosition_LoadIndexed: SkipByDesign
+cc/SourcePosition_StoreIndexed: SkipByDesign
+cc/SourcePosition_Switch: SkipByDesign
+cc/SourcePosition_TryCatchFinally: SkipByDesign
+cc/SourcePosition_While: SkipByDesign
+cc/SourcePosition_WhileContinueBreak: SkipByDesign
 
 [ $compiler == precompiler || $mode == product ]
 cc/CoreSnapshotSize: SkipByDesign # Imports dart:mirrors
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index dc0a5b0..5a14a55 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -64,7 +64,6 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
-                 "..:dart_os_config",
                ] + extra_configs
     if (is_fuchsia) {
       configs -= [ "//build/config:symbol_visibility_hidden" ]
@@ -72,7 +71,7 @@
         # 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",
+        "//garnet/public/lib/time_zone/fidl",
 
         # TODO(zra): When the platform-specific timeline code is moved out to
         # the embedder, this can go away.
@@ -91,17 +90,24 @@
 }
 
 build_libdart_vm("libdart_vm_jit") {
-  extra_configs = [ "..:dart_maybe_product_config" ]
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_os_config",
+  ]
 }
 
 build_libdart_vm("libdart_vm_jit_product") {
-  extra_configs = [ "..:dart_product_config" ]
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_os_config",
+  ]
 }
 
 build_libdart_vm("libdart_vm_precompiled_runtime") {
   extra_configs = [
     "..:dart_maybe_product_config",
     "..:dart_precompiled_runtime_config",
+    "..:dart_os_config",
   ]
 }
 
@@ -109,6 +115,7 @@
   extra_configs = [
     "..:dart_product_config",
     "..:dart_precompiled_runtime_config",
+    "..:dart_os_config",
   ]
 }
 
@@ -116,6 +123,7 @@
   extra_configs = [
     "..:dart_maybe_product_config",
     "..:dart_no_snapshot_config",
+    "..:dart_os_config",
   ]
 }
 
@@ -124,6 +132,7 @@
     "..:dart_maybe_product_config",
     "..:dart_precompiler_config",
     "..:dart_no_snapshot_config",
+    "..:dart_os_config",
   ]
 }
 
@@ -132,6 +141,25 @@
     "..:dart_product_config",
     "..:dart_precompiler_config",
     "..:dart_no_snapshot_config",
+    "..:dart_os_config",
+  ]
+}
+
+build_libdart_vm("libdart_vm_nosnapshot_with_precompiler_fuchsia") {
+  extra_configs = [
+    "..:dart_maybe_product_config",
+    "..:dart_precompiler_config",
+    "..:dart_no_snapshot_config",
+    "..:dart_os_fuchsia_config",
+  ]
+}
+
+build_libdart_vm("libdart_vm_nosnapshot_with_precompiler_product_fuchsia") {
+  extra_configs = [
+    "..:dart_product_config",
+    "..:dart_precompiler_config",
+    "..:dart_no_snapshot_config",
+    "..:dart_os_fuchsia_config",
   ]
 }
 
@@ -139,6 +167,7 @@
   extra_configs = [
     "..:dart_maybe_product_config",
     "..:dart_precompiler_config",
+    "..:dart_os_config",
   ]
 }
 
@@ -146,6 +175,7 @@
   extra_configs = [
     "..:dart_product_config",
     "..:dart_precompiler_config",
+    "..:dart_os_config",
   ]
 }
 
@@ -212,7 +242,6 @@
     configs += [
                  "..:dart_arch_config",
                  "..:dart_config",
-                 "..:dart_os_config",
                ] + extra_configs
     if (is_fuchsia) {
       configs -= [ "//build/config:symbol_visibility_hidden" ]
@@ -276,6 +305,7 @@
     extra_configs = [
       "..:dart_maybe_product_config",
       "..:dart_precompiler_config",
+      "..:dart_os_config",
     ]
     extra_deps = libdeps
     extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
@@ -285,6 +315,27 @@
     extra_configs = [
       "..:dart_product_config",
       "..:dart_precompiler_config",
+      "..:dart_os_config",
+    ]
+    extra_deps = libdeps
+    extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
+  }
+
+  build_libdart_lib("libdart_lib_nosnapshot_with_precompiler_fuchsia") {
+    extra_configs = [
+      "..:dart_maybe_product_config",
+      "..:dart_precompiler_config",
+      "..:dart_os_fuchsia_config",
+    ]
+    extra_deps = libdeps
+    extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
+  }
+
+  build_libdart_lib("libdart_lib_nosnapshot_with_precompiler_product_fuchsia") {
+    extra_configs = [
+      "..:dart_product_config",
+      "..:dart_precompiler_config",
+      "..:dart_os_fuchsia_config",
     ]
     extra_deps = libdeps
     extra_sources = all_libsources + [ "bootstrap.cc" ] + liboutputs
@@ -294,6 +345,7 @@
     extra_configs = [
       "..:dart_maybe_product_config",
       "..:dart_precompiler_config",
+      "..:dart_os_config",
     ]
     extra_deps = libdeps
     extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
@@ -303,18 +355,25 @@
     extra_configs = [
       "..:dart_product_config",
       "..:dart_precompiler_config",
+      "..:dart_os_config",
     ]
     extra_deps = libdeps
     extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
   }
 
   build_libdart_lib("libdart_lib_jit") {
-    extra_configs = [ "..:dart_maybe_product_config" ]
+    extra_configs = [
+      "..:dart_maybe_product_config",
+      "..:dart_os_config",
+    ]
     extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
   }
 
   build_libdart_lib("libdart_lib_jit_product") {
-    extra_configs = [ "..:dart_product_config" ]
+    extra_configs = [
+      "..:dart_product_config",
+      "..:dart_os_config",
+    ]
     extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
   }
 
@@ -322,6 +381,7 @@
     extra_configs = [
       "..:dart_maybe_product_config",
       "..:dart_precompiled_runtime_config",
+      "..:dart_os_config",
     ]
     extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
   }
@@ -330,6 +390,7 @@
     extra_configs = [
       "..:dart_product_config",
       "..:dart_precompiled_runtime_config",
+      "..:dart_os_config",
     ]
     extra_sources = all_libsources + [ "bootstrap_nocore.cc" ]
   }
diff --git a/runtime/vm/atomic_test.cc b/runtime/vm/atomic_test.cc
index 858ed35..c9afc97 100644
--- a/runtime/vm/atomic_test.cc
+++ b/runtime/vm/atomic_test.cc
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/globals.h"
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 8ba409b..e31ec60 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -2692,8 +2692,9 @@
   // Every class should have at least a constructor, unless it is a top level
   // class or a typedef class. The Kernel frontend does not create an implicit
   // constructor for abstract classes.
-  ASSERT(cls.IsTopLevel() || cls.IsTypedefClass() || cls.is_abstract() ||
-         (Array::Handle(cls.functions()).Length() > 0));
+  // Moreover, Dart 2 precompiler (TFA) can tree shake all members if unused.
+  ASSERT(FLAG_precompiled_mode || cls.IsTopLevel() || cls.IsTypedefClass() ||
+         cls.is_abstract() || (Array::Handle(cls.functions()).Length() > 0));
   // Resolve and finalize all member types.
   ResolveAndFinalizeMemberTypes(cls);
   // Run additional checks after all types are finalized.
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index eda3979..3ac1c40 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -4,7 +4,7 @@
 
 #include "vm/class_table.h"
 
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "vm/flags.h"
 #include "vm/freelist.h"
 #include "vm/growable_array.h"
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index d5c15cb..7eae60b 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -6,7 +6,7 @@
 #define RUNTIME_VM_CLASS_TABLE_H_
 
 #include "platform/assert.h"
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "vm/bitfield.h"
 #include "vm/globals.h"
 
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 0cac243..1b5ccc7 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -437,14 +437,15 @@
   // Call the runtime if the object is not bool::true or bool::false.
   ASSERT(locs->always_calls());
   Label done;
+  Isolate* isolate = Isolate::Current();
 
-  if (Isolate::Current()->type_checks()) {
+  if (isolate->type_checks() || isolate->strong()) {
     __ CompareObject(reg, Bool::True());
     __ b(&done, EQ);
     __ CompareObject(reg, Bool::False());
     __ b(&done, EQ);
   } else {
-    ASSERT(Isolate::Current()->asserts());
+    ASSERT(isolate->asserts());
     __ CompareObject(reg, Object::null_instance());
     __ b(&done, NE);
   }
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index bb7b194a..08cfa0b 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -435,14 +435,15 @@
   // Call the runtime if the object is not bool::true or bool::false.
   ASSERT(locs->always_calls());
   Label done;
+  Isolate* isolate = Isolate::Current();
 
-  if (Isolate::Current()->type_checks()) {
+  if (isolate->type_checks() || isolate->strong()) {
     __ CompareObject(reg, Bool::True());
     __ b(&done, EQ);
     __ CompareObject(reg, Bool::False());
     __ b(&done, EQ);
   } else {
-    ASSERT(Isolate::Current()->asserts());
+    ASSERT(isolate->asserts());
     __ CompareObject(reg, Object::null_instance());
     __ b(&done, NE);
   }
diff --git a/runtime/vm/compiler/backend/il_dbc.cc b/runtime/vm/compiler/backend/il_dbc.cc
index 9565d80..e9504a4 100644
--- a/runtime/vm/compiler/backend/il_dbc.cc
+++ b/runtime/vm/compiler/backend/il_dbc.cc
@@ -195,7 +195,8 @@
   if (compiler->is_optimizing()) {
     __ Push(locs()->in(0).reg());
   }
-  __ AssertBoolean(Isolate::Current()->type_checks() ? 1 : 0);
+  Isolate* isolate = Isolate::Current();
+  __ AssertBoolean((isolate->type_checks() || isolate->strong()) ? 1 : 0);
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id(),
                                  token_pos());
   compiler->RecordAfterCall(this, FlowGraphCompiler::kHasResult);
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index f8bd071..83661ab 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -310,14 +310,15 @@
   // Call the runtime if the object is not bool::true or bool::false.
   ASSERT(locs->always_calls());
   Label done;
+  Isolate* isolate = Isolate::Current();
 
-  if (Isolate::Current()->type_checks()) {
+  if (isolate->type_checks() || isolate->strong()) {
     __ CompareObject(reg, Bool::True());
     __ j(EQUAL, &done, Assembler::kNearJump);
     __ CompareObject(reg, Bool::False());
     __ j(EQUAL, &done, Assembler::kNearJump);
   } else {
-    ASSERT(Isolate::Current()->asserts());
+    ASSERT(isolate->asserts());
     __ CompareObject(reg, Object::null_instance());
     __ j(NOT_EQUAL, &done, Assembler::kNearJump);
   }
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 9e86173..9128f93 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -403,14 +403,15 @@
   // Call the runtime if the object is not bool::true or bool::false.
   ASSERT(locs->always_calls());
   Label done;
+  Isolate* isolate = Isolate::Current();
 
-  if (Isolate::Current()->type_checks()) {
+  if (isolate->type_checks() || isolate->strong()) {
     __ CompareObject(reg, Bool::True());
     __ j(EQUAL, &done, Assembler::kNearJump);
     __ CompareObject(reg, Bool::False());
     __ j(EQUAL, &done, Assembler::kNearJump);
   } else {
-    ASSERT(Isolate::Current()->asserts());
+    ASSERT(isolate->asserts());
     __ CompareObject(reg, Object::null_instance());
     __ j(NOT_EQUAL, &done, Assembler::kNearJump);
   }
diff --git a/runtime/vm/compiler/frontend/flow_graph_builder.cc b/runtime/vm/compiler/frontend/flow_graph_builder.cc
index 3c801f0..7ddfd0c 100644
--- a/runtime/vm/compiler/frontend/flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/flow_graph_builder.cc
@@ -945,7 +945,7 @@
 
 void TestGraphVisitor::ReturnValue(Value* value) {
   Isolate* isolate = Isolate::Current();
-  if (isolate->type_checks() || isolate->asserts()) {
+  if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
     value = Bind(new (Z) AssertBooleanInstr(condition_token_pos(), value,
                                             owner()->GetNextDeoptId()));
   }
@@ -1290,7 +1290,7 @@
     node->left()->Visit(&for_left);
     EffectGraphVisitor empty(owner());
     Isolate* isolate = Isolate::Current();
-    if (isolate->type_checks() || isolate->asserts()) {
+    if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
       ValueGraphVisitor for_right(owner());
       node->right()->Visit(&for_right);
       Value* right_value = for_right.value();
@@ -1354,7 +1354,7 @@
     node->right()->Visit(&for_right);
     Value* right_value = for_right.value();
     Isolate* isolate = Isolate::Current();
-    if (isolate->type_checks() || isolate->asserts()) {
+    if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
       right_value = for_right.Bind(new (Z) AssertBooleanInstr(
           node->right()->token_pos(), right_value, owner()->GetNextDeoptId()));
     }
@@ -1626,7 +1626,7 @@
         owner()->ic_data_array(), owner()->GetNextDeoptId());
     if (node->kind() == Token::kNE) {
       Isolate* isolate = Isolate::Current();
-      if (isolate->type_checks() || isolate->asserts()) {
+      if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
         Value* value = Bind(result);
         result = new (Z) AssertBooleanInstr(node->token_pos(), value,
                                             owner()->GetNextDeoptId());
@@ -1670,7 +1670,7 @@
     Append(for_value);
     Value* value = for_value.value();
     Isolate* isolate = Isolate::Current();
-    if (isolate->type_checks() || isolate->asserts()) {
+    if (isolate->strong() || isolate->type_checks() || isolate->asserts()) {
       value = Bind(new (Z) AssertBooleanInstr(
           node->operand()->token_pos(), value, owner()->GetNextDeoptId()));
     }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 4761c27..d39e205 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -80,6 +80,32 @@
   }
 }
 
+void TypeParameterHelper::ReadUntilExcluding(Field field) {
+  for (; next_read_ < field; ++next_read_) {
+    switch (next_read_) {
+      case kFlags:
+        flags_ = builder_->ReadFlags();
+        break;
+      case kAnnotations:
+        builder_->SkipListOfExpressions();  // read annotations.
+        break;
+      case kName:
+        name_index_ = builder_->ReadStringReference();  // read name index.
+        break;
+      case kBound:
+        builder_->SkipDartType();
+        break;
+      case kDefaultType:
+        if (builder_->ReadTag() == kSomething) {
+          builder_->SkipDartType();
+        }
+        break;
+      case kEnd:
+        return;
+    }
+  }
+}
+
 void VariableDeclarationHelper::ReadUntilExcluding(Field field) {
   if (field <= next_read_) return;
 
@@ -1189,10 +1215,14 @@
   intptr_t list_length =
       builder_->ReadListLength();  // read type_parameters list length.
   for (intptr_t i = 0; i < list_length; ++i) {
-    builder_->ReadFlags();              // read flags.
-    builder_->SkipListOfExpressions();  // read annotations.
-    builder_->SkipStringReference();    // read ith name index.
+    TypeParameterHelper helper(builder_);
+    helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
     VisitDartType();                    // read ith bound.
+    helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kDefaultType);
+    if (builder_->ReadTag() == kSomething) {
+      VisitDartType();  // read ith default type.
+    }
+    helper.Finish();
   }
   function_node_helper.SetJustRead(FunctionNodeHelper::kTypeParameters);
 
@@ -1977,10 +2007,15 @@
     intptr_t list_length =
         builder_->ReadListLength();  // read type_parameters list length.
     for (int i = 0; i < list_length; ++i) {
-      builder_->SkipFlags();              // read flags.
-      builder_->SkipListOfExpressions();  // read annotations.
-      builder_->SkipStringReference();    // read string index (name).
-      VisitDartType();                    // read dart type.
+      TypeParameterHelper helper(builder_);
+      helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
+      VisitDartType();  // read bound.
+      helper.ReadUntilExcludingAndSetJustRead(
+          TypeParameterHelper::kDefaultType);
+      if (builder_->ReadTag() == kSomething) {
+        VisitDartType();  // read default type.
+      }
+      helper.Finish();
     }
     builder_->ReadUInt();  // read required parameter count.
     builder_->ReadUInt();  // read total parameter count.
@@ -4569,10 +4604,11 @@
     }
     TypeParameter& forwarding_param = TypeParameter::Handle(Z);
     for (intptr_t i = 0; i < num_type_params; ++i) {
-      ReadFlags();                                         // skip flags
-      SkipListOfExpressions();                             // skip annotations
-      String& name = H.DartSymbolObfuscate(ReadStringReference());  // read name
+      TypeParameterHelper helper(this);
+      helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
+      String& name = H.DartSymbolObfuscate(helper.name_index_);
       AbstractType& bound = T.BuildType();                 // read bound
+      helper.Finish();
 
       if (forwarding_target != NULL) {
         forwarding_param ^= forwarding_params.TypeAt(i);
@@ -5488,10 +5524,8 @@
 void StreamingFlowGraphBuilder::SkipTypeParametersList() {
   intptr_t list_length = ReadListLength();  // read list length.
   for (intptr_t i = 0; i < list_length; ++i) {
-    SkipFlags();              // read ith flags.
-    SkipListOfExpressions();  // read annotations.
-    SkipStringReference();    // read ith name index.
-    SkipDartType();           // read ith bound.
+    TypeParameterHelper helper(this);
+    helper.Finish();
   }
 }
 
@@ -6457,8 +6491,8 @@
   return flow_graph_builder_->BuildImplicitClosureCreation(target);
 }
 
-Fragment StreamingFlowGraphBuilder::CheckBooleanInCheckedMode() {
-  return flow_graph_builder_->CheckBooleanInCheckedMode();
+Fragment StreamingFlowGraphBuilder::CheckBoolean() {
+  return flow_graph_builder_->CheckBoolean();
 }
 
 Fragment StreamingFlowGraphBuilder::CheckAssignableInCheckedMode(
@@ -6517,7 +6551,7 @@
     SkipBytes(1);  // Skip Not tag, thus go directly to the inner expression.
   }
   Fragment instructions = BuildExpression();  // read expression.
-  instructions += CheckBooleanInCheckedMode();
+  instructions += CheckBoolean();
   return instructions;
 }
 
@@ -7752,7 +7786,7 @@
   if (position != NULL) *position = TokenPosition::kNoSource;
 
   Fragment instructions = BuildExpression();  // read expression.
-  instructions += CheckBooleanInCheckedMode();
+  instructions += CheckBoolean();
   instructions += BooleanNegate();
   return instructions;
 }
@@ -8536,7 +8570,7 @@
   instructions += BuildExpression();  // read condition.
   instructions += PushArgument();
   instructions += EvaluateAssertion();
-  instructions += CheckBooleanInCheckedMode();
+  instructions += CheckBoolean();
   instructions += Constant(Bool::True());
   instructions += BranchIfEqual(&then, &otherwise, false);
 
@@ -9603,15 +9637,14 @@
   {
     AlternativeReadingScope alt(reader_);
     for (intptr_t i = 0; i < type_parameter_count; i++) {
-      SkipFlags();
-      SkipListOfExpressions();  // read annotations.
+      TypeParameterHelper helper(this);
+      helper.Finish();
       parameter = TypeParameter::New(
           set_on_class ? *active_class->klass : Class::Handle(Z),
           parameterized_function, i,
-          H.DartSymbolObfuscate(ReadStringReference()),  // read ith name index.
+          H.DartSymbolObfuscate(helper.name_index_),  // read ith name index.
           null_bound, TokenPosition::kNoSource);
       type_parameters.SetTypeAt(i, parameter);
-      SkipDartType();  // read guard.
     }
   }
 
@@ -9629,9 +9662,8 @@
 
   // Step b) Fill in the bounds of all [TypeParameter]s.
   for (intptr_t i = 0; i < type_parameter_count; i++) {
-    SkipFlags();
-    SkipListOfExpressions();  // read annotations.
-    SkipStringReference();    // read ith name index.
+    TypeParameterHelper helper(this);
+    helper.ReadUntilExcludingAndSetJustRead(TypeParameterHelper::kBound);
 
     // TODO(github.com/dart-lang/kernel/issues/42): This should be handled
     // by the frontend.
@@ -9648,6 +9680,8 @@
       }
       parameter.set_bound(bound);
     }
+
+    helper.Finish();
   }
 }
 
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 0a16a94..e9b3b57 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -76,11 +76,51 @@
   intptr_t next_read_;
 };
 
-struct TypeParameterHelper {
+class TypeParameterHelper {
+ public:
+  enum Field {
+    kStart,  // tag.
+    kFlags,
+    kAnnotations,
+    kName,
+    kBound,
+    kDefaultType,
+    kEnd,
+  };
+
   enum Flag {
     kIsGenericCovariantImpl = 1 << 0,
     kIsGenericCovariantInterface = 1 << 1
   };
+
+  explicit TypeParameterHelper(StreamingFlowGraphBuilder* builder) {
+    builder_ = builder;
+    next_read_ = kStart;
+  }
+
+  void ReadUntilIncluding(Field field) {
+    ReadUntilExcluding(static_cast<Field>(static_cast<int>(field) + 1));
+  }
+
+  void ReadUntilExcluding(Field field);
+
+  void SetNext(Field field) { next_read_ = field; }
+  void SetJustRead(Field field) { next_read_ = field + 1; }
+
+  void ReadUntilExcludingAndSetJustRead(Field field) {
+    ReadUntilExcluding(field);
+    SetJustRead(field);
+  }
+
+  void Finish() { ReadUntilExcluding(kEnd); }
+
+  TokenPosition position_;
+  uint8_t flags_;
+  StringIndex name_index_;
+
+ private:
+  StreamingFlowGraphBuilder* builder_;
+  intptr_t next_read_;
 };
 
 // Helper class that reads a kernel VariableDeclaration from binary.
@@ -1276,7 +1316,7 @@
   JoinEntryInstr* BuildJoinEntry(intptr_t try_index);
   Fragment Goto(JoinEntryInstr* destination);
   Fragment BuildImplicitClosureCreation(const Function& target);
-  Fragment CheckBooleanInCheckedMode();
+  Fragment CheckBoolean();
   Fragment CheckAssignableInCheckedMode(const AbstractType& dst_type,
                                         const String& dst_name);
   Fragment CheckArgumentType(LocalVariable* variable, const AbstractType& type);
@@ -1434,6 +1474,7 @@
   friend class StreamingDartTypeTranslator;
   friend class StreamingScopeBuilder;
   friend class VariableDeclarationHelper;
+  friend class TypeParameterHelper;
 };
 
 class AlternativeScriptScope {
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 0372fa1..35ec95c 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -2223,9 +2223,9 @@
                     ICData::kStatic);
 }
 
-Fragment FlowGraphBuilder::CheckBooleanInCheckedMode() {
+Fragment FlowGraphBuilder::CheckBoolean() {
   Fragment instructions;
-  if (I->type_checks()) {
+  if (I->strong() || I->type_checks() || I->asserts()) {
     LocalVariable* top_of_stack = MakeTemporary();
     instructions += LoadLocal(top_of_stack);
     instructions += AssertBool();
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index efb5e13..2dca058 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -783,7 +783,7 @@
   Fragment EvaluateAssertion();
   Fragment CheckVariableTypeInCheckedMode(const AbstractType& dst_type,
                                           const String& name_symbol);
-  Fragment CheckBooleanInCheckedMode();
+  Fragment CheckBoolean();
   Fragment CheckAssignable(const AbstractType& dst_type,
                            const String& dst_name);
 
diff --git a/runtime/vm/compiler/intrinsifier.cc b/runtime/vm/compiler/intrinsifier.cc
index a74987c..654d33c 100644
--- a/runtime/vm/compiler/intrinsifier.cc
+++ b/runtime/vm/compiler/intrinsifier.cc
@@ -71,30 +71,34 @@
   Error& error = Error::Handle(zone);
 
 #define SETUP_FUNCTION(class_name, function_name, destination, type, fp)       \
+  func = Function::null();                                                     \
   if (strcmp(#class_name, "::") == 0) {                                        \
     str = String::New(#function_name);                                         \
     func = lib.LookupFunctionAllowPrivate(str);                                \
   } else {                                                                     \
     str = String::New(#class_name);                                            \
     cls = lib.LookupClassAllowPrivate(str);                                    \
-    ASSERT(!cls.IsNull());                                                     \
-    error = cls.EnsureIsFinalized(thread);                                     \
-    if (!error.IsNull()) {                                                     \
-      OS::PrintErr("%s\n", error.ToErrorCString());                            \
+    ASSERT(FLAG_precompiled_mode || !cls.IsNull());                            \
+    if (!cls.IsNull()) {                                                       \
+      error = cls.EnsureIsFinalized(thread);                                   \
+      if (!error.IsNull()) {                                                   \
+        OS::PrintErr("%s\n", error.ToErrorCString());                          \
+      }                                                                        \
+      ASSERT(error.IsNull());                                                  \
+      if (#function_name[0] == '.') {                                          \
+        str = String::New(#class_name #function_name);                         \
+      } else {                                                                 \
+        str = String::New(#function_name);                                     \
+      }                                                                        \
+      func = cls.LookupFunctionAllowPrivate(str);                              \
     }                                                                          \
-    ASSERT(error.IsNull());                                                    \
-    if (#function_name[0] == '.') {                                            \
-      str = String::New(#class_name #function_name);                           \
-    } else {                                                                   \
-      str = String::New(#function_name);                                       \
-    }                                                                          \
-    func = cls.LookupFunctionAllowPrivate(str);                                \
   }                                                                            \
-  if (func.IsNull()) {                                                         \
+  if (!func.IsNull()) {                                                        \
+    func.set_is_intrinsic(true);                                               \
+  } else if (!FLAG_precompiled_mode) {                                         \
     FATAL2("Intrinsifier failed to find method %s in class %s\n",              \
            #function_name, #class_name);                                       \
-  }                                                                            \
-  func.set_is_intrinsic(true);
+  }
 
   // Set up all core lib functions that can be intrinsified.
   lib = Library::CoreLibrary();
diff --git a/runtime/vm/compiler/method_recognizer.cc b/runtime/vm/compiler/method_recognizer.cc
index d8d86ce..7505d2d 100644
--- a/runtime/vm/compiler/method_recognizer.cc
+++ b/runtime/vm/compiler/method_recognizer.cc
@@ -136,23 +136,25 @@
 
 #define SET_RECOGNIZED_KIND(class_name, function_name, enum_name, type, fp)    \
   func = Library::GetFunction(libs, #class_name, #function_name);              \
-  if (func.IsNull()) {                                                         \
+  if (!func.IsNull()) {                                                        \
+    CHECK_FINGERPRINT3(func, class_name, function_name, enum_name, fp);        \
+    func.set_recognized_kind(k##enum_name);                                    \
+  } else if (!FLAG_precompiled_mode) {                                         \
     OS::PrintErr("Missing %s::%s\n", #class_name, #function_name);             \
     UNREACHABLE();                                                             \
-  }                                                                            \
-  CHECK_FINGERPRINT3(func, class_name, function_name, enum_name, fp);          \
-  func.set_recognized_kind(k##enum_name);
+  }
 
   RECOGNIZED_LIST(SET_RECOGNIZED_KIND);
 
 #define SET_FUNCTION_BIT(class_name, function_name, dest, fp, setter, value)   \
   func = Library::GetFunction(libs, #class_name, #function_name);              \
-  if (func.IsNull()) {                                                         \
+  if (!func.IsNull()) {                                                        \
+    CHECK_FINGERPRINT3(func, class_name, function_name, dest, fp);             \
+    func.setter(value);                                                        \
+  } else if (!FLAG_precompiled_mode) {                                         \
     OS::PrintErr("Missing %s::%s\n", #class_name, #function_name);             \
     UNREACHABLE();                                                             \
-  }                                                                            \
-  CHECK_FINGERPRINT3(func, class_name, function_name, dest, fp);               \
-  func.setter(value);
+  }
 
 #define SET_IS_ALWAYS_INLINE(class_name, function_name, dest, fp)              \
   SET_FUNCTION_BIT(class_name, function_name, dest, fp, set_always_inline, true)
diff --git a/runtime/vm/compiler_stats.h b/runtime/vm/compiler_stats.h
index 1ab7041..412cb61 100644
--- a/runtime/vm/compiler_stats.h
+++ b/runtime/vm/compiler_stats.h
@@ -5,8 +5,8 @@
 #ifndef RUNTIME_VM_COMPILER_STATS_H_
 #define RUNTIME_VM_COMPILER_STATS_H_
 
+#include "platform/atomic.h"
 #include "vm/allocation.h"
-#include "vm/atomic.h"
 #include "vm/flags.h"
 #include "vm/isolate.h"
 #include "vm/timer.h"
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 5c508f0..85adc30 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -2807,16 +2807,6 @@
   }
 }
 
-RawError* Debugger::OneTimeBreakAtEntry(const Function& target_function) {
-  LongJumpScope jump;
-  if (setjmp(*jump.Set()) == 0) {
-    SetBreakpointAtEntry(target_function, true);
-    return Error::null();
-  } else {
-    return Thread::Current()->sticky_error();
-  }
-}
-
 Breakpoint* Debugger::SetBreakpointAtEntry(const Function& target_function,
                                            bool single_shot) {
   ASSERT(!target_function.IsNull());
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 6c344b0..b88d742 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -489,7 +489,6 @@
   Breakpoint* SetBreakpointAtLineCol(const String& script_url,
                                      intptr_t line_number,
                                      intptr_t column_number);
-  RawError* OneTimeBreakAtEntry(const Function& target_function);
 
   BreakpointLocation* BreakpointLocationAtLineCol(const String& script_url,
                                                   intptr_t line_number,
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index 08c2c06..ff62dbf 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -50,8 +50,6 @@
     "Run optimizing compilation in background")                                \
   R(background_compilation_stop_alot, false, bool, false,                      \
     "Stress test system: stop background compiler often.")                     \
-  R(break_at_isolate_spawn, false, bool, false,                                \
-    "Insert a one-time breakpoint at the entrypoint for all spawned isolates") \
   P(causal_async_stacks, bool, !USING_PRODUCT, "Improved async stacks")        \
   P(collect_code, bool, true, "Attempt to GC infrequently used code.")         \
   P(collect_dynamic_function_names, bool, true,                                \
diff --git a/runtime/vm/handles_impl.h b/runtime/vm/handles_impl.h
index 7cfb01c..e5b731c 100644
--- a/runtime/vm/handles_impl.h
+++ b/runtime/vm/handles_impl.h
@@ -156,7 +156,11 @@
                  CountScopedHandles());
   }
   if (scoped_blocks_->next_block() == NULL) {
-    scoped_blocks_->set_next_block(new HandlesBlock(NULL));
+    HandlesBlock* block = new HandlesBlock(NULL);
+    if (block == NULL) {
+      OUT_OF_MEMORY();
+    }
+    scoped_blocks_->set_next_block(block);
   }
   scoped_blocks_ = scoped_blocks_->next_block();
   scoped_blocks_->set_next_handle_slot(0);
@@ -203,7 +207,9 @@
                  CountScopedHandles());
   }
   zone_blocks_ = new HandlesBlock(zone_blocks_);
-  ASSERT(zone_blocks_ != NULL);
+  if (zone_blocks_ == NULL) {
+    OUT_OF_MEMORY();
+  }
 }
 
 #if defined(DEBUG)
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 3a6edba..1c45698 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -7,8 +7,8 @@
 #include "include/dart_api.h"
 #include "include/dart_native_api.h"
 #include "platform/assert.h"
+#include "platform/atomic.h"
 #include "platform/text_buffer.h"
-#include "vm/atomic.h"
 #include "vm/class_finalizer.h"
 #include "vm/code_observers.h"
 #include "vm/compiler/jit/compiler.h"
@@ -1536,18 +1536,6 @@
     Function& func = Function::Handle(thread->zone());
     func ^= result.raw();
 
-    // TODO(turnidge): Currently we need a way to force a one-time
-    // breakpoint for all spawned isolates to support isolate
-    // debugging.  Remove this once the vmservice becomes the standard
-    // way to debug. Set the breakpoint on the static function instead
-    // of its implicit closure function because that latter is merely
-    // a dispatcher that is marked as undebuggable.
-#if !defined(PRODUCT)
-    if (FLAG_break_at_isolate_spawn) {
-      isolate->debugger()->OneTimeBreakAtEntry(func);
-    }
-#endif
-
     func = func.ImplicitClosureFunction();
 
     const Array& capabilities = Array::Handle(Array::New(2));
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 2794d13..b3a69f1 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -7,7 +7,7 @@
 
 #include "include/dart_api.h"
 #include "platform/assert.h"
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "vm/base_isolate.h"
 #include "vm/class_table.h"
 #include "vm/exceptions.h"
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ed5d21c..d971e45 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3550,8 +3550,13 @@
       return Symbols::List().raw();
 #endif  // !defined(PRODUCT)
   }
-  const String& name = String::Handle(Name());
-  return String::ScrubName(name);
+  String& name = String::Handle(Name());
+  name = String::ScrubName(name);
+  if (name.raw() == Symbols::FutureImpl().raw() &&
+      library() == Library::AsyncLibrary()) {
+    return Symbols::Future().raw();
+  }
+  return name.raw();
 }
 
 void Class::set_script(const Script& value) const {
@@ -4778,7 +4783,6 @@
                                         NameVisibility name_visibility) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
-  ASSERT(from_index + len <= Length());
   String& name = String::Handle(zone);
   const intptr_t num_strings =
       (len == 0) ? 2 : 2 * len + 1;  // "<""T"", ""T"">".
@@ -4786,8 +4790,14 @@
   pieces.Add(Symbols::LAngleBracket());
   AbstractType& type = AbstractType::Handle(zone);
   for (intptr_t i = 0; i < len; i++) {
-    type = TypeAt(from_index + i);
-    name = type.BuildName(name_visibility);
+    if (from_index + i < Length()) {
+      type = TypeAt(from_index + i);
+      name = type.BuildName(name_visibility);
+    } else {
+      // Show dynamic type argument in strong mode.
+      ASSERT(thread->isolate()->strong());
+      name = Symbols::Dynamic().raw();
+    }
     pieces.Add(name);
     if (i < len - 1) {
       pieces.Add(Symbols::CommaSpace());
@@ -16529,8 +16539,10 @@
         num_type_params = num_args;
       } else {
         ASSERT(num_args == 0);  // Type is raw.
-        // No need to fill up with "dynamic".
-        num_type_params = 0;
+        // No need to fill up with "dynamic", unless running in strong mode.
+        if (!thread->isolate()->strong()) {
+          num_type_params = 0;
+        }
       }
     } else {
       // The actual type argument vector can be longer than necessary, because
@@ -16549,7 +16561,8 @@
   GrowableHandlePtrArray<const String> pieces(zone, 4);
   pieces.Add(class_name);
   if ((num_type_params == 0) ||
-      args.IsRaw(first_type_param_index, num_type_params)) {
+      (!thread->isolate()->strong() &&
+       args.IsRaw(first_type_param_index, num_type_params))) {
     // Do nothing.
   } else {
     const String& args_name = String::Handle(
@@ -16802,6 +16815,7 @@
     return false;  // TODO(regis): We should return "maybe after instantiation".
   }
   const Class& type_cls = Class::Handle(zone, type_class());
+  const Class& other_type_cls = Class::Handle(zone, other.type_class());
   // Function types cannot be handled by Class::TypeTest().
   const bool other_is_dart_function_type = other.IsDartFunctionType();
   if (other_is_dart_function_type || other.IsFunctionType()) {
@@ -16818,18 +16832,7 @@
                           space);
     }
     // In strong mode, subtyping rules of callable instances are restricted.
-    if (isolate->strong()) {
-      // [this] is not a function type.
-      // If [other] is a function type, then [this] can't be a subtype of
-      // [other], according to Dart 2 subtyping rules.
-      // This check is needed to avoid falling through to class-based type
-      // tests, which yield incorrect result if [this] = _Closure class,
-      // and [other] is a function type, because class of a function type is
-      // also _Closure.
-      if (other.IsFunctionType()) {
-        return false;
-      }
-    } else {
+    if (!isolate->strong()) {
       // Check if type S has a call() method of function type T.
       const Function& call_function =
           Function::Handle(zone, type_cls.LookupCallFunctionForTypeTest());
@@ -16850,6 +16853,19 @@
         }
       }
     }
+    if (other.IsFunctionType() && !other_type_cls.IsTypedefClass()) {
+      // [this] is not a function type (and, in non-strong mode, does not
+      // declare a compatible call() method as verified above). Therefore,
+      // non-function type [this] cannot be a subtype of function type [other],
+      // unless [other] is not only a function type, but also a named typedef.
+      // Indeed a typedef also behaves as a regular class-based type (with type
+      // arguments when generic).
+      // This check is needed to avoid falling through to class-based type
+      // tests, which yield incorrect result if [this] = _Closure class,
+      // and [other] is a function type, because class of a function type is
+      // also _Closure (unless [other] is a typedef).
+      return false;
+    }
   }
   if (IsFunctionType()) {
     // In strong mode, check if 'other' is 'FutureOr'.
@@ -16861,7 +16877,7 @@
     return false;
   }
   return type_cls.TypeTest(test_kind, TypeArguments::Handle(zone, arguments()),
-                           Class::Handle(zone, other.type_class()),
+                           other_type_cls,
                            TypeArguments::Handle(zone, other.arguments()),
                            bound_error, bound_trail, space);
 }
@@ -22532,7 +22548,7 @@
   const Function& func = Function::Handle(zone, function());
   uint32_t result = 0;
   if (func.IsImplicitInstanceClosureFunction()) {
-    // Implicit instance closures are not unqiue, so combine function's hash
+    // Implicit instance closures are not unique, so combine function's hash
     // code with identityHashCode of cached receiver.
     result = static_cast<uint32_t>(func.ComputeClosureHash());
     const Context& context = Context::Handle(zone, this->context());
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index 0e4e6c4..bd21b78 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -14,14 +14,13 @@
 #include <zircon/syscalls/object.h>
 #include <zircon/types.h>
 
+#include <fuchsia/cpp/time_zone.h>
+
 #include "lib/app/cpp/environment_services.h"
-#include "lib/time_service/fidl/time_service.fidl.h"
 
 #include "platform/assert.h"
 #include "vm/zone.h"
 
-static constexpr char kTimeServiceName[] = "time_service::TimeService";
-
 namespace dart {
 
 #ifndef PRODUCT
@@ -42,17 +41,18 @@
 }
 
 static zx_status_t GetTimeServicePtr(
-    time_service::TimeServiceSyncPtr* time_svc) {
+    time_zone::TimezoneSyncPtr* time_svc) {
   zx::channel service_root = app::subtle::CreateStaticServiceRootHandle();
-  zx::channel time_svc_channel = GetSynchronousProxy(time_svc).TakeChannel();
-  return fdio_service_connect_at(service_root.get(), kTimeServiceName,
+  zx::channel time_svc_channel = time_svc->NewRequest().TakeChannel();
+  return fdio_service_connect_at(service_root.get(),
+                                 time_zone::Timezone::Name_,
                                  time_svc_channel.release());
 }
 
 static zx_status_t GetLocalAndDstOffsetInSeconds(int64_t seconds_since_epoch,
                                                  int32_t* local_offset,
                                                  int32_t* dst_offset) {
-  time_service::TimeServiceSyncPtr time_svc;
+  time_zone::TimezoneSyncPtr time_svc;
   zx_status_t status = GetTimeServicePtr(&time_svc);
   if (status == ZX_OK) {
     time_svc->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000, local_offset,
@@ -64,9 +64,9 @@
 }
 
 const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
-  time_service::TimeServiceSyncPtr time_svc;
+  time_zone::TimezoneSyncPtr time_svc;
   if (GetTimeServicePtr(&time_svc) == ZX_OK) {
-    f1dl::String res;
+    fidl::StringPtr res;
     time_svc->GetTimezoneId(&res);
     char* tz_name = Thread::Current()->zone()->Alloc<char>(res->size() + 1);
     memmove(tz_name, res->data(), res->size());
diff --git a/runtime/vm/os_thread.cc b/runtime/vm/os_thread.cc
index e2ca88b..6aa8ab9 100644
--- a/runtime/vm/os_thread.cc
+++ b/runtime/vm/os_thread.cc
@@ -4,7 +4,7 @@
 
 #include "vm/os_thread.h"
 
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "vm/lockers.h"
 #include "vm/log.h"
 #include "vm/thread_interrupter.h"
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 5e691ac..cf7b0b4 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -6,8 +6,8 @@
 #include "platform/memory_sanitizer.h"
 #include "platform/utils.h"
 
+#include "platform/atomic.h"
 #include "vm/allocation.h"
-#include "vm/atomic.h"
 #include "vm/code_patcher.h"
 #include "vm/debugger.h"
 #include "vm/instructions.h"
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 420ed6c..a987790 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -6,7 +6,7 @@
 #define RUNTIME_VM_RAW_OBJECT_H_
 
 #include "platform/assert.h"
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "vm/exceptions.h"
 #include "vm/globals.h"
 #include "vm/snapshot.h"
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 3e9e015..5056ab6 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -4049,6 +4049,37 @@
     PrintMissingParamError(js, "value");
     return true;
   }
+
+  if (Flags::Lookup(flag_name) == NULL) {
+    JSONObject jsobj(js);
+    jsobj.AddProperty("type", "Error");
+    jsobj.AddProperty("message", "Cannot set flag: flag not found");
+    return true;
+  }
+
+  // Changing most flags at runtime is dangerous because e.g., it may leave the
+  // behavior generated code and the runtime out of sync.
+  const char* kAllowedFlags[] = {
+      "pause_isolates_on_start",
+      "pause_isolates_on_exit",
+      "pause_isolates_on_unhandled_exceptions",
+  };
+
+  bool allowed = false;
+  for (size_t i = 0; i < ARRAY_SIZE(kAllowedFlags); i++) {
+    if (strcmp(flag_name, kAllowedFlags[i]) == 0) {
+      allowed = true;
+      break;
+    }
+  }
+
+  if (!allowed) {
+    JSONObject jsobj(js);
+    jsobj.AddProperty("type", "Error");
+    jsobj.AddProperty("message", "Cannot set flag: cannot change at runtime");
+    return true;
+  }
+
   const char* error = NULL;
   if (Flags::SetFlag(flag_name, flag_value, &error)) {
     PrintSuccess(js);
@@ -4330,7 +4361,7 @@
     request_heap_snapshot_params },
   { "setExceptionPauseMode", SetExceptionPauseMode,
     set_exception_pause_mode_params },
-  { "_setFlag", SetFlag,
+  { "setFlag", SetFlag,
     set_flags_params },
   { "setLibraryDebuggable", SetLibraryDebuggable,
     set_library_debuggable_params },
diff --git a/runtime/vm/service.h b/runtime/vm/service.h
index b6704cb..cb81061 100644
--- a/runtime/vm/service.h
+++ b/runtime/vm/service.h
@@ -15,7 +15,7 @@
 namespace dart {
 
 #define SERVICE_PROTOCOL_MAJOR_VERSION 3
-#define SERVICE_PROTOCOL_MINOR_VERSION 5
+#define SERVICE_PROTOCOL_MINOR_VERSION 7
 
 class Array;
 class EmbedderServiceHandler;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index db2b21f..d756a0f 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.5
+# Dart VM Service Protocol 3.7
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.5_ of the Dart VM Service Protocol. This
+This document describes of _version 3.7_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -41,6 +41,7 @@
 	- [removeBreakpoint](#removebreakpoint)
 	- [resume](#resume)
 	- [setExceptionPauseMode](#setexceptionpausemode)
+	- [setFlag](#setflag)
 	- [setLibraryDebuggable](#setlibrarydebuggable)
 	- [setName](#setname)
 	- [setVMName](#setvmname)
@@ -469,7 +470,8 @@
 ```
 @Instance|@Error|Sentinel evaluate(string isolateId,
                                    string targetId,
-                                   string expression)
+                                   string expression,
+                                   map<string,string> scope [optional])
 ```
 
 The _evaluate_ RPC is used to evaluate an expression in the context of
@@ -485,6 +487,12 @@
 garbage collector, then the _Collected_ [Sentinel](#sentinel) is
 returned.
 
+If _scope_ is provided, it should be a map from identifiers to object ids.
+These bindings will be added to the scope in which the expression is evaluated,
+which is a child scope of the class or library for instance/class or library
+targets respectively. This means bindings provided in _scope_ may shadow
+instance members, class members and top-level members.
+
 If an error occurs while evaluating the expression, an [@Error](#error)
 reference will be returned.
 
@@ -496,7 +504,8 @@
 ```
 @Instance|@Error|Sentinel evaluateInFrame(string isolateId,
                                           int frameIndex,
-                                          string expression)
+                                          string expression,
+                                          map<string,string> scope [optional])
 ```
 
 The _evaluateInFrame_ RPC is used to evaluate an expression in the
@@ -504,6 +513,12 @@
 desired [Frame](#frame), with an index of _0_ indicating the top (most
 recent) frame.
 
+If _scope_ is provided, it should be a map from identifiers to object ids.
+These bindings will be added to the scope in which the expression is evaluated,
+which is a child scope of the frame's current scope. This means bindings
+provided in _scope_ may shadow instance members, class members, top-level
+members, parameters and locals.
+
 If an error occurs while evaluating the expression, an [@Error](#error)
 reference will be returned.
 
@@ -740,6 +755,24 @@
 Unhandled | Pause isolate on unhandled exceptions
 All  | Pause isolate on all thrown exceptions
 
+### setFlag
+
+```
+Success setFlag(string name,
+                string value)
+```
+
+The _setFlag_ RPC is used to set a VM flag at runtime. Returns an error if the
+named flag does not exist, the flag may not be set at runtime, or the value is
+of the wrong type for the flag.
+
+The following flags may be set at runtime:
+
+ * pause_isolates_on_start
+ * pause_isolates_on_exit
+ * pause_isolates_on_unhandled_exceptions
+
+See [Success](#success).
 
 ### setLibraryDebuggable
 
@@ -1488,10 +1521,11 @@
 ```
 class Frame extends Response {
   int index;
-  @Function function;
-  @Code code;
-  SourceLocation location;
-  BoundVariable[] vars;
+  @Function function [optional];
+  @Code code [optional];
+  SourceLocation location [optional];
+  BoundVariable[] vars [optional];
+  FrameKind kind [optional];
 }
 ```
 
@@ -2248,6 +2282,19 @@
 Adding new values to _SentinelKind_ is considered a backwards
 compatible change. Clients must handle this gracefully.
 
+
+### FrameKind
+```
+enum FrameKind {
+  Regular,
+  AsyncCausal,
+  AsyncSuspensionMarker,
+  AsyncActivation
+}
+```
+
+A _FrameKind_ is used to distinguish different kinds of _Frame_ objects.
+
 ### Script
 
 ```
@@ -2417,6 +2464,8 @@
 ```
 class Stack extends Response {
   Frame[] frames;
+  Frame[] asyncCausalFrames [optional];
+  Frame[] awaiterFrames [optional];
   Message[] messages;
 }
 ```
@@ -2596,6 +2645,7 @@
 3.3 | Pause event now indicates if the isolate is paused at an await, yield, or yield* suspension point via the 'atAsyncSuspension' field. Resume command now supports the step parameter 'OverAsyncSuspension'. A Breakpoint added synthetically by an 'OverAsyncSuspension' resume command identifies itself as such via the 'isSyntheticAsyncContinuation' field.
 3.4 | Add the superType and mixin fields to Class. Added new pause event 'None'.
 3.5 | Add the error field to SourceReportRange.  Clarify definition of token position.  Add "Isolate must be paused" error code.
-3.6 (unreleased) | Add 'scopeStartTokenPos', 'scopeEndTokenPos', and 'declarationTokenPos' to BoundVariable. Add 'PausePostRequest' event kind. Add 'Rewind' StepOption. Add error code 107 (isolate cannot resume). Add 'reloadSources' RPC and related error codes.
+3.6 | Add 'scopeStartTokenPos', 'scopeEndTokenPos', and 'declarationTokenPos' to BoundVariable. Add 'PausePostRequest' event kind. Add 'Rewind' StepOption. Add error code 107 (isolate cannot resume). Add 'reloadSources' RPC and related error codes. Add optional parameter 'scope' to 'evaluate' and 'evaluateInFrame'.
+3.7 | Add 'setFlag'.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index 97356ab..04581b5 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -1,11 +1,11 @@
 Note: this dev version of the protocol contains not yet released functionality,
 and is subject to change.
 
-# Dart VM Service Protocol 3.6-dev
+# Dart VM Service Protocol 3.8-dev
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.5_ of the Dart VM Service Protocol. This
+This document describes of _version 3.8-dev_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -44,6 +44,7 @@
 	- [removeBreakpoint](#removebreakpoint)
 	- [resume](#resume)
 	- [setExceptionPauseMode](#setexceptionpausemode)
+	- [setFlag](#setflag)
 	- [setLibraryDebuggable](#setlibrarydebuggable)
 	- [setName](#setname)
 	- [setVMName](#setvmname)
@@ -757,6 +758,24 @@
 Unhandled | Pause isolate on unhandled exceptions
 All  | Pause isolate on all thrown exceptions
 
+### setFlag
+
+```
+Success setFlag(string name,
+                string value)
+```
+
+The _setFlag_ RPC is used to set a VM flag at runtime. Returns an error if the
+named flag does not exist, the flag may not be set at runtime, or the value is
+of the wrong type for the flag.
+
+The following flags may be set at runtime:
+
+ * pause_isolates_on_start
+ * pause_isolates_on_exit
+ * pause_isolates_on_unhandled_exceptions
+
+See [Success](#success).
 
 ### setLibraryDebuggable
 
@@ -2629,6 +2648,7 @@
 3.3 | Pause event now indicates if the isolate is paused at an await, yield, or yield* suspension point via the 'atAsyncSuspension' field. Resume command now supports the step parameter 'OverAsyncSuspension'. A Breakpoint added synthetically by an 'OverAsyncSuspension' resume command identifies itself as such via the 'isSyntheticAsyncContinuation' field.
 3.4 | Add the superType and mixin fields to Class. Added new pause event 'None'.
 3.5 | Add the error field to SourceReportRange.  Clarify definition of token position.  Add "Isolate must be paused" error code.
-3.6 (unreleased) | Add 'scopeStartTokenPos', 'scopeEndTokenPos', and 'declarationTokenPos' to BoundVariable. Add 'PausePostRequest' event kind. Add 'Rewind' StepOption. Add error code 107 (isolate cannot resume). Add 'reloadSources' RPC and related error codes. Add optional parameter 'scope' to 'evaluate' and 'evaluateInFrame'.
+3.6 | Add 'scopeStartTokenPos', 'scopeEndTokenPos', and 'declarationTokenPos' to BoundVariable. Add 'PausePostRequest' event kind. Add 'Rewind' StepOption. Add error code 107 (isolate cannot resume). Add 'reloadSources' RPC and related error codes. Add optional parameter 'scope' to 'evaluate' and 'evaluateInFrame'.
+3.7 | Add 'setFlag'.
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 4af3163..01ae09b 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -136,6 +136,7 @@
   V(AwaitTempVarPrefix, ":await_temp_var_")                                    \
   V(AwaitContextVar, ":await_ctx_var")                                         \
   V(AwaitJumpVar, ":await_jump_var")                                           \
+  V(FutureImpl, "_Future")                                                     \
   V(Future, "Future")                                                          \
   V(FutureOr, "FutureOr")                                                      \
   V(FutureMicrotask, "Future.microtask")                                       \
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index c506170..3f98f69 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -7,8 +7,8 @@
 
 #include "include/dart_api.h"
 #include "platform/assert.h"
+#include "platform/atomic.h"
 #include "platform/safe_stack.h"
-#include "vm/atomic.h"
 #include "vm/bitfield.h"
 #include "vm/globals.h"
 #include "vm/handles.h"
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index be11b0e..d8d8e85 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -11,7 +11,7 @@
 #include <fcntl.h>
 #include <cstdlib>
 
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "vm/isolate.h"
 #include "vm/json_stream.h"
 #include "vm/lockers.h"
diff --git a/runtime/vm/timeline_android.cc b/runtime/vm/timeline_android.cc
index b43c508..74376b1 100644
--- a/runtime/vm/timeline_android.cc
+++ b/runtime/vm/timeline_android.cc
@@ -9,7 +9,7 @@
 #include <fcntl.h>
 #include <cstdlib>
 
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "vm/isolate.h"
 #include "vm/json_stream.h"
 #include "vm/lockers.h"
diff --git a/runtime/vm/timeline_linux.cc b/runtime/vm/timeline_linux.cc
index b244ecd..6ce1060 100644
--- a/runtime/vm/timeline_linux.cc
+++ b/runtime/vm/timeline_linux.cc
@@ -9,7 +9,7 @@
 #include <fcntl.h>
 #include <cstdlib>
 
-#include "vm/atomic.h"
+#include "platform/atomic.h"
 #include "vm/isolate.h"
 #include "vm/json_stream.h"
 #include "vm/lockers.h"
diff --git a/runtime/vm/timer.h b/runtime/vm/timer.h
index 2f5ce46..7d0efcb 100644
--- a/runtime/vm/timer.h
+++ b/runtime/vm/timer.h
@@ -5,9 +5,9 @@
 #ifndef RUNTIME_VM_TIMER_H_
 #define RUNTIME_VM_TIMER_H_
 
+#include "platform/atomic.h"
 #include "platform/utils.h"
 #include "vm/allocation.h"
-#include "vm/atomic.h"
 #include "vm/flags.h"
 #include "vm/os.h"
 
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index 53fa500..a2d0391 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -13,12 +13,6 @@
   "ast_printer.h",
   "ast_transformer.cc",
   "ast_transformer.h",
-  "atomic.h",
-  "atomic_android.h",
-  "atomic_fuchsia.h",
-  "atomic_linux.h",
-  "atomic_macos.h",
-  "atomic_win.h",
   "base_isolate.h",
   "become.cc",
   "become.h",
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index 0e98946..e850ad6 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -465,7 +465,7 @@
 @patch
 class Socket {
   @patch
-  static Future<Socket> connect(host, int port,
+  static Future<Socket> _connect(host, int port,
       {sourceAddress, Duration timeout}) {
     throw new UnsupportedError("Socket constructor");
   }
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart b/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
index c035e20..86ef3ec 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_helper.dart
@@ -840,7 +840,15 @@
    * pass messages along to the isolate running in the worker.
    */
   static void _processWorkerMessage(/* Worker */ sender, e) {
-    var msg = _deserializeMessage(_getEventData(e));
+    // Since we are listening on a global event, be graceful about other
+    // messages that may not belong to the isolate communication.
+    // See Issue #32438
+    var data = _getEventData(e);
+    if (!_isIsolateMessage(data)) return;
+
+    var msg = _deserializeMessage(data);
+    if (msg is! JSObject && msg is! Map) return;
+
     switch (msg['command']) {
       case 'start':
         _globalState.currentManagerId = msg['id'];
diff --git a/sdk/lib/_internal/js_runtime/lib/isolate_serialization.dart b/sdk/lib/_internal/js_runtime/lib/isolate_serialization.dart
index 31574ce..7872979 100644
--- a/sdk/lib/_internal/js_runtime/lib/isolate_serialization.dart
+++ b/sdk/lib/_internal/js_runtime/lib/isolate_serialization.dart
@@ -14,6 +14,31 @@
   return new _Deserializer().deserialize(message);
 }
 
+bool _isIsolateMessage(message) {
+  if (_isPrimitive(message)) return true;
+  if (message is! JSArray) return false;
+  if (message.isEmpty) return false;
+  switch (message.first) {
+    case "ref":
+    case "buffer":
+    case "typed":
+    case "fixed":
+    case "extendable":
+    case "mutable":
+    case "const":
+    case "map":
+    case "sendport":
+    case "raw sendport":
+    case "js-object":
+    case "function":
+    case "capability":
+    case "dart":
+      return true;
+    default:
+      return false;
+  }
+}
+
 /// Clones the message.
 ///
 /// Contrary to a `_deserializeMessage(_serializeMessage(x))` the `_clone`
@@ -33,7 +58,7 @@
 
   /// Returns a message that can be transmitted through web-worker channels.
   serialize(x) {
-    if (isPrimitive(x)) return serializePrimitive(x);
+    if (_isPrimitive(x)) return serializePrimitive(x);
 
     int serializationId = serializedObjectIds[x];
     if (serializationId != null) return makeRef(serializationId);
@@ -73,7 +98,6 @@
 
   makeRef(int serializationId) => ["ref", serializationId];
 
-  bool isPrimitive(x) => x == null || x is String || x is num || x is bool;
   serializePrimitive(primitive) => primitive;
 
   serializeByteBuffer(NativeByteBuffer buffer) {
@@ -190,7 +214,7 @@
 
   /// Returns a message that can be transmitted through web-worker channels.
   deserialize(x) {
-    if (isPrimitive(x)) return deserializePrimitive(x);
+    if (_isPrimitive(x)) return deserializePrimitive(x);
 
     if (x is! JSArray) throw new ArgumentError("Bad serialized message: $x");
 
@@ -228,7 +252,6 @@
     }
   }
 
-  bool isPrimitive(x) => x == null || x is String || x is num || x is bool;
   deserializePrimitive(x) => x;
 
   // ['ref', id].
@@ -385,3 +408,5 @@
         '', '#(#, #, #)', initializeObject, classId, emptyInstance, fields);
   }
 }
+
+bool _isPrimitive(x) => x == null || x is String || x is num || x is bool;
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index a57a9d9..e3fe5422a 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -92,6 +92,9 @@
 // TODO(floitsch): move this to foreign_helper.dart or similar.
 @ForceInline()
 bool isDartFunctionType(Object type) {
+  // Function type test is using the `in` operator which doesn't work on
+  // primitive types.
+  assert(!(type == null || type is num || type is String));
   return JS_BUILTIN(
       'returns:bool;effects:none;depends:none', JsBuiltin.isFunctionType, type);
 }
@@ -100,10 +103,19 @@
 // TODO(floitsch): move this to foreign_helper.dart or similar.
 @ForceInline()
 bool isDartFutureOrType(Object type) {
+  // FutureOr test is using the `in` operator which doesn't work on primitive
+  // types.
+  assert(!(type == null || type is num || type is String));
   return JS_BUILTIN(
       'returns:bool;effects:none;depends:none', JsBuiltin.isFutureOrType, type);
 }
 
+@ForceInline()
+bool isDartVoidTypeRti(Object type) {
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none', JsBuiltin.isVoidType, type);
+}
+
 /// Retrieves the class name from type information stored on the constructor of
 /// [type].
 // TODO(floitsch): move this to foreign_helper.dart or similar.
@@ -162,6 +174,14 @@
       JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME));
 }
 
+/// Returns whether the given type is the dynamic type.
+// TODO(floitsch): move this to foreign_helper.dart or similar.
+@ForceInline()
+bool isDartDynamicTypeRti(type) {
+  return JS_BUILTIN(
+      'returns:bool;effects:none;depends:none', JsBuiltin.isDynamicType, type);
+}
+
 /// Returns whether the given type is _the_ Dart Object type.
 // TODO(floitsch): move this to foreign_helper.dart or similar.
 @ForceInline()
@@ -582,8 +602,8 @@
 
     int requiredParametersInfo =
         JS('int', '#[#]', data, REQUIRED_PARAMETERS_INFO);
-    int requiredParameterCount = JS('int', '# >> 1', requiredParametersInfo);
-    bool isAccessor = (requiredParametersInfo & 1) == 1;
+    int requiredParameterCount = JS('int', '# >> 2', requiredParametersInfo);
+    bool isAccessor = (requiredParametersInfo & 2) == 2;
 
     int optionalParametersInfo =
         JS('int', '#[#]', data, OPTIONAL_PARAMETERS_INFO);
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index b334336..ae3fac4 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -215,9 +215,12 @@
 }
 
 String runtimeTypeToStringV2(var rti, List<String> genericContext) {
-  if (rti == null) {
+  if (isDartDynamicTypeRti(rti)) {
     return 'dynamic';
   }
+  if (isDartVoidTypeRti(rti)) {
+    return 'void';
+  }
   if (isJsArray(rti)) {
     // A list representing a type with arguments.
     return _getRuntimeTypeAsStringV2(rti, genericContext);
@@ -706,13 +709,47 @@
   return invokeOn(signature, context, typeArguments);
 }
 
+/// Returns `true` if the runtime type representation [type] is a top type.
+///
+/// For Dart 1 this is either `dynamic` or `Object`. For Dart 2 this is either
+/// `dynamic`, `void` or `Object`.
+@ForceInline()
+bool isTopType(var type) {
+  return JS_GET_FLAG('STRONG_MODE') ? isTopTypeV2(type) : isTopTypeV1(type);
+}
+
+/// Returns `true` if the runtime type representation [type] is a top type for
+/// Dart 1. That is, either `dynamic` or `Object`.
+@ForceInline()
+bool isTopTypeV1(var type) {
+  return isDartDynamicTypeRti(type) || isDartObjectTypeRti(type);
+}
+
+/// Returns `true` if the runtime type representation [type] is a top type for
+/// Dart 2. That is, either `dynamic`, `void` or `Object`.
+@ForceInline()
+bool isTopTypeV2(var type) {
+  return isDartDynamicTypeRti(type) ||
+      isDartVoidTypeRti(type) ||
+      isDartObjectTypeRti(type);
+}
+
 /// Returns `true` if the runtime type representation [type] is a supertype of
 /// [Null].
 @ForceInline()
 bool isSupertypeOfNull(var type) {
   return JS_GET_FLAG('STRONG_MODE')
-      ? isSupertypeOfNullBase(type) || isSupertypeOfNullRecursive(type)
-      : isSupertypeOfNullBase(type);
+      ? isSupertypeOfNullBaseV2(type) || isSupertypeOfNullRecursive(type)
+      : isSupertypeOfNullBaseV1(type);
+}
+
+/// Returns `true` if the runtime type representation [type] is a simple
+/// supertype of [Null].
+@ForceInline()
+bool isSupertypeOfNullBaseV1(var type) {
+  return isDartDynamicTypeRti(type) ||
+      isDartObjectTypeRti(type) ||
+      isNullTypeRti(type);
 }
 
 /// Returns `true` if the runtime type representation [type] is a simple
@@ -721,9 +758,11 @@
 /// This method doesn't handle `FutureOr<Null>`. This is handle by
 /// [isSupertypeOfNullRecursive] because it requires a recursive check.
 @ForceInline()
-bool isSupertypeOfNullBase(var type) {
-  // `null` means `dynamic`.
-  return type == null || isDartObjectTypeRti(type) || isNullTypeRti(type);
+bool isSupertypeOfNullBaseV2(var type) {
+  return isDartDynamicTypeRti(type) ||
+      isDartObjectTypeRti(type) ||
+      isNullTypeRti(type) ||
+      isDartVoidTypeRti(type);
 }
 
 /// Returns `true` if the runtime type representation [type] is a `FutureOr`
@@ -732,9 +771,14 @@
 /// This method is recursive to be able to handle both `FutureOr<Null>` and
 /// `FutureOr<FutureOr<Null>>` etc.
 bool isSupertypeOfNullRecursive(var type) {
+  if (isGenericFunctionTypeParameter(type)) {
+    // We need to check for function type variables because `isDartFutureOrType`
+    // doesn't work on numbers.
+    return false;
+  }
   if (isDartFutureOrType(type)) {
     var typeArgument = getFutureOrArgument(type);
-    return isSupertypeOfNullBase(type) ||
+    return isSupertypeOfNullBaseV2(type) ||
         isSupertypeOfNullRecursive(typeArgument);
   }
   return false;
@@ -762,7 +806,7 @@
  */
 bool checkSubtypeOfRuntimeType(o, t) {
   if (o == null) return isSupertypeOfNull(t);
-  if (t == null) return true;
+  if (isTopType(t)) return true;
   // Get the runtime type information from the object here, because we may
   // overwrite o with the interceptor below.
   var rti = getRuntimeTypeInfo(o);
@@ -832,7 +876,7 @@
   // Subtyping is reflexive.
   if (isIdentical(s, t)) return true;
   // If either type is dynamic, [s] is a subtype of [t].
-  if (s == null || t == null) return true;
+  if (isDartDynamicTypeRti(s) || isDartDynamicTypeRti(t)) return true;
 
   // Generic function type parameters must match exactly, which would have
   // exited earlier. The de Bruijn indexing ensures the representation as a
@@ -886,12 +930,15 @@
   if (isIdentical(s, t)) return true;
 
   // [t] is a top type?
-  if (t == null) return true;
-  if (isDartObjectTypeRti(t)) return true;
-  // TODO(sra): void is a top type.
+  if (isTopTypeV2(t)) return true;
 
   // [s] is a top type?
-  if (s == null) {
+  if (isTopTypeV2(s)) {
+    if (isGenericFunctionTypeParameter(t)) {
+      // We need to check for function type variables because
+      // `isDartFutureOrType` doesn't work on numbers.
+      return false;
+    }
     if (isDartFutureOrType(t)) {
       // [t] is FutureOr<T>. Check [s] <: T.
       var tTypeArgument = getFutureOrArgument(t);
@@ -1158,12 +1205,8 @@
     return false;
   }
 
-  // 'void' is a top type, so use `null` (dynamic) in its place.
-  // TODO(sra): Create a void type that can be used in all positions.
-  var sReturnType =
-      hasField(s, voidReturnTag) ? null : getField(s, returnTypeTag);
-  var tReturnType =
-      hasField(t, voidReturnTag) ? null : getField(t, returnTypeTag);
+  var sReturnType = getField(s, returnTypeTag);
+  var tReturnType = getField(t, returnTypeTag);
   if (!isSubtypeV2(sReturnType, sEnv, tReturnType, tEnv)) return false;
 
   var requiredParametersTag =
@@ -1251,12 +1294,14 @@
   return true;
 }
 
-/**
- * Returns whether [type] is the representation of a generic function type
- * parameter. Generic function type parameters are represented de Bruijn
- * indexes.
- */
+/// Returns whether [type] is the representation of a generic function type
+/// parameter. Generic function type parameters are represented de Bruijn
+/// indexes.
+///
+/// This test is only valid if [type] is known _not_ to be the void rti, whose
+/// runtime representation is -1.
 bool isGenericFunctionTypeParameter(var type) {
+  assert(!isDartVoidTypeRti(type));
   return type is num; // Actually int, but 'is num' is faster.
 }
 
@@ -1362,7 +1407,8 @@
 /// scope. This is subtracted off the de Bruijn index for the type parameter to
 /// arrive at an potential index into [parameters].
 bindInstantiatedType(rti, parameters, int depth) {
-  if (rti == null) return rti; // dynamic.
+  if (isDartDynamicTypeRti(rti)) return rti; // dynamic.
+  if (isDartVoidTypeRti(rti)) return rti; // void.
   // Functions are constructors denoting the class of the constructor.
   if (isJsFunction(rti)) return rti;
 
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index 3e07289..fdcc183 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -418,6 +418,16 @@
   ///     JS_BUILTIN('bool', JsBuiltin.isFutureOrType, o)
   isFutureOrType,
 
+  /// Returns true if the given type is the `void` type.
+  ///
+  ///     JS_BUILTIN('bool', JsBuiltin.isVoidType, o)
+  isVoidType,
+
+  /// Returns true if the given type is the `dynamic` type.
+  ///
+  ///     JS_BUILTIN('bool', JsBuiltin.isDynamicType, o)
+  isDynamicType,
+
   /// Returns the JavaScript-constructor name given an rti encoding.
   ///
   ///     JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti)
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index ceecfac..cba877e 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -43,7 +43,6 @@
 import 'dart:web_gl' as gl;
 import 'dart:web_gl' show RenderingContext, RenderingContext2;
 import 'dart:web_sql';
-import 'dart:_isolate_helper' show IsolateNatives;
 import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -121,8 +120,6 @@
   String nonce;
 }
 
-createCustomUpgrader(Type customElementClass, $this) => $this;
-
 /**
  * Emitted for any setlike IDL entry needs a callback signature.
  * Today there is only one.
@@ -26926,15 +26923,27 @@
   void _initMessageEvent_1(typeArg, canBubbleArg, cancelableArg, dataArg,
       originArg, lastEventIdArg, sourceArg, List<MessagePort> portsArg) native;
 }
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-@DocsEditable()
+// WARNING: Do not edit - generated code.
+
 @DomName('MessagePort')
 @Unstable()
 @Native("MessagePort")
 class MessagePort extends EventTarget {
+  void addEventListener(String type, EventListener listener,
+      [bool useCapture]) {
+    // Messages posted to ports are initially paused, allowing listeners to be
+    // setup, start() needs to be explicitly invoked to begin handling messages.
+    if (type == 'message') {
+      start();
+    }
+
+    super.addEventListener(type, listener, useCapture);
+  }
+
   // To suppress missing implicit constructor warnings.
   factory MessagePort._() {
     throw new UnsupportedError("Not supported");
@@ -26986,6 +26995,7 @@
   @DocsEditable()
   Stream<MessageEvent> get onMessage => messageEvent.forTarget(this);
 }
+
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
diff --git a/sdk/lib/io/overrides.dart b/sdk/lib/io/overrides.dart
index 4c85c9a..4eed013 100644
--- a/sdk/lib/io/overrides.dart
+++ b/sdk/lib/io/overrides.dart
@@ -79,6 +79,11 @@
       // Link
       Link Function(String) createLink,
 
+      // Socket
+      Future<Socket> Function(dynamic, int,
+              {dynamic sourceAddress, Duration timeout})
+          socketConnect,
+
       // Optional Zone parameters
       ZoneSpecification zoneSpecification,
       Function onError}) {
@@ -108,6 +113,9 @@
 
       // Link
       createLink,
+
+      // Socket
+      socketConnect,
     );
     return _asyncRunZoned<R>(body,
         zoneValues: {_ioOverridesToken: overrides},
@@ -236,9 +244,22 @@
   // Link
 
   /// Returns a new [Link] object for the given [path].
+  ///
   /// When this override is installed, this function overrides the behavior of
   /// `new Link()` and `new Link.fromUri()`.
   Link createLink(String path) => new _Link(path);
+
+  // Socket
+
+  /// Asynchronously returns a [Socket] connected to the given host and port.
+  ///
+  /// When this override is installed, this functions overrides the behavior of
+  /// `Socet.connect(...)`.
+  Future<Socket> socketConnect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    return Socket._connect(host, port,
+        sourceAddress: sourceAddress, timeout: timeout);
+  }
 }
 
 class _IOOverridesScope extends IOOverrides {
@@ -270,6 +291,10 @@
   // Link
   Link Function(String) _createLink;
 
+  // Socket
+  Future<Socket> Function(dynamic, int,
+      {dynamic sourceAddress, Duration timeout}) _socketConnect;
+
   _IOOverridesScope(
     // Directory
     this._createDirectory,
@@ -296,6 +321,9 @@
 
     // Link
     this._createLink,
+
+    // Socket
+    this._socketConnect,
   );
 
   // Directory
@@ -390,6 +418,7 @@
     return super.fsWatch(path, events, recursive);
   }
 
+  @override
   bool fsWatchIsSupported() {
     if (_fsWatchIsSupported != null) return _fsWatchIsSupported();
     if (_previous != null) return _previous.fsWatchIsSupported();
@@ -403,4 +432,20 @@
     if (_previous != null) return _previous.createLink(path);
     return super.createLink(path);
   }
+
+  // Socket
+  @override
+  Future<Socket> socketConnect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    if (_socketConnect != null) {
+      return _socketConnect(host, port,
+          sourceAddress: sourceAddress, timeout: timeout);
+    }
+    if (_previous != null) {
+      return _previous.socketConnect(host, port,
+          sourceAddress: sourceAddress, timeout: timeout);
+    }
+    return super.socketConnect(host, port,
+        sourceAddress: sourceAddress, timeout: timeout);
+  }
 }
diff --git a/sdk/lib/io/socket.dart b/sdk/lib/io/socket.dart
index b1565cd..7c25e2c 100644
--- a/sdk/lib/io/socket.dart
+++ b/sdk/lib/io/socket.dart
@@ -536,7 +536,18 @@
    * [timeout]. On timeout, a [SocketException] is thrown and all ongoing
    * connection attempts to [host] are cancelled.
    */
-  external static Future<Socket> connect(host, int port,
+  static Future<Socket> connect(host, int port,
+      {sourceAddress, Duration timeout}) {
+    final IOOverrides overrides = IOOverrides.current;
+    if (overrides == null) {
+      return Socket._connect(host, port,
+          sourceAddress: sourceAddress, timeout: timeout);
+    }
+    return overrides.socketConnect(host, port,
+        sourceAddress: sourceAddress, timeout: timeout);
+  }
+
+  external static Future<Socket> _connect(host, int port,
       {sourceAddress, Duration timeout});
 
   /**
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index 9025f36..a8c5ade 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -2964,6 +2964,7 @@
 LayoutTests/fast/filesystem/filesystem-reference_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/filesystem-unserializable_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/filesystem-uri-origin_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/filesystem/input-access-entries_t01: RuntimeError # See issue 143
 LayoutTests/fast/filesystem/op-copy_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/op-get-entry_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/filesystem/op-get-metadata_t01: RuntimeError # Please triage this failure
@@ -3236,6 +3237,7 @@
 LayoutTests/fast/text/find-soft-hyphen_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/international/iso-8859-8_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/international/listbox-width-rtl_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/text/international/rtl-text-wrapping_t01: RuntimeError # See issue 143
 LayoutTests/fast/text/international/thai-offsetForPosition-inside-character_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/line-break-after-question-mark_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/text/line-breaks-after-hyphen-before-number_t01: RuntimeError # Please triage this failure
@@ -6163,6 +6165,7 @@
 LayoutTests/fast/forms/ValidityState-typeMismatch-email_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/autocomplete_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/autofocus-input-css-style-change_t01: Pass, RuntimeError # Fails 7 out of 10.
+LayoutTests/fast/forms/autofocus-opera-007_t01: RuntimeError # See issue 143
 LayoutTests/fast/forms/button-baseline-and-collapsing_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/button/button-disabled-blur_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/forms/checkValidity-001_t01: RuntimeError # co19 issue 142
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index 8347cd1..3668431 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -851,8 +851,6 @@
 Language/Expressions/Unary_Expressions/syntax_t27/20: CompileTimeError
 Language/Expressions/Unary_Expressions/syntax_t27/21: CompileTimeError
 Language/Expressions/Unary_Expressions/variable_negative_t03: CompileTimeError
-Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
-Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
 Language/Functions/Formal_Parameters/Optional_Formals/syntax_t06: CompileTimeError
 Language/Functions/Formal_Parameters/Optional_Formals/syntax_t10: CompileTimeError
 Language/Functions/Formal_Parameters/Required_Formals/syntax_t05: CompileTimeError
@@ -1700,8 +1698,6 @@
 Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t07: MissingCompileTimeError
 Language/Expressions/Property_Extraction/Getter_Access_and_Method_Extraction/class_object_member_t08: MissingCompileTimeError
 Language/Expressions/Throw/syntax_t02: MissingCompileTimeError
-Language/Functions/Formal_Parameters/Optional_Formals/default_value_t01: MissingCompileTimeError
-Language/Functions/Formal_Parameters/Optional_Formals/default_value_t02: MissingCompileTimeError
 Language/Libraries_and_Scripts/Exports/reexport_t01: MissingCompileTimeError
 Language/Libraries_and_Scripts/Exports/reexport_t02: MissingCompileTimeError
 Language/Libraries_and_Scripts/Imports/invalid_uri_deferred_t02: CompileTimeError
diff --git a/tests/compiler/dart2js/helpers/element_lookup.dart b/tests/compiler/dart2js/helpers/element_lookup.dart
new file mode 100644
index 0000000..670e45f
--- /dev/null
+++ b/tests/compiler/dart2js/helpers/element_lookup.dart
@@ -0,0 +1,48 @@
+// 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 'package:compiler/src/common_elements.dart' show ElementEnvironment;
+import 'package:compiler/src/elements/entities.dart';
+import 'package:compiler/src/elements/types.dart';
+import 'package:compiler/src/world.dart' show ClosedWorld;
+
+ClassEntity findClass(ClosedWorld closedWorld, String name) {
+  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
+  ClassEntity cls =
+      elementEnvironment.lookupClass(elementEnvironment.mainLibrary, name);
+  cls ??= elementEnvironment.lookupClass(
+      closedWorld.commonElements.coreLibrary, name);
+  assert(cls != null, "Class '$name' not found.");
+  return cls;
+}
+
+MemberEntity findClassMember(
+    ClosedWorld closedWorld, String className, String memberName) {
+  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
+  ClassEntity cls = findClass(closedWorld, className);
+  assert(cls != null, "Class '$className' not found.");
+  MemberEntity member = elementEnvironment.lookupClassMember(cls, memberName);
+  assert(member != null, "Member '$memberName' not found in $cls.");
+  return member;
+}
+
+MemberEntity findMember(ClosedWorld closedWorld, String name) {
+  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
+  MemberEntity member = elementEnvironment.lookupLibraryMember(
+      elementEnvironment.mainLibrary, name);
+  member ??= elementEnvironment.lookupLibraryMember(
+      closedWorld.commonElements.coreLibrary, name);
+  assert(member != null, "Member '$name' not found.");
+  return member;
+}
+
+FunctionType findFunctionType(ClosedWorld closedWorld, String name) {
+  FunctionEntity function = findMember(closedWorld, name);
+  return closedWorld.elementEnvironment.getFunctionType(function);
+}
+
+DartType findFieldType(ClosedWorld closedWorld, String name) {
+  FieldEntity field = findMember(closedWorld, name);
+  return closedWorld.elementEnvironment.getFieldType(field);
+}
diff --git a/tests/compiler/dart2js/inference/list_tracer_test.dart b/tests/compiler/dart2js/inference/list_tracer_test.dart
index 6182436..5e682cc 100644
--- a/tests/compiler/dart2js/inference/list_tracer_test.dart
+++ b/tests/compiler/dart2js/inference/list_tracer_test.dart
@@ -8,6 +8,7 @@
 import 'package:expect/expect.dart';
 
 import 'type_mask_test_helper.dart';
+import '../helpers/element_lookup.dart';
 import '../memory_compiler.dart';
 
 String generateTest(String listAllocation) {
diff --git a/tests/compiler/dart2js/inference/map_tracer_test.dart b/tests/compiler/dart2js/inference/map_tracer_test.dart
index a2be02a..33e6b10 100644
--- a/tests/compiler/dart2js/inference/map_tracer_test.dart
+++ b/tests/compiler/dart2js/inference/map_tracer_test.dart
@@ -12,6 +12,7 @@
 import 'package:expect/expect.dart';
 
 import 'type_mask_test_helper.dart';
+import '../helpers/element_lookup.dart';
 import '../memory_compiler.dart';
 
 String generateTest(String mapAllocation) {
diff --git a/tests/compiler/dart2js/inference/type_mask_test_helper.dart b/tests/compiler/dart2js/inference/type_mask_test_helper.dart
index 450821c..a3b661b 100644
--- a/tests/compiler/dart2js/inference/type_mask_test_helper.dart
+++ b/tests/compiler/dart2js/inference/type_mask_test_helper.dart
@@ -4,9 +4,6 @@
 
 library type_mask_test_helper;
 
-import 'package:compiler/src/common_elements.dart' show ElementEnvironment;
-import 'package:compiler/src/elements/entities.dart'
-    show ClassEntity, MemberEntity;
 import 'package:compiler/src/types/types.dart';
 import 'package:compiler/src/world.dart' show ClosedWorld;
 
@@ -40,30 +37,3 @@
         closedWorld);
   }
 }
-
-ClassEntity findClass(ClosedWorld closedWorld, String name) {
-  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
-  ClassEntity cls =
-      elementEnvironment.lookupClass(elementEnvironment.mainLibrary, name);
-  assert(cls != null, "Class '$name' not found.");
-  return cls;
-}
-
-MemberEntity findClassMember(
-    ClosedWorld closedWorld, String className, String memberName) {
-  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
-  ClassEntity cls =
-      elementEnvironment.lookupClass(elementEnvironment.mainLibrary, className);
-  assert(cls != null, "Class '$className' not found.");
-  MemberEntity member = elementEnvironment.lookupClassMember(cls, memberName);
-  assert(member != null, "Member '$memberName' not found in $cls.");
-  return member;
-}
-
-MemberEntity findMember(ClosedWorld closedWorld, String name) {
-  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
-  MemberEntity member = elementEnvironment.lookupLibraryMember(
-      elementEnvironment.mainLibrary, name);
-  assert(member != null, "Member '$name' not found.");
-  return member;
-}
diff --git a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05_strong.dart b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05_strong.dart
index 7e28606..b0b6317 100644
--- a/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05_strong.dart
+++ b/tests/compiler/dart2js/rti/data/generic_methods_dynamic_05_strong.dart
@@ -4,18 +4,18 @@
 
 // Test derived from language_2/generic_methods_dynamic_test/05
 
-/*class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SubListIterable],explicit=[JSArray,List<JSArray.E>],implicit=[JSArray.E],indirect,needsArgs*/
-/*class: global#List:deps=[C.bar,EmptyIterable,Iterable,JSArray,ListIterable,makeListFixedLength],explicit=[List,List.E,List<B>,List<JSArray.E>,List<makeListFixedLength.T>],implicit=[List.E],indirect,needsArgs*/
+/*class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SubListIterable],explicit=[JSArray],needsArgs*/
+/*class: global#List:deps=[C.bar,EmptyIterable,Iterable,JSArray,ListIterable],explicit=[List,List<B>],needsArgs*/
 
 import "package:expect/expect.dart";
 
 class A {}
 
-/*class: B:explicit=[List<B>],implicit=[B]*/
+/*class: B:explicit=[List<B>]*/
 class B {}
 
 class C {
-  /*element: C.bar:implicit=[bar.T],indirect,needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
+  /*element: C.bar:needsArgs,selectors=[Selector(call, bar, arity=1, types=1)]*/
   List<T> bar<T>(Iterable<T> t) => <T>[t.first];
 }
 
diff --git a/tests/compiler/dart2js/rti/data/list_literal_strong.dart b/tests/compiler/dart2js/rti/data/list_literal_strong.dart
index a927f9e..a2db42d 100644
--- a/tests/compiler/dart2js/rti/data/list_literal_strong.dart
+++ b/tests/compiler/dart2js/rti/data/list_literal_strong.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*class: global#List:deps=[Class.m,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin,makeListFixedLength],explicit=[List,List.E,List<JSArray.E>,List<makeListFixedLength.T>],implicit=[List.E],indirect,needsArgs*/
-/*class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray,List<JSArray.E>],implicit=[JSArray.E],indirect,needsArgs*/
+/*class: global#List:deps=[Class.m,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin],explicit=[List],implicit=[List.E],indirect,needsArgs*/
+/*class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 
 main() {
   var c = new Class();
diff --git a/tests/compiler/dart2js/rti/data/list_to_set_strong.dart b/tests/compiler/dart2js/rti/data/list_to_set_strong.dart
index da4535a..9f00b07 100644
--- a/tests/compiler/dart2js/rti/data/list_to_set_strong.dart
+++ b/tests/compiler/dart2js/rti/data/list_to_set_strong.dart
@@ -2,8 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin,makeListFixedLength],explicit=[List,List.E,List<JSArray.E>,List<makeListFixedLength.T>],implicit=[List.E],indirect,needsArgs*/
-/*class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray,List<JSArray.E>],implicit=[JSArray.E],indirect,needsArgs*/
+/*class: global#List:deps=[Class,EmptyIterable,Iterable,JSArray,ListIterable,SetMixin],explicit=[List],implicit=[List.E],indirect,needsArgs*/
+/*class: global#JSArray:deps=[EmptyIterable,List,ListIterable,SetMixin,SubListIterable],explicit=[JSArray],implicit=[JSArray.E],indirect,needsArgs*/
 
 main() {
   var c = new Class<int>();
diff --git a/tests/compiler/dart2js/rti/data/map_literal_strong.dart b/tests/compiler/dart2js/rti/data/map_literal_strong.dart
index c4d4b4c..1643414 100644
--- a/tests/compiler/dart2js/rti/data/map_literal_strong.dart
+++ b/tests/compiler/dart2js/rti/data/map_literal_strong.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*class: global#Map:indirect,needsArgs*/
-/*class: global#LinkedHashMap:deps=[Map],explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],indirect,needsArgs*/
-/*class: global#JsLinkedHashMap:deps=[LinkedHashMap],direct,explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],needsArgs*/
-/*class: global#double:explicit=[double],implicit=[double]*/
+/*class: global#Map:*/
+/*class: global#LinkedHashMap:deps=[Map]*/
+/*class: global#JsLinkedHashMap:deps=[LinkedHashMap]*/
+/*class: global#double:explicit=[double]*/
 /*class: global#JSDouble:*/
 
 main() {
diff --git a/tests/compiler/dart2js/rti/data/map_to_set_strong.dart b/tests/compiler/dart2js/rti/data/map_to_set_strong.dart
index a111643..4cfda0e 100644
--- a/tests/compiler/dart2js/rti/data/map_to_set_strong.dart
+++ b/tests/compiler/dart2js/rti/data/map_to_set_strong.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-/*class: global#Map:deps=[Class],indirect,needsArgs*/
-/*class: global#LinkedHashMap:deps=[Map],explicit=[LinkedHashMap<LinkedHashMap.K,LinkedHashMap.V>],implicit=[LinkedHashMap.K,LinkedHashMap.V],indirect,needsArgs*/
-/*class: global#JsLinkedHashMap:deps=[LinkedHashMap],explicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],implicit=[JsLinkedHashMap.K,JsLinkedHashMap.V],indirect,needsArgs*/
-/*class: global#double:explicit=[double],implicit=[double]*/
+/*class: global#Map:deps=[Class],needsArgs*/
+/*class: global#LinkedHashMap:deps=[Map],needsArgs*/
+/*class: global#JsLinkedHashMap:deps=[LinkedHashMap],implicit=[JsLinkedHashMap.K],needsArgs*/
+/*class: global#double:explicit=[double]*/
 /*class: global#JSDouble:*/
 
 main() {
@@ -15,8 +15,7 @@
   set is Set<String>;
 }
 
-/*ast.class: Class:needsArgs*/
-/*kernel.class: Class:implicit=[Class.S,Class.T],indirect,needsArgs*/
+/*class: Class:needsArgs*/
 class Class<T, S> {
   m() {
     return <T, S>{};
diff --git a/tests/compiler/dart2js/rti/instance_call_test.dart b/tests/compiler/dart2js/rti/instance_call_test.dart
index 3523924..1b656ed 100644
--- a/tests/compiler/dart2js/rti/instance_call_test.dart
+++ b/tests/compiler/dart2js/rti/instance_call_test.dart
@@ -99,7 +99,8 @@
 main() {
   asyncTest(() async {
     CompilationResult result = await runCompiler(
-        memorySourceFiles: {'main.dart': code}, options: [Flags.strongMode]);
+        memorySourceFiles: {'main.dart': code},
+        options: [Flags.strongMode, Flags.omitImplicitChecks]);
     Expect.isTrue(result.isSuccess);
     Compiler compiler = result.compiler;
     ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
diff --git a/tests/compiler/dart2js/rti/rti_need_test.dart b/tests/compiler/dart2js/rti/rti_need_test.dart
index 053b43b..644acd6 100644
--- a/tests/compiler/dart2js/rti/rti_need_test.dart
+++ b/tests/compiler/dart2js/rti/rti_need_test.dart
@@ -7,6 +7,7 @@
 import 'package:compiler/src/closure.dart';
 import 'package:compiler/src/common.dart';
 import 'package:compiler/src/common_elements.dart';
+import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/diagnostic_listener.dart';
 import 'package:compiler/src/elements/elements.dart';
@@ -34,6 +35,7 @@
         dataDir, computeAstRtiMemberNeed, computeKernelRtiMemberNeed,
         computeClassDataFromAst: computeAstRtiClassNeed,
         computeClassDataFromKernel: computeKernelRtiClassNeed,
+        options: [Flags.omitImplicitChecks], // only used in strong-mode
         args: args);
   });
 }
diff --git a/tests/compiler/dart2js/type_representation_test.dart b/tests/compiler/dart2js/type_representation_test.dart
index b334504..b4cfd1c 100644
--- a/tests/compiler/dart2js/type_representation_test.dart
+++ b/tests/compiler/dart2js/type_representation_test.dart
@@ -6,282 +6,333 @@
 
 library type_representation_test;
 
-import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
-import 'type_test_helper.dart';
-import 'package:compiler/src/elements/resolution_types.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common_elements.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/elements/types.dart';
 import 'package:compiler/src/js/js.dart';
-import 'package:compiler/src/elements/elements.dart' show Element, ClassElement;
+import 'package:compiler/src/elements/entities.dart';
 import 'package:compiler/src/js_backend/backend.dart' show JavaScriptBackend;
 import 'package:compiler/src/js_backend/runtime_types.dart'
     show TypeRepresentationGenerator;
+import 'package:compiler/src/world.dart';
+import 'package:expect/expect.dart';
+import 'helpers/element_lookup.dart';
+import 'memory_compiler.dart';
+import 'type_test_helper.dart';
 
 void main() {
-  testTypeRepresentations();
+  asyncTest(() async {
+    print('--test from ast---------------------------------------------------');
+    await testAll(useKernel: false);
+    print('--test from kernel------------------------------------------------');
+    await testAll(useKernel: true);
+    print('--test from kernel (strong)---------------------------------------');
+    await testAll(useKernel: true, strongMode: true);
+  });
 }
 
-void testTypeRepresentations() {
-  asyncTest(() => TypeEnvironment.create(r"""
-      typedef void Typedef();
-      typedef int Typedef2();
-      typedef List<int> Typedef3();
-      typedef Typedef4();
-      typedef Typedef5(int a, String b);
-      typedef Typedef6(int a, [String b]);
-      typedef Typedef7(int a, String b, [List<int> c, d]);
-      typedef Typedef8(int a, {String b});
-      typedef Typedef9(int a, String b, {List<int> c, d});
-      typedef Typedef10(void f(int a, [b]));
-
-      void m1() {}
-      int m2() => 0;
-      List<int> m3() => null;
-      m4() {}
-      m5(int a, String b) {}
-      m6(int a, [String b]) {}
-      m7(int a, String b, [List<int> c, d]) {}
-      m8(int a, {String b}) {}
-      m9(int a, String b, {List<int> c, d}) {}
-      m10(void f(int a, [b])) {}
-      """).then((env) {
-        var elementEnvironment =
-            env.compiler.frontendStrategy.elementEnvironment;
-        var closedWorldRefiner =
-            env.compiler.closeResolution(elementEnvironment.mainFunction);
-        var closedWorld = closedWorldRefiner.closedWorld;
-        env.compiler.startCodegen(closedWorld);
-        TypeRepresentationGenerator typeRepresentation =
-            new TypeRepresentationGenerator(env.compiler.backend.namer, false);
-
-        Expression onVariable(TypeVariableType _variable) {
-          ResolutionTypeVariableType variable = _variable;
-          return new VariableUse(variable.name);
-        }
-
-        String stringify(Expression expression) {
-          return prettyPrint(expression,
-              enableMinification: env.compiler.options.enableMinification);
-        }
-
-        void expect(ResolutionDartType type, String expectedRepresentation,
-            [String expectedTypedefRepresentation]) {
-          bool encodeTypedefName = false;
-          Expression expression = typeRepresentation.getTypeRepresentation(
-              env.compiler.backend.emitter.emitter,
-              type,
-              onVariable,
-              (x) => encodeTypedefName);
-          Expect.stringEquals(expectedRepresentation, stringify(expression));
-
-          encodeTypedefName = true;
-          expression = typeRepresentation.getTypeRepresentation(
-              env.compiler.backend.emitter.emitter,
-              type,
-              onVariable,
-              (x) => encodeTypedefName);
-          if (expectedTypedefRepresentation == null) {
-            expectedTypedefRepresentation = expectedRepresentation;
-          }
-          Expect.stringEquals(
-              expectedTypedefRepresentation, stringify(expression));
-        }
-
-        String getJsName(Element cls) {
-          Expression name = typeRepresentation.getJavaScriptClassName(
-              cls, env.compiler.backend.emitter.emitter);
-          return stringify(name);
-        }
-
-        JavaScriptBackend backend = env.compiler.backend;
-        String func = backend.namer.functionTypeTag;
-        String retvoid = backend.namer.functionTypeVoidReturnTag;
-        String ret = backend.namer.functionTypeReturnTypeTag;
-        String args = backend.namer.functionTypeRequiredParametersTag;
-        String opt = backend.namer.functionTypeOptionalParametersTag;
-        String named = backend.namer.functionTypeNamedParametersTag;
-        String typedefTag = backend.namer.typedefTag;
-
-        ClassElement List_ = env.getElement('List');
-        ResolutionTypeVariableType List_E = List_.typeVariables[0];
-        ClassElement Map_ = env.getElement('Map');
-        ResolutionTypeVariableType Map_K = Map_.typeVariables[0];
-        ResolutionTypeVariableType Map_V = Map_.typeVariables[1];
-
-        ResolutionDartType int_ = env['int'];
-        ResolutionDartType String_ = env['String'];
-        ResolutionDartType dynamic_ = env['dynamic'];
-        ResolutionDartType Typedef_ = env['Typedef'];
-        ResolutionDartType Typedef2_ = env['Typedef2'];
-        ResolutionDartType Typedef3_ = env['Typedef3'];
-        ResolutionDartType Typedef4_ = env['Typedef4'];
-        ResolutionDartType Typedef5_ = env['Typedef5'];
-        ResolutionDartType Typedef6_ = env['Typedef6'];
-        ResolutionDartType Typedef7_ = env['Typedef7'];
-        ResolutionDartType Typedef8_ = env['Typedef8'];
-        ResolutionDartType Typedef9_ = env['Typedef9'];
-        ResolutionDartType Typedef10_ = env['Typedef10'];
-
-        String List_rep = getJsName(List_);
-        String List_E_rep = stringify(onVariable(List_E));
-        String Map_rep = getJsName(Map_);
-        String Map_K_rep = stringify(onVariable(Map_K));
-        String Map_V_rep = stringify(onVariable(Map_V));
-
-        String int_rep = getJsName(int_.element);
-        String String_rep = getJsName(String_.element);
-
-        String Typedef_rep = getJsName(Typedef_.element);
-        String Typedef2_rep = getJsName(Typedef2_.element);
-        String Typedef3_rep = getJsName(Typedef3_.element);
-        String Typedef4_rep = getJsName(Typedef4_.element);
-        String Typedef5_rep = getJsName(Typedef5_.element);
-        String Typedef6_rep = getJsName(Typedef6_.element);
-        String Typedef7_rep = getJsName(Typedef7_.element);
-        String Typedef8_rep = getJsName(Typedef8_.element);
-        String Typedef9_rep = getJsName(Typedef9_.element);
-        String Typedef10_rep = getJsName(Typedef10_.element);
-
-        expect(int_, '$int_rep');
-        expect(String_, '$String_rep');
-        expect(dynamic_, 'null');
-
-        // List<E>
-        expect(List_.computeType(env.compiler.resolution),
-            '[$List_rep, $List_E_rep]');
-        // List
-        expect(List_.rawType, '$List_rep');
-        // List<dynamic>
-        expect(instantiate(List_, [dynamic_]), '$List_rep');
-        // List<int>
-        expect(instantiate(List_, [int_]), '[$List_rep, $int_rep]');
-        // List<Typedef>
-        expect(
-            instantiate(List_, [Typedef_]),
-            '[$List_rep, {$func: 1, $retvoid: true}]',
-            '[$List_rep, {$func: 1, $retvoid: true,'
-            ' $typedefTag: $Typedef_rep}]');
-        expect(
-            instantiate(List_, [Typedef2_]),
-            '[$List_rep, {$func: 1, $ret: $int_rep}]',
-            '[$List_rep, {$func: 1, $ret: $int_rep,'
-            ' $typedefTag: $Typedef2_rep}]');
-        expect(
-            instantiate(List_, [Typedef3_]),
-            '[$List_rep, {$func: 1, $ret: [$List_rep, $int_rep]}]',
-            '[$List_rep, {$func: 1, $ret: [$List_rep, $int_rep],'
-            ' $typedefTag: $Typedef3_rep}]');
-        expect(instantiate(List_, [Typedef4_]), '[$List_rep, {$func: 1}]',
-            '[$List_rep, {$func: 1, $typedefTag: $Typedef4_rep}]');
-        expect(
-            instantiate(List_, [Typedef5_]),
-            '[$List_rep, {$func: 1,'
-            ' $args: [$int_rep, $String_rep]}]',
-            '[$List_rep, {$func: 1,'
-            ' $args: [$int_rep, $String_rep], $typedefTag: $Typedef5_rep}]');
-        expect(
-            instantiate(List_, [Typedef6_]),
-            '[$List_rep, {$func: 1,'
-            ' $args: [$int_rep], $opt: [$String_rep]}]',
-            '[$List_rep, {$func: 1,'
-            ' $args: [$int_rep], $opt: [$String_rep],'
-            ' $typedefTag: $Typedef6_rep}]');
-        expect(
-            instantiate(List_, [Typedef7_]),
-            '[$List_rep, {$func: 1, $args: '
-            '[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep],,]}]',
-            '[$List_rep, {$func: 1, $args: '
-            '[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep],,], '
-            '$typedefTag: $Typedef7_rep}]');
-        expect(
-            instantiate(List_, [Typedef8_]),
-            '[$List_rep, {$func: 1, $args: [$int_rep],'
-            ' $named: {b: $String_rep}}]',
-            '[$List_rep, {$func: 1, $args: [$int_rep],'
-            ' $named: {b: $String_rep}, $typedefTag: $Typedef8_rep}]');
-        expect(
-            instantiate(List_, [Typedef9_]),
-            '[$List_rep, {$func: 1, '
-            '$args: [$int_rep, $String_rep], $named: '
-            '{c: [$List_rep, $int_rep], d: null}}]',
-            '[$List_rep, {$func: 1, '
-            '$args: [$int_rep, $String_rep], $named: {c: [$List_rep, $int_rep],'
-            ' d: null}, $typedefTag: $Typedef9_rep}]');
-        expect(
-            instantiate(List_, [Typedef10_]),
-            '[$List_rep, {$func: 1, '
-            '$args: [{$func: 1, $retvoid: true, '
-            '$args: [$int_rep], $opt: [,]}]}]',
-            '[$List_rep, {$func: 1, '
-            '$args: [{$func: 1, $retvoid: true, '
-            '$args: [$int_rep], $opt: [,]}], $typedefTag: $Typedef10_rep}]');
-
-        // Map<K,V>
-        expect(Map_.computeType(env.compiler.resolution),
-            '[$Map_rep, $Map_K_rep, $Map_V_rep]');
-        // Map
-        expect(Map_.rawType, '$Map_rep');
-        // Map<dynamic,dynamic>
-        expect(instantiate(Map_, [dynamic_, dynamic_]), '$Map_rep');
-        // Map<int,String>
-        expect(instantiate(Map_, [int_, String_]),
-            '[$Map_rep, $int_rep, $String_rep]');
-
-        // void m1() {}
-        expect(computeType(env.getElement('m1'), env.compiler.resolution),
-            '{$func: 1, $retvoid: true}');
-
-        // int m2() => 0;
-        expect(computeType(env.getElement('m2'), env.compiler.resolution),
-            '{$func: 1, $ret: $int_rep}');
-
-        // List<int> m3() => null;
-        expect(computeType(env.getElement('m3'), env.compiler.resolution),
-            '{$func: 1, $ret: [$List_rep, $int_rep]}');
-
-        // m4() {}
-        expect(computeType(env.getElement('m4'), env.compiler.resolution),
-            '{$func: 1}');
-
-        // m5(int a, String b) {}
-        expect(computeType(env.getElement('m5'), env.compiler.resolution),
-            '{$func: 1, $args: [$int_rep, $String_rep]}');
-
-        // m6(int a, [String b]) {}
-        expect(
-            computeType(env.getElement('m6'), env.compiler.resolution),
-            '{$func: 1, $args: [$int_rep],'
-            ' $opt: [$String_rep]}');
-
-        // m7(int a, String b, [List<int> c, d]) {}
-        expect(
-            computeType(env.getElement('m7'), env.compiler.resolution),
-            '{$func: 1,'
-            ' $args: [$int_rep, $String_rep],'
-            ' $opt: [[$List_rep, $int_rep],,]}');
-
-        // m8(int a, {String b}) {}
-        expect(
-            computeType(env.getElement('m8'), env.compiler.resolution),
-            '{$func: 1,'
-            ' $args: [$int_rep], $named: {b: $String_rep}}');
-
-        // m9(int a, String b, {List<int> c, d}) {}
-        expect(
-            computeType(env.getElement('m9'), env.compiler.resolution),
-            '{$func: 1,'
-            ' $args: [$int_rep, $String_rep],'
-            ' $named: {c: [$List_rep, $int_rep], d: null}}');
-
-        // m10(void f(int a, [b])) {}
-        expect(
-            computeType(env.getElement('m10'), env.compiler.resolution),
-            '{$func: 1, $args:'
-            ' [{$func: 1,'
-            ' $retvoid: true, $args: [$int_rep], $opt: [,]}]}');
-      }));
+testAll({bool useKernel, bool strongMode: false}) async {
+  await testTypeRepresentations(useKernel: useKernel, strongMode: strongMode);
 }
 
-computeType(element, resolution) {
-  return element.computeType(resolution);
+List<FunctionTypeData> signatures = const <FunctionTypeData>[
+  const FunctionTypeData("void", "1", "()"),
+  const FunctionTypeData("int", "2", "()"),
+  const FunctionTypeData("List<int>", "3", "()"),
+  const FunctionTypeData("dynamic", "4", "()"),
+  const FunctionTypeData("dynamic", "5", "(int a, String b)"),
+  const FunctionTypeData("dynamic", "6", "(int a, [String b])"),
+  const FunctionTypeData(
+      "dynamic", "7", "(int a, String b, [List<int> c, dynamic d])"),
+  const FunctionTypeData("dynamic", "8", "(int a, {String b})"),
+  const FunctionTypeData(
+      "dynamic", "9", "(int a, String b, {List<int> c, dynamic d})"),
+  const FunctionTypeData(
+      "dynamic", "10", "(void Function(int a, [dynamic b]) f)"),
+  const FunctionTypeData("FutureOr<int>", "11",
+      "<T extends num, S>(FutureOr<T> a, S b, List<void> c)"),
+];
+
+testTypeRepresentations({bool useKernel, bool strongMode}) async {
+  String source = '''
+import 'dart:async';
+
+${createTypedefs(signatures, prefix: 'Typedef')}
+${createMethods(signatures, prefix: 'm')}
+
+main() {
+  ${createUses(signatures, prefix: 'Typedef')}
+  ${createUses(signatures, prefix: 'm')}
+}
+''';
+  CompilationResult result = await runCompiler(
+      memorySourceFiles: {'main.dart': source},
+      options: useKernel
+          ? (strongMode ? [Flags.strongMode] : [])
+          : [Flags.useOldFrontend]);
+  Expect.isTrue(result.isSuccess);
+  Compiler compiler = result.compiler;
+  JavaScriptBackend backend = compiler.backend;
+
+  TypeRepresentationGenerator typeRepresentation =
+      new TypeRepresentationGenerator(backend.namer, strongMode: strongMode);
+
+  Expression onVariable(TypeVariableType _variable) {
+    TypeVariableType variable = _variable;
+    return new VariableUse(variable.element.name);
+  }
+
+  String stringify(Expression expression) {
+    return prettyPrint(expression,
+        enableMinification: compiler.options.enableMinification);
+  }
+
+  void expect(DartType type, String expectedRepresentation,
+      [String expectedTypedefRepresentation]) {
+    bool encodeTypedefName = false;
+    Expression expression = typeRepresentation.getTypeRepresentation(
+        backend.emitter.emitter, type, onVariable, (x) => encodeTypedefName);
+    Expect.stringEquals(expectedRepresentation, stringify(expression));
+
+    encodeTypedefName = true;
+    expression = typeRepresentation.getTypeRepresentation(
+        backend.emitter.emitter, type, onVariable, (x) => encodeTypedefName);
+    if (expectedTypedefRepresentation == null) {
+      expectedTypedefRepresentation = expectedRepresentation;
+    }
+    Expect.stringEquals(expectedTypedefRepresentation, stringify(expression));
+  }
+
+  String getJsName(Entity cls) {
+    Expression name =
+        typeRepresentation.getJavaScriptClassName(cls, backend.emitter.emitter);
+    return stringify(name);
+  }
+
+  ClosedWorld closedWorld = compiler.backendClosedWorldForTesting;
+  ElementEnvironment elementEnvironment = closedWorld.elementEnvironment;
+  String func = backend.namer.functionTypeTag;
+  String ret = backend.namer.functionTypeReturnTypeTag;
+  String retvoid = strongMode
+      ? '$ret: -1'
+      : '${backend.namer.functionTypeVoidReturnTag}: true';
+  String args = backend.namer.functionTypeRequiredParametersTag;
+  String opt = backend.namer.functionTypeOptionalParametersTag;
+  String named = backend.namer.functionTypeNamedParametersTag;
+  String bounds = backend.namer.functionTypeGenericBoundsTag;
+  String futureOr = backend.namer.futureOrTag;
+  String futureOrType = backend.namer.futureOrTypeTag;
+  String typedefTag = backend.namer.typedefTag;
+
+  ClassEntity List_ = findClass(closedWorld, 'List');
+  TypeVariableType List_E =
+      elementEnvironment.getThisType(List_).typeArguments[0];
+  ClassEntity Map_ = findClass(closedWorld, 'Map');
+  TypeVariableType Map_K =
+      elementEnvironment.getThisType(Map_).typeArguments[0];
+  TypeVariableType Map_V =
+      elementEnvironment.getThisType(Map_).typeArguments[1];
+
+  InterfaceType Object_ = closedWorld.commonElements.objectType;
+  InterfaceType num_ = closedWorld.commonElements.numType;
+  InterfaceType int_ = closedWorld.commonElements.intType;
+  InterfaceType String_ = closedWorld.commonElements.stringType;
+  DartType dynamic_ = closedWorld.commonElements.dynamicType;
+  DartType Typedef1_ = findFieldType(closedWorld, 'Typedef1');
+  DartType Typedef2_ = findFieldType(closedWorld, 'Typedef2');
+  DartType Typedef3_ = findFieldType(closedWorld, 'Typedef3');
+  DartType Typedef4_ = findFieldType(closedWorld, 'Typedef4');
+  DartType Typedef5_ = findFieldType(closedWorld, 'Typedef5');
+  DartType Typedef6_ = findFieldType(closedWorld, 'Typedef6');
+  DartType Typedef7_ = findFieldType(closedWorld, 'Typedef7');
+  DartType Typedef8_ = findFieldType(closedWorld, 'Typedef8');
+  DartType Typedef9_ = findFieldType(closedWorld, 'Typedef9');
+  DartType Typedef10_ = findFieldType(closedWorld, 'Typedef10');
+  DartType Typedef11_ = findFieldType(closedWorld, 'Typedef11');
+
+  String List_rep = getJsName(List_);
+  String List_E_rep = stringify(onVariable(List_E));
+  String Map_rep = getJsName(Map_);
+  String Map_K_rep = stringify(onVariable(Map_K));
+  String Map_V_rep = stringify(onVariable(Map_V));
+
+  String Object_rep = getJsName(Object_.element);
+  String num_rep = getJsName(num_.element);
+  String int_rep = getJsName(int_.element);
+  String String_rep = getJsName(String_.element);
+
+  String getTypedefTag(DartType type) {
+    if (useKernel) {
+      // TODO(johnniwinther): Should/can we preserve typedef names from kernel?
+      return '';
+    }
+    TypedefType typedef = type;
+    return ', $typedefTag: ${getJsName(typedef.element)}';
+  }
+
+  String Typedef1_tag = getTypedefTag(Typedef1_);
+  String Typedef2_tag = getTypedefTag(Typedef2_);
+  String Typedef3_tag = getTypedefTag(Typedef3_);
+  String Typedef4_tag = getTypedefTag(Typedef4_);
+  String Typedef5_tag = getTypedefTag(Typedef5_);
+  String Typedef6_tag = getTypedefTag(Typedef6_);
+  String Typedef7_tag = getTypedefTag(Typedef7_);
+  String Typedef8_tag = getTypedefTag(Typedef8_);
+  String Typedef9_tag = getTypedefTag(Typedef9_);
+  String Typedef10_tag = getTypedefTag(Typedef10_);
+  String Typedef11_tag = getTypedefTag(Typedef11_);
+
+  expect(int_, '$int_rep');
+  expect(String_, '$String_rep');
+  expect(dynamic_, 'null');
+
+  // List<E>
+  expect(elementEnvironment.getThisType(List_), '[$List_rep, $List_E_rep]');
+  // List
+  expect(elementEnvironment.getRawType(List_), '$List_rep');
+  // List<dynamic>
+  expect(instantiate(List_, [dynamic_]), '$List_rep');
+  // List<int>
+  expect(instantiate(List_, [int_]), '[$List_rep, $int_rep]');
+  // List<Typedef1>
+  expect(instantiate(List_, [Typedef1_]), '[$List_rep, {$func: 1, $retvoid}]',
+      '[$List_rep, {$func: 1, $retvoid$Typedef1_tag}]');
+  expect(
+      instantiate(List_, [Typedef2_]),
+      '[$List_rep, {$func: 1, $ret: $int_rep}]',
+      '[$List_rep, {$func: 1, $ret: $int_rep$Typedef2_tag}]');
+  expect(
+      instantiate(List_, [Typedef3_]),
+      '[$List_rep, {$func: 1, $ret: [$List_rep, $int_rep]}]',
+      '[$List_rep, {$func: 1, $ret: [$List_rep, $int_rep]$Typedef3_tag}]');
+  expect(instantiate(List_, [Typedef4_]), '[$List_rep, {$func: 1}]',
+      '[$List_rep, {$func: 1$Typedef4_tag}]');
+  expect(
+      instantiate(List_, [Typedef5_]),
+      '[$List_rep, {$func: 1,'
+      ' $args: [$int_rep, $String_rep]}]',
+      '[$List_rep, {$func: 1,'
+      ' $args: [$int_rep, $String_rep]$Typedef5_tag}]');
+  expect(
+      instantiate(List_, [Typedef6_]),
+      '[$List_rep, {$func: 1,'
+      ' $args: [$int_rep], $opt: [$String_rep]}]',
+      '[$List_rep, {$func: 1,'
+      ' $args: [$int_rep], $opt: [$String_rep]$Typedef6_tag}]');
+  expect(
+      instantiate(List_, [Typedef7_]),
+      '[$List_rep, {$func: 1, $args: '
+      '[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep],,]}]',
+      '[$List_rep, {$func: 1, $args: '
+      '[$int_rep, $String_rep], $opt: [[$List_rep, $int_rep],,]'
+      '$Typedef7_tag}]');
+  expect(
+      instantiate(List_, [Typedef8_]),
+      '[$List_rep, {$func: 1, $args: [$int_rep],'
+      ' $named: {b: $String_rep}}]',
+      '[$List_rep, {$func: 1, $args: [$int_rep],'
+      ' $named: {b: $String_rep}$Typedef8_tag}]');
+  expect(
+      instantiate(List_, [Typedef9_]),
+      '[$List_rep, {$func: 1, '
+      '$args: [$int_rep, $String_rep], $named: '
+      '{c: [$List_rep, $int_rep], d: null}}]',
+      '[$List_rep, {$func: 1, '
+      '$args: [$int_rep, $String_rep], $named: {c: [$List_rep, $int_rep],'
+      ' d: null}$Typedef9_tag}]');
+  expect(
+      instantiate(List_, [Typedef10_]),
+      '[$List_rep, {$func: 1, '
+      '$args: [{$func: 1, $retvoid, '
+      '$args: [$int_rep], $opt: [,]}]}]',
+      '[$List_rep, {$func: 1, '
+      '$args: [{$func: 1, $retvoid, '
+      '$args: [$int_rep], $opt: [,]}]$Typedef10_tag}]');
+  if (!strongMode) {
+    expect(
+        instantiate(List_, [Typedef11_]),
+        '[$List_rep, {$func: 1, $args: [,, [$List_rep,,]]}]',
+        '[$List_rep, {$func: 1, $args: [,, [$List_rep,,]]$Typedef11_tag}]');
+  } else {
+    expect(
+        instantiate(List_, [Typedef11_]),
+        '[$List_rep, {$func: 1, $bounds: [$num_rep, $Object_rep], '
+        '$ret: {$futureOr: 1, $futureOrType: $int_rep}, '
+        '$args: [{$futureOr: 1, $futureOrType: 0}, 1, [$List_rep, -1]]}]');
+  }
+
+  // Map<K,V>
+  expect(elementEnvironment.getThisType(Map_),
+      '[$Map_rep, $Map_K_rep, $Map_V_rep]');
+  // Map
+  expect(elementEnvironment.getRawType(Map_), '$Map_rep');
+  // Map<dynamic,dynamic>
+  expect(instantiate(Map_, [dynamic_, dynamic_]), '$Map_rep');
+  // Map<int,String>
+  expect(
+      instantiate(Map_, [int_, String_]), '[$Map_rep, $int_rep, $String_rep]');
+
+  // void m1() {}
+  expect(findFunctionType(closedWorld, 'm1'), '{$func: 1, $retvoid}');
+
+  // int m2() => 0;
+  expect(findFunctionType(closedWorld, 'm2'), '{$func: 1, $ret: $int_rep}');
+
+  // List<int> m3() => null;
+  expect(findFunctionType(closedWorld, 'm3'),
+      '{$func: 1, $ret: [$List_rep, $int_rep]}');
+
+  // m4() {}
+  expect(findFunctionType(closedWorld, 'm4'), '{$func: 1}');
+
+  // m5(int a, String b) {}
+  expect(findFunctionType(closedWorld, 'm5'),
+      '{$func: 1, $args: [$int_rep, $String_rep]}');
+
+  // m6(int a, [String b]) {}
+  expect(
+      findFunctionType(closedWorld, 'm6'),
+      '{$func: 1, $args: [$int_rep],'
+      ' $opt: [$String_rep]}');
+
+  // m7(int a, String b, [List<int> c, d]) {}
+  expect(
+      findFunctionType(closedWorld, 'm7'),
+      '{$func: 1,'
+      ' $args: [$int_rep, $String_rep],'
+      ' $opt: [[$List_rep, $int_rep],,]}');
+
+  // m8(int a, {String b}) {}
+  expect(
+      findFunctionType(closedWorld, 'm8'),
+      '{$func: 1,'
+      ' $args: [$int_rep], $named: {b: $String_rep}}');
+
+  // m9(int a, String b, {List<int> c, d}) {}
+  expect(
+      findFunctionType(closedWorld, 'm9'),
+      '{$func: 1,'
+      ' $args: [$int_rep, $String_rep],'
+      ' $named: {c: [$List_rep, $int_rep], d: null}}');
+
+  // m10(void f(int a, [b])) {}
+  expect(
+      findFunctionType(closedWorld, 'm10'),
+      '{$func: 1, $args:'
+      ' [{$func: 1,'
+      ' $retvoid, $args: [$int_rep], $opt: [,]}]}');
+
+  // FutureOr<int> m11<T, S>(FutureOr<T> a, S b, List<void> c) {}
+  if (!strongMode) {
+    expect(findFunctionType(closedWorld, 'm11'),
+        '{$func: 1, $args: [,, [$List_rep,,]]}');
+  } else {
+    expect(
+        findFunctionType(closedWorld, 'm11'),
+        '{$func: 1, $bounds: [$num_rep, $Object_rep], '
+        '$ret: {$futureOr: 1, $futureOrType: $int_rep}, '
+        '$args: [{$futureOr: 1, $futureOrType: 0}, 1, [$List_rep, -1]]}');
+  }
 }
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 6a03262..ee2a76a 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -351,3 +351,13 @@
   sb.write(additionalData);
   return sb.toString();
 }
+
+/// Return source code that uses the function types in [dataList].
+String createUses(List<FunctionTypeData> dataList, {String prefix: ''}) {
+  StringBuffer sb = new StringBuffer();
+  for (int index = 0; index < dataList.length; index++) {
+    FunctionTypeData data = dataList[index];
+    sb.writeln('$prefix${data.name};');
+  }
+  return sb.toString();
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index b011ab8..8ef249e 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -95,6 +95,7 @@
 deferred_custom_loader_test: SkipByDesign # Issue 25683
 deferred_fail_and_retry_test: SkipByDesign # Uses eval to simulate failed loading.
 deferred_fail_and_retry_worker_test: SkipByDesign # Uses eval to simulate failed loading.
+js_interop_optional_arg_test: RuntimeError # Issue 31082
 js_interop_test: RuntimeError # Issue 31082
 
 [ $compiler == dart2js && $fast_startup ]
@@ -211,6 +212,7 @@
 
 [ $compiler == dart2js && !$strong ]
 generic_method_dynamic_is_test: RuntimeError # Test against function type variables is only supported in strong mode.
+generic_method_dynamic_type_test: SkipByDesign # Requires strong mode support for function type variables.
 generic_method_static_is_test: RuntimeError # Test against function type variables is only supported in strong mode.
 local_signature_test: RuntimeError # Test against function type variables is only supported in strong mode.
 
diff --git a/tests/compiler/dart2js_extra/generic_method_dynamic_type_test.dart b/tests/compiler/dart2js_extra/generic_method_dynamic_type_test.dart
new file mode 100644
index 0000000..ab7221d
--- /dev/null
+++ b/tests/compiler/dart2js_extra/generic_method_dynamic_type_test.dart
@@ -0,0 +1,25 @@
+// 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 'package:expect/expect.dart';
+
+class C<CT> {
+  foo<FT extends CT>() => CT;
+
+  BT bar<BT extends CT>(BT x) => x;
+  CT map<MT extends CT>(MT x) => x;
+}
+
+main() {
+  dynamic o = new C<num>();
+
+  Expect.equals('<T1 extends num>() => dynamic', o.foo.runtimeType.toString());
+
+  // Instantiations
+  int Function(int) f1 = new C<num>().bar;
+  num Function(int) f2 = new C<num>().map;
+
+  Expect.equals('(int) => int', f1.runtimeType.toString());
+  Expect.equals('(int) => num', f2.runtimeType.toString());
+}
diff --git a/tests/compiler/dart2js_extra/js_interop_optional_arg_test.dart b/tests/compiler/dart2js_extra/js_interop_optional_arg_test.dart
new file mode 100644
index 0000000..4c50389
--- /dev/null
+++ b/tests/compiler/dart2js_extra/js_interop_optional_arg_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+/// Test that optional arguments of js-interop constructors are not passed
+/// explicitly when missing.
+///
+/// This is a regression test for issue 32697
+
+import "package:js/js.dart";
+import "package:expect/expect.dart";
+import "dart:js" as js;
+
+@JS('C')
+class C {
+  external C([a]);
+  external bool get isUndefined;
+}
+
+main() {
+  js.context.callMethod("eval", [
+    """
+  function C(a){
+    this.isUndefined = a === undefined;
+  };
+  """
+  ]);
+
+  Expect.isTrue(new C().isUndefined);
+}
diff --git a/tests/corelib_2/corelib_2.status b/tests/corelib_2/corelib_2.status
index b88cc46..90bd0d6 100644
--- a/tests/corelib_2/corelib_2.status
+++ b/tests/corelib_2/corelib_2.status
@@ -2,7 +2,6 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 iterable_where_type_test: RuntimeError # Disabled.  Issue 32463
-
 maps_test: Skip # Maps class no longer exists
 
 [ $compiler == dart2analyzer ]
@@ -214,8 +213,15 @@
 
 [ $compiler == dart2js && $fasta && $host_checked && $strong ]
 apply3_test: RuntimeError
+bigint_parse_radix_test: RuntimeError
 bigint_test: RuntimeError
 cast_test: RuntimeError
+date_time2_test: RuntimeError
+date_time3_test: RuntimeError
+date_time4_test: RuntimeError
+date_time7_test: RuntimeError
+date_time_parse_test: RuntimeError
+date_time_test: RuntimeError
 dynamic_nosuchmethod_test: RuntimeError
 error_stack_trace1_test: RuntimeError # Issue 12399
 growable_list_test: RuntimeError # Concurrent modifications test always runs
@@ -229,29 +235,66 @@
 iterable_return_type_test/01: RuntimeError # Issue 20085
 iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
 iterable_to_list_test/01: RuntimeError # Issue 26501
+json_map_test: RuntimeError
 list_concurrent_modify_test: RuntimeError # dart2js does not fully implement these
 list_test/01: RuntimeError
 list_test/none: RuntimeError
 list_unmodifiable_test: RuntimeError
+main_test: RuntimeError
 nan_infinity_test/01: RuntimeError
 reg_exp_all_matches_test: RuntimeError
+reg_exp_cache_test: RuntimeError
+reg_exp_first_match_test: RuntimeError
+reg_exp_group_test: RuntimeError
+reg_exp_groups_test: RuntimeError
 reg_exp_start_end_test: RuntimeError
+reg_exp_string_match_test: RuntimeError
+regexp/UC16_test: RuntimeError
+regexp/alternatives_test: RuntimeError
+regexp/assertion_test: RuntimeError
+regexp/bol-with-multiline_test: RuntimeError
+regexp/bol_test: RuntimeError
+regexp/capture-3_test: RuntimeError
 regexp/capture_test: RuntimeError
+regexp/character-match-out-of-order_test: RuntimeError
+regexp/default_arguments_test: RuntimeError
+regexp/dotstar_test: RuntimeError
+regexp/early-acid3-86_test: RuntimeError
 regexp/ecma-regex-examples_test: RuntimeError
+regexp/extended-characters-match_test: RuntimeError
+regexp/find-first-asserted_test: RuntimeError
 regexp/global_test: RuntimeError
 regexp/indexof_test: RuntimeError
+regexp/invalid-range-in-class_test: RuntimeError
 regexp/lastindex_test: RuntimeError
+regexp/look-ahead_test: RuntimeError
+regexp/lookahead_test: RuntimeError
+regexp/loop-capture_test: RuntimeError
+regexp/many-brackets_test: RuntimeError
+regexp/no-extensions_test: RuntimeError
+regexp/non-bmp_test: RuntimeError
+regexp/non-capturing-backtracking_test: RuntimeError
 regexp/non-capturing-groups_test: RuntimeError
+regexp/non-greedy-parentheses_test: RuntimeError
 regexp/parentheses_test: RuntimeError
 regexp/pcre-test-4_test: RuntimeError
+regexp/pcre_test: RuntimeError
+regexp/range-bound-ffff_test: RuntimeError
+regexp/ranges-and-escaped-hyphens_test: RuntimeError
+regexp/regexp_escape_test: RuntimeError
 regexp/regexp_kde_test: RuntimeError
 regexp/regexp_test: RuntimeError
 regexp/regress-regexp-codeflush_test: RuntimeError
+regexp/regress-regexp-construct-result_test: RuntimeError
+regexp/repeat-match-waldemar_test: RuntimeError
+regexp/stack-overflow2_test: RuntimeError
+regexp/stack-overflow_test: RuntimeError
 regexp/standalones_test: RuntimeError
-splay_tree_from_iterable_test: RuntimeError
+regexp/unicode-handling_test: RuntimeError
+regexp/zero-length-alternatives_test: RuntimeError
 string_from_list_test: RuntimeError
 string_fromcharcodes_test: RuntimeError
-string_replace_test: Crash # NoSuchMethodError: The getter 'isDynamic' was called on null.
+string_replace_test: RuntimeError
 string_split_test/checkedstore: RuntimeError # Issue 30548: does not check stores into List<String>
 string_split_test/none: RuntimeError
 string_test: RuntimeError
@@ -262,8 +305,15 @@
 
 [ $compiler == dart2js && $fasta && $minified && $strong ]
 apply3_test: RuntimeError
+bigint_parse_radix_test: RuntimeError
 bigint_test: RuntimeError
 cast_test: RuntimeError
+date_time2_test: RuntimeError
+date_time3_test: RuntimeError
+date_time4_test: RuntimeError
+date_time7_test: RuntimeError
+date_time_parse_test: RuntimeError
+date_time_test: RuntimeError
 dynamic_nosuchmethod_test: RuntimeError
 error_stack_trace1_test: RuntimeError # Issue 12399
 growable_list_test: RuntimeError # Concurrent modifications test always runs
@@ -278,33 +328,70 @@
 iterable_return_type_test/01: RuntimeError # Issue 20085
 iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
 iterable_to_list_test/01: RuntimeError # Issue 26501
+json_map_test: RuntimeError
 list_concurrent_modify_test: RuntimeError # dart2js does not fully implement these
 list_test/01: RuntimeError
 list_test/none: RuntimeError
 list_unmodifiable_test: RuntimeError
+main_test: RuntimeError
 nan_infinity_test/01: RuntimeError
 nsm_invocation_test: RuntimeError # Symbols don't match due to minifiaction.
 reg_exp_all_matches_test: RuntimeError
+reg_exp_cache_test: RuntimeError
+reg_exp_first_match_test: RuntimeError
+reg_exp_group_test: RuntimeError
+reg_exp_groups_test: RuntimeError
 reg_exp_start_end_test: RuntimeError
+reg_exp_string_match_test: RuntimeError
+regexp/UC16_test: RuntimeError
+regexp/alternatives_test: RuntimeError
+regexp/assertion_test: RuntimeError
+regexp/bol-with-multiline_test: RuntimeError
+regexp/bol_test: RuntimeError
+regexp/capture-3_test: RuntimeError
 regexp/capture_test: RuntimeError
+regexp/character-match-out-of-order_test: RuntimeError
+regexp/default_arguments_test: RuntimeError
+regexp/dotstar_test: RuntimeError
+regexp/early-acid3-86_test: RuntimeError
 regexp/ecma-regex-examples_test: RuntimeError
+regexp/extended-characters-match_test: RuntimeError
+regexp/find-first-asserted_test: RuntimeError
 regexp/global_test: RuntimeError
 regexp/indexof_test: RuntimeError
+regexp/invalid-range-in-class_test: RuntimeError
 regexp/lastindex_test: RuntimeError
+regexp/look-ahead_test: RuntimeError
+regexp/lookahead_test: RuntimeError
+regexp/loop-capture_test: RuntimeError
+regexp/many-brackets_test: RuntimeError
+regexp/no-extensions_test: RuntimeError
+regexp/non-bmp_test: RuntimeError
+regexp/non-capturing-backtracking_test: RuntimeError
 regexp/non-capturing-groups_test: RuntimeError
+regexp/non-greedy-parentheses_test: RuntimeError
 regexp/parentheses_test: RuntimeError
 regexp/pcre-test-4_test: RuntimeError
+regexp/pcre_test: RuntimeError
+regexp/range-bound-ffff_test: RuntimeError
+regexp/ranges-and-escaped-hyphens_test: RuntimeError
+regexp/regexp_escape_test: RuntimeError
 regexp/regexp_kde_test: RuntimeError
 regexp/regexp_test: RuntimeError
 regexp/regress-regexp-codeflush_test: RuntimeError
+regexp/regress-regexp-construct-result_test: RuntimeError
+regexp/repeat-match-waldemar_test: RuntimeError
+regexp/stack-overflow2_test: RuntimeError
+regexp/stack-overflow_test: RuntimeError
 regexp/standalones_test: RuntimeError
-splay_tree_from_iterable_test: RuntimeError
+regexp/unicode-handling_test: RuntimeError
+regexp/zero-length-alternatives_test: RuntimeError
 string_from_list_test: RuntimeError
 string_fromcharcodes_test: RuntimeError
+string_replace_test: RuntimeError
 string_split_test/checkedstore: RuntimeError # Issue 30548: does not check stores into List<String>
 string_split_test/none: RuntimeError
 string_test: RuntimeError
-string_replace_test: RuntimeError
 symbol_operator_test/03: RuntimeError
 symbol_operator_test/none: RuntimeError
 symbol_reserved_word_test/03: RuntimeError # Issue 19972, new Symbol('void') should be allowed.
@@ -313,7 +400,6 @@
 uri_test: RuntimeError
 
 [ $compiler == dart2js && $fasta && $strong ]
-null_nosuchmethod_test: RuntimeError # Fails if type checks are skipped.
 shuffle_test: RuntimeError
 
 [ $compiler == dart2js && $fasta && !$strong ]
@@ -462,7 +548,6 @@
 [ $runtime != none && ($compiler == dartdevc || $compiler == dartdevk) ]
 apply2_test: RuntimeError # Issue 29921
 apply3_test: RuntimeError # Issue 29921
-apply_test/01: RuntimeError # Issue 32157
 bigint_test: Pass, Slow
 compare_to2_test: RuntimeError # Issue 30170
 date_time10_test: RuntimeError # Issue 29921
diff --git a/tests/html/custom/element_upgrade_test.html b/tests/html/custom/element_upgrade_test.html
index 3267d7f..9ae03d3 100644
--- a/tests/html/custom/element_upgrade_test.html
+++ b/tests/html/custom/element_upgrade_test.html
@@ -45,7 +45,5 @@
 
   <script type="text/javascript"
       src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  <script type="text/javascript"
-      src="/packages/browser/interop.js"></script>
   %TEST_SCRIPTS%
 </body>
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index e848251..25c60c3 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -328,8 +328,6 @@
 class_literal_test/03: RuntimeError
 class_literal_test/07: RuntimeError
 config_import_test: RuntimeError # not supported by fasta
-const_error_multiply_initialized_test/02: MissingCompileTimeError
-const_error_multiply_initialized_test/04: MissingCompileTimeError
 const_evaluation_test/01: RuntimeError
 const_instance_field_test/01: MissingCompileTimeError
 const_map2_test/00: MissingCompileTimeError
@@ -342,7 +340,7 @@
 constructor3_test: RuntimeError
 constructor5_test: RuntimeError
 constructor6_test: RuntimeError
-constructor_call_as_function_test/01: CompileTimeError # Issue 32517
+constructor_call_as_function_test/01: MissingRuntimeError
 constructor_named_arguments_test/none: RuntimeError
 constructor_redirect1_negative_test: Crash # Issue 30856
 constructor_redirect2_negative_test: Crash # Issue 30856
diff --git a/tests/language/language_kernel.status b/tests/language/language_kernel.status
index 0c2222c..4eb9408 100644
--- a/tests/language/language_kernel.status
+++ b/tests/language/language_kernel.status
@@ -18,14 +18,11 @@
 class_cycle_test/02: MissingCompileTimeError
 class_cycle_test/03: MissingCompileTimeError
 config_import_test: Crash
-const_error_multiply_initialized_test/02: MissingCompileTimeError
-const_error_multiply_initialized_test/04: MissingCompileTimeError
 const_instance_field_test/01: MissingCompileTimeError
 const_map2_test/00: MissingCompileTimeError
 const_map3_test/00: MissingCompileTimeError
 const_switch2_test/01: MissingCompileTimeError
 constants_test/05: MissingCompileTimeError
-constructor_call_as_function_test/01: CompileTimeError # Issue 32517
 constructor_redirect1_negative_test: Fail
 constructor_redirect2_negative_test: Fail
 constructor_redirect_test/01: MissingCompileTimeError
@@ -154,25 +151,18 @@
 compile_time_constant_c_test/02: MissingCompileTimeError
 const_conditional_test/08: MissingCompileTimeError
 const_constructor_nonconst_field_test/01: MissingCompileTimeError
-const_error_multiply_initialized_test/01: MissingCompileTimeError
-const_error_multiply_initialized_test/03: MissingCompileTimeError
 const_native_factory_test/01: MissingCompileTimeError
 const_optional_args_negative_test: Fail
 const_syntax_test/05: MissingCompileTimeError
 const_syntax_test/08: MissingCompileTimeError
-const_syntax_test/09: MissingCompileTimeError
 const_syntax_test/10: MissingCompileTimeError
 constructor3_negative_test: Fail
 constructor_call_wrong_argument_count_negative_test: Fail
-deferred_constraints_constants_test/default_argument2: MissingCompileTimeError
 deopt_inlined_function_lazy_test: CompileTimeError
 duplicate_interface_negative_test: Fail
 export_ambiguous_main_negative_test: Fail
 field3a_negative_test: Fail
 field_method4_negative_test: Fail
-final_syntax_test/09: MissingCompileTimeError
-function_type_parameter2_negative_test: Fail
-function_type_parameter_negative_test: Fail
 guess_cid_test: CompileTimeError
 import_combinators_negative_test: Fail
 instance_call_wrong_argument_count_negative_test: Fail
diff --git a/tests/language_2/assert_assignable_type_test.dart b/tests/language_2/assert_assignable_type_test.dart
index 9721bf2..06b1c8d 100644
--- a/tests/language_2/assert_assignable_type_test.dart
+++ b/tests/language_2/assert_assignable_type_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program to test arithmetic operations.
-// VMOptions=--optimization-counter-threshold=10 --checked --no-background-compilation
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
 
 // This test crashes if we recompute type of AssertAssignableInstr based on its
 // output types. By doing that we would eliminate not only the unnecessary
diff --git a/tests/language_2/call_function_test.dart b/tests/language_2/call_function_test.dart
index 6eae858..49d8b7c 100644
--- a/tests/language_2/call_function_test.dart
+++ b/tests/language_2/call_function_test.dart
@@ -40,4 +40,10 @@
   Expect.equals('Foo42', baz(42));
   Expect.equals('Foo42', foo(42));
   Expect.equals('Foo42', dyn(42));
+
+  var s = (FooType).toString();
+  var minified = s != 'FooType'; // dart2js --minify has minified names.
+  dynamic d = null;
+  Expect.throws(() => d(),
+      (e) => e is NoSuchMethodError && (minified || '$e'.contains('call')));
 }
diff --git a/tests/language_2/call_method_as_cast_test.dart b/tests/language_2/call_method_as_cast_test.dart
index 47a14d9..f0718a3 100644
--- a/tests/language_2/call_method_as_cast_test.dart
+++ b/tests/language_2/call_method_as_cast_test.dart
@@ -27,10 +27,9 @@
   Expect.throwsCastError(() => c as NullToObject); //# 02: ok
   Expect.throwsCastError(() => c as Function); //# 03: ok
 
-  // The same goes for class `D`, except that it is a subtype of `Function`
-  // because it is explicitly declared to be so.
+  // The same goes for class `D`: `implements Function` is ignored in Dart 2.
   D d = new D();
   Expect.throwsCastError(() => d as BToB); //# 04: ok
   Expect.throwsCastError(() => d as NullToObject); //# 05: ok
-  Expect.identical(d as Function, d); //# 06: ok
+  Expect.throwsCastError(() => d as Function); //# 06: ok
 }
diff --git a/tests/language_2/call_method_implicit_invoke_local_test.dart b/tests/language_2/call_method_implicit_invoke_local_test.dart
index 02db7ea..5528311 100644
--- a/tests/language_2/call_method_implicit_invoke_local_test.dart
+++ b/tests/language_2/call_method_implicit_invoke_local_test.dart
@@ -26,4 +26,7 @@
   dynamic d2 = c2;
   // Implicitly invokes d2.call(1)
   Expect.equals(d2(1), 2); //# 04: ok
+  // Cannot invoke with the wrong signature.
+  c2(); //# 05: compile-time error
+  c2(3, 4); //# 05: compile-time error
 }
diff --git a/tests/language_2/call_method_implicit_tear_off_implements_function_test.dart b/tests/language_2/call_method_implicit_tear_off_implements_function_test.dart
index da4e1dc..610baab 100644
--- a/tests/language_2/call_method_implicit_tear_off_implements_function_test.dart
+++ b/tests/language_2/call_method_implicit_tear_off_implements_function_test.dart
@@ -47,11 +47,18 @@
 }
 
 void check5(Function f) {
-  Expect.identical(c, f);
+  Expect.isFalse(identical(c, f));
+  Expect.equals(c.call, f);
+  B b = new B();
+  Expect.identical(f(b), b);
 }
 
 void check6(FutureOr<Function> f) {
-  Expect.identical(c, f);
+  Expect.isFalse(identical(c, f));
+  Expect.equals(c.call, f);
+  B b = new B();
+  Function f2 = f;
+  Expect.identical(f2(b), b);
 }
 
 void check7(C x) {
@@ -84,9 +91,9 @@
   check2(c); //# 02: ok
   check3(c); //# 03: ok
   check4(c); //# 04: ok
-  // Does not tear off c.call
   check5(c); //# 05: ok
   check6(c); //# 06: ok
+  // Does not tear off c.call
   check7(c); //# 07: ok
   check8(c); //# 08: ok
   check9(c); //# 09: ok
diff --git a/tests/language_2/call_method_is_check_test.dart b/tests/language_2/call_method_is_check_test.dart
index 0b8f534..9c705a3 100644
--- a/tests/language_2/call_method_is_check_test.dart
+++ b/tests/language_2/call_method_is_check_test.dart
@@ -27,10 +27,9 @@
   Expect.isFalse(c is NullToObject); //# 02: ok
   Expect.isFalse(c is Function); //# 03: ok
 
-  // The same goes for class `D`, except that it is a subtype of `Function`
-  // because it is explicitly declared to be so.
+  // The same goes for class `D`: `implements Function` is ignored in Dart 2.
   D d = new D();
   Expect.isFalse(d is BToB); //# 04: ok
   Expect.isFalse(d is NullToObject); //# 05: ok
-  Expect.isTrue(d is Function); //# 06: ok
+  Expect.isFalse(d is Function); //# 06: ok
 }
diff --git a/tests/language_2/call_method_must_not_be_field_test.dart b/tests/language_2/call_method_must_not_be_field_test.dart
index bc6209d..05cbce9 100644
--- a/tests/language_2/call_method_must_not_be_field_test.dart
+++ b/tests/language_2/call_method_must_not_be_field_test.dart
@@ -25,4 +25,5 @@
   c.call(); //# 04: ok
   void Function() f = c.call; //# 05: ok
   d.call(); //# 06: ok
+  (d.call)(); //# 07: ok
 }
diff --git a/tests/language_2/call_with_no_such_method_test.dart b/tests/language_2/call_with_no_such_method_test.dart
index 53792bb..95c27d5 100644
--- a/tests/language_2/call_with_no_such_method_test.dart
+++ b/tests/language_2/call_with_no_such_method_test.dart
@@ -5,7 +5,9 @@
 import "package:expect/expect.dart";
 
 class F {
-  call() => null;
+  final int value;
+  F(this.value);
+  call() => value;
   noSuchMethod(Invocation i) {
     if (i.memberName == #call && i.isMethod) {
       return i.positionalArguments[0];
@@ -15,6 +17,14 @@
 }
 
 main() {
-  var result = Function.apply(new F(), ['a', 'b', 'c', 'd']);
+  F f = new F(42);
+  // Tears off f.call, fails with nSM (wrong number of arguments).
+  Expect.throwsNoSuchMethodError(() => Function.apply(f, ['a', 'b', 'c', 'd']));
+
+  dynamic d = f;
+  var result = d('a', 'b', 'c', 'd'); // calls F.noSuchMethod
   Expect.equals('a', result);
+
+  // Tears off f.call, call succeeds
+  Expect.equals(42, Function.apply(f, []));
 }
diff --git a/tests/language_2/covariant_subtyping_test.dart b/tests/language_2/covariant_subtyping_test.dart
index e0ff19b..b083c3d 100644
--- a/tests/language_2/covariant_subtyping_test.dart
+++ b/tests/language_2/covariant_subtyping_test.dart
@@ -202,7 +202,8 @@
   ClassF<int> cc = new ClassF<int>();
   ClassF<Object> ca = cc; // An upcast, per covariance.
   F<Object> f = ca;
-  Expect.equals(f.runtimeType.toString(), 'ClassF<int>');
+  void f2(Object x) {}
+  Expect.equals(f.runtimeType, f2.runtimeType);
   Expect.throwsTypeError(() => f(new Object()));
 }
 
diff --git a/tests/language_2/cyclic_type_test.dart b/tests/language_2/cyclic_type_test.dart
index 216f1eb..ada6b6e 100644
--- a/tests/language_2/cyclic_type_test.dart
+++ b/tests/language_2/cyclic_type_test.dart
@@ -35,11 +35,11 @@
 
   var d;
   d = new Derived(); // //# 00: continued
-  Expect.equals("Derived", d.t.toString()); // //# 00: continued
+  Expect.equals("Derived<dynamic>", d.t.toString()); // //# 00: continued
   d = new Derived<bool>(); // //# 00: continued
   Expect.equals("Derived<bool>", d.t.toString()); // //# 00: continued
   d = new Derived<Derived>(); // //# 00: continued
-  Expect.equals("Derived<Derived>", d.t.toString()); // //# 00: continued
+  Expect.equals("Derived<Derived<dynamic>>", d.t.toString()); // //# 00: continued
 
   d = new Derived(); // //# 01: continued
 
@@ -50,23 +50,23 @@
   Expect.equals("Derived<Derived<int>>", d.t.toString()); // //# 01: continued
 
   d = new Derived(); // //# 02: continued
-  Expect.equals("Derived<Derived>", d.t.toString()); // //# 02: continued
+  Expect.equals("Derived<Derived<dynamic>>", d.t.toString()); // //# 02: continued
   d = new Derived<bool>(); // //# 02: continued
   Expect.equals("Derived<Derived<bool>>", d.t.toString()); // //# 02: continued
   d = new Derived<Derived>(); // //# 02: continued
-  Expect.equals("Derived<Derived<Derived>>", d.t.toString()); // //# 02: continued
+  Expect.equals("Derived<Derived<Derived<dynamic>>>", d.t.toString()); // //# 02: continued
 
   d = new Derived1(); // //# 03: continued
-  Expect.equals("Derived2", d.t.toString()); // //# 03: continued
+  Expect.equals("Derived2<dynamic>", d.t.toString()); // //# 03: continued
   d = new Derived2(); // //# 03: continued
-  Expect.equals("Derived1", d.t.toString()); // //# 03: continued
+  Expect.equals("Derived1<dynamic>", d.t.toString()); // //# 03: continued
   d = new Derived2<Derived1<int>>(); // //# 03: continued
   Expect.equals("Derived1<Derived1<int>>", d.t.toString()); // //# 03: continued
 
   d = new Derived1(); // //# 04: continued
-  Expect.equals("Derived2", d.t.toString()); // //# 04: continued
+  Expect.equals("Derived2<dynamic>", d.t.toString()); // //# 04: continued
   d = new Derived2(); // //# 04: continued
-  Expect.equals("Derived1<Derived2>", d.t.toString()); // //# 04: continued
+  Expect.equals("Derived1<Derived2<dynamic>>", d.t.toString()); // //# 04: continued
   d = new Derived2<Derived1<int>>(); // //# 04: continued
   Expect.equals("Derived1<Derived2<Derived1<int>>>", d.t.toString()); // //# 04: continued
 }
diff --git a/tests/language_2/f_bounded_quantification4_test.dart b/tests/language_2/f_bounded_quantification4_test.dart
index 79bd737..d48a31d 100644
--- a/tests/language_2/f_bounded_quantification4_test.dart
+++ b/tests/language_2/f_bounded_quantification4_test.dart
@@ -11,5 +11,5 @@
 class B<T> extends A {}
 
 main() {
-  Expect.equals("B<B>", new B<B>().runtimeType.toString());
+  Expect.equals("B<B<dynamic>>", new B<B>().runtimeType.toString());
 }
diff --git a/tests/language_2/function_apply_generic_test.dart b/tests/language_2/function_apply_generic_test.dart
new file mode 100644
index 0000000..88d4857
--- /dev/null
+++ b/tests/language_2/function_apply_generic_test.dart
@@ -0,0 +1,62 @@
+// 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 "package:expect/expect.dart";
+
+List<T> staticFn<T>(
+    [T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10]) {
+  return <T>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+}
+
+class C<CT> {
+  List<T> memberFn<T>(
+      [T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10]) {
+    return <T>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+  }
+
+  // Intercepted, e.g. on JSArray.
+  List<T> map<T>(
+      [T a1, T a2, T a3, T a4, T a5, T a6, T a7, T a8, T a9, T a10]) {
+    return <T>[a1, a2, a3, a4, a5, a6, a7, a8, a9, a10];
+  }
+}
+
+check(a, b) {
+  print('a: $a\nb: $b');
+  Expect.equals(a.toString(), b.toString());
+}
+
+main() {
+  check('[1, 2, 3, null, null, null, null, null, null, null]',
+      Function.apply(staticFn, [1, 2, 3]));
+
+  check('[1, 2, 3, 4, null, null, null, null, null, null]',
+      Function.apply(staticFn, [1, 2, 3, 4]));
+
+  check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+      Function.apply(staticFn, [1, 2, 3, 4, 5, 6, 7]));
+
+  var o = new C<num>();
+  dynamic memberFn1 = o.map;
+
+  check('[1, 2, 3, null, null, null, null, null, null, null]',
+      Function.apply(memberFn1, [1, 2, 3]));
+
+  check('[1, 2, 3, 4, null, null, null, null, null, null]',
+      Function.apply(memberFn1, [1, 2, 3, 4]));
+
+  check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+      Function.apply(memberFn1, [1, 2, 3, 4, 5, 6, 7]));
+
+  dynamic memberFn2 = o.memberFn;
+
+  check('[1, 2, 3, null, null, null, null, null, null, null]',
+      Function.apply(memberFn2, [1, 2, 3]));
+
+  check('[1, 2, 3, 4, null, null, null, null, null, null]',
+      Function.apply(memberFn2, [1, 2, 3, 4]));
+
+  check('[1, 2, 3, 4, 5, 6, 7, null, null, null]',
+      Function.apply(memberFn2, [1, 2, 3, 4, 5, 6, 7]));
+}
diff --git a/tests/language_2/function_subtype3_test.dart b/tests/language_2/function_subtype3_test.dart
index b2190d6..09bc65f 100644
--- a/tests/language_2/function_subtype3_test.dart
+++ b/tests/language_2/function_subtype3_test.dart
@@ -15,16 +15,37 @@
   testInt() => new FunctionLike<int>() is T;
 }
 
+class Bar<T> {
+  testString() {
+    Function f = new FunctionLike<String>();
+    return f is T;
+  }
+
+  testInt() {
+    Function f = new FunctionLike<int>();
+    return f is T;
+  }
+}
+
 typedef String ReturnString(Object arg);
 typedef int ReturnInt(Object arg);
 
 main() {
-  var stringFoo = new Foo<ReturnString>();
-  var intFoo = new Foo<ReturnInt>();
+  {
+    var stringFoo = new Foo<ReturnString>();
+    var intFoo = new Foo<ReturnInt>();
+    Expect.isFalse(stringFoo.testString());
+    Expect.isFalse(stringFoo.testInt());
+    Expect.isFalse(intFoo.testString());
+    Expect.isFalse(intFoo.testInt());
+  }
 
-  Expect.isTrue(stringFoo.testString());
-  Expect.isFalse(stringFoo.testInt());
-
-  Expect.isFalse(intFoo.testString());
-  Expect.isTrue(intFoo.testInt());
+  {
+    var stringBar = new Bar<ReturnString>();
+    var intBar = new Bar<ReturnInt>();
+    Expect.isTrue(stringBar.testString());
+    Expect.isFalse(stringBar.testInt());
+    Expect.isFalse(intBar.testString());
+    Expect.isTrue(intBar.testInt());
+  }
 }
diff --git a/tests/language_2/function_subtype_call0_test.dart b/tests/language_2/function_subtype_call0_test.dart
index d862683..bacced1 100644
--- a/tests/language_2/function_subtype_call0_test.dart
+++ b/tests/language_2/function_subtype_call0_test.dart
@@ -25,18 +25,36 @@
 }
 
 main() {
-  Expect.isTrue(new C1() is Foo, 'new C1() is Foo');
-  Expect.isTrue(new C1() is Bar, 'new C1() is Bar');
-  Expect.isFalse(new C1() is Baz, 'new C1() is Baz');
-  Expect.isTrue(new C1() is Boz, 'new C1() is Boz');
+  Function c1 = new C1(); // implicit tearoff of `call`
+  Expect.isTrue(c1 is Foo, 'c1 is Foo');
+  Expect.isTrue(c1 is Bar, 'c1 is Bar');
+  Expect.isFalse(c1 is Baz, 'c1 is Baz');
+  Expect.isTrue(c1 is Boz, 'c1 is Boz');
+  Expect.isFalse(c1 is C1, 'c1 is C1');
 
-  Expect.isFalse(new C2() is Foo, 'new C2() is Foo');
-  Expect.isFalse(new C2() is Bar, 'new C2() is Bar');
-  Expect.isTrue(new C2() is Baz, 'new C2() is Baz');
-  Expect.isTrue(new C2() is Boz, 'new C2() is Boz');
+  Function c2 = new C2(); // implicit tearoff of `call`
+  Expect.isFalse(c2 is Foo, 'c2 is Foo');
+  Expect.isFalse(c2 is Bar, 'c2 is Bar');
+  Expect.isTrue(c2 is Baz, 'c2 is Baz');
+  Expect.isTrue(c2 is Boz, 'c2 is Boz');
+  Expect.isFalse(c2 is C2, 'c2 is C2');
 
-  Expect.isFalse(new C3() is Foo, 'new C3() is Foo');
-  Expect.isFalse(new C3() is Bar, 'new C3() is Bar');
-  Expect.isFalse(new C3() is Baz, 'new C3() is Baz');
-  Expect.isTrue(new C3() is Boz, 'new C3() is Boz');
+  Function c3 = new C3(); // implicit tearoff of `call`
+  Expect.isFalse(c3 is Foo, 'c3 is Foo');
+  Expect.isFalse(c3 is Bar, 'c3 is Bar');
+  Expect.isFalse(c3 is Baz, 'c3 is Baz');
+  Expect.isTrue(c3 is Boz, 'c3 is Boz');
+  Expect.isFalse(c3 is C3, 'c3 is C3');
+
+  expectIsNotFunction(new C1());
+  expectIsNotFunction(new C2());
+  expectIsNotFunction(new C3());
+}
+
+expectIsNotFunction(Object obj) {
+  Expect.isFalse(obj is Function, '$obj should not be a Function');
+  Expect.isFalse(obj is Foo, '$obj should not be a Foo');
+  Expect.isFalse(obj is Bar, '$obj should not be a Bar');
+  Expect.isFalse(obj is Baz, '$obj should not be a Baz');
+  Expect.isFalse(obj is Boz, '$obj should not be a Boz');
 }
diff --git a/tests/language_2/function_subtype_call1_test.dart b/tests/language_2/function_subtype_call1_test.dart
index 07daa9b..179f9f0 100644
--- a/tests/language_2/function_subtype_call1_test.dart
+++ b/tests/language_2/function_subtype_call1_test.dart
@@ -21,33 +21,39 @@
 }
 
 main() {
-  Expect.isTrue(new C1<bool>() is Foo, 'new C1<bool>() is Foo');
-  Expect.isTrue(new C1<bool>() is Bar, 'new C1<bool>() is Bar');
-  Expect.isFalse(new C1<bool>() is Baz, 'new C1<bool>() is Baz');
-  Expect.isTrue(new C1<bool>() is Boz, 'new C1<bool>() is Boz');
+  Function c1_bool = new C1<bool>(); // implicit tearoff of `call`
+  Expect.isTrue(c1_bool is Foo, 'c1_bool is Foo');
+  Expect.isTrue(c1_bool is Bar, 'c1_bool is Bar');
+  Expect.isFalse(c1_bool is Baz, 'c1_bool is Baz');
+  Expect.isTrue(c1_bool is Boz, 'c1_bool is Boz');
 
-  Expect.isTrue(new C1<int>() is Foo, 'new C1<int>() is Foo');
-  Expect.isTrue(new C1<int>() is Bar, 'new C1<int>() is Bar');
-  Expect.isFalse(new C1<int>() is Baz, 'new C1<int>() is Baz');
-  Expect.isTrue(new C1<int>() is Boz, 'new C1<int>() is Boz');
+  Function c1_int = new C1<int>(); // implicit tearoff of `call`
+  Expect.isTrue(c1_int is Foo, 'c1_int is Foo');
+  Expect.isTrue(c1_int is Bar, 'c1_int is Bar');
+  Expect.isFalse(c1_int is Baz, 'c1_int is Baz');
+  Expect.isTrue(c1_int is Boz, 'c1_int is Boz');
 
-  Expect.isTrue(new C1() is Foo, 'new C1() is Foo');
-  Expect.isTrue(new C1() is Bar, 'new C1() is Bar');
-  Expect.isFalse(new C1() is Baz, 'new C1() is Baz');
-  Expect.isTrue(new C1() is Boz, 'new C1() is Boz');
+  Function c1 = new C1(); // implicit tearoff of `call`
+  Expect.isTrue(c1 is Foo, 'c1 is Foo');
+  Expect.isTrue(c1 is Bar, 'c1 is Bar');
+  Expect.isFalse(c1 is Baz, 'c1 is Baz');
+  Expect.isTrue(c1 is Boz, 'c1 is Boz');
 
-  Expect.isFalse(new C2<bool>() is Foo, 'new C2<bool>() is Foo');
-  Expect.isFalse(new C2<bool>() is Bar, 'new C2<bool>() is Bar');
-  Expect.isTrue(new C2<bool>() is Baz, 'new C2<bool>() is Baz');
-  Expect.isTrue(new C2<bool>() is Boz, 'new C2<bool>() is Boz');
+  Function c2_bool = new C2<bool>(); // implicit tearoff of `call`
+  Expect.isFalse(c2_bool is Foo, 'c2_bool is Foo');
+  Expect.isFalse(c2_bool is Bar, 'c2_bool is Bar');
+  Expect.isTrue(c2_bool is Baz, 'c2_bool is Baz');
+  Expect.isTrue(c2_bool is Boz, 'c2_bool is Boz');
 
-  Expect.isFalse(new C2<int>() is Foo, 'new C2<int>() is Foo');
-  Expect.isFalse(new C2<int>() is Bar, 'new C2<int>() is Bar');
-  Expect.isTrue(new C2<int>() is Baz, 'new C2<int>() is Baz');
-  Expect.isTrue(new C2<int>() is Boz, 'new C2<int>() is Boz');
+  Function c2_int = new C2<int>(); // implicit tearoff of `call`
+  Expect.isFalse(c2_int is Foo, 'c2_int is Foo');
+  Expect.isFalse(c2_int is Bar, 'c2_int is Bar');
+  Expect.isTrue(c2_int is Baz, 'c2_int is Baz');
+  Expect.isTrue(c2_int is Boz, 'c2_int is Boz');
 
-  Expect.isFalse(new C2() is Foo, 'new C2() is Foo');
-  Expect.isFalse(new C2() is Bar, 'new C2() is Bar');
-  Expect.isTrue(new C2() is Baz, 'new C2() is Baz');
-  Expect.isTrue(new C2() is Boz, 'new C2() is Boz');
+  Function c2 = new C2(); // implicit tearoff of `call`
+  Expect.isFalse(c2 is Foo, 'c2 is Foo');
+  Expect.isFalse(c2 is Bar, 'c2 is Bar');
+  Expect.isTrue(c2 is Baz, 'c2 is Baz');
+  Expect.isTrue(c2 is Boz, 'c2 is Boz');
 }
diff --git a/tests/language_2/function_subtype_call2_test.dart b/tests/language_2/function_subtype_call2_test.dart
index 4c211f3..ed16fe7 100644
--- a/tests/language_2/function_subtype_call2_test.dart
+++ b/tests/language_2/function_subtype_call2_test.dart
@@ -25,36 +25,39 @@
 class D2<S, T> extends C2<T> {}
 
 main() {
-  Expect.isTrue(new D1<String, bool>() is Foo, 'new D1<String, bool>() is Foo');
-  Expect.isTrue(new D1<String, bool>() is Bar, 'new D1<String, bool>() is Bar');
-  Expect.isFalse(
-      new D1<String, bool>() is Baz, 'new D1<String, bool>() is Baz');
-  Expect.isTrue(new D1<String, bool>() is Boz, 'new D1<String, bool>() is Boz');
+  Function d1_String_bool = new D1<String, bool>();
+  Expect.isTrue(d1_String_bool is Foo, 'd1_String_bool is Foo');
+  Expect.isTrue(d1_String_bool is Bar, 'd1_String_bool is Bar');
+  Expect.isFalse(d1_String_bool is Baz, 'd1_String_bool is Baz');
+  Expect.isTrue(d1_String_bool is Boz, 'd1_String_bool is Boz');
 
-  Expect.isTrue(new D1<bool, int>() is Foo, 'new D1<bool, int>() is Foo');
-  Expect.isTrue(new D1<bool, int>() is Bar, 'new D1<bool, int>() is Bar');
-  Expect.isFalse(new D1<bool, int>() is Baz, 'new D1<bool, int>() is Baz');
-  Expect.isTrue(new D1<bool, int>() is Boz, 'new D1<bool, int>() is Boz');
+  Function d1_bool_int = new D1<bool, int>();
+  Expect.isTrue(d1_bool_int is Foo, 'd1_bool_int is Foo');
+  Expect.isTrue(d1_bool_int is Bar, 'd1_bool_int is Bar');
+  Expect.isFalse(d1_bool_int is Baz, 'd1_bool_int is Baz');
+  Expect.isTrue(d1_bool_int is Boz, 'd1_bool_int is Boz');
 
-  Expect.isTrue(new D1() is Foo, 'new D1() is Foo');
-  Expect.isTrue(new D1() is Bar, 'new D1() is Bar');
-  Expect.isFalse(new D1() is Baz, 'new D1() is Baz');
-  Expect.isTrue(new D1() is Boz, 'new D1() is Boz');
+  Function d1 = new D1();
+  Expect.isTrue(d1 is Foo, 'd1 is Foo');
+  Expect.isTrue(d1 is Bar, 'd1 is Bar');
+  Expect.isFalse(d1 is Baz, 'd1 is Baz');
+  Expect.isTrue(d1 is Boz, 'd1 is Boz');
 
-  Expect.isFalse(
-      new D2<String, bool>() is Foo, 'new D2<String, bool>() is Foo');
-  Expect.isFalse(
-      new D2<String, bool>() is Bar, 'new D2<String, bool>() is Bar');
-  Expect.isTrue(new D2<String, bool>() is Baz, 'new D2<String, bool>() is Baz');
-  Expect.isTrue(new D2<String, bool>() is Boz, 'new D2<String, bool>() is Boz');
+  Function d2_String_bool = new D2<String, bool>();
+  Expect.isFalse(d2_String_bool is Foo, 'd2_String_bool is Foo');
+  Expect.isFalse(d2_String_bool is Bar, 'd2_String_bool is Bar');
+  Expect.isTrue(d2_String_bool is Baz, 'd2_String_bool is Baz');
+  Expect.isTrue(d2_String_bool is Boz, 'd2_String_bool is Boz');
 
-  Expect.isFalse(new D2<bool, int>() is Foo, 'new D2<bool, int>() is Foo');
-  Expect.isFalse(new D2<bool, int>() is Bar, 'new D2<bool, int>() is Bar');
-  Expect.isTrue(new D2<bool, int>() is Baz, 'new D2<bool, int>() is Baz');
-  Expect.isTrue(new D2<bool, int>() is Boz, 'new D2<bool, int>() is Boz');
+  Function d2_bool_int = new D2<bool, int>();
+  Expect.isFalse(d2_bool_int is Foo, 'd2_bool_int is Foo');
+  Expect.isFalse(d2_bool_int is Bar, 'd2_bool_int is Bar');
+  Expect.isTrue(d2_bool_int is Baz, 'd2_bool_int is Baz');
+  Expect.isTrue(d2_bool_int is Boz, 'd2_bool_int is Boz');
 
-  Expect.isFalse(new D2() is Foo, 'new D2() is Foo');
-  Expect.isFalse(new D2() is Bar, 'new D2() is Bar');
-  Expect.isTrue(new D2() is Baz, 'new D2() is Baz');
-  Expect.isTrue(new D2() is Boz, 'new D2() is Boz');
+  Function d2 = new D2();
+  Expect.isFalse(d2 is Foo, 'd2 is Foo');
+  Expect.isFalse(d2 is Bar, 'd2 is Bar');
+  Expect.isTrue(d2 is Baz, 'd2 is Baz');
+  Expect.isTrue(d2 is Boz, 'd2 is Boz');
 }
diff --git a/tests/language_2/generic_test.dart b/tests/language_2/generic_test.dart
index 0b00d05..16742d5 100644
--- a/tests/language_2/generic_test.dart
+++ b/tests/language_2/generic_test.dart
@@ -1,7 +1,6 @@
 // Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
-// VMOptions=--checked
 
 /// Dart test program testing generic type allocations and generic type tests.
 import "package:expect/expect.dart";
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index c0b565c..7294e48 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -8,7 +8,6 @@
 abstract_override_adds_optional_args_concrete_test: MissingCompileTimeError # Issue #30568
 abstract_override_adds_optional_args_supercall_test: MissingCompileTimeError # Issue #30568
 bad_initializer2_negative_test: Fail # Issue 14880
-black_listed_test/none: Fail # Issue 14228
 built_in_identifier_prefix_test: CompileTimeError
 built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Issue 28813
 cascade_test/none: Fail # Issue 11577
@@ -1144,9 +1143,6 @@
 accessor_conflict_import_prefixed_test: CompileTimeError # Issue 25626
 accessor_conflict_import_test: CompileTimeError # Issue 25626
 additional_interface_adds_optional_args_test: CompileTimeError # Issue #30568
-call_method_implicit_tear_off_assignable_test: CompileTimeError # Issue 32426
-call_method_override_test/01: MissingCompileTimeError
-call_method_override_test/02: MissingCompileTimeError
 cascaded_forwarding_stubs_test: CompileTimeError
 config_import_corelib_test: CompileTimeError
 conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Crashes or times out
@@ -1251,7 +1247,6 @@
 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_promotion_functions_test/01: Pass
 type_promotion_functions_test/05: Pass
 type_promotion_functions_test/06: Pass
@@ -1283,6 +1278,7 @@
 async_congruence_method_test/01: MissingCompileTimeError
 async_congruence_unnamed_test/01: MissingCompileTimeError
 async_congruence_unnamed_test/02: MissingCompileTimeError
+black_listed_test/none: Fail # Issue 14228
 built_in_identifier_type_annotation_test/35: MissingCompileTimeError # Issue 28813
 built_in_identifier_type_annotation_test/36: MissingCompileTimeError # Issue 28813
 built_in_identifier_type_annotation_test/37: MissingCompileTimeError # Issue 28813
@@ -1303,6 +1299,7 @@
 built_in_identifier_type_annotation_test/72: MissingCompileTimeError # Issue 28813
 built_in_identifier_type_annotation_test/78: MissingCompileTimeError # Issue 28813
 built_in_identifier_type_annotation_test/81: MissingCompileTimeError # Issue 28813
+call_method_implicit_invoke_local_test/05: MissingCompileTimeError
 call_method_implicit_tear_off_assignable_test: StaticWarning
 call_method_implicit_tear_off_implements_function_test/03: StaticWarning
 call_method_implicit_tear_off_test/03: StaticWarning
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index a8eb7cf..0c92c91 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -63,7 +63,6 @@
 regress_23996_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
 
 [ $compiler == dart2js && $runtime != none ]
-covariant_subtyping_with_substitution_test: RuntimeError
 covariant_tear_off_type_test: RuntimeError
 
 [ $compiler == dart2js && $runtime != none && $checked ]
@@ -549,18 +548,6 @@
 covariance_field_test/03: RuntimeError
 covariance_field_test/04: RuntimeError
 covariance_field_test/05: RuntimeError
-covariance_method_test/01: RuntimeError
-covariance_method_test/02: RuntimeError
-covariance_method_test/03: RuntimeError
-covariance_method_test/04: RuntimeError
-covariance_method_test/05: RuntimeError
-covariance_method_test/06: RuntimeError
-covariance_setter_test/01: RuntimeError
-covariance_setter_test/02: RuntimeError
-covariance_setter_test/03: RuntimeError
-covariance_setter_test/04: RuntimeError
-covariance_setter_test/05: RuntimeError
-covariance_setter_test/06: RuntimeError
 recursive_mixin_test: RuntimeError # no check without --checked
 
 [ $compiler == dart2js && !$checked && !$enable_asserts ]
@@ -569,28 +556,12 @@
 [ $compiler == dart2js && !$checked && $fasta ]
 bool_check_test: RuntimeError
 bool_condition_check_test: RuntimeError
-bug31436_test: RuntimeError
-cascaded_forwarding_stubs_generic_test: RuntimeError
-cascaded_forwarding_stubs_test: RuntimeError
-constructor_call_as_function_test: CompileTimeError # Issue 32517
-forwarding_semi_stub_test: RuntimeError
 forwarding_stub_tearoff_generic_test: RuntimeError
 forwarding_stub_tearoff_test: RuntimeError
-implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_composite_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_prefix_constructor_named_test: CompileTimeError # Issue 32517
 issue31596_implement_covariant_test: RuntimeError
 issue31596_super_test/02: MissingCompileTimeError
 issue31596_super_test/04: MissingCompileTimeError
 issue31596_super_test/05: RuntimeError
-issue31596_tearoff_test: RuntimeError
 issue31596_test: RuntimeError
 nsm5_test: MissingCompileTimeError
 override_inheritance_no_such_method_test/05: MissingCompileTimeError
@@ -1028,10 +999,14 @@
 typevariable_substitution2_test/02: RuntimeError
 
 [ $compiler == dart2js && $fasta ]
+call_method_as_cast_test/06: RuntimeError
 call_method_function_typed_value_test/02: RuntimeError
 call_method_function_typed_value_test/04: RuntimeError
 call_method_function_typed_value_test/06: RuntimeError
 call_method_function_typed_value_test/08: RuntimeError
+call_method_implicit_tear_off_implements_function_test/05: RuntimeError
+call_method_implicit_tear_off_implements_function_test/06: RuntimeError
+call_method_is_check_test/06: RuntimeError
 call_method_must_not_be_field_test/03: RuntimeError # Issue 32155
 call_method_must_not_be_getter_test/03: RuntimeError # Issue 32155
 call_with_no_such_method_test: RuntimeError
@@ -1094,6 +1069,7 @@
 async_star_await_pauses_test: RuntimeError
 async_star_cancel_while_paused_test: Crash # 'file:*/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart': Failed assertion: line 208 pos 18: '!(_useKernel && _strongMode && !_disableRtiOptimization) ||
 async_star_regression_2238_test: RuntimeError
+async_star_regression_23116_test: RuntimeError
 async_star_stream_take_test: RuntimeError
 async_star_test/01: RuntimeError
 async_star_test/02: RuntimeError
@@ -1111,6 +1087,10 @@
 bit_operations_test: RuntimeError
 branch_canonicalization_test: RuntimeError
 branches_test: Crash # 'package:front_end/src/fasta/kernel/kernel_shadow_ast.dart': Failed assertion: line 441 pos 16: 'identical(combiner.arguments.positional[0], rhs)': is not true.
+call_method_implicit_tear_off_implements_function_test/02: RuntimeError
+call_method_implicit_tear_off_implements_function_test/04: RuntimeError
+call_method_implicit_tear_off_test/02: RuntimeError
+call_method_implicit_tear_off_test/04: RuntimeError
 call_non_method_field_test/01: MissingCompileTimeError
 call_non_method_field_test/02: MissingCompileTimeError
 canonical_const2_test: RuntimeError, OK # non JS number semantics
@@ -1170,17 +1150,14 @@
 covariance_type_parameter_test/01: RuntimeError
 covariance_type_parameter_test/02: RuntimeError
 covariance_type_parameter_test/03: RuntimeError
-covariant_override/runtime_check_test: RuntimeError
 covariant_override/tear_off_type_test: RuntimeError
-covariant_subtyping_tearoff1_test: RuntimeError
-covariant_subtyping_tearoff2_test: RuntimeError
-covariant_subtyping_tearoff3_test: RuntimeError
 covariant_subtyping_test: CompileTimeError
-covariant_subtyping_unsafe_call1_test: RuntimeError
-covariant_subtyping_unsafe_call2_test: RuntimeError
-covariant_subtyping_unsafe_call3_test: RuntimeError
 ct_const_test: CompileTimeError
 cyclic_constructor_test/01: Crash # Issue 30856
+cyclic_type_test/00: RuntimeError
+cyclic_type_test/02: RuntimeError
+cyclic_type_test/03: RuntimeError
+cyclic_type_test/04: RuntimeError
 cyclic_type_variable_test/01: MissingCompileTimeError
 cyclic_type_variable_test/02: MissingCompileTimeError
 cyclic_type_variable_test/03: MissingCompileTimeError
@@ -1238,6 +1215,7 @@
 external_test/21: CompileTimeError
 external_test/24: CompileTimeError
 extract_type_arguments_test: RuntimeError # Issue 31371
+f_bounded_quantification4_test: RuntimeError
 f_bounded_quantification_test/01: MissingCompileTimeError
 f_bounded_quantification_test/02: MissingCompileTimeError
 factory2_test/03: MissingCompileTimeError
@@ -1265,8 +1243,6 @@
 function_subtype3_test: RuntimeError
 function_subtype_bound_closure3_test: RuntimeError
 function_subtype_bound_closure4_test: RuntimeError
-function_subtype_bound_closure7_test: RuntimeError
-function_subtype_call0_test: RuntimeError
 function_subtype_call1_test: RuntimeError
 function_subtype_call2_test: RuntimeError
 function_subtype_cast1_test: RuntimeError
@@ -1274,7 +1250,6 @@
 function_subtype_not1_test: RuntimeError
 function_subtype_setter0_test: RuntimeError
 function_subtype_typearg5_test: RuntimeError
-function_type2_test: RuntimeError
 function_type_alias2_test: RuntimeError
 function_type_alias4_test: RuntimeError
 generic_closure_test/01: RuntimeError
@@ -1283,7 +1258,6 @@
 generic_function_dcall_test: RuntimeError
 generic_function_type_as_type_argument_test/01: MissingCompileTimeError
 generic_function_type_as_type_argument_test/02: MissingCompileTimeError
-generic_function_type_within_type_argument_test: RuntimeError
 generic_function_typedef_test/01: RuntimeError
 generic_instanceof2_test: RuntimeError
 generic_instanceof_test: RuntimeError
@@ -1315,11 +1289,8 @@
 identical_const_test/03: MissingCompileTimeError
 identical_const_test/04: MissingCompileTimeError
 if_null_precedence_test/none: RuntimeError
-implicit_creation/implicit_new_or_const_composite_test: RuntimeError
-implicit_creation/implicit_new_or_const_test: RuntimeError
 implicit_this_test/01: MissingCompileTimeError
 implicit_this_test/04: MissingCompileTimeError
-inferrer_synthesized_constructor_test: RuntimeError
 infinity_test: RuntimeError # non JS number semantics - Issue 4984
 initializing_formal_type_annotation_test/01: MissingCompileTimeError
 initializing_formal_type_annotation_test/02: MissingCompileTimeError
@@ -1375,7 +1346,6 @@
 malbounded_type_test_test/02: MissingCompileTimeError
 many_generic_instanceof_test: RuntimeError
 many_overridden_no_such_method_test: RuntimeError
-map_literal11_test/none: MissingRuntimeError
 map_literal3_test/01: MissingCompileTimeError
 map_literal3_test/02: MissingCompileTimeError
 map_literal3_test/03: MissingCompileTimeError
@@ -1450,6 +1420,7 @@
 mixin_invalid_bound_test/08: MissingCompileTimeError
 mixin_invalid_bound_test/09: MissingCompileTimeError
 mixin_invalid_bound_test/10: MissingCompileTimeError
+mixin_mixin6_test: RuntimeError
 mixin_of_mixin_test/none: CompileTimeError
 mixin_super_2_test/none: CompileTimeError
 mixin_super_bound_test/01: MissingCompileTimeError
@@ -1501,9 +1472,9 @@
 no_main_test/01: CompileTimeError
 no_such_method_mock_test: RuntimeError
 no_such_method_test: RuntimeError
+nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
 nosuchmethod_forwarding/nosuchmethod_forwarding_test/05: RuntimeError
 nosuchmethod_forwarding/nosuchmethod_forwarding_test/06: RuntimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
 null_no_such_method_test: CompileTimeError
 null_test/mirrors: RuntimeError
 null_test/none: RuntimeError
@@ -1581,6 +1552,8 @@
 redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
 redirecting_factory_malbounded_test/01: MissingCompileTimeError
 redirecting_factory_reflection_test: RuntimeError
+reg_ex2_test: RuntimeError
+reg_exp2_test: RuntimeError
 reg_exp_test: RuntimeError
 regress_13462_1_test: RuntimeError
 regress_18535_test: RuntimeError
@@ -1789,6 +1762,7 @@
 async_star_await_pauses_test: RuntimeError
 async_star_cancel_while_paused_test: Crash # Interpolated value #1 is not an Expression or List of Expressions: [VariableUse(f), Instance of 'LiteralNull', null]
 async_star_regression_2238_test: RuntimeError
+async_star_regression_23116_test: RuntimeError
 async_star_stream_take_test: RuntimeError
 async_star_test/01: RuntimeError
 async_star_test/02: RuntimeError
@@ -1805,6 +1779,10 @@
 bad_override_test/05: MissingCompileTimeError
 bit_operations_test: RuntimeError
 branch_canonicalization_test: RuntimeError
+call_method_implicit_tear_off_implements_function_test/02: RuntimeError
+call_method_implicit_tear_off_implements_function_test/04: RuntimeError
+call_method_implicit_tear_off_test/02: RuntimeError
+call_method_implicit_tear_off_test/04: RuntimeError
 call_non_method_field_test/01: MissingCompileTimeError
 call_non_method_field_test/02: MissingCompileTimeError
 canonical_const2_test: RuntimeError, OK # non JS number semantics
@@ -1863,15 +1841,8 @@
 covariance_type_parameter_test/01: RuntimeError
 covariance_type_parameter_test/02: RuntimeError
 covariance_type_parameter_test/03: RuntimeError
-covariant_override/runtime_check_test: RuntimeError
 covariant_override/tear_off_type_test: RuntimeError
-covariant_subtyping_tearoff1_test: RuntimeError
-covariant_subtyping_tearoff2_test: RuntimeError
-covariant_subtyping_tearoff3_test: RuntimeError
 covariant_subtyping_test: CompileTimeError
-covariant_subtyping_unsafe_call1_test: RuntimeError
-covariant_subtyping_unsafe_call2_test: RuntimeError
-covariant_subtyping_unsafe_call3_test: RuntimeError
 ct_const_test: CompileTimeError
 cyclic_constructor_test/01: Crash # Issue 30856
 cyclic_type_variable_test/01: MissingCompileTimeError
@@ -1959,8 +1930,6 @@
 function_subtype3_test: RuntimeError
 function_subtype_bound_closure3_test: RuntimeError
 function_subtype_bound_closure4_test: RuntimeError
-function_subtype_bound_closure7_test: RuntimeError
-function_subtype_call0_test: RuntimeError
 function_subtype_call1_test: RuntimeError
 function_subtype_call2_test: RuntimeError
 function_subtype_cast1_test: RuntimeError
@@ -1968,14 +1937,12 @@
 function_subtype_not1_test: RuntimeError
 function_subtype_setter0_test: RuntimeError
 function_subtype_typearg5_test: RuntimeError
-function_type2_test: RuntimeError
 function_type_alias2_test: RuntimeError
 function_type_alias4_test: RuntimeError
 generic_function_bounds_test: RuntimeError
 generic_function_dcall_test: RuntimeError
 generic_function_type_as_type_argument_test/01: MissingCompileTimeError
 generic_function_type_as_type_argument_test/02: MissingCompileTimeError
-generic_function_type_within_type_argument_test: RuntimeError
 generic_function_typedef_test/01: RuntimeError
 generic_instanceof2_test: RuntimeError
 generic_instanceof_test: RuntimeError
@@ -2007,11 +1974,8 @@
 identical_const_test/03: MissingCompileTimeError
 identical_const_test/04: MissingCompileTimeError
 if_null_precedence_test/none: RuntimeError
-implicit_creation/implicit_new_or_const_composite_test: RuntimeError
-implicit_creation/implicit_new_or_const_test: RuntimeError
 implicit_this_test/01: MissingCompileTimeError
 implicit_this_test/04: MissingCompileTimeError
-inferrer_synthesized_constructor_test: RuntimeError
 infinity_test: RuntimeError # non JS number semantics - Issue 4984
 initializing_formal_type_annotation_test/01: MissingCompileTimeError
 initializing_formal_type_annotation_test/02: MissingCompileTimeError
@@ -2067,7 +2031,6 @@
 malbounded_type_test_test/02: MissingCompileTimeError
 many_generic_instanceof_test: RuntimeError
 many_overridden_no_such_method_test: RuntimeError
-map_literal11_test/none: MissingRuntimeError
 map_literal3_test/01: MissingCompileTimeError
 map_literal3_test/02: MissingCompileTimeError
 map_literal3_test/03: MissingCompileTimeError
@@ -2198,9 +2161,9 @@
 no_such_method_mock_test: RuntimeError
 no_such_method_native_test: RuntimeError
 no_such_method_test: RuntimeError
+nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
 nosuchmethod_forwarding/nosuchmethod_forwarding_test/05: RuntimeError
 nosuchmethod_forwarding/nosuchmethod_forwarding_test/06: RuntimeError
-nosuchmethod_forwarding/nosuchmethod_forwarding_arguments_test: RuntimeError
 null_no_such_method_test: CompileTimeError
 null_test/mirrors: RuntimeError
 null_test/none: RuntimeError
@@ -2269,6 +2232,8 @@
 redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
 redirecting_factory_malbounded_test/01: MissingCompileTimeError
 redirecting_factory_reflection_test: RuntimeError
+reg_ex2_test: RuntimeError
+reg_exp2_test: RuntimeError
 reg_exp_test: RuntimeError
 regress_13462_1_test: RuntimeError
 regress_18535_test: RuntimeError
@@ -2416,3 +2381,4 @@
 mixin_mixin_bound2_test: RuntimeError # Issue 31054
 mixin_mixin_bound_test: RuntimeError # Issue 31054
 mixin_mixin_type_arguments_test: RuntimeError # Issue 31054
+
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index ebb3c4d..5eb7866 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -20,39 +20,9 @@
 async_star_test/none: RuntimeError
 await_future_test: Pass, Timeout # Issue 29920
 bit_operations_test: RuntimeError # No bigints on web.
-black_listed_test/none: Fail # Issue 14228
 bug32372_test: RuntimeError
 built_in_identifier_prefix_test: CompileTimeError
 built_in_identifier_type_annotation_test/22: MissingCompileTimeError # Issue 28816
-call_method_as_cast_test/01: RuntimeError
-call_method_as_cast_test/02: RuntimeError
-call_method_as_cast_test/03: RuntimeError
-call_method_as_cast_test/04: RuntimeError
-call_method_as_cast_test/05: RuntimeError
-call_method_function_typed_value_test/02: RuntimeError
-call_method_function_typed_value_test/04: RuntimeError
-call_method_function_typed_value_test/06: RuntimeError
-call_method_function_typed_value_test/08: RuntimeError
-call_method_implicit_tear_off_assignable_test: CompileTimeError # Issue 32426
-call_method_implicit_tear_off_implements_function_test/01: RuntimeError
-call_method_implicit_tear_off_implements_function_test/02: RuntimeError
-call_method_implicit_tear_off_implements_function_test/03: RuntimeError
-call_method_implicit_tear_off_implements_function_test/04: RuntimeError
-call_method_implicit_tear_off_test/01: RuntimeError
-call_method_implicit_tear_off_test/02: RuntimeError
-call_method_implicit_tear_off_test/03: RuntimeError
-call_method_implicit_tear_off_test/04: RuntimeError
-call_method_implicit_tear_off_test/05: RuntimeError
-call_method_implicit_tear_off_test/06: RuntimeError
-call_method_is_check_test/01: RuntimeError
-call_method_is_check_test/02: RuntimeError
-call_method_is_check_test/03: RuntimeError
-call_method_is_check_test/04: RuntimeError
-call_method_is_check_test/05: RuntimeError
-call_method_must_not_be_field_test/03: RuntimeError
-call_method_must_not_be_getter_test/03: RuntimeError
-call_method_override_test/01: MissingCompileTimeError
-call_method_override_test/02: MissingCompileTimeError
 cascaded_forwarding_stubs_generic_test: RuntimeError
 cascaded_forwarding_stubs_test: CompileTimeError
 conflicting_generic_interfaces_hierarchy_loop_infinite_test: Skip # Crashes or times out
@@ -338,25 +308,13 @@
 bad_override_test/05: MissingCompileTimeError
 built_in_identifier_type_annotation_test/05: RuntimeError # Issue 32194
 built_in_identifier_type_annotation_test/none: RuntimeError # Issue 32194
-call_method_as_cast_test/01: RuntimeError
-call_method_as_cast_test/02: RuntimeError
-call_method_as_cast_test/03: RuntimeError
-call_method_as_cast_test/04: RuntimeError
-call_method_as_cast_test/05: RuntimeError
-call_method_function_typed_value_test/02: RuntimeError
-call_method_function_typed_value_test/04: RuntimeError
-call_method_function_typed_value_test/06: RuntimeError
-call_method_function_typed_value_test/08: RuntimeError
-call_method_is_check_test/01: RuntimeError
-call_method_is_check_test/02: RuntimeError
-call_method_is_check_test/03: RuntimeError
-call_method_is_check_test/04: RuntimeError
-call_method_is_check_test/05: RuntimeError
-call_method_must_not_be_field_test/03: RuntimeError # Issue 32157
-call_method_must_not_be_getter_test/03: RuntimeError # Issue 32157
+call_method_as_cast_test/06: RuntimeError # Kernel allows classes to subtype `Function` so DDK elides the explicit cast.
+call_method_implicit_tear_off_implements_function_test/05: RuntimeError # Kernel is missing the implicit `call` tearoff for assignment `Function`
+call_method_implicit_tear_off_implements_function_test/06: RuntimeError # Kernel is missing the implicit `call` tearoff for assignment `Function`
+call_method_must_not_be_field_test/06: RuntimeError # Kernel does not distinguish `d()` from `d.call()`
+call_method_must_not_be_getter_test/06: RuntimeError # Kernel does not distinguish `d()` from `d.call()`
 call_non_method_field_test/01: MissingCompileTimeError
 call_non_method_field_test/02: MissingCompileTimeError
-call_with_no_such_method_test: RuntimeError
 cast_test/none: RuntimeError # Issue 32194
 check_member_static_test/01: MissingCompileTimeError
 check_member_static_test/02: MissingCompileTimeError
@@ -394,7 +352,6 @@
 const_types_test/39: MissingCompileTimeError
 constant_string_interpolation2_test: RuntimeError # Issue 32194
 constants_test/05: MissingCompileTimeError
-constructor_call_as_function_test: CompileTimeError # Issue 32517
 constructor_redirect1_negative_test/01: MissingCompileTimeError
 constructor_redirect2_negative_test: MissingCompileTimeError
 constructor_redirect_test/01: MissingCompileTimeError
@@ -408,7 +365,6 @@
 cyclic_typedef_test/11: Crash
 default_factory2_test/01: MissingCompileTimeError
 default_factory_test/01: MissingCompileTimeError
-deferred_constraints_constants_test/default_argument2: MissingCompileTimeError
 deferred_inheritance_constraints_test/extends: MissingCompileTimeError
 deferred_inheritance_constraints_test/implements: MissingCompileTimeError
 deferred_inheritance_constraints_test/mixin: MissingCompileTimeError
@@ -440,8 +396,6 @@
 field_override_test/01: MissingCompileTimeError
 function_propagation_test: RuntimeError
 function_subtype_closure0_test: RuntimeError # Expect.throws(TypeError) fails: Did not throw
-function_type_parameter2_negative_test: Fail
-function_type_parameter_negative_test: Fail
 generic_function_bounds_test: RuntimeError
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
 generic_methods_recursive_bound_test/02: MissingCompileTimeError
@@ -457,28 +411,17 @@
 identical_const_test/02: MissingCompileTimeError
 identical_const_test/03: MissingCompileTimeError
 identical_const_test/04: MissingCompileTimeError
-implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_test: CompileTimeError # Issue 32517
 implicit_creation/implicit_const_not_default_values_test/e.*: MissingCompileTimeError
-implicit_creation/implicit_const_not_default_values_test/e12: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e15: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e18: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e21: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e24: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e27: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e3: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e30: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e6: Pass # Issue 32517
-implicit_creation/implicit_const_not_default_values_test/e9: Pass # Issue 32517
-implicit_creation/implicit_new_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_composite_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_prefix_constructor_named_test: CompileTimeError # Issue 32517
+implicit_creation/implicit_const_not_default_values_test/e12: Pass
+implicit_creation/implicit_const_not_default_values_test/e15: Pass
+implicit_creation/implicit_const_not_default_values_test/e18: Pass
+implicit_creation/implicit_const_not_default_values_test/e21: Pass
+implicit_creation/implicit_const_not_default_values_test/e24: Pass
+implicit_creation/implicit_const_not_default_values_test/e27: Pass
+implicit_creation/implicit_const_not_default_values_test/e3: Pass
+implicit_creation/implicit_const_not_default_values_test/e30: Pass
+implicit_creation/implicit_const_not_default_values_test/e6: Pass
+implicit_creation/implicit_const_not_default_values_test/e9: Pass
 implicit_this_test/01: MissingCompileTimeError
 implicit_this_test/04: MissingCompileTimeError
 initializing_formal_type_annotation_test/01: MissingCompileTimeError
@@ -757,8 +700,6 @@
 branch_canonicalization_test: RuntimeError # Issue 29920; Expect.equals(expected: <0>, actual: <1>) fails.
 built_in_identifier_prefix_test: CompileTimeError
 call_closurization_test: RuntimeError # Issue 29920; TypeError: Cannot read property '0' of undefined
-call_operator_test/01: RuntimeError # Issue 32157
-call_operator_test/02: RuntimeError # Issue 32157
 call_test: RuntimeError # Expect.throws(NoSuchMethodError) fails: Did not throw
 canonical_const2_test: RuntimeError # Ints and doubles are unified.; Expect.isFalse(true) fails.
 closure_call_wrong_argument_count_negative_test: Fail
@@ -776,6 +717,7 @@
 ct_const_test: RuntimeError # Issue 2992; RangeError: Maximum call stack size exceeded
 custom_await_stack_trace_test: RuntimeError # Issue 29920; Uncaught Expect.equals(at index 0: Expected <Blah \x0ABloop\x0ABleep\x0A...>
 cyclic_type2_test: RuntimeError # Issue 29920; Uncaught ReferenceError: V is not defined
+cyclic_type_test/00: RuntimeError # Issue 32564: <dynamic> not printed.
 cyclic_type_test/02: RuntimeError # Issue 29920; Uncaught RangeError: Maximum call stack size exceeded
 cyclic_type_test/03: RuntimeError # Issue 29920; Uncaught ReferenceError: U is not defined
 cyclic_type_test/04: RuntimeError # Issue 29920; Uncaught ReferenceError: U is not defined
@@ -790,6 +732,7 @@
 exception_test: RuntimeError # DDC doesn't implement NullThrownError?; Expect.isTrue(false) fails.
 expect_test: RuntimeError # Issue 29920; Expect.identical did not fail
 f_bounded_quantification3_test: RuntimeError # Issue 29920; Uncaught Error: type arguments should not be null: (F1, F2) => {
+f_bounded_quantification4_test: RuntimeError # Issue 32564: <dynamic> not printed.
 field3_test/01: MissingCompileTimeError
 field_increment_bailout_test: RuntimeError # Issue 29920; UnimplementedError: JsInstanceMirror.delegate unimplemented
 field_initialization_order_test/none: RuntimeError # Expect.equals(expected: <b.a.ai.bi.>, actual: <b.bi.a.ai.>) fails.
@@ -833,6 +776,7 @@
 many_overridden_no_such_method_test: RuntimeError # UnimplementedError: JsInstanceMirror.delegate unimplemented; UnimplementedError: JsInstanceMirror.delegate unimplemented
 method_override7_test/03: MissingCompileTimeError # Issue 30514
 mint_arithmetic_test: RuntimeError # Issue 29920; Expect.equals(expected: <4294967297>, actual: <1>) fails.
+mixin_mixin6_test: RuntimeError # Issue 32564: <dynamic> not printed.
 modulo_test: RuntimeError # Ints and doubles are unified.; Expect.throws fails: Did not throw
 multiline_newline_test/04: MissingCompileTimeError
 multiline_newline_test/04r: MissingCompileTimeError
@@ -885,3 +829,4 @@
 switch_try_catch_test: RuntimeError # Issue 29920; Expect.throws: Unexpected 'UnimplementedError: node <ShadowContinueSwitchStatement> see https://github.com/dart-lang/sdk/issues/29352 `continue #L1;
 truncdiv_test: RuntimeError # Issue 29920; Expect.throws fails: Did not throw
 vm/*: SkipByDesign # VM only tests.; VM only tests.
+
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 7fff2fc..ef87534 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -584,13 +584,9 @@
 type_variable_bounds4_test/01: RuntimeError
 
 [ $compiler == dartk && $runtime == vm && !$checked && $strong ]
-bool_check_test: RuntimeError
-bool_condition_check_test: RuntimeError
 compile_time_constant_static2_test/04: MissingCompileTimeError
 compile_time_constant_static3_test/04: MissingCompileTimeError
 conditional_rewrite_test: RuntimeError # Issue 31402 (Not)
-field_override_optimization_test: RuntimeError
-if_null_precedence_test/none: RuntimeError
 type_error_test: RuntimeError # Issue 31402 (Variable declaration)
 
 # ===== dartk + vm status lines =====
@@ -600,9 +596,12 @@
 async_star_pause_test: Fail, OK
 async_star_test/02: RuntimeError # Issue 31402 (Invocation arguments)
 built_in_identifier_prefix_test: CompileTimeError
+call_method_as_cast_test/06: RuntimeError
+call_method_implicit_tear_off_implements_function_test/05: RuntimeError
+call_method_implicit_tear_off_implements_function_test/06: RuntimeError
+call_method_is_check_test/06: RuntimeError
 call_method_must_not_be_field_test/03: RuntimeError # Issue 32265
 call_method_must_not_be_getter_test/03: RuntimeError # Issue 32265
-call_with_no_such_method_test: RuntimeError
 compile_time_constant_k_test/01: MissingCompileTimeError
 compile_time_constant_k_test/02: MissingCompileTimeError
 compile_time_constant_k_test/03: MissingCompileTimeError
@@ -624,7 +623,6 @@
 const_string_test: RuntimeError
 constructor12_test: RuntimeError
 constructor3_test: Fail, OK, Pass
-constructor_call_as_function_test: CompileTimeError # Issue 32517
 ct_const2_test: Pass, Crash # Flaky
 ct_const_test: RuntimeError
 cyclic_type2_test: RuntimeError, CompileTimeError
@@ -653,10 +651,6 @@
 flatten_test/12: MissingRuntimeError
 for_in_side_effects_test/01: MissingCompileTimeError
 function_propagation_test: RuntimeError
-function_subtype3_test: RuntimeError
-function_subtype_call0_test: RuntimeError, OK
-function_subtype_call1_test: RuntimeError
-function_subtype_call2_test: RuntimeError
 function_subtype_inline2_test: RuntimeError
 function_type_alias6_test/none: RuntimeError
 generic_function_dcall_test: RuntimeError
@@ -667,18 +661,7 @@
 generic_tearoff_test: CompileTimeError
 generic_tearoff_test: RuntimeError
 if_null_evaluation_order_test: Pass
-implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_test: CompileTimeError # Issue 32517
 implicit_creation/implicit_new_constructor_generic_test: Pass
-implicit_creation/implicit_new_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_composite_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_prefix_constructor_named_test: CompileTimeError # Issue 32517
 initializing_formal_type_annotation_test/01: MissingCompileTimeError
 initializing_formal_type_annotation_test/02: MissingCompileTimeError
 instantiate_tearoff_of_call_test: CompileTimeError
@@ -888,13 +871,9 @@
 [ $compiler == dartkp && $runtime == dart_precompiled && !$checked && $strong ]
 assertion_initializer_const_error_test/01: MissingCompileTimeError
 assertion_initializer_const_function_error_test/01: MissingCompileTimeError
-bool_check_test: RuntimeError
-bool_condition_check_test: RuntimeError
 compile_time_constant_static2_test/04: MissingCompileTimeError
 compile_time_constant_static3_test/04: MissingCompileTimeError
 conditional_rewrite_test: RuntimeError # Issue 31402 (Not)
-field_override_optimization_test: RuntimeError
-if_null_precedence_test/none: RuntimeError
 implicit_downcast_during_combiner_test: RuntimeError
 implicit_downcast_during_compound_assignment_test: RuntimeError
 implicit_downcast_during_conditional_expression_test: RuntimeError
@@ -925,10 +904,17 @@
 async_star_cancel_while_paused_test: RuntimeError
 async_star_pause_test: Fail, OK
 async_star_test/02: RuntimeError, CompileTimeError # Issue 31402 (Invocation arguments)
+bad_override_test/03: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+bad_override_test/04: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+bad_override_test/05: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 built_in_identifier_prefix_test: CompileTimeError
+call_method_as_cast_test/06: RuntimeError
+call_method_implicit_tear_off_implements_function_test/05: RuntimeError
+call_method_implicit_tear_off_implements_function_test/06: RuntimeError
+call_method_is_check_test/06: RuntimeError
 call_method_must_not_be_field_test/03: RuntimeError # Issue 32265
 call_method_must_not_be_getter_test/03: RuntimeError # Issue 32265
-call_with_no_such_method_test: RuntimeError
+check_member_static_test/02: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 checked_setter3_test/01: MissingCompileTimeError
 checked_setter3_test/02: MissingCompileTimeError
 checked_setter3_test/03: MissingCompileTimeError
@@ -983,18 +969,21 @@
 external_test/13: MissingRuntimeError # KernelVM bug: Unbound external.
 external_test/20: MissingRuntimeError # KernelVM bug: Unbound external.
 factory3_test/01: Pass
+fauxverride_test/03: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+fauxverride_test/05: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 field_increment_bailout_test: SkipByDesign
 field_initialization_order_test: Fail, OK
+field_override3_test/00: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+field_override3_test/01: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+field_override3_test/02: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+field_override3_test/03: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+field_override4_test/02: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 flatten_test/05: MissingRuntimeError
 flatten_test/08: MissingRuntimeError
 flatten_test/09: MissingRuntimeError
 flatten_test/12: MissingRuntimeError
 for_in_side_effects_test/01: MissingCompileTimeError
 function_propagation_test: RuntimeError
-function_subtype3_test: RuntimeError
-function_subtype_call0_test: RuntimeError, OK
-function_subtype_call1_test: RuntimeError
-function_subtype_call2_test: RuntimeError
 function_subtype_inline2_test: RuntimeError
 function_type_alias6_test/none: RuntimeError
 generic_function_dcall_test: RuntimeError
@@ -1007,6 +996,10 @@
 generic_no_such_method_dispatcher_simple_test: CompileTimeError # Issue 31533
 generic_no_such_method_dispatcher_test: CompileTimeError # Issue 31533
 generic_tearoff_test: CompileTimeError
+getter_override2_test/02: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+getter_override_test/00: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+getter_override_test/01: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+getter_override_test/02: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 hello_dart_test: Skip # Incompatible flag: --compile_all
 implicit_closure_test: Skip # Incompatible flag: --use_slow_path
 implicit_creation/implicit_new_constructor_generic_test: Pass
@@ -1064,6 +1057,10 @@
 method_override6_test/01: MissingCompileTimeError
 method_override6_test/02: MissingCompileTimeError
 method_override6_test/03: MissingCompileTimeError
+method_override7_test/00: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+method_override7_test/01: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+method_override7_test/02: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+method_override8_test/01: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 method_override_test: CompileTimeError # Issue 31616
 mixin_illegal_super_use_test: Skip # Issues 24478 and 23773
 mixin_illegal_superclass_test: Skip # Issues 24478 and 23773
@@ -1077,6 +1074,10 @@
 null_test/mirrors: Skip # Uses mirrors.
 null_test/none: SkipByDesign
 overridden_no_such_method_test: SkipByDesign
+override_field_method2_negative_test: Fail # Issue 32613: override check is missing in CFE.
+override_field_method4_negative_test: Fail # Issue 32613: override check is missing in CFE.
+override_field_method5_negative_test: Fail # Issue 32613: override check is missing in CFE.
+override_field_test/01: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 override_inheritance_field_test/04: CompileTimeError # Issue 31616
 override_inheritance_field_test/06: CompileTimeError # Issue 31616
 override_inheritance_field_test/26: CompileTimeError # Issue 31616
@@ -1084,6 +1085,11 @@
 override_inheritance_generic_test/02: CompileTimeError
 override_inheritance_method_test/28: CompileTimeError
 override_inheritance_method_test/29: CompileTimeError
+override_inheritance_mixed_test/01: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+override_inheritance_mixed_test/02: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+override_inheritance_mixed_test/03: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+override_inheritance_mixed_test/04: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+override_inheritance_mixed_test/08: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 override_inheritance_mixed_test/08: Pass # Correctly passes.
 parser_quirks_test: CompileTimeError # Issue 31533
 redirecting_factory_infinite_steps_test/01: MissingCompileTimeError
@@ -1101,6 +1107,8 @@
 regress_29405_test: CompileTimeError # Issue 31402 (Invocation arguments)
 regress_30339_test: CompileTimeError # Issue 31402 (Variable declaration)
 setter_no_getter_test/01: Pass, CompileTimeError # Issue 31533 (started passing after switching to batch-mode)
+setter_override_test/00: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
+setter_override_test/03: MissingCompileTimeError # Issue 32613: override check is missing in CFE.
 stacktrace_demangle_ctors_test: RuntimeError
 string_interpolate_test: CompileTimeError # Issue 31533
 string_interpolation_and_buffer_test: RuntimeError # Issue 31402 (Return and yield statements)
@@ -1201,7 +1209,6 @@
 constants_test/05: MissingCompileTimeError
 cyclic_typedef_test/10: Crash
 cyclic_typedef_test/11: Crash
-deferred_constraints_constants_test/default_argument2: MissingCompileTimeError
 deferred_load_library_wrong_args_test/01: CompileTimeError
 deferred_shared_and_unshared_classes_test: CompileTimeError
 duplicate_implements_test/01: MissingCompileTimeError
@@ -1219,8 +1226,6 @@
 field_override3_test/02: MissingCompileTimeError
 field_override3_test/03: MissingCompileTimeError
 field_override4_test/02: MissingCompileTimeError
-function_type_parameter2_negative_test: Fail
-function_type_parameter_negative_test: Fail
 generic_function_type_as_type_argument_test/01: MissingCompileTimeError
 generic_function_type_as_type_argument_test/02: MissingCompileTimeError
 generic_methods_generic_function_result_test/01: MissingCompileTimeError
@@ -1338,31 +1343,16 @@
 type_promotion_more_specific_test/04: CompileTimeError
 
 [ $compiler == fasta && !$strong ]
+call_method_implicit_invoke_local_test/05: MissingCompileTimeError
 invalid_override_in_mixin_test/01: MissingCompileTimeError
 map_literal1_test/01: MissingCompileTimeError
 
-[ $runtime == vm && $fasta ]
-implicit_creation/implicit_new_or_const_composite_test: RuntimeError
-implicit_creation/implicit_new_or_const_test: RuntimeError
-
 [ $fasta && $strong ]
 compile_time_constant_k_test/01: MissingCompileTimeError
 compile_time_constant_k_test/02: MissingCompileTimeError
 compile_time_constant_k_test/03: MissingCompileTimeError
 compile_time_constant_static2_test/04: MissingCompileTimeError
 compile_time_constant_static3_test/04: MissingCompileTimeError
-constructor_call_as_function_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_composite_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_prefix_constructor_named_test: CompileTimeError # Issue 32517
 initializing_formal_type_annotation_test/01: MissingCompileTimeError
 initializing_formal_type_annotation_test/02: MissingCompileTimeError
 issue18628_2_test/01: MissingCompileTimeError
@@ -1529,14 +1519,9 @@
 const_constructor2_test/24: MissingCompileTimeError
 const_constructor3_test/02: MissingCompileTimeError
 const_constructor3_test/04: MissingCompileTimeError
-const_error_multiply_initialized_test/01: MissingCompileTimeError
-const_error_multiply_initialized_test/02: MissingCompileTimeError
-const_error_multiply_initialized_test/03: MissingCompileTimeError
-const_error_multiply_initialized_test/04: MissingCompileTimeError
 const_init2_test/02: MissingCompileTimeError
 const_native_factory_test: MissingCompileTimeError
 const_syntax_test/08: MissingCompileTimeError
-const_syntax_test/09: MissingCompileTimeError
 const_syntax_test/10: MissingCompileTimeError
 const_types_test/01: MissingCompileTimeError
 const_types_test/02: MissingCompileTimeError
@@ -1550,7 +1535,6 @@
 constants_test/05: MissingCompileTimeError
 constructor13_test/01: MissingCompileTimeError
 constructor13_test/02: MissingCompileTimeError
-constructor_call_as_function_test: CompileTimeError # Issue 32517
 constructor_call_wrong_argument_count_negative_test: Fail
 constructor_duplicate_final_test/01: MissingCompileTimeError
 constructor_duplicate_final_test/02: MissingCompileTimeError
@@ -1558,7 +1542,6 @@
 constructor_redirect1_negative_test/none: MissingCompileTimeError
 create_unresolved_type_test/01: MissingCompileTimeError
 cyclic_typedef_test/13: MissingCompileTimeError
-deferred_constraints_constants_test/default_argument2: MissingCompileTimeError
 deferred_constraints_type_annotation_test/as_operation: MissingCompileTimeError
 deferred_constraints_type_annotation_test/catch_check: MissingCompileTimeError
 deferred_constraints_type_annotation_test/is_check: MissingCompileTimeError
@@ -1625,7 +1608,6 @@
 final_for_in_variable_test: MissingCompileTimeError
 final_param_test: MissingCompileTimeError
 final_super_field_set_test: MissingCompileTimeError
-final_syntax_test/09: MissingCompileTimeError
 final_syntax_test/10: MissingCompileTimeError
 final_variable_assignment_test/01: MissingCompileTimeError
 final_variable_assignment_test/02: MissingCompileTimeError
@@ -1649,8 +1631,6 @@
 function_type_call_getter2_test/03: MissingCompileTimeError
 function_type_call_getter2_test/04: MissingCompileTimeError
 function_type_call_getter2_test/05: MissingCompileTimeError
-function_type_parameter2_negative_test: Fail
-function_type_parameter_negative_test: Fail
 fuzzy_arrows_test/01: MissingCompileTimeError
 generic_constructor_mixin2_test/01: MissingCompileTimeError
 generic_constructor_mixin3_test/01: MissingCompileTimeError
@@ -1703,17 +1683,6 @@
 if_null_assignment_static_test/42: MissingCompileTimeError
 if_null_precedence_test/06: MissingCompileTimeError
 if_null_precedence_test/07: MissingCompileTimeError
-implicit_creation/implicit_const_context_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_generic_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_const_context_prefix_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_constructor_named_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_constructor_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_composite_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_or_const_test: CompileTimeError # Issue 32517
-implicit_creation/implicit_new_prefix_constructor_named_test: CompileTimeError # Issue 32517
 implicit_this_test/02: MissingCompileTimeError
 import_combinators2_test/00: MissingCompileTimeError
 import_self_test/01: MissingCompileTimeError
diff --git a/tests/language_2/language_2_precompiled.status b/tests/language_2/language_2_precompiled.status
index c69bb03..aa44ee3 100644
--- a/tests/language_2/language_2_precompiled.status
+++ b/tests/language_2/language_2_precompiled.status
@@ -366,9 +366,11 @@
 for_in_side_effects_test/01: MissingCompileTimeError
 function_malformed_result_type_test/00: MissingCompileTimeError
 function_propagation_test: RuntimeError
+function_subtype3_test: RuntimeError
 function_subtype_bound_closure3_test: RuntimeError
 function_subtype_bound_closure4_test: RuntimeError
 function_subtype_bound_closure7_test: RuntimeError
+function_subtype_call0_test: RuntimeError
 function_subtype_call1_test: RuntimeError
 function_subtype_call2_test: RuntimeError
 function_subtype_cast0_test: RuntimeError
diff --git a/tests/language_2/language_2_vm.status b/tests/language_2/language_2_vm.status
index dfc7a3b..56d7d4f 100644
--- a/tests/language_2/language_2_vm.status
+++ b/tests/language_2/language_2_vm.status
@@ -15,8 +15,6 @@
 assertion_initializer_const_error2_test/cc09: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc10: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc11: MissingCompileTimeError # Not reporting failed assert() at compile time.
-implicit_creation/implicit_new_or_const_composite_test: RuntimeError
-implicit_creation/implicit_new_or_const_test: RuntimeError
 
 [ $arch == arm64 && $runtime == vm ]
 closure_cycles_test: Pass, Slow
@@ -58,7 +56,6 @@
 export_ambiguous_main_negative_test: Fail # Issue 14763
 field_initialization_order_test: Fail, OK
 hello_dart_test: Skip # Incompatible flag: --compile_all
-language_2/least_upper_bound_expansive_test/none: CompileTimeError
 library_env_test/has_html_support: RuntimeError, OK
 library_env_test/has_no_io_support: RuntimeError, OK
 main_not_a_function_test: Skip
@@ -411,6 +408,7 @@
 for_in_side_effects_test/01: MissingCompileTimeError
 function_malformed_result_type_test/00: MissingCompileTimeError
 function_propagation_test: RuntimeError
+function_subtype3_test: RuntimeError
 function_subtype_bound_closure1_test: RuntimeError
 function_subtype_bound_closure2_test: RuntimeError
 function_subtype_bound_closure3_test: RuntimeError
@@ -419,6 +417,7 @@
 function_subtype_bound_closure5a_test: RuntimeError
 function_subtype_bound_closure6_test: RuntimeError
 function_subtype_bound_closure7_test: RuntimeError
+function_subtype_call0_test: RuntimeError
 function_subtype_call1_test: RuntimeError
 function_subtype_call2_test: RuntimeError
 function_subtype_cast0_test: RuntimeError
@@ -1036,9 +1035,15 @@
 unresolved_top_level_var_test: MissingCompileTimeError
 
 [ $compiler != dartk && $runtime == vm && $checked ]
+call_method_as_cast_test/06: RuntimeError
+call_method_implicit_invoke_local_test/05: MissingCompileTimeError
+call_method_implicit_tear_off_implements_function_test/05: RuntimeError
+call_method_implicit_tear_off_implements_function_test/06: RuntimeError
+call_method_is_check_test/06: RuntimeError
 call_operator_test/01: RuntimeError
 call_operator_test/02: RuntimeError
 call_type_literal_test: RuntimeError
+call_with_no_such_method_test: RuntimeError
 class_literal_static_test/none: RuntimeError
 class_literal_test/none: RuntimeError
 constructor_call_as_function_test: RuntimeError
@@ -1285,7 +1290,9 @@
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
 constructor3_test: Fail, OK, Pass
 cyclic_type2_test: Fail, OK
+cyclic_type_test/00: RuntimeError, OK # Not running in strong mode.
 cyclic_type_test/02: Fail, OK # Non-contractive types are not supported in the vm.
+cyclic_type_test/03: RuntimeError, OK # Not running in strong mode.
 cyclic_type_test/04: Fail, OK
 deferred_redirecting_factory_test: Fail, Crash # Issue 23408
 duplicate_export_negative_test: Fail # Issue 6134
@@ -1293,12 +1300,14 @@
 example_constructor_test: Fail, OK
 export_ambiguous_main_negative_test: Fail # Issue 14763
 field_initialization_order_test: Fail, OK
+f_bounded_quantification4_test: RuntimeError, OK # Not running in strong mode.
 generic_methods_bounds_test/02: MissingRuntimeError
 library_env_test/has_html_support: RuntimeError, OK
 library_env_test/has_no_io_support: RuntimeError, OK
 main_not_a_function_test: Skip
 mixin_illegal_super_use_test: Skip # Issues 24478 and 23773
 mixin_illegal_superclass_test: Skip # Issues 24478 and 23773
+mixin_mixin6_test: RuntimeError, OK # Not running in strong mode.
 multiline_strings_test: Fail # Issue 23020
 no_main_test/01: Skip
 regress_19413_test: MissingCompileTimeError
diff --git a/tests/language_2/mixin_mixin6_test.dart b/tests/language_2/mixin_mixin6_test.dart
index 65a32dd..eb2cadc 100644
--- a/tests/language_2/mixin_mixin6_test.dart
+++ b/tests/language_2/mixin_mixin6_test.dart
@@ -26,7 +26,7 @@
 
 main() {
   var c = new C<int>();
-  Expect.equals("Map<dynamic, Set>", c.m().toString());
+  Expect.equals("Map<dynamic, Set<dynamic>>", c.m().toString());
   Expect.isTrue(c is K<int>);
   Expect.isTrue(c is J);
   Expect.isTrue(c is I<Set>);
diff --git a/tests/language_2/no_such_method_mock_test.dart b/tests/language_2/no_such_method_mock_test.dart
index 64d0597..49d8f24 100644
--- a/tests/language_2/no_such_method_mock_test.dart
+++ b/tests/language_2/no_such_method_mock_test.dart
@@ -106,9 +106,7 @@
 
   testMockTearoffs();
   testMockCallable();
-
-  // TODO(jmesserly): enable these tests once we have implicit call tearoff.
-  // testMockCallableTearoff();
+  testMockCallableTearoff();
 }
 
 testMockCallable() {
diff --git a/tests/language_2/vm/integer_type_propagation_test.dart b/tests/language_2/vm/integer_type_propagation_test.dart
index c8b313c..cdf6a0b 100644
--- a/tests/language_2/vm/integer_type_propagation_test.dart
+++ b/tests/language_2/vm/integer_type_propagation_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 // Test various optimizations and deoptimizations of optimizing compiler..
-// VMOptions=--checked --enable-inlining-annotations --no-background-compilation --optimization-counter-threshold=1000
+// VMOptions=--enable-inlining-annotations --no-background-compilation --optimization-counter-threshold=1000
 
 import "package:expect/expect.dart";
 
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index edefa0d..280687c 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -164,7 +164,6 @@
 mirrors/metadata_allowed_values_test/14: MissingCompileTimeError
 mirrors/metadata_nested_constructor_call_test/03: MissingCompileTimeError
 mirrors/metadata_nested_constructor_call_test/04: MissingCompileTimeError
-mirrors/metadata_nested_constructor_call_test/06: MissingCompileTimeError # Issue 32517
 mirrors/native_class_test: CompileTimeError
 mirrors/variable_is_const_test/01: MissingCompileTimeError
 typed_data/int32x4_bigint_test: CompileTimeError
diff --git a/tests/lib_2/html/custom/element_upgrade_test.html b/tests/lib_2/html/custom/element_upgrade_test.html
index 3267d7f..9ae03d3 100644
--- a/tests/lib_2/html/custom/element_upgrade_test.html
+++ b/tests/lib_2/html/custom/element_upgrade_test.html
@@ -45,7 +45,5 @@
 
   <script type="text/javascript"
       src="/root_dart/tools/testing/dart/test_controller.js"></script>
-  <script type="text/javascript"
-      src="/packages/browser/interop.js"></script>
   %TEST_SCRIPTS%
 </body>
diff --git a/tests/lib_2/html/js_dart_functions_test.dart b/tests/lib_2/html/js_dart_functions_test.dart
index 93499db..f4d20b1 100644
--- a/tests/lib_2/html/js_dart_functions_test.dart
+++ b/tests/lib_2/html/js_dart_functions_test.dart
@@ -62,10 +62,13 @@
     expect(result, 42);
   });
 
-  test('emulated functions should be callable in JS', () {
+  test('emulated functions should not be callable in JS', () {
     context['callable'] = new Callable();
-    var result = context.callMethod('callable');
-    expect(result, 'called');
+    expect(() => context.callMethod('callable'), throwsNoSuchMethodError);
+
+    Function f = new Callable();
+    context['callable'] = f;
+    expect(context.callMethod('callable'), 'called');
     context.deleteProperty('callable');
   });
 }
diff --git a/tests/lib_2/html/message_channel_test.dart b/tests/lib_2/html/message_channel_test.dart
new file mode 100644
index 0000000..c6029dd
--- /dev/null
+++ b/tests/lib_2/html/message_channel_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:html';
+
+import 'package:expect/minitest.dart';
+
+main() async {
+  var gotOnMessage = false;
+  var gotEventListener = false;
+
+  Completer completer = new Completer();
+
+  var channel = new MessageChannel();
+  channel.port1.postMessage("Tickle me.");
+
+  channel.port2.onMessage.listen((MessageEvent e) {
+    expect(e.data, "Tickle me.");
+    gotOnMessage = true;
+  });
+
+  channel.port2.addEventListener("message", (message) {
+    var msg = message as MessageEvent;
+    expect(msg.data, "Tickle me.");
+    gotEventListener = true;
+    completer.complete();
+  });
+
+  // Wait for the event listener.
+  await completer.future;
+
+  // Make sure both fired.
+  expect(gotOnMessage, true);
+  expect(gotEventListener, true);
+}
diff --git a/tests/lib_2/isolate/issue_24243_parent_isolate_test.dart b/tests/lib_2/isolate/issue_24243_parent_isolate_test.dart
index f7c122d..6294767 100644
--- a/tests/lib_2/isolate/issue_24243_parent_isolate_test.dart
+++ b/tests/lib_2/isolate/issue_24243_parent_isolate_test.dart
@@ -7,7 +7,6 @@
 // OtherScripts=issue_24243_child1_isolate.dart
 // OtherScripts=issue_24243_child2_isolate.dart
 // OtherScripts=issue_24243_child3_isolate.dart
-// VMOptions=--checked
 
 import 'dart:collection';
 import 'dart:isolate';
diff --git a/tests/lib_2/isolate/typed_message_test.dart b/tests/lib_2/isolate/typed_message_test.dart
index 4bb2770..1b2f8a9 100644
--- a/tests/lib_2/isolate/typed_message_test.dart
+++ b/tests/lib_2/isolate/typed_message_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 // Dart test program for testing isolate communication with
 // typed objects.
-// VMOptions=--checked
 
 library TypedMessageTest;
 
diff --git a/tests/lib_2/lib_2.status b/tests/lib_2/lib_2.status
index a5c29d5..52ea01c 100644
--- a/tests/lib_2/lib_2.status
+++ b/tests/lib_2/lib_2.status
@@ -163,6 +163,7 @@
 [ !$checked && !$strong ]
 async/future_or_only_in_async_test/00: MissingCompileTimeError
 async/multiple_timer_test: Pass, Fail # Timing related
+isolate/issue_24243_parent_isolate_test: SkipByDesign # Requires type checks.
 
 [ !$fasta && $strong ]
 mirrors/redirecting_factory_test: CompileTimeError # Issue 30855
diff --git a/tests/lib_2/lib_2_dart2js.status b/tests/lib_2/lib_2_dart2js.status
index a7913ac..2025fa0 100644
--- a/tests/lib_2/lib_2_dart2js.status
+++ b/tests/lib_2/lib_2_dart2js.status
@@ -289,6 +289,7 @@
 html/location_test: RuntimeError
 html/media_stream_test: RuntimeError
 html/mediasource_test: RuntimeError
+html/message_channel_test: RuntimeError
 html/messageevent_test: RuntimeError
 html/mirrors_js_typed_interop_test: RuntimeError
 html/mouse_event_test: RuntimeError
@@ -371,6 +372,7 @@
 html/html_mock_test: RuntimeError # Issue 31038
 html/input_element_attributes_test: RuntimeError
 html/interactive_media_test: RuntimeError
+html/js_dart_functions_test: RuntimeError # does not implement Dart 2 implicit `.call` tearoff
 html/js_extend_class_test: RuntimeError
 
 [ $compiler == dart2js && $runtime == drt && !$checked ]
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index 8e31a42..7cace3c 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -146,7 +146,6 @@
 mirrors/load_library_test: RuntimeError
 mirrors/metadata_allowed_values_test/16: Skip # Flaky, crashes.
 mirrors/metadata_constructed_constant_test: Crash, RuntimeError
-mirrors/metadata_nested_constructor_call_test/06: Pass # Issue 32517
 mirrors/metadata_scope_test/none: RuntimeError
 mirrors/method_mirror_location_test: RuntimeError
 mirrors/method_mirror_source_line_ending_test: Crash
@@ -345,7 +344,6 @@
 mirrors/relation_subclass_test: CompileTimeError
 
 [ $fasta && $strong ]
-mirrors/metadata_nested_constructor_call_test/06: MissingCompileTimeError # Issue 32517
 mirrors/top_level_accessors_test/01: MissingCompileTimeError
 
 [ $fasta && !$strong ]
@@ -355,7 +353,6 @@
 mirrors/metadata_allowed_values_test/02: MissingCompileTimeError
 mirrors/metadata_allowed_values_test/27: MissingCompileTimeError
 mirrors/metadata_constructor_arguments_test/04: MissingCompileTimeError
-mirrors/metadata_nested_constructor_call_test/06: MissingCompileTimeError # Issue 32517
 mirrors/native_class_test: CompileTimeError
 mirrors/redirecting_factory_different_type_test/01: MissingCompileTimeError
 mirrors/reflect_class_test/01: MissingCompileTimeError
diff --git a/tests/standalone/io/io_override_test.dart b/tests/standalone/io/io_override_test.dart
index fe69637..1d6abb2 100644
--- a/tests/standalone/io/io_override_test.dart
+++ b/tests/standalone/io/io_override_test.dart
@@ -157,6 +157,11 @@
   String targetSync() => null;
 }
 
+Future<Socket> socketConnect(host, int port,
+    {sourceAddress, Duration timeout}) {
+  return null;
+}
+
 Future<Null> ioOverridesRunTest() async {
   Future<Null> f = IOOverrides.runZoned(
     () async {
@@ -175,6 +180,7 @@
       Expect.isFalse(FileSystemEntity.isWatchSupported);
       Expect.isNull(new Directory("directory").watch());
       Expect.isTrue(new Link("link") is LinkMock);
+      Expect.isNull(Socket.connect(null, 0));
     },
     createDirectory: DirectoryMock.createDirectory,
     getCurrentDirectory: DirectoryMock.getCurrent,
@@ -190,6 +196,7 @@
     fsWatch: FileSystemWatcherMock.watch,
     fsWatchIsSupported: FileSystemWatcherMock.watchSupported,
     createLink: LinkMock.createLink,
+    socketConnect: socketConnect,
   );
   Expect.isFalse(new Directory("directory") is DirectoryMock);
   Expect.isTrue(new Directory("directory") is Directory);
diff --git a/tools/VERSION b/tools/VERSION
index 789f1ce..eda92b0 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 0
 PATCH 0
-PRERELEASE 43
+PRERELEASE 44
 PRERELEASE_PATCH 0
diff --git a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
index 0ee1f54..b6959e6 100644
--- a/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/html_dart2js.darttemplate
@@ -29,6 +29,8 @@
  * * For even more examples, see
  * [Dart HTML5 Samples](https://github.com/dart-lang/dart-html5-samples)
  * on Github.
+ *
+ * {@category Web}
  */
 library dart.dom.html;
 
@@ -61,7 +63,6 @@
     findConstructorForNativeSubclassType,
     getNativeInterceptor,
     setDispatchProperty;
-import 'dart:_isolate_helper' show IsolateNatives;
 import 'dart:_foreign_helper' show JS, JS_INTERCEPTOR_CONSTANT;
 
 export 'dart:math' show Rectangle, Point;
@@ -138,8 +139,6 @@
   String nonce;
 }
 
-createCustomUpgrader(Type customElementClass, $this) => $this;
-
 /**
  * Emitted for any setlike IDL entry needs a callback signature.
  * Today there is only one.
diff --git a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
index 128f945..e64c887 100644
--- a/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/indexed_db_dart2js.darttemplate
@@ -77,6 +77,8 @@
  *
  * [IndexedDB reference](http://docs.webplatform.org/wiki/apis/indexeddb)
  * provides wiki-style docs about indexedDB
+ *
+ * {@category Web}
  */
 library dart.dom.indexed_db;
 
diff --git a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
index e2a05b4..e2f72ee 100644
--- a/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/svg_dart2js.darttemplate
@@ -9,6 +9,8 @@
  * For details about the features and syntax of SVG, a W3C standard,
  * refer to the
  * [Scalable Vector Graphics Specification](http://www.w3.org/TR/SVG/).
+ *
+ * {@category Web}
  */
 library dart.dom.svg;
 
diff --git a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
index ce8e678..31437b3 100644
--- a/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_audio_dart2js.darttemplate
@@ -4,6 +4,8 @@
 
 /**
  * High-fidelity audio programming in the browser.
+ *
+ * {@category Web}
  */
 library dart.dom.web_audio;
 
diff --git a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
index 88023f7..e336c9b 100644
--- a/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_gl_dart2js.darttemplate
@@ -4,6 +4,8 @@
 
 /**
  * 3D programming in the browser.
+ *
+ * {@category Web}
  */
 library dart.dom.web_gl;
 
diff --git a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
index 85a580b..b006d56 100644
--- a/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
+++ b/tools/dom/templates/html/dart2js/web_sql_dart2js.darttemplate
@@ -11,6 +11,8 @@
  * for more information.
  *
  * The [dart:indexed_db] APIs is a recommended alternatives.
+ *
+ * {@category Web}
  */
 library dart.dom.web_sql;
 
diff --git a/tools/dom/templates/html/impl/impl_MessagePort.darttemplate b/tools/dom/templates/html/impl/impl_MessagePort.darttemplate
new file mode 100644
index 0000000..824012e
--- /dev/null
+++ b/tools/dom/templates/html/impl/impl_MessagePort.darttemplate
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// WARNING: Do not edit - generated code.
+
+part of $LIBRARYNAME;
+
+$(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS$IMPLEMENTS {
+
+  void addEventListener(String type, EventListener listener,
+      [bool useCapture]) {
+    // Messages posted to ports are initially paused, allowing listeners to be
+    // setup, start() needs to be explicitly invoked to begin handling messages.
+    if (type == 'message') {
+      start();
+    }
+
+    super.addEventListener(type, listener, useCapture);
+  }
+
+$!MEMBERS
+}
+
diff --git a/tools/observatory_tool.py b/tools/observatory_tool.py
index 21dd72b..654f1f6 100755
--- a/tools/observatory_tool.py
+++ b/tools/observatory_tool.py
@@ -18,24 +18,25 @@
 PUB_PATH = os.path.join(DART_ROOT, 'third_party', 'pkg',
                         'pub', 'bin', 'pub.dart')
 IGNORE_PATTERNS = shutil.ignore_patterns(
-    '*.map',
+    '$sdk',
     '*.concat.js',
-    '*.scriptUrls',
+    '*.log',
+    '*.map',
     '*.precompiled.js',
-    'bower.json',
-    'package.json',
+    '*.scriptUrls',
+    '*_buildLogs*',
+    '*~',
     'CustomElements.*',
-    'dart_support.*',
-    'interop_support.*',
     'HTMLImports.*',
     'MutationObserver.*',
     'ShadowDOM.*',
-    'webcomponents.*',
-    'webcomponents-lite.js',
+    'bower.json',
+    'dart_support.*',
+    'interop_support.*',
+    'package.json',
     'unittest*',
-    '*_buildLogs*',
-    '*.log',
-    '*~')
+    'webcomponents-lite.js',
+    'webcomponents.*')
 
 usage = """observatory_tool.py [options]"""