Version 2.0.0-dev.55.0

Merge commit '4a323f8aef90b0dc65c351b978ef66cedd55f73e' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0269232..a13f6d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,46 @@
+## 2.0.0-dev.55.0
+
+### Language
+
+* Changed the `cast` method to always change the type.  Deprecated the
+  `retype` method and made it redirect to `cast`.  Applies to all of the
+  following interfaces:
+  * `Stream`:
+  * `StreamTransformer`
+  * `Iterable`
+  * `Map`
+
+### Tool Changes
+
+#### dart2js
+
+* Several fixes to improve support for running output of dart2js as a webworker.
+
+* `dart:isolate` implementation removed. To launch background tasks,
+  please use webworkers instead. APIs for webworkers can be accessed from
+  `dart:html` or JS-interop.
+
+#### Pub
+
+* Use forward-slash paths to Git on Windows
+
 ## 2.0.0-dev.54.0
 
+### Core library changes
+
+* `dart:io`
+  * Added Dart-styled constants to  `ZLibOptions`, `FileMode`, `FileLock`,
+    `FileSystemEntityType`, `FileSystemEvent`, `ProcessStartMode`,
+    `ProcessSignal`, `InternetAddressType`, `InternetAddress`,
+    `SocketDirection`, `SocketOption`, `RawSocketEvent`, and `StdioType`, and
+    deprecated the old `SCREAMING_CAPS` constants.
+  * Added the Dart-styled top-level constants `zlib`, `gzip`, and
+    `systemEncoding`, and deprecated the old `SCREAMING_CAPS` top-level
+    constants.
+  * Removed the top-level `FileMode` constants `READ`, `WRITE`, `APPEND`,
+    `WRITE_ONLY`, and `WRITE_ONLY_APPEND`. Please use e.g. `FileMode.read`
+    instead.
+
 ### Tool Changes
 
 #### Pub
diff --git a/DEPS b/DEPS
index 6564eee..6e0ad81 100644
--- a/DEPS
+++ b/DEPS
@@ -98,7 +98,7 @@
   "intl_tag": "0.15.2",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.6",
-  "linter_tag": "0.1.49",
+  "linter_tag": "0.1.50",
   "logging_tag": "0.11.3+1",
   "markdown_tag": "1.1.1",
   "matcher_tag": "0.12.1+4",
@@ -114,7 +114,7 @@
   "ply_rev": "604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "1.3.4",
   "protobuf_tag": "0.7.1",
-  "pub_rev": "c61b8a3a24a7b1f931bad24b1f663e2c9a4c4354",
+  "pub_rev": "0c172864be2d2043a9d630e07f6b4eae7472653f",
   "pub_semver_tag": "1.4.1",
   "quiver_tag": "5aaa3f58c48608af5b027444d561270b53f15dbf",
   "resource_rev":"af5a5bf65511943398146cf146e466e5f0b95cb9",
diff --git a/docs/language/Dart.g b/docs/language/Dart.g
index 827db76..f586c96 100644
--- a/docs/language/Dart.g
+++ b/docs/language/Dart.g
@@ -471,7 +471,11 @@
     ;
 
 enumType
-    :    ENUM typeIdentifier LBRACE identifier (',' identifier)* (',')? RBRACE
+    :    ENUM typeIdentifier LBRACE enumEntry (',' enumEntry)* (',')? RBRACE
+    ;
+
+enumEntry
+    :    metadata identifier
     ;
 
 typeParameter
diff --git a/docs/language/dartLangSpec.tex b/docs/language/dartLangSpec.tex
index 30d92e1..3d99fb8 100644
--- a/docs/language/dartLangSpec.tex
+++ b/docs/language/dartLangSpec.tex
@@ -2738,21 +2738,26 @@
 An {\em enumerated type}, or {\em enum}, is used to represent a fixed number of constant values.
 
 \begin{grammar}
-{\bf enumType:}metadata \ENUM{} id `\{' id [\gcomma{} id]* [\gcomma{}] `\}'
+{\bf enumType:}metadata \ENUM{} identifier
+  \gnewline{} `\{' enumEntry (\gcomma{} enumEntry)* (\gcomma{})? `\}'
+  .
+
+{\bf enumEntry:}metadata identifier
   .
 \end{grammar}
 
 \LMHash{}
-The declaration of an enum of the form \code{metadata \ENUM{} E \{ id$_0$, \ldots,\ id$_{n-1}$\};}
+The declaration of an enum of the form
+\code{$m$ \ENUM{} E \{$m_0\,\,id_0, \ldots,\ m_{n-1}\,\,id_{n-1}$\}}
 has the same effect as a class declaration
 
 \begin{dartCode}
-metadata \CLASS{} E \{
+$m$ \CLASS{} E \{
   \FINAL{} int index;
   \CONST{} E(\THIS{}.index);
-  \STATIC{} \CONST{} E id$_0$ = \CONST{} E(0);
+  $m_0$ \STATIC{} \CONST{} E id$_0$ = \CONST{} E(0);
   $\ldots$
-  \STATIC{} \CONST{} E id$_{n-1}$ = const E(n - 1);
+  $m_{n-1}$ \STATIC{} \CONST{} E id$_{n-1}$ = const E(n - 1);
   \STATIC{} \CONST{} List<E> values = const <E>[id$_0, \ldots, $ id$_{n-1}$];
   String toString() => \{ 0: `E.id$_0$', $\ldots$, n-1: `E.id$_{n-1}$'\}[index]
 \}
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index b838056..110ad96 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -1275,15 +1275,13 @@
                 analysisServer, path, result.lineInfo, unit);
           });
         }
-        // TODO:(dantup) Uncomment this and equivilent in
-        // test/analysis/notification_folding_test.dart once the
-        // implementation is complete.
-        // if (analysisServer._hasAnalysisServiceSubscription(
-        //     AnalysisService.FOLDING, path)) {
-        //   _runDelayed(() {
-        //     sendAnalysisNotificationFolding(analysisServer, path, unit);
-        //   });
-        // }
+        if (analysisServer._hasAnalysisServiceSubscription(
+            AnalysisService.FOLDING, path)) {
+          _runDelayed(() {
+            sendAnalysisNotificationFolding(
+                analysisServer, path, result.lineInfo, unit);
+          });
+        }
         if (analysisServer._hasAnalysisServiceSubscription(
             AnalysisService.OUTLINE, path)) {
           _runDelayed(() {
diff --git a/pkg/analysis_server/lib/src/computer/computer_folding.dart b/pkg/analysis_server/lib/src/computer/computer_folding.dart
index 19b0c0d..bea49f1 100644
--- a/pkg/analysis_server/lib/src/computer/computer_folding.dart
+++ b/pkg/analysis_server/lib/src/computer/computer_folding.dart
@@ -4,18 +4,20 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 
 /**
  * A computer for [CompilationUnit] folding.
  */
 class DartUnitFoldingComputer {
+  final LineInfo _lineInfo;
   final CompilationUnit _unit;
 
   Directive _firstDirective, _lastDirective;
   final List<FoldingRegion> _foldingRegions = [];
 
-  DartUnitFoldingComputer(this._unit);
+  DartUnitFoldingComputer(this._lineInfo, this._unit);
 
   /**
    * Returns a list of folding regions, not `null`.
@@ -26,8 +28,10 @@
     if (_firstDirective != null &&
         _lastDirective != null &&
         _firstDirective != _lastDirective) {
-      _foldingRegions.add(new FoldingRegion(FoldingKind.DIRECTIVES,
-          _firstDirective.offset, _lastDirective.end - _firstDirective.offset));
+      _foldingRegions.add(new FoldingRegion(
+          FoldingKind.DIRECTIVES,
+          _firstDirective.keyword.end,
+          _lastDirective.end - _firstDirective.keyword.end));
     }
 
     return _foldingRegions;
@@ -42,11 +46,89 @@
   _DartUnitFoldingComputerVisitor(this._computer);
 
   @override
-  visitImportDirective(ImportDirective node) {
-    if (_computer._firstDirective == null) {
-      _computer._firstDirective = node;
+  Object visitBlockFunctionBody(BlockFunctionBody node) {
+    final FoldingKind kind = node.parent is ConstructorDeclaration ||
+            node.parent is MethodDeclaration
+        ? FoldingKind.CLASS_MEMBER
+        : FoldingKind.TOP_LEVEL_DECLARATION;
+    _addRegion(
+        node.block.leftBracket.end, node.block.rightBracket.offset, kind);
+    return super.visitBlockFunctionBody(node);
+  }
+
+  @override
+  Object visitClassDeclaration(ClassDeclaration node) {
+    _addRegion(node.leftBracket.end, node.rightBracket.offset,
+        FoldingKind.TOP_LEVEL_DECLARATION);
+    return super.visitClassDeclaration(node);
+  }
+
+  @override
+  Object visitAnnotation(Annotation node) {
+    if (node.arguments != null &&
+        node.arguments.leftParenthesis != null &&
+        node.arguments.rightParenthesis != null) {
+      _addRegion(
+          node.arguments.leftParenthesis.end,
+          node.arguments.rightParenthesis.offset,
+          FoldingKind.TOP_LEVEL_DECLARATION);
     }
-    _computer._lastDirective = node;
+    return super.visitAnnotation(node);
+  }
+
+  @override
+  Object visitComment(Comment node) {
+    final FoldingKind kind = node.isDocumentation
+        ? FoldingKind.DOCUMENTATION_COMMENT
+        : FoldingKind.COMMENT;
+    _addRegion(node.offset, node.end, kind);
+    return super.visitComment(node);
+  }
+
+  @override
+  Object visitExportDirective(ExportDirective node) {
+    _recordDirective(node);
+    return super.visitExportDirective(node);
+  }
+
+  @override
+  visitImportDirective(ImportDirective node) {
+    _recordDirective(node);
     return super.visitImportDirective(node);
   }
+
+  @override
+  Object visitLibraryDirective(LibraryDirective node) {
+    _recordDirective(node);
+    return super.visitLibraryDirective(node);
+  }
+
+  @override
+  Object visitPartDirective(PartDirective node) {
+    _recordDirective(node);
+    return super.visitPartDirective(node);
+  }
+
+  @override
+  Object visitPartOfDirective(PartOfDirective node) {
+    _recordDirective(node);
+    return super.visitPartOfDirective(node);
+  }
+
+  _addRegion(int startOffset, int endOffset, FoldingKind kind) {
+    // TODO(dantup): This class is marked deprecated; find out what to change it to.
+    final LineInfo_Location start =
+        _computer._lineInfo.getLocation(startOffset);
+    final LineInfo_Location end = _computer._lineInfo.getLocation(endOffset);
+
+    if (start.lineNumber != end.lineNumber) {
+      _computer._foldingRegions
+          .add(new FoldingRegion(kind, startOffset, endOffset - startOffset));
+    }
+  }
+
+  _recordDirective(Directive node) {
+    _computer._firstDirective ??= node;
+    _computer._lastDirective = node;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/operation/operation_analysis.dart b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
index c08b148..24a4811 100644
--- a/pkg/analysis_server/lib/src/operation/operation_analysis.dart
+++ b/pkg/analysis_server/lib/src/operation/operation_analysis.dart
@@ -81,10 +81,10 @@
   });
 }
 
-void sendAnalysisNotificationFolding(
-    AnalysisServer server, String file, CompilationUnit dartUnit) {
+void sendAnalysisNotificationFolding(AnalysisServer server, String file,
+    LineInfo lineInfo, CompilationUnit dartUnit) {
   _sendNotification(server, () {
-    var regions = new DartUnitFoldingComputer(dartUnit).compute();
+    var regions = new DartUnitFoldingComputer(lineInfo, dartUnit).compute();
     var params = new protocol.AnalysisFoldingParams(file, regions);
     server.sendNotification(params.toNotification());
   });
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index e111a67..ac0d78b 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -17,7 +17,6 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/file_instrumentation.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
-import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
@@ -199,12 +198,6 @@
   static const String FILE_READ_MODE = "file-read-mode";
 
   /**
-   * The name of the flag used when analyzing the flutter repository.
-   * See comments in source for `flutter analyze --watch`.
-   */
-  static const FLUTTER_REPO = "flutter-repo";
-
-  /**
    * The name of the option used to print usage information.
    */
   static const String HELP_OPTION = "help";
@@ -321,8 +314,6 @@
     }
     analysisServerOptions.useCFE = results[USE_CFE];
 
-    ContextBuilderOptions.flutterRepo = results[FLUTTER_REPO];
-
     telemetry.Analytics analytics = telemetry.createAnalyticsInstance(
         'UA-26406144-29', 'analysis-server',
         disableForSession: results[SUPPRESS_ANALYTICS_FLAG]);
@@ -501,10 +492,6 @@
         help: "enable sending instrumentation information to a server",
         defaultsTo: false,
         negatable: false);
-    parser.addFlag(FLUTTER_REPO,
-        help: 'used by "flutter analyze" to enable specific lints'
-            ' when analyzing the flutter repository',
-        hide: false);
     parser.addFlag(HELP_OPTION,
         help: "print this help message without starting a server",
         abbr: 'h',
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 79b6f55..a97741f 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -632,8 +632,7 @@
     AstNode argumentList = namedExpression.parent;
 
     // Prepare the invoked element.
-    var context =
-        new _ExecutableParameters(session, astProvider, argumentList.parent);
+    var context = new _ExecutableParameters(astProvider, argumentList.parent);
     if (context == null) {
       return;
     }
@@ -645,8 +644,15 @@
 
     Future<void> addParameter(int offset, String prefix, String suffix) async {
       if (offset != null) {
-        DartChangeBuilder changeBuilder = await context.addParameter(
-            offset, prefix, namedExpression.staticType, name, suffix);
+        var changeBuilder = new DartChangeBuilder(session);
+        await changeBuilder.addFileEdit(context.file, (builder) {
+          builder.addInsertion(offset, (builder) {
+            builder.write(prefix);
+            builder.writeParameterMatchingArgument(
+                namedExpression, 0, new Set<String>());
+            builder.write(suffix);
+          });
+        });
         _addFixFromBuilder(
             changeBuilder, DartFixKind.ADD_MISSING_PARAMETER_NAMED,
             args: [name]);
@@ -666,91 +672,67 @@
   }
 
   Future<Null> _addFix_addMissingParameter() async {
-    if (node is ArgumentList && node.parent is MethodInvocation) {
-      ArgumentList argumentList = node;
-      MethodInvocation invocation = node.parent;
-      SimpleIdentifier methodName = invocation.methodName;
-      Element targetElement = methodName.bestElement;
-      List<Expression> arguments = argumentList.arguments;
-      if (targetElement is ExecutableElement) {
-        List<ParameterElement> parameters = targetElement.parameters;
-        int numParameters = parameters.length;
-        Iterable<ParameterElement> requiredParameters =
-            parameters.takeWhile((p) => p.isNotOptional);
-        Iterable<ParameterElement> optionalParameters =
-            parameters.skipWhile((p) => p.isNotOptional);
-        // prepare the argument to add a new parameter for
-        int numRequired = requiredParameters.length;
-        if (numRequired >= arguments.length) {
-          return;
-        }
-        Expression argument = arguments[numRequired];
-        // prepare target
-        int targetOffset;
-        if (numRequired != 0) {
-          SimpleIdentifier lastName = await astProvider
-              .getParsedNameForElement(requiredParameters.last);
-          if (lastName != null) {
-            targetOffset = lastName.end;
-          } else {
-            return;
-          }
-        } else {
-          SimpleIdentifier targetName =
-              await astProvider.getParsedNameForElement(targetElement);
-          AstNode targetDeclaration = targetName?.parent;
-          if (targetDeclaration is FunctionDeclaration) {
-            FunctionExpression function = targetDeclaration.functionExpression;
-            Token paren = function.parameters?.leftParenthesis;
-            if (paren == null) {
-              return;
-            }
-            targetOffset = paren.end;
-          } else if (targetDeclaration is MethodDeclaration) {
-            Token paren = targetDeclaration.parameters?.leftParenthesis;
-            if (paren == null) {
-              return;
-            }
-            targetOffset = paren.end;
-          } else {
-            return;
-          }
-        }
-        Source targetSource = targetElement.source;
-        String targetFile = targetSource.fullName;
-        DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
-        await changeBuilder.addFileEdit(targetFile,
-            (DartFileEditBuilder builder) {
-          builder.addInsertion(targetOffset, (DartEditBuilder builder) {
-            if (numRequired != 0) {
-              builder.write(', ');
-            }
+    // The error is reported on ArgumentList.
+    if (node is! ArgumentList) {
+      return;
+    }
+    ArgumentList argumentList = node;
+    List<Expression> arguments = argumentList.arguments;
+
+    // Prepare the invoked element.
+    var context = new _ExecutableParameters(astProvider, node.parent);
+    if (context == null) {
+      return;
+    }
+
+    // prepare the argument to add a new parameter for
+    int numRequired = context.required.length;
+    if (numRequired >= arguments.length) {
+      return;
+    }
+    Expression argument = arguments[numRequired];
+
+    Future<void> addParameter(
+        FixKind kind, int offset, String prefix, String suffix) async {
+      if (offset != null) {
+        var changeBuilder = new DartChangeBuilder(session);
+        await changeBuilder.addFileEdit(context.file, (builder) {
+          builder.addInsertion(offset, (builder) {
+            builder.write(prefix);
             builder.writeParameterMatchingArgument(
                 argument, numRequired, new Set<String>());
-            if (numRequired != numParameters) {
-              builder.write(', ');
-            }
+            builder.write(suffix);
           });
         });
-        _addFixFromBuilder(
-            changeBuilder, DartFixKind.ADD_MISSING_PARAMETER_REQUIRED);
-        if (optionalParameters.isEmpty) {
-          DartChangeBuilder changeBuilder = new DartChangeBuilder(session);
-          await changeBuilder.addFileEdit(targetFile,
-              (DartFileEditBuilder builder) {
-            builder.addInsertion(targetOffset, (DartEditBuilder builder) {
-              if (numRequired != 0) {
-                builder.write(', ');
-              }
-              builder.write('[');
-              builder.writeParameterMatchingArgument(
-                  argument, numRequired, new Set<String>());
-              builder.write(']');
-            });
-          });
-          _addFixFromBuilder(
-              changeBuilder, DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL);
-        }
+        _addFixFromBuilder(changeBuilder, kind);
+      }
+    }
+
+    // Suggest adding a required parameter.
+    {
+      var kind = DartFixKind.ADD_MISSING_PARAMETER_REQUIRED;
+      if (context.required.isNotEmpty) {
+        var prevNode = await context.getParameterNode(context.required.last);
+        await addParameter(kind, prevNode?.end, ', ', '');
+      } else {
+        var parameterList = await context.getParameterList();
+        var offset = parameterList?.leftParenthesis?.end;
+        var suffix = context.executable.parameters.isNotEmpty ? ', ' : '';
+        await addParameter(kind, offset, '', suffix);
+      }
+    }
+
+    // Suggest adding the first optional positional parameter.
+    if (context.optionalPositional.isEmpty && context.named.isEmpty) {
+      var kind = DartFixKind.ADD_MISSING_PARAMETER_POSITIONAL;
+      var prefix = context.required.isNotEmpty ? ', [' : '[';
+      if (context.required.isNotEmpty) {
+        var prevNode = await context.getParameterNode(context.required.last);
+        await addParameter(kind, prevNode?.end, prefix, ']');
+      } else {
+        var parameterList = await context.getParameterList();
+        var offset = parameterList?.leftParenthesis?.end;
+        await addParameter(kind, offset, prefix, ']');
       }
     }
   }
@@ -3791,7 +3773,6 @@
  * [ExecutableElement], its parameters, and operations on them.
  */
 class _ExecutableParameters {
-  final AnalysisSession session;
   final AstProvider astProvider;
   final ExecutableElement executable;
 
@@ -3799,8 +3780,7 @@
   final List<ParameterElement> optionalPositional = [];
   final List<ParameterElement> named = [];
 
-  factory _ExecutableParameters(
-      AnalysisSession session, AstProvider astProvider, AstNode invocation) {
+  factory _ExecutableParameters(AstProvider astProvider, AstNode invocation) {
     Element element;
     if (invocation is InstanceCreationExpression) {
       element = invocation.staticElement;
@@ -3809,13 +3789,13 @@
       element = invocation.methodName.staticElement;
     }
     if (element is ExecutableElement) {
-      return new _ExecutableParameters._(session, astProvider, element);
+      return new _ExecutableParameters._(astProvider, element);
     } else {
       return null;
     }
   }
 
-  _ExecutableParameters._(this.session, this.astProvider, this.executable) {
+  _ExecutableParameters._(this.astProvider, this.executable) {
     for (var parameter in executable.parameters) {
       if (parameter.isNotOptional) {
         required.add(parameter);
@@ -3827,22 +3807,7 @@
     }
   }
 
-  /**
-   * Write the code for a new parameter with the given [type] and [name].
-   */
-  Future<DartChangeBuilder> addParameter(int offset, String prefix,
-      DartType type, String name, String suffix) async {
-    String targetFile = executable.source.fullName;
-    var changeBuilder = new DartChangeBuilder(session);
-    await changeBuilder.addFileEdit(targetFile, (builder) {
-      builder.addInsertion(offset, (builder) {
-        builder.write(prefix);
-        builder.writeParameter(name, type: type);
-        builder.write(suffix);
-      });
-    });
-    return changeBuilder;
-  }
+  String get file => executable.source.fullName;
 
   /**
    * Return the [FormalParameterList] of the [executable], or `null` is cannot
@@ -3851,7 +3816,9 @@
   Future<FormalParameterList> getParameterList() async {
     var name = await astProvider.getParsedNameForElement(executable);
     AstNode targetDeclaration = name?.parent;
-    if (targetDeclaration is FunctionDeclaration) {
+    if (targetDeclaration is ConstructorDeclaration) {
+      return targetDeclaration.parameters;
+    } else if (targetDeclaration is FunctionDeclaration) {
       FunctionExpression function = targetDeclaration.functionExpression;
       return function.parameters;
     } else if (targetDeclaration is MethodDeclaration) {
diff --git a/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart b/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart
index 0e5e556..94bfd73 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/naming_conventions.dart
@@ -178,17 +178,9 @@
       }
     }
   }
-  // first character
-  int currentChar = identifier.codeUnitAt(0);
-  if (!isLetter(currentChar) &&
-      currentChar != CHAR_UNDERSCORE &&
-      currentChar != CHAR_DOLLAR) {
-    String message = "$desc must begin with $beginDesc.";
-    return new RefactoringStatus.fatal(message);
-  }
-  // other characters
-  for (int i = 1; i < length; i++) {
-    currentChar = identifier.codeUnitAt(i);
+  // invalid characters
+  for (int i = 0; i < length; i++) {
+    int currentChar = identifier.codeUnitAt(i);
     if (!isLetterOrDigit(currentChar) &&
         currentChar != CHAR_UNDERSCORE &&
         currentChar != CHAR_DOLLAR) {
@@ -197,6 +189,14 @@
       return new RefactoringStatus.fatal(message);
     }
   }
+  // first character
+  final int currentChar = identifier.codeUnitAt(0);
+  if (!isLetter(currentChar) &&
+      currentChar != CHAR_UNDERSCORE &&
+      currentChar != CHAR_DOLLAR) {
+    String message = "$desc must begin with $beginDesc.";
+    return new RefactoringStatus.fatal(message);
+  }
   // OK
   return new RefactoringStatus();
 }
diff --git a/pkg/analysis_server/test/analysis/notification_folding_test.dart b/pkg/analysis_server/test/analysis/notification_folding_test.dart
index 51a400b..6d43ddb 100644
--- a/pkg/analysis_server/test/analysis/notification_folding_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_folding_test.dart
@@ -15,11 +15,7 @@
 
 main() {
   defineReflectiveSuite(() {
-    // TODO(dantup): Uncomment once implementation is complete.
-    // Cannot just mark the tests as @failingTest as they time out
-    // (no FOLDING notification ever) and failingTest doesn't seem
-    // to cover that.
-    // defineReflectiveTests(_AnalysisNotificationFoldingTest);
+    defineReflectiveTests(_AnalysisNotificationFoldingTest);
   });
 }
 
@@ -33,7 +29,9 @@
 ''';
 
   static final expectedResults = [
-    new FoldingRegion(FoldingKind.DIRECTIVES, 0, 40)
+    // We don't include the first "import" in the region because
+    // we want that to remain visible (not collapse).
+    new FoldingRegion(FoldingKind.DIRECTIVES, 6, 34)
   ];
 
   List<FoldingRegion> lastRegions;
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 0f0bb9c..be7a4cc 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -825,6 +825,90 @@
 ''');
   }
 
+  test_addMissingParameterNamed_constructor_hasNamed() async {
+    await resolveTestUnit('''
+class A {
+  A(int a, {int b}) {}
+}
+
+main() {
+  new A(1, b: 2, named: 3.0);
+}
+''');
+    await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
+class A {
+  A(int a, {int b, double named}) {}
+}
+
+main() {
+  new A(1, b: 2, named: 3.0);
+}
+''');
+  }
+
+  test_addMissingParameterNamed_constructor_hasRequired() async {
+    await resolveTestUnit('''
+class A {
+  A(int a) {}
+}
+
+main() {
+  new A(1, named: 2.0);
+}
+''');
+    await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
+class A {
+  A(int a, {double named}) {}
+}
+
+main() {
+  new A(1, named: 2.0);
+}
+''');
+  }
+
+  test_addMissingParameterNamed_constructor_noParameters() async {
+    await resolveTestUnit('''
+class A {
+  A() {}
+}
+
+main() {
+  new A(named: 42);
+}
+''');
+    await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
+class A {
+  A({int named}) {}
+}
+
+main() {
+  new A(named: 42);
+}
+''');
+  }
+
+  test_addMissingParameterNamed_constructor_noParameters_named() async {
+    await resolveTestUnit('''
+class A {
+  A.aaa() {}
+}
+
+main() {
+  new A.aaa(named: 42);
+}
+''');
+    await assertHasFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED, '''
+class A {
+  A.aaa({int named}) {}
+}
+
+main() {
+  new A.aaa(named: 42);
+}
+''');
+  }
+
   test_addMissingParameterNamed_function_hasNamed() async {
     await resolveTestUnit('''
 test(int a, {int b: 0}) {}
@@ -897,6 +981,19 @@
 ''');
   }
 
+  test_addMissingParameterNamed_method_hasOptionalPositional() async {
+    await resolveTestUnit('''
+class A {
+  test(int a, [int b]) {}
+
+  main() {
+    test(1, 2, named: 3.0);
+  }
+}
+''');
+    await assertNoFix(DartFixKind.ADD_MISSING_PARAMETER_NAMED);
+  }
+
   test_addMissingParameterNamed_method_hasRequired() async {
     await resolveTestUnit('''
 class A {
diff --git a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
index 4079387..bcdb836 100644
--- a/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/extract_method_test.dart
@@ -779,6 +779,22 @@
     assertRefactoringStatus(
         refactoring.checkName(), RefactoringProblemSeverity.FATAL,
         expectedMessage: "Method name must not be empty.");
+    // incorrect casing
+    refactoring.name = 'Aaa';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.WARNING,
+        expectedMessage: "Method name should start with a lowercase letter.");
+    // starts with digit
+    refactoring.name = '0aa';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.FATAL,
+        expectedMessage:
+            "Method name must begin with a lowercase letter or underscore.");
+    // invalid name (quote)
+    refactoring.name = '"';
+    assertRefactoringStatus(
+        refactoring.checkName(), RefactoringProblemSeverity.FATAL,
+        expectedMessage: "Method name must not contain '\"'.");
     // OK
     refactoring.name = 'res';
     assertRefactoringStatusOK(refactoring.checkName());
diff --git a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart b/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
index fb78873..9c3f157 100644
--- a/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/naming_conventions_test.dart
@@ -48,9 +48,14 @@
 
   void test_validateClassName_notIdentifierStart() {
     assertRefactoringStatus(
+        validateClassName("badName"), RefactoringProblemSeverity.WARNING,
+        expectedMessage: "Class name should start with an uppercase letter.");
+  }
+
+  void test_validateClassName_invalidCharacter() {
+    assertRefactoringStatus(
         validateClassName("-NewName"), RefactoringProblemSeverity.FATAL,
-        expectedMessage:
-            "Class name must begin with an uppercase letter or underscore.");
+        expectedMessage: "Class name must not contain '-'.");
   }
 
   void test_validateClassName_null() {
@@ -290,10 +295,16 @@
   }
 
   void test_validateFunctionTypeAliasName_notIdentifierStart() {
-    assertRefactoringStatus(validateFunctionTypeAliasName("-NewName"),
-        RefactoringProblemSeverity.FATAL,
+    assertRefactoringStatus(validateFunctionTypeAliasName("newName"),
+        RefactoringProblemSeverity.WARNING,
         expectedMessage:
-            "Function type alias name must begin with an uppercase letter or underscore.");
+            "Function type alias name should start with an uppercase letter.");
+  }
+
+  void test_validateFunctionTypeAliasName_invalidCharacters() {
+    assertRefactoringStatus(validateFunctionTypeAliasName("New-Name"),
+        RefactoringProblemSeverity.FATAL,
+        expectedMessage: "Function type alias name must not contain \'-\'.");
   }
 
   void test_validateFunctionTypeAliasName_null() {
diff --git a/pkg/analysis_server/test/src/computer/folding_computer_test.dart b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
index c9d00a1..72a26a7 100644
--- a/pkg/analysis_server/test/src/computer/folding_computer_test.dart
+++ b/pkg/analysis_server/test/src/computer/folding_computer_test.dart
@@ -41,13 +41,13 @@
 
   test_multiple_import_directives() async {
     String content = """
-/*1*/import 'dart:async';
+import/*1:INC*/ 'dart:async';
 
 // We can have comments
 import 'package:a/b.dart';
 import 'package:b/c.dart';
 
-import '../a.dart';/*1:DIRECTIVES*/
+import '../a.dart';/*1:EXC:DIRECTIVES*/
 
 main() {}
 """;
@@ -56,11 +56,116 @@
     _compareRegions(regions, content);
   }
 
+  test_multiple_directive_types() async {
+    String content = """
+import/*1:INC*/ 'dart:async';
+
+// We can have comments
+import 'package:a/b.dart';
+import 'package:b/c.dart';
+
+export '../a.dart';/*1:EXC:DIRECTIVES*/
+
+main() {}
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_function() async {
+    String content = """
+// Content before
+
+main() {/*1:INC*/
+  print("Hello, world!");
+/*1:INC:TOP_LEVEL_DECLARATION*/}
+
+// Content after
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_function_with_dart_doc() async {
+    String content = """
+// Content before
+
+/*1:EXC*//// This is a doc comment
+/// that spans lines/*1:INC:DOCUMENTATION_COMMENT*/
+main() {/*2:INC*/
+  print("Hello, world!");
+/*2:INC:TOP_LEVEL_DECLARATION*/}
+
+// Content after
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_nested_function() async {
+    String content = """
+// Content before
+
+main() {/*1:INC*/
+  doPrint() {/*2:INC*/
+    print("Hello, world!");
+  /*2:INC:TOP_LEVEL_DECLARATION*/}
+  doPrint();
+/*1:INC:TOP_LEVEL_DECLARATION*/}
+
+// Content after
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_class() async {
+    String content = """
+// Content before
+
+class Person {/*1:INC*/
+  Person() {/*2:INC*/
+    print("Hello, world!");
+  /*2:INC:CLASS_MEMBER*/}
+
+  void sayHello() {/*3:INC*/
+    print("Hello, world!");
+  /*3:INC:CLASS_MEMBER*/}
+/*1:INC:TOP_LEVEL_DECLARATION*/}
+
+// Content after
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
+  test_annotations() async {
+    String content = """
+@myMultilineAnnotation(/*1:INC*/
+  "this",
+  "is a test"
+/*1:INC:TOP_LEVEL_DECLARATION*/)
+@another()
+@andAnother
+main() {/*2:INC*/
+  print("Hello, world!");
+/*2:INC:TOP_LEVEL_DECLARATION*/}
+""";
+
+    final regions = await _computeRegions(content);
+    _compareRegions(regions, content);
+  }
+
   /// Compares provided folding regions with expected
   /// regions extracted from the comments in the provided content.
   void _compareRegions(List<FoldingRegion> regions, String content) {
     // Find all numeric markers for region starts.
-    final regex = new RegExp(r'/\*(\d+)\*/');
+    final regex = new RegExp(r'/\*(\d+):(INC|EXC)\*/');
     final expectedRegions = regex.allMatches(content);
 
     // Check we didn't get more than expected, since the loop below only
@@ -71,14 +176,22 @@
     // ensure it's in the results.
     expectedRegions.forEach((m) {
       final i = m.group(1);
+      final inclusiveStart = m.group(2) == "INC";
       // Find the end marker.
-      final endMatch = new RegExp('/\\*$i:(.+?)\\*/').firstMatch(content);
+      final endMatch =
+          new RegExp('/\\*$i:(INC|EXC):(.+?)\\*/').firstMatch(content);
 
-      final expectedStart = m.end;
-      final expectedLength = endMatch.start - expectedStart;
-      final expectedKindString = endMatch.group(1);
-      final expectedKind = FoldingKind.VALUES
-          .firstWhere((f) => f.toString() == 'FoldingKind.$expectedKindString');
+      final inclusiveEnd = endMatch.group(1) == "INC";
+      final expectedKindString = endMatch.group(2);
+      final expectedKind = FoldingKind.VALUES.firstWhere(
+          (f) => f.toString() == 'FoldingKind.$expectedKindString',
+          orElse: () => throw new Exception(
+              "Annotated test code references $expectedKindString but "
+              "this does not exist in FoldingKind"));
+
+      final expectedStart = inclusiveStart ? m.start : m.end;
+      final expectedLength =
+          (inclusiveEnd ? endMatch.end : endMatch.start) - expectedStart;
 
       expect(
           regions,
@@ -90,7 +203,8 @@
   Future<List<FoldingRegion>> _computeRegions(String sourceContent) async {
     newFile(sourcePath, content: sourceContent);
     ResolveResult result = await driver.getResult(sourcePath);
-    DartUnitFoldingComputer computer = new DartUnitFoldingComputer(result.unit);
+    DartUnitFoldingComputer computer =
+        new DartUnitFoldingComputer(result.lineInfo, result.unit);
     return computer.compute();
   }
 }
diff --git a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
index b03c081..ef5fb8f 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -779,6 +779,7 @@
 import 'dart:isolate';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer_plugin/plugin/plugin.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart';
 import 'package:analyzer_plugin/starter.dart';
@@ -802,6 +803,9 @@
   String get version => '0.0.1';
 
   @override
+  AnalysisDriverGeneric createAnalysisDriver(ContextRoot contextRoot) => null;
+
+  @override
   Future<AnalysisHandleWatchEventsResult> handleAnalysisHandleWatchEvents(
       AnalysisHandleWatchEventsParams parameters) async =>
     new AnalysisHandleWatchEventsResult();
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 5b3e1db..7be888a 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -28,7 +28,6 @@
 import 'package:analyzer/src/generated/workspace.dart';
 import 'package:analyzer/src/lint/registry.dart';
 import 'package:analyzer/src/plugin/resolver_provider.dart';
-import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart';
 import 'package:analyzer/src/task/options.dart';
@@ -487,18 +486,6 @@
           verbose('Using default lint rules');
         }
       }
-      if (ContextBuilderOptions.flutterRepo) {
-        // TODO(devoncarew): Should we still be auto-inserting this?
-        const lintName = 'public_member_api_docs';
-        Linter rule = options.lintRules.firstWhere(
-            (Linter lint) => lint.name == lintName,
-            orElse: () => null);
-        if (rule == null) {
-          rule = Registry.ruleRegistry
-              .firstWhere((Linter lint) => lint.name == lintName);
-          options.lintRules = new List.from(options.lintRules)..add(rule);
-        }
-      }
     } else {
       verbose('Using default analysis options');
     }
@@ -656,12 +643,6 @@
  */
 class ContextBuilderOptions {
   /**
-   * A flag indicating that the flutter repository is being analyzed.
-   * See comments in source for `flutter analyze --watch`.
-   */
-  static bool flutterRepo = false;
-
-  /**
    * The results of parsing the command line arguments as defined by
    * [defineAnalysisArguments] or `null` if none.
    */
diff --git a/pkg/analyzer/lib/src/fasta/ast_body_builder.dart b/pkg/analyzer/lib/src/fasta/ast_body_builder.dart
new file mode 100644
index 0000000..c24180f1
--- /dev/null
+++ b/pkg/analyzer/lib/src/fasta/ast_body_builder.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/ast/ast.dart' show Expression, Statement;
+import 'package:analyzer/src/fasta/ast_building_factory.dart'
+    show AstBuildingForest;
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:front_end/src/fasta/kernel/body_builder.dart' show BodyBuilder;
+import 'package:front_end/src/fasta/kernel/kernel_builder.dart'
+    show KernelClassBuilder, KernelLibraryBuilder, ModifierBuilder, Scope;
+import 'package:front_end/src/fasta/type_inference/type_inferrer.dart'
+    show TypeInferrer;
+import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
+import 'package:kernel/core_types.dart' show CoreTypes;
+
+class AstBodyBuilder extends BodyBuilder<Expression, Statement, dynamic> {
+  @override
+  final AstBuildingForest forest;
+
+  AstBodyBuilder(
+      KernelLibraryBuilder library,
+      ModifierBuilder member,
+      Scope scope,
+      Scope formalParameterScope,
+      ClassHierarchy hierarchy,
+      CoreTypes coreTypes,
+      KernelClassBuilder classBuilder,
+      bool isInstanceMember,
+      Uri uri,
+      TypeInferrer typeInferrer,
+      TypeProvider typeProvider)
+      : forest = new AstBuildingForest(typeProvider),
+        super(library, member, scope, formalParameterScope, hierarchy,
+            coreTypes, classBuilder, isInstanceMember, uri, typeInferrer);
+
+  @override
+  void printEvent(String name) {
+    // TODO(scheglov): Call of super is commented out to prevent spamming.
+//    super.printEvent(name);
+  }
+}
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 9c01d75..b654900 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -2530,6 +2530,12 @@
     push(popTypedList<Annotation>(count) ?? NullValue.Metadata);
   }
 
+  @override
+  void printEvent(String name) {
+    // TODO(scheglov): Call of super is commented out to prevent spamming.
+//    super.printEvent(name);
+  }
+
   ParameterKind _toAnalyzerParameterKind(FormalParameterKind type) {
     if (type == FormalParameterKind.optionalPositional) {
       return ParameterKind.POSITIONAL;
diff --git a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
index 96318e4..4382c12 100644
--- a/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_building_factory.dart
@@ -5,17 +5,22 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/src/dart/ast/ast_factory.dart';
+import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
 import 'package:front_end/src/fasta/kernel/forest.dart';
 import 'package:kernel/ast.dart' as kernel;
 
 /// An implementation of a [Forest] that can be used to build an AST structure.
 class AstBuildingForest
     implements Forest<Expression, Statement, Token, _Arguments> {
+  /// The type provider used to resolve the types of literal nodes, or `null` if
+  /// type resolution is not being performed.
+  final TypeProvider _typeProvider;
+
   /// The factory used to create AST nodes.
   AstFactoryImpl astFactory = new AstFactoryImpl();
 
   /// Initialize a newly created AST-building forest.
-  AstBuildingForest();
+  AstBuildingForest(this._typeProvider);
 
   @override
   _Arguments arguments(List<Expression> positional, Token location,
@@ -79,14 +84,13 @@
           condition, question, thenExpression, colon, elseExpression);
 
   @override
-  kernel.DartType getTypeAt(Object typeArguments, int index) {
-    return null; // (typeArguments as TypeArgumentList).arguments[index].type.kernelType;
+  kernel.DartType getTypeAt(TypeArgumentList typeArguments, int index) {
+    return null; // typeArguments.arguments[index].type.kernelType;
   }
 
   @override
-  int getTypeCount(Object typeArguments) {
-    return (typeArguments as TypeArgumentList).arguments.length;
-  }
+  int getTypeCount(TypeArgumentList typeArguments) =>
+      typeArguments.arguments.length;
 
   @override
   bool isErroneousNode(covariant node) => false; // ???
@@ -98,15 +102,18 @@
 
   @override
   Expression literalBool(bool value, Token location) =>
-      astFactory.booleanLiteral(location, value);
+      astFactory.booleanLiteral(location, value)
+        ..staticType = _typeProvider?.boolType;
 
   @override
   Expression literalDouble(double value, Token location) =>
-      astFactory.doubleLiteral(location, value);
+      astFactory.doubleLiteral(location, value)
+        ..staticType = _typeProvider?.doubleType;
 
   @override
   Expression literalInt(int value, Token location) =>
-      astFactory.integerLiteral(location, value);
+      astFactory.integerLiteral(location, value)
+        ..staticType = _typeProvider?.intType;
 
   @override
   Expression literalList(
@@ -134,22 +141,26 @@
           constKeyword, typeArguments, leftBracket, entries, rightBracket);
 
   @override
-  Expression literalNull(Token location) => astFactory.nullLiteral(location);
+  Expression literalNull(Token location) =>
+      astFactory.nullLiteral(location)..staticType = _typeProvider?.nullType;
 
   @override
   Expression literalString(String value, Token location) =>
-      astFactory.simpleStringLiteral(location, value);
+      astFactory.simpleStringLiteral(location, value)
+        ..staticType = _typeProvider?.stringType;
 
   @override
   Expression literalSymbol(String value, Token location) {
     // TODO(brianwilkerson) Get the missing information.
-    return astFactory.symbolLiteral(location, null /* components */);
+    return astFactory.symbolLiteral(location, null /* components */)
+      ..staticType = _typeProvider?.symbolType;
   }
 
   @override
   Expression literalType(covariant type, Token location) {
     // TODO(brianwilkerson) Capture the type information.
-    return astFactory.simpleIdentifier(location);
+    return astFactory.simpleIdentifier(location)
+      ..staticType = _typeProvider?.typeType;
   }
 
   @override
@@ -167,7 +178,8 @@
 
   @override
   Expression notExpression(Expression operand, Token operator) =>
-      astFactory.prefixExpression(operator, operand);
+      astFactory.prefixExpression(operator, operand)
+        ..staticType = _typeProvider?.boolType;
 
   @override
   int readOffset(AstNode node) => node.offset;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index a96b872..8d228f3 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -28,6 +28,7 @@
 import 'package:front_end/src/fasta/parser/identifier_context.dart' as fasta;
 import 'package:front_end/src/fasta/parser/member_kind.dart' as fasta;
 import 'package:front_end/src/fasta/parser/parser.dart' as fasta;
+import 'package:front_end/src/fasta/parser/type_info.dart' as fasta;
 import 'package:front_end/src/fasta/scanner.dart' as fasta;
 
 export 'package:analyzer/src/dart/ast/utilities.dart' show ResolutionCopier;
diff --git a/pkg/analyzer/lib/src/generated/parser_fasta.dart b/pkg/analyzer/lib/src/generated/parser_fasta.dart
index 2a7322b..3944ae3 100644
--- a/pkg/analyzer/lib/src/generated/parser_fasta.dart
+++ b/pkg/analyzer/lib/src/generated/parser_fasta.dart
@@ -291,8 +291,10 @@
 
   @override
   TypeArgumentList parseTypeArgumentList() {
-    currentToken = fastaParser
-        .parseTypeArgumentsOpt(fastaParser.syntheticPreviousToken(currentToken))
+    Token previous = fastaParser.syntheticPreviousToken(currentToken);
+    currentToken = fasta
+        .computeTypeParamOrArg(previous)
+        .parseArguments(previous, fastaParser)
         .next;
     return astBuilder.pop();
   }
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 3120bb0..5103eca 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -53,6 +53,12 @@
 @reflectiveTest
 class ClassMemberParserTest_Fasta extends FastaParserTestCase
     with ClassMemberParserTestMixin {
+  @failingTest
+  @override
+  void test_parseAwaitExpression_inSync() {
+    super.test_parseAwaitExpression_inSync();
+  }
+
   @override
   void test_parseClassMember_method_generic_comment_noReturnType() {
     // Ignored: Fasta does not support the generic comment syntax.
diff --git a/pkg/analyzer/test/generated/parser_forest_test.dart b/pkg/analyzer/test/generated/parser_forest_test.dart
index 7b9bc03..5c22fec 100644
--- a/pkg/analyzer/test/generated/parser_forest_test.dart
+++ b/pkg/analyzer/test/generated/parser_forest_test.dart
@@ -2,43 +2,24 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'dart:async';
-import 'dart:io' show File;
-
-import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/src/fasta/ast_building_factory.dart';
-import "package:front_end/src/api_prototype/front_end.dart";
-import "package:front_end/src/api_prototype/memory_file_system.dart";
-import "package:front_end/src/base/processed_options.dart";
-import "package:front_end/src/compute_platform_binaries_location.dart";
-import 'package:front_end/src/fasta/compiler_context.dart';
-import 'package:front_end/src/fasta/constant_context.dart';
-import 'package:front_end/src/fasta/dill/built_type_builder.dart';
-import 'package:front_end/src/fasta/dill/dill_target.dart';
-import "package:front_end/src/fasta/fasta_codes.dart";
-import 'package:front_end/src/fasta/kernel/body_builder.dart';
-import 'package:front_end/src/fasta/kernel/forest.dart';
-import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
-import "package:front_end/src/fasta/kernel/kernel_target.dart";
-import 'package:front_end/src/fasta/modifier.dart' as Modifier;
-import 'package:front_end/src/fasta/parser/parser.dart';
-import 'package:front_end/src/fasta/scanner.dart';
-import 'package:front_end/src/fasta/ticker.dart';
-import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
-import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
-import 'package:front_end/src/fasta/uri_translator_impl.dart';
-import 'package:front_end/src/scanner/token.dart';
-import 'package:kernel/class_hierarchy.dart' as kernel;
-import 'package:kernel/core_types.dart' as kernel;
-import 'package:kernel/kernel.dart' as kernel;
-import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../src/fasta/body_builder_test_helper.dart';
 import 'parser_test.dart';
 
 main() async {
   defineReflectiveSuite(() {
+    // TODO(brianwilkerson) Implement the remaining parser tests.
+//    defineReflectiveTests(ClassMemberParserTest_Forest);
+//    defineReflectiveTests(ComplexParserTest_Forest);
+//    defineReflectiveTests(ErrorParserTest_Forest);
     defineReflectiveTests(ExpressionParserTest_Forest);
+//    defineReflectiveTests(FormalParameterParserTest_Forest);
+//    defineReflectiveTests(NonErrorParserTest_Forest);
+//    defineReflectiveTests(RecoveryParserTest_Forest);
+//    defineReflectiveTests(SimpleParserTest_Forest);
+    defineReflectiveTests(StatementParserTest_Forest);
+    defineReflectiveTests(TopLevelParserTest_Forest);
   });
 }
 
@@ -46,19 +27,9 @@
  * Tests of the fasta parser based on [ExpressionParserTestMixin].
  */
 @reflectiveTest
-class ExpressionParserTest_Forest extends FastaParserTestCase
+class ExpressionParserTest_Forest extends FastaBodyBuilderTestCase
     with ExpressionParserTestMixin {
-  @failingTest
-  void test_1_plus_2() {
-    Expression expression = parseAdditiveExpression('1 + 2');
-    expect(expression, isNotNull);
-    assertNoErrors();
-    var binaryExpression = expression as BinaryExpression;
-    expect(binaryExpression.leftOperand, isNotNull);
-    expect(binaryExpression.operator, isNotNull);
-    expect(binaryExpression.operator.type, TokenType.PLUS);
-    expect(binaryExpression.rightOperand, isNotNull);
-  }
+  ExpressionParserTest_Forest() : super(false);
 
   @failingTest
   void test_namedArgument() {
@@ -355,11 +326,6 @@
   }
 
   @failingTest
-  void test_parseConstExpression_listLiteral_untyped() {
-    super.test_parseConstExpression_listLiteral_untyped();
-  }
-
-  @failingTest
   void test_parseConstExpression_mapLiteral_typed() {
     super.test_parseConstExpression_mapLiteral_typed();
   }
@@ -370,11 +336,6 @@
   }
 
   @failingTest
-  void test_parseConstExpression_mapLiteral_untyped() {
-    super.test_parseConstExpression_mapLiteral_untyped();
-  }
-
-  @failingTest
   void test_parseEqualityExpression_normal() {
     super.test_parseEqualityExpression_normal();
   }
@@ -586,26 +547,11 @@
   }
 
   @failingTest
-  void test_parseListLiteral_multiple() {
-    super.test_parseListLiteral_multiple();
-  }
-
-  @failingTest
-  void test_parseListLiteral_single() {
-    super.test_parseListLiteral_single();
-  }
-
-  @failingTest
   void test_parseListLiteral_single_withTypeArgument() {
     super.test_parseListLiteral_single_withTypeArgument();
   }
 
   @failingTest
-  void test_parseListOrMapLiteral_list_noType() {
-    super.test_parseListOrMapLiteral_list_noType();
-  }
-
-  @failingTest
   void test_parseListOrMapLiteral_list_type() {
     super.test_parseListOrMapLiteral_list_type();
   }
@@ -747,16 +693,6 @@
   }
 
   @failingTest
-  void test_parsePrimaryExpression_double() {
-    super.test_parsePrimaryExpression_double();
-  }
-
-  @failingTest
-  void test_parsePrimaryExpression_false() {
-    super.test_parsePrimaryExpression_false();
-  }
-
-  @failingTest
   void test_parsePrimaryExpression_function_arguments() {
     super.test_parsePrimaryExpression_function_arguments();
   }
@@ -772,31 +708,11 @@
   }
 
   @failingTest
-  void test_parsePrimaryExpression_hex() {
-    super.test_parsePrimaryExpression_hex();
-  }
-
-  @failingTest
   void test_parsePrimaryExpression_identifier() {
     super.test_parsePrimaryExpression_identifier();
   }
 
   @failingTest
-  void test_parsePrimaryExpression_int() {
-    super.test_parsePrimaryExpression_int();
-  }
-
-  @failingTest
-  void test_parsePrimaryExpression_listLiteral() {
-    super.test_parsePrimaryExpression_listLiteral();
-  }
-
-  @failingTest
-  void test_parsePrimaryExpression_listLiteral_index() {
-    super.test_parsePrimaryExpression_listLiteral_index();
-  }
-
-  @failingTest
   void test_parsePrimaryExpression_listLiteral_typed() {
     super.test_parsePrimaryExpression_listLiteral_typed();
   }
@@ -807,11 +723,6 @@
   }
 
   @failingTest
-  void test_parsePrimaryExpression_mapLiteral() {
-    super.test_parsePrimaryExpression_mapLiteral();
-  }
-
-  @failingTest
   void test_parsePrimaryExpression_mapLiteral_typed() {
     super.test_parsePrimaryExpression_mapLiteral_typed();
   }
@@ -827,31 +738,11 @@
   }
 
   @failingTest
-  void test_parsePrimaryExpression_null() {
-    super.test_parsePrimaryExpression_null();
-  }
-
-  @failingTest
   void test_parsePrimaryExpression_parenthesized() {
     super.test_parsePrimaryExpression_parenthesized();
   }
 
   @failingTest
-  void test_parsePrimaryExpression_string() {
-    super.test_parsePrimaryExpression_string();
-  }
-
-  @failingTest
-  void test_parsePrimaryExpression_string_multiline() {
-    super.test_parsePrimaryExpression_string_multiline();
-  }
-
-  @failingTest
-  void test_parsePrimaryExpression_string_raw() {
-    super.test_parsePrimaryExpression_string_raw();
-  }
-
-  @failingTest
   void test_parsePrimaryExpression_super() {
     super.test_parsePrimaryExpression_super();
   }
@@ -862,11 +753,6 @@
   }
 
   @failingTest
-  void test_parsePrimaryExpression_true() {
-    super.test_parsePrimaryExpression_true();
-  }
-
-  @failingTest
   void test_parseRedirectingConstructorInvocation_named() {
     super.test_parseRedirectingConstructorInvocation_named();
   }
@@ -962,56 +848,11 @@
   }
 
   @failingTest
-  void test_parseStringLiteral_multiline_encodedSpace() {
-    super.test_parseStringLiteral_multiline_encodedSpace();
-  }
-
-  @failingTest
   void test_parseStringLiteral_multiline_endsWithInterpolation() {
     super.test_parseStringLiteral_multiline_endsWithInterpolation();
   }
 
   @failingTest
-  void test_parseStringLiteral_multiline_escapedBackslash() {
-    super.test_parseStringLiteral_multiline_escapedBackslash();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_escapedBackslash_raw() {
-    super.test_parseStringLiteral_multiline_escapedBackslash_raw();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_escapedEolMarker() {
-    super.test_parseStringLiteral_multiline_escapedEolMarker();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_escapedEolMarker_raw() {
-    super.test_parseStringLiteral_multiline_escapedEolMarker_raw();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_escapedSpaceAndEolMarker() {
-    super.test_parseStringLiteral_multiline_escapedSpaceAndEolMarker();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_escapedSpaceAndEolMarker_raw() {
-    super.test_parseStringLiteral_multiline_escapedSpaceAndEolMarker_raw();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_escapedTab() {
-    super.test_parseStringLiteral_multiline_escapedTab();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_escapedTab_raw() {
-    super.test_parseStringLiteral_multiline_escapedTab_raw();
-  }
-
-  @failingTest
   void test_parseStringLiteral_multiline_quoteAfterInterpolation() {
     super.test_parseStringLiteral_multiline_quoteAfterInterpolation();
   }
@@ -1022,31 +863,11 @@
   }
 
   @failingTest
-  void test_parseStringLiteral_multiline_twoSpaces() {
-    super.test_parseStringLiteral_multiline_twoSpaces();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_twoSpaces_raw() {
-    super.test_parseStringLiteral_multiline_twoSpaces_raw();
-  }
-
-  @failingTest
-  void test_parseStringLiteral_multiline_untrimmed() {
-    super.test_parseStringLiteral_multiline_untrimmed();
-  }
-
-  @failingTest
   void test_parseStringLiteral_quoteAfterInterpolation() {
     super.test_parseStringLiteral_quoteAfterInterpolation();
   }
 
   @failingTest
-  void test_parseStringLiteral_single() {
-    super.test_parseStringLiteral_single();
-  }
-
-  @failingTest
   void test_parseStringLiteral_startsWithInterpolation() {
     super.test_parseStringLiteral_startsWithInterpolation();
   }
@@ -1163,129 +984,1381 @@
 }
 
 /**
- * Implementation of [AbstractParserTestCase] specialized for testing building
- * Analyzer AST using the fasta [Forest] API.
+ * Tests of the fasta parser based on [StatementParserTestMixin].
  */
-class FastaParserTestCase extends Object
-    with ParserTestHelpers
-    implements AbstractParserTestCase {
-  // TODO(danrubel): Consider HybridFileSystem.
-  static final MemoryFileSystem fs =
-      new MemoryFileSystem(Uri.parse("org-dartlang-test:///"));
+@reflectiveTest
+class StatementParserTest_Forest extends FastaBodyBuilderTestCase
+    with StatementParserTestMixin {
+  StatementParserTest_Forest() : super(false);
 
-  /// The custom URI used to locate the dill file in the MemoryFileSystem.
-  static final Uri sdkSummary = fs.currentDirectory.resolve("vm_platform.dill");
-
-  /// The in memory test code URI
-  static final Uri entryPoint = fs.currentDirectory.resolve("main.dart");
-
-  static ProcessedOptions options;
-
-  static KernelTarget kernelTarget;
-
-  @override
-  Expression parseAdditiveExpression(String code) {
-    ScannerResult scan = scanString(code);
-
-    return CompilerContext.runWithOptions(options, (CompilerContext c) {
-      KernelLibraryBuilder library = new KernelLibraryBuilder(
-        entryPoint,
-        entryPoint,
-        kernelTarget.loader,
-        null /* actualOrigin */,
-        null /* enclosingLibrary */,
-      );
-      List<KernelTypeVariableBuilder> typeVariableBuilders =
-          <KernelTypeVariableBuilder>[];
-      List<KernelFormalParameterBuilder> formalParameterBuilders =
-          <KernelFormalParameterBuilder>[];
-      KernelProcedureBuilder procedureBuilder = new KernelProcedureBuilder(
-          null /* metadata */,
-          Modifier.staticMask /* or Modifier.varMask */,
-          new BuiltTypeBuilder(new kernel.DynamicType()),
-          "analyzerTest",
-          typeVariableBuilders,
-          formalParameterBuilders,
-          kernel.ProcedureKind.Method,
-          library,
-          -1 /* charOffset */,
-          -1 /* charOpenParenOffset */,
-          -1 /* charEndOffset */);
-
-      TypeInferrerDisabled typeInferrer =
-          new TypeInferrerDisabled(new TypeSchemaEnvironment(
-        kernelTarget.loader.coreTypes,
-        kernelTarget.loader.hierarchy,
-        // TODO(danrubel): Enable strong mode.
-        false /* strong mode */,
-      ));
-
-      BodyBuilder builder = new BodyBuilder(
-        library,
-        procedureBuilder,
-        library.scope,
-        procedureBuilder.computeFormalParameterScope(library.scope),
-        kernelTarget.loader.hierarchy,
-        kernelTarget.loader.coreTypes,
-        null /* classBuilder */,
-        false /* isInstanceMember */,
-        null /* uri */,
-        typeInferrer,
-        new AstBuildingForest(),
-      )..constantContext = ConstantContext.none; // .inferred ?
-
-      Parser parser = new Parser(builder);
-      parser.parseExpression(parser.syntheticPreviousToken(scan.tokens));
-      return builder.pop();
-    });
+  @failingTest
+  void test_invalid_typeParamAnnotation() {
+    super.test_invalid_typeParamAnnotation();
   }
 
-  Future setUp() async {
-    // TODO(danrubel): Tear down once all tests in group have been run.
-    if (options != null) {
-      return;
-    }
-
-    // Read the dill file containing kernel platform summaries into memory.
-    List<int> sdkSummaryBytes = await new File.fromUri(
-            computePlatformBinariesLocation().resolve("vm_platform.dill"))
-        .readAsBytes();
-    fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryBytes);
-
-    final CompilerOptions optionBuilder = new CompilerOptions()
-      ..strongMode = false // TODO(danrubel): enable strong mode.
-      ..reportMessages = true
-      ..verbose = false
-      ..fileSystem = fs
-      ..sdkSummary = sdkSummary
-      ..onProblem = (FormattedMessage problem, Severity severity,
-          List<FormattedMessage> context) {
-        // TODO(danrubel): Capture problems and check against expectations.
-        print(problem.formatted);
-      };
-
-    options = new ProcessedOptions(optionBuilder, false, [entryPoint]);
-
-    UriTranslatorImpl uriTranslator = await options.getUriTranslator();
-
-    await CompilerContext.runWithOptions(options, (CompilerContext c) async {
-      DillTarget dillTarget = new DillTarget(
-          new Ticker(isVerbose: false), uriTranslator, options.target);
-
-      kernelTarget = new KernelTarget(fs, true, dillTarget, uriTranslator);
-
-      // Load the dill file containing platform code.
-      dillTarget.loader.read(Uri.parse('dart:core'), -1, fileUri: sdkSummary);
-      kernel.Component sdkComponent =
-          kernel.loadComponentFromBytes(sdkSummaryBytes);
-      dillTarget.loader
-          .appendLibraries(sdkComponent, byteCount: sdkSummaryBytes.length);
-      await dillTarget.buildOutlines();
-      await kernelTarget.buildOutlines();
-      kernelTarget.computeCoreTypes();
-      assert(kernelTarget.loader.coreTypes != null);
-    });
+  @failingTest
+  void test_invalid_typeParamAnnotation2() {
+    super.test_invalid_typeParamAnnotation2();
   }
 
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+  @failingTest
+  void test_invalid_typeParamAnnotation3() {
+    super.test_invalid_typeParamAnnotation3();
+  }
+
+  @failingTest
+  void test_parseAssertStatement() {
+    super.test_parseAssertStatement();
+  }
+
+  @failingTest
+  void test_parseAssertStatement_messageLowPrecedence() {
+    super.test_parseAssertStatement_messageLowPrecedence();
+  }
+
+  @failingTest
+  void test_parseAssertStatement_messageString() {
+    super.test_parseAssertStatement_messageString();
+  }
+
+  @failingTest
+  void test_parseAssertStatement_trailingComma_message() {
+    super.test_parseAssertStatement_trailingComma_message();
+  }
+
+  @failingTest
+  void test_parseAssertStatement_trailingComma_noMessage() {
+    super.test_parseAssertStatement_trailingComma_noMessage();
+  }
+
+  @failingTest
+  void test_parseBlock_empty() {
+    super.test_parseBlock_empty();
+  }
+
+  @failingTest
+  void test_parseBlock_nonEmpty() {
+    super.test_parseBlock_nonEmpty();
+  }
+
+  @failingTest
+  void test_parseBreakStatement_label() {
+    super.test_parseBreakStatement_label();
+  }
+
+  @failingTest
+  void test_parseBreakStatement_noLabel() {
+    super.test_parseBreakStatement_noLabel();
+  }
+
+  @failingTest
+  void test_parseContinueStatement_label() {
+    super.test_parseContinueStatement_label();
+  }
+
+  @failingTest
+  void test_parseContinueStatement_noLabel() {
+    super.test_parseContinueStatement_noLabel();
+  }
+
+  @failingTest
+  void test_parseDoStatement() {
+    super.test_parseDoStatement();
+  }
+
+  @failingTest
+  void test_parseEmptyStatement() {
+    super.test_parseEmptyStatement();
+  }
+
+  @failingTest
+  void test_parseForStatement_each_await() {
+    super.test_parseForStatement_each_await();
+  }
+
+  @failingTest
+  void test_parseForStatement_each_genericFunctionType() {
+    super.test_parseForStatement_each_genericFunctionType();
+  }
+
+  @failingTest
+  void test_parseForStatement_each_identifier() {
+    super.test_parseForStatement_each_identifier();
+  }
+
+  @failingTest
+  void test_parseForStatement_each_noType_metadata() {
+    super.test_parseForStatement_each_noType_metadata();
+  }
+
+  @failingTest
+  void test_parseForStatement_each_type() {
+    super.test_parseForStatement_each_type();
+  }
+
+  @failingTest
+  void test_parseForStatement_each_var() {
+    super.test_parseForStatement_each_var();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_c() {
+    super.test_parseForStatement_loop_c();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_cu() {
+    super.test_parseForStatement_loop_cu();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_ecu() {
+    super.test_parseForStatement_loop_ecu();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_i() {
+    super.test_parseForStatement_loop_i();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_i_withMetadata() {
+    super.test_parseForStatement_loop_i_withMetadata();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_ic() {
+    super.test_parseForStatement_loop_ic();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_icu() {
+    super.test_parseForStatement_loop_icu();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_iicuu() {
+    super.test_parseForStatement_loop_iicuu();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_iu() {
+    super.test_parseForStatement_loop_iu();
+  }
+
+  @failingTest
+  void test_parseForStatement_loop_u() {
+    super.test_parseForStatement_loop_u();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclarationStatement() {
+    super.test_parseFunctionDeclarationStatement();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclarationStatement_typeParameterComments() {
+    super.test_parseFunctionDeclarationStatement_typeParameterComments();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclarationStatement_typeParameters() {
+    super.test_parseFunctionDeclarationStatement_typeParameters();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclarationStatement_typeParameters_noReturnType() {
+    super.test_parseFunctionDeclarationStatement_typeParameters_noReturnType();
+  }
+
+  @failingTest
+  void test_parseIfStatement_else_block() {
+    super.test_parseIfStatement_else_block();
+  }
+
+  @failingTest
+  void test_parseIfStatement_else_statement() {
+    super.test_parseIfStatement_else_statement();
+  }
+
+  @failingTest
+  void test_parseIfStatement_noElse_block() {
+    super.test_parseIfStatement_noElse_block();
+  }
+
+  @failingTest
+  void test_parseIfStatement_noElse_statement() {
+    super.test_parseIfStatement_noElse_statement();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_const_list_empty() {
+    super.test_parseNonLabeledStatement_const_list_empty();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_const_list_nonEmpty() {
+    super.test_parseNonLabeledStatement_const_list_nonEmpty();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_const_map_empty() {
+    super.test_parseNonLabeledStatement_const_map_empty();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_const_map_nonEmpty() {
+    super.test_parseNonLabeledStatement_const_map_nonEmpty();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_const_object() {
+    super.test_parseNonLabeledStatement_const_object();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_const_object_named_typeParameters() {
+    super.test_parseNonLabeledStatement_const_object_named_typeParameters();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_constructorInvocation() {
+    super.test_parseNonLabeledStatement_constructorInvocation();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_false() {
+    super.test_parseNonLabeledStatement_false();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_functionDeclaration() {
+    super.test_parseNonLabeledStatement_functionDeclaration();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_functionDeclaration_arguments() {
+    super.test_parseNonLabeledStatement_functionDeclaration_arguments();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_functionExpressionIndex() {
+    super.test_parseNonLabeledStatement_functionExpressionIndex();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_functionInvocation() {
+    super.test_parseNonLabeledStatement_functionInvocation();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_invokeFunctionExpression() {
+    super.test_parseNonLabeledStatement_invokeFunctionExpression();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_localFunction_gftReturnType() {
+    super.test_parseNonLabeledStatement_localFunction_gftReturnType();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_null() {
+    super.test_parseNonLabeledStatement_null();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_startingWithBuiltInIdentifier() {
+    super.test_parseNonLabeledStatement_startingWithBuiltInIdentifier();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_true() {
+    super.test_parseNonLabeledStatement_true();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_typeCast() {
+    super.test_parseNonLabeledStatement_typeCast();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_variableDeclaration_final_namedFunction() {
+    super
+        .test_parseNonLabeledStatement_variableDeclaration_final_namedFunction();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_variableDeclaration_gftType() {
+    super.test_parseNonLabeledStatement_variableDeclaration_gftType();
+  }
+
+  @failingTest
+  void
+      test_parseNonLabeledStatement_variableDeclaration_gftType_functionReturnType() {
+    super
+        .test_parseNonLabeledStatement_variableDeclaration_gftType_functionReturnType();
+  }
+
+  @failingTest
+  void
+      test_parseNonLabeledStatement_variableDeclaration_gftType_gftReturnType() {
+    super
+        .test_parseNonLabeledStatement_variableDeclaration_gftType_gftReturnType();
+  }
+
+  @failingTest
+  void
+      test_parseNonLabeledStatement_variableDeclaration_gftType_gftReturnType2() {
+    super
+        .test_parseNonLabeledStatement_variableDeclaration_gftType_gftReturnType2();
+  }
+
+  @failingTest
+  void
+      test_parseNonLabeledStatement_variableDeclaration_gftType_noReturnType() {
+    super
+        .test_parseNonLabeledStatement_variableDeclaration_gftType_noReturnType();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_variableDeclaration_gftType_returnType() {
+    super
+        .test_parseNonLabeledStatement_variableDeclaration_gftType_returnType();
+  }
+
+  @failingTest
+  void
+      test_parseNonLabeledStatement_variableDeclaration_gftType_voidReturnType() {
+    super
+        .test_parseNonLabeledStatement_variableDeclaration_gftType_voidReturnType();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_variableDeclaration_typeParam() {
+    super.test_parseNonLabeledStatement_variableDeclaration_typeParam();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_variableDeclaration_typeParam2() {
+    super.test_parseNonLabeledStatement_variableDeclaration_typeParam2();
+  }
+
+  @failingTest
+  void test_parseNonLabeledStatement_variableDeclaration_typeParam3() {
+    super.test_parseNonLabeledStatement_variableDeclaration_typeParam3();
+  }
+
+  @failingTest
+  void test_parseStatement_emptyTypeArgumentList() {
+    super.test_parseStatement_emptyTypeArgumentList();
+  }
+
+  @failingTest
+  void test_parseStatement_function_gftReturnType() {
+    super.test_parseStatement_function_gftReturnType();
+  }
+
+  @failingTest
+  void test_parseStatement_functionDeclaration_noReturnType() {
+    super.test_parseStatement_functionDeclaration_noReturnType();
+  }
+
+  @failingTest
+  void
+      test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
+    super
+        .test_parseStatement_functionDeclaration_noReturnType_typeParameterComments();
+  }
+
+  @failingTest
+  void test_parseStatement_functionDeclaration_noReturnType_typeParameters() {
+    super.test_parseStatement_functionDeclaration_noReturnType_typeParameters();
+  }
+
+  @failingTest
+  void test_parseStatement_functionDeclaration_returnType() {
+    super.test_parseStatement_functionDeclaration_returnType();
+  }
+
+  @failingTest
+  void test_parseStatement_functionDeclaration_returnType_typeParameters() {
+    super.test_parseStatement_functionDeclaration_returnType_typeParameters();
+  }
+
+  @failingTest
+  void test_parseStatement_multipleLabels() {
+    super.test_parseStatement_multipleLabels();
+  }
+
+  @failingTest
+  void test_parseStatement_noLabels() {
+    super.test_parseStatement_noLabels();
+  }
+
+  @failingTest
+  void test_parseStatement_singleLabel() {
+    super.test_parseStatement_singleLabel();
+  }
+
+  @failingTest
+  void test_parseSwitchStatement_case() {
+    super.test_parseSwitchStatement_case();
+  }
+
+  @failingTest
+  void test_parseSwitchStatement_empty() {
+    super.test_parseSwitchStatement_empty();
+  }
+
+  @failingTest
+  void test_parseSwitchStatement_labeledCase() {
+    super.test_parseSwitchStatement_labeledCase();
+  }
+
+  @failingTest
+  void test_parseSwitchStatement_labeledDefault() {
+    super.test_parseSwitchStatement_labeledDefault();
+  }
+
+  @failingTest
+  void test_parseSwitchStatement_labeledStatementInCase() {
+    super.test_parseSwitchStatement_labeledStatementInCase();
+  }
+
+  @failingTest
+  void test_parseTryStatement_catch() {
+    super.test_parseTryStatement_catch();
+  }
+
+  @failingTest
+  void test_parseTryStatement_catch_error_missingCatchParam() {
+    super.test_parseTryStatement_catch_error_missingCatchParam();
+  }
+
+  @failingTest
+  void test_parseTryStatement_catch_error_missingCatchParen() {
+    super.test_parseTryStatement_catch_error_missingCatchParen();
+  }
+
+  @failingTest
+  void test_parseTryStatement_catch_error_missingCatchTrace() {
+    super.test_parseTryStatement_catch_error_missingCatchTrace();
+  }
+
+  @failingTest
+  void test_parseTryStatement_catch_finally() {
+    super.test_parseTryStatement_catch_finally();
+  }
+
+  @failingTest
+  void test_parseTryStatement_finally() {
+    super.test_parseTryStatement_finally();
+  }
+
+  @failingTest
+  void test_parseTryStatement_multiple() {
+    super.test_parseTryStatement_multiple();
+  }
+
+  @failingTest
+  void test_parseTryStatement_on() {
+    super.test_parseTryStatement_on();
+  }
+
+  @failingTest
+  void test_parseTryStatement_on_catch() {
+    super.test_parseTryStatement_on_catch();
+  }
+
+  @failingTest
+  void test_parseTryStatement_on_catch_finally() {
+    super.test_parseTryStatement_on_catch_finally();
+  }
+
+  @failingTest
+  void test_parseVariableDeclaration_equals_builtIn() {
+    super.test_parseVariableDeclaration_equals_builtIn();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_const_noType() {
+    super.test_parseVariableDeclarationListAfterMetadata_const_noType();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_const_type() {
+    super.test_parseVariableDeclarationListAfterMetadata_const_type();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_const_typeComment() {
+    super.test_parseVariableDeclarationListAfterMetadata_const_typeComment();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_dynamic_typeComment() {
+    super.test_parseVariableDeclarationListAfterMetadata_dynamic_typeComment();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_final_noType() {
+    super.test_parseVariableDeclarationListAfterMetadata_final_noType();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_final_type() {
+    super.test_parseVariableDeclarationListAfterMetadata_final_type();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_final_typeComment() {
+    super.test_parseVariableDeclarationListAfterMetadata_final_typeComment();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_type_multiple() {
+    super.test_parseVariableDeclarationListAfterMetadata_type_multiple();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_type_single() {
+    super.test_parseVariableDeclarationListAfterMetadata_type_single();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_type_typeComment() {
+    super.test_parseVariableDeclarationListAfterMetadata_type_typeComment();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_var_multiple() {
+    super.test_parseVariableDeclarationListAfterMetadata_var_multiple();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_var_single() {
+    super.test_parseVariableDeclarationListAfterMetadata_var_single();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationListAfterMetadata_var_typeComment() {
+    super.test_parseVariableDeclarationListAfterMetadata_var_typeComment();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationStatementAfterMetadata_multiple() {
+    super.test_parseVariableDeclarationStatementAfterMetadata_multiple();
+  }
+
+  @failingTest
+  void test_parseVariableDeclarationStatementAfterMetadata_single() {
+    super.test_parseVariableDeclarationStatementAfterMetadata_single();
+  }
+
+  @failingTest
+  void test_parseWhileStatement() {
+    super.test_parseWhileStatement();
+  }
+
+  @failingTest
+  void test_parseYieldStatement_each() {
+    super.test_parseYieldStatement_each();
+  }
+
+  @failingTest
+  void test_parseYieldStatement_normal() {
+    super.test_parseYieldStatement_normal();
+  }
+}
+
+@reflectiveTest
+class TopLevelParserTest_Forest extends FastaBodyBuilderTestCase
+    with TopLevelParserTestMixin {
+  TopLevelParserTest_Forest() : super(false);
+
+  @failingTest
+  void test_function_literal_allowed_at_toplevel() {
+    super.test_function_literal_allowed_at_toplevel();
+  }
+
+  @failingTest
+  void
+      test_function_literal_allowed_in_ArgumentList_in_ConstructorFieldInitializer() {
+    super
+        .test_function_literal_allowed_in_ArgumentList_in_ConstructorFieldInitializer();
+  }
+
+  @failingTest
+  void
+      test_function_literal_allowed_in_IndexExpression_in_ConstructorFieldInitializer() {
+    super
+        .test_function_literal_allowed_in_IndexExpression_in_ConstructorFieldInitializer();
+  }
+
+  @failingTest
+  void
+      test_function_literal_allowed_in_ListLiteral_in_ConstructorFieldInitializer() {
+    super
+        .test_function_literal_allowed_in_ListLiteral_in_ConstructorFieldInitializer();
+  }
+
+  @failingTest
+  void
+      test_function_literal_allowed_in_MapLiteral_in_ConstructorFieldInitializer() {
+    super
+        .test_function_literal_allowed_in_MapLiteral_in_ConstructorFieldInitializer();
+  }
+
+  @failingTest
+  void
+      test_function_literal_allowed_in_ParenthesizedExpression_in_ConstructorFieldInitializer() {
+    super
+        .test_function_literal_allowed_in_ParenthesizedExpression_in_ConstructorFieldInitializer();
+  }
+
+  @failingTest
+  void
+      test_function_literal_allowed_in_StringInterpolation_in_ConstructorFieldInitializer() {
+    super
+        .test_function_literal_allowed_in_StringInterpolation_in_ConstructorFieldInitializer();
+  }
+
+  @failingTest
+  void test_import_as_show() {
+    super.test_import_as_show();
+  }
+
+  @failingTest
+  void test_import_show_hide() {
+    super.test_import_show_hide();
+  }
+
+  @failingTest
+  void test_import_withDocComment() {
+    super.test_import_withDocComment();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_abstract() {
+    super.test_parseClassDeclaration_abstract();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_empty() {
+    super.test_parseClassDeclaration_empty();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_extends() {
+    super.test_parseClassDeclaration_extends();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_extendsAndImplements() {
+    super.test_parseClassDeclaration_extendsAndImplements();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_extendsAndWith() {
+    super.test_parseClassDeclaration_extendsAndWith();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_extendsAndWithAndImplements() {
+    super.test_parseClassDeclaration_extendsAndWithAndImplements();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_implements() {
+    super.test_parseClassDeclaration_implements();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_metadata() {
+    super.test_parseClassDeclaration_metadata();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_native() {
+    super.test_parseClassDeclaration_native();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_nonEmpty() {
+    super.test_parseClassDeclaration_nonEmpty();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_typeAlias_implementsC() {
+    super.test_parseClassDeclaration_typeAlias_implementsC();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_typeAlias_withB() {
+    super.test_parseClassDeclaration_typeAlias_withB();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_typeParameters() {
+    super.test_parseClassDeclaration_typeParameters();
+  }
+
+  @failingTest
+  void test_parseClassDeclaration_withDocumentationComment() {
+    super.test_parseClassDeclaration_withDocumentationComment();
+  }
+
+  @failingTest
+  void test_parseClassTypeAlias_withDocumentationComment() {
+    super.test_parseClassTypeAlias_withDocumentationComment();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_abstractAsPrefix_parameterized() {
+    super.test_parseCompilationUnit_abstractAsPrefix_parameterized();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_builtIn_asFunctionName() {
+    super.test_parseCompilationUnit_builtIn_asFunctionName();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_builtIn_asFunctionName_withTypeParameter() {
+    super.test_parseCompilationUnit_builtIn_asFunctionName_withTypeParameter();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_builtIn_asGetter() {
+    super.test_parseCompilationUnit_builtIn_asGetter();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_directives_multiple() {
+    super.test_parseCompilationUnit_directives_multiple();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_directives_single() {
+    super.test_parseCompilationUnit_directives_single();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_empty() {
+    super.test_parseCompilationUnit_empty();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_exportAsPrefix() {
+    super.test_parseCompilationUnit_exportAsPrefix();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_exportAsPrefix_parameterized() {
+    super.test_parseCompilationUnit_exportAsPrefix_parameterized();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_operatorAsPrefix_parameterized() {
+    super.test_parseCompilationUnit_operatorAsPrefix_parameterized();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_pseudo_prefixed() {
+    super.test_parseCompilationUnit_pseudo_prefixed();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_script() {
+    super.test_parseCompilationUnit_script();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_skipFunctionBody_withInterpolation() {
+    super.test_parseCompilationUnit_skipFunctionBody_withInterpolation();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_topLevelDeclaration() {
+    super.test_parseCompilationUnit_topLevelDeclaration();
+  }
+
+  @failingTest
+  void test_parseCompilationUnit_typedefAsPrefix() {
+    super.test_parseCompilationUnit_typedefAsPrefix();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_abstractAsPrefix() {
+    super.test_parseCompilationUnitMember_abstractAsPrefix();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_class() {
+    super.test_parseCompilationUnitMember_class();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_classTypeAlias() {
+    super.test_parseCompilationUnitMember_classTypeAlias();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_constVariable() {
+    super.test_parseCompilationUnitMember_constVariable();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_expressionFunctionBody_tokens() {
+    super.test_parseCompilationUnitMember_expressionFunctionBody_tokens();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_finalVariable() {
+    super.test_parseCompilationUnitMember_finalVariable();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_external_noType() {
+    super.test_parseCompilationUnitMember_function_external_noType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_external_type() {
+    super.test_parseCompilationUnitMember_function_external_type();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_generic_noReturnType() {
+    super.test_parseCompilationUnitMember_function_generic_noReturnType();
+  }
+
+  @failingTest
+  void
+      test_parseCompilationUnitMember_function_generic_noReturnType_annotated() {
+    super
+        .test_parseCompilationUnitMember_function_generic_noReturnType_annotated();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_generic_returnType() {
+    super.test_parseCompilationUnitMember_function_generic_returnType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_generic_void() {
+    super.test_parseCompilationUnitMember_function_generic_void();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_gftReturnType() {
+    super.test_parseCompilationUnitMember_function_gftReturnType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_noReturnType() {
+    super.test_parseCompilationUnitMember_function_noReturnType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_noType() {
+    super.test_parseCompilationUnitMember_function_noType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_type() {
+    super.test_parseCompilationUnitMember_function_type();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_function_void() {
+    super.test_parseCompilationUnitMember_function_void();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_getter_external_noType() {
+    super.test_parseCompilationUnitMember_getter_external_noType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_getter_external_type() {
+    super.test_parseCompilationUnitMember_getter_external_type();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_getter_noType() {
+    super.test_parseCompilationUnitMember_getter_noType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_getter_type() {
+    super.test_parseCompilationUnitMember_getter_type();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_setter_external_noType() {
+    super.test_parseCompilationUnitMember_setter_external_noType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_setter_external_type() {
+    super.test_parseCompilationUnitMember_setter_external_type();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_setter_noType() {
+    super.test_parseCompilationUnitMember_setter_noType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_setter_type() {
+    super.test_parseCompilationUnitMember_setter_type();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_typeAlias_abstract() {
+    super.test_parseCompilationUnitMember_typeAlias_abstract();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_typeAlias_generic() {
+    super.test_parseCompilationUnitMember_typeAlias_generic();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_typeAlias_implements() {
+    super.test_parseCompilationUnitMember_typeAlias_implements();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_typeAlias_noImplements() {
+    super.test_parseCompilationUnitMember_typeAlias_noImplements();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_typedef() {
+    super.test_parseCompilationUnitMember_typedef();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_typedef_withDocComment() {
+    super.test_parseCompilationUnitMember_typedef_withDocComment();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_typedVariable() {
+    super.test_parseCompilationUnitMember_typedVariable();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_variable() {
+    super.test_parseCompilationUnitMember_variable();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_variable_gftType_gftReturnType() {
+    super.test_parseCompilationUnitMember_variable_gftType_gftReturnType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_variable_gftType_noReturnType() {
+    super.test_parseCompilationUnitMember_variable_gftType_noReturnType();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_variable_withDocumentationComment() {
+    super.test_parseCompilationUnitMember_variable_withDocumentationComment();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_variableGet() {
+    super.test_parseCompilationUnitMember_variableGet();
+  }
+
+  @failingTest
+  void test_parseCompilationUnitMember_variableSet() {
+    super.test_parseCompilationUnitMember_variableSet();
+  }
+
+  @failingTest
+  void test_parseDirective_export() {
+    super.test_parseDirective_export();
+  }
+
+  @failingTest
+  void test_parseDirective_export_withDocComment() {
+    super.test_parseDirective_export_withDocComment();
+  }
+
+  @failingTest
+  void test_parseDirective_import() {
+    super.test_parseDirective_import();
+  }
+
+  @failingTest
+  void test_parseDirective_library() {
+    super.test_parseDirective_library();
+  }
+
+  @failingTest
+  void test_parseDirective_library_1_component() {
+    super.test_parseDirective_library_1_component();
+  }
+
+  @failingTest
+  void test_parseDirective_library_2_components() {
+    super.test_parseDirective_library_2_components();
+  }
+
+  @failingTest
+  void test_parseDirective_library_3_components() {
+    super.test_parseDirective_library_3_components();
+  }
+
+  @failingTest
+  void test_parseDirective_library_withDocumentationComment() {
+    super.test_parseDirective_library_withDocumentationComment();
+  }
+
+  @failingTest
+  void test_parseDirective_part() {
+    super.test_parseDirective_part();
+  }
+
+  @failingTest
+  void test_parseDirective_part_of_1_component() {
+    super.test_parseDirective_part_of_1_component();
+  }
+
+  @failingTest
+  void test_parseDirective_part_of_2_components() {
+    super.test_parseDirective_part_of_2_components();
+  }
+
+  @failingTest
+  void test_parseDirective_part_of_3_components() {
+    super.test_parseDirective_part_of_3_components();
+  }
+
+  @failingTest
+  void test_parseDirective_part_of_withDocumentationComment() {
+    super.test_parseDirective_part_of_withDocumentationComment();
+  }
+
+  @failingTest
+  void test_parseDirective_part_withDocumentationComment() {
+    super.test_parseDirective_part_withDocumentationComment();
+  }
+
+  @failingTest
+  void test_parseDirective_partOf() {
+    super.test_parseDirective_partOf();
+  }
+
+  @failingTest
+  void test_parseDirectives_complete() {
+    super.test_parseDirectives_complete();
+  }
+
+  @failingTest
+  void test_parseDirectives_empty() {
+    super.test_parseDirectives_empty();
+  }
+
+  @failingTest
+  void test_parseDirectives_mixed() {
+    super.test_parseDirectives_mixed();
+  }
+
+  @failingTest
+  void test_parseDirectives_multiple() {
+    super.test_parseDirectives_multiple();
+  }
+
+  @failingTest
+  void test_parseDirectives_script() {
+    super.test_parseDirectives_script();
+  }
+
+  @failingTest
+  void test_parseDirectives_single() {
+    super.test_parseDirectives_single();
+  }
+
+  @failingTest
+  void test_parseDirectives_topLevelDeclaration() {
+    super.test_parseDirectives_topLevelDeclaration();
+  }
+
+  @failingTest
+  void test_parseEnumDeclaration_one() {
+    super.test_parseEnumDeclaration_one();
+  }
+
+  @failingTest
+  void test_parseEnumDeclaration_trailingComma() {
+    super.test_parseEnumDeclaration_trailingComma();
+  }
+
+  @failingTest
+  void test_parseEnumDeclaration_two() {
+    super.test_parseEnumDeclaration_two();
+  }
+
+  @failingTest
+  void test_parseEnumDeclaration_withDocComment_onEnum() {
+    super.test_parseEnumDeclaration_withDocComment_onEnum();
+  }
+
+  @failingTest
+  void test_parseEnumDeclaration_withDocComment_onValue() {
+    super.test_parseEnumDeclaration_withDocComment_onValue();
+  }
+
+  @failingTest
+  void test_parseExportDirective_configuration_multiple() {
+    super.test_parseExportDirective_configuration_multiple();
+  }
+
+  @failingTest
+  void test_parseExportDirective_configuration_single() {
+    super.test_parseExportDirective_configuration_single();
+  }
+
+  @failingTest
+  void test_parseExportDirective_hide() {
+    super.test_parseExportDirective_hide();
+  }
+
+  @failingTest
+  void test_parseExportDirective_hide_show() {
+    super.test_parseExportDirective_hide_show();
+  }
+
+  @failingTest
+  void test_parseExportDirective_noCombinator() {
+    super.test_parseExportDirective_noCombinator();
+  }
+
+  @failingTest
+  void test_parseExportDirective_show() {
+    super.test_parseExportDirective_show();
+  }
+
+  @failingTest
+  void test_parseExportDirective_show_hide() {
+    super.test_parseExportDirective_show_hide();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclaration_function() {
+    super.test_parseFunctionDeclaration_function();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclaration_functionWithTypeParameters() {
+    super.test_parseFunctionDeclaration_functionWithTypeParameters();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclaration_functionWithTypeParameters_comment() {
+    super.test_parseFunctionDeclaration_functionWithTypeParameters_comment();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclaration_getter() {
+    super.test_parseFunctionDeclaration_getter();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclaration_getter_generic_comment_returnType() {
+    super.test_parseFunctionDeclaration_getter_generic_comment_returnType();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclaration_metadata() {
+    super.test_parseFunctionDeclaration_metadata();
+  }
+
+  @failingTest
+  void test_parseFunctionDeclaration_setter() {
+    super.test_parseFunctionDeclaration_setter();
+  }
+
+  @failingTest
+  void test_parseGenericTypeAlias_noTypeParameters() {
+    super.test_parseGenericTypeAlias_noTypeParameters();
+  }
+
+  @failingTest
+  void test_parseGenericTypeAlias_typeParameters() {
+    super.test_parseGenericTypeAlias_typeParameters();
+  }
+
+  @failingTest
+  void test_parseImportDirective_configuration_multiple() {
+    super.test_parseImportDirective_configuration_multiple();
+  }
+
+  @failingTest
+  void test_parseImportDirective_configuration_single() {
+    super.test_parseImportDirective_configuration_single();
+  }
+
+  @failingTest
+  void test_parseImportDirective_deferred() {
+    super.test_parseImportDirective_deferred();
+  }
+
+  @failingTest
+  void test_parseImportDirective_hide() {
+    super.test_parseImportDirective_hide();
+  }
+
+  @failingTest
+  void test_parseImportDirective_noCombinator() {
+    super.test_parseImportDirective_noCombinator();
+  }
+
+  @failingTest
+  void test_parseImportDirective_prefix() {
+    super.test_parseImportDirective_prefix();
+  }
+
+  @failingTest
+  void test_parseImportDirective_prefix_hide_show() {
+    super.test_parseImportDirective_prefix_hide_show();
+  }
+
+  @failingTest
+  void test_parseImportDirective_prefix_show_hide() {
+    super.test_parseImportDirective_prefix_show_hide();
+  }
+
+  @failingTest
+  void test_parseImportDirective_show() {
+    super.test_parseImportDirective_show();
+  }
+
+  @failingTest
+  void test_parseLibraryDirective() {
+    super.test_parseLibraryDirective();
+  }
+
+  @failingTest
+  void test_parsePartDirective() {
+    super.test_parsePartDirective();
+  }
+
+  @failingTest
+  void test_parsePartOfDirective_name() {
+    super.test_parsePartOfDirective_name();
+  }
+
+  @failingTest
+  void test_parsePartOfDirective_uri() {
+    super.test_parsePartOfDirective_uri();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_function_noParameters() {
+    super.test_parseTypeAlias_function_noParameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_function_noReturnType() {
+    super.test_parseTypeAlias_function_noReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_function_parameterizedReturnType() {
+    super.test_parseTypeAlias_function_parameterizedReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_function_parameters() {
+    super.test_parseTypeAlias_function_parameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_function_typeParameters() {
+    super.test_parseTypeAlias_function_typeParameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_function_voidReturnType() {
+    super.test_parseTypeAlias_function_voidReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_noParameters() {
+    super.test_parseTypeAlias_genericFunction_noParameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_noReturnType() {
+    super.test_parseTypeAlias_genericFunction_noReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_parameterizedReturnType() {
+    super.test_parseTypeAlias_genericFunction_parameterizedReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_parameters() {
+    super.test_parseTypeAlias_genericFunction_parameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_typeParameters() {
+    super.test_parseTypeAlias_genericFunction_typeParameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_typeParameters_noParameters() {
+    super.test_parseTypeAlias_genericFunction_typeParameters_noParameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_typeParameters_noReturnType() {
+    super.test_parseTypeAlias_genericFunction_typeParameters_noReturnType();
+  }
+
+  @failingTest
+  void
+      test_parseTypeAlias_genericFunction_typeParameters_parameterizedReturnType() {
+    super
+        .test_parseTypeAlias_genericFunction_typeParameters_parameterizedReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_typeParameters_parameters() {
+    super.test_parseTypeAlias_genericFunction_typeParameters_parameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_typeParameters_typeParameters() {
+    super.test_parseTypeAlias_genericFunction_typeParameters_typeParameters();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_typeParameters_voidReturnType() {
+    super.test_parseTypeAlias_genericFunction_typeParameters_voidReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_voidReturnType() {
+    super.test_parseTypeAlias_genericFunction_voidReturnType();
+  }
+
+  @failingTest
+  void test_parseTypeAlias_genericFunction_withDocComment() {
+    super.test_parseTypeAlias_genericFunction_withDocComment();
+  }
+
+  @failingTest
+  void test_parseTypeVariable_withDocumentationComment() {
+    super.test_parseTypeVariable_withDocumentationComment();
+  }
 }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index 1f39754..7c45cac 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -322,7 +322,13 @@
 
 @reflectiveTest
 class ClassMemberParserTest extends ParserTestCase
-    with ClassMemberParserTestMixin {}
+    with ClassMemberParserTestMixin {
+  @failingTest
+  @override
+  void test_parseAwaitExpression_inSync() {
+    super.test_parseAwaitExpression_inSync();
+  }
+}
 
 /**
  * Tests which exercise the parser using a class member.
@@ -365,7 +371,6 @@
         statement);
   }
 
-  @failingTest
   void test_parseAwaitExpression_inSync() {
     // This test requires better error recovery than we currently have. In
     // particular, we need to be able to distinguish between an await expression
@@ -525,38 +530,6 @@
     expect(variable.name, isNotNull);
   }
 
-  void test_parseClassMember_field_nameKeyword() {
-    createParser('var for;');
-    ClassMember member = parser.parseClassMember('C');
-    expect(member, isNotNull);
-    listener.assertErrors(usingFastaParser
-        ? [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 3)]
-        : [
-            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 3),
-            expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 3)
-          ]);
-  }
-
-  void test_parseClassMember_field_nameMissing() {
-    createParser('var ;');
-    ClassMember member = parser.parseClassMember('C');
-    expect(member, isNotNull);
-    listener.assertErrors(
-        [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 1)]);
-  }
-
-  void test_parseClassMember_field_nameMissing2() {
-    createParser('var "";');
-    ClassMember member = parser.parseClassMember('C');
-    expect(member, isNotNull);
-    listener.assertErrors(usingFastaParser
-        ? [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 2)]
-        : [
-            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 2),
-            expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 2)
-          ]);
-  }
-
   void test_parseClassMember_field_namedOperator() {
     createParser('var operator;');
     ClassMember member = parser.parseClassMember('C');
@@ -615,6 +588,38 @@
     expect(variable.name, isNotNull);
   }
 
+  void test_parseClassMember_field_nameKeyword() {
+    createParser('var for;');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 3)]
+        : [
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 3),
+            expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 3)
+          ]);
+  }
+
+  void test_parseClassMember_field_nameMissing() {
+    createParser('var ;');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    listener.assertErrors(
+        [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 1)]);
+  }
+
+  void test_parseClassMember_field_nameMissing2() {
+    createParser('var "";');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    listener.assertErrors(usingFastaParser
+        ? [expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 2)]
+        : [
+            expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 2),
+            expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 4, 2)
+          ]);
+  }
+
   void test_parseClassMember_field_static() {
     createParser('static A f;');
     ClassMember member = parser.parseClassMember('C');
@@ -2209,6 +2214,16 @@
     expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
   }
 
+  void test_logicalAndExpression_precedence_bitwiseOr_left() {
+    BinaryExpression expression = parseExpression("x | y < z");
+    expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
+  }
+
+  void test_logicalAndExpression_precedence_bitwiseOr_right() {
+    BinaryExpression expression = parseExpression("x < y | z");
+    expect(expression.rightOperand, new isInstanceOf<BinaryExpression>());
+  }
+
   void test_logicalAndExpressionStatement() {
     // Assert that `<` and `>` are not interpreted as type arguments.
     ExpressionStatement statement = parseStatement("C<T && T>U;");
@@ -2216,6 +2231,22 @@
     expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
   }
 
+  void test_logicalOrExpression() {
+    BinaryExpression expression = parseExpression("x || y || z");
+    expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
+  }
+
+  void test_logicalOrExpression_precedence_logicalAnd_left() {
+    BinaryExpression expression = parseExpression("x && y || z");
+    expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
+  }
+
+  void test_logicalOrExpression_precedence_logicalAnd_right() {
+    BinaryExpression expression = parseExpression("x || y && z");
+    EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
+        BinaryExpression, expression.rightOperand);
+  }
+
   void test_methodInvocation1() {
     // Assert that `<` and `>` are not interpreted as type arguments.
     ExpressionStatement statement = parseStatement("f(a < b, c > 3);");
@@ -2240,32 +2271,6 @@
     expect(method.argumentList.arguments, hasLength(2));
   }
 
-  void test_logicalAndExpression_precedence_bitwiseOr_left() {
-    BinaryExpression expression = parseExpression("x | y < z");
-    expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
-  }
-
-  void test_logicalAndExpression_precedence_bitwiseOr_right() {
-    BinaryExpression expression = parseExpression("x < y | z");
-    expect(expression.rightOperand, new isInstanceOf<BinaryExpression>());
-  }
-
-  void test_logicalOrExpression() {
-    BinaryExpression expression = parseExpression("x || y || z");
-    expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
-  }
-
-  void test_logicalOrExpression_precedence_logicalAnd_left() {
-    BinaryExpression expression = parseExpression("x && y || z");
-    expect(expression.leftOperand, new isInstanceOf<BinaryExpression>());
-  }
-
-  void test_logicalOrExpression_precedence_logicalAnd_right() {
-    BinaryExpression expression = parseExpression("x || y && z");
-    EngineTestCase.assertInstanceOf((obj) => obj is BinaryExpression,
-        BinaryExpression, expression.rightOperand);
-  }
-
   void test_multipleLabels_statement() {
     LabeledStatement statement = parseStatement("a: b: c: return x;");
     expect(statement.labels, hasLength(3));
@@ -2386,6 +2391,36 @@
  */
 @reflectiveTest
 class ErrorParserTest extends ParserTestCase with ErrorParserTestMixin {
+  @failingTest
+  @override
+  void test_expectedListOrMapLiteral() {
+    super.test_expectedListOrMapLiteral();
+  }
+
+  @failingTest
+  @override
+  void test_invalidCommentReference__new_nonIdentifier() {
+    super.test_invalidCommentReference__new_nonIdentifier();
+  }
+
+  @failingTest
+  @override
+  void test_invalidCommentReference__new_tooMuch() {
+    super.test_invalidCommentReference__new_tooMuch();
+  }
+
+  @failingTest
+  @override
+  void test_invalidCommentReference__nonNew_nonIdentifier() {
+    super.test_invalidCommentReference__nonNew_nonIdentifier();
+  }
+
+  @failingTest
+  @override
+  void test_invalidCommentReference__nonNew_tooMuch() {
+    super.test_invalidCommentReference__nonNew_tooMuch();
+  }
+
   void test_missingIdentifier_number() {
     createParser('1');
     SimpleIdentifier expression = parser.parseSimpleIdentifier();
@@ -2633,7 +2668,14 @@
 
   void test_constEnum() {
     parseCompilationUnit("const enum E {ONE}",
-        errors: [expectedError(ParserErrorCode.CONST_ENUM, 0, 5)]);
+        errors: usingFastaParser
+            ? [
+                // Fasta interprets the `const` as a malformed top level const
+                // and `enum` as the start of an enum declaration.
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 6, 4),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 6, 4),
+              ]
+            : [expectedError(ParserErrorCode.CONST_ENUM, 0, 5)]);
   }
 
   void test_constFactory() {
@@ -2687,7 +2729,14 @@
 
   void test_constTypedef() {
     parseCompilationUnit("const typedef F();",
-        errors: [expectedError(ParserErrorCode.CONST_TYPEDEF, 0, 5)]);
+        errors: usingFastaParser
+            ? [
+                // Fasta interprets the `const` as a malformed top level const
+                // and `typedef` as the start of an typedef declaration.
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 6, 7),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 6, 7),
+              ]
+            : [expectedError(ParserErrorCode.CONST_TYPEDEF, 0, 5)]);
   }
 
   void test_continueOutsideOfLoop_continueInDoStatement() {
@@ -3159,7 +3208,6 @@
     expectNotNullIfNoErrors(literal);
   }
 
-  @failingTest
   void test_expectedListOrMapLiteral() {
     // It isn't clear that this test can ever pass. The parser is currently
     // create a synthetic list literal in this case, but isSynthetic() isn't
@@ -3616,7 +3664,14 @@
 
   void test_finalEnum() {
     parseCompilationUnit("final enum E {ONE}",
-        errors: [expectedError(ParserErrorCode.FINAL_ENUM, 0, 5)]);
+        errors: usingFastaParser
+            ? [
+                // Fasta interprets the `final` as a malformed top level final
+                // and `enum` as the start of a enum declaration.
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 6, 4),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 6, 4),
+              ]
+            : [expectedError(ParserErrorCode.FINAL_ENUM, 0, 5)]);
   }
 
   void test_finalMethod() {
@@ -3633,7 +3688,14 @@
 
   void test_finalTypedef() {
     parseCompilationUnit("final typedef F();",
-        errors: [expectedError(ParserErrorCode.FINAL_TYPEDEF, 0, 5)]);
+        errors: usingFastaParser
+            ? [
+                // Fasta interprets the `final` as a malformed top level final
+                // and `typedef` as the start of an typedef declaration.
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 6, 7),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 6, 7),
+              ]
+            : [expectedError(ParserErrorCode.FINAL_TYPEDEF, 0, 5)]);
   }
 
   void test_functionTypedField_invalidType_abstract() {
@@ -3929,7 +3991,6 @@
     expectNotNullIfNoErrors(literal);
   }
 
-  @failingTest
   void test_invalidCommentReference__new_nonIdentifier() {
     // This test fails because the method parseCommentReference returns null.
     createParser('');
@@ -3939,7 +4000,6 @@
         [expectedError(ParserErrorCode.INVALID_COMMENT_REFERENCE, 0, 6)]);
   }
 
-  @failingTest
   void test_invalidCommentReference__new_tooMuch() {
     createParser('');
     CommentReference reference = parser.parseCommentReference('new a.b.c.d', 0);
@@ -3948,7 +4008,6 @@
         [expectedError(ParserErrorCode.INVALID_COMMENT_REFERENCE, 0, 11)]);
   }
 
-  @failingTest
   void test_invalidCommentReference__nonNew_nonIdentifier() {
     // This test fails because the method parseCommentReference returns null.
     createParser('');
@@ -3958,7 +4017,6 @@
         [expectedError(ParserErrorCode.INVALID_COMMENT_REFERENCE, 0, 2)]);
   }
 
-  @failingTest
   void test_invalidCommentReference__nonNew_tooMuch() {
     createParser('');
     CommentReference reference = parser.parseCommentReference('a.b.c.d', 0);
@@ -3967,17 +4025,6 @@
         [expectedError(ParserErrorCode.INVALID_COMMENT_REFERENCE, 0, 7)]);
   }
 
-  void test_invalidConstructorName_with() {
-    createParser("C.with();");
-    ClassMember member = parser.parseClassMember('C');
-    expectNotNullIfNoErrors(member);
-    listener.assertErrors([
-      usingFastaParser
-          ? expectedError(ParserErrorCode.MISSING_IDENTIFIER, 2, 4)
-          : expectedError(ParserErrorCode.INVALID_CONSTRUCTOR_NAME, 0, 1)
-    ]);
-  }
-
   void test_invalidConstructorName_star() {
     createParser("C.*();");
     ClassMember member = parser.parseClassMember('C');
@@ -3990,6 +4037,17 @@
           ]);
   }
 
+  void test_invalidConstructorName_with() {
+    createParser("C.with();");
+    ClassMember member = parser.parseClassMember('C');
+    expectNotNullIfNoErrors(member);
+    listener.assertErrors([
+      usingFastaParser
+          ? expectedError(ParserErrorCode.MISSING_IDENTIFIER, 2, 4)
+          : expectedError(ParserErrorCode.INVALID_CONSTRUCTOR_NAME, 0, 1)
+    ]);
+  }
+
   void test_invalidHexEscape_invalidDigit() {
     StringLiteral literal = parseExpression("'\\x0 a'",
         errors: [expectedError(ParserErrorCode.INVALID_HEX_ESCAPE, 1, 3)]);
@@ -5702,14 +5760,24 @@
   void test_varClass() {
     parseCompilationUnit("var class C {}",
         errors: usingFastaParser
-            ? [expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 3)]
+            ? [
+                // Fasta interprets the `var` as a malformed top level var
+                // and `class` as the start of a class declaration.
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 5),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 4, 5),
+              ]
             : [expectedError(ParserErrorCode.VAR_CLASS, 0, 3)]);
   }
 
   void test_varEnum() {
     parseCompilationUnit("var enum E {ONE}",
         errors: usingFastaParser
-            ? [expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 3)]
+            ? [
+                // Fasta interprets the `var` as a malformed top level var
+                // and `enum` as the start of an enum declaration.
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 4),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 4, 4),
+              ]
             : [expectedError(ParserErrorCode.VAR_ENUM, 0, 3)]);
   }
 
@@ -5724,7 +5792,12 @@
   void test_varTypedef() {
     parseCompilationUnit("var typedef F();",
         errors: usingFastaParser
-            ? [expectedError(ParserErrorCode.EXTRANEOUS_MODIFIER, 0, 3)]
+            ? [
+                // Fasta interprets the `var` as a malformed top level var
+                // and `typedef` as the start of an typedef declaration.
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 4, 7),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 4, 7),
+              ]
             : [expectedError(ParserErrorCode.VAR_TYPEDEF, 0, 3)]);
   }
 
@@ -11056,17 +11129,10 @@
   }
 
   void test_incomplete_topLevelVariable_const() {
-    CompilationUnit unit = parseCompilationUnit("const ",
-        codes: usingFastaParser
-            ? [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                CompileTimeErrorCode.CONST_NOT_INITIALIZED
-              ]
-            : [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ]);
+    CompilationUnit unit = parseCompilationUnit("const ", codes: [
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.EXPECTED_TOKEN
+    ]);
     NodeList<CompilationUnitMember> declarations = unit.declarations;
     expect(declarations, hasLength(1));
     CompilationUnitMember member = declarations[0];
@@ -11080,17 +11146,10 @@
   }
 
   void test_incomplete_topLevelVariable_final() {
-    CompilationUnit unit = parseCompilationUnit("final ",
-        codes: usingFastaParser
-            ? [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                StaticWarningCode.FINAL_NOT_INITIALIZED
-              ]
-            : [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ]);
+    CompilationUnit unit = parseCompilationUnit("final ", codes: [
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.EXPECTED_TOKEN
+    ]);
     NodeList<CompilationUnitMember> declarations = unit.declarations;
     expect(declarations, hasLength(1));
     CompilationUnitMember member = declarations[0];
@@ -11124,17 +11183,10 @@
     CompilationUnit unit = parseCompilationUnit(r'''
 class C {
   const
-}''',
-        codes: usingFastaParser
-            ? [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN,
-                CompileTimeErrorCode.CONST_NOT_INITIALIZED
-              ]
-            : [
-                ParserErrorCode.MISSING_IDENTIFIER,
-                ParserErrorCode.EXPECTED_TOKEN
-              ]);
+}''', codes: [
+      ParserErrorCode.MISSING_IDENTIFIER,
+      ParserErrorCode.EXPECTED_TOKEN
+    ]);
     NodeList<CompilationUnitMember> declarations = unit.declarations;
     expect(declarations, hasLength(1));
     CompilationUnitMember unitMember = declarations[0];
@@ -13259,20 +13311,6 @@
  * More complex tests should be defined in the class [ComplexParserTest].
  */
 abstract class SimpleParserTestMixin implements AbstractParserTestCase {
-  void test_classDeclaration_complexTypeParam() {
-    CompilationUnit unit = parseCompilationUnit('''
-class C<@Foo.bar(const [], const [1], const{"":r""}, 0xFF + 2, .3, 4.5) T> {}
-''');
-    ClassDeclaration clazz = unit.declarations[0];
-    expect(clazz.name.name, 'C');
-    expect(clazz.typeParameters.typeParameters, hasLength(1));
-    TypeParameter typeParameter = clazz.typeParameters.typeParameters[0];
-    expect(typeParameter.name.name, 'T');
-    expect(typeParameter.metadata, hasLength(1));
-    Annotation metadata = typeParameter.metadata[0];
-    expect(metadata.name.name, 'Foo.bar');
-  }
-
   ConstructorName parseConstructorName(String name) {
     createParser('new $name();');
     Statement statement = parser.parseStatement2();
@@ -13351,6 +13389,20 @@
     return classDecl.withClause;
   }
 
+  void test_classDeclaration_complexTypeParam() {
+    CompilationUnit unit = parseCompilationUnit('''
+class C<@Foo.bar(const [], const [1], const{"":r""}, 0xFF + 2, .3, 4.5) T> {}
+''');
+    ClassDeclaration clazz = unit.declarations[0];
+    expect(clazz.name.name, 'C');
+    expect(clazz.typeParameters.typeParameters, hasLength(1));
+    TypeParameter typeParameter = clazz.typeParameters.typeParameters[0];
+    expect(typeParameter.name.name, 'T');
+    expect(typeParameter.metadata, hasLength(1));
+    Annotation metadata = typeParameter.metadata[0];
+    expect(metadata.name.name, 'Foo.bar');
+  }
+
   void test_parseAnnotation_n1() {
     createParser('@A');
     Annotation annotation = parser.parseAnnotation();
@@ -13947,6 +13999,15 @@
     expect(creation.typeArguments.toSource(), '<int, int Function(String)>');
   }
 
+  void test_parseLibraryIdentifier_builtin() {
+    String name = "deferred";
+    LibraryIdentifier identifier = parseLibraryIdentifier(name);
+    expectNotNullIfNoErrors(identifier);
+    listener.assertNoErrors();
+    expect(identifier.name, name);
+    expect(identifier.beginToken.type.isBuiltIn, isTrue);
+  }
+
   void test_parseLibraryIdentifier_invalid() {
     parseCompilationUnit('library <myLibId>;',
         errors: usingFastaParser
@@ -13966,23 +14027,6 @@
     expect(identifier.name, name);
   }
 
-  void test_parseLibraryIdentifier_single() {
-    String name = "a";
-    LibraryIdentifier identifier = parseLibraryIdentifier(name);
-    expectNotNullIfNoErrors(identifier);
-    listener.assertNoErrors();
-    expect(identifier.name, name);
-  }
-
-  void test_parseLibraryIdentifier_builtin() {
-    String name = "deferred";
-    LibraryIdentifier identifier = parseLibraryIdentifier(name);
-    expectNotNullIfNoErrors(identifier);
-    listener.assertNoErrors();
-    expect(identifier.name, name);
-    expect(identifier.beginToken.type.isBuiltIn, isTrue);
-  }
-
   void test_parseLibraryIdentifier_pseudo() {
     String name = "await";
     LibraryIdentifier identifier = parseLibraryIdentifier(name);
@@ -13992,6 +14036,14 @@
     expect(identifier.beginToken.type.isPseudo, isTrue);
   }
 
+  void test_parseLibraryIdentifier_single() {
+    String name = "a";
+    LibraryIdentifier identifier = parseLibraryIdentifier(name);
+    expectNotNullIfNoErrors(identifier);
+    listener.assertNoErrors();
+    expect(identifier.name, name);
+  }
+
   void test_parseOptionalReturnType() {
     // TODO(brianwilkerson) Implement tests for this method.
   }
@@ -14484,6 +14536,48 @@
  * the parsing statements.
  */
 abstract class StatementParserTestMixin implements AbstractParserTestCase {
+  void test_invalid_typeParamAnnotation() {
+    parseCompilationUnit('main() { C<@Foo T> v; }',
+        errors: usingFastaParser
+            // TODO(danrubel): Improve this error to indicate that annotations
+            // are not valid in this context.
+            ? [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 1)]
+            : [
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1)
+              ]);
+  }
+
+  void test_invalid_typeParamAnnotation2() {
+    parseCompilationUnit('main() { C<@Foo.bar(1) T> v; }',
+        errors: usingFastaParser
+            // TODO(danrubel): Improve this error to indicate that annotations
+            // are not valid in this context.
+            ? [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 1)]
+            : [
+                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1)
+              ]);
+  }
+
+  void test_invalid_typeParamAnnotation3() {
+    if (usingFastaParser) {
+      parseCompilationUnit('''
+main() {
+  C<@Foo.bar(const [], const [1], const{"":r""}, 0xFF + 2, .3, 4.5) T,
+    F Function<G>(int, String, {Bar b}),
+    void Function<H>(int i, [String j, K]),
+    A<B<C>>,
+    W<X<Y<Z>>>
+  > v;
+}''', errors: [
+        // TODO(danrubel): Improve this error to indicate that annotations
+        // are not valid in this context.
+        expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 13, 1)
+      ]);
+    }
+  }
+
   void test_parseAssertStatement() {
     var statement = parseStatement('assert (x);') as AssertStatement;
     assertNoErrors();
@@ -15232,48 +15326,6 @@
         new isInstanceOf<GenericFunctionType>());
   }
 
-  void test_invalid_typeParamAnnotation() {
-    parseCompilationUnit('main() { C<@Foo T> v; }',
-        errors: usingFastaParser
-            // TODO(danrubel): Improve this error to indicate that annotations
-            // are not valid in this context.
-            ? [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 1)]
-            : [
-                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
-                expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1)
-              ]);
-  }
-
-  void test_invalid_typeParamAnnotation2() {
-    parseCompilationUnit('main() { C<@Foo.bar(1) T> v; }',
-        errors: usingFastaParser
-            // TODO(danrubel): Improve this error to indicate that annotations
-            // are not valid in this context.
-            ? [expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 11, 1)]
-            : [
-                expectedError(ParserErrorCode.MISSING_IDENTIFIER, 11, 1),
-                expectedError(ParserErrorCode.EXPECTED_TOKEN, 11, 1)
-              ]);
-  }
-
-  void test_invalid_typeParamAnnotation3() {
-    if (usingFastaParser) {
-      parseCompilationUnit('''
-main() {
-  C<@Foo.bar(const [], const [1], const{"":r""}, 0xFF + 2, .3, 4.5) T,
-    F Function<G>(int, String, {Bar b}),
-    void Function<H>(int i, [String j, K]),
-    A<B<C>>,
-    W<X<Y<Z>>>
-  > v;
-}''', errors: [
-        // TODO(danrubel): Improve this error to indicate that annotations
-        // are not valid in this context.
-        expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 13, 1)
-      ]);
-    }
-  }
-
   void test_parseStatement_emptyTypeArgumentList() {
     var declaration = parseStatement('C<> c;') as VariableDeclarationStatement;
     assertErrorsWithCodes([ParserErrorCode.EXPECTED_TYPE_NAME]);
@@ -15478,29 +15530,6 @@
     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
@@ -15526,6 +15555,29 @@
     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_finally() {
     var statement =
         parseStatement('try {} catch (e, s) {} finally {}') as TryStatement;
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index 2601fcd..17789d4368 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -736,34 +736,6 @@
     _expectEqualOptions(options, expected);
   }
 
-  void test_getAnalysisOptions_default_flutter_repo() {
-    _defineMockLintRules();
-    AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
-    builderOptions.defaultOptions = defaultOptions;
-    AnalysisOptionsImpl expected = new AnalysisOptionsImpl();
-    expected.lint = true;
-    expected.lintRules = <Linter>[_mockLintRule, _mockPublicMemberApiDocs];
-    String packagesFilePath =
-        resourceProvider.convertPath('/some/directory/path/.packages');
-    createFile(packagesFilePath, 'flutter:/pkg/flutter/lib/');
-    String optionsFilePath = resourceProvider
-        .convertPath('/pkg/flutter/lib/analysis_options_user.yaml');
-    createFile(optionsFilePath, '''
-linter:
-  rules:
-    - mock_lint_rule
-''');
-    String projPath = resourceProvider.convertPath('/some/directory/path');
-    AnalysisOptions options;
-    try {
-      ContextBuilderOptions.flutterRepo = true;
-      options = builder.getAnalysisOptions(projPath);
-    } finally {
-      ContextBuilderOptions.flutterRepo = false;
-    }
-    _expectEqualOptions(options, expected);
-  }
-
   void test_getAnalysisOptions_default_noOverrides() {
     AnalysisOptionsImpl defaultOptions = new AnalysisOptionsImpl();
     defaultOptions.enableLazyAssignmentOperators = true;
diff --git a/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
new file mode 100644
index 0000000..c39a719
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/body_builder_test_helper.dart
@@ -0,0 +1,470 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+import 'dart:io' show File;
+
+import 'package:analyzer/analyzer.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/fasta/ast_body_builder.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import "package:front_end/src/api_prototype/front_end.dart";
+import "package:front_end/src/api_prototype/memory_file_system.dart";
+import "package:front_end/src/base/processed_options.dart";
+import "package:front_end/src/compute_platform_binaries_location.dart";
+import 'package:front_end/src/fasta/compiler_context.dart';
+import 'package:front_end/src/fasta/constant_context.dart';
+import 'package:front_end/src/fasta/dill/dill_target.dart';
+import "package:front_end/src/fasta/fasta_codes.dart";
+import 'package:front_end/src/fasta/kernel/body_builder.dart' hide Identifier;
+import 'package:front_end/src/fasta/kernel/forest.dart';
+import 'package:front_end/src/fasta/kernel/kernel_builder.dart';
+import "package:front_end/src/fasta/kernel/kernel_target.dart";
+import 'package:front_end/src/fasta/modifier.dart' as Modifier;
+import 'package:front_end/src/fasta/parser/parser.dart';
+import 'package:front_end/src/fasta/scanner.dart';
+import 'package:front_end/src/fasta/ticker.dart';
+import 'package:front_end/src/fasta/type_inference/type_inferrer.dart';
+import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
+import 'package:front_end/src/fasta/uri_translator_impl.dart';
+import 'package:kernel/class_hierarchy.dart' as kernel;
+import 'package:kernel/core_types.dart' as kernel;
+import 'package:kernel/kernel.dart' as kernel;
+
+import '../../generated/parser_test.dart';
+import '../../generated/test_support.dart';
+
+/**
+ * Implementation of [AbstractParserTestCase] specialized for testing building
+ * Analyzer AST using the fasta [Forest] API.
+ */
+class FastaBodyBuilderTestCase extends Object
+    with ParserTestHelpers
+    implements AbstractParserTestCase {
+  // TODO(danrubel): Consider HybridFileSystem.
+  static final MemoryFileSystem fs =
+      new MemoryFileSystem(Uri.parse("org-dartlang-test:///"));
+
+  /// The custom URI used to locate the dill file in the MemoryFileSystem.
+  static final Uri sdkSummary = fs.currentDirectory.resolve("vm_platform.dill");
+
+  /// The in memory test code URI
+  static final Uri entryPoint = fs.currentDirectory.resolve("main.dart");
+
+  static ProcessedOptions options;
+
+  static KernelTarget kernelTarget;
+
+  static TypeProvider _typeProvider;
+
+  final bool resolveTypes;
+
+  FastaBodyBuilderTestCase(this.resolveTypes);
+
+  TypeProvider get typeProvider => _typeProvider;
+
+  @override
+  void assertNoErrors() {
+    // TODO(brianwilkerson) Implement this.
+  }
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  Expression parseAdditiveExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseAssignableExpression(String code, bool primaryAllowed) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseAssignableSelector(String code, bool optional,
+      {bool allowConditional: true}) {
+    return parseExpression(code);
+  }
+
+  @override
+  AwaitExpression parseAwaitExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseBitwiseAndExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseBitwiseOrExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseBitwiseXorExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseCascadeSection(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  CompilationUnit parseCompilationUnit(String source,
+      {List<ErrorCode> codes, List<ExpectedError> errors}) {
+    return _parse(source, (parser, token) => parser.parseUnit(token.next));
+  }
+
+  @override
+  ConditionalExpression parseConditionalExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseConstExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  ConstructorInitializer parseConstructorInitializer(String code) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  CompilationUnit parseDirectives(String source,
+      [List<ErrorCode> errorCodes = const <ErrorCode>[]]) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  BinaryExpression parseEqualityExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseExpression(String source,
+      {List<ErrorCode> codes,
+      List<ExpectedError> errors,
+      int expectedEndOffset}) {
+    // TODO(brianwilkerson) Check error codes.
+    return _parse(source, (parser, token) => parser.parseExpression(token));
+  }
+
+  @override
+  List<Expression> parseExpressionList(String code) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  Expression parseExpressionWithoutCascade(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  FormalParameter parseFormalParameter(String code, ParameterKind kind,
+      {List<ErrorCode> errorCodes: const <ErrorCode>[]}) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  FormalParameterList parseFormalParameterList(String code,
+      {bool inFunctionType: false,
+      List<ErrorCode> errorCodes: const <ErrorCode>[],
+      List<ExpectedError> errors}) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  CompilationUnitMember parseFullCompilationUnitMember() {
+    throw new UnimplementedError();
+  }
+
+  @override
+  Directive parseFullDirective() {
+    throw new UnimplementedError();
+  }
+
+  @override
+  FunctionExpression parseFunctionExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  InstanceCreationExpression parseInstanceCreationExpression(
+      String code, Token newToken) {
+    return parseExpression(code);
+  }
+
+  @override
+  ListLiteral parseListLiteral(
+      Token token, String typeArgumentsCode, String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  TypedLiteral parseListOrMapLiteral(Token modifier, String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseLogicalAndExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseLogicalOrExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  MapLiteral parseMapLiteral(
+      Token token, String typeArgumentsCode, String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  MapLiteralEntry parseMapLiteralEntry(String code) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  Expression parseMultiplicativeExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  InstanceCreationExpression parseNewExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  NormalFormalParameter parseNormalFormalParameter(String code,
+      {bool inFunctionType: false,
+      List<ErrorCode> errorCodes: const <ErrorCode>[]}) {
+    throw new UnimplementedError();
+  }
+
+  @override
+  Expression parsePostfixExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Identifier parsePrefixedIdentifier(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parsePrimaryExpression(String code,
+      {int expectedEndOffset, List<ExpectedError> errors}) {
+    return parseExpression(code,
+        expectedEndOffset: expectedEndOffset, errors: errors);
+  }
+
+  @override
+  Expression parseRelationalExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  RethrowExpression parseRethrowExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  BinaryExpression parseShiftExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  SimpleIdentifier parseSimpleIdentifier(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Statement parseStatement(String source,
+      {bool enableLazyAssignmentOperators, int expectedEndOffset}) {
+    // TODO(brianwilkerson) Check error codes.
+    return _parse(source, (parser, token) => parser.parseStatement(token));
+  }
+
+  @override
+  Expression parseStringLiteral(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  SymbolLiteral parseSymbolLiteral(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseThrowExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  Expression parseThrowExpressionWithoutCascade(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  PrefixExpression parseUnaryExpression(String code) {
+    return parseExpression(code);
+  }
+
+  @override
+  VariableDeclarationList parseVariableDeclarationList(String source) {
+    throw new UnimplementedError();
+  }
+
+  Future setUp() async {
+    // TODO(danrubel): Tear down once all tests in group have been run.
+    if (options != null) {
+      return;
+    }
+
+    // Read the dill file containing kernel platform summaries into memory.
+    List<int> sdkSummaryBytes = await new File.fromUri(
+            computePlatformBinariesLocation().resolve("vm_platform.dill"))
+        .readAsBytes();
+    fs.entityForUri(sdkSummary).writeAsBytesSync(sdkSummaryBytes);
+
+    final CompilerOptions optionBuilder = new CompilerOptions()
+      ..strongMode = false // TODO(danrubel): enable strong mode.
+      ..reportMessages = true
+      ..verbose = false
+      ..fileSystem = fs
+      ..sdkSummary = sdkSummary
+      ..onProblem = (FormattedMessage problem, Severity severity,
+          List<FormattedMessage> context) {
+        // TODO(danrubel): Capture problems and check against expectations.
+//        print(problem.formatted);
+      };
+
+    options = new ProcessedOptions(optionBuilder, false, [entryPoint]);
+
+    UriTranslatorImpl uriTranslator = await options.getUriTranslator();
+
+    await CompilerContext.runWithOptions(options, (CompilerContext c) async {
+      DillTarget dillTarget = new DillTarget(
+          new Ticker(isVerbose: false), uriTranslator, options.target);
+
+      kernelTarget = new KernelTarget(fs, true, dillTarget, uriTranslator);
+
+      // Load the dill file containing platform code.
+      dillTarget.loader.read(Uri.parse('dart:core'), -1, fileUri: sdkSummary);
+      kernel.Component sdkComponent =
+          kernel.loadComponentFromBytes(sdkSummaryBytes);
+      dillTarget.loader
+          .appendLibraries(sdkComponent, byteCount: sdkSummaryBytes.length);
+      await dillTarget.buildOutlines();
+      await kernelTarget.buildOutlines();
+      kernelTarget.computeCoreTypes();
+      assert(kernelTarget.loader.coreTypes != null);
+
+      // Initialize the typeProvider if types should be resolved.
+      Map<String, Element> map = <String, Element>{};
+      var coreTypes = kernelTarget.loader.coreTypes;
+      for (var coreType in [
+        coreTypes.boolClass,
+        coreTypes.doubleClass,
+        coreTypes.functionClass,
+        coreTypes.futureClass,
+        coreTypes.futureOrClass,
+        coreTypes.intClass,
+        coreTypes.iterableClass,
+        coreTypes.iteratorClass,
+        coreTypes.listClass,
+        coreTypes.mapClass,
+        coreTypes.nullClass,
+        coreTypes.numClass,
+        coreTypes.objectClass,
+        coreTypes.stackTraceClass,
+        coreTypes.streamClass,
+        coreTypes.stringClass,
+        coreTypes.symbolClass,
+        coreTypes.typeClass
+      ]) {
+        map[coreType.name] = _buildElement(coreType);
+      }
+      Namespace namespace = new Namespace(map);
+      _typeProvider = new TypeProviderImpl.forNamespaces(namespace, namespace);
+    });
+  }
+
+  Element _buildElement(kernel.Class coreType) {
+    ClassElementImpl element =
+        new ClassElementImpl(coreType.name, coreType.fileOffset);
+    element.typeParameters = coreType.typeParameters.map((parameter) {
+      TypeParameterElementImpl element =
+          new TypeParameterElementImpl(parameter.name, parameter.fileOffset);
+      element.type = new TypeParameterTypeImpl(element);
+      return element;
+    }).toList();
+    return element;
+  }
+
+  T _parse<T>(
+      String source, void parseFunction(Parser parser, Token previousToken)) {
+    ScannerResult scan = scanString(source);
+
+    return CompilerContext.runWithOptions(options, (CompilerContext c) {
+      KernelLibraryBuilder library = new KernelLibraryBuilder(
+        entryPoint,
+        entryPoint,
+        kernelTarget.loader,
+        null /* actualOrigin */,
+        null /* enclosingLibrary */,
+      );
+      List<KernelTypeVariableBuilder> typeVariableBuilders =
+          <KernelTypeVariableBuilder>[];
+      List<KernelFormalParameterBuilder> formalParameterBuilders =
+          <KernelFormalParameterBuilder>[];
+      KernelProcedureBuilder procedureBuilder = new KernelProcedureBuilder(
+          null /* metadata */,
+          Modifier.staticMask /* or Modifier.varMask */,
+          kernelTarget.dynamicType,
+          "analyzerTest",
+          typeVariableBuilders,
+          formalParameterBuilders,
+          kernel.ProcedureKind.Method,
+          library,
+          -1 /* charOffset */,
+          -1 /* charOpenParenOffset */,
+          -1 /* charEndOffset */);
+
+      TypeInferrerDisabled typeInferrer =
+          new TypeInferrerDisabled(new TypeSchemaEnvironment(
+        kernelTarget.loader.coreTypes,
+        kernelTarget.loader.hierarchy,
+        // TODO(danrubel): Enable strong mode.
+        false /* strong mode */,
+      ));
+
+      BodyBuilder builder = new AstBodyBuilder(
+        library,
+        procedureBuilder,
+        library.scope,
+        procedureBuilder.computeFormalParameterScope(library.scope),
+        kernelTarget.loader.hierarchy,
+        kernelTarget.loader.coreTypes,
+        null /* classBuilder */,
+        false /* isInstanceMember */,
+        null /* uri */,
+        typeInferrer,
+        typeProvider,
+      )..constantContext = ConstantContext.none; // .inferred ?
+
+      Parser parser = new Parser(builder);
+      parseFunction(parser, parser.syntheticPreviousToken(scan.tokens));
+      return builder.pop();
+    });
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
index 5f08265..5041adb 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/class_declaration_test.dart
@@ -68,7 +68,7 @@
                 ParserErrorCode.MISSING_CLASS_BODY
               ],
               'class A extends B with _s_ {}',
-              failing: allExceptEof),
+              failing: ['functionVoid', 'functionNonVoid', 'getter']),
           new TestDescriptor(
               'extendsNameWithBody',
               'class A extends B with {}',
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
new file mode 100644
index 0000000..22b63e2
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/enum_declaration_test.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+
+import 'partial_code_support.dart';
+
+main() {
+  new EnumDeclarationTest().buildAll();
+}
+
+class EnumDeclarationTest extends PartialCodeTest {
+  buildAll() {
+    List<String> allExceptEof = PartialCodeTest.declarationSuffixes
+        .map((TestSuffix t) => t.name)
+        .toList();
+    buildTests(
+        'enum_declaration',
+        [
+          new TestDescriptor(
+              'keyword',
+              'enum',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.MISSING_ENUM_BODY
+              ],
+              'enum _s_ {}',
+              expectedErrorsInValidCode: [ParserErrorCode.EMPTY_ENUM_BODY],
+              failing: ['functionNonVoid', 'getter']),
+          new TestDescriptor('name', 'enum E',
+              [ParserErrorCode.MISSING_ENUM_BODY], 'enum E {}',
+              expectedErrorsInValidCode: [ParserErrorCode.EMPTY_ENUM_BODY]),
+          new TestDescriptor(
+              'missingName',
+              'enum {}',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EMPTY_ENUM_BODY
+              ],
+              'enum _s_ {}',
+              expectedErrorsInValidCode: [ParserErrorCode.EMPTY_ENUM_BODY]),
+          new TestDescriptor(
+              'leftBrace',
+              'enum E {',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ScannerErrorCode.EXPECTED_TOKEN
+              ],
+              'enum E {_s_}',
+              failing: [
+                'eof' /* tested separately below */,
+                'typedef',
+                'functionNonVoid',
+                'getter',
+                'setter'
+              ]),
+          new TestDescriptor(
+              'comma',
+              'enum E {,',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ScannerErrorCode.EXPECTED_TOKEN
+              ],
+              'enum E {_s_,_s_}',
+              failing: [
+                'eof' /* tested separately below */,
+                'typedef',
+                'functionNonVoid',
+                'getter',
+                'setter'
+              ]),
+          new TestDescriptor('value', 'enum E {a',
+              [ScannerErrorCode.EXPECTED_TOKEN], 'enum E {a}'),
+          new TestDescriptor(
+              'commaValue',
+              'enum E {,a',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ScannerErrorCode.EXPECTED_TOKEN
+              ],
+              'enum E {_s_, a}'),
+          new TestDescriptor('commaRightBrace', 'enum E {,}',
+              [ParserErrorCode.MISSING_IDENTIFIER], 'enum E {_s_}'),
+          new TestDescriptor('commaValueRightBrace', 'enum E {, a}',
+              [ParserErrorCode.MISSING_IDENTIFIER], 'enum E {_s_, a}'),
+        ],
+        PartialCodeTest.declarationSuffixes);
+    buildTests('enum_eof', [
+      new TestDescriptor(
+          'leftBrace',
+          'enum E {',
+          [ParserErrorCode.EMPTY_ENUM_BODY, ScannerErrorCode.EXPECTED_TOKEN],
+          'enum E {}',
+          expectedErrorsInValidCode: [ParserErrorCode.EMPTY_ENUM_BODY]),
+      new TestDescriptor(
+          'comma',
+          'enum E {,',
+          [ParserErrorCode.MISSING_IDENTIFIER, ScannerErrorCode.EXPECTED_TOKEN],
+          'enum E {_s_}'),
+    ], []);
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/field_declaration_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/field_declaration_test.dart
index d3a1af6..a4ddf6b 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/field_declaration_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/field_declaration_test.dart
@@ -31,11 +31,7 @@
         new TestDescriptor(
           'const_noName',
           'const',
-          [
-            ParserErrorCode.MISSING_IDENTIFIER,
-            ParserErrorCode.EXPECTED_TOKEN,
-            CompileTimeErrorCode.CONST_NOT_INITIALIZED
-          ],
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
           'const _s_;',
           failing: allExceptEof,
           expectedErrorsInValidCode: [
@@ -166,11 +162,7 @@
         new TestDescriptor(
           'static_const_noName',
           'static const',
-          [
-            ParserErrorCode.MISSING_IDENTIFIER,
-            ParserErrorCode.EXPECTED_TOKEN,
-            CompileTimeErrorCode.CONST_NOT_INITIALIZED
-          ],
+          [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN],
           'static const _s_;',
           failing: allExceptEof,
           expectedErrorsInValidCode: [
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
index eb14122..b7269e7 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/test_all.dart
@@ -10,6 +10,7 @@
 import 'class_declaration_test.dart' as class_declaration;
 import 'continue_statement_test.dart' as continue_statement;
 import 'do_statement_test.dart' as do_statement;
+import 'enum_declaration_test.dart' as enum_declaration;
 import 'export_directive_test.dart' as export_directive;
 import 'field_declaration_test.dart' as field_declaration;
 import 'forEach_statement_test.dart' as forEach_statement;
@@ -38,6 +39,7 @@
     class_declaration.main();
     continue_statement.main();
     do_statement.main();
+    enum_declaration.main();
     export_directive.main();
     field_declaration.main();
     for_statement.main();
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
index 1d27bed..bb3264c 100644
--- a/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/top_level_variable_test.dart
@@ -33,10 +33,15 @@
             [
               ParserErrorCode.MISSING_IDENTIFIER,
               ParserErrorCode.EXPECTED_TOKEN,
-              CompileTimeErrorCode.CONST_NOT_INITIALIZED
             ],
             "const _s_;",
-            failing: allExceptEof,
+            failing: [
+              'class',
+              'functionVoid',
+              'functionNonVoid',
+              'getter',
+              'setter'
+            ],
             expectedErrorsInValidCode: [
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
             ],
@@ -49,7 +54,7 @@
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
             ],
             "const a;",
-            failing: ['typedef', 'functionNonVoid', 'getter', 'setter'],
+            failing: ['functionNonVoid', 'getter', 'setter'],
             expectedErrorsInValidCode: [
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
             ],
@@ -72,11 +77,10 @@
             [
               ParserErrorCode.MISSING_IDENTIFIER,
               ParserErrorCode.EXPECTED_TOKEN,
-              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
             ],
             "const a, _s_;",
-            failing: ['typedef', 'functionNonVoid', 'getter', 'setter'],
+            failing: ['functionNonVoid', 'getter'],
             expectedErrorsInValidCode: [
               CompileTimeErrorCode.CONST_NOT_INITIALIZED,
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
@@ -88,11 +92,10 @@
             [
               ParserErrorCode.MISSING_IDENTIFIER,
               ParserErrorCode.EXPECTED_TOKEN,
-              CompileTimeErrorCode.CONST_NOT_INITIALIZED,
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
             ],
             "const int a, _s_;",
-            failing: ['typedef', 'functionNonVoid', 'getter', 'setter'],
+            failing: ['functionNonVoid', 'getter'],
             expectedErrorsInValidCode: [
               CompileTimeErrorCode.CONST_NOT_INITIALIZED,
               CompileTimeErrorCode.CONST_NOT_INITIALIZED
@@ -132,10 +135,15 @@
             [
               ParserErrorCode.MISSING_IDENTIFIER,
               ParserErrorCode.EXPECTED_TOKEN,
-              StaticWarningCode.FINAL_NOT_INITIALIZED
             ],
             "final _s_;",
-            failing: allExceptEof,
+            failing: [
+              'class',
+              'functionVoid',
+              'functionNonVoid',
+              'getter',
+              'setter'
+            ],
             expectedErrorsInValidCode: [
               StaticWarningCode.FINAL_NOT_INITIALIZED
             ],
@@ -148,7 +156,7 @@
               StaticWarningCode.FINAL_NOT_INITIALIZED
             ],
             "final a;",
-            failing: ['typedef', 'functionNonVoid', 'getter', 'setter'],
+            failing: ['functionNonVoid', 'getter', 'setter'],
             expectedErrorsInValidCode: [
               StaticWarningCode.FINAL_NOT_INITIALIZED
             ],
@@ -189,14 +197,14 @@
               ParserErrorCode.EXPECTED_TOKEN
             ],
             "var _s_;",
-            failing: allExceptEof,
+            failing: ['functionVoid', 'functionNonVoid', 'getter', 'setter'],
           ),
           new TestDescriptor(
             'varName',
             'var a',
             [ParserErrorCode.EXPECTED_TOKEN],
             "var a;",
-            failing: ['typedef', 'functionNonVoid', 'getter', 'setter'],
+            failing: ['functionNonVoid', 'getter', 'setter'],
           ),
           new TestDescriptor(
             'varNameEquals',
diff --git a/pkg/analyzer/test/src/fasta/resolution_test.dart b/pkg/analyzer/test/src/fasta/resolution_test.dart
new file mode 100644
index 0000000..0eedb6b
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/resolution_test.dart
@@ -0,0 +1,99 @@
+// 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/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/parser_test.dart';
+import 'body_builder_test_helper.dart';
+
+main() async {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ResolutionTest);
+  });
+}
+
+/**
+ * Tests of the fasta parser based on [ExpressionParserTestMixin].
+ */
+@reflectiveTest
+class ResolutionTest extends FastaBodyBuilderTestCase {
+  ResolutionTest() : super(true);
+
+  test_booleanLiteral_false() {
+    Expression result = parseExpression('false');
+    expect(result, new isInstanceOf<BooleanLiteral>());
+    expect((result as BooleanLiteral).staticType, typeProvider.boolType);
+  }
+
+  test_booleanLiteral_true() {
+    Expression result = parseExpression('true');
+    expect(result, new isInstanceOf<BooleanLiteral>());
+    expect((result as BooleanLiteral).staticType, typeProvider.boolType);
+  }
+
+  test_doubleLiteral() {
+    Expression result = parseExpression('4.2');
+    expect(result, new isInstanceOf<DoubleLiteral>());
+    expect((result as DoubleLiteral).staticType, typeProvider.doubleType);
+  }
+
+  test_integerLiteral() {
+    Expression result = parseExpression('3');
+    expect(result, new isInstanceOf<IntegerLiteral>());
+    expect((result as IntegerLiteral).staticType, typeProvider.intType);
+  }
+
+  @failingTest
+  test_listLiteral_explicitType() {
+    Expression result = parseExpression('<int>[]');
+    expect(result, new isInstanceOf<ListLiteral>());
+    InterfaceType listType = typeProvider.listType;
+    expect((result as ListLiteral).staticType,
+        listType.instantiate([typeProvider.intType]));
+  }
+
+  @failingTest
+  test_listLiteral_noType() {
+    Expression result = parseExpression('[]');
+    expect(result, new isInstanceOf<ListLiteral>());
+    InterfaceType listType = typeProvider.listType;
+    expect((result as ListLiteral).staticType,
+        listType.instantiate([typeProvider.dynamicType]));
+  }
+
+  @failingTest
+  test_mapLiteral_explicitType() {
+    Expression result = parseExpression('<String, int>{}');
+    expect(result, new isInstanceOf<MapLiteral>());
+    InterfaceType mapType = typeProvider.mapType;
+    expect((result as MapLiteral).staticType,
+        mapType.instantiate([typeProvider.stringType, typeProvider.intType]));
+  }
+
+  @failingTest
+  test_mapLiteral_noType() {
+    Expression result = parseExpression('{}');
+    expect(result, new isInstanceOf<MapLiteral>());
+    InterfaceType mapType = typeProvider.mapType;
+    expect(
+        (result as MapLiteral).staticType,
+        mapType
+            .instantiate([typeProvider.dynamicType, typeProvider.dynamicType]));
+  }
+
+  test_nullLiteral() {
+    Expression result = parseExpression('null');
+    expect(result, new isInstanceOf<NullLiteral>());
+    expect((result as NullLiteral).staticType, typeProvider.nullType);
+  }
+
+  test_simpleStringLiteral() {
+    Expression result = parseExpression('"abc"');
+    expect(result, new isInstanceOf<SimpleStringLiteral>());
+    expect((result as SimpleStringLiteral).staticType, typeProvider.stringType);
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/test_all.dart b/pkg/analyzer/test/src/fasta/test_all.dart
index 036a911..675b470 100644
--- a/pkg/analyzer/test/src/fasta/test_all.dart
+++ b/pkg/analyzer/test/src/fasta/test_all.dart
@@ -8,6 +8,7 @@
 import 'message_coverage_test.dart' as message_coverage;
 import 'recovery/test_all.dart' as recovery;
 import 'resolution_applier_test.dart' as resolution_applier;
+import 'resolution_test.dart' as resolution;
 
 main() {
   defineReflectiveSuite(() {
@@ -15,5 +16,6 @@
     message_coverage.main();
     recovery.main();
     resolution_applier.main();
+    resolution.main();
   }, name: 'fasta');
 }
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 44e1444..73af369 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -385,7 +385,6 @@
     expect(v.initializer.type.toString(), '() → () → Null');
   }
 
-  @failingTest
   test_circularReference_viaClosures() async {
     var mainUnit = await checkFileElement('''
 var x = /*info:INFERRED_TYPE_CLOSURE*/() => /*error:TOP_LEVEL_CYCLE*/y;
@@ -399,7 +398,6 @@
     expect(y.type.toString(), 'dynamic');
   }
 
-  @failingTest
   test_circularReference_viaClosures_initializerTypes() async {
     var mainUnit = await checkFileElement('''
 var x = /*info:INFERRED_TYPE_CLOSURE*/() => /*error:TOP_LEVEL_CYCLE*/y;
@@ -3604,7 +3602,6 @@
 ''');
   }
 
-  @failingTest
   test_instantiateToBounds_typeName_OK_hasBound_definedAfter() async {
     var unit = await checkFileElement(r'''
 class B<T extends A> {}
@@ -4149,7 +4146,6 @@
     expect(v.type.toString(), 'List<dynamic>');
   }
 
-  @failingTest
   test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1() async {
     // Note: (f<dynamic>) is not properly resulting in an instantiated
     // function type due to dartbug.com/25824.
@@ -4182,7 +4178,6 @@
     expect(v.type.toString(), 'List<int>');
   }
 
-  @failingTest
   test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1() async {
     // TODO(paulberry): for some reason (f<int>) is not properly resulting
     // in an instantiated function type.
@@ -4419,6 +4414,40 @@
     CompilationUnit unit = await checkFile(content);
     return unit.element;
   }
+
+  @failingTest
+  @override
+  void test_circularReference_viaClosures() {
+    super.test_circularReference_viaClosures();
+  }
+
+  @failingTest
+  @override
+  void test_circularReference_viaClosures_initializerTypes() {
+    super.test_circularReference_viaClosures_initializerTypes();
+  }
+
+  @failingTest
+  @override
+  void test_instantiateToBounds_typeName_OK_hasBound_definedAfter() {
+    super.test_instantiateToBounds_typeName_OK_hasBound_definedAfter();
+  }
+
+  @failingTest
+  @override
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1();
+  }
+
+  @failingTest
+  @override
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1();
+  }
 }
 
 @reflectiveTest
@@ -4429,6 +4458,19 @@
   @override
   bool get hasExtraTaskModelPass => false;
 
+  @failingTest
+  @override
+  void test_circularReference_viaClosures() {
+    super.test_circularReference_viaClosures();
+  }
+
+  @failingTest
+  @override
+  test_circularReference_viaClosures_initializerTypes() async {
+    await super.test_circularReference_viaClosures_initializerTypes();
+  }
+
+  @failingTest
   @override
   test_instantiateToBounds_typeName_OK_hasBound_definedAfter() async {
     await super.test_instantiateToBounds_typeName_OK_hasBound_definedAfter();
@@ -4448,18 +4490,16 @@
   }
 
   @override
-  test_circularReference_viaClosures() async {
-    await super.test_circularReference_viaClosures();
-  }
-
-  @override
   test_unsafeBlockClosureInference_closureCall() async {
     await super.test_unsafeBlockClosureInference_closureCall();
   }
 
+  @failingTest
   @override
-  test_circularReference_viaClosures_initializerTypes() async {
-    await super.test_circularReference_viaClosures_initializerTypes();
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_explicitDynamicParam_viaExpr1();
   }
 
   @failingTest
@@ -4471,6 +4511,14 @@
 
   @failingTest
   @override
+  void
+      test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1() {
+    super
+        .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr1();
+  }
+
+  @failingTest
+  @override
   test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2() async {
     await super
         .test_unsafeBlockClosureInference_functionCall_explicitTypeParam_viaExpr2();
diff --git a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
index 1c2fad7..2ab6bc1 100644
--- a/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
+++ b/pkg/analyzer_plugin/lib/src/channel/isolate_channel.dart
@@ -222,7 +222,7 @@
 
   @override
   void kill() {
-    _isolate.kill(priority: Isolate.immediate);
+    _isolate?.kill(priority: Isolate.immediate);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 8ff3879..1ad4fc81 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -382,12 +382,7 @@
     // TODO(sigmund): use libraries.json instead of .platform files, then simply
     // use the `supported` bit.
     if (libraryUri != null && libraryUri.scheme != "unsupported") {
-      // Dart2js always "supports" importing 'dart:mirrors' but will abort
-      // the compilation at a later point if the backend doesn't support
-      // mirrors. In this case 'mirrors' should not be in the environment.
-      if (libraryName == 'mirrors') {
-        return compiler.backend.supportsReflection ? "true" : null;
-      }
+      if (libraryName == 'mirrors') return null;
       if (libraryName == 'isolate') return null;
       return "true";
     }
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index 152ac6c..c35ddbb 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -35,12 +35,10 @@
   static const String generateCodeWithCompileTimeErrors =
       '--generate-code-with-compile-time-errors';
 
-  /// TODO(sigmund): delete this flag.
+  /// TODO(sigmund): delete these flags.
   static const String useKernel = '--use-kernel';
-
-  /// Temporary flag to revert to the old front-end once the new common
-  /// 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';
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index d0a95e6..ff7d0d7 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -1129,6 +1129,10 @@
   FunctionEntity get convertRtiToRuntimeType =>
       _findHelperFunction('convertRtiToRuntimeType');
 
+  FunctionEntity _extractTypeArguments;
+  FunctionEntity get extractTypeArguments => _extractTypeArguments ??=
+      _findLibraryMember(internalLibrary, 'extractTypeArguments');
+
   FunctionEntity get toStringForNativeObject =>
       _findHelperFunction('toStringForNativeObject');
 
@@ -1210,17 +1214,6 @@
       _env.lookupLibrary(Uris.dart__js_embedded_names, required: true),
       'JsBuiltin');
 
-  // From dart:_isolate_helper
-
-  FunctionEntity get startRootIsolate =>
-      _findLibraryMember(isolateHelperLibrary, 'startRootIsolate');
-
-  FunctionEntity get currentIsolate =>
-      _findLibraryMember(isolateHelperLibrary, '_currentIsolate');
-
-  FunctionEntity get callInIsolate =>
-      _findLibraryMember(isolateHelperLibrary, '_callInIsolate');
-
   static final Uri PACKAGE_EXPECT =
       new Uri(scheme: 'package', path: 'expect/expect.dart');
 
@@ -1393,6 +1386,9 @@
   /// Calls [f] for each class member declared in [cls].
   void forEachLocalClassMember(ClassEntity cls, void f(MemberEntity member));
 
+  /// Calls [f] for each class member added to [cls] during compilation.
+  void forEachInjectedClassMember(ClassEntity cls, void f(MemberEntity member));
+
   /// Calls [f] for each class member declared or inherited in [cls] together
   /// with the class that declared the member.
   ///
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 7bc310e..dde70dd 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -39,7 +39,6 @@
 import 'io/source_information.dart' show SourceInformation;
 import 'io/source_file.dart' show Binary;
 import 'js_backend/backend.dart' show JavaScriptBackend;
-import 'js_backend/element_strategy.dart' show ElementBackendStrategy;
 import 'kernel/kernel_backend_strategy.dart';
 import 'kernel/kernel_strategy.dart';
 import 'library_loader.dart'
@@ -192,20 +191,12 @@
     } else {
       _reporter = new CompilerDiagnosticReporter(this, options);
     }
-    if (options.useKernel) {
-      kernelFrontEndTask = new GenericTask('Front end', measurer);
-      frontendStrategy = new KernelFrontEndStrategy(kernelFrontEndTask, options,
-          reporter, environment, options.kernelInitializedCompilerState);
-      backendStrategy = new KernelBackendStrategy(this);
-      _impactCache = <Entity, WorldImpact>{};
-      _impactCacheDeleter = new _MapImpactCacheDeleter(_impactCache);
-    } else {
-      frontendStrategy = new ResolutionFrontEndStrategy(this);
-      backendStrategy = new ElementBackendStrategy(this);
-      _resolution = createResolution();
-      _impactCache = _resolution._worldImpactCache;
-      _impactCacheDeleter = _resolution;
-    }
+    kernelFrontEndTask = new GenericTask('Front end', measurer);
+    frontendStrategy = new KernelFrontEndStrategy(kernelFrontEndTask, options,
+        reporter, environment, options.kernelInitializedCompilerState);
+    backendStrategy = new KernelBackendStrategy(this);
+    _impactCache = <Entity, WorldImpact>{};
+    _impactCacheDeleter = new _MapImpactCacheDeleter(_impactCache);
 
     if (options.verbose) {
       progress = new ProgressImpl(_reporter);
@@ -241,7 +232,7 @@
       dumpInfoTask = new DumpInfoTask(this),
       selfTask,
     ];
-    if (options.useKernel) tasks.add(kernelFrontEndTask);
+    tasks.add(kernelFrontEndTask);
 
     _parsingContext =
         new ParsingContext(reporter, parser, scanner, patchParser, backend);
@@ -385,47 +376,9 @@
     // front end for the Kernel path since Kernel doesn't have the notion of
     // imports (everything has already been resolved). (See
     // https://github.com/dart-lang/sdk/issues/29368)
-    if (!options.useKernel) {
-      for (Uri uri in resolvedUriTranslator.disallowedLibraryUris) {
-        if (loadedLibraries.containsLibrary(uri)) {
-          Set<String> importChains =
-              computeImportChainsFor(loadedLibraries, uri);
-          reporter.reportInfo(
-              NO_LOCATION_SPANNABLE, MessageKind.DISALLOWED_LIBRARY_IMPORT, {
-            'uri': uri,
-            'importChain': importChains
-                .join(MessageTemplate.DISALLOWED_LIBRARY_IMPORT_PADDING)
-          });
-        }
-      }
-
-      if (loadedLibraries.containsLibrary(Uris.dart_core)) {
-        bool importsMirrorsLibrary =
-            loadedLibraries.containsLibrary(Uris.dart_mirrors);
-        if (importsMirrorsLibrary && !backend.supportsReflection) {
-          Set<String> importChains =
-              computeImportChainsFor(loadedLibraries, Uris.dart_mirrors);
-          reporter.reportErrorMessage(NO_LOCATION_SPANNABLE,
-              MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_BY_BACKEND, {
-            'importChain': importChains
-                .join(MessageTemplate.MIRRORS_NOT_SUPPORTED_BY_BACKEND_PADDING)
-          });
-        } else if (importsMirrorsLibrary &&
-            !options.enableExperimentalMirrors) {
-          Set<String> importChains =
-              computeImportChainsFor(loadedLibraries, Uris.dart_mirrors);
-          reporter.reportWarningMessage(
-              NO_LOCATION_SPANNABLE, MessageKind.IMPORT_EXPERIMENTAL_MIRRORS, {
-            'importChain': importChains
-                .join(MessageTemplate.IMPORT_EXPERIMENTAL_MIRRORS_PADDING)
-          });
-        }
-      }
-    } else {
-      if (loadedLibraries.containsLibrary(Uris.dart_mirrors)) {
-        reporter.reportWarningMessage(NO_LOCATION_SPANNABLE,
-            MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_WITH_CFE);
-      }
+    if (loadedLibraries.containsLibrary(Uris.dart_mirrors)) {
+      reporter.reportWarningMessage(NO_LOCATION_SPANNABLE,
+          MessageKind.MIRRORS_LIBRARY_NOT_SUPPORT_WITH_CFE);
     }
     backend.onLibrariesLoaded(frontendStrategy.commonElements, loadedLibraries);
     return loadedLibraries;
@@ -529,11 +482,6 @@
         FunctionEntity mainFunction =
             frontendStrategy.computeMain(rootLibrary, mainImpact);
 
-        if (!options.useKernel) {
-          // TODO(johnniwinther): Support mirrors usages analysis from dill.
-          mirrorUsageAnalyzerTask.analyzeUsage(rootLibrary);
-        }
-
         // In order to see if a library is deferred, we must compute the
         // compile-time constants that are metadata.  This means adding
         // something to the resolution queue.  So we cannot wait with
@@ -562,11 +510,6 @@
             }
           }
         }
-        if (frontendStrategy.commonElements.mirrorsLibrary != null &&
-            !options.useKernel) {
-          // TODO(johnniwinther): Support mirrors from dill.
-          resolveLibraryMetadata();
-        }
         reporter.log('Resolving...');
 
         processQueue(frontendStrategy.elementEnvironment, resolutionEnqueuer,
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index e08a1d1..0c6117c 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -132,7 +132,6 @@
   bool showWarnings;
   bool showHints;
   bool enableColors;
-  bool useKernel = true;
   Uri platformBinaries = computePlatformBinariesLocation();
   Map<String, dynamic> environment = new Map<String, dynamic>();
 
@@ -248,8 +247,7 @@
   }
 
   void setUseOldFrontend(String argument) {
-    useKernel = false;
-    passThrough(argument);
+    helpAndFail("Option '${Flags.useOldFrontend}' is not supported.");
   }
 
   void setPlatformBinaries(String argument) {
@@ -505,11 +503,9 @@
   }
 
   Uri script = currentDirectory.resolve(arguments[0]);
-  if (useKernel) {
-    diagnosticHandler.autoReadFileUri = true;
-    // TODO(sigmund): reenable hints (Issue #32111)
-    diagnosticHandler.showHints = showHints = false;
-  }
+  diagnosticHandler.autoReadFileUri = true;
+  // TODO(sigmund): reenable hints (Issue #32111)
+  diagnosticHandler.showHints = showHints = false;
   CompilerOptions compilerOptions = CompilerOptions.parse(options,
       libraryRoot: libraryRoot, platformBinaries: platformBinaries)
     ..entryPoint = script
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index 1e56455..1ccd493 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -97,9 +97,6 @@
   /// Will be `true` if the program contains deferred libraries.
   bool isProgramSplit = false;
 
-  /// Whether mirrors have been used in the program.
-  bool _isMirrorsUsed = false;
-
   static const ImpactUseCase IMPACT_USE = const ImpactUseCase('Deferred load');
 
   /// A mapping from the name of a defer import to all the output units it
@@ -224,10 +221,6 @@
       collectConstantsInBody(analyzableElement, constants);
     }
 
-    if (_isMirrorsUsed) {
-      collectConstantsFromMetadata(element, constants);
-    }
-
     if (element is FunctionEntity) {
       _collectTypeDependencies(
           elementEnvironment.getFunctionType(element), elements);
@@ -686,8 +679,6 @@
 
     work() {
       var queue = new WorkQueue(this.importSets);
-      _isMirrorsUsed =
-          closedWorld.backendUsage.isMirrorsUsed && !compiler.options.useKernel;
 
       // Add `main` and their recursive dependencies to the main output unit.
       // We do this upfront to avoid wasting time visiting these elements when
@@ -696,8 +687,8 @@
 
       // Also add "global" dependencies to the main output unit.  These are
       // things that the backend needs but cannot associate with a particular
-      // element, for example, startRootIsolate.  This set also contains
-      // elements for which we lack precise information.
+      // element. This set also contains elements for which we lack precise
+      // information.
       for (MemberEntity element
           in closedWorld.backendUsage.globalFunctionDependencies) {
         element = element is MethodElement ? element.implementation : element;
@@ -708,9 +699,6 @@
         element = element is ClassElement ? element.implementation : element;
         queue.addElement(element, importSets.mainSet);
       }
-      if (_isMirrorsUsed) {
-        addMirrorElementsForLibrary(queue, main.library, importSets.mainSet);
-      }
 
       void emptyQueue() {
         while (queue.isNotEmpty) {
@@ -729,10 +717,6 @@
       }
 
       emptyQueue();
-      if (_isMirrorsUsed) {
-        addDeferredMirrorElements(queue);
-        emptyQueue();
-      }
     }
 
     reporter.withCurrentElement(main.library, () => measure(work));
@@ -1262,4 +1246,12 @@
         _constantToUnit[constant] == null || _constantToUnit[constant] == unit);
     _constantToUnit[constant] = unit;
   }
+
+  /// Registers [newEntity] to be emitted in the same output unit as
+  /// [existingEntity];
+  void registerColocatedMembers(
+      MemberEntity existingEntity, MemberEntity newEntity) {
+    assert(_entityToUnit[newEntity] == null);
+    _entityToUnit[newEntity] = outputUnitForMember(existingEntity);
+  }
 }
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index dee89c3..251dacd 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -637,7 +637,7 @@
         dumpInfoDuration: new Duration(milliseconds: this.timing),
         noSuchMethodEnabled: closedWorld.backendUsage.isNoSuchMethodUsed,
         isRuntimeTypeUsed: closedWorld.backendUsage.isRuntimeTypeUsed,
-        isIsolateInUse: closedWorld.backendUsage.isIsolateInUse,
+        isIsolateInUse: false,
         isFunctionApplyUsed: closedWorld.backendUsage.isFunctionApplyUsed,
         isMirrorsUsed: closedWorld.backendUsage.isMirrorsUsed,
         minified: compiler.options.enableMinification);
diff --git a/pkg/compiler/lib/src/helpers/debug_collection.dart b/pkg/compiler/lib/src/helpers/debug_collection.dart
index 2ec5eb9..03ac0e9 100644
--- a/pkg/compiler/lib/src/helpers/debug_collection.dart
+++ b/pkg/compiler/lib/src/helpers/debug_collection.dart
@@ -21,12 +21,10 @@
     putIfAbsentCallback = value;
   }
 
-  Map<RK, RV> cast<RK, RV>() {
-    Map<Object, Object> self = this;
-    return self is Map<RK, RV> ? self : this.retype<RK, RV>();
-  }
+  Map<RK, RV> cast<RK, RV>() => Map.castFrom<K, V, RK, RV>(this);
 
-  Map<RK, RV> retype<RK, RV>() => Map.castFrom<K, V, RK, RV>(this);
+  @Deprecated("Use cast instead.")
+  Map<RK, RV> retype<RK, RV>() => cast<RK, RV>();
 
   bool containsValue(Object value) {
     return sourceMap.containsValue(value);
@@ -109,12 +107,10 @@
 
   Iterator<E> get iterator => iterable.iterator;
 
-  Iterable<R> cast<R>() {
-    Iterable<Object> self = this;
-    return self is Iterable<R> ? self : this.retype<R>();
-  }
+  Iterable<R> cast<R>() => Iterable.castFrom<E, R>(this);
 
-  Iterable<R> retype<R>() => Iterable.castFrom<E, R>(this);
+  @Deprecated("Use cast instead.")
+  Iterable<R> retype<R>() => cast<R>();
 
   Iterable<T> map<T>(T f(E element)) => iterable.map(f);
 
@@ -193,12 +189,10 @@
 
   List<E> get list => iterable;
 
-  List<R> cast<R>() {
-    List<Object> self = this;
-    return self is List<R> ? self : this.retype<R>();
-  }
+  List<R> cast<R>() => List.castFrom<E, R>(this);
 
-  List<R> retype<R>() => List.castFrom<E, R>(this);
+  @Deprecated("Use cast instead.")
+  List<R> retype<R>() => cast<R>();
 
   List<E> operator +(List<E> other) => list + other;
 
@@ -302,12 +296,10 @@
 
   Set<E> get set => iterable;
 
-  Set<R> cast<R>() {
-    Set<Object> self = this;
-    return self is Set<R> ? self : this.retype<R>();
-  }
+  Set<R> cast<R>() => Set.castFrom<E, R>(this);
 
-  Set<R> retype<R>() => Set.castFrom<E, R>(this);
+  @Deprecated("Use cast instead.")
+  Set<R> retype<R>() => cast<R>();
 
   bool contains(Object value) => set.contains(value);
 
diff --git a/pkg/compiler/lib/src/helpers/expensive_map.dart b/pkg/compiler/lib/src/helpers/expensive_map.dart
index 35001e4..48be384 100644
--- a/pkg/compiler/lib/src/helpers/expensive_map.dart
+++ b/pkg/compiler/lib/src/helpers/expensive_map.dart
@@ -68,12 +68,10 @@
     }
   }
 
-  Map<KR, VR> cast<KR, VR>() {
-    Map<Object, Object> self = this;
-    return self is Map<KR, VR> ? self : Map.castFrom<K, V, KR, VR>(this);
-  }
+  Map<KR, VR> cast<KR, VR>() => Map.castFrom<K, V, KR, VR>(this);
 
-  Map<KR, VR> retype<KR, VR>() => Map.castFrom<K, V, KR, VR>(this);
+  @Deprecated("Use cast instead.")
+  Map<KR, VR> retype<KR, VR>() => cast<KR, VR>();
 
   Iterable<MapEntry<K, V>> get entries => _maps[0].entries;
 
diff --git a/pkg/compiler/lib/src/helpers/track_map.dart b/pkg/compiler/lib/src/helpers/track_map.dart
index 833a08a..0a87cf5 100644
--- a/pkg/compiler/lib/src/helpers/track_map.dart
+++ b/pkg/compiler/lib/src/helpers/track_map.dart
@@ -99,7 +99,8 @@
 
   Map<KR, VR> cast<KR, VR>() => _map.cast<KR, VR>();
 
-  Map<KR, VR> retype<KR, VR>() => _map.retype<KR, VR>();
+  @Deprecated("Use cast instead.")
+  Map<KR, VR> retype<KR, VR>() => cast<KR, VR>();
 
   Iterable<MapEntry<K, V>> get entries => _map.entries;
 
diff --git a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
index 217c1ee..dc823ff 100644
--- a/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
+++ b/pkg/compiler/lib/src/inferrer/kernel_inferrer_engine.dart
@@ -212,8 +212,8 @@
         }
         break;
       case MemberKind.closureField:
-        break;
       case MemberKind.signature:
+      case MemberKind.generatorBody:
         break;
     }
     failedAt(member, 'Unexpected member definition: $definition.');
diff --git a/pkg/compiler/lib/src/io/kernel_source_information.dart b/pkg/compiler/lib/src/io/kernel_source_information.dart
index 586b0f7..1b85861 100644
--- a/pkg/compiler/lib/src/io/kernel_source_information.dart
+++ b/pkg/compiler/lib/src/io/kernel_source_information.dart
@@ -144,6 +144,7 @@
           return _buildFunction(name, base ?? node, node.function);
         }
         break;
+      // TODO(sra): generatorBody
       default:
     }
     return _buildTreeNode(base ?? node, name: name);
@@ -209,6 +210,16 @@
           return _buildBody(node, node.function.body);
         }
         break;
+      case MemberKind.generatorBody:
+        ir.Node node = definition.node;
+        if (node is ir.FunctionDeclaration) {
+          return _buildBody(node, node.function.body);
+        } else if (node is ir.FunctionExpression) {
+          return _buildBody(node, node.function.body);
+        } else if (node is ir.Member && node.function != null) {
+          return _buildBody(node, node.function.body);
+        }
+        break;
       default:
     }
     return _buildTreeNode(definition.node);
diff --git a/pkg/compiler/lib/src/js/rewrite_async.dart b/pkg/compiler/lib/src/js/rewrite_async.dart
index c26521e..936cddf 100644
--- a/pkg/compiler/lib/src/js/rewrite_async.dart
+++ b/pkg/compiler/lib/src/js/rewrite_async.dart
@@ -159,6 +159,9 @@
   js.VariableUse get self => new js.VariableUse(selfName);
   String selfName;
 
+  /// The rewritten code can take type arguments. These are added if needed.
+  List<String> typeArgumentNames = <String>[];
+
   final DiagnosticReporter reporter;
   // For error reporting only.
   Spannable get spannable {
@@ -245,6 +248,15 @@
     return result;
   }
 
+  List<js.Expression> processTypeArguments(List<js.Expression> types) {
+    if (types == null) {
+      String name = freshName('type');
+      typeArgumentNames.add(name);
+      return <js.Expression>[new js.VariableUse(name)];
+    }
+    return types;
+  }
+
   /// All the pieces are collected in this map, to create a switch with a case
   /// for each label.
   ///
@@ -532,6 +544,7 @@
   /// Returns the rewritten function.
   js.Fun finishFunction(
       List<js.Parameter> parameters,
+      List<js.Parameter> typeParameters,
       js.Statement rewrittenBody,
       js.VariableDeclarationList variableDeclarations,
       SourceInformation functionSourceInformation,
@@ -738,8 +751,11 @@
     js.VariableDeclarationList variableDeclarations =
         new js.VariableDeclarationList(variables);
 
-    return finishFunction(node.params, rewrittenBody, variableDeclarations,
-        node.sourceInformation, bodySourceInformation);
+    // Names are already safe when added.
+    List<js.Parameter> typeParameters =
+        typeArgumentNames.map((name) => new js.Parameter(name)).toList();
+    return finishFunction(node.params, typeParameters, rewrittenBody,
+        variableDeclarations, node.sourceInformation, bodySourceInformation);
   }
 
   @override
@@ -1739,7 +1755,7 @@
   ///
   /// Specific to async methods.
   final js.Expression completerFactory;
-  final js.Expression completerFactoryTypeArgument;
+  List<js.Expression> completerFactoryTypeArguments;
 
   final js.Expression wrapBody;
 
@@ -1749,7 +1765,7 @@
       this.asyncReturn,
       this.asyncRethrow,
       this.completerFactory,
-      this.completerFactoryTypeArgument,
+      this.completerFactoryTypeArguments,
       this.wrapBody,
       String safeVariableName(String proposedName),
       js.Name bodyName})
@@ -1803,7 +1819,7 @@
         completer,
         js.js('#(#)', [
           completerFactory,
-          completerFactoryTypeArgument
+          completerFactoryTypeArguments
         ]).withSourceInformation(sourceInformation),
         sourceInformation));
     if (analysis.hasExplicitReturns) {
@@ -1816,6 +1832,8 @@
   @override
   void initializeNames() {
     completerName = freshName("completer");
+    completerFactoryTypeArguments =
+        processTypeArguments(completerFactoryTypeArguments);
   }
 
   @override
@@ -1833,6 +1851,7 @@
   @override
   js.Fun finishFunction(
       List<js.Parameter> parameters,
+      List<js.Parameter> typeParameters,
       js.Statement rewrittenBody,
       js.VariableDeclarationList variableDeclarations,
       SourceInformation functionSourceInformation,
@@ -1884,12 +1903,13 @@
       "innerFunction": innerFunction,
     }).withSourceInformation(bodySourceInformation);
     return js.js("""
-        function (#parameters) {
+        function (#parameters, #typeParameters) {
           #variableDeclarations;
           var #bodyName = #wrapBodyCall;
           #returnAsyncStart;
         }""", {
       "parameters": parameters,
+      "typeParameters": typeParameters,
       "variableDeclarations": variableDeclarations,
       "bodyName": bodyName,
       "wrapBodyCall": wrapBodyCall,
@@ -1904,7 +1924,7 @@
   /// Constructor creating the Iterable for a sync* method. Called with
   /// [bodyName].
   final js.Expression iterableFactory;
-  final js.Expression iterableFactoryTypeArgument;
+  List<js.Expression> iterableFactoryTypeArguments;
 
   /// A JS Expression that creates a marker showing that iteration is over.
   ///
@@ -1922,7 +1942,7 @@
   SyncStarRewriter(DiagnosticReporter diagnosticListener, spannable,
       {this.endOfIteration,
       this.iterableFactory,
-      this.iterableFactoryTypeArgument,
+      this.iterableFactoryTypeArguments,
       this.yieldStarExpression,
       this.uncaughtErrorExpression,
       String safeVariableName(String proposedName),
@@ -1949,6 +1969,7 @@
   @override
   js.Fun finishFunction(
       List<js.Parameter> parameters,
+      List<js.Parameter> typeParameters,
       js.Statement rewrittenBody,
       js.VariableDeclarationList variableDeclarations,
       SourceInformation functionSourceInformation,
@@ -2017,19 +2038,20 @@
     js.Expression callIterableFactory =
         js.js("#iterableFactory(#innerFunction, #type)", {
       "iterableFactory": iterableFactory,
-      "type": iterableFactoryTypeArgument,
+      "type": iterableFactoryTypeArguments,
       "innerFunction": innerFunction,
     }).withSourceInformation(bodySourceInformation);
     js.Statement returnCallIterableFactory = new js.Return(callIterableFactory)
         .withSourceInformation(bodySourceInformation);
     return js.js("""
-          function (#renamedParameters) {
+          function (#renamedParameters, #typeParameters) {
             if (#needsThis)
               var #self = this;
             #returnCallIterableFactory;
           }
           """, {
       "renamedParameters": renamedParameters,
+      "typeParameters": typeParameters,
       "needsThis": analysis.hasThis,
       "self": selfName,
       "returnCallIterableFactory": returnCallIterableFactory,
@@ -2075,7 +2097,10 @@
   }
 
   @override
-  void initializeNames() {}
+  void initializeNames() {
+    iterableFactoryTypeArguments =
+        processTypeArguments(iterableFactoryTypeArguments);
+  }
 }
 
 class AsyncStarRewriter extends AsyncRewriterBase {
@@ -2115,7 +2140,7 @@
   ///
   /// Specific to async* methods.
   final js.Expression newController;
-  final js.Expression newControllerTypeArgument;
+  List<js.Expression> newControllerTypeArguments;
 
   /// Used to get the `Stream` out of the [controllerName] variable.
   final js.Expression streamOfController;
@@ -2136,7 +2161,7 @@
       {this.asyncStarHelper,
       this.streamOfController,
       this.newController,
-      this.newControllerTypeArgument,
+      this.newControllerTypeArguments,
       this.yieldExpression,
       this.yieldStarExpression,
       this.wrapBody,
@@ -2184,6 +2209,7 @@
   @override
   js.Fun finishFunction(
       List<js.Parameter> parameters,
+      List<js.Parameter> typeParameters,
       js.Statement rewrittenBody,
       js.VariableDeclarationList variableDeclarations,
       SourceInformation functionSourceInformation,
@@ -2277,12 +2303,13 @@
         new js.Return(streamOfControllerCall)
             .withSourceInformation(bodySourceInformation);
     return js.js("""
-        function (#parameters) {
+        function (#parameters, #typeParameters) {
           #declareBodyName;
           #variableDeclarations;
           #returnStreamOfControllerCall;
         }""", {
       "parameters": parameters,
+      "typeParameters": typeParameters,
       "declareBodyName": declareBodyName,
       "variableDeclarations": variableDeclarations,
       "returnStreamOfControllerCall": returnStreamOfControllerCall,
@@ -2329,7 +2356,7 @@
         js.js('#(#, #)', [
           newController,
           bodyName,
-          newControllerTypeArgument
+          newControllerTypeArguments
         ]).withSourceInformation(sourceInformation),
         sourceInformation));
     if (analysis.hasYield) {
@@ -2343,6 +2370,8 @@
   void initializeNames() {
     controllerName = freshName("controller");
     nextWhenCanceledName = freshName("nextWhenCanceled");
+    newControllerTypeArguments =
+        processTypeArguments(newControllerTypeArguments);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index c83d813..28f2622 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -324,10 +324,6 @@
 
   FrontendStrategy get frontendStrategy => compiler.frontendStrategy;
 
-  /// Returns true if the backend supports reflection and this isn't Dart 2.
-  bool get supportsReflection =>
-      emitter.supportsReflection && !compiler.options.useKernel;
-
   FunctionCompiler functionCompiler;
 
   CodeEmitterTask emitter;
@@ -1169,7 +1165,8 @@
     if (element.asyncMarker == AsyncMarker.SYNC) return code;
 
     AsyncRewriterBase rewriter = null;
-    jsAst.Name name = namer.methodPropertyName(element);
+    jsAst.Name name = namer.methodPropertyName(
+        element is JGeneratorBody ? element.function : element);
 
     switch (element.asyncMarker) {
       case AsyncMarker.ASYNC:
@@ -1182,7 +1179,7 @@
                 emitter.staticFunctionAccess(commonElements.endOfIteration),
             iterableFactory: emitter
                 .staticFunctionAccess(commonElements.syncStarIterableFactory),
-            iterableFactoryTypeArgument:
+            iterableFactoryTypeArguments:
                 _fetchItemType(element, elementEnvironment),
             yieldStarExpression:
                 emitter.staticFunctionAccess(commonElements.yieldStar),
@@ -1205,7 +1202,7 @@
             wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
             newController: emitter.staticFunctionAccess(
                 commonElements.asyncStarStreamControllerFactory),
-            newControllerTypeArgument:
+            newControllerTypeArguments:
                 _fetchItemType(element, elementEnvironment),
             safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
             yieldExpression:
@@ -1223,19 +1220,22 @@
     return rewriter.rewrite(code, bodySourceInformation, exitSourceInformation);
   }
 
-  /// Returns an expression that evaluates the type argument to the
+  /// Returns an optional expression that evaluates the type argument to the
   /// Future/Stream/Iterable.
-  jsAst.Expression _fetchItemType(
+  /// Returns an empty list if the type is not needed.
+  /// Returns `null` if the type expression is determined by
+  /// the outside context and should be added as a function parameter.
+  List<jsAst.Expression> _fetchItemType(
       FunctionEntity element, ElementEnvironment elementEnvironment) {
-    DartType type =
-        elementEnvironment.getFunctionAsyncOrSyncStarElementType(element);
+    //DartType type =
+    //  elementEnvironment.getFunctionAsyncOrSyncStarElementType(element);
 
-    if (!type.containsFreeTypeVariables) {
-      return rtiEncoder.getTypeRepresentation(emitter.emitter, type, null);
-    }
+    //if (!type.containsFreeTypeVariables) {
+    //  var ast = rtiEncoder.getTypeRepresentation(emitter.emitter, type, null);
+    //  return <jsAst.Expression>[ast];
+    //}
 
-    // TODO(sra): Handle types that have type variables.
-    return js('null');
+    return null;
   }
 
   AsyncRewriter _makeAsyncRewriter(
@@ -1254,7 +1254,7 @@
         ? commonElements.asyncAwaitCompleterFactory
         : commonElements.syncCompleterFactory;
 
-    jsAst.Expression itemTypeExpression =
+    List<jsAst.Expression> itemTypeExpression =
         _fetchItemType(element, elementEnvironment);
 
     var rewriter = new AsyncRewriter(reporter, element,
@@ -1267,7 +1267,7 @@
             emitter.staticFunctionAccess(commonElements.asyncHelperRethrow),
         wrapBody: emitter.staticFunctionAccess(commonElements.wrapBody),
         completerFactory: emitter.staticFunctionAccess(completerFactory),
-        completerFactoryTypeArgument: itemTypeExpression,
+        completerFactoryTypeArguments: itemTypeExpression,
         safeVariableName: namer.safeVariablePrefixForAsyncRewrite,
         bodyName: namer.deriveAsyncBodyName(name));
 
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index cf43c6c..71bec0c 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -141,54 +141,30 @@
         } else {
           staticUses.add(_commonElements.asyncHelperStart);
         }
-        if (!_options.useKernel) {
-          if (_options.startAsyncSynchronously) {
-            staticUses.add(_commonElements.asyncAwaitCompleterFactory);
-          } else {
-            staticUses.add(_commonElements.syncCompleterFactory);
-          }
-        }
         return new BackendImpact(staticUses: staticUses);
       }();
 
   BackendImpact _syncStarBody;
 
   BackendImpact get syncStarBody {
-    return _syncStarBody ??= _options.useKernel
-        ? new BackendImpact(staticUses: [
-            _commonElements.endOfIteration,
-            _commonElements.yieldStar,
-            _commonElements.syncStarUncaughtError,
-          ])
-        : new BackendImpact(staticUses: [
-            _commonElements.endOfIteration,
-            _commonElements.yieldStar,
-            _commonElements.syncStarUncaughtError,
-            _commonElements.syncStarIterableFactory,
-          ]);
+    return _syncStarBody ??= new BackendImpact(staticUses: [
+      _commonElements.endOfIteration,
+      _commonElements.yieldStar,
+      _commonElements.syncStarUncaughtError,
+    ]);
   }
 
   BackendImpact _asyncStarBody;
 
   BackendImpact get asyncStarBody {
-    return _asyncStarBody ??= _options.useKernel
-        ? new BackendImpact(staticUses: [
-            _commonElements.asyncStarHelper,
-            _commonElements.streamOfController,
-            _commonElements.yieldSingle,
-            _commonElements.yieldStar,
-            _commonElements.streamIteratorConstructor,
-            _commonElements.wrapBody,
-          ])
-        : new BackendImpact(staticUses: [
-            _commonElements.asyncStarHelper,
-            _commonElements.streamOfController,
-            _commonElements.yieldSingle,
-            _commonElements.yieldStar,
-            _commonElements.streamIteratorConstructor,
-            _commonElements.wrapBody,
-            _commonElements.asyncStarStreamControllerFactory,
-          ]);
+    return _asyncStarBody ??= new BackendImpact(staticUses: [
+      _commonElements.asyncStarHelper,
+      _commonElements.streamOfController,
+      _commonElements.yieldSingle,
+      _commonElements.yieldStar,
+      _commonElements.streamIteratorConstructor,
+      _commonElements.wrapBody,
+    ]);
   }
 
   BackendImpact _typeVariableBoundCheck;
@@ -749,24 +725,6 @@
         dynamicUses: [Selectors.noSuchMethod_]);
   }
 
-  BackendImpact _isolateSupport;
-
-  /// Backend impact for isolate support.
-  BackendImpact get isolateSupport {
-    return _isolateSupport ??=
-        new BackendImpact(globalUses: [_commonElements.startRootIsolate]);
-  }
-
-  BackendImpact _isolateSupportForResolution;
-
-  /// Additional backend impact for isolate support in resolution.
-  BackendImpact get isolateSupportForResolution {
-    return _isolateSupportForResolution ??= new BackendImpact(globalUses: [
-      _commonElements.currentIsolate,
-      _commonElements.callInIsolate
-    ]);
-  }
-
   BackendImpact _loadLibrary;
 
   /// Backend impact for accessing a `loadLibrary` function on a deferred
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index ac81356..ed8dced 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -36,9 +36,6 @@
   /// `true` of `Object.runtimeType` is used.
   bool get isRuntimeTypeUsed;
 
-  /// `true` if the `dart:isolate` library is in use.
-  bool get isIsolateInUse;
-
   /// `true` if `Function.apply` is used.
   bool get isFunctionApplyUsed;
 
@@ -81,9 +78,6 @@
   /// `true` of `Object.runtimeType` is used.
   bool isRuntimeTypeUsed;
 
-  /// `true` if the `dart:isolate` library is in use.
-  bool isIsolateInUse;
-
   /// `true` if `Function.apply` is used.
   bool isFunctionApplyUsed;
 
@@ -120,9 +114,6 @@
   /// `true` of `Object.runtimeType` is used.
   bool isRuntimeTypeUsed = false;
 
-  /// `true` if the `dart:isolate` library is in use.
-  bool isIsolateInUse = false;
-
   /// `true` if `Function.apply` is used.
   bool isFunctionApplyUsed = false;
 
@@ -289,7 +280,6 @@
         requiresPreamble: requiresPreamble,
         isInvokeOnUsed: isInvokeOnUsed,
         isRuntimeTypeUsed: isRuntimeTypeUsed,
-        isIsolateInUse: isIsolateInUse,
         isFunctionApplyUsed: isFunctionApplyUsed,
         isMirrorsUsed: isMirrorsUsed,
         isNoSuchMethodUsed: isNoSuchMethodUsed,
@@ -320,9 +310,6 @@
   /// `true` of `Object.runtimeType` is used.
   final bool isRuntimeTypeUsed;
 
-  /// `true` if the `dart:isolate` library is in use.
-  final bool isIsolateInUse;
-
   /// `true` if `Function.apply` is used.
   final bool isFunctionApplyUsed;
 
@@ -345,7 +332,6 @@
       this.requiresPreamble,
       this.isInvokeOnUsed,
       this.isRuntimeTypeUsed,
-      this.isIsolateInUse,
       this.isFunctionApplyUsed,
       this.isMirrorsUsed,
       this.isNoSuchMethodUsed,
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index b5d3feb..39c2fb4 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -78,26 +78,6 @@
     }
   }
 
-  /// Called to enable support for isolates. Any backend specific [WorldImpact]
-  /// of this is returned.
-  WorldImpact _enableIsolateSupport(FunctionEntity mainMethod) {
-    WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
-    // TODO(floitsch): We should also ensure that the class IsolateMessage is
-    // instantiated. Currently, just enabling isolate support works.
-    if (mainMethod != null) {
-      // The JavaScript backend implements [Isolate.spawn] by looking up
-      // top-level functions by name. So all top-level function tear-off
-      // closures have a private name field.
-      //
-      // The JavaScript backend of [Isolate.spawnUri] uses the same internal
-      // implementation as [Isolate.spawn], and fails if it cannot look main up
-      // by name.
-      impactBuilder.registerStaticUse(new StaticUse.staticTearOff(mainMethod));
-    }
-    _impacts.isolateSupport.registerImpact(impactBuilder, _elementEnvironment);
-    return impactBuilder;
-  }
-
   /// Computes the [WorldImpact] of calling [mainMethod] as the entry point.
   WorldImpact _computeMainImpact(FunctionEntity mainMethod) {
     WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl();
@@ -107,11 +87,6 @@
           .registerImpact(mainImpact, _elementEnvironment);
       mainImpact.registerStaticUse(
           new StaticUse.staticInvoke(mainMethod, callStructure));
-      // If the main method takes arguments, this compilation could be the
-      // target of Isolate.spawnUri. Strictly speaking, that can happen also if
-      // main takes no arguments, but in this case the spawned isolate can't
-      // communicate with the spawning isolate.
-      mainImpact.addImpact(_enableIsolateSupport(mainMethod));
     }
     mainImpact.registerStaticUse(
         new StaticUse.staticInvoke(mainMethod, CallStructure.NO_ARGS));
@@ -125,9 +100,6 @@
     if (mainMethod != null) {
       enqueuer.applyImpact(_computeMainImpact(mainMethod));
     }
-    if (_backendUsage.isIsolateInUse) {
-      enqueuer.applyImpact(_enableIsolateSupport(mainMethod));
-    }
   }
 
   @override
diff --git a/pkg/compiler/lib/src/js_backend/mirrors_data.dart b/pkg/compiler/lib/src/js_backend/mirrors_data.dart
index c128794..fe94bca 100644
--- a/pkg/compiler/lib/src/js_backend/mirrors_data.dart
+++ b/pkg/compiler/lib/src/js_backend/mirrors_data.dart
@@ -542,11 +542,11 @@
   void computeMembersNeededForReflection(
       ResolutionWorldBuilder worldBuilder, ClosedWorld closedWorld) {
     if (_membersNeededForReflection != null) return;
-    if (!closedWorld.backendUsage.isMirrorsUsed ||
-        _compiler.options.useKernel) {
+    if (!closedWorld.backendUsage.isMirrorsUsed || true) {
       createImmutableSets();
       return;
     }
+    // TODO(johnniwinther): Remove this:
     _classesNeededForReflection = new Set<ClassEntity>();
     _typedefsNeededForReflection = new Set<TypedefEntity>();
     _membersNeededForReflection = new Set<MemberEntity>();
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 00393c0..f671f25 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -24,6 +24,7 @@
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
 import '../js_model/closure.dart';
+import '../js_model/elements.dart' show JGeneratorBody;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/selector.dart' show Selector, SelectorKind;
 import '../universe/world_builder.dart' show CodegenWorldBuilder;
@@ -782,13 +783,29 @@
         ctor, () => _proposeNameForConstructorBody(ctor));
   }
 
+  /// Name for a generator body.
+  jsAst.Name generatorBodyInstanceMethodName(JGeneratorBody method) {
+    assert(method.isInstanceMember);
+    // TODO(sra): Except for methods declared in mixins, we can use a compact
+    // naming scheme like we do for [ConstructorBodyEntity].
+    FunctionEntity function = method.function;
+    return _disambiguateInternalMember(method, () {
+      String invocationName = operatorNameToIdentifier(function.name);
+      return '${invocationName}\$body\$${method.enclosingClass.name}';
+    });
+  }
+
   /// Annotated name for [method] encoding arity and named parameters.
   jsAst.Name instanceMethodName(FunctionEntity method) {
-    // TODO(johnniwinther): Avoid the use of [ConstructorBodyEntity]. The
-    // codegen model should be explicit about its constructor body elements.
+    // TODO(johnniwinther): Avoid the use of [ConstructorBodyEntity] and
+    // [JGeneratorBody]. The codegen model should be explicit about its
+    // constructor body elements.
     if (method is ConstructorBodyEntity) {
       return constructorBodyName(method);
     }
+    if (method is JGeneratorBody) {
+      return generatorBodyInstanceMethodName(method);
+    }
     return invocationName(new Selector.fromElement(method));
   }
 
@@ -1337,6 +1354,8 @@
   String _proposeNameForMember(MemberEntity element) {
     if (element.isConstructor) {
       return _proposeNameForConstructor(element);
+    } else if (element is JGeneratorBody) {
+      return _proposeNameForMember(element.function) + r'$body';
     } else if (element.enclosingClass != null) {
       ClassEntity enclosingClass = element.enclosingClass;
       return '${enclosingClass.name}_${element.name}';
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index 289ae42..d0ecf6e 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -4,7 +4,7 @@
 
 library js_backend.backend.resolution_listener;
 
-import '../common/names.dart' show Identifiers, Uris;
+import '../common/names.dart' show Identifiers;
 import '../common_elements.dart' show CommonElements, ElementEnvironment;
 import '../constants/values.dart';
 import '../deferred_load.dart';
@@ -117,30 +117,6 @@
     }
   }
 
-  /// Called to enable support for isolates. Any backend specific [WorldImpact]
-  /// of this is returned.
-  WorldImpact _enableIsolateSupport(FunctionEntity mainMethod) {
-    WorldImpactBuilderImpl impactBuilder = new WorldImpactBuilderImpl();
-    // TODO(floitsch): We should also ensure that the class IsolateMessage is
-    // instantiated. Currently, just enabling isolate support works.
-    if (mainMethod != null) {
-      // The JavaScript backend implements [Isolate.spawn] by looking up
-      // top-level functions by name. So all top-level function tear-off
-      // closures have a private name field.
-      //
-      // The JavaScript backend of [Isolate.spawnUri] uses the same internal
-      // implementation as [Isolate.spawn], and fails if it cannot look main up
-      // by name.
-      impactBuilder.registerStaticUse(new StaticUse.staticTearOff(mainMethod));
-    }
-    _impacts.isolateSupport.registerImpact(impactBuilder, _elementEnvironment);
-    _backendUsage.processBackendImpact(_impacts.isolateSupport);
-    _impacts.isolateSupportForResolution
-        .registerImpact(impactBuilder, _elementEnvironment);
-    _backendUsage.processBackendImpact(_impacts.isolateSupportForResolution);
-    return impactBuilder;
-  }
-
   /// Computes the [WorldImpact] of calling [mainMethod] as the entry point.
   WorldImpact _computeMainImpact(FunctionEntity mainMethod) {
     WorldImpactBuilderImpl mainImpact = new WorldImpactBuilderImpl();
@@ -151,11 +127,6 @@
       _backendUsage.processBackendImpact(_impacts.mainWithArguments);
       mainImpact.registerStaticUse(
           new StaticUse.staticInvoke(mainMethod, callStructure));
-      // If the main method takes arguments, this compilation could be the
-      // target of Isolate.spawnUri. Strictly speaking, that can happen also if
-      // main takes no arguments, but in this case the spawned isolate can't
-      // communicate with the spawning isolate.
-      mainImpact.addImpact(_enableIsolateSupport(mainMethod));
     }
     mainImpact.registerStaticUse(
         new StaticUse.staticInvoke(mainMethod, CallStructure.NO_ARGS));
@@ -311,29 +282,6 @@
       }
     }
 
-    // Enable isolate support if we start using something from the isolate
-    // library, or timers for the async library.  We exclude constant fields,
-    // which are ending here because their initializing expression is
-    // compiled.
-    LibraryEntity library = member.library;
-    if (!_backendUsage.isIsolateInUse && !(member.isField && member.isConst)) {
-      Uri uri = library.canonicalUri;
-      if (uri == Uris.dart_isolate) {
-        _backendUsage.isIsolateInUse = true;
-        worldImpact
-            .addImpact(_enableIsolateSupport(_elementEnvironment.mainFunction));
-      } else if (uri == Uris.dart_async) {
-        if (member.name == '_createTimer' ||
-            member.name == '_createPeriodicTimer') {
-          // The [:Timer:] class uses the event queue of the isolate
-          // library, so we make sure that event queue is generated.
-          _backendUsage.isIsolateInUse = true;
-          worldImpact.addImpact(
-              _enableIsolateSupport(_elementEnvironment.mainFunction));
-        }
-      }
-    }
-
     if (member.isGetter && member.name == Identifiers.runtimeType_) {
       // Enable runtime type support if we discover a getter called
       // runtimeType. We have to enable runtime type before hitting the
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 6002105..e333f45 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -278,11 +278,6 @@
   jsAst.Name get makeConstListProperty =>
       namer.internalGlobal('makeConstantList');
 
-  /// The name of the property that contains all field names.
-  ///
-  /// This property is added to constructors when isolate support is enabled.
-  static const String FIELD_NAMES_PROPERTY_NAME = r"$__fields__";
-
   /// For deferred loading we communicate the initializers via this global var.
   final String deferredInitializers = r"$dart_deferred_initializers$";
 
@@ -374,13 +369,6 @@
             generateEmbeddedGlobalAccessString(embeddedNames.TYPES);
         return jsAst.js.expressionTemplateFor("$typesAccess[#]");
 
-      case JsBuiltin.createDartClosureFromNameOfStaticFunction:
-        // The global-functions map contains a map from name to tear-off
-        // getters.
-        String functionGettersMap =
-            generateEmbeddedGlobalAccessString(embeddedNames.GLOBAL_FUNCTIONS);
-        return jsAst.js.expressionTemplateFor("$functionGettersMap[#]()");
-
       default:
         reporter.internalError(
             NO_LOCATION_SPANNABLE, "Unhandled Builtin: $builtin");
@@ -1115,18 +1103,7 @@
     cspPrecompiledFunctionFor(outputUnit)
         .add(new jsAst.FunctionDeclaration(constructorName, constructorAst));
 
-    String fieldNamesProperty = FIELD_NAMES_PROPERTY_NAME;
-    bool hasIsolateSupport = _closedWorld.backendUsage.isIsolateInUse;
-    jsAst.Node fieldNamesArray;
-    if (hasIsolateSupport) {
-      fieldNamesArray =
-          new jsAst.ArrayInitializer(fields.map(js.quoteName).toList());
-    } else {
-      fieldNamesArray = new jsAst.LiteralNull();
-    }
-
-    cspPrecompiledFunctionFor(outputUnit).add(js.statement(
-        r'''
+    cspPrecompiledFunctionFor(outputUnit).add(js.statement(r'''
         {
           #constructorName.#typeNameProperty = #constructorNameString;
           // IE does not have a name property.
@@ -1134,18 +1111,11 @@
               #constructorName.name = #constructorNameString;
           $desc = $collectedClasses$.#constructorName[1];
           #constructorName.prototype = $desc;
-          ''' /* next string is not a raw string */ '''
-          if (#hasIsolateSupport) {
-            #constructorName.$fieldNamesProperty = #fieldNamesArray;
-          }
-        }''',
-        {
-          "constructorName": constructorName,
-          "typeNameProperty": typeNameProperty,
-          "constructorNameString": js.quoteName(constructorName),
-          "hasIsolateSupport": hasIsolateSupport,
-          "fieldNamesArray": fieldNamesArray
-        }));
+        }''', {
+      "constructorName": constructorName,
+      "typeNameProperty": typeNameProperty,
+      "constructorNameString": js.quoteName(constructorName),
+    }));
 
     cspPrecompiledConstructorNamesFor(outputUnit).add(js('#', constructorName));
   }
@@ -1961,12 +1931,11 @@
 
   jsAst.Comment buildGeneratedBy() {
     StringBuffer flavor = new StringBuffer();
-    flavor.write(compiler.options.useKernel ? 'kernel FE' : 'ast FE');
+    flavor.write('full emitter');
     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');
     return new jsAst.Comment(generatedBy(compiler, flavor: '$flavor'));
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 e734b9d..b8df5d2 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
@@ -35,8 +35,6 @@
     ClosedWorld closedWorld) {
   jsAst.Expression typeInformationAccess =
       emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPE_INFORMATION);
-  jsAst.Expression globalFunctionsAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.GLOBAL_FUNCTIONS);
   jsAst.Expression staticsAccess =
       emitter.generateEmbeddedGlobalAccess(embeddedNames.STATICS);
   jsAst.Expression interceptedNamesAccess =
@@ -49,10 +47,6 @@
       emitter.generateEmbeddedGlobalAccess(embeddedNames.LIBRARIES);
   jsAst.Expression typesAccess =
       emitter.generateEmbeddedGlobalAccess(embeddedNames.TYPES);
-  jsAst.Expression createNewIsolateFunctionAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.CREATE_NEW_ISOLATE);
-  jsAst.Expression classIdExtractorAccess =
-      emitter.generateEmbeddedGlobalAccess(embeddedNames.CLASS_ID_EXTRACTOR);
   jsAst.Expression allClassesAccess =
       emitter.generateEmbeddedGlobalAccess(embeddedNames.ALL_CLASSES);
   jsAst.Expression precompiledAccess =
@@ -63,12 +57,6 @@
       emitter.generateEmbeddedGlobalAccess(embeddedNames.INTERCEPTORS_BY_TAG);
   jsAst.Expression leafTagsAccess =
       emitter.generateEmbeddedGlobalAccess(embeddedNames.LEAF_TAGS);
-  jsAst.Expression initializeEmptyInstanceAccess = emitter
-      .generateEmbeddedGlobalAccess(embeddedNames.INITIALIZE_EMPTY_INSTANCE);
-  jsAst.Expression classFieldsExtractorAccess = emitter
-      .generateEmbeddedGlobalAccess(embeddedNames.CLASS_FIELDS_EXTRACTOR);
-  jsAst.Expression instanceFromClassIdAccess = emitter
-      .generateEmbeddedGlobalAccess(embeddedNames.INSTANCE_FROM_CLASS_ID);
 
   String reflectableField = namer.reflectableField;
   String reflectionInfoField = namer.reflectionInfoField;
@@ -108,21 +96,12 @@
     'staticsPropertyName': namer.staticsPropertyName,
     'staticsPropertyNameString': js.quoteName(namer.staticsPropertyName),
     'typeInformation': typeInformationAccess,
-    'globalFunctions': globalFunctionsAccess,
     'enabledInvokeOn': closedWorld.backendUsage.isInvokeOnUsed,
     'interceptedNames': interceptedNamesAccess,
     'interceptedNamesSet': emitter.generateInterceptedNamesSet(),
     'notInCspMode': !compiler.options.useContentSecurityPolicy,
     'inCspMode': compiler.options.useContentSecurityPolicy,
     'deferredAction': namer.deferredAction,
-    'hasIsolateSupport': program.hasIsolateSupport,
-    'fieldNamesProperty': js.string(Emitter.FIELD_NAMES_PROPERTY_NAME),
-    'createNewIsolateFunction': createNewIsolateFunctionAccess,
-    'isolateName': namer.isolateName,
-    'classIdExtractor': classIdExtractorAccess,
-    'classFieldsExtractor': classFieldsExtractorAccess,
-    'instanceFromClassId': instanceFromClassIdAccess,
-    'initializeEmptyInstance': initializeEmptyInstanceAccess,
     'allClasses': allClassesAccess,
     'debugFastObjects': DEBUG_FAST_OBJECTS,
     'isTreeShakingDisabled': backend.mirrorsData.isTreeShakingDisabled,
@@ -232,13 +211,11 @@
 
       var str = "function " + name + "(";
       var body = "";
-      if (#hasIsolateSupport) { var fieldNames = ""; }
 
       for (var i = 0; i < fields.length; i++) {
         if(i != 0) str += ", ";
 
         var field = generateAccessor(fields[i], accessors, name);
-        if (#hasIsolateSupport) { fieldNames += "'" + field + "',"; }
         var parameter = "p_" + field;
         str += parameter;
         body += ("this." + field + " = " + parameter + ";\\n");
@@ -253,39 +230,11 @@
       if (typeof defineClass.name != "string") {
         str += name + ".name=\\"" + name + "\\";\\n";
       }
-      if (#hasIsolateSupport) {
-        str += name + "." + #fieldNamesProperty + "=[" + fieldNames
-               + "];\\n";
-      }
       str += accessors.join("");
 
       return str;
     }
 
-    if (#hasIsolateSupport) {
-      #createNewIsolateFunction = function() { return new #isolateName(); };
-
-      #classIdExtractor = function(o) { return o.constructor.name; };
-
-      #classFieldsExtractor = function(o) {
-        var fieldNames = o.constructor.#fieldNamesProperty;
-        if (!fieldNames) return [];  // TODO(floitsch): do something else here.
-        var result = [];
-        result.length = fieldNames.length;
-        for (var i = 0; i < fieldNames.length; i++) {
-          result[i] = o[fieldNames[i]];
-        }
-        return result;
-      };
-
-      #instanceFromClassId = function(name) { return new #allClasses[name](); };
-
-      #initializeEmptyInstance = function(name, o, fields) {
-        #allClasses[name].apply(o, fields);
-        return o;
-      }
-    }
-
     // If the browser supports changing the prototype via __proto__, we make
     // use of that feature. Otherwise, we copy the properties into a new
     // constructor.
@@ -629,7 +578,6 @@
       } else if (typeof element === "function") {
         globalObject[previousProperty = property] = element;
         functions.push(property);
-        #globalFunctions[property] = element;
       } else if (element.constructor === Array) {
         if (#needsStructuredMemberInfo) {
           addStubs(globalObject, element, property, true, functions);
@@ -732,9 +680,7 @@
         f = tearOff(funcs, array, isStatic, name, isIntercepted);
         prototype[name].\$getter = f;
         f.\$getterStub = true;
-        // Used to create an isolate using spawnFunction.
         if (isStatic) {
-          #globalFunctions[name] = f;
           functions.push(getterStubName);
         }
         prototype[getterStubName] = f;
@@ -795,7 +741,6 @@
   if (!#mangledGlobalNames) #mangledGlobalNames = map();
   if (!#statics) #statics = map();
   if (!#typeInformation) #typeInformation = map();
-  if (!#globalFunctions) #globalFunctions = map();
   if (#enabledInvokeOn)
     if (!#interceptedNames) #interceptedNames = #interceptedNamesSet;
   var libraries = #libraries;
diff --git a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
index e32b7cc..e20f889 100644
--- a/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/main_call_stub_generator.dart
@@ -6,44 +6,18 @@
 
 import 'package:js_runtime/shared/embedded_names.dart' as embeddedNames;
 
-import '../common_elements.dart';
 import '../elements/entities.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
-import '../js_backend/backend_usage.dart' show BackendUsage;
 
 import 'code_emitter_task.dart' show Emitter;
 
 class MainCallStubGenerator {
-  final CommonElements _commonElements;
-  final Emitter _emitter;
-  final BackendUsage _backendUsage;
-
-  MainCallStubGenerator(
-      this._commonElements, this._emitter, this._backendUsage);
-
-  /// Returns the code equivalent to:
-  ///   `function(args) { $.startRootIsolate(X.main$closure(), args); }`
-  jsAst.Expression _buildIsolateSetupClosure(
-      FunctionEntity appMain, FunctionEntity isolateMain) {
-    jsAst.Expression mainAccess = _emitter.isolateStaticClosureAccess(appMain);
-    // Since we pass the closurized version of the main method to
-    // the isolate method, we must make sure that it exists.
-    return js('function(a){ #(#, a); }',
-        [_emitter.staticFunctionAccess(isolateMain), mainAccess]);
-  }
-
-  jsAst.Statement generateInvokeMain(FunctionEntity main) {
-    jsAst.Expression mainCallClosure = null;
-    if (_backendUsage.isIsolateInUse) {
-      FunctionEntity isolateMain = _commonElements.startRootIsolate;
-      mainCallClosure = _buildIsolateSetupClosure(main, isolateMain);
-    } else {
-      mainCallClosure = _emitter.staticFunctionAccess(main);
-    }
-
+  static jsAst.Statement generateInvokeMain(
+      Emitter emitter, FunctionEntity main) {
+    jsAst.Expression mainCallClosure = emitter.staticFunctionAccess(main);
     jsAst.Expression currentScriptAccess =
-        _emitter.generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
+        emitter.generateEmbeddedGlobalAccess(embeddedNames.CURRENT_SCRIPT);
 
     // This code finds the currently executing script by listening to the
     // onload event of all script tags and getting the first script which
diff --git a/pkg/compiler/lib/src/js_emitter/model.dart b/pkg/compiler/lib/src/js_emitter/model.dart
index 3634ee2..a66b830 100644
--- a/pkg/compiler/lib/src/js_emitter/model.dart
+++ b/pkg/compiler/lib/src/js_emitter/model.dart
@@ -16,7 +16,6 @@
   final List<Holder> holders;
   final bool outputContainsConstantList;
   final bool needsNativeSupport;
-  final bool hasIsolateSupport;
   final bool hasSoftDeferredClasses;
 
   /// A map from load id to the list of fragments that need to be loaded.
@@ -40,11 +39,9 @@
       this.typeToInterceptorMap, this._metadataCollector, this.finalizers,
       {this.needsNativeSupport,
       this.outputContainsConstantList,
-      this.hasIsolateSupport,
       this.hasSoftDeferredClasses}) {
     assert(needsNativeSupport != null);
     assert(outputContainsConstantList != null);
-    assert(hasIsolateSupport != null);
   }
 
   /// Accessor for the list of metadata entries for a given [OutputUnit].
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 87667ed..3a78a8f 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
@@ -277,7 +277,6 @@
         _buildTypeToInterceptorMap(), _task.metadataCollector, finalizers,
         needsNativeSupport: needsNativeSupport,
         outputContainsConstantList: collector.outputContainsConstantList,
-        hasIsolateSupport: _backendUsage.isIsolateInUse,
         hasSoftDeferredClasses: _notSoftDeferred != null);
   }
 
@@ -391,10 +390,8 @@
 
   js.Statement _buildInvokeMain() {
     if (_isMockCompilation) return js.js.comment("Mock compilation");
-
-    MainCallStubGenerator generator = new MainCallStubGenerator(
-        _commonElements, _task.emitter, _backendUsage);
-    return generator.generateInvokeMain(_mainFunction);
+    return MainCallStubGenerator.generateInvokeMain(
+        _task.emitter, _mainFunction);
   }
 
   DeferredFragment _buildDeferredFragment(LibrariesMap librariesMap) {
@@ -687,7 +684,6 @@
         _rtiChecks,
         _rtiEncoder,
         _jsInteropAnalysis,
-        _options.useKernel,
         _options.strongMode);
 
     void visitMember(MemberEntity member) {
@@ -744,6 +740,7 @@
     if (!onlyForRti && !_elementEnvironment.isMixinApplication(cls)) {
       List<MemberEntity> members = <MemberEntity>[];
       _elementEnvironment.forEachLocalClassMember(cls, members.add);
+      _elementEnvironment.forEachInjectedClassMember(cls, members.add);
       _elementEnvironment.forEachConstructorBody(cls, members.add);
       _sorter.sortMembers(members).forEach(visitMember);
     }
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index a277091..b483325 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -106,7 +106,6 @@
   final RuntimeTypesChecks _rtiChecks;
   final RuntimeTypesEncoder _rtiEncoder;
   final JsInteropAnalysis _jsInteropAnalysis;
-  final bool _useKernel;
   final bool _strongMode;
 
   RuntimeTypeGenerator(
@@ -118,7 +117,6 @@
       this._rtiChecks,
       this._rtiEncoder,
       this._jsInteropAnalysis,
-      this._useKernel,
       this._strongMode);
 
   /**
@@ -169,7 +167,7 @@
         if (classFunctionType.signatureFunction != null) {
           // Use precomputed signature function if live.
         } else {
-          assert(!_useKernel || !_strongMode);
+          assert(!_strongMode);
           // Generate the signature on the fly. This is only supported for
           // Dart 1.
 
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 4d150cc..29fb797 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -5,7 +5,7 @@
 library dart2js.js_emitter.startup_emitter;
 
 import 'package:js_runtime/shared/embedded_names.dart'
-    show JsBuiltin, METADATA, STATIC_FUNCTION_NAME_TO_CLOSURE, TYPES;
+    show JsBuiltin, METADATA, TYPES;
 
 import '../../common.dart';
 import '../../compiler.dart' show Compiler;
@@ -162,11 +162,6 @@
         String typesAccess = _emitter.generateEmbeddedGlobalAccessString(TYPES);
         return js.js.expressionTemplateFor("$typesAccess[#]");
 
-      case JsBuiltin.createDartClosureFromNameOfStaticFunction:
-        String functionAccess = _emitter.generateEmbeddedGlobalAccessString(
-            STATIC_FUNCTION_NAME_TO_CLOSURE);
-        return js.js.expressionTemplateFor("$functionAccess(#)");
-
       default:
         reporter.internalError(
             NO_LOCATION_SPANNABLE, "Unhandled Builtin: $builtin");
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 b47e96d..9bb77ff 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
@@ -1399,75 +1399,6 @@
           js.string(TYPE_TO_INTERCEPTOR_MAP), program.typeToInterceptorMap));
     }
 
-    if (program.hasIsolateSupport) {
-      String staticStateName = namer.staticStateHolder;
-      // TODO(floitsch): this doesn't create a new isolate, but just reuses
-      // the current static state. Since we don't run multiple isolates in the
-      // same JavaScript context (except for testing) this shouldn't have any
-      // impact on real-world programs, though.
-      globals.add(new js.Property(js.string(CREATE_NEW_ISOLATE),
-          js.js('function () { return $staticStateName; }')));
-
-      js.Expression nameToClosureFunction = js.js('''
-        // First fetch the static function. From there we can execute its
-        // getter function which builds a Dart closure.
-        function(name) {
-           var staticFunction = getGlobalFromName(name);
-           var getterFunction = staticFunction.$tearOffPropertyName;
-           return getterFunction();
-         }''');
-      globals.add(new js.Property(
-          js.string(STATIC_FUNCTION_NAME_TO_CLOSURE), nameToClosureFunction));
-
-      globals.add(new js.Property(js.string(CLASS_ID_EXTRACTOR),
-          js.js('function(o) { return o.constructor.name; }')));
-
-      js.Expression extractFieldsFunction = js.js('''
-      function(o) {
-        var constructor = o.constructor;
-        var fieldNames = constructor.$cachedClassFieldNames;
-        if (!fieldNames) {
-          // Extract the fields from an empty unmodified object.
-          var empty = new constructor();
-          // This gives us the keys that the constructor sets.
-          fieldNames = constructor.$cachedClassFieldNames = Object.keys(empty);
-        }
-        var result = new Array(fieldNames.length);
-        for (var i = 0; i < fieldNames.length; i++) {
-          result[i] = o[fieldNames[i]];
-        }
-        return result;
-      }''');
-      globals.add(new js.Property(
-          js.string(CLASS_FIELDS_EXTRACTOR), extractFieldsFunction));
-
-      js.Expression createInstanceFromClassIdFunction = js.js('''
-        function(name) {
-          var constructor = getGlobalFromName(name);
-          return new constructor();
-        }
-      ''');
-      globals.add(new js.Property(js.string(INSTANCE_FROM_CLASS_ID),
-          createInstanceFromClassIdFunction));
-
-      js.Expression initializeEmptyInstanceFunction = js.js('''
-      function(name, o, fields) {
-        var constructor = o.constructor;
-        // By construction the object `o` is an empty object with the same
-        // keys as the one we used in the extract-fields function.
-        var fieldNames = Object.keys(o);
-        if (fieldNames.length != fields.length) {
-          throw new Error("Mismatch during deserialization.");
-        }
-        for (var i = 0; i < fields.length; i++) {
-          o[fieldNames[i]] = fields[i];
-        }
-        return o;
-      }''');
-      globals.add(new js.Property(js.string(INITIALIZE_EMPTY_INSTANCE),
-          initializeEmptyInstanceFunction));
-    }
-
     globals.add(emitMangledGlobalNames());
 
     // The [MANGLED_NAMES] table must contain the mapping for const symbols.
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 5c5933a..f2ba354 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
@@ -9,17 +9,12 @@
 
 import 'package:js_runtime/shared/embedded_names.dart'
     show
-        CLASS_FIELDS_EXTRACTOR,
-        CLASS_ID_EXTRACTOR,
-        CREATE_NEW_ISOLATE,
         DEFERRED_INITIALIZED,
         DEFERRED_LIBRARY_PARTS,
         DEFERRED_PART_URIS,
         DEFERRED_PART_HASHES,
         GET_TYPE_FROM_NAME,
-        INITIALIZE_EMPTY_INSTANCE,
         INITIALIZE_LOADED_HUNK,
-        INSTANCE_FROM_CLASS_ID,
         INTERCEPTORS_BY_TAG,
         IS_HUNK_INITIALIZED,
         IS_HUNK_LOADED,
@@ -28,7 +23,6 @@
         MANGLED_NAMES,
         METADATA,
         NATIVE_SUPERCLASS_TAG_NAME,
-        STATIC_FUNCTION_NAME_TO_CLOSURE,
         TYPE_TO_INTERCEPTOR_MAP,
         TYPES;
 
@@ -228,12 +222,11 @@
   /// Generates a simple header that provides the compiler's build id.
   js.Comment buildGeneratedBy() {
     StringBuffer flavor = new StringBuffer();
-    flavor.write(compiler.options.useKernel ? 'kernel FE' : 'ast FE');
+    flavor.write('fast startup emitter');
     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/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index fdda596..43e81b6 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -143,6 +143,10 @@
     return new JConstructorBody(constructor);
   }
 
+  JGeneratorBody createGeneratorBody(FunctionEntity function) {
+    return new JGeneratorBody(function);
+  }
+
   IndexedFunction createGetter(LibraryEntity library,
       ClassEntity enclosingClass, Name name, AsyncMarker asyncMarker,
       {bool isStatic, bool isExternal, bool isAbstract}) {
@@ -498,6 +502,19 @@
   String get _kind => 'method';
 }
 
+class JGeneratorBody extends JFunction {
+  final FunctionEntity function;
+  final int hashCode;
+
+  JGeneratorBody(this.function)
+      : hashCode = function.hashCode + 1, // Hack stabilize sort order.
+        super(function.library, function.enclosingClass, function.memberName,
+            function.parameterStructure, function.asyncMarker,
+            isStatic: function.isStatic, isExternal: false);
+
+  String get _kind => 'generator_body';
+}
+
 class JGetter extends JFunction {
   final bool isAbstract;
 
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 11fa8ee..c4c47a1 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -391,7 +391,6 @@
         requiresPreamble: backendUsage.requiresPreamble,
         isInvokeOnUsed: backendUsage.isInvokeOnUsed,
         isRuntimeTypeUsed: backendUsage.isRuntimeTypeUsed,
-        isIsolateInUse: backendUsage.isIsolateInUse,
         isFunctionApplyUsed: backendUsage.isFunctionApplyUsed,
         isMirrorsUsed: backendUsage.isMirrorsUsed,
         isNoSuchMethodUsed: backendUsage.isNoSuchMethodUsed);
diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
index 8c7e543..1c1d2f6 100644
--- a/pkg/compiler/lib/src/js_model/locals.dart
+++ b/pkg/compiler/lib/src/js_model/locals.dart
@@ -14,6 +14,8 @@
 import '../kernel/element_map.dart';
 import '../kernel/indexed.dart';
 
+import '../js_model/elements.dart' show JGeneratorBody;
+
 class GlobalLocalsMap {
   Map<MemberEntity, KernelToLocalsMap> _localsMaps =
       <MemberEntity, KernelToLocalsMap>{};
@@ -419,7 +421,9 @@
   /// True if this local represents a local parameter.
   final bool isRegularParameter;
 
-  JLocal(this.name, this.memberContext, {this.isRegularParameter: false});
+  JLocal(this.name, this.memberContext, {this.isRegularParameter: false}) {
+    assert(memberContext is! JGeneratorBody);
+  }
 
   String get _kind => 'local';
 
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index d6167ba..fe468dd 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -17,6 +17,7 @@
 import '../js_backend/native_data.dart';
 import '../js_emitter/code_emitter_task.dart';
 import '../js_model/closure.dart' show JRecordField, KernelScopeInfo;
+import '../js_model/elements.dart' show JGeneratorBody;
 import '../native/native.dart' as native;
 import '../ssa/type_builder.dart';
 import '../types/types.dart';
@@ -124,6 +125,7 @@
 /// Interface that translates between Kernel IR nodes and entities used for
 /// computing the [WorldImpact] for members.
 abstract class KernelToElementMapForImpact extends KernelToElementMap {
+  ElementEnvironment get elementEnvironment;
   NativeBasicData get nativeBasicData;
 
   /// Adds libraries in [component] to the set of libraries.
@@ -236,6 +238,9 @@
   /// Returns the constructor body entity corresponding to [constructor].
   FunctionEntity getConstructorBody(ir.Constructor node);
 
+  /// Returns the constructor body entity corresponding to [function].
+  JGeneratorBody getGeneratorBody(FunctionEntity function);
+
   /// Make a record to ensure variables that are are declared in one scope and
   /// modified in another get their values updated correctly.
   Map<Local, JRecordField> makeRecordContainer(
@@ -261,6 +266,8 @@
   // the closure class. It does not have a corresponding ir.Node or a method
   // body.
   signature,
+  // A separated body of a generator (sync*/async/async*) function.
+  generatorBody,
 }
 
 /// Definition information for a [MemberEntity].
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 1a73d22..8a70896 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -748,6 +748,13 @@
     });
   }
 
+  void _forEachInjectedClassMember(
+      IndexedClass cls, void f(MemberEntity member)) {
+    assert(checkFamily(cls));
+    throw new UnsupportedError(
+        'KernelToElementMapBase._forEachInjectedClassMember');
+  }
+
   void _forEachClassMember(
       IndexedClass cls, void f(ClassEntity cls, MemberEntity member)) {
     assert(checkFamily(cls));
@@ -1373,7 +1380,7 @@
   /// Returns the element type of a async/sync*/async* function.
   @override
   DartType getFunctionAsyncOrSyncStarElementType(ir.FunctionNode functionNode) {
-    DartType returnType = getFunctionType(functionNode).returnType;
+    DartType returnType = getDartType(functionNode.returnType);
     switch (functionNode.asyncMarker) {
       case ir.AsyncMarker.SyncStar:
         return elementEnvironment.getAsyncOrSyncStarElementType(
@@ -1471,6 +1478,7 @@
 
   @override
   DartType getFunctionAsyncOrSyncStarElementType(FunctionEntity function) {
+    // TODO(sra): Should be getting the DartType from the node.
     DartType returnType = getFunctionType(function).returnType;
     return getAsyncOrSyncStarElementType(function.asyncMarker, returnType);
   }
@@ -1581,6 +1589,12 @@
   }
 
   @override
+  void forEachInjectedClassMember(
+      ClassEntity cls, void f(MemberEntity member)) {
+    elementMap._forEachInjectedClassMember(cls, f);
+  }
+
+  @override
   void forEachClassMember(
       ClassEntity cls, void f(ClassEntity declarer, MemberEntity member)) {
     elementMap._forEachClassMember(cls, f);
@@ -2257,6 +2271,12 @@
 
   NativeBasicData nativeBasicData;
 
+  Map<FunctionEntity, JGeneratorBody> _generatorBodies =
+      <FunctionEntity, JGeneratorBody>{};
+
+  Map<ClassEntity, List<MemberEntity>> _injectedClassMembers =
+      <ClassEntity, List<MemberEntity>>{};
+
   JsKernelToElementMap(
       DiagnosticReporter reporter,
       Environment environment,
@@ -2514,6 +2534,11 @@
     env.forEachConstructorBody(f);
   }
 
+  void _forEachInjectedClassMember(
+      IndexedClass cls, void f(MemberEntity member)) {
+    _injectedClassMembers[cls]?.forEach(f);
+  }
+
   JRecordField _constructRecordFieldEntry(
       InterfaceType memberThisType,
       ir.VariableDeclaration variable,
@@ -2911,6 +2936,31 @@
   String _getClosureVariableName(String name, int id) {
     return "_captured_${name}_$id";
   }
+
+  JGeneratorBody getGeneratorBody(covariant IndexedFunction function) {
+    FunctionData functionData = _members.getData(function);
+    ir.TreeNode node = functionData.definition.node;
+    // TODO(sra): Maybe store this in the FunctionData.
+    JGeneratorBody generatorBody = _generatorBodies[function];
+    if (generatorBody == null) {
+      generatorBody = createGeneratorBody(function);
+      _members.register<IndexedFunction, FunctionData>(
+          generatorBody,
+          new GeneratorBodyFunctionData(
+              functionData,
+              new SpecialMemberDefinition(
+                  generatorBody, node, MemberKind.generatorBody)));
+
+      if (function.enclosingClass != null) {
+        // TODO(sra): Integrate this with ClassEnvImpl.addConstructorBody ?
+        (_injectedClassMembers[function.enclosingClass] ??= <MemberEntity>[])
+            .add(generatorBody);
+      }
+    }
+    return generatorBody;
+  }
+
+  JGeneratorBody createGeneratorBody(FunctionEntity function);
 }
 
 class KernelClassQueries extends ClassQueries {
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index da925b6..c9b9d93 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -829,6 +829,44 @@
   }
 }
 
+abstract class DelegatedFunctionData implements FunctionData {
+  final FunctionData baseData;
+
+  DelegatedFunctionData(this.baseData);
+
+  FunctionType getFunctionType(covariant KernelToElementMapBase elementMap) {
+    return baseData.getFunctionType(elementMap);
+  }
+
+  List<TypeVariableType> getFunctionTypeVariables(
+      KernelToElementMap elementMap) {
+    return baseData.getFunctionTypeVariables(elementMap);
+  }
+
+  void forEachParameter(KernelToElementMapForBuilding elementMap,
+      void f(DartType type, String name, ConstantValue defaultValue)) {
+    return baseData.forEachParameter(elementMap, f);
+  }
+
+  @override
+  Iterable<ConstantValue> getMetadata(KernelToElementMap elementMap) {
+    return const <ConstantValue>[];
+  }
+
+  InterfaceType getMemberThisType(KernelToElementMapForBuilding elementMap) {
+    return baseData.getMemberThisType(elementMap);
+  }
+
+  ClassTypeVariableAccess get classTypeVariableAccess =>
+      baseData.classTypeVariableAccess;
+}
+
+class GeneratorBodyFunctionData extends DelegatedFunctionData {
+  final MemberDefinition definition;
+  GeneratorBodyFunctionData(FunctionData baseData, this.definition)
+      : super(baseData);
+}
+
 abstract class ConstructorData extends FunctionData {
   ConstantConstructor getConstructorConstant(
       KernelToElementMapBase elementMap, ConstructorEntity constructor);
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 53fa292..dde23a9 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -226,20 +226,7 @@
   /// Whether to generate code compliant with content security policy (CSP).
   bool useContentSecurityPolicy = false;
 
-  /// Preview the unified front-end and compilation from kernel.
-  ///
-  /// When enabled the compiler will use the unified front-end to compile
-  /// sources to kernel, and then continue compilation from the kernel
-  /// representation.
-  ///
-  /// When this flag is on, the compiler also accepts reading .dill files from
-  /// disk. The compiler reads the sources differently depending on the
-  /// extension format.
-  bool useKernel = true;
-
   /// Enables strong mode in dart2js.
-  ///
-  /// This is work-in-progress and will only be supported for [useKernel].
   bool strongMode = false;
 
   /// When obfuscating for minification, whether to use the frequency of a name
@@ -343,7 +330,6 @@
       ..trustTypeAnnotations = _hasOption(options, Flags.trustTypeAnnotations)
       ..useContentSecurityPolicy =
           _hasOption(options, Flags.useContentSecurityPolicy)
-      ..useKernel = !_hasOption(options, Flags.useOldFrontend)
       ..useFrequencyNamer =
           !_hasOption(options, Flags.noFrequencyBasedMinification)
       ..useMultiSourceInfo = _hasOption(options, Flags.useMultiSourceInfo)
@@ -370,7 +356,7 @@
     if (packageRoot != null && !packageRoot.path.endsWith("/")) {
       throw new ArgumentError("[packageRoot] must end with a /");
     }
-    if (useKernel && platformBinaries == null) {
+    if (platformBinaries == null) {
       throw new ArgumentError("Missing required ${Flags.platformBinaries}");
     }
   }
@@ -386,7 +372,8 @@
         trustTypeAnnotations = true;
       }
     }
-    if (useKernel) generateCodeWithCompileTimeErrors = false;
+    // TODO(johnniwinther): Should we support this in the future?
+    generateCodeWithCompileTimeErrors = false;
     if (platformConfigUri == null) {
       platformConfigUri = _resolvePlatformConfig(libraryRoot, null, const []);
     }
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
index 06718ca..0b51c6f 100644
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
@@ -552,6 +552,10 @@
   }
 
   @override
+  void forEachInjectedClassMember(
+      covariant ClassElement cls, void f(MemberElement member)) {}
+
+  @override
   void forEachClassMember(covariant ClassElement cls,
       void f(ClassElement declarer, MemberElement member)) {
     cls.ensureResolved(_resolution);
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index a18d29f..2616b59 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -2837,23 +2837,10 @@
           node, 'Too many arguments to JS_CURRENT_ISOLATE_CONTEXT.');
     }
 
-    if (!backendUsage.isIsolateInUse) {
-      // If the isolate library is not used, we just generate code
-      // to fetch the static state.
-      String name = namer.staticStateHolder;
-      push(new HForeignCode(
-          js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
-          nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
-    } else {
-      // Call a helper method from the isolate library. The isolate
-      // library uses its own isolate structure, that encapsulates
-      // Leg's isolate.
-      MethodElement element = commonElements.currentIsolate;
-      if (element == null) {
-        reporter.internalError(node, 'Isolate library and compiler mismatch.');
-      }
-      pushInvokeStatic(null, element, [], typeMask: commonMasks.dynamicType);
-    }
+    String name = namer.staticStateHolder;
+    push(new HForeignCode(
+        js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
+        nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
   }
 
   void handleForeignJsGetFlag(ast.Send node) {
@@ -3025,27 +3012,6 @@
     stack.add(graph.addConstantNull(closedWorld));
   }
 
-  void handleForeignJsCallInIsolate(ast.Send node) {
-    Link<ast.Node> link = node.arguments;
-    if (!backendUsage.isIsolateInUse) {
-      // If the isolate library is not used, we just invoke the
-      // closure.
-      visit(link.tail.head);
-      push(new HInvokeClosure(new Selector.callClosure(0),
-          <HInstruction>[pop()], commonMasks.dynamicType, const <DartType>[]));
-    } else {
-      // Call a helper method from the isolate library.
-      MethodElement element = commonElements.callInIsolate;
-      if (element == null) {
-        reporter.internalError(node, 'Isolate library and compiler mismatch.');
-      }
-      List<HInstruction> inputs = <HInstruction>[];
-      addGenericSendArgumentsToList(link, inputs);
-      pushInvokeStatic(node, element, inputs,
-          typeMask: commonMasks.dynamicType);
-    }
-  }
-
   FunctionSignature handleForeignRawFunctionRef(ast.Send node, String name) {
     if (node.arguments.isEmpty || !node.arguments.tail.isEmpty) {
       reporter.internalError(
@@ -3115,8 +3081,6 @@
       handleForeignJs(node);
     } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
       handleForeignJsCurrentIsolateContext(node);
-    } else if (name == 'JS_CALL_IN_ISOLATE') {
-      handleForeignJsCallInIsolate(node);
     } else if (name == 'DART_CLOSURE_TO_JS') {
       handleForeignDartClosureToJs(node, 'DART_CLOSURE_TO_JS');
     } else if (name == 'RAW_DART_FUNCTION_REF') {
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index b22a63e..6836904 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -30,6 +30,7 @@
 import '../js_emitter/js_emitter.dart' show NativeEmitter;
 import '../js_model/locals.dart'
     show forEachOrderedParameter, GlobalLocalsMap, JumpVisitor;
+import '../js_model/elements.dart' show JGeneratorBody;
 import '../kernel/element_map.dart';
 import '../kernel/kernel_backend_strategy.dart';
 import '../native/native.dart' as native;
@@ -70,6 +71,7 @@
 class KernelSsaGraphBuilder extends ir.Visitor
     with GraphBuilder, SsaBuilderFieldMixin {
   final MemberEntity targetElement;
+  final MemberEntity initialTargetElement;
 
   final ClosedWorld closedWorld;
   final CodegenWorldBuilder _worldBuilder;
@@ -124,7 +126,7 @@
   StackFrame _currentFrame;
 
   KernelSsaGraphBuilder(
-      this.targetElement,
+      this.initialTargetElement,
       InterfaceType instanceType,
       this.compiler,
       this._elementMap,
@@ -136,7 +138,8 @@
       this.closureDataLookup,
       this.nativeEmitter,
       this._sourceInformationStrategy)
-      : _infoReporter = compiler.dumpInfoTask {
+      : this.targetElement = _effectiveTargetElementFor(initialTargetElement),
+        _infoReporter = compiler.dumpInfoTask {
     _enterFrame(targetElement);
     this.loopHandler = new KernelLoopHandler(this);
     typeBuilder = new KernelTypeBuilder(this, _elementMap, _globalLocalsMap);
@@ -157,6 +160,11 @@
   SourceInformationBuilder get _sourceInformationBuilder =>
       _currentFrame.sourceInformationBuilder;
 
+  static MemberEntity _effectiveTargetElementFor(MemberEntity member) {
+    if (member is JGeneratorBody) return member.function;
+    return member;
+  }
+
   void _enterFrame(MemberEntity member) {
     AsyncMarker asyncMarker = AsyncMarker.SYNC;
     ir.FunctionNode function = getFunctionNode(_elementMap, member);
@@ -183,7 +191,7 @@
       // TODO(het): no reason to do this here...
       HInstruction.idCounter = 0;
       MemberDefinition definition =
-          _elementMap.getMemberDefinition(targetElement);
+          _elementMap.getMemberDefinition(initialTargetElement);
 
       switch (definition.kind) {
         case MemberKind.regular:
@@ -247,6 +255,10 @@
           }
           buildMethodSignature(originalClosureNode);
           break;
+        case MemberKind.generatorBody:
+          buildGeneratorBody(
+              initialTargetElement, _functionNodeOf(definition.node));
+          break;
       }
       assert(graph.isValid());
 
@@ -269,6 +281,13 @@
     });
   }
 
+  ir.FunctionNode _functionNodeOf(ir.TreeNode node) {
+    if (node is ir.Member) return node.function;
+    if (node is ir.FunctionDeclaration) return node.function;
+    if (node is ir.FunctionExpression) return node.function;
+    return null;
+  }
+
   ir.FunctionNode _ensureDefaultArgumentValues(ir.FunctionNode function) {
     // Register all [function]'s default argument values.
     //
@@ -386,8 +405,8 @@
         // Unused, so bind to `dynamic`.
         param = graph.addConstantNull(closedWorld);
       }
-      localsHandler.directLocals[
-          localsHandler.getTypeVariableAsLocal(typeVariableType)] = param;
+      Local local = localsHandler.getTypeVariableAsLocal(typeVariableType);
+      localsHandler.directLocals[local] = param;
     });
   }
 
@@ -414,11 +433,14 @@
         // Unused, so bind to `dynamic`.
         param = graph.addConstantNull(closedWorld);
       }
-      localsHandler.directLocals[
-          localsHandler.getTypeVariableAsLocal(typeVariableType)] = param;
+      Local local = localsHandler.getTypeVariableAsLocal(typeVariableType);
+      localsHandler.directLocals[local] = param;
+      functionTypeParameterLocals.add(local);
     });
   }
 
+  List<Local> functionTypeParameterLocals = <Local>[];
+
   /// Builds a generative constructor.
   ///
   /// Generative constructors are built in stages, in effect inlining the
@@ -622,7 +644,6 @@
 
   void _invokeConstructorBody(ir.Constructor constructor,
       List<HInstruction> inputs, SourceInformation sourceInformation) {
-    // TODO(sra): Inline the constructor body.
     MemberEntity constructorBody = _elementMap.getConstructorBody(constructor);
     HInvokeConstructorBody invoke = new HInvokeConstructorBody(
         constructorBody, inputs, commonMasks.nonNullType, sourceInformation);
@@ -941,6 +962,11 @@
   /// Procedures.
   void buildFunctionNode(
       FunctionEntity function, ir.FunctionNode functionNode) {
+    if (functionNode.asyncMarker != ir.AsyncMarker.Sync) {
+      buildGenerator(function, functionNode);
+      return;
+    }
+
     openFunction(function, functionNode);
 
     // If [functionNode] is `operator==` we explicitly add a null check at the
@@ -968,6 +994,78 @@
     closeFunction();
   }
 
+  /// Builds a SSA graph for a sync*/async/async* generator.
+  void buildGenerator(FunctionEntity function, ir.FunctionNode functionNode) {
+    // TODO(sra): Optimize by generating a merged entry + body when (1) there
+    // are no checks in the entry and (2) the element type is simple.
+    if (true == true) {
+      buildGeneratorEntry(function, functionNode);
+    } else {
+      openFunction(function, functionNode);
+      functionNode.body.accept(this);
+      closeFunction();
+    }
+  }
+
+  /// Builds a SSA graph for a sync*/async/async* generator body.
+  void buildGeneratorEntry(
+      FunctionEntity function, ir.FunctionNode functionNode) {
+    graph.isGeneratorEntry = true;
+
+    // TODO(sra): Omit entry checks.
+    openFunction(function, functionNode);
+
+    // Generate type argument for generator class.
+
+    // Tail-call body.
+    JGeneratorBody body = _elementMap.getGeneratorBody(function);
+    backend.outputUnitData.registerColocatedMembers(function, body);
+
+    // Is 'buildAsyncBody' the best location for the entry?
+    var sourceInformation = _sourceInformationBuilder.buildAsyncBody();
+
+    // Forward all the parameters.
+    List<HInstruction> inputs = <HInstruction>[];
+    if (graph.thisInstruction != null) {
+      inputs.add(graph.thisInstruction);
+    }
+    if (graph.explicitReceiverParameter != null) {
+      inputs.add(graph.explicitReceiverParameter);
+    }
+    for (Local local in parameters.keys) {
+      inputs.add(localsHandler.readLocal(local));
+    }
+    for (Local local in functionTypeParameterLocals) {
+      inputs.add(localsHandler.readLocal(local));
+    }
+
+    // Add the type parameter for the generator's element type.
+    DartType elementType = _elementMap.elementEnvironment
+        .getAsyncOrSyncStarElementType(function.asyncMarker, _returnType);
+    inputs.add(typeBuilder.analyzeTypeArgument(elementType, function));
+
+    push(new HInvokeGeneratorBody(
+        body,
+        inputs,
+        commonMasks.dynamicType, // TODO: better type.
+        sourceInformation));
+
+    closeAndGotoExit(
+        new HReturn(abstractValueDomain, pop(), sourceInformation));
+
+    closeFunction();
+  }
+
+  /// Builds a SSA graph for a sync*/async/async* generator body.
+  void buildGeneratorBody(
+      JGeneratorBody function, ir.FunctionNode functionNode) {
+    // TODO(sra): Omit entry checks.
+    FunctionEntity entry = function.function;
+    openFunction(entry, functionNode);
+    functionNode.body.accept(this);
+    closeFunction();
+  }
+
   void _potentiallyAddFunctionParameterTypeChecks(ir.FunctionNode function) {
     // Put the type checks in the first successor of the entry,
     // because that is where the type guards will also be inserted.
@@ -999,7 +1097,8 @@
   }
 
   void checkTypeVariableBounds(FunctionEntity method) {
-    if (rtiNeed.methodNeedsTypeArguments(method)) {
+    if (rtiNeed.methodNeedsTypeArguments(method) &&
+        options.parameterCheckPolicy.isEmitted) {
       ir.FunctionNode function = getFunctionNode(_elementMap, method);
       for (ir.TypeParameter typeParameter in function.typeParameters) {
         Local local = localsMap.getLocalTypeVariable(
@@ -3104,6 +3203,13 @@
       return;
     }
     FunctionEntity function = _elementMap.getMember(target);
+
+    if (options.strongMode &&
+        function == _commonElements.extractTypeArguments &&
+        handleExtractTypeArguments(node, sourceInformation)) {
+      return;
+    }
+
     TypeMask typeMask = _typeInferenceMap.getReturnTypeOf(function);
 
     List<DartType> typeArguments =
@@ -3306,15 +3412,78 @@
     }
   }
 
+  /// Replace calls to `extractTypeArguments` with equivalent code. Returns
+  /// `true` if `extractTypeArguments` is handled.
+  bool handleExtractTypeArguments(
+      ir.StaticInvocation invocation, SourceInformation sourceInformation) {
+    // Expand calls as follows:
+    //
+    //     r = extractTypeArguments<Map>(e, f)
+    // -->
+    //     interceptor = getInterceptor(e);
+    //     T1 = getRuntimeTypeArgumentIntercepted(interceptor, e, 'Map', 0);
+    //     T2 = getRuntimeTypeArgumentIntercepted(interceptor, e, 'Map', 1);
+    //     r = f<T1, T2>();
+    //
+    // TODO(sra): Should we add a check before the variable extraction? We could
+    // add a type check (which would permit `null`), or add an is-check with an
+    // explicit throw.
+
+    if (invocation.arguments.positional.length != 2) return false;
+    if (invocation.arguments.named.isNotEmpty) return false;
+    var types = invocation.arguments.types;
+    if (types.length != 1) return false;
+
+    // The type should be a single type name.
+    ir.DartType type = types.first;
+    DartType typeValue =
+        localsHandler.substInContext(_elementMap.getDartType(type));
+    if (typeValue is! InterfaceType) return false;
+    InterfaceType interfaceType = typeValue;
+    if (!interfaceType.treatAsRaw) return false;
+
+    ClassEntity cls = interfaceType.element;
+    InterfaceType thisType = _elementMap.elementEnvironment.getThisType(cls);
+
+    List<HInstruction> arguments =
+        _visitPositionalArguments(invocation.arguments);
+
+    HInstruction object = arguments[0];
+    HInstruction closure = arguments[1];
+    HInstruction interceptor = _interceptorFor(object, sourceInformation);
+
+    List<HInstruction> inputs = <HInstruction>[closure];
+    List<DartType> typeArguments = <DartType>[];
+
+    thisType.typeArguments.forEach((_typeVariable) {
+      TypeVariableType variable = _typeVariable;
+      typeArguments.add(variable);
+      HInstruction readType = new HTypeInfoReadVariable.intercepted(
+          variable, interceptor, object, commonMasks.dynamicType);
+      add(readType);
+      inputs.add(readType);
+    });
+
+    // TODO(sra): In compliance mode, insert a check that [closure] is a
+    // function of N type arguments.
+
+    Selector selector =
+        new Selector.callClosure(0, const <String>[], typeArguments.length);
+    push(new HInvokeClosure(
+        selector, inputs, commonMasks.dynamicType, typeArguments));
+
+    return true;
+  }
+
   void handleInvokeStaticForeign(
       ir.StaticInvocation invocation, ir.Procedure target) {
     String name = target.name.name;
     if (name == 'JS') {
       handleForeignJs(invocation);
     } else if (name == 'JS_CURRENT_ISOLATE_CONTEXT') {
+      // TODO(sigmund): delete. The only reference left to this foreign function
+      // is from the deprecated dart:mirrors code.
       handleForeignJsCurrentIsolateContext(invocation);
-    } else if (name == 'JS_CALL_IN_ISOLATE') {
-      handleForeignJsCallInIsolate(invocation);
     } else if (name == 'DART_CLOSURE_TO_JS') {
       handleForeignDartClosureToJs(invocation, 'DART_CLOSURE_TO_JS');
     } else if (name == 'RAW_DART_FUNCTION_REF') {
@@ -3427,57 +3596,12 @@
       return;
     }
 
-    if (!backendUsage.isIsolateInUse) {
-      // If the isolate library is not used, we just generate code
-      // to fetch the static state.
-      String name = namer.staticStateHolder;
-      push(new HForeignCode(
-          js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
-          nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
-    } else {
-      // Call a helper method from the isolate library. The isolate library uses
-      // its own isolate structure that encapsulates the isolate structure used
-      // for binding to methods.
-      FunctionEntity target = _commonElements.currentIsolate;
-      if (target == null) {
-        reporter.internalError(
-            _elementMap.getSpannable(targetElement, invocation),
-            'Isolate library and compiler mismatch.');
-      }
-      _pushStaticInvocation(target, <HInstruction>[], commonMasks.dynamicType,
-          const <DartType>[]);
-    }
-  }
-
-  void handleForeignJsCallInIsolate(ir.StaticInvocation invocation) {
-    if (_unexpectedForeignArguments(invocation,
-        minPositional: 2, maxPositional: 2)) {
-      // Result expected on stack.
-      stack.add(graph.addConstantNull(closedWorld));
-      return;
-    }
-
-    List<HInstruction> inputs = _visitPositionalArguments(invocation.arguments);
-
-    if (!backendUsage.isIsolateInUse) {
-      // If the isolate library is not used, we ignore the isolate argument and
-      // just invoke the closure.
-      push(new HInvokeClosure(
-          new Selector.callClosure(0),
-          <HInstruction>[inputs[1]],
-          commonMasks.dynamicType,
-          const <DartType>[]));
-    } else {
-      // Call a helper method from the isolate library.
-      FunctionEntity callInIsolate = _commonElements.callInIsolate;
-      if (callInIsolate == null) {
-        reporter.internalError(
-            _elementMap.getSpannable(targetElement, invocation),
-            'Isolate library and compiler mismatch.');
-      }
-      _pushStaticInvocation(
-          callInIsolate, inputs, commonMasks.dynamicType, const <DartType>[]);
-    }
+    // Isolates cannot be spawned, so we just generate code to fetch the static
+    // state.
+    String name = namer.staticStateHolder;
+    push(new HForeignCode(
+        js.js.parseForeignJS(name), commonMasks.dynamicType, <HInstruction>[],
+        nativeBehavior: native.NativeBehavior.DEPENDS_OTHER));
   }
 
   void handleForeignDartClosureToJs(
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index fc0c71b..49cf09b 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -23,6 +23,7 @@
 import '../js_backend/namer.dart';
 import '../js_backend/runtime_types.dart';
 import '../js_emitter/code_emitter_task.dart';
+import '../js_model/elements.dart' show JGeneratorBody;
 import '../native/native.dart' as native;
 import '../options.dart';
 import '../types/abstract_value_domain.dart';
@@ -47,20 +48,24 @@
 
   String get name => 'SSA code generator';
 
-  js.Fun buildJavaScriptFunction(
-      FunctionEntity element, List<js.Parameter> parameters, js.Block body) {
-    js.AsyncModifier asyncModifier = element.asyncMarker.isAsync
+  js.Fun buildJavaScriptFunction(bool isGeneratorEntry, FunctionEntity element,
+      List<js.Parameter> parameters, js.Block body) {
+    js.Fun finish(js.AsyncModifier asyncModifier) {
+      return new js.Fun(parameters, body, asyncModifier: asyncModifier)
+          .withSourceInformation(sourceInformationFactory
+              .createBuilderForContext(element)
+              .buildDeclaration(element));
+    }
+
+    if (isGeneratorEntry) return finish(const js.AsyncModifier.sync());
+
+    return finish(element.asyncMarker.isAsync
         ? (element.asyncMarker.isYielding
             ? const js.AsyncModifier.asyncStar()
             : const js.AsyncModifier.async())
         : (element.asyncMarker.isYielding
             ? const js.AsyncModifier.syncStar()
-            : const js.AsyncModifier.sync());
-
-    return new js.Fun(parameters, body, asyncModifier: asyncModifier)
-        .withSourceInformation(sourceInformationFactory
-            .createBuilderForContext(element)
-            .buildDeclaration(element));
+            : const js.AsyncModifier.sync()));
   }
 
   js.Expression generateCode(
@@ -118,8 +123,8 @@
           work);
       codegen.visitGraph(graph);
       backend.tracer.traceGraph("codegen", graph);
-      return buildJavaScriptFunction(
-          work.element, codegen.parameters, codegen.body);
+      return buildJavaScriptFunction(graph.isGeneratorEntry, work.element,
+          codegen.parameters, codegen.body);
     });
   }
 }
@@ -1782,6 +1787,27 @@
         node.element, new CallStructure.unnamed(arguments.length)));
   }
 
+  void visitInvokeGeneratorBody(HInvokeGeneratorBody node) {
+    JGeneratorBody element = node.element;
+    if (element.isInstanceMember) {
+      use(node.inputs[0]);
+      js.Expression object = pop();
+      List<js.Expression> arguments = visitArguments(node.inputs);
+      js.Name methodName = _namer.instanceMethodName(element);
+      push(js
+          .propertyCall(object, methodName, arguments)
+          .withSourceInformation(node.sourceInformation));
+    } else {
+      push(_emitter.staticFunctionAccess(element));
+      List<js.Expression> arguments = visitArguments(node.inputs, start: 0);
+      push(new js.Call(pop(), arguments,
+          sourceInformation: node.sourceInformation));
+    }
+
+    _registry
+        .registerStaticUse(new StaticUse.generatorBodyInvoke(node.element));
+  }
+
   void visitOneShotInterceptor(HOneShotInterceptor node) {
     List<js.Expression> arguments = visitArguments(node.inputs);
     var isolate = new js.VariableUse(
diff --git a/pkg/compiler/lib/src/ssa/kernel_impact.dart b/pkg/compiler/lib/src/ssa/kernel_impact.dart
index 735c58e..7b93861 100644
--- a/pkg/compiler/lib/src/ssa/kernel_impact.dart
+++ b/pkg/compiler/lib/src/ssa/kernel_impact.dart
@@ -397,6 +397,11 @@
       handleNew(node, node.target, isConst: node.isConst);
     } else {
       FunctionEntity target = elementMap.getMethod(node.target);
+      if (_options.strongMode &&
+          target == commonElements.extractTypeArguments) {
+        _handleExtractTypeArguments(node, target);
+        return;
+      }
       List<DartType> typeArguments = _visitArguments(node.arguments);
       impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
           target, elementMap.getCallStructure(node.arguments), typeArguments));
@@ -426,6 +431,35 @@
     }
   }
 
+  void _handleExtractTypeArguments(
+      ir.StaticInvocation node, FunctionEntity target) {
+    // extractTypeArguments<Map>(obj, fn) has additional impacts:
+    //
+    //   1. All classes implementing Map need to carry type arguments (similar
+    //      to checking `o is Map<K, V>`).
+    //
+    //   2. There is an invocation of fn with some number of type arguments.
+    //
+    List<DartType> typeArguments = _visitArguments(node.arguments);
+    impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
+        target, elementMap.getCallStructure(node.arguments), typeArguments));
+
+    if (typeArguments.length != 1) return;
+    DartType matchedType = typeArguments.first;
+
+    if (matchedType is! InterfaceType) return;
+    InterfaceType interfaceType = matchedType;
+    ClassEntity cls = interfaceType.element;
+    InterfaceType thisType = elementMap.elementEnvironment.getThisType(cls);
+
+    impactBuilder.registerTypeUse(new TypeUse.isCheck(thisType));
+
+    Selector selector = new Selector.callClosure(
+        0, const <String>[], thisType.typeArguments.length);
+    impactBuilder.registerDynamicUse(
+        new ConstrainedDynamicUse(selector, null, thisType.typeArguments));
+  }
+
   @override
   void visitStaticGet(ir.StaticGet node) {
     ir.Member target = node.target;
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index a42c238..7d6720a 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -60,6 +60,7 @@
   R visitInvokeStatic(HInvokeStatic node);
   R visitInvokeSuper(HInvokeSuper node);
   R visitInvokeConstructorBody(HInvokeConstructorBody node);
+  R visitInvokeGeneratorBody(HInvokeGeneratorBody node);
   R visitIs(HIs node);
   R visitIsViaInterceptor(HIsViaInterceptor node);
   R visitLazyStatic(HLazyStatic node);
@@ -206,10 +207,15 @@
   HBasicBlock exit;
   HThis thisInstruction;
 
+  /// `true` if a sync*/async/async* method is split into an entry and a body
+  /// and this graph is for the entry, which should not be rewritten.
+  bool isGeneratorEntry = false;
+
   /// Receiver parameter, set for methods using interceptor calling convention.
   HParameterValue explicitReceiverParameter;
   bool isRecursiveMethod = false;
   bool calledInLoop = false;
+
   final List<HBasicBlock> blocks = <HBasicBlock>[];
 
   /// Nodes containing list allocations for which there is a known fixed length.
@@ -414,6 +420,8 @@
   visitInvokeClosure(HInvokeClosure node) => visitInvokeDynamic(node);
   visitInvokeConstructorBody(HInvokeConstructorBody node) =>
       visitInvokeStatic(node);
+  visitInvokeGeneratorBody(HInvokeGeneratorBody node) =>
+      visitInvokeStatic(node);
   visitInvokeDynamicMethod(HInvokeDynamicMethod node) =>
       visitInvokeDynamic(node);
   visitInvokeDynamicGetter(HInvokeDynamicGetter node) =>
@@ -1821,6 +1829,25 @@
   accept(HVisitor visitor) => visitor.visitInvokeConstructorBody(this);
 }
 
+class HInvokeGeneratorBody extends HInvokeStatic {
+  // Directly call the JGeneratorBody method. The generator body can be a static
+  // method or a member. The target is directly called.
+  // The 'inputs' are
+  //     [arg1, ..., argN] or
+  //     [receiver, arg1, ..., argN] or
+  //     [interceptor, receiver, arg1, ... argN].
+  // The 'inputs' may or may not have an additional type argument used for
+  // creating the generator (T for new Completer<T>() inside the body).
+  HInvokeGeneratorBody(FunctionEntity element, List<HInstruction> inputs,
+      AbstractValue type, SourceInformation sourceInformation)
+      : super(element, inputs, type, const <DartType>[]) {
+    this.sourceInformation = sourceInformation;
+  }
+
+  String toString() => 'HInvokeGeneratorBody(${element.name})';
+  accept(HVisitor visitor) => visitor.visitInvokeGeneratorBody(this);
+}
+
 abstract class HFieldAccess extends HInstruction {
   final FieldEntity element;
 
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index f9c45ea..def9ec7 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -45,7 +45,7 @@
     optimizer.optimize(work, graph, closedWorld);
     MemberEntity element = work.element;
     js.Expression result = generator.generateCode(work, graph, closedWorld);
-    if (element is FunctionEntity) {
+    if (element is FunctionEntity && !graph.isGeneratorEntry) {
       SourceInformationBuilder sourceInformationBuilder =
           backend.sourceInformationStrategy.createBuilderForContext(element);
       result = backend.rewriteAsync(
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index f7956fb..413c044 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -350,6 +350,11 @@
     return handleGenericInvoke("InvokeConstructorBody", target, invoke.inputs);
   }
 
+  String visitInvokeGeneratorBody(HInvokeGeneratorBody invoke) {
+    String target = invoke.element.name;
+    return handleGenericInvoke("InvokeGeneratorBody", target, invoke.inputs);
+  }
+
   String visitForeignCode(HForeignCode node) {
     var template = node.codeTemplate;
     String code = '${template.ast}';
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index ac340805..c9b456e 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -4,7 +4,6 @@
 
 import 'graph_builder.dart';
 import 'nodes.dart';
-import '../common.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
 import '../io/source_information.dart';
@@ -115,9 +114,8 @@
   HInstruction addTypeVariableReference(
       TypeVariableType type, MemberEntity member,
       {SourceInformation sourceInformation}) {
-    assert(assertTypeInContext(type));
     if (type.element.typeDeclaration is! ClassEntity &&
-        (!builder.options.strongMode || !builder.options.useKernel)) {
+        !builder.options.strongMode) {
       // GENERIC_METHODS:  We currently don't reify method type variables.
       return builder.graph.addConstantNull(builder.closedWorld);
     }
@@ -204,25 +202,9 @@
     return representation;
   }
 
-  /// Check that [type] is valid in the context of `localsHandler.contextClass`.
-  /// This should only be called in assertions.
-  bool assertTypeInContext(DartType type, [Spannable spannable]) {
-    if (builder.compiler.options.useKernel) return true;
-    ClassEntity contextClass = DartTypes.getClassContext(type);
-    assert(
-        contextClass == null ||
-            contextClass == builder.localsHandler.instanceType?.element,
-        failedAt(
-            spannable ?? CURRENT_ELEMENT_SPANNABLE,
-            "Type '$type' is not valid context of "
-            "${builder.localsHandler.instanceType?.element}."));
-    return true;
-  }
-
   HInstruction analyzeTypeArgument(
       DartType argument, MemberEntity sourceElement,
       {SourceInformation sourceInformation}) {
-    assert(assertTypeInContext(argument));
     argument = argument.unaliased;
     if (argument.treatAsDynamic) {
       // Represent [dynamic] as [null].
@@ -237,7 +219,7 @@
     List<HInstruction> inputs = <HInstruction>[];
     argument.forEachTypeVariable((TypeVariableType variable) {
       if (variable.element.typeDeclaration is ClassEntity ||
-          (builder.options.strongMode && builder.options.useKernel)) {
+          builder.options.strongMode) {
         // TODO(johnniwinther): Also make this conditional on whether we have
         // calculated we need that particular method signature.
         inputs.add(analyzeTypeArgument(variable, sourceElement));
@@ -280,7 +262,6 @@
       }
     }
     type = type.unaliased;
-    assert(assertTypeInContext(type, original));
     if (type.isInterfaceType && !type.treatAsRaw) {
       InterfaceType interfaceType = type;
       TypeMask subtype =
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index 7983684..ed3c1b9 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -378,7 +378,6 @@
   final ClassQueries classQueries;
 
   bool hasRuntimeTypeSupport = false;
-  bool hasIsolateSupport = false;
   bool hasFunctionApplySupport = false;
 
   bool _closed = false;
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index 263d4ac..3d03614 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -170,9 +170,10 @@
   factory Selector.call(Name name, CallStructure callStructure) =>
       new Selector(SelectorKind.CALL, name, callStructure);
 
-  factory Selector.callClosure(int arity, [List<String> namedArguments]) =>
+  factory Selector.callClosure(int arity,
+          [List<String> namedArguments, int typeArgumentCount = 0]) =>
       new Selector(SelectorKind.CALL, Names.call,
-          new CallStructure(arity, namedArguments));
+          new CallStructure(arity, namedArguments, typeArgumentCount));
 
   factory Selector.callClosureFrom(Selector selector) =>
       new Selector(SelectorKind.CALL, Names.call, selector.callStructure);
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index 9e105084..d5c894e 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -305,6 +305,12 @@
         callStructure: callStructure);
   }
 
+  /// Direct invocation of a generator (body) [element], as a static call or
+  /// through a this or super constructor call.
+  factory StaticUse.generatorBodyInvoke(FunctionEntity element) {
+    return new StaticUse.internal(element, StaticUseKind.INVOKE);
+  }
+
   /// Direct invocation of a method [element] with the given [callStructure].
   factory StaticUse.directInvoke(FunctionEntity element,
       CallStructure callStructure, List<DartType> typeArguments) {
diff --git a/pkg/compiler/lib/src/util/emptyset.dart b/pkg/compiler/lib/src/util/emptyset.dart
index d37b0c4..1fa3dba 100644
--- a/pkg/compiler/lib/src/util/emptyset.dart
+++ b/pkg/compiler/lib/src/util/emptyset.dart
@@ -9,12 +9,10 @@
 class ImmutableEmptySet<E> extends IterableBase<E> implements Set<E> {
   const ImmutableEmptySet();
 
-  Set<R> cast<R>() {
-    Set<Object> self = this;
-    return self is Set<R> ? self : this.retype<R>();
-  }
+  Set<R> cast<R>() => new ImmutableEmptySet<R>();
 
-  Set<R> retype<R>() => new ImmutableEmptySet<R>();
+  @Deprecated("Use cast instead.")
+  Set<R> retype<R>() => cast<R>();
 
   get iterator => const _EmptySetIterator();
   int get length => 0;
diff --git a/pkg/compiler/lib/src/util/setlet.dart b/pkg/compiler/lib/src/util/setlet.dart
index 27e7a86..08195f0 100644
--- a/pkg/compiler/lib/src/util/setlet.dart
+++ b/pkg/compiler/lib/src/util/setlet.dart
@@ -29,7 +29,10 @@
 
   static Set<R> _newSet<R>() => new Setlet<R>();
 
-  Set<R> retype<R>() => Set.castFrom<E, R>(this, newSet: _newSet);
+  Set<R> cast<R>() => Set.castFrom<E, R>(this, newSet: _newSet);
+
+  @Deprecated("Use cast instead.")
+  Set<R> retype<R>() => cast<R>();
 
   Iterator<E> get iterator {
     if (_extra == null) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index c7c523d..c2acf4f 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -3642,10 +3642,25 @@
     var result = _emitForeignJS(node, e);
     if (result != null) return result;
 
-    if (e?.name == 'extensionSymbol' && isSdkInternalRuntime(e.library)) {
-      var args = node.argumentList.arguments;
-      var firstArg = args.length == 1 ? args[0] : null;
-      if (firstArg is StringLiteral) {
+    // Optimize some internal SDK calls.
+    if (e != null &&
+        isSdkInternalRuntime(e.library) &&
+        node.argumentList.arguments.length == 1) {
+      var firstArg = node.argumentList.arguments[0];
+      if (e.name == 'getGenericClass' && firstArg is SimpleIdentifier) {
+        var typeElem = firstArg.staticElement;
+        if (typeElem is TypeDefiningElement &&
+            typeElem.type is ParameterizedType) {
+          return _emitTopLevelNameNoInterop(typeElem, suffix: '\$');
+        }
+      }
+      if (e.name == 'unwrapType' && firstArg is SimpleIdentifier) {
+        var typeElem = firstArg.staticElement;
+        if (typeElem is TypeDefiningElement) {
+          return _emitType(fillDynamicTypeArgs(typeElem.type));
+        }
+      }
+      if (e.name == 'extensionSymbol' && firstArg is StringLiteral) {
         return _getExtensionSymbolInternal(firstArg.stringValue);
       }
     }
@@ -4059,27 +4074,6 @@
       }
     }
 
-    JS.Expression visitTemplateArg(Expression arg) {
-      if (arg is InvocationExpression) {
-        var e = arg is MethodInvocation
-            ? arg.methodName.staticElement
-            : (arg as FunctionExpressionInvocation).staticElement;
-        if (e?.name == 'getGenericClass' &&
-            e.library.name == 'dart._runtime' &&
-            arg.argumentList.arguments.length == 1) {
-          var typeArg = arg.argumentList.arguments[0];
-          if (typeArg is SimpleIdentifier) {
-            var typeElem = typeArg.staticElement;
-            if (typeElem is TypeDefiningElement &&
-                typeElem.type is ParameterizedType) {
-              return _emitTopLevelNameNoInterop(typeElem, suffix: '\$');
-            }
-          }
-        }
-      }
-      return _visitExpression(arg);
-    }
-
     // TODO(rnystrom): The JS() calls are almost never nested, and probably
     // really shouldn't be, but there are at least a couple of calls in the
     // HTML library where an argument to JS() is itself a JS() call. If those
@@ -4088,7 +4082,7 @@
     // wrapped Type object.
     var wasInForeignJS = _isInForeignJS;
     _isInForeignJS = true;
-    var jsArgs = templateArgs.map(visitTemplateArg).toList();
+    var jsArgs = templateArgs.map(_visitExpression).toList();
     _isInForeignJS = wasInForeignJS;
 
     var result = js.parseForeignJS(source).instantiate(jsArgs);
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index bc50ca2..819227d 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -4378,11 +4378,21 @@
     if (isInlineJS(target)) return _emitInlineJSCode(node) as JS.Expression;
     if (target.isFactory) return _emitFactoryInvocation(node);
 
-    if (target.name.name == 'extensionSymbol' &&
-        isSdkInternalRuntime(target.enclosingLibrary)) {
-      var args = node.arguments;
-      var firstArg = args.positional.length == 1 ? args.positional[0] : null;
-      if (firstArg is StringLiteral) {
+    // Optimize some internal SDK calls.
+    if (isSdkInternalRuntime(target.enclosingLibrary) &&
+        node.arguments.positional.length == 1) {
+      var name = target.name.name;
+      var firstArg = node.arguments.positional[0];
+      if (name == 'getGenericClass' && firstArg is TypeLiteral) {
+        var type = firstArg.type;
+        if (type is InterfaceType) {
+          return _emitTopLevelNameNoInterop(type.classNode, suffix: '\$');
+        }
+      }
+      if (name == 'unwrapType' && firstArg is TypeLiteral) {
+        return _emitType(firstArg.type);
+      }
+      if (name == 'extensionSymbol' && firstArg is StringLiteral) {
         return _getExtensionSymbolInternal(firstArg.value);
       }
     }
@@ -4531,25 +4541,6 @@
       }
     }
 
-    JS.Expression visitTemplateArg(Expression arg) {
-      if (arg is StaticInvocation) {
-        var target = arg.target;
-        var positional = arg.arguments.positional;
-        if (target.name.name == 'getGenericClass' &&
-            isSdkInternalRuntime(target.enclosingLibrary) &&
-            positional.length == 1) {
-          var typeArg = positional[0];
-          if (typeArg is TypeLiteral) {
-            var type = typeArg.type;
-            if (type is InterfaceType) {
-              return _emitTopLevelNameNoInterop(type.classNode, suffix: '\$');
-            }
-          }
-        }
-      }
-      return _visitExpression(arg);
-    }
-
     // TODO(rnystrom): The JS() calls are almost never nested, and probably
     // really shouldn't be, but there are at least a couple of calls in the
     // HTML library where an argument to JS() is itself a JS() call. If those
@@ -4558,7 +4549,7 @@
     // wrapped Type object.
     var wasInForeignJS = _isInForeignJS;
     _isInForeignJS = true;
-    var jsArgs = templateArgs.map(visitTemplateArg).toList();
+    var jsArgs = templateArgs.map(_visitExpression).toList();
     _isInForeignJS = wasInForeignJS;
 
     var result = js.parseForeignJS(source).instantiate(jsArgs);
@@ -5034,7 +5025,7 @@
   @override
   visitFunctionExpression(FunctionExpression node) {
     var fn = _emitArrowFunction(node);
-    if (!_reifyFunctionType(_currentFunction)) return fn;
+    if (!_reifyFunctionType(node.function)) return fn;
     return _emitFunctionTagged(fn, node.getStaticType(types) as FunctionType);
   }
 
@@ -5140,7 +5131,7 @@
         isBuiltinAnnotation(a, '_js_helper', 'ReifyFunctionTypes');
     while (parent != null) {
       var a = findAnnotation(parent, reifyFunctionTypes);
-      if (a != null && a is ConstructorInvocation) {
+      if (a is ConstructorInvocation) {
         var args = a.arguments.positional;
         if (args.length == 1) {
           var arg = args[0];
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index 742508b..be94da4 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -223,7 +223,13 @@
         s.trim();
         s.trimLeft();
         s.trimRight();
-        s.compareTo(s);
+
+        // compareTo relies on the interface target being String.compareTo
+        // except that method does not exist unless we insert too many
+        // forwarding stubs.
+        //
+        // s.compareTo(s);
+
         s.toString();
         // Pattern methods (allMatches, matchAsPrefix) are not recognized.
       }''');
@@ -413,27 +419,25 @@
       useAnnotations = false;
     });
     var imports = "import 'package:meta/meta.dart';";
-    group('(kernel annotation bug)', () {
-      test('variable wihout initializer', () async {
-        await expectNotNull('$imports main() { @notNull var x; print(x); }',
-            ''); // should be: 'x'
+    group('(previously known kernel annotation bug)', () {
+      test('variable without initializer', () async {
+        await expectNotNull(
+            '$imports main() { @notNull var x; print(x); }', 'x');
       });
       test('variable with initializer', () async {
         // TODO(jmesserly): this does not work in the Analyzer backend.
         await expectNotNull(
-            '$imports main() { @notNull var x = null; print(x); }',
-            ''); // should be: 'x'
+            '$imports main() { @notNull var x = null; print(x); }', 'x');
       });
       test('parameters', () async {
         await expectNotNull(
             '$imports f(@notNull x, [@notNull y, @notNull z = 42]) '
             '{ x; y; z; }',
-            '42, z'); // should be: '42, x, y, z'
+            '42, x, y, z');
       });
       test('named parameters', () async {
         await expectNotNull(
-            '$imports f({@notNull x, @notNull y: 42}) { x; y; }',
-            '42, y'); // should be: '42, x, y'
+            '$imports f({@notNull x, @notNull y: 42}) { x; y; }', '42, x, y');
       });
     });
 
diff --git a/pkg/dev_compiler/tool/input_sdk/patch/convert_patch.dart b/pkg/dev_compiler/tool/input_sdk/patch/convert_patch.dart
index 5ef68a4..18a077e 100644
--- a/pkg/dev_compiler/tool/input_sdk/patch/convert_patch.dart
+++ b/pkg/dev_compiler/tool/input_sdk/patch/convert_patch.dart
@@ -9,6 +9,7 @@
 import 'dart:_interceptors' show JSExtendableArray;
 import 'dart:_internal' show MappedIterable, ListIterable;
 import 'dart:collection' show Maps, LinkedHashMap, MapBase;
+import 'dart:_native_typed_data' show NativeUint8List;
 
 /**
  * Parses [json] and builds the corresponding parsed JSON value.
@@ -399,6 +400,98 @@
   @patch
   static String _convertIntercepted(
       bool allowMalformed, List<int> codeUnits, int start, int end) {
-    return null; // This call was not intercepted.
+    // Test `codeUnits is NativeUint8List`. Dart's NativeUint8List is
+    // implemented by JavaScript's Uint8Array.
+    if (JS('bool', '# instanceof Uint8Array', codeUnits)) {
+      // JS 'cast' to avoid a downcast equivalent to the is-check we hand-coded.
+      NativeUint8List casted = JS('NativeUint8List', '#', codeUnits);
+      return _convertInterceptedUint8List(allowMalformed, casted, start, end);
+    }
   }
+
+  static String _convertInterceptedUint8List(
+      bool allowMalformed, NativeUint8List codeUnits, int start, int end) {
+    if (allowMalformed) {
+      // TextDecoder with option {fatal: false} does not produce the same result
+      // as [Utf8Decoder]. It disagrees on the number of `U+FFFD` (REPLACEMENT
+      // CHARACTER) generated for some malformed sequences. We could use
+      // TextDecoder with option {fatal: true}, catch the error, and re-try
+      // without acceleration. That turns out to be extremely slow (the Error
+      // captures a stack trace).
+      // TODO(31370): Bring Utf8Decoder into alignment with TextDecoder.
+      // TODO(sra): If we can't do that, can we detect valid input fast enough
+      // to use a check like the [_unsafe] check below?
+      return null;
+    }
+
+    var decoder = _decoder;
+    if (decoder == null) return null;
+    if (0 == start && end == null) {
+      return _useTextDecoderChecked(decoder, codeUnits);
+    }
+
+    int length = codeUnits.length;
+    end = RangeError.checkValidRange(start, end, length);
+
+    if (0 == start && end == codeUnits.length) {
+      return _useTextDecoderChecked(decoder, codeUnits);
+    }
+
+    return _useTextDecoderChecked(decoder,
+        JS('NativeUint8List', '#.subarray(#, #)', codeUnits, start, end));
+  }
+
+  static String _useTextDecoderChecked(decoder, NativeUint8List codeUnits) {
+    if (_unsafe(codeUnits)) return null;
+    return _useTextDecoderUnchecked(decoder, codeUnits);
+  }
+
+  static String _useTextDecoderUnchecked(decoder, NativeUint8List codeUnits) {
+    // If the input is malformed, catch the exception and return `null` to fall
+    // back on unintercepted decoder. The fallback will either succeed in
+    // decoding, or report the problem better than TextDecoder.
+    try {
+      return JS('String', '#.decode(#)', decoder, codeUnits);
+    } catch (e) {}
+    return null;
+  }
+
+  /// Returns `true` if [codeUnits] contains problematic encodings.
+  ///
+  /// TextDecoder behaves differently to [Utf8Encoder] when the input encodes a
+  /// surrogate (U+D800 through U+DFFF). TextDecoder considers the surrogate to
+  /// be an encoding error and, depending on the `fatal` option, either throws
+  /// and Error or encodes the surrogate as U+FFFD. [Utf8Decoder] does not
+  /// consider the surrogate to be an error and returns the code unit encoded by
+  /// the surrogate.
+  ///
+  /// Throwing an `Error` captures the stack, whoch makes it so expensive that
+  /// it is worth checking the input for surrogates and avoiding TextDecoder in
+  /// this case.
+  static bool _unsafe(NativeUint8List codeUnits) {
+    // Surrogates encode as (hex) ED Ax xx or ED Bx xx.
+    int limit = codeUnits.length - 2;
+    for (int i = 0; i < limit; i++) {
+      int unit1 = codeUnits[i];
+      if (unit1 == 0xED) {
+        int unit2 = JS('!', '#', codeUnits[i + 1]);
+        if ((unit2 & 0xE0) == 0xA0) return true;
+      }
+    }
+    return false;
+  }
+
+  //// TextDecoder is not defined on some browsers and on the stand-alone d8 and
+  /// jsshell engines. Use a lazy initializer to do feature detection once.
+  static final _decoder = () {
+    try {
+      // Use `{fatal: true}`. 'fatal' does not correspond exactly to
+      // `!allowMalformed`: TextDecoder rejects unpaired surrogates which
+      // [Utf8Decoder] accepts.  In non-fatal mode, TextDecoder translates
+      // unpaired surrogates to REPLACEMENT CHARACTER (U+FFFD) whereas
+      // [Utf8Decoder] leaves the surrogate intact.
+      return JS('', 'new TextDecoder("utf-8", {fatal: true})');
+    } catch (e) {}
+    return null;
+  }();
 }
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 0f0c078..163e26c 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
@@ -100,8 +100,13 @@
 @JSExportName('implements')
 final _implements = JS('', 'Symbol("implements")');
 
-getImplements(clazz) => JS('', 'Object.hasOwnProperty.call(#, #) ? #[#] : null',
-    clazz, _implements, clazz, _implements);
+List Function() getImplements(clazz) => JS(
+    '',
+    'Object.hasOwnProperty.call(#, #) ? #[#] : null',
+    clazz,
+    _implements,
+    clazz,
+    _implements);
 
 /// The Symbol for storing type arguments on a specialized generic type.
 final _typeArguments = JS('', 'Symbol("typeArguments")');
@@ -159,6 +164,14 @@
 List getGenericArgs(type) =>
     JS('List', '#', safeGetOwnProperty(type, _typeArguments));
 
+List<TypeVariable> getGenericTypeFormals(genericClass) {
+  return _typeFormalsFromFunction(getGenericTypeCtor(genericClass));
+}
+
+Object instantiateClass(Object genericClass, List<Object> typeArgs) {
+  return JS('', '#.apply(null, #)', genericClass, typeArgs);
+}
+
 final _constructorSig = JS('', 'Symbol("sigCtor")');
 final _methodSig = JS('', 'Symbol("sigMethod")');
 final _fieldSig = JS('', 'Symbol("sigField")');
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/errors.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/errors.dart
index 4d2f78f..a6b3b01 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/errors.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/errors.dart
@@ -17,6 +17,7 @@
   JS('', 'dart.__ignoreWhitelistedErrors = #', flag);
 }
 
+// TODO(jmesserly): remove this?
 void ignoreAllErrors(bool flag) {
   JS('', 'dart.__ignoreAllErrors = #', flag);
 }
@@ -49,3 +50,38 @@
   throw new NoSuchMethodError(
       null, new Symbol('<Unexpected Null Value>'), null, null, null);
 }
+
+castError(obj, expectedType, [bool typeError = undefined]) {
+  var actualType = getReifiedType(obj);
+  var message = _castErrorMessage(actualType, expectedType);
+  if (JS('!', 'dart.__ignoreAllErrors')) {
+    JS('', 'console.error(#)', message);
+    return obj;
+  }
+  if (JS('!', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
+  var error = JS<bool>('!', '#', typeError)
+      ? new TypeErrorImpl(message)
+      : new CastErrorImpl(message);
+  throw error;
+}
+
+String _castErrorMessage(from, to) {
+  // If both types are generic classes, see if we can infer generic type
+  // arguments for `from` that would allow the subtype relation to work.
+  var fromClass = getGenericClass(from);
+  if (fromClass != null) {
+    var fromTypeFormals = getGenericTypeFormals(fromClass);
+    var fromType = instantiateClass(fromClass, fromTypeFormals);
+    var inferrer = new _TypeInferrer(fromTypeFormals);
+    if (inferrer.trySubtypeMatch(fromType, to)) {
+      var inferredTypes = inferrer.getInferredTypes();
+      if (inferredTypes != null) {
+        var inferred = instantiateClass(fromClass, inferredTypes);
+        return "Type '${typeName(from)}' should be '${typeName(inferred)}' "
+            "to implement expected type '${typeName(to)}'.";
+      }
+    }
+  }
+  return "Type '${typeName(from)}' is not a subtype of "
+      "expected type '${typeName(to)}'.";
+}
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 b28594e..ca353ba 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
@@ -476,33 +476,9 @@
     throw new BooleanConversionAssertionError();
 
 void booleanConversionFailed(obj) {
-  if (obj == null) {
-    _throwBooleanConversionError();
-  }
-  var actual = getReifiedType(obj);
-  var expected = JS('', '#', bool);
-  throw new TypeErrorImplementation.fromMessage(
-      "type '${typeName(actual)}' is not a subtype of "
-      "type '${typeName(expected)}' in boolean expression");
-}
-
-castError(obj, type, bool isExplicit) {
-  var objType = getReifiedType(obj);
-  if (JS('bool', '!dart.__ignoreAllErrors')) {
-    var errorInStrongMode = isSubtype(objType, type) == null;
-
-    var actual = typeName(objType);
-    var expected = typeName(type);
-    if (JS('bool', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
-
-    var error = JS('bool', '#', isExplicit)
-        ? new TypeErrorImplementation(obj, actual, expected, errorInStrongMode)
-        : new CastErrorImplementation(obj, actual, expected, errorInStrongMode);
-    throw error;
-  }
-  JS('', 'console.error(#)',
-      'Actual: ${typeName(objType)} Expected: ${typeName(type)}');
-  return obj;
+  var actual = typeName(getReifiedType(test(obj)));
+  throw new TypeErrorImpl(
+      "type '$actual' is not a 'bool' in boolean expression");
 }
 
 asInt(obj) {
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
index ea298ee..fd62cd8 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/runtime.dart
@@ -14,14 +14,10 @@
     show
         AssertionErrorImpl,
         BooleanConversionAssertionError,
-        CastErrorImplementation,
+        CastErrorImpl,
         DartIterator,
         getTraceFromException,
-        Primitives,
-        TypeErrorImplementation,
-        StrongModeCastError,
-        StrongModeErrorImplementation,
-        StrongModeTypeError,
+        TypeErrorImpl,
         JsLinkedHashMap,
         ImmutableMap,
         PrivateSymbol,
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 48b35b0..c7a40c5 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
@@ -66,7 +66,7 @@
   check_T(object) => cast(object, this, true);
 }
 
-class Dynamic extends TypeRep {
+class DynamicType extends TypeRep {
   toString() => 'dynamic';
 
   @JSExportName('is')
@@ -165,26 +165,26 @@
 }
 
 @JSExportName('dynamic')
-final _dynamic = new Dynamic();
+final _dynamic = new DynamicType();
 
-class Void extends TypeRep {
+class VoidType extends TypeRep {
   toString() => 'void';
 }
 
 @JSExportName('void')
-final void_ = new Void();
+final void_ = new VoidType();
 
-class Bottom extends TypeRep {
+class BottomType extends TypeRep {
   toString() => 'bottom';
 }
 
-final bottom = new Bottom();
+final bottom = new BottomType();
 
-class JSObject extends TypeRep {
+class JSObjectType extends TypeRep {
   toString() => 'NativeJavaScriptObject';
 }
 
-final jsobject = new JSObject();
+final jsobject = new JSObjectType();
 
 class WrappedType extends Type {
   final _wrappedType;
@@ -348,6 +348,25 @@
 
   toString() => name;
 
+  int get requiredParameterCount => args.length;
+  int get positionalParameterCount => args.length + optionals.length;
+
+  getPositionalParameter(int i) {
+    int n = args.length;
+    return i < n ? args[i] : optionals[i + n];
+  }
+
+  Map<String, Object> getNamedParameters() {
+    var result = <String, Object>{};
+    var names = getOwnPropertyNames(named);
+    JS('', '#.sort()', names);
+    for (var i = 0; JS('bool', '# < #.length', i, names); ++i) {
+      String name = JS('!', '#[#]', names, i);
+      result[name] = JS('', '#[#]', named, name);
+    }
+    return result;
+  }
+
   get name {
     if (_stringValue != null) return _stringValue;
 
@@ -490,29 +509,7 @@
 
   List<TypeVariable> get typeFormals {
     if (_typeFormals != null) return _typeFormals;
-
-    // Extract parameter names from the function parameters.
-    //
-    // This is not robust in general for user-defined JS functions, but it
-    // should handle the functions generated by our compiler.
-    //
-    // TODO(jmesserly): names of TypeVariables are only used for display
-    // purposes, such as when an error happens or if someone calls
-    // `Type.toString()`. So we could recover them lazily rather than eagerly.
-    // Alternatively we could synthesize new names.
-    String str = JS('!', '#.toString()', _instantiateTypeParts);
-    var hasParens = str[0] == '(';
-    var end = str.indexOf(hasParens ? ')' : '=>');
-    if (hasParens) {
-      _typeFormals = str
-          .substring(1, end)
-          .split(',')
-          .map((n) => new TypeVariable(n.trim()))
-          .toList();
-    } else {
-      _typeFormals = [new TypeVariable(str.substring(0, end).trim())];
-    }
-    return _typeFormals;
+    return _typeFormals = _typeFormalsFromFunction(_instantiateTypeParts);
   }
 
   checkBounds(List typeArgs) {
@@ -658,6 +655,30 @@
   }
 }
 
+List<TypeVariable> _typeFormalsFromFunction(Object typeConstructor) {
+  // Extract parameter names from the function parameters.
+  //
+  // This is not robust in general for user-defined JS functions, but it
+  // should handle the functions generated by our compiler.
+  //
+  // TODO(jmesserly): names of TypeVariables are only used for display
+  // purposes, such as when an error happens or if someone calls
+  // `Type.toString()`. So we could recover them lazily rather than eagerly.
+  // Alternatively we could synthesize new names.
+  String str = JS('!', '#.toString()', typeConstructor);
+  var hasParens = str[0] == '(';
+  var end = str.indexOf(hasParens ? ')' : '=>');
+  if (hasParens) {
+    return str
+        .substring(1, end)
+        .split(',')
+        .map((n) => new TypeVariable(n.trim()))
+        .toList();
+  } else {
+    return [new TypeVariable(str.substring(0, end).trim())];
+  }
+}
+
 Typedef typedef(name, AbstractFunctionType Function() closure) =>
     new Typedef(name, closure);
 
@@ -735,7 +756,7 @@
 /// If [isCovariant] is true, then we are checking subtyping in a covariant
 /// 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('', '''(() => {
+_isFunctionSubtype(ft1, ft2, isCovariant) => JS('', '''(() => {
   let ret1 = $ft1.returnType;
   let ret2 = $ft2.returnType;
 
@@ -838,28 +859,28 @@
 }
 
 bool _isFutureOr(type) =>
-    JS('bool', '# === #', getGenericClass(type), getGenericClass(FutureOr));
+    identical(getGenericClass(type), getGenericClass(FutureOr));
 
 bool _isSubtype(t1, t2, isCovariant) => JS('', '''(() => {
   if ($t1 === $t2) return true;
 
   // Trivially true.
-  if ($_isTop($t2) || $_isBottom($t1)) {
+  if (${_isTop(t2)} || ${_isBottom(t1)}) {
     return true;
   }
 
   // Trivially false.
-  if ($_isBottom($t2)) return null;
-  if ($_isTop($t1)) {
+  if (${_isBottom(t2)}) return null;
+  if (${_isTop(t1)}) {
     if ($t1 === $dynamic) return null;
     return false;
   }
 
   // Handle FutureOr<T> union type.
-  if ($_isFutureOr($t1)) {
-    let t1TypeArg = $getGenericArgs($t1)[0];
-    if ($_isFutureOr($t2)) {
-      let t2TypeArg = $getGenericArgs($t2)[0];
+  if (${_isFutureOr(t1)}) {
+    let t1TypeArg = ${getGenericArgs(t1)}[0];
+    if (${_isFutureOr(t2)}) {
+      let t2TypeArg = ${getGenericArgs(t2)}[0];
       // FutureOr<A> <: FutureOr<B> iff A <: B
       return $_isSubtype(t1TypeArg, t2TypeArg, $isCovariant);
     }
@@ -874,8 +895,8 @@
   if ($_isFutureOr($t2)) {
     // given t2 is Future<A> | A, then:
     // t1 <: (Future<A> | A) iff t1 <: Future<A> or t1 <: A
-    let t2TypeArg = $getGenericArgs($t2)[0];
-    var t2Future = ${getGenericClass(Future)}(t2TypeArg);
+    let t2TypeArg = ${getGenericArgs(t2)}[0];
+    let t2Future = ${getGenericClass(Future)}(t2TypeArg);
     let s1 = $_isSubtype($t1, t2Future, $isCovariant);
     let s2 = $_isSubtype($t1, t2TypeArg, $isCovariant);
     if (s1 === true || s2 === true) return true;
@@ -899,7 +920,7 @@
     if ($t1 === $jsobject && $t2 instanceof $AnonymousJSType) return true;
 
     // Compare two interface types:
-    return $isClassSubType($t1, $t2, $isCovariant);
+    return ${_isInterfaceSubtype(t1, t2, isCovariant)};
   }
 
   // Function subtyping.
@@ -953,10 +974,10 @@
   }
 
   // Handle non-generic functions.
-  return $isFunctionSubtype($t1, $t2, $isCovariant);
+  return ${_isFunctionSubtype(t1, t2, isCovariant)};
 })()''');
 
-isClassSubType(t1, t2, isCovariant) => JS('', '''(() => {
+_isInterfaceSubtype(t1, t2, isCovariant) => JS('', '''(() => {
   // We support Dart's covariant generics with the caveat that we do not
   // substitute bottom for dynamic in subtyping rules.
   // I.e., given T1, ..., Tn where at least one Ti != dynamic we disallow:
@@ -1006,7 +1027,7 @@
 
   let indefinite = false;
   function definitive(t1, t2) {
-    let result = $isClassSubType(t1, t2, $isCovariant);
+    let result = $_isInterfaceSubtype(t1, t2, $isCovariant);
     if (result == null) {
       indefinite = true;
       return false;
@@ -1050,73 +1071,373 @@
   if (typeArguments.isEmpty) {
     throw new ArgumentError('Cannot extract from non-generic type ($type).');
   }
-  List typeArgs = _extractTypes(getReifiedType(instance), type, typeArguments);
+  var supertype = _getMatchingSupertype(getReifiedType(instance), type);
   // The signature of this method guarantees that instance is a T, so we
   // should have a valid non-empty list at this point.
+  assert(supertype != null);
+  var typeArgs = getGenericArgs(supertype);
   assert(typeArgs != null && typeArgs.isNotEmpty);
   return dgcall(f, typeArgs, []);
 }
 
-// Let t2 = T<T1, ..., Tn>
-// If t1 </: T<T1, ..., Tn>
-// - return null
-// If t1 <: T<T1, ..., Tn>
-// - return [S1, ..., Sn] such that there exists no Ri where
-//   Ri != Si && Ri <: Si && t1 <: T<S1, ..., Ri, ..., Sn>
-//
-// Note: In Dart 1, there isn't necessarily a unique solution to the above -
-// t1 <: Foo<int> and t1 <: Foo<String> could both be true.  Dart 2 will
-// statically disallow.  Until then, this could return either [int] or
-// [String] depending on which it hits first.
-//
-// TODO(vsm): Consider merging with similar isClassSubType logic.
-List _extractTypes(Type t1, Type t2, List typeArguments2) => JS('', '''(() => {
-  if ($t1 == $t2) return typeArguments2;
+/// Infers type variables based on a series of [trySubtypeMatch] calls, followed
+/// by [getInferredTypes] to return the type.
+class _TypeInferrer {
+  final Map<TypeVariable, TypeConstraint> _typeVariables;
 
-  if ($t1 == $Object) return null;
+  /// Creates a [TypeConstraintGatherer] which is prepared to gather type
+  /// constraints for the given type parameters.
+  _TypeInferrer(Iterable<TypeVariable> typeVariables)
+      : _typeVariables = new Map.fromIterables(
+            typeVariables, typeVariables.map((_) => new TypeConstraint()));
 
-  // If t1 is a JS Object, we may not hit core.Object.
-  if ($t1 == null) return null;
-
-  // Check if t1 and t2 have the same raw type.  If so, check covariance on
-  // type parameters.
-  let raw1 = $getGenericClass($t1);
-  let raw2 = $getGenericClass($t2);
-  if (raw1 != null && raw1 == raw2) {
-    let typeArguments1 = $getGenericArgs($t1);
-    let length = typeArguments1.length;
-    if (length == 0 || length != typeArguments2.length) $assertFailed();
-    // TODO(vsm): Remove this subtyping check if/when we eliminate the ability
-    // to implement multiple versions of the same interface
-    // (e.g., Foo<int>, Foo<String>).
-    for (let i = 0; i < length; ++i) {
-      let result =
-          $_isSubtype(typeArguments1[i], typeArguments2[i], true);
-      if (!result) {
+  /// Returns the inferred types based on the current constraints.
+  List<Object> getInferredTypes() {
+    var result = new List<Object>();
+    for (var constraint in _typeVariables.values) {
+      // Prefer the known bound, if any.
+      if (constraint.lower != null) {
+        result.add(constraint.lower);
+      } else if (constraint.upper != null) {
+        result.add(constraint.upper);
+      } else {
         return null;
       }
     }
-    return typeArguments1;
+    return result;
   }
 
-  var result = $_extractTypes($t1.__proto__, $t2, $typeArguments2);
-  if (result) return result;
+  /// Tries to match [subtype] against [supertype].
+  ///
+  /// If the match succeeds, the resulting type constraints are recorded for
+  /// later use by [computeConstraints].  If the match fails, the set of type
+  /// constraints is unchanged.
+  bool trySubtypeMatch(Object subtype, Object supertype) =>
+      _isSubtypeMatch(subtype, supertype);
+
+  void _constrainLower(TypeVariable parameter, Object lower) {
+    _typeVariables[parameter]._constrainLower(lower);
+  }
+
+  void _constrainUpper(TypeVariable parameter, Object upper) {
+    _typeVariables[parameter]._constrainUpper(upper);
+  }
+
+  bool _isFunctionSubtypeMatch(FunctionType subtype, FunctionType supertype) {
+    // A function type `(M0,..., Mn, [M{n+1}, ..., Mm]) -> R0` is a subtype
+    // match for a function type `(N0,..., Nk, [N{k+1}, ..., Nr]) -> R1` with
+    // respect to `L` under constraints `C0 + ... + Cr + C`
+    // - If `R0` is a subtype match for a type `R1` with respect to `L` under
+    //   constraints `C`:
+    // - If `n <= k` and `r <= m`.
+    // - And for `i` in `0...r`, `Ni` is a subtype match for `Mi` with respect
+    //   to `L` under constraints `Ci`.
+    // Function types with named parameters are treated analogously to the
+    // positional parameter case above.
+    // A generic function type `<T0 extends B0, ..., Tn extends Bn>F0` is a
+    // subtype match for a generic function type `<S0 extends B0, ..., Sn
+    // extends Bn>F1` with respect to `L` under constraints `Cl`:
+    // - If `F0[Z0/T0, ..., Zn/Tn]` is a subtype match for `F0[Z0/S0, ...,
+    //   Zn/Sn]` with respect to `L` under constraints `C`, where each `Zi` is a
+    //   fresh type variable with bound `Bi`.
+    // - And `Cl` is `C` with each constraint replaced with its closure with
+    //   respect to `[Z0, ..., Zn]`.
+    if (subtype.requiredParameterCount > supertype.requiredParameterCount) {
+      return false;
+    }
+    if (subtype.positionalParameterCount < supertype.positionalParameterCount) {
+      return false;
+    }
+    // Test the return types.
+    if (supertype.returnType is! VoidType &&
+        !_isSubtypeMatch(subtype.returnType, supertype.returnType)) {
+      return false;
+    }
+
+    // Test the parameter types.
+    for (int i = 0, n = supertype.positionalParameterCount; i < n; ++i) {
+      if (!_isSubtypeMatch(supertype.getPositionalParameter(i),
+          subtype.getPositionalParameter(i))) {
+        return false;
+      }
+    }
+    var supertypeNamed = supertype.getNamedParameters();
+    var subtypeNamed = supertype.getNamedParameters();
+    for (var name in supertypeNamed.keys) {
+      var subtypeParamType = subtypeNamed[name];
+      if (subtypeParamType == null) return false;
+      if (!_isSubtypeMatch(supertypeNamed[name], subtypeParamType)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  bool _isInterfaceSubtypeMatch(Object subtype, Object supertype) {
+    // A type `P<M0, ..., Mk>` is a subtype match for `P<N0, ..., Nk>` with
+    // respect to `L` under constraints `C0 + ... + Ck`:
+    // - If `Mi` is a subtype match for `Ni` with respect to `L` under
+    //   constraints `Ci`.
+    // A type `P<M0, ..., Mk>` is a subtype match for `Q<N0, ..., Nj>` with
+    // respect to `L` under constraints `C`:
+    // - If `R<B0, ..., Bj>` is the superclass of `P<M0, ..., Mk>` and `R<B0,
+    //   ..., Bj>` is a subtype match for `Q<N0, ..., Nj>` with respect to `L`
+    //   under constraints `C`.
+    // - Or `R<B0, ..., Bj>` is one of the interfaces implemented by `P<M0, ...,
+    //   Mk>` (considered in lexical order) and `R<B0, ..., Bj>` is a subtype
+    //   match for `Q<N0, ..., Nj>` with respect to `L` under constraints `C`.
+    // - Or `R<B0, ..., Bj>` is a mixin into `P<M0, ..., Mk>` (considered in
+    //   lexical order) and `R<B0, ..., Bj>` is a subtype match for `Q<N0, ...,
+    //   Nj>` with respect to `L` under constraints `C`.
+
+    // Note that since kernel requires that no class may only appear in the set
+    // of supertypes of a given type more than once, the order of the checks
+    // above is irrelevant; we just need to find the matched superclass,
+    // substitute, and then iterate through type variables.
+    var matchingSupertype = _getMatchingSupertype(subtype, supertype);
+    if (matchingSupertype == null) return false;
+
+    var matchingTypeArgs = getGenericArgs(matchingSupertype);
+    var supertypeTypeArgs = getGenericArgs(supertype);
+    for (int i = 0; i < supertypeTypeArgs.length; i++) {
+      if (!_isSubtypeMatch(matchingTypeArgs[i], supertypeTypeArgs[i])) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  bool _isNull(Object type) => identical(type, unwrapType(Null));
+
+  /// Attempts to match [subtype] as a subtype of [supertype], gathering any
+  /// constraints discovered in the process.
+  ///
+  /// If a set of constraints was found, `true` is returned and the caller
+  /// may proceed to call [computeConstraints].  Otherwise, `false` is returned.
+  ///
+  /// In the case where `false` is returned, some bogus constraints may have
+  /// been added to [_protoConstraints].  It is the caller's responsibility to
+  /// discard them if necessary.
+  bool _isSubtypeMatch(Object subtype, Object supertype) {
+    // A type variable `T` in `L` is a subtype match for any type schema `Q`:
+    // - Under constraint `T <: Q`.
+    if (subtype is TypeVariable && _typeVariables.containsKey(subtype)) {
+      _constrainUpper(subtype, supertype);
+      return true;
+    }
+    // A type schema `Q` is a subtype match for a type variable `T` in `L`:
+    // - Under constraint `Q <: T`.
+    if (supertype is TypeVariable && _typeVariables.containsKey(supertype)) {
+      _constrainLower(supertype, subtype);
+      return true;
+    }
+    // Any two equal types `P` and `Q` are subtype matches under no constraints.
+    // Note: to avoid making the algorithm quadratic, we just check for
+    // identical().  If P and Q are equal but not identical, recursing through
+    // the types will give the proper result.
+    if (identical(subtype, supertype)) return true;
+    // Any type `P` is a subtype match for `dynamic`, `Object`, or `void` under
+    // no constraints.
+    if (_isTop(supertype)) return true;
+    // `Null` is a subtype match for any type `Q` under no constraints.
+    // Note that nullable types will change this.
+    if (_isNull(subtype)) return true;
+
+    // Handle FutureOr<T> union type.
+    if (_isFutureOr(subtype)) {
+      var subtypeArg = getGenericArgs(subtype)[0];
+      if (_isFutureOr(supertype)) {
+        // `FutureOr<P>` is a subtype match for `FutureOr<Q>` with respect to `L`
+        // under constraints `C`:
+        // - If `P` is a subtype match for `Q` with respect to `L` under constraints
+        //   `C`.
+        var supertypeArg = getGenericArgs(supertype)[0];
+        return _isSubtypeMatch(subtypeArg, supertypeArg);
+      }
+
+      // `FutureOr<P>` is a subtype match for `Q` with respect to `L` under
+      // constraints `C0 + C1`:
+      // - If `Future<P>` is a subtype match for `Q` with respect to `L` under
+      //   constraints `C0`.
+      // - And `P` is a subtype match for `Q` with respect to `L` under
+      //   constraints `C1`.
+      var subtypeFuture = JS('!', '#(#)', getGenericClass(Future), subtypeArg);
+      return _isSubtypeMatch(subtypeFuture, supertype) &&
+          _isSubtypeMatch(subtypeArg, supertype);
+    }
+
+    if (_isFutureOr(supertype)) {
+      // `P` is a subtype match for `FutureOr<Q>` with respect to `L` under
+      // constraints `C`:
+      // - If `P` is a subtype match for `Future<Q>` with respect to `L` under
+      //   constraints `C`.
+      // - Or `P` is not a subtype match for `Future<Q>` with respect to `L` under
+      //   constraints `C`
+      //   - And `P` is a subtype match for `Q` with respect to `L` under
+      //     constraints `C`
+      var supertypeArg = getGenericArgs(supertype)[0];
+      var supertypeFuture =
+          JS('!', '#(#)', getGenericClass(Future), supertypeArg);
+      return _isSubtypeMatch(subtype, supertypeFuture) ||
+          _isSubtypeMatch(subtype, supertypeArg);
+    }
+
+    // A type variable `T` not in `L` with bound `P` is a subtype match for the
+    // same type variable `T` with bound `Q` with respect to `L` under
+    // constraints `C`:
+    // - If `P` is a subtype match for `Q` with respect to `L` under constraints
+    //   `C`.
+    if (subtype is TypeVariable) {
+      return supertype is TypeVariable && identical(subtype, supertype);
+    }
+    if (subtype is GenericFunctionType) {
+      if (supertype is GenericFunctionType) {
+        // Given generic functions g1 and g2, g1 <: g2 iff:
+        //
+        //     g1<TFresh> <: g2<TFresh>
+        //
+        // where TFresh is a list of fresh type variables that both g1 and g2 will
+        // be instantiated with.
+        var formalCount = subtype.formalCount;
+        if (formalCount != supertype.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 to avoid capture because it does not depend on its
+        // TypeVariable objects, rather it uses JS function parameters to ensure
+        // correct binding.
+        var fresh = supertype.typeFormals;
+
+        // Check the bounds of the type parameters of g1 and g2.
+        // given a type parameter `T1 extends U1` from g1, and a type parameter
+        // `T2 extends U2` from g2, we must ensure that:
+        //
+        //      U2 <: U1
+        //
+        // (Note the reversal of direction -- type formal bounds are
+        // contravariant, similar to the function's formal parameter types).
+        //
+        var t1Bounds = subtype.instantiateTypeBounds(fresh);
+        var t2Bounds = supertype.instantiateTypeBounds(fresh);
+        // TODO(jmesserly): we could optimize for the common case of no bounds.
+        for (var i = 0; i < formalCount; i++) {
+          if (!_isSubtypeMatch(t2Bounds[i], t1Bounds[i])) {
+            return false;
+          }
+        }
+        return _isFunctionSubtypeMatch(
+            subtype.instantiate(fresh), supertype.instantiate(fresh));
+      } else {
+        return false;
+      }
+    } else if (supertype is GenericFunctionType) {
+      return false;
+    }
+
+    // A type `P` is a subtype match for `Function` with respect to `L` under no
+    // constraints:
+    // - If `P` implements a call method.
+    // - Or if `P` is a function type.
+    // TODO(paulberry): implement this case.
+    // A type `P` is a subtype match for a type `Q` with respect to `L` under
+    // constraints `C`:
+    // - If `P` is an interface type which implements a call method of type `F`,
+    //   and `F` is a subtype match for a type `Q` with respect to `L` under
+    //   constraints `C`.
+    // TODO(paulberry): implement this case.
+    if (subtype is FunctionType) {
+      if (supertype is! FunctionType) {
+        if (identical(supertype, unwrapType(Function)) ||
+            identical(supertype, unwrapType(Object))) {
+          return true;
+        } else {
+          return false;
+        }
+      }
+      if (supertype is FunctionType) {
+        return _isFunctionSubtypeMatch(subtype, supertype);
+      }
+    }
+    return _isInterfaceSubtypeMatch(subtype, supertype);
+  }
+
+  bool _isTop(Object type) =>
+      identical(type, _dynamic) ||
+      identical(type, void_) ||
+      identical(type, unwrapType(Object));
+}
+
+/// A constraint on a type parameter that we're inferring.
+class TypeConstraint {
+  /// The lower bound of the type being constrained.  This bound must be a
+  /// subtype of the type being constrained.
+  Object lower;
+
+  /// The upper bound of the type being constrained.  The type being constrained
+  /// must be a subtype of this bound.
+  Object upper;
+
+  void _constrainLower(Object type) {
+    if (lower != null) {
+      if (isSubtype(lower, type)) {
+        // nothing to do, existing lower bound is lower than the new one.
+        return;
+      }
+      if (!isSubtype(type, lower)) {
+        // Neither bound is lower and we don't have GLB, so use bottom type.
+        type = unwrapType(Null);
+      }
+    }
+    lower = type;
+  }
+
+  void _constrainUpper(Object type) {
+    if (upper != null) {
+      if (isSubtype(type, upper)) {
+        // nothing to do, existing upper bound is higher than the new one.
+        return;
+      }
+      if (!isSubtype(upper, type)) {
+        // Neither bound is higher and we don't have LUB, so use top type.
+        type = unwrapType(Object);
+      }
+    }
+    upper = type;
+  }
+
+  String toString() => '${typeName(lower)} <: <type> <: ${typeName(upper)}';
+}
+
+/// Finds a supertype of [subtype] that matches the class [supertype], but may
+/// contain different generic type arguments.
+Object _getMatchingSupertype(Object subtype, Object supertype) {
+  if (identical(subtype, supertype)) return supertype;
+  if (subtype == null || subtype == unwrapType(Object)) return null;
+
+  var subclass = getGenericClass(subtype);
+  var superclass = getGenericClass(supertype);
+  if (subclass != null && identical(subclass, superclass)) {
+    return subtype; // matching supertype found!
+  }
+
+  var result = _getMatchingSupertype(JS('', '#.__proto__', subtype), supertype);
+  if (result != null) return result;
 
   // Check mixin.
-  let m1 = $getMixin($t1);
-  if (m1 != null) {
-    result = $_extractTypes(m1, $t2, $typeArguments2);
-    if (result) return result;
+  var mixin = getMixin(subtype);
+  if (mixin != null) {
+    result = _getMatchingSupertype(mixin, supertype);
+    if (result != null) return result;
   }
 
   // Check interfaces.
-  let getInterfaces = $getImplements($t1);
-  if (getInterfaces) {
-    for (let i1 of getInterfaces()) {
-      result = $_extractTypes(i1, $t2, $typeArguments2);
-      if (result) return result;
+  var getInterfaces = getImplements(subtype);
+  if (getInterfaces != null) {
+    for (var iface in getInterfaces()) {
+      result = _getMatchingSupertype(iface, supertype);
+      if (result != null) return result;
     }
   }
 
   return null;
-})()''');
+}
diff --git a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
index d913dfa..87b3cbb 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/ddc_runtime/utils.dart
@@ -40,7 +40,7 @@
 /// assertion failure (TypeError) or CastError.
 void throwTypeError(String message) {
   if (JS('bool', 'dart.__trapRuntimeErrors')) JS('', 'debugger');
-  throw new TypeErrorImplementation.fromMessage(message);
+  throw new TypeErrorImpl(message);
 }
 
 /// This error indicates a bug in the runtime or the compiler.
diff --git a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
index abcf157..3cac8a5 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_array.dart
@@ -66,12 +66,10 @@
     }
   }
 
-  List<R> cast<R>() {
-    List<Object> self = this;
-    return self is List<R> ? self : List.castFrom<E, R>(this);
-  }
+  List<R> cast<R>() => List.castFrom<E, R>(this);
 
-  List<R> retype<R>() => List.castFrom<E, R>(this);
+  @Deprecated("Use cast instead.")
+  List<R> retype<R>() => cast<R>();
 
   void add(E value) {
     checkGrowable('add');
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 e7e7bd6..738db86 100644
--- a/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
+++ b/pkg/dev_compiler/tool/input_sdk/private/js_helper.dart
@@ -737,46 +737,25 @@
 // TODO(lrn): These exceptions should be implemented in core.
 // When they are, remove the 'Implementation' here.
 
-/** Thrown by type assertions that fail. */
-class TypeErrorImplementation extends Error implements TypeError {
+/// Thrown by type assertions that fail.
+class TypeErrorImpl extends Error implements TypeError {
   final String message;
 
-  /**
-   * Normal type error caused by a failed subtype test.
-   */
-  // TODO(sra): Include [value] in message.
-  TypeErrorImplementation(Object value, Object actualType, Object expectedType,
-      bool strongModeError)
-      : message = "Type '${actualType}' is not a subtype "
-            "of type '${expectedType}'" +
-            (strongModeError ? " in strong mode" : "");
-
-  TypeErrorImplementation.fromMessage(String this.message);
+  TypeErrorImpl(this.message);
 
   String toString() => message;
 }
 
-/** Thrown by the 'as' operator if the cast isn't valid. */
-class CastErrorImplementation extends Error implements CastError {
-  // TODO(lrn): Rename to CastError (and move implementation into core).
+/// Thrown by the 'as' operator if the cast isn't valid.
+class CastErrorImpl extends Error implements CastError {
   final String message;
 
-  /**
-   * Normal cast error caused by a failed type cast.
-   */
-  // TODO(sra): Include [value] in message.
-  CastErrorImplementation(Object value, Object actualType, Object expectedType,
-      bool strongModeError)
-      : message = "CastError: Casting value of type '$actualType' to"
-            " type '$expectedType' which is incompatible" +
-            (strongModeError ? " in strong mode": "");
+  CastErrorImpl(this.message);
 
   String toString() => message;
 }
 
-
 class FallThroughErrorImplementation extends FallThroughError {
-  FallThroughErrorImplementation();
   String toString() => "Switch case fall-through.";
 }
 
diff --git a/pkg/front_end/lib/src/base/instrumentation.dart b/pkg/front_end/lib/src/base/instrumentation.dart
index 4f537c7..c87b07e 100644
--- a/pkg/front_end/lib/src/base/instrumentation.dart
+++ b/pkg/front_end/lib/src/base/instrumentation.dart
@@ -46,9 +46,6 @@
     var buffer = new StringBuffer();
     void writeParameter(VariableDeclaration parameter) {
       var covariances = <String>[];
-      if (parameter.isGenericCovariantInterface) {
-        covariances.add('genericInterface');
-      }
       if (parameter.isGenericCovariantImpl) {
         covariances.add('genericImpl');
       }
@@ -91,9 +88,6 @@
         if (i != 0) buffer.write(', ');
         var typeParameter = function.typeParameters[i];
         var covariances = <String>[];
-        if (typeParameter.isGenericCovariantInterface) {
-          covariances.add('genericInterface');
-        }
         if (typeParameter.isGenericCovariantImpl) {
           covariances.add('genericImpl');
         }
diff --git a/pkg/front_end/lib/src/fasta/dill/built_type_builder.dart b/pkg/front_end/lib/src/fasta/dill/built_type_builder.dart
deleted file mode 100644
index 3b170eb..0000000
--- a/pkg/front_end/lib/src/fasta/dill/built_type_builder.dart
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library fasta.built_type_builder;
-
-import 'package:kernel/ast.dart' show DartType, Supertype;
-
-import '../kernel/kernel_builder.dart'
-    show KernelTypeBuilder, LibraryBuilder, TypeBuilder;
-
-import '../problems.dart' show unimplemented, unsupported;
-
-class BuiltTypeBuilder extends KernelTypeBuilder {
-  final DartType builtType;
-
-  BuiltTypeBuilder(this.builtType);
-
-  DartType build(LibraryBuilder library) => builtType;
-
-  Supertype buildSupertype(
-      LibraryBuilder library, int charOffset, Uri fileUri) {
-    return unimplemented("buildSupertype", -1, null);
-  }
-
-  Supertype buildMixedInType(
-      LibraryBuilder library, int charOffset, Uri fileUri) {
-    return unimplemented("buildMixedInType", -1, null);
-  }
-
-  buildInvalidType(int charOffset, Uri fileUri) {
-    return unimplemented("buildInvalidType", -1, null);
-  }
-
-  String get debugName => "BuiltTypeBuilder";
-
-  StringBuffer printOn(StringBuffer buffer) {
-    return buffer..write(builtType.toString());
-  }
-
-  String get name {
-    return unimplemented("name", -1, null);
-  }
-
-  BuiltTypeBuilder clone(List<TypeBuilder> newTypes) {
-    return unsupported("clone", -1, null);
-  }
-}
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 02d9745..252270f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -62,10 +62,6 @@
 
 import 'constness.dart' show Constness;
 
-import 'fangorn.dart' show Fangorn;
-
-import 'forest.dart' show Forest;
-
 import 'frontend_accessors.dart' show buildIsNull;
 
 import 'redirecting_factory_body.dart'
@@ -81,15 +77,18 @@
 
 import 'kernel_api.dart';
 
-import 'kernel_ast_api.dart';
+import 'kernel_ast_api.dart' hide Expression, Statement;
+
+import 'kernel_ast_api.dart' as kernel show Expression, Statement;
 
 import 'kernel_builder.dart';
 
 // TODO(ahe): Remove this and ensure all nodes have a location.
 const noLocation = null;
 
-class BodyBuilder<Arguments> extends ScopeListener<JumpTarget>
-    implements BuilderHelper<Arguments> {
+abstract class BodyBuilder<Expression, Statement, Arguments>
+    extends ScopeListener<JumpTarget>
+    implements BuilderHelper<Expression, Statement, Arguments> {
   @override
   final KernelLibraryBuilder library;
 
@@ -162,9 +161,9 @@
 
   int functionNestingLevel = 0;
 
-  Statement compileTimeErrorInTry;
+  kernel.Statement compileTimeErrorInTry;
 
-  Statement compileTimeErrorInLoopOrSwitch;
+  kernel.Statement compileTimeErrorInLoopOrSwitch;
 
   Scope switchScope;
 
@@ -182,10 +181,6 @@
   /// and where that was.
   Map<String, int> initializedFields;
 
-  // TODO(ahe): Update type parameters.
-  @override
-  Forest<dynamic, dynamic, Token, dynamic> forest;
-
   BodyBuilder(
       KernelLibraryBuilder library,
       this.member,
@@ -196,8 +191,7 @@
       this.classBuilder,
       this.isInstanceMember,
       this.uri,
-      this._typeInferrer,
-      [this.forest = const Fangorn()])
+      this._typeInferrer)
       : enclosingScope = scope,
         library = library,
         enableNative =
@@ -238,7 +232,7 @@
   @override
   Expression toValue(Object node) {
     if (node is FastaAccessor) {
-      return node.buildSimpleRead();
+      return toExpression(node.buildSimpleRead());
     } else if (node is Expression) {
       return node;
     } else if (node is PrefixBuilder) {
@@ -255,7 +249,7 @@
   }
 
   Expression toEffect(Object node) {
-    if (node is FastaAccessor) return node.buildForEffect();
+    if (node is FastaAccessor) return toExpression(node.buildForEffect());
     return toValue(node);
   }
 
@@ -278,13 +272,13 @@
   }
 
   Block popBlock(int count, Token beginToken) {
-    List<dynamic /*Statement | List<Statement>*/ > statements =
-        popList(count) ?? <Statement>[];
-    List<Statement> copy;
+    List<dynamic /*kernel.Statement | List<kernel.Statement>*/ > statements =
+        popList(count) ?? <kernel.Statement>[];
+    List<kernel.Statement> copy;
     for (int i = 0; i < statements.length; i++) {
       var statement = statements[i];
       if (statement is List) {
-        copy ??= new List<Statement>.from(statements.getRange(0, i));
+        copy ??= new List<kernel.Statement>.from(statements.getRange(0, i));
         // TODO(sigmund): remove this assignment (issue #28651)
         Iterable subStatements = statement;
         copy.addAll(subStatements);
@@ -296,16 +290,16 @@
       ..fileOffset = offsetForToken(beginToken);
   }
 
-  Statement popStatementIfNotNull(Object value) {
+  kernel.Statement popStatementIfNotNull(Object value) {
     return value == null ? null : popStatement();
   }
 
-  Statement popStatement() {
+  kernel.Statement popStatement() {
     var statement = pop();
     if (statement is List) {
-      return new Block(new List<Statement>.from(statement));
+      return new Block(new List<kernel.Statement>.from(statement));
     } else if (statement is VariableDeclaration) {
-      return new Block(<Statement>[statement]);
+      return new Block(<kernel.Statement>[statement]);
     } else {
       return statement;
     }
@@ -327,7 +321,7 @@
           .forEach((String name, Builder builder) {
         if (outerSwitchScope == null) {
           JumpTarget target = builder;
-          for (Statement statement in target.users) {
+          for (kernel.Statement statement in target.users) {
             statement.parent.replaceChild(
                 statement,
                 wrapInCompileTimeErrorStatement(statement,
@@ -349,13 +343,14 @@
     int offset = variable.fileOffset;
     Message message = template.withArguments(name);
     if (variable.initializer == null) {
-      variable.initializer =
-          buildCompileTimeError(message, offset, name.length, context: context)
-            ..parent = variable;
+      variable.initializer = toKernelExpression(
+          buildCompileTimeError(message, offset, name.length, context: context))
+        ..parent = variable;
     } else {
-      variable.initializer = wrapInLocatedCompileTimeError(
-          variable.initializer, message.withLocation(uri, offset, name.length),
-          context: context)
+      variable.initializer = toKernelExpression(wrapInLocatedCompileTimeError(
+          toExpression(variable.initializer),
+          message.withLocation(uri, offset, name.length),
+          context: context))
         ..parent = variable;
     }
   }
@@ -490,7 +485,7 @@
         _typeInferrer.inferFieldInitializer(
             this,
             field.hasTypeInferredFromInitializer ? null : field.builtType,
-            initializer);
+            toKernelExpression(initializer));
       }
     }
     pop(); // Type.
@@ -505,7 +500,7 @@
         field = fields[i].target;
         cloner ??= new CloneVisitor();
         for (Expression annotation in annotations) {
-          field.addAnnotation(cloner.clone(annotation));
+          field.addAnnotation(cloner.clone(toKernelExpression(annotation)));
         }
       }
     }
@@ -549,8 +544,11 @@
                       formal.charOffset),
                   formal.charOffset);
             } else {
-              initializer = buildFieldInitializer(true, formal.name,
-                  formal.charOffset, new VariableGet(formal.declaration));
+              initializer = buildFieldInitializer(
+                  true,
+                  formal.name,
+                  formal.charOffset,
+                  toExpression(new VariableGet(formal.declaration)));
             }
             member.addInitializer(initializer, _typeInferrer);
           }
@@ -605,8 +603,8 @@
       initializer = buildSuperInitializer(
           false,
           node.target,
-          node.arguments
-              as dynamic, // TODO(ahe): Remove this cast when buildSuperInitializer is moved to [Forest].
+          node.arguments as dynamic, // TODO(ahe): Remove this cast when
+          // buildSuperInitializer is moved to [Forest].
           token.charOffset);
     } else {
       Expression value = toValue(node);
@@ -636,7 +634,7 @@
 
   @override
   void finishFunction(List annotations, FormalParameters formals,
-      AsyncMarker asyncModifier, Statement body) {
+      AsyncMarker asyncModifier, kernel.Statement body) {
     debugEvent("finishFunction");
     typePromoter.finished();
 
@@ -652,9 +650,10 @@
             // TODO(ahe): Should store: realParameter.fileOffset
             // https://github.com/dart-lang/sdk/issues/32289
             null);
-        realParameter.initializer = initializer..parent = realParameter;
+        realParameter.initializer = toKernelExpression(initializer)
+          ..parent = realParameter;
         _typeInferrer.inferParameterInitializer(
-            this, initializer, realParameter.type);
+            this, toKernelExpression(initializer), realParameter.type);
       }
     }
 
@@ -674,7 +673,7 @@
         if (builder.formals != null) {
           // Illegal parameters were removed by the function builder.
           // Add them as local variable to put them in scope of the body.
-          List<Statement> statements = <Statement>[];
+          List<kernel.Statement> statements = <kernel.Statement>[];
           for (KernelFormalParameterBuilder parameter in builder.formals) {
             statements.add(parameter.target);
           }
@@ -696,7 +695,7 @@
     Member target = builder.target;
     _typeInferrer.inferMetadata(this, annotations);
     for (Expression annotation in annotations ?? const []) {
-      target.addAnnotation(annotation);
+      target.addAnnotation(toKernelExpression(annotation));
     }
     if (builder is KernelConstructorBuilder) {
       finishConstructor(builder, asyncModifier);
@@ -709,8 +708,8 @@
   }
 
   @override
-  List<Expression> finishMetadata() {
-    List<Expression> expressions = pop();
+  List<kernel.Expression> finishMetadata() {
+    List<kernel.Expression> expressions = pop();
     _typeInferrer.inferMetadata(this, expressions);
     return expressions;
   }
@@ -743,12 +742,13 @@
               .withLocation(uri, eof.charOffset, eof.length));
     }
 
-    ShadowReturnStatement fakeReturn = new ShadowReturnStatement(expression);
+    ShadowReturnStatement fakeReturn =
+        new ShadowReturnStatement(toKernelExpression(expression));
 
     _typeInferrer.inferFunctionBody(
         this, const DynamicType(), AsyncMarker.Sync, fakeReturn);
 
-    return fakeReturn.expression;
+    return toExpression(fakeReturn.expression);
   }
 
   void finishConstructor(
@@ -806,7 +806,7 @@
   @override
   void endExpressionStatement(Token token) {
     debugEvent("ExpressionStatement");
-    push(new ShadowExpressionStatement(popForEffect()));
+    push(new ShadowExpressionStatement(toKernelExpression(popForEffect())));
   }
 
   @override
@@ -824,8 +824,8 @@
         if (i > firstNamedArgumentIndex) {
           arguments[i] = new NamedExpression(
               "#$i",
-              deprecated_buildCompileTimeError(
-                  "Expected named argument.", arguments[i].fileOffset))
+              toKernelExpression(deprecated_buildCompileTimeError(
+                  "Expected named argument.", arguments[i].fileOffset)))
             ..fileOffset = beginToken.charOffset;
         }
       }
@@ -840,9 +840,9 @@
           named = <NamedExpression>[
             new NamedExpression(
                 named[1].name,
-                deprecated_buildCompileTimeError(
+                toKernelExpression(deprecated_buildCompileTimeError(
                     "Duplicated named argument '${named[1].name}'.",
-                    named[1].fileOffset))
+                    named[1].fileOffset)))
           ];
         }
       } else if (named.length > 2) {
@@ -852,9 +852,10 @@
           if (seenNames.containsKey(expression.name)) {
             hasProblem = true;
             var prevNamedExpression = seenNames[expression.name];
-            prevNamedExpression.value = deprecated_buildCompileTimeError(
-                "Duplicated named argument '${expression.name}'.",
-                expression.fileOffset)
+            prevNamedExpression.value = toKernelExpression(
+                deprecated_buildCompileTimeError(
+                    "Duplicated named argument '${expression.name}'.",
+                    expression.fileOffset))
               ..parent = prevNamedExpression;
           } else {
             seenNames[expression.name] = expression;
@@ -873,7 +874,8 @@
   @override
   void handleParenthesizedExpression(Token token) {
     debugEvent("ParenthesizedExpression");
-    push(new ParenthesizedExpression(this, popForValue(), token.endGroup));
+    push(new ParenthesizedExpression(
+        this, toKernelExpression(popForValue()), token.endGroup));
   }
 
   @override
@@ -923,7 +925,7 @@
       expression.extend();
     } else {
       VariableDeclaration variable = new ShadowVariableDeclaration.forValue(
-          expression, functionNestingLevel);
+          toKernelExpression(expression), functionNestingLevel);
       push(new ShadowCascadeExpression(variable));
       push(new VariableAccessor(this, token, variable));
     }
@@ -934,7 +936,7 @@
     debugEvent("endCascade");
     Expression expression = popForEffect();
     ShadowCascadeExpression cascadeReceiver = pop();
-    cascadeReceiver.finalize(expression);
+    cascadeReceiver.finalize(toKernelExpression(expression));
     push(cascadeReceiver);
   }
 
@@ -957,7 +959,8 @@
   void beginBinaryExpression(Token token) {
     if (optional("&&", token) || optional("||", token)) {
       Expression lhs = popForValue();
-      typePromoter.enterLogicalExpression(lhs, token.stringValue);
+      typePromoter.enterLogicalExpression(
+          toKernelExpression(lhs), token.stringValue);
       push(lhs);
     }
   }
@@ -1009,10 +1012,13 @@
   void doLogicalExpression(Token token) {
     Expression argument = popForValue();
     Expression receiver = pop();
-    var logicalExpression =
-        new ShadowLogicalExpression(receiver, token.stringValue, argument)
-          ..fileOffset = offsetForToken(token);
-    typePromoter.exitLogicalExpression(argument, logicalExpression);
+    var logicalExpression = new ShadowLogicalExpression(
+        toKernelExpression(receiver),
+        token.stringValue,
+        toKernelExpression(argument))
+      ..fileOffset = offsetForToken(token);
+    typePromoter.exitLogicalExpression(
+        toKernelExpression(argument), logicalExpression);
     push(logicalExpression);
   }
 
@@ -1020,12 +1026,13 @@
   void doIfNull(Token token) {
     Expression b = popForValue();
     Expression a = popForValue();
-    VariableDeclaration variable = new VariableDeclaration.forValue(a);
+    VariableDeclaration variable =
+        new VariableDeclaration.forValue(toKernelExpression(a));
     push(new ShadowIfNullExpression(
         variable,
         new ConditionalExpression(
             buildIsNull(new VariableGet(variable), offsetForToken(token)),
-            b,
+            toKernelExpression(b),
             new VariableGet(variable),
             null))
       ..fileOffset = offsetForToken(token));
@@ -1122,14 +1129,16 @@
       return buildCompileTimeError(message, charOffset, noLength,
           context: context);
     } else {
-      Expression error = library.loader.instantiateNoSuchMethodError(
-          receiver, name, forest.castArguments(arguments), charOffset,
-          isMethod: !isGetter && !isSetter,
-          isGetter: isGetter,
-          isSetter: isSetter,
-          isStatic: isStatic,
-          isTopLevel: !isStatic && !isSuper);
-      return new ShadowSyntheticExpression(new Throw(error));
+      Expression error = toExpression(library.loader
+          .instantiateNoSuchMethodError(toKernelExpression(receiver), name,
+              forest.castArguments(arguments), charOffset,
+              isMethod: !isGetter && !isSetter,
+              isGetter: isGetter,
+              isSetter: isSetter,
+              isStatic: isStatic,
+              isTopLevel: !isStatic && !isSuper));
+      return toExpression(
+          new ShadowSyntheticExpression(new Throw(toKernelExpression(error))));
     }
   }
 
@@ -1535,7 +1544,9 @@
         if (expressions == null) {
           expressions = parts.sublist(0, i);
         }
-        expressions.addAll(part.expressions);
+        for (kernel.Expression expression in part.expressions) {
+          expressions.add(toExpression(expression));
+        }
       } else {
         if (expressions != null) {
           expressions.add(part);
@@ -1577,7 +1588,7 @@
       push(deprecated_buildCompileTimeErrorStatement(
           "Can't return from a constructor.", beginToken.charOffset));
     } else {
-      push(new ShadowReturnStatement(expression)
+      push(new ShadowReturnStatement(toKernelExpression(expression))
         ..fileOffset = beginToken.charOffset);
     }
   }
@@ -1585,7 +1596,7 @@
   @override
   void beginThenStatement(Token token) {
     Expression condition = popForValue();
-    typePromoter.enterThen(condition);
+    typePromoter.enterThen(toKernelExpression(condition));
     push(condition);
     super.beginThenStatement(token);
   }
@@ -1598,12 +1609,13 @@
 
   @override
   void endIfStatement(Token ifToken, Token elseToken) {
-    Statement elsePart = popStatementIfNotNull(elseToken);
-    Statement thenPart = popStatement();
+    kernel.Statement elsePart = popStatementIfNotNull(elseToken);
+    kernel.Statement thenPart = popStatement();
     Expression condition = pop();
     typePromoter.exitConditional();
-    push(new ShadowIfStatement(condition, thenPart, elsePart)
-      ..fileOffset = ifToken.charOffset);
+    push(
+        new ShadowIfStatement(toKernelExpression(condition), thenPart, elsePart)
+          ..fileOffset = ifToken.charOffset);
   }
 
   @override
@@ -1641,7 +1653,7 @@
     bool isFinal = (currentLocalVariableModifiers & finalMask) != 0;
     assert(isConst == (constantContext == ConstantContext.inferred));
     push(new ShadowVariableDeclaration(identifier.name, functionNestingLevel,
-        initializer: initializer,
+        initializer: toKernelExpression(initializer),
         type: currentLocalVariableType,
         isFinal: isFinal,
         isConst: isConst)
@@ -1699,7 +1711,14 @@
     constantContext = pop();
     currentLocalVariableType = pop();
     currentLocalVariableModifiers = pop();
-    pop(); // Metadata.
+    List<Expression> annotations = pop();
+    if (annotations != null) {
+      for (VariableDeclaration variable in variables) {
+        for (Expression annotation in annotations) {
+          variable.addAnnotation(toKernelExpression(annotation));
+        }
+      }
+    }
     if (variables.length != 1) {
       push(variables);
     } else {
@@ -1731,7 +1750,7 @@
           offsetForToken(token), lengthForToken(token)));
     } else {
       push(new DelayedAssignment(
-          this, token, accessor, value, token.stringValue));
+          this, token, accessor, toKernelExpression(value), token.stringValue));
     }
   }
 
@@ -1747,7 +1766,7 @@
     }
   }
 
-  void exitLoopOrSwitch(Statement statement) {
+  void exitLoopOrSwitch(kernel.Statement statement) {
     if (compileTimeErrorInLoopOrSwitch != null) {
       push(compileTimeErrorInLoopOrSwitch);
       compileTimeErrorInLoopOrSwitch = null;
@@ -1772,7 +1791,7 @@
       return <VariableDeclaration>[];
     } else if (variableOrExpression is Expression) {
       VariableDeclaration variable = new ShadowVariableDeclaration.forEffect(
-          variableOrExpression, functionNestingLevel);
+          toKernelExpression(variableOrExpression), functionNestingLevel);
       return <VariableDeclaration>[variable];
     } else if (variableOrExpression is ExpressionStatement) {
       VariableDeclaration variable = new ShadowVariableDeclaration.forEffect(
@@ -1786,12 +1805,12 @@
   void endForStatement(Token forKeyword, Token leftParen, Token leftSeparator,
       int updateExpressionCount, Token endToken) {
     debugEvent("ForStatement");
-    Statement body = popStatement();
+    kernel.Statement body = popStatement();
     List<Expression> updates = popListForEffect(updateExpressionCount);
-    Statement conditionStatement = popStatement();
+    kernel.Statement conditionStatement = popStatement();
     Expression condition = null;
     if (conditionStatement is ExpressionStatement) {
-      condition = conditionStatement.expression;
+      condition = toExpression(conditionStatement.expression);
     } else {
       assert(conditionStatement is EmptyStatement);
     }
@@ -1809,9 +1828,9 @@
       body = new ShadowLabeledStatement(body);
       continueTarget.resolveContinues(body);
     }
-    Statement result =
-        new ShadowForStatement(variables, condition, updates, body)
-          ..fileOffset = forKeyword.charOffset;
+    kernel.Statement result = new ShadowForStatement(variables,
+        toKernelExpression(condition), toKernelExpressionList(updates), body)
+      ..fileOffset = forKeyword.charOffset;
     if (breakTarget.hasUsers) {
       result = new ShadowLabeledStatement(result);
       breakTarget.resolveBreaks(result);
@@ -1833,7 +1852,7 @@
 
   @override
   void handleLiteralList(
-      int count, Token beginToken, Token constKeyword, Token endToken) {
+      int count, Token leftBracket, Token constKeyword, Token rightBracket) {
     debugEvent("LiteralList");
     List<Expression> expressions = popListForValue(count);
     Object typeArguments = pop();
@@ -1842,8 +1861,8 @@
       if (forest.getTypeCount(typeArguments) > 1) {
         addProblem(
             fasta.messageListLiteralTooManyTypeArguments,
-            offsetForToken(beginToken),
-            lengthOfSpan(beginToken, beginToken.endGroup));
+            offsetForToken(leftBracket),
+            lengthOfSpan(leftBracket, leftBracket.endGroup));
       } else {
         typeArgument = forest.getTypeAt(typeArguments, 0);
         if (library.loader.target.strongMode) {
@@ -1857,9 +1876,9 @@
         constKeyword != null || constantContext == ConstantContext.inferred,
         typeArgument,
         typeArguments,
-        beginToken,
+        leftBracket,
         expressions,
-        endToken));
+        rightBracket));
   }
 
   @override
@@ -1884,7 +1903,7 @@
 
   @override
   void handleLiteralMap(
-      int count, Token beginToken, Token constKeyword, Token endToken) {
+      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
     debugEvent("LiteralMap");
     List entries = forest.mapEntryList(count);
     popList(count, entries);
@@ -1895,8 +1914,8 @@
       if (forest.getTypeCount(typeArguments) != 2) {
         addProblem(
             fasta.messageListLiteralTypeArgumentMismatch,
-            offsetForToken(beginToken),
-            lengthOfSpan(beginToken, beginToken.endGroup));
+            offsetForToken(leftBrace),
+            lengthOfSpan(leftBrace, leftBrace.endGroup));
       } else {
         keyType = forest.getTypeAt(typeArguments, 0);
         valueType = forest.getTypeAt(typeArguments, 1);
@@ -1913,9 +1932,9 @@
         keyType,
         valueType,
         typeArguments,
-        beginToken,
+        leftBrace,
         entries,
-        endToken));
+        rightBrace));
   }
 
   @override
@@ -2057,8 +2076,8 @@
     bool isInverted = not != null;
     Expression isExpression = forest.isExpression(operand, operator, not, type);
     if (operand is VariableGet) {
-      typePromoter.handleIsCheck(isExpression, isInverted, operand.variable,
-          type, functionNestingLevel);
+      typePromoter.handleIsCheck(toKernelExpression(isExpression), isInverted,
+          operand.variable, type, functionNestingLevel);
     }
     if (constantContext != ConstantContext.none) {
       push(deprecated_buildCompileTimeError(
@@ -2071,7 +2090,7 @@
   @override
   void beginConditionalExpression(Token question) {
     Expression condition = popForValue();
-    typePromoter.enterThen(condition);
+    typePromoter.enterThen(toKernelExpression(condition));
     push(condition);
     super.beginConditionalExpression(question);
   }
@@ -2103,8 +2122,8 @@
       push(deprecated_buildCompileTimeError(
           "Not a constant expression.", throwToken.charOffset));
     } else {
-      push(
-          new ShadowThrow(expression)..fileOffset = offsetForToken(throwToken));
+      push(new ShadowThrow(toKernelExpression(expression))
+        ..fileOffset = offsetForToken(throwToken));
     }
   }
 
@@ -2134,7 +2153,7 @@
     }
     bool isConst = (modifiers & constMask) != 0;
     bool isFinal = (modifiers & finalMask) != 0;
-    ignore(Unhandled.Metadata);
+    List<Expression> annotations = pop();
     VariableDeclaration variable;
     if (!inCatchClause &&
         functionNestingLevel == 0 &&
@@ -2162,6 +2181,14 @@
         variable.fileOffset = offsetForToken(name.token);
       }
     }
+    if (annotations != null) {
+      if (functionNestingLevel == 0) {
+        _typeInferrer.inferMetadata(this, toKernelExpressionList(annotations));
+      }
+      for (Expression annotation in annotations) {
+        variable.addAnnotation(toKernelExpression(annotation));
+      }
+    }
     push(variable);
   }
 
@@ -2215,7 +2242,8 @@
     debugEvent("ValuedFormalParameter");
     Expression initializer = popForValue();
     Identifier name = pop();
-    push(new InitializedIdentifier(name.token, initializer));
+    push(
+        new InitializedIdentifier(name.token, toKernelExpression(initializer)));
   }
 
   @override
@@ -2290,7 +2318,7 @@
       }
       if (catchParameters.required.length > 2 ||
           catchParameters.optional != null) {
-        body = new Block(<Statement>[
+        body = new Block(<kernel.Statement>[
           compileTimeErrorInTry ??= deprecated_buildCompileTimeErrorStatement(
               "Invalid catch arguments.", catchKeyword.next.charOffset)
         ]);
@@ -2302,9 +2330,9 @@
 
   @override
   void endTryStatement(int catchCount, Token tryKeyword, Token finallyKeyword) {
-    Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
+    kernel.Statement finallyBlock = popStatementIfNotNull(finallyKeyword);
     List<Catch> catches = popList(catchCount);
-    Statement tryBlock = popStatement();
+    kernel.Statement tryBlock = popStatement();
     if (compileTimeErrorInTry == null) {
       if (catches != null) {
         tryBlock = new ShadowTryCatch(tryBlock, catches);
@@ -2335,12 +2363,17 @@
       push(new SuperIndexAccessor(
           this,
           openSquareBracket,
-          index,
+          toKernelExpression(index),
           lookupInstanceMember(indexGetName, isSuper: true),
           lookupInstanceMember(indexSetName, isSuper: true)));
     } else {
       push(IndexAccessor.make(
-          this, openSquareBracket, toValue(receiver), index, null, null));
+          this,
+          openSquareBracket,
+          toKernelExpression(toValue(receiver)),
+          toKernelExpression(index),
+          null,
+          null));
     }
   }
 
@@ -2531,10 +2564,10 @@
         return deprecated_buildCompileTimeError(
             "Not a const constructor.", charOffset);
       }
-      return new ShadowConstructorInvocation(target, targetTypeArguments,
-          initialTarget, forest.castArguments(arguments),
+      return toExpression(new ShadowConstructorInvocation(target,
+          targetTypeArguments, initialTarget, forest.castArguments(arguments),
           isConst: isConst)
-        ..fileOffset = charOffset;
+        ..fileOffset = charOffset);
     } else {
       Procedure procedure = target;
       if (procedure.isFactory) {
@@ -2545,15 +2578,15 @@
           return deprecated_buildCompileTimeError(
               "Not a const factory.", charOffset);
         }
-        return new ShadowFactoryConstructorInvocation(target,
+        return toExpression(new ShadowFactoryConstructorInvocation(target,
             targetTypeArguments, initialTarget, forest.castArguments(arguments),
             isConst: isConst)
-          ..fileOffset = charOffset;
+          ..fileOffset = charOffset);
       } else {
-        return new ShadowStaticInvocation(
+        return toExpression(new ShadowStaticInvocation(
             target, forest.castArguments(arguments),
             isConst: isConst)
-          ..fileOffset = charOffset;
+          ..fileOffset = charOffset);
       }
     }
   }
@@ -2764,13 +2797,14 @@
       } else if (b.isConstructor) {
         initialTarget = b.target;
         if (type.isAbstract) {
-          return new ShadowSyntheticExpression(evaluateArgumentsBefore(
-              arguments,
-              buildAbstractClassInstantiationError(
-                  fasta.templateAbstractClassInstantiation
-                      .withArguments(type.name),
-                  type.name,
-                  nameToken.charOffset)));
+          return toExpression(new ShadowSyntheticExpression(toKernelExpression(
+              evaluateArgumentsBefore(
+                  arguments,
+                  buildAbstractClassInstantiationError(
+                      fasta.templateAbstractClassInstantiation
+                          .withArguments(type.name),
+                      type.name,
+                      nameToken.charOffset)))));
         } else {
           target = initialTarget;
         }
@@ -2786,13 +2820,14 @@
               "Cyclic definition of factory '${name}'.", nameToken.charOffset);
         }
         if (target is Constructor && target.enclosingClass.isAbstract) {
-          return new ShadowSyntheticExpression(evaluateArgumentsBefore(
-              arguments,
-              buildAbstractClassInstantiationError(
-                  fasta.templateAbstractRedirectedClassInstantiation
-                      .withArguments(target.enclosingClass.name),
-                  target.enclosingClass.name,
-                  nameToken.charOffset)));
+          return toExpression(new ShadowSyntheticExpression(toKernelExpression(
+              evaluateArgumentsBefore(
+                  arguments,
+                  buildAbstractClassInstantiationError(
+                      fasta.templateAbstractRedirectedClassInstantiation
+                          .withArguments(target.enclosingClass.name),
+                      target.enclosingClass.name,
+                      nameToken.charOffset)))));
         }
         RedirectingFactoryBody body = getRedirectingFactoryBody(target);
         if (body != null) {
@@ -2865,7 +2900,7 @@
     debugEvent("NamedArgument");
     Expression value = popForValue();
     Identifier identifier = pop();
-    push(new NamedExpression(identifier.name, value)
+    push(new NamedExpression(identifier.name, toKernelExpression(value))
       ..fileOffset = offsetForToken(identifier.token));
   }
 
@@ -2932,7 +2967,7 @@
   }
 
   void pushNamedFunction(Token token, bool isFunctionExpression) {
-    Statement body = popStatement();
+    kernel.Statement body = popStatement();
     AsyncMarker asyncModifier = pop();
     exitLocalScope();
     FormalParameters formals = pop();
@@ -2942,8 +2977,9 @@
     returnType ??= const DynamicType();
     exitFunction();
     List<TypeParameter> typeParameters = typeVariableBuildersToKernel(pop());
+    List<Expression> annotations;
     if (!isFunctionExpression) {
-      pop(); // Metadata.
+      annotations = pop(); // Metadata.
     }
     FunctionNode function = formals.addToFunction(new FunctionNode(body,
         typeParameters: typeParameters,
@@ -2954,26 +2990,33 @@
 
     if (declaration is FunctionDeclaration) {
       VariableDeclaration variable = declaration.variable;
+      if (annotations != null) {
+        for (Expression annotation in annotations) {
+          variable.addAnnotation(toKernelExpression(annotation));
+        }
+      }
       ShadowFunctionDeclaration.setHasImplicitReturnType(
           declaration, hasImplicitReturnType);
 
       variable.type = function.functionType;
       if (isFunctionExpression) {
-        Expression oldInitializer = variable.initializer;
+        Expression oldInitializer = toExpression(variable.initializer);
         variable.initializer = new ShadowFunctionExpression(function)
           ..parent = variable
           ..fileOffset = formals.charOffset;
         exitLocalScope();
-        Expression expression = new ShadowNamedFunctionExpression(variable);
+        Expression expression =
+            toExpression(new ShadowNamedFunctionExpression(variable));
         if (oldInitializer != null) {
           // This must have been a compile-time error.
-          assert(isErroneousNode(oldInitializer));
+          assert(isErroneousNode(toKernelExpression(oldInitializer)));
 
           push(new Let(
-              new VariableDeclaration.forValue(oldInitializer)
-                ..fileOffset = expression.fileOffset,
-              expression)
-            ..fileOffset = expression.fileOffset);
+              new VariableDeclaration.forValue(
+                  toKernelExpression(oldInitializer))
+                ..fileOffset = forest.readOffset(expression),
+              toKernelExpression(expression))
+            ..fileOffset = forest.readOffset(expression));
         } else {
           push(expression);
         }
@@ -2984,7 +3027,7 @@
           // This must have been a compile-time error.
           assert(isErroneousNode(variable.initializer));
 
-          push(new Block(<Statement>[
+          push(new Block(<kernel.Statement>[
             new ExpressionStatement(variable.initializer),
             declaration
           ])
@@ -3015,7 +3058,7 @@
   @override
   void endFunctionExpression(Token beginToken, Token token) {
     debugEvent("FunctionExpression");
-    Statement body = popStatement();
+    kernel.Statement body = popStatement();
     AsyncMarker asyncModifier = pop();
     exitLocalScope();
     FormalParameters formals = pop();
@@ -3039,15 +3082,16 @@
       Token doKeyword, Token whileKeyword, Token endToken) {
     debugEvent("DoWhileStatement");
     Expression condition = popForValue();
-    Statement body = popStatement();
+    kernel.Statement body = popStatement();
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
     if (continueTarget.hasUsers) {
       body = new ShadowLabeledStatement(body);
       continueTarget.resolveContinues(body);
     }
-    Statement result = new ShadowDoStatement(body, condition)
-      ..fileOffset = doKeyword.charOffset;
+    kernel.Statement result =
+        new ShadowDoStatement(body, toKernelExpression(condition))
+          ..fileOffset = doKeyword.charOffset;
     if (breakTarget.hasUsers) {
       result = new ShadowLabeledStatement(result);
       breakTarget.resolveBreaks(result);
@@ -3072,7 +3116,7 @@
   void endForIn(Token awaitToken, Token forToken, Token leftParenthesis,
       Token inKeyword, Token endToken) {
     debugEvent("ForIn");
-    Statement body = popStatement();
+    kernel.Statement body = popStatement();
     Expression expression = popForValue();
     var lvalue = pop();
     exitLocalScope();
@@ -3114,12 +3158,16 @@
       body = combineStatements(
           new ShadowLoopAssignmentStatement(syntheticAssignment), body);
     } else {
-      variable = new VariableDeclaration.forValue(
+      variable = new VariableDeclaration.forValue(toKernelExpression(
           deprecated_buildCompileTimeError("Expected lvalue, but got ${lvalue}",
-              forToken.next.next.charOffset));
+              forToken.next.next.charOffset)));
     }
-    Statement result = new ShadowForInStatement(
-        variable, expression, body, declaresVariable, syntheticAssignment,
+    kernel.Statement result = new ShadowForInStatement(
+        variable,
+        toKernelExpression(expression),
+        body,
+        declaresVariable,
+        syntheticAssignment,
         isAsync: awaitToken != null)
       ..fileOffset = awaitToken?.charOffset ?? forToken.charOffset
       ..bodyOffset = body.fileOffset;
@@ -3153,7 +3201,7 @@
   @override
   void endLabeledStatement(int labelCount) {
     debugEvent("LabeledStatement");
-    Statement statement = popStatement();
+    kernel.Statement statement = popStatement();
     LabelTarget target = pop();
     exitLocalScope();
     if (target.breakTarget.hasUsers) {
@@ -3193,7 +3241,7 @@
   @override
   void endWhileStatement(Token whileKeyword, Token endToken) {
     debugEvent("WhileStatement");
-    Statement body = popStatement();
+    kernel.Statement body = popStatement();
     Expression condition = popForValue();
     JumpTarget continueTarget = exitContinueTarget();
     JumpTarget breakTarget = exitBreakTarget();
@@ -3201,8 +3249,9 @@
       body = new ShadowLabeledStatement(body);
       continueTarget.resolveContinues(body);
     }
-    Statement result = new ShadowWhileStatement(condition, body)
-      ..fileOffset = whileKeyword.charOffset;
+    kernel.Statement result =
+        new ShadowWhileStatement(toKernelExpression(condition), body)
+          ..fileOffset = whileKeyword.charOffset;
     if (breakTarget.hasUsers) {
       result = new ShadowLabeledStatement(result);
       breakTarget.resolveBreaks(result);
@@ -3266,10 +3315,11 @@
       }
     }
 
-    AssertStatement statement = new ShadowAssertStatement(condition,
+    AssertStatement statement = new ShadowAssertStatement(
+        toKernelExpression(condition),
         conditionStartOffset: startOffset,
         conditionEndOffset: endOffset,
-        message: message);
+        message: toKernelExpression(message));
     switch (kind) {
       case Assert.Statement:
         push(statement);
@@ -3291,7 +3341,8 @@
   @override
   void endYieldStatement(Token yieldToken, Token starToken, Token endToken) {
     debugEvent("YieldStatement");
-    push(new ShadowYieldStatement(popForValue(), isYieldStar: starToken != null)
+    push(new ShadowYieldStatement(toKernelExpression(popForValue()),
+        isYieldStar: starToken != null)
       ..fileOffset = yieldToken.charOffset);
   }
 
@@ -3357,9 +3408,10 @@
     List<Expression> expressions = pop();
     List<int> expressionOffsets = <int>[];
     for (Expression expression in expressions) {
-      expressionOffsets.add(expression.fileOffset);
+      expressionOffsets.add(forest.readOffset(expression));
     }
-    push(new SwitchCase(expressions, expressionOffsets, block,
+    push(new SwitchCase(
+        toKernelExpressionList(expressions), expressionOffsets, block,
         isDefault: defaultKeyword != null)
       ..fileOffset = firstToken.charOffset);
     push(labels);
@@ -3374,8 +3426,9 @@
     exitSwitchScope();
     exitLocalScope();
     Expression expression = popForValue();
-    Statement result = new ShadowSwitchStatement(expression, cases)
-      ..fileOffset = switchKeyword.charOffset;
+    kernel.Statement result =
+        new ShadowSwitchStatement(toKernelExpression(expression), cases)
+          ..fileOffset = switchKeyword.charOffset;
     if (target.hasUsers) {
       result = new ShadowLabeledStatement(result);
       target.resolveBreaks(result);
@@ -3419,8 +3472,8 @@
           lastNode is! Rethrow &&
           lastNode is! ReturnStatement &&
           lastNode is! Throw) {
-        block.addStatement(
-            new ExpressionStatement(buildFallThroughError(current.fileOffset)));
+        block.addStatement(new ExpressionStatement(
+            toKernelExpression(buildFallThroughError(current.fileOffset))));
       }
     }
 
@@ -3545,8 +3598,7 @@
     debugEvent("TypeVariable");
     DartType bound = pop();
     Identifier name = pop();
-    // TODO(ahe): Do not discard metadata.
-    pop(); // Metadata.
+    List<Expression> annotations = pop();
     KernelTypeVariableBuilder variable;
     Object inScope = scopeLookup(scope, name.name, token);
     if (inScope is TypeDeclarationAccessor) {
@@ -3558,6 +3610,12 @@
           name.name, library, offsetForToken(name.token), null);
     }
     variable.parameter.bound = bound;
+    if (annotations != null) {
+      _typeInferrer.inferMetadata(this, toKernelExpressionList(annotations));
+      for (Expression annotation in annotations) {
+        variable.parameter.addAnnotation(toKernelExpression(annotation));
+      }
+    }
     push(variable
       ..finish(library, library.loader.target.objectClassBuilder,
           library.loader.target.dynamicType));
@@ -3607,7 +3665,7 @@
 
   @override
   void handleInvalidStatement(Token token, Message message) {
-    Statement statement = pop();
+    kernel.Statement statement = pop();
     push(wrapInCompileTimeErrorStatement(statement, message));
   }
 
@@ -3623,15 +3681,15 @@
       {List<LocatedMessage> context}) {
     library.addCompileTimeError(message, charOffset, length, uri,
         wasHandled: true, context: context);
-    return new ShadowSyntheticExpression(library.loader
+    return toExpression(new ShadowSyntheticExpression(library.loader
         .throwCompileConstantError(library.loader
-            .buildCompileTimeError(message, charOffset, length, uri)));
+            .buildCompileTimeError(message, charOffset, length, uri))));
   }
 
   Expression wrapInCompileTimeError(Expression expression, Message message,
       {List<LocatedMessage> context}) {
-    return wrapInLocatedCompileTimeError(
-        expression, message.withLocation(uri, expression.fileOffset, noLength),
+    return wrapInLocatedCompileTimeError(expression,
+        message.withLocation(uri, forest.readOffset(expression), noLength),
         context: context);
   }
 
@@ -3640,17 +3698,19 @@
       {List<LocatedMessage> context}) {
     // TODO(askesc): Produce explicit error expression wrapping the original.
     // See [issue 29717](https://github.com/dart-lang/sdk/issues/29717)
-    return new Let(
-        new VariableDeclaration.forValue(buildCompileTimeError(
-            message.messageObject, message.charOffset, message.length,
-            context: context))
-          ..fileOffset = expression.fileOffset,
+    return toExpression(new Let(
+        new VariableDeclaration.forValue(toKernelExpression(
+            buildCompileTimeError(
+                message.messageObject, message.charOffset, message.length,
+                context: context)))
+          ..fileOffset = forest.readOffset(expression),
         new Let(
-            new VariableDeclaration.forValue(expression)
-              ..fileOffset = expression.fileOffset,
-            storeOffset(forest.literalNull(null), expression.fileOffset))
-          ..fileOffset = expression.fileOffset)
-      ..fileOffset = expression.fileOffset;
+            new VariableDeclaration.forValue(toKernelExpression(expression))
+              ..fileOffset = forest.readOffset(expression),
+            toKernelExpression(storeOffset(
+                forest.literalNull(null), forest.readOffset(expression))))
+          ..fileOffset = forest.readOffset(expression))
+      ..fileOffset = forest.readOffset(expression));
   }
 
   Expression buildFallThroughError(int charOffset) {
@@ -3662,14 +3722,14 @@
     // TODO(ahe): Compute a LocatedMessage above instead?
     Location location = messages.getLocationFromUri(uri, charOffset);
 
-    return new Throw(buildStaticInvocation(
+    return toExpression(new Throw(toKernelExpression(buildStaticInvocation(
         library.loader.coreTypes.fallThroughErrorUrlAndLineConstructor,
         forest.arguments(<Expression>[
           storeOffset(forest.literalString("${location?.file ?? uri}", null),
               charOffset),
           storeOffset(forest.literalInt(location?.line ?? 0, null), charOffset),
         ], noLocation),
-        charOffset: charOffset));
+        charOffset: charOffset))));
   }
 
   Expression buildAbstractClassInstantiationError(
@@ -3678,27 +3738,29 @@
     addProblemErrorIfConst(message, charOffset, className.length);
     // TODO(ahe): The following doesn't make sense to Analyzer AST.
     Builder constructor = library.loader.getAbstractClassInstantiationError();
-    return new Throw(buildStaticInvocation(
+    return toExpression(new Throw(toKernelExpression(buildStaticInvocation(
         constructor.target,
         forest.arguments(<Expression>[
           storeOffset(forest.literalString(className, null), charOffset)
-        ], noLocation)));
+        ], noLocation)))));
   }
 
-  Statement deprecated_buildCompileTimeErrorStatement(error,
+  kernel.Statement deprecated_buildCompileTimeErrorStatement(error,
       [int charOffset = -1]) {
-    return new ShadowExpressionStatement(
-        deprecated_buildCompileTimeError(error, charOffset));
+    return new ShadowExpressionStatement(toKernelExpression(
+        deprecated_buildCompileTimeError(error, charOffset)));
   }
 
-  Statement buildCompileTimeErrorStatement(Message message, int charOffset,
+  kernel.Statement buildCompileTimeErrorStatement(
+      Message message, int charOffset,
       {List<LocatedMessage> context}) {
-    return new ShadowExpressionStatement(
-        buildCompileTimeError(message, charOffset, noLength, context: context));
+    return new ShadowExpressionStatement(toKernelExpression(
+        buildCompileTimeError(message, charOffset, noLength,
+            context: context)));
   }
 
-  Statement wrapInCompileTimeErrorStatement(
-      Statement statement, Message message) {
+  kernel.Statement wrapInCompileTimeErrorStatement(
+      kernel.Statement statement, Message message) {
     // TODO(askesc): Produce explicit error statement wrapping the original.
     // See [issue 29717](https://github.com/dart-lang/sdk/issues/29717)
     return buildCompileTimeErrorStatement(message, statement.fileOffset);
@@ -3709,7 +3771,7 @@
       [int charOffset = -1]) {
     needsImplicitSuperInitializer = false;
     return new ShadowInvalidInitializer(
-        new VariableDeclaration.forValue(expression))
+        new VariableDeclaration.forValue(toKernelExpression(expression)))
       ..fileOffset = charOffset;
   }
 
@@ -3752,15 +3814,16 @@
         Builder constructor =
             library.loader.getDuplicatedFieldInitializerError();
         return buildInvalidInitializer(
-            new Throw(buildStaticInvocation(
+            toExpression(new Throw(toKernelExpression(buildStaticInvocation(
                 constructor.target,
                 forest.arguments(<Expression>[
                   storeOffset(forest.literalString(name, null), offset)
                 ], noLocation),
-                charOffset: offset)),
+                charOffset: offset)))),
             offset);
       } else {
-        return new ShadowFieldInitializer(builder.field, expression)
+        return new ShadowFieldInitializer(
+            builder.field, toKernelExpression(expression))
           ..fileOffset = offset
           ..isSynthetic = isSynthetic;
       }
@@ -3835,7 +3898,7 @@
     if (member.isNative) {
       push(NullValue.FunctionBody);
     } else {
-      push(new Block(<Statement>[
+      push(new Block(<kernel.Statement>[
         deprecated_buildCompileTimeErrorStatement(
             "Expected '{'.", token.charOffset)
       ]));
@@ -3869,12 +3932,13 @@
     List<Expression> expressions =
         new List<Expression>.from(forest.argumentsPositional(arguments));
     for (NamedExpression named in forest.argumentsNamed(arguments)) {
-      expressions.add(named.value);
+      expressions.add(toExpression(named.value));
     }
     for (Expression argument in expressions.reversed) {
-      expression = new Let(
-          new VariableDeclaration.forValue(argument, isFinal: true),
-          expression);
+      expression = toExpression(new Let(
+          new VariableDeclaration.forValue(toKernelExpression(argument),
+              isFinal: true),
+          toKernelExpression(expression)));
     }
     return expression;
   }
@@ -3910,36 +3974,40 @@
               offset,
               name.name.length);
         }
-        return new ShadowSuperMethodInvocation(
+        return toExpression(new ShadowSuperMethodInvocation(
             name, forest.castArguments(arguments), target)
-          ..fileOffset = offset;
+          ..fileOffset = offset);
       }
 
-      receiver = new ShadowSuperPropertyGet(name, target)..fileOffset = offset;
-      return new ShadowMethodInvocation(
-          receiver, callName, forest.castArguments(arguments),
+      receiver = toExpression(
+          new ShadowSuperPropertyGet(name, target)..fileOffset = offset);
+      return toExpression(new ShadowMethodInvocation(
+          toKernelExpression(receiver),
+          callName,
+          forest.castArguments(arguments),
           isImplicitCall: true)
-        ..fileOffset = forest.readOffset(arguments);
+        ..fileOffset = forest.readOffset(arguments));
     }
 
     if (isNullAware) {
-      VariableDeclaration variable = new VariableDeclaration.forValue(receiver);
-      return new ShadowNullAwareMethodInvocation(
+      VariableDeclaration variable =
+          new VariableDeclaration.forValue(toKernelExpression(receiver));
+      return toExpression(new ShadowNullAwareMethodInvocation(
           variable,
           new ConditionalExpression(
               buildIsNull(new VariableGet(variable), offset),
-              storeOffset(forest.literalNull(null), offset),
+              toKernelExpression(storeOffset(forest.literalNull(null), offset)),
               new MethodInvocation(new VariableGet(variable), name,
                   forest.castArguments(arguments), interfaceTarget)
                 ..fileOffset = offset,
               null)
             ..fileOffset = offset)
-        ..fileOffset = offset;
+        ..fileOffset = offset);
     } else {
-      return new ShadowMethodInvocation(
-          receiver, name, forest.castArguments(arguments),
+      return toExpression(new ShadowMethodInvocation(
+          toKernelExpression(receiver), name, forest.castArguments(arguments),
           isImplicitCall: isImplicitCall, interfaceTarget: interfaceTarget)
-        ..fileOffset = offset;
+        ..fileOffset = offset);
     }
   }
 
@@ -3983,18 +4051,34 @@
   Expression wrapInDeferredCheck(
       Expression expression, KernelPrefixBuilder prefix, int charOffset) {
     var check = new VariableDeclaration.forValue(
-        forest.checkLibraryIsLoaded(prefix.dependency))
+        toKernelExpression(forest.checkLibraryIsLoaded(prefix.dependency)))
       ..fileOffset = charOffset;
-    return new ShadowDeferredCheck(check, expression);
+    return toExpression(
+        new ShadowDeferredCheck(check, toKernelExpression(expression)));
   }
 
+  // TODO(ahe): Remove this method once Forest API is complete.
   @override
   T storeOffset<T>(T object, int offset) {
-    TreeNode node = object as TreeNode;
+    TreeNode node = object as dynamic;
     node.fileOffset = offset;
     return object;
   }
 
+  // TODO(ahe): Remove this method once Forest API is complete.
+  kernel.Expression toKernelExpression(Expression expression) {
+    return expression as dynamic;
+  }
+
+  // TODO(ahe): Remove this method once Forest API is complete.
+  Expression toExpression(kernel.Expression expression) {
+    return expression as dynamic;
+  }
+
+  List<kernel.Expression> toKernelExpressionList(List<Expression> expressions) {
+    return expressions as dynamic;
+  }
+
   bool isErroneousNode(TreeNode node) {
     return library.loader.handledErrors.isNotEmpty &&
         forest.isErroneousNode(node);
@@ -4007,7 +4091,7 @@
 
   Identifier(this.token);
 
-  Expression get initializer => null;
+  kernel.Expression get initializer => null;
 
   String toString() => "identifier($name)";
 }
@@ -4023,7 +4107,7 @@
 }
 
 class InitializedIdentifier extends Identifier {
-  final Expression initializer;
+  final kernel.Expression initializer;
 
   InitializedIdentifier(Token token, this.initializer) : super(token);
 
@@ -4052,25 +4136,27 @@
     return unsupported("plainNameForRead", token.charOffset, helper.uri);
   }
 
-  Expression doInvocation(int charOffset, Arguments arguments) {
+  kernel.Expression doInvocation(int charOffset, Arguments arguments) {
     return unhandled("${runtimeType}", "doInvocation", charOffset, uri);
   }
 
-  Expression buildSimpleRead();
+  kernel.Expression buildSimpleRead();
 
-  Expression buildForEffect();
+  kernel.Expression buildForEffect();
 
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    return makeInvalidWrite(value);
-  }
-
-  Expression buildNullAwareAssignment(
-      Expression value, DartType type, int offset,
+  kernel.Expression buildAssignment(kernel.Expression value,
       {bool voidContext: false}) {
     return makeInvalidWrite(value);
   }
 
-  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    return makeInvalidWrite(value);
+  }
+
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget,
@@ -4078,14 +4164,14 @@
     return makeInvalidWrite(value);
   }
 
-  Expression buildPrefixIncrement(Name binaryOperator,
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget}) {
     return makeInvalidWrite(null);
   }
 
-  Expression buildPostfixIncrement(Name binaryOperator,
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget}) {
@@ -4096,7 +4182,7 @@
     return unsupported("makeInvalidRead", token.charOffset, helper.uri);
   }
 
-  Expression makeInvalidWrite(Expression value) {
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
     return helper.deprecated_buildCompileTimeError(
         "Can't be used as left-hand side of assignment.",
         offsetForToken(token));
@@ -4104,7 +4190,7 @@
 }
 
 class DelayedAssignment<Arguments> extends ContextAccessor<Arguments> {
-  final Expression value;
+  final kernel.Expression value;
 
   final String assignmentOperator;
 
@@ -4112,15 +4198,15 @@
       this.value, this.assignmentOperator)
       : super(helper, token, accessor);
 
-  Expression buildSimpleRead() {
+  kernel.Expression buildSimpleRead() {
     return handleAssignment(false);
   }
 
-  Expression buildForEffect() {
+  kernel.Expression buildForEffect() {
     return handleAssignment(true);
   }
 
-  Expression handleAssignment(bool voidContext) {
+  kernel.Expression handleAssignment(bool voidContext) {
     if (helper.constantContext != ConstantContext.none) {
       return helper.deprecated_buildCompileTimeError(
           "Not a constant expression.", offsetForToken(token));
@@ -4190,14 +4276,14 @@
       FastaAccessor accessor, this.binaryOperator, this.interfaceTarget)
       : super(helper, token, accessor);
 
-  Expression buildSimpleRead() {
+  kernel.Expression buildSimpleRead() {
     return accessor.buildPostfixIncrement(binaryOperator,
         offset: offsetForToken(token),
         voidContext: false,
         interfaceTarget: interfaceTarget);
   }
 
-  Expression buildForEffect() {
+  kernel.Expression buildForEffect() {
     return accessor.buildPostfixIncrement(binaryOperator,
         offset: offsetForToken(token),
         voidContext: true,
@@ -4206,7 +4292,7 @@
 }
 
 class JumpTarget extends Builder {
-  final List<Statement> users = <Statement>[];
+  final List<kernel.Statement> users = <kernel.Statement>[];
 
   final JumpTargetKind kind;
 
@@ -4283,7 +4369,7 @@
 
   bool get hasUsers => breakTarget.hasUsers || continueTarget.hasUsers;
 
-  List<Statement> get users => unsupported("users", charOffset, fileUri);
+  List<kernel.Statement> get users => unsupported("users", charOffset, fileUri);
 
   JumpTargetKind get kind => unsupported("kind", charOffset, fileUri);
 
@@ -4415,13 +4501,13 @@
 ///     }
 ///
 /// If [body] is a [Block], it's returned with [statement] prepended to it.
-Block combineStatements(Statement statement, Statement body) {
+Block combineStatements(kernel.Statement statement, kernel.Statement body) {
   if (body is Block) {
     body.statements.insert(0, statement);
     statement.parent = body;
     return body;
   } else {
-    return new Block(<Statement>[statement, body]);
+    return new Block(<kernel.Statement>[statement, body]);
   }
 }
 
diff --git a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
index 45c842e..7dbebfe 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fangorn.dart
@@ -172,11 +172,10 @@
   int readOffset(TreeNode node) => node.fileOffset;
 
   @override
-  int getTypeCount(Object typeArguments) => (typeArguments as List).length;
+  int getTypeCount(List typeArguments) => typeArguments.length;
 
   @override
-  DartType getTypeAt(Object typeArguments, int index) =>
-      (typeArguments as List)[index];
+  DartType getTypeAt(List typeArguments, int index) => typeArguments[index];
 
   @override
   Expression loadLibrary(LibraryDependency dependency) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
index 81521a1..25ddc28 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -56,7 +56,9 @@
 
 import 'frontend_accessors.dart' show Accessor;
 
-import 'kernel_ast_api.dart';
+import 'kernel_ast_api.dart' hide Expression, Statement;
+
+import 'kernel_ast_api.dart' as kernel show Expression, Statement;
 
 import 'kernel_builder.dart'
     show
@@ -73,7 +75,7 @@
         PrefixBuilder,
         TypeDeclarationBuilder;
 
-abstract class BuilderHelper<Arguments> {
+abstract class BuilderHelper<Expression, Statement, Arguments> {
   LibraryBuilder get library;
 
   Uri get uri;
@@ -84,8 +86,7 @@
 
   ConstantContext get constantContext;
 
-  // TODO(ahe): Update type parameters.
-  Forest<dynamic, dynamic, Token, dynamic> get forest;
+  Forest<Expression, Statement, Token, Arguments> get forest;
 
   Constructor lookupConstructor(Name name, {bool isSuper});
 
@@ -98,7 +99,8 @@
 
   finishSend(Object receiver, Arguments arguments, int offset);
 
-  Expression buildCompileTimeError(Message message, int charOffset, int length);
+  Expression buildCompileTimeError(Message message, int charOffset, int length,
+      {List<LocatedMessage> context});
 
   Expression wrapInCompileTimeError(Expression expression, Message message);
 
@@ -212,7 +214,9 @@
 abstract class FastaAccessor<Arguments> implements Accessor<Arguments> {
   BuilderHelper get helper;
 
-  Forest<Expression, Statement, Token, Arguments> get forest => helper.forest;
+  // TODO(ahe): Change type arguments.
+  Forest<kernel.Expression, kernel.Statement, Token, Arguments> get forest =>
+      helper.forest;
 
   String get plainNameForRead;
 
@@ -226,7 +230,7 @@
     return helper.storeOffset(node, offset);
   }
 
-  Expression buildForEffect() => buildSimpleRead();
+  kernel.Expression buildForEffect() => buildSimpleRead();
 
   Initializer buildFieldInitializer(Map<String, int> initializedFields) {
     int offset = offsetForToken(token);
@@ -236,22 +240,22 @@
         offset);
   }
 
-  Expression makeInvalidRead() {
+  kernel.Expression makeInvalidRead() {
     return buildThrowNoSuchMethodError(
         forest.literalNull(token), forest.argumentsEmpty(noLocation),
         isGetter: true);
   }
 
-  Expression makeInvalidWrite(Expression value) {
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
     return buildThrowNoSuchMethodError(forest.literalNull(token),
-        forest.arguments(<Expression>[value], noLocation),
+        forest.arguments(<kernel.Expression>[value], noLocation),
         isSetter: true);
   }
 
-  /* Expression | FastaAccessor | Initializer */ doInvocation(
+  /* kernel.Expression | FastaAccessor | Initializer */ doInvocation(
       int offset, Arguments arguments);
 
-  /* Expression | FastaAccessor */ buildPropertyAccess(
+  /* kernel.Expression | FastaAccessor */ buildPropertyAccess(
       IncompleteSend send, int operatorOffset, bool isNullAware) {
     if (send is SendAccessor) {
       return helper.buildMethodInvocation(buildSimpleRead(), send.name,
@@ -275,8 +279,8 @@
     return const InvalidType();
   }
 
-  /* Expression | FastaAccessor */ buildThrowNoSuchMethodError(
-      Expression receiver, Arguments arguments,
+  /* kernel.Expression | FastaAccessor */ buildThrowNoSuchMethodError(
+      kernel.Expression receiver, Arguments arguments,
       {bool isSuper: false,
       bool isGetter: false,
       bool isSetter: false,
@@ -296,7 +300,7 @@
   bool get isThisPropertyAccessor => false;
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowIllegalAssignment(rhs);
 }
 
@@ -304,7 +308,7 @@
   /// Pass [arguments] that must be evaluated before throwing an error.  At
   /// most one of [isGetter] and [isSetter] should be true and they're passed
   /// to [BuilderHelper.buildThrowNoSuchMethodError] if it is used.
-  Expression buildError(Arguments arguments,
+  kernel.Expression buildError(Arguments arguments,
       {bool isGetter: false, bool isSetter: false, int offset});
 
   DartType buildErroneousTypeNotAPrefix(Identifier suffix);
@@ -334,7 +338,7 @@
   }
 
   @override
-  buildThrowNoSuchMethodError(Expression receiver, Arguments arguments,
+  buildThrowNoSuchMethodError(kernel.Expression receiver, Arguments arguments,
       {bool isSuper: false,
       bool isGetter: false,
       bool isSetter: false,
@@ -346,68 +350,70 @@
   }
 
   @override
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    return buildError(forest.arguments(<Expression>[value], noLocation),
+  kernel.Expression buildAssignment(kernel.Expression value,
+      {bool voidContext: false}) {
+    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
         isSetter: true);
   }
 
   @override
-  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget,
       bool isPreIncDec: false}) {
-    return buildError(forest.arguments(<Expression>[value], token),
+    return buildError(forest.arguments(<kernel.Expression>[value], token),
         isGetter: true);
   }
 
   @override
-  Expression buildPrefixIncrement(Name binaryOperator,
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget}) {
     // TODO(ahe): For the Analyzer, we probably need to build a prefix
     // increment node that wraps an error.
     return buildError(
-        forest.arguments(
-            <Expression>[storeOffset(forest.literalInt(1, null), offset)],
-            noLocation),
+        forest.arguments(<kernel.Expression>[
+          storeOffset(forest.literalInt(1, null), offset)
+        ], noLocation),
         isGetter: true);
   }
 
   @override
-  Expression buildPostfixIncrement(Name binaryOperator,
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget}) {
     // TODO(ahe): For the Analyzer, we probably need to build a post increment
     // node that wraps an error.
     return buildError(
-        forest.arguments(
-            <Expression>[storeOffset(forest.literalInt(1, null), offset)],
-            noLocation),
+        forest.arguments(<kernel.Expression>[
+          storeOffset(forest.literalInt(1, null), offset)
+        ], noLocation),
         isGetter: true);
   }
 
   @override
-  Expression buildNullAwareAssignment(
-      Expression value, DartType type, int offset,
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
       {bool voidContext: false}) {
-    return buildError(forest.arguments(<Expression>[value], noLocation),
+    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
         isSetter: true);
   }
 
   @override
-  Expression buildSimpleRead() =>
+  kernel.Expression buildSimpleRead() =>
       buildError(forest.argumentsEmpty(noLocation), isGetter: true);
 
   @override
-  Expression makeInvalidRead() =>
+  kernel.Expression makeInvalidRead() =>
       buildError(forest.argumentsEmpty(noLocation), isGetter: true);
 
   @override
-  Expression makeInvalidWrite(Expression value) {
-    return buildError(forest.arguments(<Expression>[value], noLocation),
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
+    return buildError(forest.arguments(<kernel.Expression>[value], noLocation),
         isSetter: true);
   }
 }
@@ -429,7 +435,7 @@
         offsetForToken(token), uri);
   }
 
-  Expression buildSimpleRead() {
+  kernel.Expression buildSimpleRead() {
     if (!isSuper) {
       return forest.thisExpression(token);
     } else {
@@ -525,17 +531,19 @@
     }
   }
 
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
-    return buildAssignmentError();
-  }
-
-  Expression buildNullAwareAssignment(
-      Expression value, DartType type, int offset,
+  kernel.Expression buildAssignment(kernel.Expression value,
       {bool voidContext: false}) {
     return buildAssignmentError();
   }
 
-  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
+      {bool voidContext: false}) {
+    return buildAssignmentError();
+  }
+
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget,
@@ -543,21 +551,21 @@
     return buildAssignmentError();
   }
 
-  Expression buildPrefixIncrement(Name binaryOperator,
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget}) {
     return buildAssignmentError();
   }
 
-  Expression buildPostfixIncrement(Name binaryOperator,
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
       {int offset: TreeNode.noOffset,
       bool voidContext: false,
       Procedure interfaceTarget}) {
     return buildAssignmentError();
   }
 
-  Expression buildAssignmentError() {
+  kernel.Expression buildAssignmentError() {
     String message =
         isSuper ? "Can't assign to 'super'." : "Can't assign to 'this'.";
     return helper.deprecated_buildCompileTimeError(
@@ -593,7 +601,7 @@
       : super(helper, token, null);
 
   @override
-  Expression buildError(Arguments arguments,
+  kernel.Expression buildError(Arguments arguments,
       {bool isGetter: false, bool isSetter: false, int offset}) {
     int length = noLength;
     if (offset == null) {
@@ -628,11 +636,12 @@
 
   String get plainNameForRead => name.name;
 
-  Expression buildSimpleRead() {
+  kernel.Expression buildSimpleRead() {
     return unsupported("buildSimpleRead", offsetForToken(token), uri);
   }
 
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+  kernel.Expression buildAssignment(kernel.Expression value,
+      {bool voidContext: false}) {
     return unsupported("buildAssignment", offsetForToken(token), uri);
   }
 
@@ -657,13 +666,14 @@
         isNullAware: isNullAware);
   }
 
-  Expression buildNullAwareAssignment(
-      Expression value, DartType type, int offset,
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
       {bool voidContext: false}) {
     return unsupported("buildNullAwareAssignment", offset, uri);
   }
 
-  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
       {int offset,
       bool voidContext: false,
       Procedure interfaceTarget,
@@ -672,19 +682,19 @@
         "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
   }
 
-  Expression buildPrefixIncrement(Name binaryOperator,
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
       {int offset, bool voidContext: false, Procedure interfaceTarget}) {
     return unsupported(
         "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
   }
 
-  Expression buildPostfixIncrement(Name binaryOperator,
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
       {int offset, bool voidContext: false, Procedure interfaceTarget}) {
     return unsupported(
         "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
   }
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return unsupported("doInvocation", offset, uri);
   }
 
@@ -700,11 +710,12 @@
 
   String get plainNameForRead => name.name;
 
-  Expression buildSimpleRead() {
+  kernel.Expression buildSimpleRead() {
     return unsupported("buildSimpleRead", offsetForToken(token), uri);
   }
 
-  Expression buildAssignment(Expression value, {bool voidContext: false}) {
+  kernel.Expression buildAssignment(kernel.Expression value,
+      {bool voidContext: false}) {
     return unsupported("buildAssignment", offsetForToken(token), uri);
   }
 
@@ -728,13 +739,14 @@
         helper, token, helper.toValue(receiver), name, null, null, isNullAware);
   }
 
-  Expression buildNullAwareAssignment(
-      Expression value, DartType type, int offset,
+  kernel.Expression buildNullAwareAssignment(
+      kernel.Expression value, DartType type, int offset,
       {bool voidContext: false}) {
     return unsupported("buildNullAwareAssignment", offset, uri);
   }
 
-  Expression buildCompoundAssignment(Name binaryOperator, Expression value,
+  kernel.Expression buildCompoundAssignment(
+      Name binaryOperator, kernel.Expression value,
       {int offset,
       bool voidContext: false,
       Procedure interfaceTarget,
@@ -743,19 +755,19 @@
         "buildCompoundAssignment", offset ?? offsetForToken(token), uri);
   }
 
-  Expression buildPrefixIncrement(Name binaryOperator,
+  kernel.Expression buildPrefixIncrement(Name binaryOperator,
       {int offset, bool voidContext: false, Procedure interfaceTarget}) {
     return unsupported(
         "buildPrefixIncrement", offset ?? offsetForToken(token), uri);
   }
 
-  Expression buildPostfixIncrement(Name binaryOperator,
+  kernel.Expression buildPostfixIncrement(Name binaryOperator,
       {int offset, bool voidContext: false, Procedure interfaceTarget}) {
     return unsupported(
         "buildPostfixIncrement", offset ?? offsetForToken(token), uri);
   }
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return unsupported("doInvocation", offset, uri);
   }
 
@@ -769,15 +781,15 @@
     with FastaAccessor<Arguments> {
   final BuilderHelper helper;
 
-  IndexAccessor.internal(this.helper, Token token, Expression receiver,
-      Expression index, Procedure getter, Procedure setter)
+  IndexAccessor.internal(this.helper, Token token, kernel.Expression receiver,
+      kernel.Expression index, Procedure getter, Procedure setter)
       : super.internal(helper, receiver, index, getter, setter, token);
 
   String get plainNameForRead => "[]";
 
   String get plainNameForWrite => "[]=";
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return helper.buildMethodInvocation(
         buildSimpleRead(), callName, arguments, forest.readOffset(arguments),
         isImplicitCall: true);
@@ -788,8 +800,8 @@
   static FastaAccessor make(
       BuilderHelper helper,
       Token token,
-      Expression receiver,
-      Expression index,
+      kernel.Expression receiver,
+      kernel.Expression index,
       Procedure getter,
       Procedure setter) {
     if (receiver is ThisExpression) {
@@ -801,7 +813,7 @@
   }
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowIndexAssign(receiver, index, rhs);
 }
 
@@ -809,15 +821,15 @@
     with FastaAccessor<Arguments> {
   final BuilderHelper helper;
 
-  PropertyAccessor.internal(this.helper, Token token, Expression receiver,
-      Name name, Member getter, Member setter)
+  PropertyAccessor.internal(this.helper, Token token,
+      kernel.Expression receiver, Name name, Member getter, Member setter)
       : super.internal(helper, receiver, name, getter, setter, token);
 
   String get plainNameForRead => name.name;
 
   bool get isThisPropertyAccessor => receiver is ThisExpression;
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return helper.buildMethodInvocation(receiver, name, arguments, offset);
   }
 
@@ -826,7 +838,7 @@
   static FastaAccessor make(
       BuilderHelper helper,
       Token token,
-      Expression receiver,
+      kernel.Expression receiver,
       Name name,
       Member getter,
       Member setter,
@@ -843,7 +855,7 @@
   }
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowPropertyAssign(receiver, rhs);
 }
 
@@ -879,7 +891,7 @@
 
   String get plainNameForRead => (readTarget ?? writeTarget).name.name;
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     if (helper.constantContext != ConstantContext.none &&
         !helper.isIdentical(readTarget)) {
       helper.deprecated_addCompileTimeError(
@@ -901,7 +913,7 @@
   toString() => "StaticAccessor()";
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowStaticAssignment(rhs);
 }
 
@@ -913,7 +925,7 @@
 
   String get plainNameForRead => 'loadLibrary';
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     if (forest.argumentsPositional(arguments).length > 0 ||
         forest.argumentsNamed(arguments).length > 0) {
       helper.addProblemErrorIfConst(
@@ -943,7 +955,7 @@
     if (propertyAccess is FastaAccessor) {
       return new DeferredAccessor(helper, token, builder, propertyAccess);
     } else {
-      Expression expression = propertyAccess;
+      kernel.Expression expression = propertyAccess;
       return helper.wrapInDeferredCheck(expression, builder, token.charOffset);
     }
   }
@@ -961,7 +973,7 @@
     return const InvalidType();
   }
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return helper.wrapInDeferredCheck(
         accessor.doInvocation(offset, arguments), builder, token.charOffset);
   }
@@ -975,7 +987,7 @@
 
   String get plainNameForRead => name.name;
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     if (helper.constantContext != ConstantContext.none) {
       helper.deprecated_addCompileTimeError(
           offset, "Not a constant expression.");
@@ -997,13 +1009,13 @@
   toString() => "SuperPropertyAccessor()";
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowPropertyAssign(null, rhs, isSuper: true);
 }
 
 class ThisIndexAccessor<Arguments> extends kernel.ThisIndexAccessor<Arguments>
     with FastaAccessor<Arguments> {
-  ThisIndexAccessor(BuilderHelper helper, Token token, Expression index,
+  ThisIndexAccessor(BuilderHelper helper, Token token, kernel.Expression index,
       Procedure getter, Procedure setter)
       : super(helper, index, getter, setter, token);
 
@@ -1011,7 +1023,7 @@
 
   String get plainNameForWrite => "[]=";
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return helper.buildMethodInvocation(
         buildSimpleRead(), callName, arguments, offset,
         isImplicitCall: true);
@@ -1020,13 +1032,13 @@
   toString() => "ThisIndexAccessor()";
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowIndexAssign(null, index, rhs);
 }
 
 class SuperIndexAccessor<Arguments> extends kernel.SuperIndexAccessor<Arguments>
     with FastaAccessor<Arguments> {
-  SuperIndexAccessor(BuilderHelper helper, Token token, Expression index,
+  SuperIndexAccessor(BuilderHelper helper, Token token, kernel.Expression index,
       Member getter, Member setter)
       : super(helper, index, getter, setter, token);
 
@@ -1034,7 +1046,7 @@
 
   String get plainNameForWrite => "[]=";
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return helper.buildMethodInvocation(
         buildSimpleRead(), callName, arguments, offset,
         isImplicitCall: true);
@@ -1043,7 +1055,7 @@
   toString() => "SuperIndexAccessor()";
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowIndexAssign(null, index, rhs, isSuper: true);
 }
 
@@ -1059,7 +1071,7 @@
 
   bool get isThisPropertyAccessor => true;
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     Member interfaceTarget = getter;
     if (interfaceTarget == null) {
       helper.warnUnresolvedMethod(name, offset);
@@ -1077,7 +1089,7 @@
   toString() => "ThisPropertyAccessor()";
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowPropertyAssign(null, rhs);
 }
 
@@ -1085,20 +1097,26 @@
     .NullAwarePropertyAccessor<Arguments> with FastaAccessor<Arguments> {
   final BuilderHelper helper;
 
-  NullAwarePropertyAccessor(this.helper, Token token, Expression receiver,
-      Name name, Member getter, Member setter, DartType type)
+  NullAwarePropertyAccessor(
+      this.helper,
+      Token token,
+      kernel.Expression receiver,
+      Name name,
+      Member getter,
+      Member setter,
+      DartType type)
       : super(helper, receiver, name, getter, setter, type, token);
 
   String get plainNameForRead => name.name;
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return unimplemented("doInvocation", offset, uri);
   }
 
   toString() => "NullAwarePropertyAccessor()";
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowPropertyAssign(receiverExpression, rhs);
 }
 
@@ -1117,7 +1135,7 @@
 
   String get plainNameForRead => variable.name;
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
         adjustForImplicitCall(plainNameForRead, offset),
         isImplicitCall: true);
@@ -1126,7 +1144,7 @@
   toString() => "VariableAccessor()";
 
   @override
-  ShadowComplexAssignment startComplexAssignment(Expression rhs) =>
+  ShadowComplexAssignment startComplexAssignment(kernel.Expression rhs) =>
       new ShadowVariableAssignment(rhs);
 }
 
@@ -1134,11 +1152,11 @@
     with FastaAccessor<Arguments> {
   final String plainNameForRead;
 
-  ReadOnlyAccessor(BuilderHelper helper, Expression expression,
+  ReadOnlyAccessor(BuilderHelper helper, kernel.Expression expression,
       this.plainNameForRead, Token token)
       : super(helper, expression, token);
 
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return helper.buildMethodInvocation(buildSimpleRead(), callName, arguments,
         adjustForImplicitCall(plainNameForRead, offset),
         isImplicitCall: true);
@@ -1152,22 +1170,23 @@
   LargeIntAccessor(BuilderHelper helper, Token token) : super(helper, token);
 
   @override
-  Expression buildError() {
+  kernel.Expression buildError() {
     return helper.buildCompileTimeError(
         templateIntegerLiteralIsOutOfRange.withArguments(token),
         offsetForToken(token),
         lengthForToken(token));
   }
 
-  Expression doInvocation(int offset, Arguments arguments) => buildError();
+  kernel.Expression doInvocation(int offset, Arguments arguments) =>
+      buildError();
 }
 
 class ParenthesizedExpression<Arguments> extends ReadOnlyAccessor<Arguments> {
   ParenthesizedExpression(
-      BuilderHelper helper, Expression expression, Token token)
+      BuilderHelper helper, kernel.Expression expression, Token token)
       : super(helper, expression, null, token);
 
-  Expression makeInvalidWrite(Expression value) {
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
     return helper.deprecated_buildCompileTimeError(
         "Can't assign to a parenthesized expression.", offsetForToken(token));
   }
@@ -1193,7 +1212,7 @@
       Token token)
       : super(helper, null, plainNameForRead, token);
 
-  Expression get expression {
+  kernel.Expression get expression {
     if (super.expression == null) {
       int offset = offsetForToken(token);
       if (declaration is KernelInvalidTypeBuilder) {
@@ -1212,11 +1231,11 @@
     return super.expression;
   }
 
-  Expression makeInvalidWrite(Expression value) {
+  kernel.Expression makeInvalidWrite(kernel.Expression value) {
     return buildThrowNoSuchMethodError(
         forest.literalNull(token),
-        storeOffset(
-            forest.arguments(<Expression>[value], null), value.fileOffset),
+        storeOffset(forest.arguments(<kernel.Expression>[value], null),
+            value.fileOffset),
         isSetter: true);
   }
 
@@ -1320,7 +1339,7 @@
   }
 
   @override
-  Expression doInvocation(int offset, Arguments arguments) {
+  kernel.Expression doInvocation(int offset, Arguments arguments) {
     return helper.buildConstructorInvocation(declaration, token, arguments, "",
         null, token.charOffset, Constness.implicit);
   }
@@ -1339,7 +1358,7 @@
 
   UnresolvedAccessor(this.helper, this.name, this.token);
 
-  Expression doInvocation(int charOffset, Arguments arguments) {
+  kernel.Expression doInvocation(int charOffset, Arguments arguments) {
     return buildError(arguments, offset: charOffset);
   }
 
@@ -1354,7 +1373,7 @@
   }
 
   @override
-  Expression buildError(Arguments arguments,
+  kernel.Expression buildError(Arguments arguments,
       {bool isGetter: false, bool isSetter: false, int offset}) {
     offset ??= offsetForToken(this.token);
     return helper.throwNoSuchMethodError(
diff --git a/pkg/front_end/lib/src/fasta/kernel/forest.dart b/pkg/front_end/lib/src/fasta/kernel/forest.dart
index 49d9333..c194492 100644
--- a/pkg/front_end/lib/src/fasta/kernel/forest.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/forest.dart
@@ -5,8 +5,7 @@
 library fasta.forest;
 
 // TODO(ahe): Remove this import.
-import 'package:kernel/ast.dart' as kernel show Arguments;
-import 'package:kernel/ast.dart';
+import 'package:kernel/ast.dart' as kernel show Arguments, DartType;
 
 /// A tree factory.
 ///
@@ -43,16 +42,15 @@
 
   /// Return a representation of a list literal. The [constKeyword] is the
   /// location of the `const` keyword, or `null` if there is no keyword. The
-  /// [isConst] is `true` if either the `const` keyword is not-`null` or if the
-  /// list literal is in a const context. The [typeArgument] is the
-  /// representation of the single valid type argument preceding the list
-  /// literal, or `null` if there is no type argument, there is more than one
-  /// type argument, or if the type argument cannot be resolved. The
-  /// [typeArguments] is the representation of all of the type arguments
-  /// preceding the list literal, or `null` if there are no type arguments. The
-  /// [leftBracket] is the location of the `[`. The list of [expressions] is a
-  /// list of the representations of the list elements. The [rightBracket] is
-  /// the location of the `]`.
+  /// [isConst] is `true` if the literal is either explicitly or implicitly a
+  /// constant. The [typeArgument] is the representation of the single valid
+  /// type argument preceding the list literal, or `null` if there is no type
+  /// argument, there is more than one type argument, or if the type argument
+  /// cannot be resolved. The [typeArguments] is the representation of all of
+  /// the type arguments preceding the list literal, or `null` if there are no
+  /// type arguments. The [leftBracket] is the location of the `[`. The list of
+  /// [expressions] is a list of the representations of the list elements. The
+  /// [rightBracket] is the location of the `]`.
   Expression literalList(
       Location constKeyword,
       bool isConst,
@@ -64,18 +62,17 @@
 
   /// Return a representation of a map literal. The [constKeyword] is the
   /// location of the `const` keyword, or `null` if there is no keyword. The
-  /// [isConst] is `true` if either the `const` keyword is not-`null` or if the
-  /// map literal is in a const context. The [keyType] is the representation of
-  /// the first type argument preceding the map literal, or `null` if there are
-  /// not exactly two type arguments or if the first type argument cannot be
-  /// resolved. The [valueType] is the representation of the second type
-  /// argument preceding the map literal, or `null` if there are not exactly two
-  /// type arguments or if the second type argument cannot be resolved. The
-  /// [typeArguments] is the representation of all of the type arguments
-  /// preceding the map literal, or `null` if there are no type arguments. The
-  /// [leftBracket] is the location of the `{`. The list of [entries] is a
-  /// list of the representations of the map entries. The [rightBracket] is
-  /// the location of the `}`.
+  /// [isConst] is `true` if the literal is either explicitly or implicitly a
+  /// constant. The [keyType] is the representation of the first type argument
+  /// preceding the map literal, or `null` if there are not exactly two type
+  /// arguments or if the first type argument cannot be resolved. The
+  /// [valueType] is the representation of the second type argument preceding
+  /// the map literal, or `null` if there are not exactly two type arguments or
+  /// if the second type argument cannot be resolved. The [typeArguments] is the
+  /// representation of all of the type arguments preceding the map literal, or
+  /// `null` if there are no type arguments. The [leftBracket] is the location
+  /// of the `{`. The list of [entries] is a list of the representations of the
+  /// map entries. The [rightBracket] is the location of the `}`.
   Expression literalMap(
       Location constKeyword,
       bool isConst,
@@ -112,11 +109,11 @@
 
   /// Given a representation of a list of [typeArguments], return the number of
   /// type arguments in the list.
-  int getTypeCount(Object typeArguments);
+  int getTypeCount(covariant typeArguments);
 
   /// Given a representation of a list of [typeArguments], return the type
   /// associated with the argument at the given [index].
-  DartType getTypeAt(Object typeArguments, int index);
+  kernel.DartType getTypeAt(covariant typeArguments, int index);
 
   Expression loadLibrary(covariant dependency);
 
@@ -128,9 +125,10 @@
   Expression awaitExpression(Expression operand, Location location);
 
   /// Return a representation of a conditional expression. The [condition] is
-  /// the condition. The [question] is the `?`. The [thenExpression] is the
-  /// expression following the question mark. The [colon] is the `:`. The
-  /// [elseExpression] is the expression following the colon.
+  /// the expression preceding the question mark. The [question] is the `?`. The
+  /// [thenExpression] is the expression following the question mark. The
+  /// [colon] is the `:`. The [elseExpression] is the expression following the
+  /// colon.
   Expression conditionalExpression(Expression condition, Location question,
       Expression thenExpression, Location colon, Expression elseExpression);
 
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 d384b5a..b2cad0c 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
@@ -83,7 +83,6 @@
         ShadowIllegalAssignment,
         ShadowIndexAssign,
         ShadowInvalidInitializer,
-        ShadowIsNotExpression,
         ShadowLabeledStatement,
         ShadowLogicalExpression,
         ShadowLoopAssignmentStatement,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
new file mode 100644
index 0000000..e825cf4
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_body_builder.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library fasta.kernel_body_builder;
+
+import 'package:kernel/ast.dart' show Arguments, Expression, Statement;
+
+import '../scanner.dart' show Token;
+
+import '../type_inference/type_inferrer.dart' show TypeInferrer;
+
+import 'body_builder.dart' show BodyBuilder;
+
+import 'fangorn.dart' show Fangorn;
+
+import 'forest.dart' show Forest;
+
+import 'kernel_api.dart' show ClassHierarchy, CoreTypes;
+
+import 'kernel_builder.dart'
+    show KernelClassBuilder, KernelLibraryBuilder, ModifierBuilder, Scope;
+
+class KernelBodyBuilder extends BodyBuilder<Expression, Statement, Arguments> {
+  @override
+  final Forest<Expression, Statement, Token, Arguments> forest =
+      const Fangorn();
+
+  KernelBodyBuilder(
+      KernelLibraryBuilder library,
+      ModifierBuilder member,
+      Scope scope,
+      Scope formalParameterScope,
+      ClassHierarchy hierarchy,
+      CoreTypes coreTypes,
+      KernelClassBuilder classBuilder,
+      bool isInstanceMember,
+      Uri uri,
+      TypeInferrer typeInferrer)
+      : super(library, member, scope, formalParameterScope, hierarchy,
+            coreTypes, classBuilder, isInstanceMember, uri, typeInferrer);
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
index 0e60a3e..4c7ec10 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_field_builder.dart
@@ -22,7 +22,7 @@
 
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 
-import 'body_builder.dart' show BodyBuilder;
+import 'kernel_body_builder.dart' show KernelBodyBuilder;
 
 import 'kernel_builder.dart'
     show Builder, FieldBuilder, KernelTypeBuilder, MetadataBuilder;
@@ -95,7 +95,7 @@
       var typeInferrer = typeInferenceEngine.createTopLevelTypeInferrer(
           field.enclosingClass?.thisType, field);
       if (hasInitializer) {
-        var bodyBuilder = new BodyBuilder(
+        KernelBodyBuilder bodyBuilder = new KernelBodyBuilder(
             library,
             this,
             memberScope,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index b4c9192..71372b9 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -34,6 +34,7 @@
 import 'package:front_end/src/fasta/type_inference/type_schema_elimination.dart';
 import 'package:front_end/src/fasta/type_inference/type_schema_environment.dart';
 import 'package:kernel/ast.dart' hide InvalidExpression, InvalidInitializer;
+import 'package:kernel/clone.dart' show CloneVisitor;
 import 'package:kernel/frontend/accessors.dart';
 import 'package:kernel/type_algebra.dart';
 
@@ -879,6 +880,7 @@
     }
     inferrer.inferStatement(body);
     if (_declaresVariable) {
+      inferrer.inferMetadataKeepingHelper(variable.annotations);
       var tempVar =
           new VariableDeclaration(null, type: inferredType, isFinal: true);
       var variableGet = new VariableGet(tempVar)
@@ -941,6 +943,7 @@
 
   @override
   void _inferStatement(ShadowTypeInferrer inferrer) {
+    inferrer.inferMetadataKeepingHelper(variable.annotations);
     inferrer.inferLocalFunction(
         function,
         null,
@@ -2270,6 +2273,26 @@
 
   @override
   void _inferStatement(ShadowTypeInferrer inferrer) {
+    inferrer.inferMetadataKeepingHelper(annotations);
+
+    // After the inference was done on the annotations, we may clone them for
+    // this instance of VariableDeclaration in order to avoid having the same
+    // annotation node for two VariableDeclaration nodes in a situation like
+    // the following:
+    //
+    //     class Foo { const Foo(List<String> list); }
+    //
+    //     @Foo(const [])
+    //     var x, y;
+    CloneVisitor cloner = new CloneVisitor();
+    for (int i = 0; i < annotations.length; ++i) {
+      Expression annotation = annotations[i];
+      if (annotation.parent != this) {
+        annotations[i] = cloner.clone(annotation);
+        annotations[i].parent = this;
+      }
+    }
+
     var declaredType = _implicitlyTyped ? const UnknownType() : type;
     DartType inferredType;
     DartType initializerType;
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
index 9d57e58..b9bbf76 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context.dart
@@ -88,13 +88,12 @@
       isContinuation: true);
 
   /// Identifier is the type name being declared by an enum declaration.
-  static const enumDeclaration = const IdentifierContext('enumDeclaration',
-      inDeclaration: true, isBuiltInIdentifierAllowed: false);
+  static const enumDeclaration = const EnumDeclarationIdentifierContext();
 
   /// Identifier is an enumerated value name being declared by an enum
   /// declaration.
   static const enumValueDeclaration =
-      const IdentifierContext('enumValueDeclaration', inDeclaration: true);
+      const EnumValueDeclarationIdentifierContext();
 
   /// Identifier is the name being declared by a class declaration or a named
   /// mixin application, for example, `Foo` in `class Foo = X with Y;`.
@@ -121,9 +120,8 @@
       const TypeReferenceIdentifierContext.continuation();
 
   /// Identifier is a name being declared by a top level variable declaration.
-  static const topLevelVariableDeclaration = const IdentifierContext(
-      'topLevelVariableDeclaration',
-      inDeclaration: true);
+  static const topLevelVariableDeclaration =
+      const TopLevelVariableIdentifierContext();
 
   /// Identifier is a name being declared by a field declaration.
   static const fieldDeclaration = const FieldDeclarationIdentifierContext();
diff --git a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
index 99a9c48..f18b2ac 100644
--- a/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/identifier_context_impl.dart
@@ -15,7 +15,7 @@
 import 'type_info.dart'
     show insertSyntheticIdentifierAfter, isValidTypeReference;
 
-import 'util.dart' show optional, skipMetadata;
+import 'util.dart' show optional;
 
 /// See [IdentifierContext.classOrNamedMixinDeclaration].
 class ClassOrNamedMixinIdentifierContext extends IdentifierContext {
@@ -39,7 +39,7 @@
           message: fasta.templateExpectedIdentifier.withArguments(identifier));
     } else if (identifier.type.isBuiltIn) {
       parser.reportRecoverableErrorWithToken(
-          identifier, fasta.templateBuiltInIdentifierAsType);
+          identifier, fasta.templateBuiltInIdentifierInDeclaration);
     } else {
       parser.reportRecoverableErrorWithToken(
           identifier, fasta.templateExpectedIdentifier);
@@ -95,6 +95,69 @@
   }
 }
 
+/// See [IdentifierContext.enumDeclaration].
+class EnumDeclarationIdentifierContext extends IdentifierContext {
+  const EnumDeclarationIdentifierContext()
+      : super('enumDeclaration',
+            inDeclaration: true, isBuiltInIdentifierAllowed: false);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.type.isPseudo) {
+      return identifier;
+    }
+
+    // Recovery
+    if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
+        isOneOfOrEof(identifier, const ['{'])) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else if (identifier.type.isBuiltIn) {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateBuiltInIdentifierInDeclaration);
+    } else {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+      if (!identifier.isKeywordOrIdentifier) {
+        // When in doubt, consume the token to ensure we make progress
+        // but insert a synthetic identifier to satisfy listeners.
+        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+      }
+    }
+    return identifier;
+  }
+}
+
+/// See [IdentifierContext.enumValueDeclaration].
+class EnumValueDeclarationIdentifierContext extends IdentifierContext {
+  const EnumValueDeclarationIdentifierContext()
+      : super('enumValueDeclaration', inDeclaration: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    if (identifier.isIdentifier) {
+      return identifier;
+    }
+
+    // Recovery
+    parser.reportRecoverableErrorWithToken(
+        identifier, fasta.templateExpectedIdentifier);
+    if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
+        isOneOfOrEof(identifier, const [',', '}'])) {
+      return insertSyntheticIdentifierAfter(token, parser);
+    } else if (!identifier.isKeywordOrIdentifier) {
+      // When in doubt, consume the token to ensure we make progress
+      // but insert a synthetic identifier to satisfy listeners.
+      return insertSyntheticIdentifierAfter(identifier, parser);
+    }
+    return identifier;
+  }
+}
+
 /// See [IdentifierContext.expression].
 class ExpressionIdentifierContext extends IdentifierContext {
   const ExpressionIdentifierContext()
@@ -248,10 +311,12 @@
   Token ensureIdentifier(Token token, Parser parser) {
     Token identifier = token.next;
     assert(identifier.kind != IDENTIFIER_TOKEN);
+    const followingValues = const ['.', ';'];
+
     if (identifier.isIdentifier) {
       Token next = identifier.next;
-      if (isOneOfOrEof(next, const ['.', ';']) ||
-          !looksLikeStartOfNextTopLevelDeclaration(identifier)) {
+      if (!looksLikeStartOfNextTopLevelDeclaration(identifier) ||
+          isOneOfOrEof(next, followingValues)) {
         return identifier;
       }
       // Although this is a valid library name, the library declaration
@@ -260,7 +325,7 @@
     }
 
     // Recovery
-    if (isOneOfOrEof(identifier, const ['.', ';']) ||
+    if (isOneOfOrEof(identifier, followingValues) ||
         looksLikeStartOfNextTopLevelDeclaration(identifier)) {
       identifier = parser.insertSyntheticIdentifier(token, this,
           message: fasta.templateExpectedIdentifier.withArguments(identifier));
@@ -348,6 +413,49 @@
   }
 }
 
+/// See [IdentifierContext.topLevelVariableDeclaration].
+class TopLevelVariableIdentifierContext extends IdentifierContext {
+  const TopLevelVariableIdentifierContext()
+      : super('topLevelVariableDeclaration', inDeclaration: true);
+
+  @override
+  Token ensureIdentifier(Token token, Parser parser) {
+    Token identifier = token.next;
+    assert(identifier.kind != IDENTIFIER_TOKEN);
+    const followingValues = const [';', '=', ','];
+
+    if (identifier.isIdentifier) {
+      Token next = identifier.next;
+      if (!looksLikeStartOfNextTopLevelDeclaration(identifier) ||
+          isOneOfOrEof(next, followingValues)) {
+        return identifier;
+      }
+      // Although this is a valid top level var name, the var declaration
+      // is invalid and this looks like the start of the next declaration.
+      // In this situation, fall through to insert a synthetic var name.
+    }
+
+    // Recovery
+    if (looksLikeStartOfNextTopLevelDeclaration(identifier) ||
+        isOneOfOrEof(identifier, followingValues)) {
+      identifier = parser.insertSyntheticIdentifier(token, this,
+          message: fasta.templateExpectedIdentifier.withArguments(identifier));
+    } else if (identifier.type.isBuiltIn) {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateBuiltInIdentifierInDeclaration);
+    } else {
+      parser.reportRecoverableErrorWithToken(
+          identifier, fasta.templateExpectedIdentifier);
+      if (!identifier.isKeywordOrIdentifier) {
+        // When in doubt, consume the token to ensure we make progress
+        // but insert a synthetic identifier to satisfy listeners.
+        identifier = insertSyntheticIdentifierAfter(identifier, parser);
+      }
+    }
+    return identifier;
+  }
+}
+
 /// See [IdentifierContext].typedefDeclaration
 class TypedefDeclarationIdentifierContext extends IdentifierContext {
   const TypedefDeclarationIdentifierContext()
@@ -409,20 +517,6 @@
     assert(next.kind != IDENTIFIER_TOKEN);
     if (isValidTypeReference(next)) {
       return next;
-    }
-
-    // Recovery: skip over any annotations
-    while (optional('@', next)) {
-      // TODO(danrubel): Improve this error message to indicate that an
-      // annotation is not allowed before type arguments.
-      parser.reportRecoverableErrorWithToken(
-          next, fasta.templateUnexpectedToken);
-      token = skipMetadata(token);
-      next = token.next;
-    }
-
-    if (isValidTypeReference(next)) {
-      return next;
     } else if (next.isKeywordOrIdentifier) {
       if (optional("void", next)) {
         parser.reportRecoverableError(next, fasta.messageInvalidVoid);
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 79786ca..5c3e99c 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1047,12 +1047,12 @@
   }
 
   void handleLiteralList(
-      int count, Token beginToken, Token constKeyword, Token endToken) {
+      int count, Token leftBracket, Token constKeyword, Token rightBracket) {
     logEvent("LiteralList");
   }
 
   void handleLiteralMap(
-      int count, Token beginToken, Token constKeyword, Token endToken) {
+      int count, Token leftBrace, Token constKeyword, Token rightBrace) {
     logEvent("LiteralMap");
   }
 
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 2ef4384..53154e7 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -87,6 +87,7 @@
     show
         TypeInfo,
         TypeParamOrArgInfo,
+        computeMethodTypeArguments,
         computeType,
         computeTypeParamOrArg,
         isGeneralizedFunctionType,
@@ -94,8 +95,6 @@
         noType,
         noTypeParamOrArg;
 
-import 'type_info_impl.dart' show skipTypeVariables;
-
 import 'util.dart' show optional;
 
 /// An event generating parser of Dart programs. This parser expects all tokens
@@ -332,9 +331,12 @@
       listener.endTopLevelDeclaration(token.next);
       count++;
       if (start == token.next) {
+        // Recovery:
         // If progress has not been made reaching the end of the token stream,
         // then report an error and skip the current token.
         token = token.next;
+        listener.beginMetadataStar(token);
+        listener.endMetadataStar(0);
         reportRecoverableErrorWithToken(
             token, fasta.templateExpectedDeclaration);
         listener.handleInvalidTopLevelDeclaration(token);
@@ -443,15 +445,26 @@
       return parseScript(token);
     }
     token = parseMetadataStar(token);
-    if (token.next.isTopLevelKeyword) {
+    Token next = token.next;
+    if (next.isTopLevelKeyword) {
       return parseTopLevelKeywordDeclaration(token, null, directiveState);
     }
     Token start = token;
     // Skip modifiers to find a top level keyword or identifier
-    while (token.next.isModifier) {
-      token = token.next;
+    if (next.isModifier) {
+      if (optional('var', next) ||
+          ((optional('const', next) || optional('final', next)) &&
+              // Ignore `const class` and `final class` so that it is reported
+              // below as an invalid modifier on a class.
+              !optional('class', next.next))) {
+        directiveState?.checkDeclaration();
+        return parseTopLevelMemberImpl(token);
+      }
+      while (token.next.isModifier) {
+        token = token.next;
+      }
     }
-    Token next = token.next;
+    next = token.next;
     if (next.isTopLevelKeyword) {
       Token beforeAbstractToken;
       Token beforeModifier = start;
@@ -915,10 +928,10 @@
   /// ```
   Token parseTypeList(Token token) {
     listener.beginTypeList(token.next);
-    token = parseType(token);
+    token = computeType(token, true).ensureTypeOrVoid(token, this);
     int count = 1;
     while (optional(',', token.next)) {
-      token = parseType(token.next);
+      token = computeType(token.next, true).ensureTypeOrVoid(token.next, this);
       count++;
     }
     listener.endTypeList(count);
@@ -1006,7 +1019,7 @@
     if (optional("<", token.next)) {
       reportRecoverableError(token.next, fasta.messageMetadataTypeArguments);
     }
-    token = parseTypeArgumentsOpt(token);
+    token = computeTypeParamOrArg(token).parseArguments(token, this);
     Token period = null;
     if (optional('.', token.next)) {
       period = token.next;
@@ -1508,22 +1521,6 @@
     return token;
   }
 
-  /// Returns `true` if [token] matches '<' type (',' type)* '>' '(', and
-  /// otherwise returns `false`. The final '(' is not part of the grammar
-  /// construct `typeArguments`, but it is required here such that type
-  /// arguments in generic method invocations can be recognized, and as few as
-  /// possible other constructs will pass (e.g., 'a < C, D > 3').
-  bool isValidMethodTypeArguments(Token token) {
-    // TODO(danrubel): Replace call with a call to computeTypeVar.
-    if (optional('<', token)) {
-      Token endGroup = skipTypeVariables(token);
-      if (endGroup != null && optional('(', endGroup.next)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   /// ```
   /// qualified:
   ///   identifier qualifiedRest*
@@ -1614,7 +1611,12 @@
           break;
         } else {
           // Recovery
-          if (next.isIdentifier) {
+          Token endGroup = leftBrace.endGroup;
+          if (endGroup.isSynthetic) {
+            // The scanner did not place the synthetic '}' correctly.
+            token = rewriter.moveSynthetic(token, endGroup);
+            break;
+          } else if (next.isIdentifier) {
             // If the next token is an identifier, assume a missing comma.
             // TODO(danrubel): Consider improved recovery for missing `}`
             // both here and when the scanner inserts a synthetic `}`
@@ -1929,14 +1931,7 @@
         token = next;
       } else {
         reportRecoverableErrorWithToken(next, context.recoveryTemplate);
-        if (context == IdentifierContext.topLevelVariableDeclaration) {
-          // Since the token is not a keyword or identifier, consume it to
-          // ensure forward progress in parseField.
-          token = next.next;
-          // Supply a non-empty method name so that it does not accidentally
-          // match the default constructor.
-          token = insertSyntheticIdentifier(next, context);
-        } else if (context == IdentifierContext.constructorReference) {
+        if (context == IdentifierContext.constructorReference) {
           token = insertSyntheticIdentifier(token, context);
         } else {
           token = next;
@@ -2008,10 +2003,6 @@
       followingValues = [';'];
     } else if (context == IdentifierContext.constructorReferenceContinuation) {
       followingValues = ['.', ',', '(', ')', '[', ']', '}', ';'];
-    } else if (context == IdentifierContext.enumDeclaration) {
-      followingValues = ['{'];
-    } else if (context == IdentifierContext.enumValueDeclaration) {
-      followingValues = [',', '}'];
     } else if (context == IdentifierContext.formalParameterDeclaration) {
       followingValues = [':', '=', ',', '(', ')', '[', ']', '{', '}'];
     } else if (context == IdentifierContext.labelDeclaration) {
@@ -2026,8 +2017,6 @@
       followingValues = ['.', '(', '{', '=>'];
     } else if (context == IdentifierContext.topLevelFunctionDeclaration) {
       followingValues = ['(', '{', '=>'];
-    } else if (context == IdentifierContext.topLevelVariableDeclaration) {
-      followingValues = [';', '=', ','];
     } else if (context == IdentifierContext.typeVariableDeclaration) {
       followingValues = ['<', '>', ';', '}'];
     } else {
@@ -2082,9 +2071,7 @@
     // could create a method to test whether a given token matches one of the
     // patterns.
     List<String> initialKeywords;
-    if (context == IdentifierContext.enumDeclaration) {
-      initialKeywords = topLevelKeywords();
-    } else if (context == IdentifierContext.formalParameterDeclaration) {
+    if (context == IdentifierContext.formalParameterDeclaration) {
       initialKeywords = topLevelKeywords()
         ..addAll(classMemberKeywords())
         ..addAll(statementKeywords())
@@ -2100,8 +2087,6 @@
       initialKeywords = statementKeywords();
     } else if (context == IdentifierContext.topLevelFunctionDeclaration) {
       initialKeywords = topLevelKeywords();
-    } else if (context == IdentifierContext.topLevelVariableDeclaration) {
-      initialKeywords = topLevelKeywords();
     } else if (context == IdentifierContext.typeVariableDeclaration) {
       initialKeywords = topLevelKeywords()
         ..addAll(classMemberKeywords())
@@ -2522,14 +2507,23 @@
           next = token.next;
         }
         if (isModifier(next)) {
-          ModifierRecoveryContext context = new ModifierRecoveryContext(this);
-          token = context.parseTopLevelModifiers(token,
-              externalToken: externalToken, varFinalOrConst: varFinalOrConst);
-          next = token.next;
+          // Recovery
+          if (varFinalOrConst != null &&
+              (optional('final', next) ||
+                  optional('var', next) ||
+                  optional('const', next))) {
+            // If another `var`, `final`, or `const` then fall through
+            // to parse that as part of the next top level declaration.
+          } else {
+            ModifierRecoveryContext context = new ModifierRecoveryContext(this);
+            token = context.parseTopLevelModifiers(token,
+                externalToken: externalToken, varFinalOrConst: varFinalOrConst);
+            next = token.next;
 
-          externalToken = context.externalToken;
-          varFinalOrConst = context.varFinalOrConst;
-          context = null;
+            externalToken = context.externalToken;
+            varFinalOrConst = context.varFinalOrConst;
+            context = null;
+          }
         }
       }
     }
@@ -2746,7 +2740,7 @@
       token = parseExpression(next);
       listener.endFieldInitializer(assignment, token.next);
     } else {
-      if (varFinalOrConst != null) {
+      if (varFinalOrConst != null && !name.isSynthetic) {
         if (optional("const", varFinalOrConst)) {
           reportRecoverableError(
               name,
@@ -3572,7 +3566,7 @@
     listener.beginConstructorReference(start);
     token = parseQualifiedRestOpt(
         start, IdentifierContext.constructorReferenceContinuation);
-    token = parseTypeArgumentsOpt(token);
+    token = computeTypeParamOrArg(token).parseArguments(token, this);
     Token period = null;
     if (optional('.', token.next)) {
       period = token.next;
@@ -4115,9 +4109,8 @@
     TokenType type = next.type;
     int tokenLevel = type.precedence;
     Token typeArguments;
-    TypeParamOrArgInfo typeArg = computeTypeParamOrArg(token);
-    if (typeArg != noTypeParamOrArg &&
-        optional('(', typeArg.skip(token).next)) {
+    TypeParamOrArgInfo typeArg = computeMethodTypeArguments(token);
+    if (typeArg != noTypeParamOrArg) {
       // For example a(b)<T>(c), where token is before '<'.
       typeArguments = next;
       token = typeArg.parseArguments(token, this);
@@ -4224,10 +4217,11 @@
         listener.endBinaryExpression(period);
       }
       Token typeArguments;
-      if (isValidMethodTypeArguments(next)) {
+      TypeParamOrArgInfo typeArg = computeMethodTypeArguments(token);
+      if (typeArg != noTypeParamOrArg) {
         // For example a(b)..<T>(c), where token is '<'.
         typeArguments = next;
-        token = parseTypeArgumentsOpt(token);
+        token = typeArg.parseArguments(token, this);
         next = token.next;
         assert(optional('(', next));
       }
@@ -4327,12 +4321,7 @@
         next = token.next;
       } else if (optional('(', next)) {
         if (typeArguments == null) {
-          if (isValidMethodTypeArguments(next)) {
-            token = parseTypeArgumentsOpt(token);
-            next = token.next;
-          } else {
-            listener.handleNoTypeArguments(next);
-          }
+          listener.handleNoTypeArguments(next);
         }
         token = parseArguments(token);
         next = token.next;
@@ -4646,7 +4635,7 @@
       token = parseTypeVariablesOpt(token);
       return parseLiteralFunctionSuffix(token);
     } else {
-      token = parseTypeArgumentsOpt(token);
+      token = computeTypeParamOrArg(token).parseArguments(token, this);
       Token next = token.next;
       if (optional('{', next)) {
         return parseLiteralMapSuffix(token, constKeyword);
@@ -4918,8 +4907,9 @@
 
   Token parseSend(Token token, IdentifierContext context) {
     Token beginToken = token = ensureIdentifier(token, context);
-    if (isValidMethodTypeArguments(token.next)) {
-      token = parseTypeArgumentsOpt(token);
+    TypeParamOrArgInfo typeArg = computeMethodTypeArguments(token);
+    if (typeArg != noTypeParamOrArg) {
+      token = typeArg.parseArguments(token, this);
     } else {
       listener.handleNoTypeArguments(token.next);
     }
diff --git a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
index b80a0a9..d5b8eae 100644
--- a/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
+++ b/pkg/front_end/lib/src/fasta/parser/token_stream_rewriter.dart
@@ -83,7 +83,8 @@
 
     // A no-op rewriter could simply return `>>` here.
 
-    Token gt1 = new SimpleToken(TokenType.GT, gtgt.charOffset);
+    Token gt1 =
+        new SimpleToken(TokenType.GT, gtgt.charOffset, gtgt.precedingComments);
     Token gt2 = gt1.setNext(new SimpleToken(TokenType.GT, gt1.charOffset + 1));
     gt2.setNext(gtgt.next);
 
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info.dart b/pkg/front_end/lib/src/fasta/parser/type_info.dart
index 0addae0..b70a1e2 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info.dart
@@ -150,7 +150,8 @@
         if ((!identical('get', value) &&
             !identical('set', value) &&
             !identical('factory', value) &&
-            !identical('operator', value))) {
+            !identical('operator', value) &&
+            !(identical('typedef', value) && next.next.isIdentifier))) {
           return new ComplexTypeInfo(token, typeParamOrArg)
               .computeBuiltinAsType(required);
         }
@@ -279,3 +280,15 @@
   // TODO(danrubel): Consider adding additional const for common situations.
   return new ComplexTypeParamOrArgInfo(token).compute(innerEndGroup);
 }
+
+/// Called by the parser to obtain information about a possible group of type
+/// type arguments that follow [token] and that are followed by '('.
+/// Returns the type arguments if [token] matches '<' type (',' type)* '>' '(',
+/// and otherwise returns [noTypeParamOrArg]. The final '(' is not part of the
+/// grammar construct `typeArguments`, but it is required here such that type
+/// arguments in generic method invocations can be recognized, and as few as
+/// possible other constructs will pass (e.g., 'a < C, D > 3').
+TypeParamOrArgInfo computeMethodTypeArguments(Token token) {
+  TypeParamOrArgInfo typeArg = computeTypeParamOrArg(token);
+  return optional('(', typeArg.skip(token).next) ? typeArg : noTypeParamOrArg;
+}
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index 4120e05..376d485 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -8,6 +8,8 @@
 
 import '../fasta_codes.dart' as fasta;
 
+import '../scanner/token_constants.dart' show IDENTIFIER_TOKEN;
+
 import '../util/link.dart' show Link;
 
 import 'identifier_context.dart' show IdentifierContext;
@@ -214,7 +216,13 @@
 }
 
 bool looksLikeName(Token token) =>
-    token.isIdentifier || optional('this', token);
+    token.kind == IDENTIFIER_TOKEN ||
+    optional('this', token) ||
+    (token.isIdentifier &&
+        // Although `typedef` is a legal identifier,
+        // type `typedef` identifier is not legal and in this situation
+        // `typedef` is probably a separate declaration.
+        (!optional('typedef', token) || !token.next.isIdentifier));
 
 Token skipTypeVariables(Token token) {
   assert(optional('<', token));
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index 3f9ee22..5cf8451 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -24,7 +24,7 @@
 import '../fasta_codes.dart'
     show Message, messageExpectedBlockToSkip, templateInternalProblemNotFound;
 
-import '../kernel/body_builder.dart' show BodyBuilder;
+import '../kernel/kernel_body_builder.dart' show KernelBodyBuilder;
 
 import '../parser.dart' show IdentifierContext, MemberKind, Parser, optional;
 
@@ -536,8 +536,17 @@
     ConstantContext constantContext = builder.isConstructor && builder.isConst
         ? ConstantContext.inferred
         : ConstantContext.none;
-    return new BodyBuilder(library, builder, memberScope, formalParameterScope,
-        hierarchy, coreTypes, currentClass, isInstanceMember, uri, typeInferrer)
+    return new KernelBodyBuilder(
+        library,
+        builder,
+        memberScope,
+        formalParameterScope,
+        hierarchy,
+        coreTypes,
+        currentClass,
+        isInstanceMember,
+        uri,
+        typeInferrer)
       ..constantContext = constantContext;
   }
 
diff --git a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
index 25e961f..06f8279 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/interface_resolver.dart
@@ -232,14 +232,8 @@
         : substitution.substituteType(type).accept(needsCheckVisitor);
     for (int i = 0; i < interfacePositionalParameters.length; i++) {
       var parameter = interfacePositionalParameters[i];
-      var isGenericCovariantInterface = needsCheck(parameter.type);
-      if (isGenericCovariantInterface !=
-          parameter.isGenericCovariantInterface) {
-        fixes.add((FunctionNode function) => function.positionalParameters[i]
-            .isGenericCovariantInterface = isGenericCovariantInterface);
-      }
       var isGenericCovariantImpl =
-          isGenericCovariantInterface || parameter.isGenericCovariantImpl;
+          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
       var isCovariant = parameter.isCovariant;
       var superParameter = parameter;
       for (int j = _start; j < _end; j++) {
@@ -275,14 +269,8 @@
     }
     for (int i = 0; i < interfaceNamedParameters.length; i++) {
       var parameter = interfaceNamedParameters[i];
-      var isGenericCovariantInterface = needsCheck(parameter.type);
-      if (isGenericCovariantInterface !=
-          parameter.isGenericCovariantInterface) {
-        fixes.add((FunctionNode function) => function.namedParameters[i]
-            .isGenericCovariantInterface = isGenericCovariantInterface);
-      }
       var isGenericCovariantImpl =
-          isGenericCovariantInterface || parameter.isGenericCovariantImpl;
+          parameter.isGenericCovariantImpl || needsCheck(parameter.type);
       var isCovariant = parameter.isCovariant;
       var superParameter = parameter;
       for (int j = _start; j < _end; j++) {
@@ -317,14 +305,8 @@
     }
     for (int i = 0; i < interfaceTypeParameters.length; i++) {
       var typeParameter = interfaceTypeParameters[i];
-      var isGenericCovariantInterface = needsCheck(typeParameter.bound);
-      if (isGenericCovariantInterface !=
-          typeParameter.isGenericCovariantInterface) {
-        fixes.add((FunctionNode function) => function.typeParameters[i]
-            .isGenericCovariantInterface = isGenericCovariantInterface);
-      }
-      var isGenericCovariantImpl =
-          isGenericCovariantInterface || typeParameter.isGenericCovariantImpl;
+      var isGenericCovariantImpl = typeParameter.isGenericCovariantImpl ||
+          needsCheck(typeParameter.bound);
       var superTypeParameter = typeParameter;
       for (int j = _start; j < _end; j++) {
         var otherMember = _finalizedCandidate(j);
@@ -431,8 +413,7 @@
       return new VariableDeclaration(parameter.name,
           type: substitution.substituteType(parameter.type),
           isCovariant: parameter.isCovariant)
-        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl
-        ..isGenericCovariantInterface = parameter.isGenericCovariantInterface;
+        ..isGenericCovariantImpl = parameter.isGenericCovariantImpl;
     }
 
     var targetTypeParameters = target.function.typeParameters;
@@ -444,9 +425,7 @@
       for (int i = 0; i < targetTypeParameters.length; i++) {
         var targetTypeParameter = targetTypeParameters[i];
         var typeParameter = new TypeParameter(targetTypeParameter.name, null)
-          ..isGenericCovariantImpl = targetTypeParameter.isGenericCovariantImpl
-          ..isGenericCovariantInterface =
-              targetTypeParameter.isGenericCovariantInterface;
+          ..isGenericCovariantImpl = targetTypeParameter.isGenericCovariantImpl;
         typeParameters[i] = typeParameter;
         additionalSubstitution[targetTypeParameter] =
             new TypeParameterType(typeParameter);
@@ -1136,10 +1115,9 @@
   void _recordInstrumentation(Class class_) {
     var uri = class_.fileUri;
     void recordCovariance(int fileOffset, bool isExplicitlyCovariant,
-        bool isGenericCovariantInterface, bool isGenericCovariantImpl) {
+        bool isGenericCovariantImpl) {
       var covariance = <String>[];
       if (isExplicitlyCovariant) covariance.add('explicit');
-      if (isGenericCovariantInterface) covariance.add('genericInterface');
       if (!isExplicitlyCovariant && isGenericCovariantImpl) {
         covariance.add('genericImpl');
       }
@@ -1157,14 +1135,11 @@
       }
       void recordFormalAnnotations(VariableDeclaration formal) {
         recordCovariance(formal.fileOffset, formal.isCovariant,
-            formal.isGenericCovariantInterface, formal.isGenericCovariantImpl);
+            formal.isGenericCovariantImpl);
       }
 
       void recordTypeParameterAnnotations(TypeParameter typeParameter) {
-        recordCovariance(
-            typeParameter.fileOffset,
-            false,
-            typeParameter.isGenericCovariantInterface,
+        recordCovariance(typeParameter.fileOffset, false,
             typeParameter.isGenericCovariantImpl);
       }
 
@@ -1174,8 +1149,8 @@
     }
     for (var field in class_.fields) {
       if (field.isStatic) continue;
-      recordCovariance(field.fileOffset, field.isCovariant,
-          field.isGenericCovariantInterface, field.isGenericCovariantImpl);
+      recordCovariance(
+          field.fileOffset, field.isCovariant, field.isGenericCovariantImpl);
     }
   }
 
@@ -1217,12 +1192,10 @@
       // information is propagated to the getter/setter during type inference.
       var type = member.type;
       var isGenericCovariantImpl = member.isGenericCovariantImpl;
-      var isGenericCovariantInterface = member.isGenericCovariantInterface;
       var isCovariant = member.isCovariant;
       if (setter) {
         var valueParam = new VariableDeclaration('_', type: type)
           ..isGenericCovariantImpl = isGenericCovariantImpl
-          ..isGenericCovariantInterface = isGenericCovariantInterface
           ..isCovariant = isCovariant;
         var function = new FunctionNode(null,
             positionalParameters: [valueParam], returnType: const VoidType());
@@ -1344,13 +1317,5 @@
   }
 
   @override
-  bool get isGenericCovariantInterface => _field.isGenericCovariantInterface;
-
-  @override
-  void set isGenericCovariantInterface(bool value) {
-    _field.isGenericCovariantInterface = value;
-  }
-
-  @override
   DartType get type => _field.type;
 }
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
index d278b10..a6f0aee 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_constraint_gatherer.dart
@@ -42,7 +42,7 @@
 
   /// Tries to match [subtype] against [supertype].
   ///
-  /// If the match suceeds, the resulting type constraints are recorded for
+  /// If the match succeeds, the resulting type constraints are recorded for
   /// later use by [computeConstraints].  If the match fails, the set of type
   /// constraints is unchanged.
   bool trySubtypeMatch(DartType subtype, DartType supertype) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 4971952..719ca60 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -337,6 +337,10 @@
   /// Performs type inference on the given metadata annotations.
   void inferMetadata(BuilderHelper helper, List<Expression> annotations);
 
+  /// Performs type inference on the given metadata annotations keeping the
+  /// existing helper if possible.
+  void inferMetadataKeepingHelper(List<Expression> annotations);
+
   /// Performs type inference on the given function parameter initializer
   /// expression.
   void inferParameterInitializer(
@@ -374,6 +378,9 @@
   void inferMetadata(BuilderHelper helper, List<Expression> annotations) {}
 
   @override
+  void inferMetadataKeepingHelper(List<Expression> annotations) {}
+
+  @override
   void inferParameterInitializer(
       BuilderHelper helper, Expression initializer, DartType declaredType) {}
 }
@@ -1100,6 +1107,7 @@
       var positionalParameters = function.positionalParameters;
       for (var i = 0; i < positionalParameters.length; i++) {
         var parameter = positionalParameters[i];
+        inferMetadataKeepingHelper(parameter.annotations);
         if (i >= function.requiredParameterCount &&
             parameter.initializer == null) {
           parameter.initializer = new ShadowNullLiteral()..parent = parameter;
@@ -1109,6 +1117,7 @@
         }
       }
       for (var parameter in function.namedParameters) {
+        inferMetadataKeepingHelper(parameter.annotations);
         if (parameter.initializer == null) {
           parameter.initializer = new ShadowNullLiteral()..parent = parameter;
         }
@@ -1239,14 +1248,25 @@
   void inferMetadata(BuilderHelper helper, List<Expression> annotations) {
     if (annotations != null) {
       this.helper = helper;
+      inferMetadataKeepingHelper(annotations);
+      this.helper = null;
+    }
+  }
+
+  @override
+  void inferMetadataKeepingHelper(List<Expression> annotations) {
+    if (annotations != null) {
       // Place annotations in a temporary list literal so that they will have a
       // parent.  This is necessary in case any of the annotations need to get
       // replaced during type inference.
+      var parents = annotations.map((e) => e.parent).toList();
       new ListLiteral(annotations);
       for (var annotation in annotations) {
         inferExpression(annotation, const UnknownType(), false);
       }
-      this.helper = null;
+      for (int i = 0; i < annotations.length; ++i) {
+        annotations[i].parent = parents[i];
+      }
     }
   }
 
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 932840e..f18ea4d 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -10,7 +10,9 @@
 # 2. A suggestion for how to correct the problem (tip).
 #
 # 3. Examples that produce the message (one of expression, statement,
-#    declaration, member, script, or bytes).
+#    declaration, member, script, bytes or external). Note that 'external'
+#    should be the path to an external test. The external test will not be run,
+#    but the existance of the file will be verified.
 #
 # A message shouldn't indicate which kind of diagnostic it is, for example,
 # warning or error. Tools are expected to prepend "Warning: ", or "Error: ",
@@ -43,6 +45,9 @@
 # Long term, the analyzer and front-end need to share the same error codes. So
 # eventually all error codes should have an `analyzerCode` field.
 #
+# In some cases a mesage is internal to the frontend, and no meaningful dart2js
+# nor analyzer code can be provided. In such cases set `frontendInternal: true`.
+#
 # ## Parameter Substitution in Template and Tip
 #
 # The fields `template` and `tip` are subject to parameter substitution. When
@@ -537,13 +542,9 @@
     - "external foo; main(){}"
     - "final class C {}"
     - "abstract enum foo {bar}"
-    - "const enum foo {bar}"
-    - "final enum foo {bar}"
     - "abstract void foo() {}"
     - "static void foo() {}"
     - "abstract typedef foo();"
-    - "const typedef foo();"
-    - "final typedef foo();"
     - "static typedef foo();"
 
 FinalAndCovariant:
diff --git a/pkg/front_end/test/fasta/messages_test.dart b/pkg/front_end/test/fasta/messages_test.dart
index 16f96a5..334a62f 100644
--- a/pkg/front_end/test/fasta/messages_test.dart
+++ b/pkg/front_end/test/fasta/messages_test.dart
@@ -83,6 +83,8 @@
 
       List<String> unknownKeys = <String>[];
       List<Example> examples = <Example>[];
+      String externalTest;
+      bool frontendInternal = false;
       String analyzerCode;
       String dart2jsCode;
       Severity severity;
@@ -103,6 +105,10 @@
             }
             break;
 
+          case "frontendInternal":
+            frontendInternal = value;
+            break;
+
           case "analyzerCode":
             analyzerCode = value;
             break;
@@ -170,6 +176,10 @@
             }
             break;
 
+          case "external":
+            externalTest = node.value;
+            break;
+
           default:
             unknownKeys.add(key);
         }
@@ -213,16 +223,29 @@
           severity != Severity.internalProblem);
 
       yield createDescription(
+          "externalexample",
+          null,
+          exampleAndAnalyzerCodeRequired &&
+                  externalTest != null &&
+                  !(new File(externalTest).existsSync())
+              ? "Given external example for $name points to a nonexisting file."
+              : null);
+
+      yield createDescription(
           "example",
           null,
-          exampleAndAnalyzerCodeRequired && examples.isEmpty
+          exampleAndAnalyzerCodeRequired &&
+                  examples.isEmpty &&
+                  externalTest == null
               ? "No example for $name, please add at least one example."
               : null);
 
       yield createDescription(
           "analyzerCode",
           null,
-          exampleAndAnalyzerCodeRequired && analyzerCode == null
+          exampleAndAnalyzerCodeRequired &&
+                  !frontendInternal &&
+                  analyzerCode == null
               ? "No analyzer code for $name."
                   "\nTry running"
                   " <BUILDDIR>/dart-sdk/bin/dartanalyzer --format=machine"
@@ -234,6 +257,7 @@
           "dart2jsCode",
           null,
           exampleAndAnalyzerCodeRequired &&
+                  !frontendInternal &&
                   analyzerCode != null &&
                   dart2jsCode == null
               ? "No dart2js code for $name."
diff --git a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
index 7aca4b1..679349d 100644
--- a/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
+++ b/pkg/front_end/test/fasta/type_inference/interface_resolver_test.dart
@@ -609,12 +609,9 @@
     var resolvedMethod = node.finalize();
     expect(resolvedMethod, same(method));
     expect(u.isGenericCovariantImpl, isTrue);
-    expect(u.isGenericCovariantInterface, isTrue);
     expect(x.isGenericCovariantImpl, isTrue);
-    expect(x.isGenericCovariantInterface, isTrue);
     expect(x.isCovariant, isFalse);
     expect(y.isGenericCovariantImpl, isTrue);
-    expect(y.isGenericCovariantInterface, isTrue);
     expect(y.isCovariant, isFalse);
   }
 
@@ -627,7 +624,6 @@
     var resolvedAccessor = node.finalize() as SyntheticAccessor;
     expect(SyntheticAccessor.getField(resolvedAccessor), same(field));
     expect(field.isGenericCovariantImpl, isTrue);
-    expect(field.isGenericCovariantInterface, isTrue);
     expect(field.isCovariant, isFalse);
   }
 
@@ -641,14 +637,12 @@
     var resolvedAccessor = node.finalize() as SyntheticAccessor;
     expect(SyntheticAccessor.getField(resolvedAccessor), same(fieldB));
     expect(fieldB.isGenericCovariantImpl, isFalse);
-    expect(fieldB.isGenericCovariantInterface, isFalse);
     expect(fieldB.isCovariant, isTrue);
   }
 
   void test_field_isGenericCovariantImpl_inherited() {
     var typeParameter = new TypeParameter('T', objectType);
     var fieldA = makeField(type: new TypeParameterType(typeParameter))
-      ..isGenericCovariantInterface = true
       ..isGenericCovariantImpl = true;
     var fieldB = makeField(type: numType);
     var a =
@@ -662,7 +656,6 @@
     var resolvedAccessor = node.finalize() as SyntheticAccessor;
     expect(SyntheticAccessor.getField(resolvedAccessor), same(fieldB));
     expect(fieldB.isGenericCovariantImpl, isTrue);
-    expect(fieldB.isGenericCovariantInterface, isFalse);
     expect(fieldB.isCovariant, isFalse);
   }
 
@@ -734,11 +727,9 @@
     var stub = node.finalize();
     var x = stub.function.positionalParameters[0];
     expect(x.isGenericCovariantImpl, isFalse);
-    expect(x.isGenericCovariantInterface, isFalse);
     expect(x.isCovariant, isTrue);
     var y = stub.function.namedParameters[0];
     expect(y.isGenericCovariantImpl, isFalse);
-    expect(y.isGenericCovariantInterface, isFalse);
     expect(y.isCovariant, isTrue);
     expect(stub.forwardingStubInterfaceTarget, same(methodA));
     expect(getStubTarget(stub), same(methodA));
@@ -756,17 +747,14 @@
     var methodB = makeEmptyMethod(typeParameters: [
       new TypeParameter('U', new TypeParameterType(typeParameterB))
         ..isGenericCovariantImpl = true
-        ..isGenericCovariantInterface = true
     ], positionalParameters: [
       new ShadowVariableDeclaration('x', 0,
           type: new TypeParameterType(typeParameterB))
         ..isGenericCovariantImpl = true
-        ..isGenericCovariantInterface = true
     ], namedParameters: [
       new ShadowVariableDeclaration('y', 0,
           type: new TypeParameterType(typeParameterB))
         ..isGenericCovariantImpl = true
-        ..isGenericCovariantInterface = true
     ]);
     var a = makeClass(name: 'A', procedures: [methodA]);
     var b = makeClass(
@@ -779,14 +767,11 @@
     var stub = node.finalize();
     var u = stub.function.typeParameters[0];
     expect(u.isGenericCovariantImpl, isTrue);
-    expect(u.isGenericCovariantInterface, isFalse);
     var x = stub.function.positionalParameters[0];
     expect(x.isGenericCovariantImpl, isTrue);
-    expect(x.isGenericCovariantInterface, isFalse);
     expect(x.isCovariant, isFalse);
     var y = stub.function.namedParameters[0];
     expect(y.isGenericCovariantImpl, isTrue);
-    expect(y.isGenericCovariantInterface, isFalse);
     expect(y.isCovariant, isFalse);
     expect(stub.forwardingStubInterfaceTarget, same(methodA));
     expect(getStubTarget(stub), same(methodA));
@@ -1008,7 +993,6 @@
     var methodB = makeEmptyMethod(positionalParameters: [
       new ShadowVariableDeclaration('x', 0,
           type: new TypeParameterType(typeParamB))
-        ..isGenericCovariantInterface = true
         ..isGenericCovariantImpl = true
     ]);
     var methodC = makeEmptyMethod(positionalParameters: [
diff --git a/pkg/front_end/testcases/annotation_variable_declaration.dart b/pkg/front_end/testcases/annotation_variable_declaration.dart
new file mode 100644
index 0000000..c64fad7
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_variable_declaration.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2018, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+const int foo = 42;
+
+class Bar {
+  const Bar();
+  const Bar.named(x);
+}
+
+class Baz {
+  Baz(@foo constructorFormal);
+
+  factory Baz.bazFactory(@foo factoryFormal) => null;
+
+  fisk(@foo formal1, @Bar() formal2, @Bar.named(foo) formal3,
+      @foo @Bar.named(foo) formal4,
+      [@foo optional]) {
+    @foo
+    var local1;
+
+    @Bar()
+    var local2;
+
+    @Bar.named(foo)
+    var local3;
+
+    @foo
+    @Bar.named(foo)
+    var local4;
+
+    @foo
+    var localWithInitializer = "hello";
+
+    @foo
+    @Bar.named(foo)
+    var localGroupPart1, localGroupPart2;
+
+    naebdyr(@foo nestedFormal) => null;
+
+    var roedmus = (@foo closureFormal) => null;
+  }
+
+  hest({@foo named}) => null;
+}
+
+typedef hest_t({@foo named});
+
+main() {}
diff --git a/pkg/front_end/testcases/annotation_variable_declaration.dart.direct.expect b/pkg/front_end/testcases/annotation_variable_declaration.dart.direct.expect
new file mode 100644
index 0000000..95f1aa8
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_variable_declaration.dart.direct.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef hest_t = ({named: dynamic}) → dynamic;
+class Bar extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+  const constructor named(dynamic x) → void
+    : super core::Object::•()
+    ;
+}
+class Baz extends core::Object {
+  constructor •(@self::foo dynamic constructorFormal) → void
+    : super core::Object::•()
+    ;
+  static factory bazFactory(@self::foo dynamic factoryFormal) → self::Baz
+    return null;
+  method fisk(@self::foo dynamic formal1, @self::Bar::•() dynamic formal2, @self::Bar::named(self::foo) dynamic formal3, @self::foo @self::Bar::named(self::foo) dynamic formal4, [@self::foo dynamic optional = null]) → dynamic {
+    @self::foo dynamic local1;
+    @self::Bar::•() dynamic local2;
+    @self::Bar::named(self::foo) dynamic local3;
+    @self::foo @self::Bar::named(self::foo) dynamic local4;
+    @self::foo dynamic localWithInitializer = "hello";
+    @self::foo @self::Bar::named(self::foo) dynamic localGroupPart1;
+    @self::foo @self::Bar::named(self::foo) dynamic localGroupPart2;
+    function naebdyr(@self::foo dynamic nestedFormal) → dynamic
+      return null;
+    dynamic roedmus = (@self::foo dynamic closureFormal) → dynamic => null;
+  }
+  method hest({@self::foo dynamic named = null}) → dynamic
+    return null;
+}
+static const field core::int foo = 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/annotation_variable_declaration.dart.direct.transformed.expect b/pkg/front_end/testcases/annotation_variable_declaration.dart.direct.transformed.expect
new file mode 100644
index 0000000..95f1aa8
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_variable_declaration.dart.direct.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef hest_t = ({named: dynamic}) → dynamic;
+class Bar extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+  const constructor named(dynamic x) → void
+    : super core::Object::•()
+    ;
+}
+class Baz extends core::Object {
+  constructor •(@self::foo dynamic constructorFormal) → void
+    : super core::Object::•()
+    ;
+  static factory bazFactory(@self::foo dynamic factoryFormal) → self::Baz
+    return null;
+  method fisk(@self::foo dynamic formal1, @self::Bar::•() dynamic formal2, @self::Bar::named(self::foo) dynamic formal3, @self::foo @self::Bar::named(self::foo) dynamic formal4, [@self::foo dynamic optional = null]) → dynamic {
+    @self::foo dynamic local1;
+    @self::Bar::•() dynamic local2;
+    @self::Bar::named(self::foo) dynamic local3;
+    @self::foo @self::Bar::named(self::foo) dynamic local4;
+    @self::foo dynamic localWithInitializer = "hello";
+    @self::foo @self::Bar::named(self::foo) dynamic localGroupPart1;
+    @self::foo @self::Bar::named(self::foo) dynamic localGroupPart2;
+    function naebdyr(@self::foo dynamic nestedFormal) → dynamic
+      return null;
+    dynamic roedmus = (@self::foo dynamic closureFormal) → dynamic => null;
+  }
+  method hest({@self::foo dynamic named = null}) → dynamic
+    return null;
+}
+static const field core::int foo = 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/annotation_variable_declaration.dart.outline.expect b/pkg/front_end/testcases/annotation_variable_declaration.dart.outline.expect
new file mode 100644
index 0000000..6382194
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_variable_declaration.dart.outline.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef hest_t = ({named: dynamic}) → dynamic;
+class Bar extends core::Object {
+  const constructor •() → void
+    ;
+  const constructor named(dynamic x) → void
+    ;
+}
+class Baz extends core::Object {
+  constructor •(dynamic constructorFormal) → void
+    ;
+  static factory bazFactory(dynamic factoryFormal) → self::Baz
+    ;
+  method fisk(dynamic formal1, dynamic formal2, dynamic formal3, dynamic formal4, [dynamic optional]) → dynamic
+    ;
+  method hest({dynamic named}) → dynamic
+    ;
+}
+static const field core::int foo;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/annotation_variable_declaration.dart.strong.expect b/pkg/front_end/testcases/annotation_variable_declaration.dart.strong.expect
new file mode 100644
index 0000000..9ab4cb7
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_variable_declaration.dart.strong.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef hest_t = ({named: dynamic}) → dynamic;
+class Bar extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+  const constructor named(dynamic x) → void
+    : super core::Object::•()
+    ;
+}
+class Baz extends core::Object {
+  constructor •(@self::foo dynamic constructorFormal) → void
+    : super core::Object::•()
+    ;
+  static factory bazFactory(@self::foo dynamic factoryFormal) → self::Baz
+    return null;
+  method fisk(@self::foo dynamic formal1, @self::Bar::•() dynamic formal2, @self::Bar::named(self::foo) dynamic formal3, @self::foo @self::Bar::named(self::foo) dynamic formal4, [@self::foo dynamic optional = null]) → dynamic {
+    @self::foo dynamic local1;
+    @self::Bar::•() dynamic local2;
+    @self::Bar::named(self::foo) dynamic local3;
+    @self::foo @self::Bar::named(self::foo) dynamic local4;
+    @self::foo core::String localWithInitializer = "hello";
+    @self::foo @self::Bar::named(self::foo) dynamic localGroupPart1;
+    @self::foo @self::Bar::named(self::foo) dynamic localGroupPart2;
+    function naebdyr(@self::foo dynamic nestedFormal) → core::Null
+      return null;
+    (dynamic) → core::Null roedmus = (@self::foo dynamic closureFormal) → core::Null => null;
+  }
+  method hest({@self::foo dynamic named = null}) → dynamic
+    return null;
+}
+static const field core::int foo = 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/annotation_variable_declaration.dart.strong.transformed.expect b/pkg/front_end/testcases/annotation_variable_declaration.dart.strong.transformed.expect
new file mode 100644
index 0000000..9ab4cb7
--- /dev/null
+++ b/pkg/front_end/testcases/annotation_variable_declaration.dart.strong.transformed.expect
@@ -0,0 +1,36 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef hest_t = ({named: dynamic}) → dynamic;
+class Bar extends core::Object {
+  const constructor •() → void
+    : super core::Object::•()
+    ;
+  const constructor named(dynamic x) → void
+    : super core::Object::•()
+    ;
+}
+class Baz extends core::Object {
+  constructor •(@self::foo dynamic constructorFormal) → void
+    : super core::Object::•()
+    ;
+  static factory bazFactory(@self::foo dynamic factoryFormal) → self::Baz
+    return null;
+  method fisk(@self::foo dynamic formal1, @self::Bar::•() dynamic formal2, @self::Bar::named(self::foo) dynamic formal3, @self::foo @self::Bar::named(self::foo) dynamic formal4, [@self::foo dynamic optional = null]) → dynamic {
+    @self::foo dynamic local1;
+    @self::Bar::•() dynamic local2;
+    @self::Bar::named(self::foo) dynamic local3;
+    @self::foo @self::Bar::named(self::foo) dynamic local4;
+    @self::foo core::String localWithInitializer = "hello";
+    @self::foo @self::Bar::named(self::foo) dynamic localGroupPart1;
+    @self::foo @self::Bar::named(self::foo) dynamic localGroupPart2;
+    function naebdyr(@self::foo dynamic nestedFormal) → core::Null
+      return null;
+    (dynamic) → core::Null roedmus = (@self::foo dynamic closureFormal) → core::Null => null;
+  }
+  method hest({@self::foo dynamic named = null}) → dynamic
+    return null;
+}
+static const field core::int foo = 42;
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/ast_builder.status b/pkg/front_end/testcases/ast_builder.status
index 0007d0b..cbb6e2d 100644
--- a/pkg/front_end/testcases/ast_builder.status
+++ b/pkg/front_end/testcases/ast_builder.status
@@ -11,13 +11,7 @@
 inference/abstract_class_instantiation: Fail
 inference/constructors_too_many_positional_arguments: Fail
 inference/downwards_inference_annotations: Crash
-inference/downwards_inference_annotations_for_loop_variable: Fail
-inference/downwards_inference_annotations_locals: Fail
-inference/downwards_inference_annotations_locals_referring_to_locals: Fail
-inference/downwards_inference_annotations_parameter: Fail
-inference/downwards_inference_annotations_parameter_local: Fail
 inference/downwards_inference_annotations_type_variable: Fail
-inference/downwards_inference_annotations_type_variable_local: Fail
 inference/downwards_inference_annotations_typedef: Crash
 inference/downwards_inference_on_function_of_t_using_the_t: Fail
 inference/downwards_inference_yield_yield_star: Fail
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/status.status b/pkg/front_end/testcases/incremental_initialize_from_dill/status.status
index 79a60b5..f3d01d2 100644
--- a/pkg/front_end/testcases/incremental_initialize_from_dill/status.status
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/status.status
@@ -3,5 +3,3 @@
 # BSD-style license that can be found in the LICENSE.md file.
 
 # Status file for the test suite ../test/incremental_load_from_dill_yaml_test.dart.
-
-strongmode_mixins_2: Crash
diff --git a/pkg/front_end/testcases/inference/async_await.dart.strong.expect b/pkg/front_end/testcases/inference/async_await.dart.strong.expect
index 79222e9..0865e85 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.strong.expect
@@ -7,7 +7,6 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract forwarding-stub method timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<core::int> onTimeout}) → asy::Future<core::int>;
 }
 static method test() → void async {
   core::int x0;
diff --git a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
index 0c4ef21..2e07d8f 100644
--- a/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/async_await.dart.strong.transformed.expect
@@ -7,7 +7,6 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  abstract forwarding-stub method timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<core::int> onTimeout}) → asy::Future<core::int>;
 }
 static method test() → void /* originally async */ {
   final asy::Completer<dynamic> :completer = asy::Completer::sync<dynamic>();
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.expect
index bce5d96..aa889bc 100644
--- a/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method call([generic-covariant-impl generic-covariant-interface self::ActionDispatcher::P value = null]) → void {}
+  method call([generic-covariant-impl self::ActionDispatcher::P value = null]) → void {}
 }
 class Bar extends core::Object {
   synthetic constructor •() → void
diff --git a/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.transformed.expect
index bce5d96..aa889bc 100644
--- a/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/callable_generic_class.dart.strong.transformed.expect
@@ -6,7 +6,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method call([generic-covariant-impl generic-covariant-interface self::ActionDispatcher::P value = null]) → void {}
+  method call([generic-covariant-impl self::ActionDispatcher::P value = null]) → void {}
 }
 class Bar extends core::Object {
   synthetic constructor •() → void
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
index 80cb335..2994746 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t;
+  generic-covariant-impl field self::C::T t;
   constructor •(self::C::T t) → void
     : self::C::t = t, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
index d1bb8ee..3669a89 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t;
+  generic-covariant-impl field self::C::T t;
   constructor •(self::C::T t) → void
     : self::C::t = t, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
index 72af9d8..39dec86 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  generic-covariant-impl field self::C::T t = null;
   constructor _() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
index cd824ab..6259db5 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  generic-covariant-impl field self::C::T t = null;
   constructor _() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.expect
index 4989080..2b26179 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class A<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::A<self::A::T> f = new self::A::•<self::A::T>();
+  generic-covariant-impl field self::A<self::A::T> f = new self::A::•<self::A::T>();
   constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.transformed.expect
index 4989080..2b26179 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_factory_calls_constructor.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class A<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::A<self::A::T> f = new self::A::•<self::A::T>();
+  generic-covariant-impl field self::A<self::A::T> f = new self::A::•<self::A::T>();
   constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.expect
index b0115e5..e62e839 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  generic-covariant-impl field self::C::T t = null;
   constructor named(core::List<self::C::T> t) → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.transformed.expect
index b0115e5..e62e839 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  generic-covariant-impl field self::C::T t = null;
   constructor named(core::List<self::C::T> t) → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.expect
index 9fd81aa..d2511f2 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  generic-covariant-impl field self::C::T t = null;
   constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.transformed.expect
index 9fd81aa..d2511f2 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_named_factory.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t = null;
+  generic-covariant-impl field self::C::T t = null;
   constructor •() → void
     : super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.expect
index b2a5c1a..9ea221c 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t;
+  generic-covariant-impl field self::C::T t;
   constructor •(self::C::T t) → void
     : self::C::t = t, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.transformed.expect
index b2a5c1a..9ea221c 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting.dart.strong.transformed.expect
@@ -3,7 +3,7 @@
 import "dart:core" as core;
 
 class C<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::C::T t;
+  generic-covariant-impl field self::C::T t;
   constructor •(self::C::T t) → void
     : self::C::t = t, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.expect
index 54b4372..4ff0a8c 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.expect
@@ -5,12 +5,12 @@
 abstract class C<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::C::•];
   abstract get t() → self::C::T;
-  abstract set t(generic-covariant-impl generic-covariant-interface self::C::T x) → void;
+  abstract set t(generic-covariant-impl self::C::T x) → void;
   static factory •<T extends core::Object = dynamic>(self::C::•::T t) → self::C<self::C::•::T>
     let dynamic #redirecting_factory = self::CImpl::• in let self::C::•::T #typeArg0 = null in invalid-expression;
 }
 class CImpl<T extends core::Object = dynamic> extends core::Object implements self::C<self::CImpl::T> {
-  generic-covariant-impl generic-covariant-interface field self::CImpl::T t;
+  generic-covariant-impl field self::CImpl::T t;
   constructor •(self::CImpl::T t) → void
     : self::CImpl::t = t, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.transformed.expect
index 2289573..4d782c8 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory.dart.strong.transformed.expect
@@ -5,12 +5,12 @@
 abstract class C<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::C::•];
   abstract get t() → self::C::T;
-  abstract set t(generic-covariant-impl generic-covariant-interface self::C::T x) → void;
+  abstract set t(generic-covariant-impl self::C::T x) → void;
   static factory •<T extends core::Object = dynamic>(self::C::•::T t) → self::C<self::C::•::T>
     let<BottomType> #redirecting_factory = self::CImpl::• in let self::C::•::T #typeArg0 = null in invalid-expression;
 }
 class CImpl<T extends core::Object = dynamic> extends core::Object implements self::C<self::CImpl::T> {
-  generic-covariant-impl generic-covariant-interface field self::CImpl::T t;
+  generic-covariant-impl field self::CImpl::T t;
   constructor •(self::CImpl::T t) → void
     : self::CImpl::t = t, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.expect
index 111277c..ede1a6e 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.expect
@@ -5,12 +5,12 @@
 abstract class C<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::C::•];
   abstract get t() → self::C::T;
-  abstract set t(generic-covariant-impl generic-covariant-interface self::C::T x) → void;
+  abstract set t(generic-covariant-impl self::C::T x) → void;
   static factory •<T extends core::Object = dynamic>(self::C::•::T t) → self::C<self::C::•::T>
     let dynamic #redirecting_factory = self::CImpl::• in let self::C::•::T #typeArg0 = null in invalid-expression;
 }
 class CImpl<T extends core::Object = dynamic> extends core::Object implements self::C<self::CImpl::T> {
-  generic-covariant-impl generic-covariant-interface field self::CImpl::T t;
+  generic-covariant-impl field self::CImpl::T t;
   constructor _(self::CImpl::T t) → void
     : self::CImpl::t = t, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect
index 14d4ed3..2840887 100644
--- a/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_infer_from_arguments_redirecting_factory_to_factory.dart.strong.transformed.expect
@@ -5,12 +5,12 @@
 abstract class C<T extends core::Object = dynamic> extends core::Object {
   static field dynamic _redirecting# = <dynamic>[self::C::•];
   abstract get t() → self::C::T;
-  abstract set t(generic-covariant-impl generic-covariant-interface self::C::T x) → void;
+  abstract set t(generic-covariant-impl self::C::T x) → void;
   static factory •<T extends core::Object = dynamic>(self::C::•::T t) → self::C<self::C::•::T>
     let <T extends core::Object = dynamic>(self::CImpl::•::T) → self::CImpl<self::CImpl::•::T> #redirecting_factory = self::CImpl::• in let self::C::•::T #typeArg0 = null in invalid-expression;
 }
 class CImpl<T extends core::Object = dynamic> extends core::Object implements self::C<self::CImpl::T> {
-  generic-covariant-impl generic-covariant-interface field self::CImpl::T t;
+  generic-covariant-impl field self::CImpl::T t;
   constructor _(self::CImpl::T t) → void
     : self::CImpl::t = t, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
index d22785f..bf5d7a9 100644
--- a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.expect
@@ -8,8 +8,8 @@
     ;
 }
 class Pair<T extends self::Clonable<self::Pair::T> = self::Clonable<dynamic>, U extends self::Clonable<self::Pair::U> = self::Clonable<dynamic>> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::Pair::T t;
-  generic-covariant-impl generic-covariant-interface field self::Pair::U u;
+  generic-covariant-impl field self::Pair::T t;
+  generic-covariant-impl field self::Pair::U u;
   constructor •(self::Pair::T t, self::Pair::U u) → void
     : self::Pair::t = t, self::Pair::u = u, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
index d22785f..bf5d7a9 100644
--- a/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_inference_f_bounded.dart.strong.transformed.expect
@@ -8,8 +8,8 @@
     ;
 }
 class Pair<T extends self::Clonable<self::Pair::T> = self::Clonable<dynamic>, U extends self::Clonable<self::Pair::U> = self::Clonable<dynamic>> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::Pair::T t;
-  generic-covariant-impl generic-covariant-interface field self::Pair::U u;
+  generic-covariant-impl field self::Pair::T t;
+  generic-covariant-impl field self::Pair::U u;
   constructor •(self::Pair::T t, self::Pair::U u) → void
     : self::Pair::t = t, self::Pair::u = u, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.expect
index 777d093..52a04f7 100644
--- a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.expect
@@ -3,8 +3,8 @@
 import "dart:core" as core;
 
 class Pair<T extends core::Object = dynamic, U extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::Pair::T t;
-  generic-covariant-impl generic-covariant-interface field self::Pair::U u;
+  generic-covariant-impl field self::Pair::T t;
+  generic-covariant-impl field self::Pair::U u;
   constructor •(self::Pair::T t, self::Pair::U u) → void
     : self::Pair::t = t, self::Pair::u = u, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.transformed.expect
index 777d093..52a04f7 100644
--- a/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/constructors_reverse_type_parameters.dart.strong.transformed.expect
@@ -3,8 +3,8 @@
 import "dart:core" as core;
 
 class Pair<T extends core::Object = dynamic, U extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::Pair::T t;
-  generic-covariant-impl generic-covariant-interface field self::Pair::U u;
+  generic-covariant-impl field self::Pair::T t;
+  generic-covariant-impl field self::Pair::U u;
   constructor •(self::Pair::T t, self::Pair::U u) → void
     : self::Pair::t = t, self::Pair::u = u, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.expect
index 7fa4e4d..14e65f8 100644
--- a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.expect
@@ -4,7 +4,7 @@
 
 typedef Function2<S extends core::Object = dynamic, T extends core::Object = dynamic> = (S) → T;
 class A<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field (self::A::T) → self::A::T x;
+  generic-covariant-impl field (self::A::T) → self::A::T x;
   constructor •((self::A::T) → self::A::T x) → void
     : self::A::x = x, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect
index 7fa4e4d..14e65f8 100644
--- a/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downward_inference_miscellaneous.dart.strong.transformed.expect
@@ -4,7 +4,7 @@
 
 typedef Function2<S extends core::Object = dynamic, T extends core::Object = dynamic> = (S) → T;
 class A<T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field (self::A::T) → self::A::T x;
+  generic-covariant-impl field (self::A::T) → self::A::T x;
   constructor •((self::A::T) → self::A::T x) → void
     : self::A::x = x, super core::Object::•()
     ;
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.expect
index 84e4744..c7a86c1 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.expect
@@ -8,9 +8,9 @@
     ;
 }
 static method test() → void {
-  for (core::int i = 0; i.<(1); i = i.+(1)) {
+  for (@self::Foo::•(const <dynamic>[]) core::int i = 0; i.<(1); i = i.+(1)) {
   }
-  for (core::int i in <dynamic>[0]) {
+  for (@self::Foo::•(const <dynamic>[]) core::int i in <dynamic>[0]) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.transformed.expect
index 84e4744..c7a86c1 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.direct.transformed.expect
@@ -8,9 +8,9 @@
     ;
 }
 static method test() → void {
-  for (core::int i = 0; i.<(1); i = i.+(1)) {
+  for (@self::Foo::•(const <dynamic>[]) core::int i = 0; i.<(1); i = i.+(1)) {
   }
-  for (core::int i in <dynamic>[0]) {
+  for (@self::Foo::•(const <dynamic>[]) core::int i in <dynamic>[0]) {
   }
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.expect
new file mode 100644
index 0000000..e4d43d3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  for (@self::Foo::•(const <core::String>[]) core::int i = 0; i.{core::num::<}(1); i = i.{core::num::+}(1)) {
+  }
+  for (@self::Foo::•(const <core::String>[]) core::int i in <core::int>[0]) {
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.transformed.expect
new file mode 100644
index 0000000..e4d43d3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_for_loop_variable.dart.strong.transformed.expect
@@ -0,0 +1,16 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  for (@self::Foo::•(const <core::String>[]) core::int i = 0; i.{core::num::<}(1); i = i.{core::num::+}(1)) {
+  }
+  for (@self::Foo::•(const <core::String>[]) core::int i in <core::int>[0]) {
+  }
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.strong.expect
new file mode 100644
index 0000000..70f1ea3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.strong.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  @self::Foo::•(const <core::String>[]) dynamic x;
+  @self::Foo::•(const <core::String>[])
+  function f() → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.strong.transformed.expect
new file mode 100644
index 0000000..70f1ea3
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals.dart.strong.transformed.expect
@@ -0,0 +1,15 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  @self::Foo::•(const <core::String>[]) dynamic x;
+  @self::Foo::•(const <core::String>[])
+  function f() → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart
index 9d389ca..b28b2ed 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart
@@ -14,6 +14,11 @@
 
   @Foo(/*@typeArgs=int*/ const [x])
   var /*@type=dynamic*/ y;
+
+  @Foo(/*@typeArgs=int*/ const [x])
+  void bar() {}
+
+  void baz(@Foo(/*@typeArgs=int*/ const [x]) dynamic formal) {}
 }
 
 main() {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.expect
index d3afdb6..a0385be 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.expect
@@ -9,6 +9,9 @@
 }
 static method test() → void {
   const dynamic x = 0;
-  dynamic y;
+  @self::Foo::•(const <dynamic>[x]) dynamic y;
+  @self::Foo::•(const <dynamic>[x])
+  function bar() → void {}
+  function baz(@self::Foo::•(const <dynamic>[x]) dynamic formal) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.transformed.expect
index d3afdb6..a0385be 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.direct.transformed.expect
@@ -9,6 +9,9 @@
 }
 static method test() → void {
   const dynamic x = 0;
-  dynamic y;
+  @self::Foo::•(const <dynamic>[x]) dynamic y;
+  @self::Foo::•(const <dynamic>[x])
+  function bar() → void {}
+  function baz(@self::Foo::•(const <dynamic>[x]) dynamic formal) → void {}
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.strong.expect
new file mode 100644
index 0000000..eac77b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.strong.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(dynamic l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  const core::int x = 0;
+  @self::Foo::•(const <core::int>[x]) dynamic y;
+  @self::Foo::•(const <core::int>[x])
+  function bar() → void {}
+  function baz(@self::Foo::•(const <core::int>[x]) dynamic formal) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.strong.transformed.expect
new file mode 100644
index 0000000..eac77b2
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_locals_referring_to_locals.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(dynamic l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  const core::int x = 0;
+  @self::Foo::•(const <core::int>[x]) dynamic y;
+  @self::Foo::•(const <core::int>[x])
+  function bar() → void {}
+  function baz(@self::Foo::•(const <core::int>[x]) dynamic formal) → void {}
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.expect
index 306b574..9d2c6e3 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.expect
@@ -11,7 +11,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method m(dynamic x) → void {}
+  method m(@self::Foo::•(const <dynamic>[]) dynamic x) → void {}
 }
-static method f(dynamic x) → void {}
+static method f(@self::Foo::•(const <dynamic>[]) dynamic x) → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.transformed.expect
index 306b574..9d2c6e3 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.direct.transformed.expect
@@ -11,7 +11,7 @@
   synthetic constructor •() → void
     : super core::Object::•()
     ;
-  method m(dynamic x) → void {}
+  method m(@self::Foo::•(const <dynamic>[]) dynamic x) → void {}
 }
-static method f(dynamic x) → void {}
+static method f(@self::Foo::•(const <dynamic>[]) dynamic x) → void {}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.strong.expect
new file mode 100644
index 0000000..7775e23
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.strong.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m(@self::Foo::•(const <core::String>[]) dynamic x) → void {}
+}
+static method f(@self::Foo::•(const <core::String>[]) dynamic x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.strong.transformed.expect
new file mode 100644
index 0000000..7775e23
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object {
+  synthetic constructor •() → void
+    : super core::Object::•()
+    ;
+  method m(@self::Foo::•(const <core::String>[]) dynamic x) → void {}
+}
+static method f(@self::Foo::•(const <core::String>[]) dynamic x) → void {}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart
index 6cc32b3..e3198ae 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart
@@ -11,7 +11,7 @@
 
 void test() {
   void f(@Foo(/*@typeArgs=String*/ const []) /*@type=dynamic*/ x) {}
-  var /*@type=(dynamic) -> Null*/ x = /*@returnType=Null*/ (/*@type=dynamic*/ @Foo(/*@typeArgs=String*/ const [])
+  var /*@type=(dynamic) -> Null*/ x = /*@returnType=Null*/ (@Foo(/*@typeArgs=String*/ const []) /*@type=dynamic*/
       x) {};
 }
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.expect
index d53d84c..9163b9d 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.expect
@@ -8,7 +8,7 @@
     ;
 }
 static method test() → void {
-  function f(dynamic x) → void {}
-  dynamic x = (dynamic x) → dynamic {};
+  function f(@self::Foo::•(const <dynamic>[]) dynamic x) → void {}
+  dynamic x = (@self::Foo::•(const <dynamic>[]) dynamic x) → dynamic {};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.transformed.expect
index d53d84c..9163b9d 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.direct.transformed.expect
@@ -8,7 +8,7 @@
     ;
 }
 static method test() → void {
-  function f(dynamic x) → void {}
-  dynamic x = (dynamic x) → dynamic {};
+  function f(@self::Foo::•(const <dynamic>[]) dynamic x) → void {}
+  dynamic x = (@self::Foo::•(const <dynamic>[]) dynamic x) → dynamic {};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.expect
new file mode 100644
index 0000000..90d59e7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  function f(@self::Foo::•(const <core::String>[]) dynamic x) → void {}
+  (dynamic) → core::Null x = (@self::Foo::•(const <core::String>[]) dynamic x) → core::Null {};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.transformed.expect
new file mode 100644
index 0000000..90d59e7
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_parameter_local.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  function f(@self::Foo::•(const <core::String>[]) dynamic x) → void {}
+  (dynamic) → core::Null x = (@self::Foo::•(const <core::String>[]) dynamic x) → core::Null {};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart
index 3ec0b43..b048a1b 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart
@@ -11,7 +11,7 @@
 
 void test() {
   void f<@Foo(/*@typeArgs=String*/ const []) T>() {}
-  var /*@type=<T extends Object>() -> Null*/ x =
+  var /*@type=<@Foo::•(const <String>[]) T extends Object = dynamic>() -> Null*/ x =
       <@Foo(/*@typeArgs=String*/ const []) T> /*@returnType=Null*/ () {};
 }
 
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.expect
index 7f49df8..d94bf7a 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.expect
@@ -8,7 +8,7 @@
     ;
 }
 static method test() → void {
-  function f<T extends core::Object = dynamic>() → void {}
-  dynamic x = <T extends core::Object = dynamic>() → dynamic {};
+  function f<@self::Foo::•(const <dynamic>[]) T extends core::Object = dynamic>() → void {}
+  dynamic x = <@self::Foo::•(const <dynamic>[]) T extends core::Object = dynamic>() → dynamic {};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.transformed.expect
index 7f49df8..d94bf7a 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.direct.transformed.expect
@@ -8,7 +8,7 @@
     ;
 }
 static method test() → void {
-  function f<T extends core::Object = dynamic>() → void {}
-  dynamic x = <T extends core::Object = dynamic>() → dynamic {};
+  function f<@self::Foo::•(const <dynamic>[]) T extends core::Object = dynamic>() → void {}
+  dynamic x = <@self::Foo::•(const <dynamic>[]) T extends core::Object = dynamic>() → dynamic {};
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.expect
new file mode 100644
index 0000000..657f6f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  function f<@self::Foo::•(const <core::String>[]) T extends core::Object = dynamic>() → void {}
+  <@self::Foo::•(const <core::String>[]) T extends core::Object = dynamic>() → core::Null x = <@self::Foo::•(const <core::String>[]) T extends core::Object = dynamic>() → core::Null {};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.transformed.expect
new file mode 100644
index 0000000..657f6f6
--- /dev/null
+++ b/pkg/front_end/testcases/inference/downwards_inference_annotations_type_variable_local.dart.strong.transformed.expect
@@ -0,0 +1,14 @@
+library test;
+import self as self;
+import "dart:core" as core;
+
+class Foo extends core::Object {
+  const constructor •(core::List<core::String> l) → void
+    : super core::Object::•()
+    ;
+}
+static method test() → void {
+  function f<@self::Foo::•(const <core::String>[]) T extends core::Object = dynamic>() → void {}
+  <@self::Foo::•(const <core::String>[]) T extends core::Object = dynamic>() → core::Null x = <@self::Foo::•(const <core::String>[]) T extends core::Object = dynamic>() → core::Null {};
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
index 5fc98c7..148939a 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.expect
@@ -3,8 +3,8 @@
 import "dart:core" as core;
 
 class A<S extends core::Object = dynamic, T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::A::S x;
-  generic-covariant-impl generic-covariant-interface field self::A::T y;
+  generic-covariant-impl field self::A::S x;
+  generic-covariant-impl field self::A::T y;
   constructor •(self::A::S x, self::A::T y) → void
     : self::A::x = x, self::A::y = y, super core::Object::•()
     ;
@@ -35,7 +35,6 @@
   constructor named(self::D::T a) → void
     : super self::B::named(a, 3)
     ;
-  abstract forwarding-stub set x(generic-covariant-impl core::int _) → void;
 }
 class E<S extends core::Object = dynamic, T extends core::Object = dynamic> extends self::A<self::C<self::E::S>, self::E::T> {
   constructor •(self::E::T a) → void
diff --git a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
index 1100687..4e52169 100644
--- a/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/downwards_inference_on_instance_creations_infer_downwards.dart.strong.transformed.expect
@@ -3,8 +3,8 @@
 import "dart:core" as core;
 
 class A<S extends core::Object = dynamic, T extends core::Object = dynamic> extends core::Object {
-  generic-covariant-impl generic-covariant-interface field self::A::S x;
-  generic-covariant-impl generic-covariant-interface field self::A::T y;
+  generic-covariant-impl field self::A::S x;
+  generic-covariant-impl field self::A::T y;
   constructor •(self::A::S x, self::A::T y) → void
     : self::A::x = x, self::A::y = y, super core::Object::•()
     ;
@@ -35,7 +35,6 @@
   constructor named(self::D::T a) → void
     : super self::B::named(a, 3)
     ;
-  abstract forwarding-stub set x(generic-covariant-impl core::int _) → void;
 }
 class E<S extends core::Object = dynamic, T extends core::Object = dynamic> extends self::A<self::C<self::E::S>, self::E::T> {
   constructor •(self::E::T a) → void
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
index 59ff30a..e39f077 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.expect
@@ -14,7 +14,7 @@
     return null;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
index 5f0f486..7c6f301 100644
--- a/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
     return null;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
index c4514a8..4a812f5 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.expect
@@ -14,7 +14,7 @@
     return null;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
index 4d6c659..73bad2f 100644
--- a/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/inference/future_then_2.dart.strong.transformed.expect
@@ -14,7 +14,7 @@
     return null;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl generic-covariant-interface () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
+  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covariant-impl () → asy::FutureOr<self::MyFuture::T> onTimeout = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ asStream() → asy::Stream<self::MyFuture::T>;
 }
 static method test() → void {
diff --git a/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect b/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
index 41dd64d..c317b12 100644
--- a/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
+++ b/pkg/front_end/testcases/inference/future_then_3.dart.strong.expect
@@ -14,7 +14,7 @@
     return null;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ catchError(core::Function onError, {(core::Object) → core::bool test = null}) → asy::Future<self::MyFuture::T>;
   abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ whenComplete(() → asy::FutureOr<dynamic> action) → asy::Future<self::MyFuture::T>;
-  abstract no-such-method-forwarder method /* from org-dartlang-testcase-sdk:///sdk/lib/async/future.dart */ timeout(core::Duration timeLimit, {generic-covarian