Version 2.0.0-dev.15.0

Merge 220a91122a304cefcef98d0a4d75d54b78e90899 into dev
diff --git a/.packages b/.packages
index d559cca..1f0b101 100644
--- a/.packages
+++ b/.packages
@@ -45,6 +45,7 @@
 http:third_party/pkg/http/lib
 http_multi_server:third_party/pkg/http_multi_server/lib
 http_parser:third_party/pkg/http_parser/lib
+http_retry:third_party/pkg/http_retry/lib
 http_throttle:third_party/pkg/http_throttle/lib
 intl:third_party/pkg/intl/lib
 isolate:third_party/pkg/isolate/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 9941193..4a385e7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -122,59 +122,93 @@
     }
     ```
 
-* Pub
+#### Pub
 
-  * Git dependencies may now include a `path` parameter, indicating that the
-    package exists in a subdirectory of the Git repository. For example:
+##### SDK Constraints
 
-    ```yaml
-    dependencies:
-      foobar:
-        git:
-          url: git://github.com/dart-lang/multi_package_repo
-          path: pkg/foobar
-    ```
+There is now a default SDK constraint of `<2.0.0` for any package with no
+existing upper bound. This allows us to move more safely to 2.0.0. All new
+packages published on pub will now require an upper bound SDK constraint so
+future major releases of Dart don't destabilize the package ecosystem.
 
-  * `pub get` and `pub upgrade` properly produce an error message and exit code
-    when no network is present.
+All SDK constraint exclusive upper bounds are now treated as though they allow
+pre-release versions of that upper bound. For example, the SDK constraint
+`>=1.8.0 <2.0.0` now allows pre-release SDK versions such as `2.0.0-beta.3.0`.
+This allows early adopters to try out packages that don't explicitly declare
+support for the new version yet. You can disable this functionality by setting
+the `PUB_ALLOW_PRERELEASE_SDK` environment variable to `false`.
 
-  * `pub serve` now waits for file watcher events to stabilize before scheduling
-     new builds. This helps specifically with `safe-write` features in editors,
-     as well as other situations such as `save all` which cause many fast edits.
+##### Other Features
 
-  * Added the `--build-delay` argument to `pub serve` which sets the amount of
-    time (in ms) to wait between file watcher events before scheduling a build.
-    Defaults to 50.
+* Git dependencies may now include a `path` parameter, indicating that the
+  package exists in a subdirectory of the Git repository. For example:
 
-  * Removed require.js module loading timeout for dartdevc, which resolves an
-    issue where the initial load of an app might give a timeout error.
+  ```yaml
+  dependencies:
+    foobar:
+      git:
+        url: git://github.com/dart-lang/multi_package_repo
+        path: pkg/foobar
+  ```
 
-  * There is now a default SDK constraint of `<2.0.0` for any package with
-    no existing upper bound. This allows us to move more safely to 2.0.0.
+* Added an `--executables` option to `pub deps` command. This will list all
+  available executables that can be run with `pub run`.
 
-  * All new packages published on pub will now require an upper bound SDK
-    constraint so future major releases of Dart don't destabilize the package
-    ecosystem.
+* Added a `PUB_MAX_WORKERS_PER_TASK` environment variable which can be set to
+  configure the number of dartdevc/analyzer workers that are used when compiling
+  with `--web-compiler=dartdevc`.
 
-  * When on a pre-release SDK build, all upper bounds matching exactly the
-    current SDK version but with no pre-release or build modifier will be
-    upgraded to be <= the current SDK version. This allows early adopters to
-    try out packages that don't explicitly declare support yet. You can disable
-    this functionality by setting the PUB_ALLOW_PRERELEASE_SDK system
-    environment variable to `false`.
+* Pub will now automatically retry HTTP requests that fail with a 502, 503, of
+  504 error code ([issue 1556][pub#1556]).
 
-  * Added `--executables` option to `pub deps` command. This will list all
-    available executables that can be run with `pub run`.
+* Emit exit code 66 when a path dependency doesn't exist ([issue 1747][pub#1747]).
 
-  * Fixed https://github.com/dart-lang/pub/issues/1684 so root package analysis
-    options are not enforced for dependencies when compiling with dartdevc.
+[pub#1556]: https://github.com/dart-lang/pub/issues/1556
+[pub#1747]: https://github.com/dart-lang/pub/issues/1747
 
-  * Fixed https://github.com/dart-lang/sdk/issues/30246 so you can include dart
-    scripts from subdirectories with dartdevc.
+##### Bug Fixes
 
-  * Added a PUB_MAX_WORKERS_PER_TASK system environment variable which can be
-    set to configure the number of dartdevc/analyzer workers that are used
-    when compiling with --web-compiler=dartdevc.
+* Added a `--build-delay` argument to `pub serve` which sets the amount of time
+  (in ms) to wait between file watcher events before scheduling a build.
+  Defaults to 50.
+
+* `pub get` and `pub upgrade` properly produce an error message and exit code
+  when no network is present.
+
+* `pub serve` now waits for file watcher events to stabilize before scheduling
+   new builds. This helps specifically with `safe-write` features in editors,
+   as well as other situations such as `save all` which cause many fast edits.
+
+* Removed the require.js module loading timeout for dartdevc, which resolves an
+  issue where the initial load of an app might give a timeout error.
+
+* Root package analysis options are no longer enforced for dependencies when
+  compiling with dartdevc ([issue 1684][pub#1684]).
+
+* Dart scripts can be included from subdirectories with dartdevc
+  ([issue 30246][]).
+
+* The `barback` infrastructure now supports `async` 2.0.0.
+
+* Print a more informative error message when the Flutter SDK isn't
+  available ([issue 1719][pub#1719]).
+
+* Don't crash when publishing a package that contains an empty submodule
+  ([issue 1679][pub#1679]).
+
+* Emit exit code 69 for TLS errors ([issue 1729][pub#1729]).
+
+* Fix `pub global run` for packages activated from a local path that also have
+  relative path dependencies ([issue 1751][pub#1751]).
+
+[pub#1684]: https://github.com/dart-lang/pub/issues/1684
+[pub#1719]: https://github.com/dart-lang/pub/issues/1719
+[pub#1679]: https://github.com/dart-lang/pub/issues/1679
+[pub#1729]: https://github.com/dart-lang/pub/issues/1729
+[pub#1751]: https://github.com/dart-lang/pub/issues/1751
+[issue 30246]: https://github.com/dart-lang/sdk/issues/30246
+
+#### Other Tools
 
 * dartfmt
 
diff --git a/DEPS b/DEPS
index 642a59a..6f4f5f2 100644
--- a/DEPS
+++ b/DEPS
@@ -84,6 +84,7 @@
   "html_tag" : "@0.13.2",
   "http_multi_server_tag" : "@2.0.4",
   "http_parser_tag" : "@3.1.1",
+  "http_retry_tag": "@0.1.0",
   "http_tag" : "@0.11.3+14",
   "http_throttle_tag" : "@1.0.1",
   "idl_parser_rev": "@7fbe68cab90c38147dee4f48c30ad0d496c17915",
@@ -107,13 +108,13 @@
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
   "pool_tag": "@1.3.3",
   "protobuf_tag": "@0.5.4",
-  "pub_rev": "@cde958f157d3662bf968bcbed05580d5c0355e89",
+  "pub_rev": "@667281eef93b4be648cceca400e954e000edba38",
   "pub_semver_tag": "@1.3.2",
   "quiver_tag": "@0.25.0",
   "resource_rev":"@af5a5bf65511943398146cf146e466e5f0b95cb9",
   "root_certificates_rev": "@a4c7c6f23a664a37bc1b6f15a819e3f2a292791a",
   "scheduled_test_tag": "@0.12.11+1",
-  "shelf_static_tag": "@0.2.5",
+  "shelf_static_rev": "@3558aa35a0d2f0f35868c3fd64b258e140db0122",
   "shelf_packages_handler_tag": "@1.0.3",
   "shelf_tag": "@0.7.1",
   "shelf_web_socket_tag": "@0.2.2",
@@ -227,6 +228,9 @@
       Var("http_multi_server_tag"),
   Var("dart_root") + "/third_party/pkg/http_parser":
       Var("github_mirror") + "http_parser.git" + Var("http_parser_tag"),
+  Var("dart_root") + "/third_party/pkg/http_retry":
+      Var("github_mirror") + "http_retry.git" +
+      Var("http_retry_tag"),
   Var("dart_root") + "/third_party/pkg/http_throttle":
       Var("github_mirror") + "http_throttle.git" +
       Var("http_throttle_tag"),
@@ -289,7 +293,7 @@
       Var("github_mirror") + "shelf_packages_handler.git"
       + Var("shelf_packages_handler_tag"),
   Var("dart_root") + "/third_party/pkg/shelf_static":
-      Var("github_mirror") + "shelf_static.git" + Var("shelf_static_tag"),
+      Var("github_mirror") + "shelf_static.git" + Var("shelf_static_rev"),
   Var("dart_root") + "/third_party/pkg/shelf_web_socket":
       Var("github_mirror") + "shelf_web_socket.git" +
       Var("shelf_web_socket_tag"),
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index 2df2b21..bd4e9c9 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -387,6 +387,7 @@
 
     contextManager = new ContextManagerImpl(
         resourceProvider,
+        fileContentOverlay,
         sdkManager,
         packageResolverProvider,
         packageMapProvider,
@@ -442,7 +443,8 @@
         '**/*.${AnalysisEngine.SUFFIX_HTML}',
         '**/*.${AnalysisEngine.SUFFIX_HTM}',
         '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
-        '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}'
+        '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}',
+        '**/${AnalysisEngine.PUBSPEC_YAML_FILE}'
       ];
       for (String pattern in patterns) {
         try {
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 8892823..9fca4c5 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -21,6 +21,7 @@
 import 'package:analyzer/source/sdk_ext.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -28,10 +29,12 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/pubspec/pubspec_validator.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/util/absolute_path.dart';
 import 'package:analyzer/src/util/glob.dart';
 import 'package:analyzer/src/util/yaml.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart' as protocol;
 import 'package:analyzer_plugin/utilities/analyzer_converter.dart';
 import 'package:package_config/packages.dart';
 import 'package:package_config/packages_file.dart' as pkgfile show parse;
@@ -432,6 +435,11 @@
   final ResourceProvider resourceProvider;
 
   /**
+   * The file content overlay.
+   */
+  final FileContentOverlay fileContentOverlay;
+
+  /**
    * The manager used to access the SDK that should be associated with a
    * particular context.
    */
@@ -522,6 +530,7 @@
 
   ContextManagerImpl(
       this.resourceProvider,
+      this.fileContentOverlay,
       this.sdkManager,
       this.packageResolverProvider,
       this._packageMapProvider,
@@ -885,19 +894,54 @@
    * options file at the given [path].
    */
   void _analyzeAnalysisOptionsFile(AnalysisDriver driver, String path) {
-    String content = driver.fsState.getFileForPath(path).content;
-    List<AnalysisError> errors =
-        GenerateOptionsErrorsTask.analyzeAnalysisOptions(
-            resourceProvider.getFile(path).createSource(),
-            content,
-            driver.sourceFactory);
-    AnalyzerConverter converter = new AnalyzerConverter();
-    LineInfo lineInfo = _computeLineInfo(content);
+    List<protocol.AnalysisError> convertedErrors;
+    try {
+      String content = _readFile(path);
+      LineInfo lineInfo = _computeLineInfo(content);
+      List<AnalysisError> errors =
+          GenerateOptionsErrorsTask.analyzeAnalysisOptions(
+              resourceProvider.getFile(path).createSource(),
+              content,
+              driver.sourceFactory);
+      AnalyzerConverter converter = new AnalyzerConverter();
+      convertedErrors = converter.convertAnalysisErrors(errors,
+          lineInfo: lineInfo, options: driver.analysisOptions);
+    } catch (exception) {
+      // If the file cannot be analyzed, fall through to clear any previous
+      // errors.
+    }
     callbacks.notificationManager.recordAnalysisErrors(
         NotificationManager.serverId,
         path,
-        converter.convertAnalysisErrors(errors,
-            lineInfo: lineInfo, options: driver.analysisOptions));
+        convertedErrors ?? <protocol.AnalysisError>[]);
+  }
+
+  /**
+   * Use the given analysis [driver] to analyze the content of the pubspec file
+   * at the given [path].
+   */
+  void _analyzePubspecFile(AnalysisDriver driver, String path) {
+    List<protocol.AnalysisError> convertedErrors;
+    try {
+      String content = _readFile(path);
+      YamlNode node = loadYamlNode(content);
+      if (node is YamlMap) {
+        PubspecValidator validator = new PubspecValidator(
+            resourceProvider, resourceProvider.getFile(path).createSource());
+        LineInfo lineInfo = _computeLineInfo(content);
+        List<AnalysisError> errors = validator.validate(node.nodes);
+        AnalyzerConverter converter = new AnalyzerConverter();
+        convertedErrors = converter.convertAnalysisErrors(errors,
+            lineInfo: lineInfo, options: driver.analysisOptions);
+      }
+    } catch (exception) {
+      // If the file cannot be analyzed, fall through to clear any previous
+      // errors.
+    }
+    callbacks.notificationManager.recordAnalysisErrors(
+        NotificationManager.serverId,
+        path,
+        convertedErrors ?? <protocol.AnalysisError>[]);
   }
 
   void _checkForAnalysisOptionsUpdate(
@@ -941,6 +985,20 @@
     }
   }
 
+  void _checkForPubspecUpdate(
+      String path, ContextInfo info, ChangeType changeType) {
+    if (_isPubspec(path)) {
+      AnalysisDriver driver = info.analysisDriver;
+      if (driver == null) {
+        // I suspect that this happens as a result of a race condition: server
+        // has determined that the file (at [path]) is in a context, but hasn't
+        // yet created a driver for that context.
+        return;
+      }
+      _analyzePubspecFile(driver, path);
+    }
+  }
+
   /**
    * Compute the set of files that are being flushed, this is defined as
    * the set of sources in the removed context (context.sources), that are
@@ -1107,6 +1165,10 @@
     if (optionsFile != null) {
       _analyzeAnalysisOptionsFile(info.analysisDriver, optionsFile.path);
     }
+    File pubspecFile = folder.getChildAssumingFile(PUBSPEC_NAME);
+    if (pubspecFile.exists) {
+      _analyzePubspecFile(info.analysisDriver, pubspecFile.path);
+    }
     return info;
   }
 
@@ -1425,6 +1487,7 @@
     }
     _checkForPackagespecUpdate(path, info, info.folder);
     _checkForAnalysisOptionsUpdate(path, info, type);
+    _checkForPubspecUpdate(path, info, type);
   }
 
   /**
@@ -1515,6 +1578,15 @@
     }
   }
 
+  /**
+   * Read the contents of the file at the given [path], or throw an exception if
+   * the contents cannot be read.
+   */
+  String _readFile(String path) {
+    return fileContentOverlay[path] ??
+        resourceProvider.getFile(path).readAsStringSync();
+  }
+
   Packages _readPackagespec(File specFile) {
     try {
       String contents = specFile.readAsStringSync();
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 4667311..2e80f58 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -48,6 +48,12 @@
       : this.request = request,
         this.entity = request.target.entity;
 
+  Token get droppedToken => request.target.droppedToken;
+
+  bool isEmptyBody(FunctionBody body) =>
+      body is EmptyFunctionBody ||
+      (body is BlockFunctionBody && body.beginToken.isSynthetic);
+
   @override
   visitArgumentList(ArgumentList node) {
     if (request is DartCompletionRequestImpl) {
@@ -150,7 +156,7 @@
       _addClassBodyKeywords();
       int index = node.members.indexOf(entity);
       ClassMember previous = index > 0 ? node.members[index - 1] : null;
-      if (previous is MethodDeclaration && previous.body is EmptyFunctionBody) {
+      if (previous is MethodDeclaration && isEmptyBody(previous.body)) {
         _addSuggestion(Keyword.ASYNC);
         _addSuggestion2(ASYNC_STAR);
         _addSuggestion2(SYNC_STAR);
@@ -202,7 +208,7 @@
     if (entity == null || entity is Declaration) {
       if (previousMember is FunctionDeclaration &&
           previousMember.functionExpression is FunctionExpression &&
-          previousMember.functionExpression.body is EmptyFunctionBody) {
+          isEmptyBody(previousMember.functionExpression.body)) {
         _addSuggestion(Keyword.ASYNC, DART_RELEVANCE_HIGH);
         _addSuggestion2(ASYNC_STAR, relevance: DART_RELEVANCE_HIGH);
         _addSuggestion2(SYNC_STAR, relevance: DART_RELEVANCE_HIGH);
@@ -335,6 +341,23 @@
   }
 
   @override
+  visitParenthesizedExpression(ParenthesizedExpression node) {
+    Expression expression = node.expression;
+    if (expression is Identifier || expression is PropertyAccess) {
+      if (entity == node.rightParenthesis) {
+        var next = expression.endToken.next;
+        if (next == entity || next == droppedToken) {
+          // Fasta parses `if (x i^)` as `if (x ^) where the `i` is in the token
+          // stream but not part of the ParenthesizedExpression.
+          _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH);
+          return;
+        }
+      }
+    }
+    _addExpressionKeywords(node);
+  }
+
+  @override
   visitIfStatement(IfStatement node) {
     if (_isPreviousTokenSynthetic(entity, TokenType.CLOSE_PAREN)) {
       // Actual: if (x i^)
@@ -390,7 +413,7 @@
   @override
   visitMethodDeclaration(MethodDeclaration node) {
     if (entity == node.body) {
-      if (node.body is EmptyFunctionBody) {
+      if (isEmptyBody(node.body)) {
         _addClassBodyKeywords();
         _addSuggestion(Keyword.ASYNC);
         _addSuggestion2(ASYNC_STAR);
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
index 22aa8ee..9c10cdb 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_class_member.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/ast_provider.dart';
 import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/source.dart';
 
 /**
  * Checks if creating a method with the given [name] in [classElement] will
@@ -270,7 +271,9 @@
       // Check local elements that might shadow the reference.
       var localElements = await getLocalElements(match.element);
       for (LocalElement localElement in localElements) {
-        if (localElement.visibleRange.intersects(match.sourceRange)) {
+        SourceRange elementRange = localElement.visibleRange;
+        if (elementRange != null &&
+            elementRange.intersects(match.sourceRange)) {
           return new _MatchShadowedByLocal(match, localElement);
         }
       }
diff --git a/pkg/analysis_server/test/analysis/get_errors_test.dart b/pkg/analysis_server/test/analysis/get_errors_test.dart
index 431f5ed..af094d1 100644
--- a/pkg/analysis_server/test/analysis/get_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/get_errors_test.dart
@@ -46,12 +46,12 @@
   test_errorInPart() async {
     String libPath = '$testFolder/main.dart';
     String partPath = '$testFolder/main_part.dart';
-    addFile(libPath, r'''
+    newFile(libPath, content: r'''
 library main;
 part 'main_part.dart';
 class A {}
 ''');
-    addFile(partPath, r'''
+    newFile(partPath, content: r'''
 part of main;
 class A {}
 ''');
@@ -77,7 +77,7 @@
   test_fileWithoutContext() {
     // Broken under the new driver.
     String file = '/outside.dart';
-    addFile(file, '''
+    newFile(file, content: '''
 main() {
   print(42);
 }
@@ -124,7 +124,7 @@
     Request request = _createGetErrorsRequest(testFile);
     server.handleRequest(request);
     // remove context, causes sending an "invalid file" error
-    resourceProvider.deleteFolder(projectPath);
+    deleteFolder(projectPath);
     // wait for an error response
     Response response = await serverChannel.waitForResponse(request);
     expect(response.error, isNotNull);
diff --git a/pkg/analysis_server/test/analysis/get_navigation_test.dart b/pkg/analysis_server/test/analysis/get_navigation_test.dart
index 6df1179..85945fc 100644
--- a/pkg/analysis_server/test/analysis/get_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/get_navigation_test.dart
@@ -55,7 +55,7 @@
   }
 
   test_fileOutsideOfRoot() async {
-    testFile = '/outside.dart';
+    testFile = resourceProvider.convertPath('/outside.dart');
     addTestFile('''
 main() {
   var test = 0;
@@ -198,7 +198,7 @@
     server.handleRequest(request);
     // remove context, causes sending an "invalid file" error
     {
-      Folder projectFolder = resourceProvider.getResource(projectPath);
+      Folder projectFolder = getFolder(projectPath);
       server.contextManager.callbacks.removeContext(projectFolder, <String>[]);
     }
     // wait for an error response
diff --git a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
index 4293c6c..4fc4eb1 100644
--- a/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analysis_options_test.dart
@@ -43,11 +43,7 @@
   List<AnalysisError> get testFileErrors => filesErrors[testFile];
 
   void addOptionsFile(String contents) {
-    addFile(optionsFilePath, contents);
-  }
-
-  void deleteFile(String filePath) {
-    resourceProvider.deleteFile(filePath);
+    newFile(optionsFilePath, content: contents);
   }
 
   @override
diff --git a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
index c7a1196..8cfbfad 100644
--- a/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_analyzedFiles_test.dart
@@ -73,9 +73,7 @@
   }
 
   test_beforeAnalysis_excludeYamlFiles() async {
-    File yamlFile = resourceProvider
-        .getFolder(projectPath)
-        .getChildAssumingFile('sample.yaml');
+    File yamlFile = getFolder(projectPath).getChildAssumingFile('sample.yaml');
     yamlFile.writeAsStringSync('');
     addTestFile('''
 class A {}
@@ -117,7 +115,7 @@
     // Making a change that *does* affect the set of reachable files should
     // trigger the notification to be re-sent.
     addTestFile('class A {}');
-    addFile('/foo.dart', 'library foo;');
+    newFile('/foo.dart', content: 'library foo;');
     await prepareAnalyzedFiles();
     expect(analyzedFilesReceived, isTrue);
 
diff --git a/pkg/analysis_server/test/analysis/notification_errors_test.dart b/pkg/analysis_server/test/analysis/notification_errors_test.dart
index 904a0e4..161eb85 100644
--- a/pkg/analysis_server/test/analysis/notification_errors_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_errors_test.dart
@@ -45,6 +45,30 @@
     ];
   }
 
+  test_analysisOptionsFile() async {
+    String analysisOptionsFile =
+        newFile('$projectPath/analysis_options.yaml', content: '''
+linter:
+  rules:
+    - invalid_lint_rule_name
+''').path;
+
+    Request request =
+        new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
+    handleSuccessfulRequest(request);
+    await waitForTasksFinished();
+    await pumpEventQueue();
+    //
+    // Verify the error result.
+    //
+    List<AnalysisError> errors = filesErrors[analysisOptionsFile];
+    expect(errors, hasLength(1));
+    AnalysisError error = errors[0];
+    expect(error.location.file, '/project/analysis_options.yaml');
+    expect(error.severity, AnalysisErrorSeverity.WARNING);
+    expect(error.type, AnalysisErrorType.STATIC_WARNING);
+  }
+
   test_importError() async {
     createProject();
 
@@ -66,7 +90,7 @@
   test_lintError() async {
     var camelCaseTypesLintName = 'camel_case_types';
 
-    addFile('$projectPath/.analysis_options', '''
+    newFile('$projectPath/.analysis_options', content: '''
 linter:
   rules:
     - $camelCaseTypesLintName
@@ -81,7 +105,7 @@
     await waitForTasksFinished();
     List<Linter> lints;
     AnalysisDriver testDriver = (server.contextManager as ContextManagerImpl)
-        .getContextInfoFor(resourceProvider.getFolder(projectPath))
+        .getContextInfoFor(getFolder(projectPath))
         .analysisDriver;
     lints = testDriver.analysisOptions.lintRules;
     // Registry should only contain single lint rule.
@@ -100,8 +124,7 @@
 
   test_notInAnalysisRoot() async {
     createProject();
-    String otherFile = '/other.dart';
-    addFile(otherFile, 'UnknownType V;');
+    String otherFile = newFile('/other.dart', content: 'UnknownType V;').path;
     addTestFile('''
 import '/other.dart';
 main() {
@@ -128,6 +151,39 @@
     expect(error.message, isNotNull);
   }
 
+  test_pubspecFile() async {
+    String pubspecFile = newFile('$projectPath/pubspec.yaml', content: '''
+version: 1.3.2
+''').path;
+
+    Request setRootsRequest =
+        new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
+    handleSuccessfulRequest(setRootsRequest);
+    await waitForTasksFinished();
+    await pumpEventQueue();
+    //
+    // Verify the error result.
+    //
+    List<AnalysisError> errors = filesErrors[pubspecFile];
+    expect(errors, hasLength(1));
+    AnalysisError error = errors[0];
+    expect(error.location.file, '/project/pubspec.yaml');
+    expect(error.severity, AnalysisErrorSeverity.WARNING);
+    expect(error.type, AnalysisErrorType.STATIC_WARNING);
+    //
+    // Fix the error and verify the new results.
+    //
+    modifyFile(pubspecFile, '''
+name: sample
+version: 1.3.2
+''');
+    await waitForTasksFinished();
+    await pumpEventQueue();
+
+    errors = filesErrors[pubspecFile];
+    expect(errors, hasLength(0));
+  }
+
   test_StaticWarning() async {
     createProject();
     addTestFile('''
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test.dart b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
index ceabbce..16df572 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test.dart
@@ -344,7 +344,7 @@
 main() {
   var part = 42;
 }''');
-    addFile('/project/bin/my_part.dart', 'part of lib;');
+    newFile('/project/bin/my_part.dart', content: 'part of lib;');
     await prepareHighlights();
     assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
     assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
@@ -934,7 +934,7 @@
   }
 
   void _addLibraryForTestPart() {
-    addFile('$testFolder/my_lib.dart', '''
+    newFile('$testFolder/my_lib.dart', content: '''
 library lib;
 part 'test.dart';
     ''');
diff --git a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
index df9b59d..56491fe 100644
--- a/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
+++ b/pkg/analysis_server/test/analysis/notification_highlights_test2.dart
@@ -345,7 +345,7 @@
 main() {
   var part = 42;
 }''');
-    addFile('/project/bin/my_part.dart', 'part of lib;');
+    newFile('/project/bin/my_part.dart', content: 'part of lib;');
     await prepareHighlights();
     assertHasRegion(HighlightRegionType.BUILT_IN, 'part "my_');
     assertNoRegion(HighlightRegionType.BUILT_IN, 'part = 42');
@@ -1085,7 +1085,7 @@
   }
 
   void _addLibraryForTestPart() {
-    addFile('$testFolder/my_lib.dart', '''
+    newFile('$testFolder/my_lib.dart', content: '''
 library lib;
 part 'test.dart';
     ''');
diff --git a/pkg/analysis_server/test/analysis/notification_implemented_test.dart b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
index cc80eb9..7a6e597 100644
--- a/pkg/analysis_server/test/analysis/notification_implemented_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_implemented_test.dart
@@ -271,7 +271,7 @@
   }
 
   test_method_withMethod_private_differentLib() async {
-    addFile('$testFolder/lib.dart', r'''
+    newFile('$testFolder/lib.dart', content: r'''
 import 'test.dart';
 class B extends A {
   void _m() {}
diff --git a/pkg/analysis_server/test/analysis/notification_navigation_test.dart b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
index f57c671..075acf7 100644
--- a/pkg/analysis_server/test/analysis/notification_navigation_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_navigation_test.dart
@@ -229,7 +229,7 @@
   }
 
   test_annotationConstructor_importPrefix() async {
-    addFile('$testFolder/my_annotation.dart', r'''
+    newFile('$testFolder/my_annotation.dart', content: r'''
 library an;
 class MyAnnotation {
   const MyAnnotation();
@@ -304,7 +304,7 @@
   }
 
   test_annotationField_importPrefix() async {
-    addFile('$testFolder/mayn.dart', r'''
+    newFile('$testFolder/mayn.dart', content: r'''
 library an;
 const myan = new Object();
 ''');
@@ -697,8 +697,8 @@
   }
 
   test_multiplyDefinedElement() async {
-    addFile('$projectPath/bin/libA.dart', 'library A; int TEST = 1;');
-    addFile('$projectPath/bin/libB.dart', 'library B; int TEST = 2;');
+    newFile('$projectPath/bin/libA.dart', content: 'library A; int TEST = 1;');
+    newFile('$projectPath/bin/libB.dart', content: 'library B; int TEST = 2;');
     addTestFile('''
 import 'libA.dart';
 import 'libB.dart';
@@ -776,7 +776,7 @@
 
   test_partOf() async {
     var libCode = 'library lib; part "test.dart";';
-    var libFile = addFile('$projectPath/bin/lib.dart', libCode);
+    var libFile = newFile('$projectPath/bin/lib.dart', content: libCode).path;
     addTestFile('part of lib;');
     await prepareNavigation();
     assertHasRegionString('lib');
@@ -808,7 +808,7 @@
 
   test_string_export() async {
     var libCode = 'library lib;';
-    var libFile = addFile('$projectPath/bin/lib.dart', libCode);
+    var libFile = newFile('$projectPath/bin/lib.dart', content: libCode).path;
     addTestFile('export "lib.dart";');
     await prepareNavigation();
     assertHasRegionString('"lib.dart"');
@@ -823,7 +823,7 @@
 
   test_string_import() async {
     var libCode = 'library lib;';
-    var libFile = addFile('$projectPath/bin/lib.dart', libCode);
+    var libFile = newFile('$projectPath/bin/lib.dart', content: libCode).path;
     addTestFile('import "lib.dart";');
     await prepareNavigation();
     assertHasRegionString('"lib.dart"');
@@ -844,7 +844,8 @@
 
   test_string_part() async {
     var unitCode = 'part of lib;  f() {}';
-    var unitFile = addFile('$projectPath/bin/test_unit.dart', unitCode);
+    var unitFile =
+        newFile('$projectPath/bin/test_unit.dart', content: unitCode).path;
     addTestFile('''
 library lib;
 part "test_unit.dart";
diff --git a/pkg/analysis_server/test/analysis/notification_overrides_test.dart b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
index 10abe23..86cac68 100644
--- a/pkg/analysis_server/test/analysis/notification_overrides_test.dart
+++ b/pkg/analysis_server/test/analysis/notification_overrides_test.dart
@@ -232,7 +232,7 @@
   }
 
   test_BAD_privateByPrivate_inDifferentLib() async {
-    addFile('$testFolder/lib.dart', r'''
+    newFile('$testFolder/lib.dart', content: r'''
 class A {
   void _m() {}
 }
diff --git a/pkg/analysis_server/test/analysis/reanalyze_test.dart b/pkg/analysis_server/test/analysis/reanalyze_test.dart
index c78dd97..886b200 100644
--- a/pkg/analysis_server/test/analysis/reanalyze_test.dart
+++ b/pkg/analysis_server/test/analysis/reanalyze_test.dart
@@ -46,8 +46,8 @@
 
   test_reanalyze_with_overlay() async {
     createProject();
-    resourceProvider.newFolder(testFolder);
-    resourceProvider.newFile(testFile, 'main() {}');
+    newFolder(testFolder);
+    newFile(testFile, content: 'main() {}');
     // Update the content with an overlay that contains a syntax error.
     server.updateContent('1', {testFile: new AddContentOverlay('main() {')});
     await _resultsAvailable.future;
diff --git a/pkg/analysis_server/test/analysis/set_priority_files_test.dart b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
index 1de25bf..993fb07 100644
--- a/pkg/analysis_server/test/analysis/set_priority_files_test.dart
+++ b/pkg/analysis_server/test/analysis/set_priority_files_test.dart
@@ -57,49 +57,49 @@
 
   test_fileNotInAnalysisRoot() async {
     String path = '/other/file.dart';
-    addFile(path, '');
+    newFile(path);
     await _setPriorityFile(path);
     _verifyPriorityFiles(path);
   }
 
   test_ignoredInAnalysisOptions() async {
     String sampleFile = '$projectPath/samples/sample.dart';
-    addFile('$projectPath/.analysis_options', r'''
+    newFile('$projectPath/.analysis_options', content: r'''
 analyzer:
   exclude:
     - 'samples/**'
 ''');
-    addFile(sampleFile, '');
+    newFile(sampleFile);
     // attempt to set priority file
     await _setPriorityFile(sampleFile);
     _verifyPriorityFiles(sampleFile);
   }
 
   test_ignoredInAnalysisOptions_inChildContext() async {
-    addFile('$projectPath/.packages', '');
-    addFile('$projectPath/child/.packages', '');
+    newFile('$projectPath/.packages');
+    newFile('$projectPath/child/.packages');
     String sampleFile = '$projectPath/child/samples/sample.dart';
-    addFile('$projectPath/child/.analysis_options', r'''
+    newFile('$projectPath/child/.analysis_options', content: r'''
 analyzer:
   exclude:
     - 'samples/**'
 ''');
-    addFile(sampleFile, '');
+    newFile(sampleFile);
     // attempt to set priority file
     await _setPriorityFile(sampleFile);
     _verifyPriorityFiles(sampleFile);
   }
 
   test_ignoredInAnalysisOptions_inRootContext() async {
-    addFile('$projectPath/.packages', '');
-    addFile('$projectPath/child/.packages', '');
+    newFile('$projectPath/.packages');
+    newFile('$projectPath/child/.packages');
     String sampleFile = '$projectPath/child/samples/sample.dart';
-    addFile('$projectPath/.analysis_options', r'''
+    newFile('$projectPath/.analysis_options', content: r'''
 analyzer:
   exclude:
     - 'child/samples/**'
 ''');
-    addFile(sampleFile, '');
+    newFile(sampleFile);
     // attempt to set priority file
     await _setPriorityFile(sampleFile);
     _verifyPriorityFiles(sampleFile);
diff --git a/pkg/analysis_server/test/analysis/update_content_test.dart b/pkg/analysis_server/test/analysis/update_content_test.dart
index f2733f8..a4fc364 100644
--- a/pkg/analysis_server/test/analysis/update_content_test.dart
+++ b/pkg/analysis_server/test/analysis/update_content_test.dart
@@ -61,21 +61,18 @@
   }
 
   test_multiple_contexts() async {
-    String fooPath = '/project1/foo.dart';
-    resourceProvider.newFile(fooPath, '''
+    String fooPath = newFile('/project1/foo.dart', content: '''
 library foo;
 import '../project2/baz.dart';
-main() { f(); }''');
-    String barPath = '/project2/bar.dart';
-    resourceProvider.newFile(barPath, '''
+main() { f(); }''').path;
+    String barPath = newFile('/project2/bar.dart', content: '''
 library bar;
 import 'baz.dart';
-main() { f(); }''');
-    String bazPath = '/project2/baz.dart';
-    resourceProvider.newFile(bazPath, '''
+main() { f(); }''').path;
+    String bazPath = newFile('/project2/baz.dart', content: '''
 library baz;
 f(int i) {}
-''');
+''').path;
     Request request =
         new AnalysisSetAnalysisRootsParams(['/project1', '/project2'], [])
             .toRequest('0');
@@ -106,7 +103,7 @@
   @failingTest
   test_overlay_addPreviouslyImported() async {
     // The list of errors doesn't include errors for '/project/target.dart'.
-    Folder project = resourceProvider.newFolder('/project');
+    Folder project = newFolder('/project');
     handleSuccessfulRequest(
         new AnalysisSetAnalysisRootsParams([project.path], []).toRequest('0'));
 
@@ -130,8 +127,8 @@
 
   test_overlayOnly() async {
     String filePath = '/User/project1/test.dart';
-    Folder folder1 = resourceProvider.newFolder('/User/project1');
-    Folder folder2 = resourceProvider.newFolder('/User/project2');
+    Folder folder1 = newFolder('/User/project1');
+    Folder folder2 = newFolder('/User/project2');
     Request request =
         new AnalysisSetAnalysisRootsParams([folder1.path, folder2.path], [])
             .toRequest('0');
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index 2546cd8..1f797a9 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -14,11 +14,11 @@
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analyzer/context/context_root.dart' as analyzer;
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:analyzer_plugin/src/protocol/protocol_internal.dart' as plugin;
@@ -47,10 +47,9 @@
 /**
  * An abstract base for all 'analysis' domain tests.
  */
-class AbstractAnalysisTest {
+class AbstractAnalysisTest extends Object with ResourceProviderMixin {
   bool generateSummaryFiles = false;
   MockServerChannel serverChannel;
-  MemoryResourceProvider resourceProvider;
   MockPackageMapProvider packageMapProvider;
   TestPluginManager pluginManager;
   AnalysisServer server;
@@ -89,12 +88,6 @@
     handleSuccessfulRequest(request);
   }
 
-  String addFile(String path, String content) {
-    path = resourceProvider.convertPath(path);
-    resourceProvider.newFile(path, content);
-    return path;
-  }
-
   void addGeneralAnalysisSubscription(GeneralAnalysisService service) {
     generalServices.add(service);
     Request request = new AnalysisSetGeneralSubscriptionsParams(generalServices)
@@ -103,7 +96,7 @@
   }
 
   String addTestFile(String content) {
-    addFile(testFile, content);
+    newFile(testFile, content: content);
     this.testCode = content;
     return testFile;
   }
@@ -137,7 +130,7 @@
    * Creates a project `/project`.
    */
   void createProject({Map<String, String> packageRoots}) {
-    resourceProvider.newFolder(projectPath);
+    newFolder(projectPath);
     Request request = new AnalysisSetAnalysisRootsParams([projectPath], [],
             packageRoots: packageRoots)
         .toRequest('0');
@@ -149,7 +142,7 @@
    * Fails if not found.
    */
   int findFileOffset(String path, String search) {
-    File file = resourceProvider.getResource(path) as File;
+    File file = getFile(path);
     String code = file.createSource().contents.data;
     int offset = code.indexOf(search);
     expect(offset, isNot(-1), reason: '"$search" in\n$code');
@@ -177,8 +170,7 @@
   }
 
   String modifyTestFile(String content) {
-    String path = resourceProvider.convertPath(testFile);
-    resourceProvider.updateFile(path, content);
+    modifyFile(testFile, content);
     this.testCode = content;
     return testFile;
   }
@@ -204,7 +196,6 @@
 
   void setUp() {
     serverChannel = new MockServerChannel();
-    resourceProvider = new MemoryResourceProvider();
     projectPath = resourceProvider.convertPath('/project');
     testFolder = resourceProvider.convertPath('/project/bin');
     testFile = resourceProvider.convertPath('/project/bin/test.dart');
@@ -225,7 +216,6 @@
     server.done();
     handler = null;
     server = null;
-    resourceProvider = null;
     serverChannel = null;
   }
 
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 31c8a50..9ba47f2 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -10,10 +10,10 @@
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_server.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:plugin/manager.dart';
 import 'package:test/test.dart';
@@ -29,10 +29,9 @@
 }
 
 @reflectiveTest
-class AnalysisServerTest {
+class AnalysisServerTest extends Object with ResourceProviderMixin {
   MockServerChannel channel;
   AnalysisServer server;
-  MemoryResourceProvider resourceProvider;
   MockPackageMapProvider packageMapProvider;
 
   /**
@@ -42,10 +41,10 @@
   Future do_not_test_no_duplicate_notifications() async {
     // Subscribe to STATUS so we'll know when analysis is done.
     server.serverServices = [ServerService.STATUS].toSet();
-    resourceProvider.newFolder('/foo');
-    resourceProvider.newFolder('/bar');
-    resourceProvider.newFile('/foo/foo.dart', 'import "../bar/bar.dart";');
-    File bar = resourceProvider.newFile('/bar/bar.dart', 'library bar;');
+    newFolder('/foo');
+    newFolder('/bar');
+    newFile('/foo/foo.dart', content: 'import "../bar/bar.dart";');
+    File bar = newFile('/bar/bar.dart', content: 'library bar;');
     server.setAnalysisRoots('0', ['/foo', '/bar'], [], {});
     Map<AnalysisService, Set<String>> subscriptions =
         <AnalysisService, Set<String>>{};
@@ -92,7 +91,6 @@
   void setUp() {
     processRequiredPlugins();
     channel = new MockServerChannel();
-    resourceProvider = new MemoryResourceProvider();
     // Create an SDK in the mock file system.
     new MockSdk(resourceProvider: resourceProvider);
     packageMapProvider = new MockPackageMapProvider();
@@ -116,9 +114,9 @@
 
   Future test_serverStatusNotifications() {
     server.serverServices.add(ServerService.STATUS);
-    resourceProvider.newFolder('/pkg');
-    resourceProvider.newFolder('/pkg/lib');
-    resourceProvider.newFile('/pkg/lib/test.dart', 'class C {}');
+    newFolder('/pkg');
+    newFolder('/pkg/lib');
+    newFile('/pkg/lib/test.dart', content: 'class C {}');
     server.setAnalysisRoots('0', ['/pkg'], [], {});
     // Pump the event queue to make sure the server has finished any
     // analysis.
@@ -144,8 +142,8 @@
 
   test_setAnalysisSubscriptions_fileInIgnoredFolder_newOptions() async {
     String path = '/project/samples/sample.dart';
-    resourceProvider.newFile(path, '');
-    resourceProvider.newFile('/project/analysis_options.yaml', r'''
+    newFile(path);
+    newFile('/project/analysis_options.yaml', content: r'''
 analyzer:
   exclude:
     - 'samples/**'
@@ -163,8 +161,8 @@
 
   test_setAnalysisSubscriptions_fileInIgnoredFolder_oldOptions() async {
     String path = '/project/samples/sample.dart';
-    resourceProvider.newFile(path, '');
-    resourceProvider.newFile('/project/.analysis_options', r'''
+    newFile(path);
+    newFile('/project/.analysis_options', content: r'''
 analyzer:
   exclude:
     - 'samples/**'
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index af60220..75833ab 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -74,12 +74,12 @@
     super.setUp();
     return new Future(() {
       String content = spec.source;
-      addFile(testFile, content);
+      newFile(testFile, content: content);
       this.testCode = content;
       completionOffset = spec.testLocation;
       if (extraFiles != null) {
         extraFiles.forEach((String fileName, String content) {
-          addFile(fileName, content);
+          newFile(fileName, content: content);
         });
       }
     }).then((_) => getSuggestions()).then((_) {
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 566c06c..7933584 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library test.context.directory.manager;
-
 import 'dart:async';
 
 import 'package:analysis_server/src/context_manager.dart';
@@ -12,7 +10,6 @@
 import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/error/error.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/error_processor.dart';
 import 'package:analyzer/src/context/builder.dart';
@@ -25,6 +22,7 @@
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/services/lint.dart';
 import 'package:analyzer/src/summary/summary_file_builder.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer/src/util/glob.dart';
 import 'package:front_end/src/api_prototype/byte_store.dart';
 import 'package:front_end/src/base/performance_logger.dart';
@@ -90,16 +88,16 @@
     //return super.test_embedder_added();
     fail('NoSuchMethodError');
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([libPath, 'nope.dart']);
-    String embedderPath = newFolder([projPath, 'embedder']);
-    newFile([embedderPath, 'entry.dart']);
-    String embedderSrcPath = newFolder([projPath, 'embedder', 'src']);
-    newFile([embedderSrcPath, 'part.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    newFile('$libPath/nope.dart');
+    String embedderPath = '$projPath/embedder';
+    newFile('$embedderPath/entry.dart');
+    String embedderSrcPath = '$projPath/embedder/src';
+    newFile('$embedderSrcPath/part.dart');
 
     // Setup _embedder.yaml.
-    newFile([libPath, '_embedder.yaml'], r'''
+    newFile('$libPath/_embedder.yaml', content: r'''
 embedded_libs:
   "dart:foobar": "../embedder/entry.dart"
   "dart:typed_data": "../embedder/src/part"
@@ -122,7 +120,7 @@
     expect(sourceFactory.forUri('dart:typed_data'), isNull);
 
     // Add .packages file that introduces a dependency with embedded libs.
-    newFile([projPath, '.packages'], r'''
+    newFile('$projPath/.packages', content: r'''
 test_pack:lib/''');
 
     await pumpEventQueue();
@@ -138,21 +136,21 @@
 
   test_embedder_packagespec() async {
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([libPath, 'nope.dart']);
-    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
-    newFile([sdkExtPath, 'entry.dart']);
-    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
-    newFile([sdkExtSrcPath, 'part.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    newFile('$libPath/nope.dart');
+    String sdkExtPath = '$projPath/sdk_ext';
+    newFile('$sdkExtPath/entry.dart');
+    String sdkExtSrcPath = '$projPath/sdk_ext/src';
+    newFile('$sdkExtSrcPath/part.dart');
     // Setup _embedder.yaml.
-    newFile([libPath, '_embedder.yaml'], r'''
+    newFile('$libPath/_embedder.yaml', content: r'''
 embedded_libs:
   "dart:foobar": "../sdk_ext/entry.dart"
   "dart:typed_data": "../sdk_ext/src/part"
   ''');
     // Setup .packages file
-    newFile([projPath, '.packages'], r'''
+    newFile('$projPath/.packages', content: r'''
 test_pack:lib/''');
     // Setup context.
 
@@ -240,14 +238,14 @@
     manager.setIgnorePatternsForContext(
         rootInfo, ['sdk_ext/**', 'lib/ignoreme.dart']);
     // Start creating files.
-    newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([libPath, 'ignoreme.dart']);
-    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
-    newFile([sdkExtPath, 'entry.dart']);
-    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
-    newFile([sdkExtSrcPath, 'part.dart']);
+    newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    newFile('$libPath/ignoreme.dart');
+    String sdkExtPath = '$projPath/sdk_ext';
+    newFile('$sdkExtPath/entry.dart');
+    String sdkExtSrcPath = '$projPath/sdk_ext/src';
+    newFile('$sdkExtSrcPath/part.dart');
     // Pump event loop so new files are discovered and added to context.
     await pumpEventQueue();
     // Verify that ignored files were ignored.
@@ -368,21 +366,21 @@
 
   test_sdk_ext_packagespec() async {
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([libPath, 'nope.dart']);
-    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
-    newFile([sdkExtPath, 'entry.dart']);
-    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
-    newFile([sdkExtSrcPath, 'part.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    newFile('$libPath/nope.dart');
+    String sdkExtPath = '$projPath/sdk_ext';
+    newFile('$sdkExtPath/entry.dart');
+    String sdkExtSrcPath = '$projPath/sdk_ext/src';
+    newFile('$sdkExtSrcPath/part.dart');
     // Setup sdk extension mapping.
-    newFile([libPath, '_sdkext'], r'''
+    newFile('$libPath/_sdkext', content: r'''
 {
   "dart:foobar": "../sdk_ext/entry.dart"
 }
 ''');
     // Setup .packages file
-    newFile([projPath, '.packages'], r'''
+    newFile('$projPath/.packages', content: r'''
 test_pack:lib/''');
     // Setup context.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
@@ -429,13 +427,13 @@
   }
 
   void test_setRoots_addFolderWithNestedPackageSpec() {
-    String examplePath = newFolder([projPath, ContextManagerTest.EXAMPLE_NAME]);
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+    String examplePath = '$projPath/${ContextManagerTest.EXAMPLE_NAME}';
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
 
-    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([examplePath, ContextManagerImpl.PACKAGE_SPEC_NAME]);
-    newFile([examplePath, 'example.dart']);
+    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}');
+    newFile('$libPath/main.dart');
+    newFile('$examplePath/${ContextManagerImpl.PACKAGE_SPEC_NAME}');
+    newFile('$examplePath/example.dart');
 
     packageMapProvider.packageMap['proj'] = <Folder>[
       resourceProvider.getResource(libPath)
@@ -458,14 +456,15 @@
   }
 
   void test_setRoots_addFolderWithNestedPubspec() {
-    String examplePath = newFolder([projPath, ContextManagerTest.EXAMPLE_NAME]);
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+    String examplePath = '$projPath/${ContextManagerTest.EXAMPLE_NAME}';
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
 
-    newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
-    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'proj:lib/');
-    newFile([libPath, 'main.dart']);
-    newFile([examplePath, ContextManagerImpl.PUBSPEC_NAME]);
-    newFile([examplePath, 'example.dart']);
+    newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
+    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'proj:lib/');
+    newFile('$libPath/main.dart');
+    newFile('$examplePath/${ContextManagerImpl.PUBSPEC_NAME}');
+    newFile('$examplePath/example.dart');
 
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
@@ -495,7 +494,7 @@
     String packagespecPath = path.posix.join(projPath, '.packages');
     resourceProvider.newFile(packagespecPath,
         'unittest:file:///home/somebody/.pub/cache/unittest-0.9.9/lib/');
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
     File mainFile =
         resourceProvider.newFile(path.posix.join(libPath, 'main.dart'), '');
     Source source = mainFile.createSource();
@@ -546,17 +545,18 @@
   }
 
   void test_setRoots_addFolderWithPubspecAndLib() {
-    String binPath = newFolder([projPath, ContextManagerTest.BIN_NAME]);
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    String srcPath = newFolder([libPath, ContextManagerTest.SRC_NAME]);
-    String testPath = newFolder([projPath, ContextManagerTest.TEST_NAME]);
+    String binPath = '$projPath/${ContextManagerTest.BIN_NAME}';
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    String srcPath = '$libPath/${ContextManagerTest.SRC_NAME}';
+    String testPath = '$projPath/${ContextManagerTest.TEST_NAME}';
 
-    newFile([projPath, ContextManagerImpl.PUBSPEC_NAME]);
-    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'proj:lib/');
-    String appPath = newFile([binPath, 'app.dart']);
-    newFile([libPath, 'main.dart']);
-    newFile([srcPath, 'internal.dart']);
-    String testFilePath = newFile([testPath, 'main_test.dart']);
+    newFile('$projPath/${ContextManagerImpl.PUBSPEC_NAME}');
+    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'proj:lib/');
+    String appPath = newFile('$binPath/app.dart').path;
+    newFile('$libPath/main.dart');
+    newFile('$srcPath/internal.dart');
+    String testFilePath = newFile('$testPath/main_test.dart').path;
 
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     Iterable<Source> sources = callbacks.currentFileSources(projPath);
@@ -609,10 +609,12 @@
     String projectBLib = '$root/sub/sub2/bbb/lib';
     String subProjectB_file = '$projectB/bin/b.dart';
     // create files
-    newFile([projectA, ContextManagerImpl.PUBSPEC_NAME]);
-    newFile([projectA, ContextManagerImpl.PACKAGE_SPEC_NAME], 'foo:lib/');
-    newFile([projectB, ContextManagerImpl.PUBSPEC_NAME]);
-    newFile([projectB, ContextManagerImpl.PACKAGE_SPEC_NAME], 'bar:lib/');
+    newFile('$projectA/${ContextManagerImpl.PUBSPEC_NAME}');
+    newFile('$projectA/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'foo:lib/');
+    newFile('$projectB/${ContextManagerImpl.PUBSPEC_NAME}');
+    newFile('$projectB/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'bar:lib/');
     resourceProvider.newFile(rootFile, 'library root;');
     resourceProvider.newFile(subProjectA_file, 'library a;');
     resourceProvider.newFile(subProjectB_file, 'library b;');
@@ -640,8 +642,8 @@
   void test_setRoots_addPackageRoot() {
     String packagePathFoo = '/package1/foo';
     String packageRootPath = '/package2/foo';
-    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
-        'foo:file:///package1/foo');
+    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'foo:file:///package1/foo');
     Folder packageFolder = resourceProvider.newFolder(packagePathFoo);
     List<String> includedPaths = <String>[projPath];
     List<String> excludedPaths = <String>[];
@@ -893,8 +895,8 @@
 
   void test_setRoots_newlyAddedFoldersGetProperPackageMap() {
     String packagePath = '/package/foo';
-    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
-        'foo:file:///package/foo');
+    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'foo:file:///package/foo');
     Folder packageFolder = resourceProvider.newFolder(packagePath);
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     expect(
@@ -939,7 +941,8 @@
 
   void test_setRoots_packageResolver() {
     String filePath = path.posix.join(projPath, 'lib', 'foo.dart');
-    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME], 'foo:lib/');
+    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'foo:lib/');
     resourceProvider.newFile(filePath, 'contents');
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
@@ -1077,8 +1080,8 @@
     String packagePathFoo = '/package1/foo';
     String packageRootPath = '/package2/foo';
     Folder packageFolder = resourceProvider.newFolder(packagePathFoo);
-    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
-        'foo:file:///package1/foo');
+    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'foo:file:///package1/foo');
     List<String> includedPaths = <String>[projPath];
     List<String> excludedPaths = <String>[];
     manager.setRoots(includedPaths, excludedPaths,
@@ -1655,7 +1658,7 @@
   }
 }
 
-abstract class ContextManagerTest {
+abstract class ContextManagerTest extends Object with ResourceProviderMixin {
   /**
    * The name of the 'bin' directory.
    */
@@ -1685,8 +1688,6 @@
 
   TestContextManagerCallbacks callbacks;
 
-  MemoryResourceProvider resourceProvider;
-
   MockPackageMapProvider packageMapProvider;
 
   UriResolver packageResolver = null;
@@ -1737,11 +1738,6 @@
 
   Map<String, List<Folder>> get _currentPackageMap => _packageMap(projPath);
 
-  void deleteFile(List<String> pathComponents) {
-    String filePath = path.posix.joinAll(pathComponents);
-    resourceProvider.deleteFile(filePath);
-  }
-
   /**
    * TODO(brianwilkerson) This doesn't add the strong mode processor when using
    * the new analysis driver.
@@ -1749,24 +1745,6 @@
   ErrorProcessor getProcessor(AnalysisError error) => errorProcessors
       .firstWhere((ErrorProcessor p) => p.appliesTo(error), orElse: () => null);
 
-  String newFile(List<String> pathComponents, [String content = '']) {
-    String filePath = path.posix.joinAll(pathComponents);
-    resourceProvider.newFile(filePath, content);
-    return filePath;
-  }
-
-  String newFileFromBytes(List<String> pathComponents, List<int> bytes) {
-    String filePath = path.posix.joinAll(pathComponents);
-    resourceProvider.newFileWithBytes(filePath, bytes);
-    return filePath;
-  }
-
-  String newFolder(List<String> pathComponents) {
-    String folderPath = path.posix.joinAll(pathComponents);
-    resourceProvider.newFolder(folderPath);
-    return folderPath;
-  }
-
   void processRequiredPlugins() {
     ExtensionManager manager = new ExtensionManager();
     manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
@@ -1778,7 +1756,6 @@
 
   void setUp() {
     processRequiredPlugins();
-    resourceProvider = new MemoryResourceProvider();
     resourceProvider.newFolder(projPath);
     packageMapProvider = new MockPackageMapProvider();
     // Create an SDK in the mock file system.
@@ -1786,6 +1763,7 @@
     DartSdkManager sdkManager = new DartSdkManager('/', true);
     manager = new ContextManagerImpl(
         resourceProvider,
+        new FileContentOverlay(),
         sdkManager,
         providePackageResolver,
         packageMapProvider,
@@ -1833,9 +1811,13 @@
 abstract class ContextManagerWithOptionsTest extends ContextManagerTest {
   String get optionsFileName;
 
+  void deleteOptionsFile() {
+    deleteFile('$projPath/$optionsFileName');
+  }
+
   test_analysis_options_file_delete() async {
     // Setup analysis options
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 embedded_libs:
   "dart:foobar": "../sdk_ext/entry.dart"
 analyzer:
@@ -1858,7 +1840,7 @@
     expect(analysisOptions.enableStrictCallChecks, isTrue);
 
     // Remove options.
-    deleteFile([projPath, optionsFileName]);
+    deleteOptionsFile();
     await pumpEventQueue();
 
     // Verify defaults restored.
@@ -1872,8 +1854,8 @@
     // This fails because the ContextBuilder doesn't pick up the strongMode
     // flag from the embedder.yaml file.
     // Setup _embedder.yaml.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, '_embedder.yaml'], r'''
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/_embedder.yaml', content: r'''
 analyzer:
   strong-mode: true
   errors:
@@ -1884,11 +1866,11 @@
 ''');
 
     // Setup .packages file
-    newFile([projPath, '.packages'], r'''
+    newFile('$projPath/.packages', content: r'''
 test_pack:lib/''');
 
     // Setup analysis options
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   language:
     enableStrictCallChecks: true
@@ -1910,7 +1892,7 @@
     expect(lints, hasLength(2));
 
     // Remove options.
-    deleteFile([projPath, optionsFileName]);
+    deleteOptionsFile();
     await pumpEventQueue();
 
     // Verify defaults restored.
@@ -1923,17 +1905,17 @@
 
   test_analysis_options_include() async {
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
-    newFile([sdkExtPath, 'entry.dart']);
-    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
-    newFile([sdkExtSrcPath, 'part.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    String sdkExtPath = '$projPath/sdk_ext';
+    newFile('$sdkExtPath/entry.dart');
+    String sdkExtSrcPath = '$projPath/sdk_ext/src';
+    newFile('$sdkExtSrcPath/part.dart');
     // Setup analysis options file which includes another options file.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 include: other_options.yaml
 ''');
-    newFile([projPath, 'other_options.yaml'], r'''
+    newFile('$projPath/other_options.yaml', content: r'''
 analyzer:
   language:
     enableStrictCallChecks: true
@@ -1955,15 +1937,15 @@
 
   test_analysis_options_include_package() async {
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
-    newFile([sdkExtPath, 'entry.dart']);
-    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
-    newFile([sdkExtSrcPath, 'part.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    String sdkExtPath = '$projPath/sdk_ext';
+    newFile('$sdkExtPath/entry.dart');
+    String sdkExtSrcPath = '$projPath/sdk_ext/src';
+    newFile('$sdkExtSrcPath/part.dart');
     // Setup package
     String booLibPosixPath = '/my/pkg/boo/lib';
-    newFile([booLibPosixPath, 'other_options.yaml'], r'''
+    newFile('$booLibPosixPath/other_options.yaml', content: r'''
 analyzer:
   language:
     enableStrictCallChecks: true
@@ -1974,9 +1956,9 @@
     - camel_case_types
 ''');
     // Setup analysis options file which includes another options file.
-    newFile([projPath, ContextManagerImpl.PACKAGE_SPEC_NAME],
-        'boo:$booLibPosixPath\n');
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/${ContextManagerImpl.PACKAGE_SPEC_NAME}',
+        content: 'boo:$booLibPosixPath\n');
+    newFile('$projPath/$optionsFileName', content: r'''
 include: package:boo/other_options.yaml
 ''');
     // Setup context.
@@ -1991,16 +1973,16 @@
 
   test_analysis_options_parse_failure() async {
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
-    newFile([sdkExtPath, 'entry.dart']);
-    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
-    newFile([sdkExtSrcPath, 'part.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    String sdkExtPath = '$projPath/sdk_ext';
+    newFile('$sdkExtPath/entry.dart');
+    String sdkExtSrcPath = '$projPath/sdk_ext/src';
+    newFile('$sdkExtSrcPath/part.dart');
     // Setup analysis options file with ignore list.
-    String optionsFilePath = newFile([projPath, optionsFileName], r'''
+    String optionsFilePath = newFile('$projPath/$optionsFileName', content: r'''
 ;
-''');
+''').path;
     // Setup context.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
 
@@ -2012,7 +1994,7 @@
   }
 
   test_deleteRoot_hasAnalysisOptions() async {
-    newFile([projPath, optionsFileName], '');
+    newFile('$projPath/$optionsFileName');
 
     // Add the root.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
@@ -2029,14 +2011,14 @@
     // This fails because the ContextBuilder doesn't pick up the strongMode
     // flag from the embedder.yaml file.
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
-    newFile([projPath, 'test', 'test.dart']);
-    newFile([sdkExtPath, 'entry.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    String sdkExtPath = '$projPath/sdk_ext';
+    newFile('$projPath/test', content: 'test.dart');
+    newFile('$sdkExtPath/entry.dart');
     List<int> bytes = new SummaryBuilder([], null, true).build();
-    newFileFromBytes([projPath, 'sdk.ds'], bytes);
+    newFileWithBytes('$projPath/sdk.ds', bytes);
     // Setup _embedder.yaml.
-    newFile([libPath, '_embedder.yaml'], r'''
+    newFile('$libPath/_embedder.yaml', content: r'''
 embedded_libs:
   "dart:foobar": "../sdk_ext/entry.dart"
 analyzer:
@@ -2050,11 +2032,11 @@
     - avoid_as
 ''');
     // Setup .packages file
-    newFile([projPath, '.packages'], r'''
+    newFile('$projPath/.packages', content: r'''
 test_pack:lib/''');
 
     // Setup analysis options
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   exclude:
     - 'test/**'
@@ -2114,7 +2096,7 @@
 
   test_error_filter_analysis_option() async {
     // Create files.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   errors:
     unused_local_variable: ignore
@@ -2129,7 +2111,7 @@
 
   test_error_filter_analysis_option_multiple_filters() async {
     // Create files.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   errors:
     invalid_assignment: ignore
@@ -2147,7 +2129,7 @@
 
   test_error_filter_analysis_option_synonyms() async {
     // Create files.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   errors:
     unused_local_variable: ignore
@@ -2163,7 +2145,7 @@
 
   test_error_filter_analysis_option_unpsecified() async {
     // Create files.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
 #  errors:
 #    unused_local_variable: ignore
@@ -2229,15 +2211,15 @@
   test_path_filter_analysis_option() async {
     // This fails because we're not analyzing the analysis options file.
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([libPath, 'nope.dart']);
-    String sdkExtPath = newFolder([projPath, 'sdk_ext']);
-    newFile([sdkExtPath, 'entry.dart']);
-    String sdkExtSrcPath = newFolder([projPath, 'sdk_ext', 'src']);
-    newFile([sdkExtSrcPath, 'part.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    newFile('$libPath/nope.dart');
+    String sdkExtPath = '$projPath/sdk_ext';
+    newFile('$sdkExtPath/entry.dart');
+    String sdkExtSrcPath = '$projPath/sdk_ext/src';
+    newFile('$sdkExtSrcPath/part.dart');
     // Setup analysis options file with ignore list.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   exclude:
     - lib/nope.dart
@@ -2259,19 +2241,19 @@
 
   test_path_filter_child_contexts_option() async {
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([libPath, 'pubspec.yaml'], r'''
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    newFile('$libPath/pubspec.yaml', content: r'''
 name: foobar
 ''');
-    String otherLibPath = newFolder([projPath, 'other_lib']);
-    newFile([otherLibPath, 'entry.dart']);
-    newFile([otherLibPath, 'pubspec.yaml'], r'''
+    String otherLibPath = '$projPath/other_lib';
+    newFile('$otherLibPath/entry.dart');
+    newFile('$otherLibPath/pubspec.yaml', content: r'''
 name: other_lib
 ''');
     // Setup analysis options file with ignore list that ignores the 'other_lib'
     // directory by name.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   exclude:
     - 'other_lib'
@@ -2289,19 +2271,19 @@
 
   test_path_filter_recursive_wildcard_child_contexts_option() async {
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([libPath, 'pubspec.yaml'], r'''
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    newFile('$libPath/pubspec.yaml', content: r'''
   name: foobar
   ''');
-    String otherLibPath = newFolder([projPath, 'other_lib']);
-    newFile([otherLibPath, 'entry.dart']);
-    newFile([otherLibPath, 'pubspec.yaml'], r'''
+    String otherLibPath = '$projPath/other_lib';
+    newFile('$otherLibPath/entry.dart');
+    newFile('$otherLibPath/pubspec.yaml', content: r'''
   name: other_lib
   ''');
     // Setup analysis options file with ignore list that ignores 'other_lib'
     // and all descendants.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   exclude:
     - 'other_lib/**'
@@ -2320,19 +2302,19 @@
 
   test_path_filter_wildcard_child_contexts_option() async {
     // Create files.
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
-    newFile([libPath, 'pubspec.yaml'], r'''
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
+    newFile('$libPath/pubspec.yaml', content: r'''
 name: foobar
 ''');
-    String otherLibPath = newFolder([projPath, 'other_lib']);
-    newFile([otherLibPath, 'entry.dart']);
-    newFile([otherLibPath, 'pubspec.yaml'], r'''
+    String otherLibPath = '$projPath/other_lib';
+    newFile('$otherLibPath/entry.dart');
+    newFile('$otherLibPath/pubspec.yaml', content: r'''
 name: other_lib
 ''');
     // Setup analysis options file with ignore list that ignores 'other_lib'
     // and all immediate children.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   exclude:
     - 'other_lib/*'
@@ -2355,7 +2337,7 @@
     // create files
     resourceProvider.newFile(projectPubspec, 'name: project');
     resourceProvider.newFile(examplePubspec, 'name: example');
-    newFile([project, optionsFileName], r'''
+    newFile('$project/$optionsFileName', content: r'''
 analyzer:
   exclude:
     - 'example'
@@ -2389,7 +2371,7 @@
     // create files
     resourceProvider.newFile(aPubspec, 'name: aaa');
     resourceProvider.newFile(cPubspec, 'name: ccc');
-    newFile([a, optionsFileName], r'''
+    newFile('$a/$optionsFileName', content: r'''
 analyzer:
   exclude:
     - 'b**'
@@ -2416,12 +2398,12 @@
 
   test_strong_mode_analysis_option() async {
     // Create files.
-    newFile([projPath, optionsFileName], r'''
+    newFile('$projPath/$optionsFileName', content: r'''
 analyzer:
   strong-mode: true
 ''');
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
-    newFile([libPath, 'main.dart']);
+    String libPath = '$projPath/${ContextManagerTest.LIB_NAME}';
+    newFile('$libPath/main.dart');
     // Setup context.
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
     // Verify that analysis options was parsed and strong-mode set.
@@ -2429,9 +2411,9 @@
   }
 
   test_watchEvents() async {
-    String libPath = newFolder([projPath, ContextManagerTest.LIB_NAME]);
+    String libPath = newFolder('$projPath/${ContextManagerTest.LIB_NAME}').path;
     manager.setRoots(<String>[projPath], <String>[], <String, String>{});
-    newFile([libPath, 'main.dart']);
+    newFile('$libPath/main.dart');
     await new Future.delayed(new Duration(milliseconds: 1));
     expect(callbacks.watchEvents, hasLength(1));
   }
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 334e7f9..f79993c 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -9,10 +9,10 @@
 import 'package:analysis_server/protocol/protocol_generated.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/domain_analysis.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:plugin/manager.dart';
@@ -26,346 +26,271 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(AnalysisDomainTest);
+    defineReflectiveTests(AnalysisDomainHandlerTest);
     defineReflectiveTests(SetSubscriptionsTest);
   });
-
-  MockServerChannel serverChannel;
-  MemoryResourceProvider resourceProvider;
-  AnalysisServer server;
-  AnalysisDomainHandler handler;
-
-  void processRequiredPlugins() {
-    ExtensionManager manager = new ExtensionManager();
-    manager.processPlugins(AnalysisEngine.instance.requiredPlugins);
-  }
-
-  setUp(() {
-    serverChannel = new MockServerChannel();
-    resourceProvider = new MemoryResourceProvider();
-    processRequiredPlugins();
-    // Create an SDK in the mock file system.
-    new MockSdk(resourceProvider: resourceProvider);
-    server = new AnalysisServer(
-        serverChannel,
-        resourceProvider,
-        new MockPackageMapProvider(),
-        new AnalysisServerOptions(),
-        new DartSdkManager('/', false),
-        InstrumentationService.NULL_SERVICE);
-    handler = new AnalysisDomainHandler(server);
-  });
-
-  group('updateContent', testUpdateContent);
-
-  group('AnalysisDomainHandler', () {
-    // TODO(brianwilkerson) Re-enable these tests if we re-enable the
-    // analysis.getReachableSources request.
-//    group('getReachableSources', () {
-//      test('valid sources', () async {
-//        String fileA = '/project/a.dart';
-//        String fileB = '/project/b.dart';
-//        resourceProvider.newFile(fileA, 'import "b.dart";');
-//        resourceProvider.newFile(fileB, '');
-//
-//        server.setAnalysisRoots('0', ['/project/'], [], {});
-//
-//        await server.onAnalysisComplete;
-//
-//        var request =
-//            new AnalysisGetReachableSourcesParams(fileA).toRequest('0');
-//        var response = handler.handleRequest(request);
-//
-//        Map json = response.toJson()[Response.RESULT];
-//
-//        // Sanity checks.
-//        expect(json['sources'], hasLength(6));
-//        expect(json['sources']['file:///project/a.dart'],
-//            unorderedEquals(['dart:core', 'file:///project/b.dart']));
-//        expect(json['sources']['file:///project/b.dart'], ['dart:core']);
-//      });
-//
-//      test('invalid source', () async {
-//        resourceProvider.newFile('/project/a.dart', 'import "b.dart";');
-//        server.setAnalysisRoots('0', ['/project/'], [], {});
-//
-//        await server.onAnalysisComplete;
-//
-//        var request =
-//            new AnalysisGetReachableSourcesParams('/does/not/exist.dart')
-//                .toRequest('0');
-//        var response = handler.handleRequest(request);
-//        expect(response.error, isNotNull);
-//        expect(response.error.code,
-//            RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE);
-//      });
-//    });
-
-    group('setAnalysisRoots', () {
-      Response testSetAnalysisRoots(
-          List<String> included, List<String> excluded) {
-        Request request = new AnalysisSetAnalysisRootsParams(included, excluded)
-            .toRequest('0');
-        return handler.handleRequest(request);
-      }
-
-      group('excluded', () {
-        test('excluded folder', () async {
-          String fileA = '/project/aaa/a.dart';
-          String fileB = '/project/bbb/b.dart';
-          resourceProvider.newFile(fileA, '// a');
-          resourceProvider.newFile(fileB, '// b');
-          var response = testSetAnalysisRoots(['/project'], ['/project/bbb']);
-          expect(response, isResponseSuccess('0'));
-        });
-
-        test('not absolute', () async {
-          var response = testSetAnalysisRoots([], ['foo/bar']);
-          expect(
-              response,
-              isResponseFailure(
-                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
-        });
-
-        test('not normalized', () async {
-          var response = testSetAnalysisRoots([], ['/foo/../bar']);
-          expect(
-              response,
-              isResponseFailure(
-                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
-        });
-      });
-
-      group('included', () {
-        test('new folder', () async {
-          String file = '/project/bin/test.dart';
-          resourceProvider.newFile('/project/pubspec.yaml', 'name: project');
-          resourceProvider.newFile(file, 'main() {}');
-          var response = testSetAnalysisRoots(['/project'], []);
-          var serverRef = server;
-          expect(response, isResponseSuccess('0'));
-          // verify that unit is resolved eventually
-          await server.onAnalysisComplete;
-          var unit = await serverRef.getResolvedCompilationUnit(file);
-          expect(unit, isNotNull);
-        });
-
-        test('nonexistent folder', () async {
-          String fileB = '/project_b/b.dart';
-          resourceProvider.newFile(fileB, '// b');
-          var response = testSetAnalysisRoots(['/project_a', '/project_b'], []);
-          var serverRef = server;
-          expect(response, isResponseSuccess('0'));
-          // Non-existence of /project_a should not prevent files in /project_b
-          // from being analyzed.
-          await server.onAnalysisComplete;
-          var unit = await serverRef.getResolvedCompilationUnit(fileB);
-          expect(unit, isNotNull);
-        });
-
-        test('not absolute', () async {
-          var response = testSetAnalysisRoots(['foo/bar'], []);
-          expect(
-              response,
-              isResponseFailure(
-                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
-        });
-
-        test('not normalized', () async {
-          var response = testSetAnalysisRoots(['/foo/../bar'], []);
-          expect(
-              response,
-              isResponseFailure(
-                  '0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
-        });
-      });
-    });
-
-    group('setPriorityFiles', () {
-      test('invalid', () {
-        var request = new AnalysisSetPriorityFilesParams(['/project/lib.dart'])
-            .toRequest('0');
-        var response = handler.handleRequest(request);
-        expect(response, isResponseSuccess('0'));
-      });
-
-      test('valid', () {
-        resourceProvider.newFolder('/p1');
-        resourceProvider.newFile('/p1/a.dart', 'library a;');
-        resourceProvider.newFolder('/p2');
-        resourceProvider.newFile('/p2/b.dart', 'library b;');
-        resourceProvider.newFile('/p2/c.dart', 'library c;');
-
-        var setRootsRequest =
-            new AnalysisSetAnalysisRootsParams(['/p1', '/p2'], [])
-                .toRequest('0');
-        var setRootsResponse = handler.handleRequest(setRootsRequest);
-        expect(setRootsResponse, isResponseSuccess('0'));
-
-        void setPriorityFiles(List<String> fileList) {
-          var request =
-              new AnalysisSetPriorityFilesParams(fileList).toRequest('0');
-          var response = handler.handleRequest(request);
-          expect(response, isResponseSuccess('0'));
-          // TODO(brianwilkerson) Enable the line below after getPriorityFiles
-          // has been implemented.
-          // expect(server.getPriorityFiles(), unorderedEquals(fileList));
-        }
-
-        setPriorityFiles(['/p1/a.dart', '/p2/b.dart']);
-        setPriorityFiles(['/p2/b.dart', '/p2/c.dart']);
-        setPriorityFiles([]);
-      });
-    });
-
-    group('updateOptions', () {
-      test('invalid', () {
-        var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS, {
-          ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: {'not-an-option': true}
-        });
-        var response = handler.handleRequest(request);
-        // Invalid options should be silently ignored.
-        expect(response, isResponseSuccess('0'));
-      });
-
-      test('null', () {
-        // null is allowed as a synonym for {}.
-        var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS,
-            {ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: null});
-        var response = handler.handleRequest(request);
-        expect(response, isResponseSuccess('0'));
-      });
-    });
-  });
 }
 
-testUpdateContent() {
-  test('bad type', () {
+@reflectiveTest
+class AnalysisDomainHandlerTest extends AbstractAnalysisTest {
+  Future outOfRangeTest(SourceEdit edit) async {
+    AnalysisTestHelper helper = new AnalysisTestHelper();
+    helper.createSingleFileProject('library A;');
+    await helper.onAnalysisComplete;
+    helper.sendContentChange(new AddContentOverlay('library B;'));
+    await helper.onAnalysisComplete;
+    ChangeContentOverlay contentChange = new ChangeContentOverlay([edit]);
+    Request request =
+        new AnalysisUpdateContentParams({helper.testFile: contentChange})
+            .toRequest('0');
+    Response response = helper.handler.handleRequest(request);
+    expect(response,
+        isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE));
+  }
+
+  test_setAnalysisRoots_excludedFolder() async {
+    newFile('/project/aaa/a.dart', content: '// a');
+    newFile('/project/bbb/b.dart', content: '// b');
+    var response = testSetAnalysisRoots(['/project'], ['/project/bbb']);
+    expect(response, isResponseSuccess('0'));
+  }
+
+  test_setAnalysisRoots_included_newFolder() async {
+    newFile('/project/pubspec.yaml', content: 'name: project');
+    String file = newFile('/project/bin/test.dart', content: 'main() {}').path;
+    var response = testSetAnalysisRoots(['/project'], []);
+    var serverRef = server;
+    expect(response, isResponseSuccess('0'));
+    // verify that unit is resolved eventually
+    await server.onAnalysisComplete;
+    var unit = await serverRef.getResolvedCompilationUnit(file);
+    expect(unit, isNotNull);
+  }
+
+  test_setAnalysisRoots_included_nonexistentFolder() async {
+    String fileB = newFile('/project_b/b.dart', content: '// b').path;
+    var response = testSetAnalysisRoots(['/project_a', '/project_b'], []);
+    var serverRef = server;
+    expect(response, isResponseSuccess('0'));
+    // Non-existence of /project_a should not prevent files in /project_b
+    // from being analyzed.
+    await server.onAnalysisComplete;
+    var unit = await serverRef.getResolvedCompilationUnit(fileB);
+    expect(unit, isNotNull);
+  }
+
+  test_setAnalysisRoots_included_notAbsolute() async {
+    var response = testSetAnalysisRoots(['foo/bar'], []);
+    expect(response,
+        isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+  }
+
+  test_setAnalysisRoots_included_notNormalized() async {
+    var response = testSetAnalysisRoots(['/foo/../bar'], []);
+    expect(response,
+        isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+  }
+
+  test_setAnalysisRoots_notAbsolute() async {
+    var response = testSetAnalysisRoots([], ['foo/bar']);
+    expect(response,
+        isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+  }
+
+  test_setAnalysisRoots_notNormalized() async {
+    var response = testSetAnalysisRoots([], ['/foo/../bar']);
+    expect(response,
+        isResponseFailure('0', RequestErrorCode.INVALID_FILE_PATH_FORMAT));
+  }
+
+  test_setPriorityFiles_invalid() {
+    var request = new AnalysisSetPriorityFilesParams(['/project/lib.dart'])
+        .toRequest('0');
+    var response = handler.handleRequest(request);
+    expect(response, isResponseSuccess('0'));
+  }
+
+  test_setPriorityFiles_valid() {
+    newFile('/p1/a.dart', content: 'library a;');
+    newFile('/p2/b.dart', content: 'library b;');
+    newFile('/p2/c.dart', content: 'library c;');
+
+    var setRootsRequest =
+        new AnalysisSetAnalysisRootsParams(['/p1', '/p2'], []).toRequest('0');
+    var setRootsResponse = handler.handleRequest(setRootsRequest);
+    expect(setRootsResponse, isResponseSuccess('0'));
+
+    void setPriorityFiles(List<String> fileList) {
+      var request = new AnalysisSetPriorityFilesParams(fileList).toRequest('0');
+      var response = handler.handleRequest(request);
+      expect(response, isResponseSuccess('0'));
+      // TODO(brianwilkerson) Enable the line below after getPriorityFiles
+      // has been implemented.
+      // expect(server.getPriorityFiles(), unorderedEquals(fileList));
+    }
+
+    setPriorityFiles(['/p1/a.dart', '/p2/b.dart']);
+    setPriorityFiles(['/p2/b.dart', '/p2/c.dart']);
+    setPriorityFiles([]);
+  }
+
+  test_updateContent_badType() async {
     AnalysisTestHelper helper = new AnalysisTestHelper();
     helper.createSingleFileProject('// empty');
-    return helper.onAnalysisComplete.then((_) {
-      Request request = new Request('0', ANALYSIS_REQUEST_UPDATE_CONTENT, {
-        ANALYSIS_REQUEST_UPDATE_CONTENT_FILES: {
-          helper.testFile: {
-            'type': 'foo',
-          }
+    await helper.onAnalysisComplete;
+    Request request = new Request('0', ANALYSIS_REQUEST_UPDATE_CONTENT, {
+      ANALYSIS_REQUEST_UPDATE_CONTENT_FILES: {
+        helper.testFile: {
+          'type': 'foo',
         }
-      });
-      Response response = helper.handler.handleRequest(request);
-      expect(response, isResponseFailure('0'));
+      }
     });
-  });
+    Response response = helper.handler.handleRequest(request);
+    expect(response, isResponseFailure('0'));
+  }
 
-  test('full content', () {
+  test_updateContent_changeOnDisk_duringOverride() async {
+    AnalysisTestHelper helper = new AnalysisTestHelper();
+    helper.createSingleFileProject('library A;');
+    await helper.onAnalysisComplete;
+    // update code
+    helper.sendContentChange(new AddContentOverlay('library B;'));
+    // There should be no errors
+    await helper.onAnalysisComplete;
+    expect(helper.getTestErrors(), hasLength(0));
+    // Change file on disk, adding a syntax error.
+    helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
+    // There should still be no errors (file should not have been reread).
+    await helper.onAnalysisComplete;
+    expect(helper.getTestErrors(), hasLength(0));
+    // Send a content change with a null content param--file should be
+    // reread from disk.
+    helper.sendContentChange(new RemoveContentOverlay());
+    // There should be errors now.
+    await helper.onAnalysisComplete;
+    expect(helper.getTestErrors(), hasLength(1));
+  }
+
+  test_updateContent_changeOnDisk_normal() async {
+    AnalysisTestHelper helper = new AnalysisTestHelper();
+    helper.createSingleFileProject('library A;');
+    await helper.onAnalysisComplete;
+    // There should be no errors
+    expect(helper.getTestErrors(), hasLength(0));
+    // Change file on disk, adding a syntax error.
+    helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
+    // There should be errors now.
+    await pumpEventQueue();
+    await helper.onAnalysisComplete;
+    expect(helper.getTestErrors(), hasLength(1));
+  }
+
+  test_updateContent_fullContent() async {
     AnalysisTestHelper helper = new AnalysisTestHelper();
     helper.createSingleFileProject('// empty');
-    return helper.onAnalysisComplete.then((_) {
-      // no errors initially
-      List<AnalysisError> errors = helper.getTestErrors();
-      expect(errors, isEmpty);
-      // update code
-      helper.sendContentChange(new AddContentOverlay('library lib'));
-      // wait, there is an error
-      return helper.onAnalysisComplete.then((_) {
-        List<AnalysisError> errors = helper.getTestErrors();
-        expect(errors, hasLength(1));
-      });
-    });
-  });
+    await helper.onAnalysisComplete;
+    // no errors initially
+    List<AnalysisError> errors = helper.getTestErrors();
+    expect(errors, isEmpty);
+    // update code
+    helper.sendContentChange(new AddContentOverlay('library lib'));
+    // wait, there is an error
+    await helper.onAnalysisComplete;
+    errors = helper.getTestErrors();
+    expect(errors, hasLength(1));
+  }
 
-  test('incremental', () {
+  test_updateContent_incremental() async {
     AnalysisTestHelper helper = new AnalysisTestHelper();
     String initialContent = 'library A;';
     helper.createSingleFileProject(initialContent);
-    return helper.onAnalysisComplete.then((_) {
-      // no errors initially
-      List<AnalysisError> errors = helper.getTestErrors();
-      expect(errors, isEmpty);
-      // Add the file to the cache
-      helper.sendContentChange(new AddContentOverlay(initialContent));
-      // update code
-      helper.sendContentChange(new ChangeContentOverlay(
-          [new SourceEdit('library '.length, 'A;'.length, 'lib')]));
-      // wait, there is an error
-      return helper.onAnalysisComplete.then((_) {
-        List<AnalysisError> errors = helper.getTestErrors();
-        expect(errors, hasLength(1));
-      });
-    });
-  });
+    await helper.onAnalysisComplete;
+    // no errors initially
+    List<AnalysisError> errors = helper.getTestErrors();
+    expect(errors, isEmpty);
+    // Add the file to the cache
+    helper.sendContentChange(new AddContentOverlay(initialContent));
+    // update code
+    helper.sendContentChange(new ChangeContentOverlay(
+        [new SourceEdit('library '.length, 'A;'.length, 'lib')]));
+    // wait, there is an error
+    await helper.onAnalysisComplete;
+    errors = helper.getTestErrors();
+    expect(errors, hasLength(1));
+  }
 
-  test('change on disk, normal', () {
-    AnalysisTestHelper helper = new AnalysisTestHelper();
-    helper.createSingleFileProject('library A;');
-    return helper.onAnalysisComplete.then((_) {
-      // There should be no errors
-      expect(helper.getTestErrors(), hasLength(0));
-      // Change file on disk, adding a syntax error.
-      helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
-      // There should be errors now.
-      return pumpEventQueue().then((_) {
-        return helper.onAnalysisComplete.then((_) {
-          expect(helper.getTestErrors(), hasLength(1));
-        });
-      });
-    });
-  });
+  test_updateContent_outOfRange_beyondEnd() {
+    return outOfRangeTest(new SourceEdit(6, 6, 'foo'));
+  }
 
-  test('change on disk, during override', () {
-    AnalysisTestHelper helper = new AnalysisTestHelper();
-    helper.createSingleFileProject('library A;');
-    return helper.onAnalysisComplete.then((_) {
-      // update code
-      helper.sendContentChange(new AddContentOverlay('library B;'));
-      // There should be no errors
-      return helper.onAnalysisComplete.then((_) {
-        expect(helper.getTestErrors(), hasLength(0));
-        // Change file on disk, adding a syntax error.
-        helper.resourceProvider.modifyFile(helper.testFile, 'library lib');
-        // There should still be no errors (file should not have been reread).
-        return helper.onAnalysisComplete.then((_) {
-          expect(helper.getTestErrors(), hasLength(0));
-          // Send a content change with a null content param--file should be
-          // reread from disk.
-          helper.sendContentChange(new RemoveContentOverlay());
-          // There should be errors now.
-          return helper.onAnalysisComplete.then((_) {
-            expect(helper.getTestErrors(), hasLength(1));
-          });
-        });
-      });
-    });
-  });
+  test_updateContent_outOfRange_negativeLength() {
+    return outOfRangeTest(new SourceEdit(3, -1, 'foo'));
+  }
 
-  group('out of range', () {
-    Future outOfRangeTest(SourceEdit edit) {
-      AnalysisTestHelper helper = new AnalysisTestHelper();
-      helper.createSingleFileProject('library A;');
-      return helper.onAnalysisComplete.then((_) {
-        helper.sendContentChange(new AddContentOverlay('library B;'));
-        return helper.onAnalysisComplete.then((_) {
-          ChangeContentOverlay contentChange = new ChangeContentOverlay([edit]);
-          Request request =
-              new AnalysisUpdateContentParams({helper.testFile: contentChange})
-                  .toRequest('0');
-          Response response = helper.handler.handleRequest(request);
-          expect(response,
-              isResponseFailure('0', RequestErrorCode.INVALID_OVERLAY_CHANGE));
-        });
-      });
-    }
+  test_updateContent_outOfRange_negativeOffset() {
+    return outOfRangeTest(new SourceEdit(-1, 3, 'foo'));
+  }
 
-    test('negative length', () {
-      return outOfRangeTest(new SourceEdit(3, -1, 'foo'));
+  test_updateOptions_invalid() {
+    var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS, {
+      ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: {'not-an-option': true}
     });
+    var response = handler.handleRequest(request);
+    // Invalid options should be silently ignored.
+    expect(response, isResponseSuccess('0'));
+  }
 
-    test('negative offset', () {
-      return outOfRangeTest(new SourceEdit(-1, 3, 'foo'));
-    });
+  test_updateOptions_null() {
+    // null is allowed as a synonym for {}.
+    var request = new Request('0', ANALYSIS_REQUEST_UPDATE_OPTIONS,
+        {ANALYSIS_REQUEST_UPDATE_OPTIONS_OPTIONS: null});
+    var response = handler.handleRequest(request);
+    expect(response, isResponseSuccess('0'));
+  }
 
-    test('beyond end', () {
-      return outOfRangeTest(new SourceEdit(6, 6, 'foo'));
-    });
-  });
+  Response testSetAnalysisRoots(List<String> included, List<String> excluded) {
+    Request request =
+        new AnalysisSetAnalysisRootsParams(included, excluded).toRequest('0');
+    return handler.handleRequest(request);
+  }
+
+  xtest_getReachableSources_invalidSource() async {
+    // TODO(brianwilkerson) Re-enable this test if we re-enable the
+    // analysis.getReachableSources request.
+    newFile('/project/a.dart', content: 'import "b.dart";');
+    server.setAnalysisRoots('0', ['/project/'], [], {});
+
+    await server.onAnalysisComplete;
+
+    var request = new AnalysisGetReachableSourcesParams('/does/not/exist.dart')
+        .toRequest('0');
+    var response = handler.handleRequest(request);
+    expect(response.error, isNotNull);
+    expect(response.error.code,
+        RequestErrorCode.GET_REACHABLE_SOURCES_INVALID_FILE);
+  }
+
+  xtest_getReachableSources_validSources() async {
+    // TODO(brianwilkerson) Re-enable this test if we re-enable the
+    // analysis.getReachableSources request.
+    String fileA = newFile('/project/a.dart', content: 'import "b.dart";').path;
+    newFile('/project/b.dart');
+
+    server.setAnalysisRoots('0', ['/project/'], [], {});
+
+    await server.onAnalysisComplete;
+
+    var request = new AnalysisGetReachableSourcesParams(fileA).toRequest('0');
+    var response = handler.handleRequest(request);
+
+    Map json = response.toJson()[Response.RESULT];
+
+    // Sanity checks.
+    expect(json['sources'], hasLength(6));
+    expect(json['sources']['file:///project/a.dart'],
+        unorderedEquals(['dart:core', 'file:///project/b.dart']));
+    expect(json['sources']['file:///project/b.dart'], ['dart:core']);
+  }
 }
 
 @reflectiveTest
@@ -381,13 +306,11 @@
 
   test_setRoots_packages() {
     // prepare package
-    String pkgFile = '/packages/pkgA/libA.dart';
-    resourceProvider.newFile(pkgFile, '''
+    String pkgFile = newFile('/packages/pkgA/libA.dart', content: '''
 library lib_a;
 class A {}
-''');
-    resourceProvider.newFile(
-        '/project/.packages', 'pkgA:file:///packages/pkgA');
+''').path;
+    newFile('/project/.packages', content: 'pkgA:file:///packages/pkgA');
     addTestFile('''
 import 'package:pkgA/libA.dart';
 main(A a) {
@@ -407,9 +330,8 @@
 /**
  * A helper to test 'analysis.*' requests.
  */
-class AnalysisTestHelper {
+class AnalysisTestHelper extends Object with ResourceProviderMixin {
   MockServerChannel serverChannel;
-  MemoryResourceProvider resourceProvider;
   AnalysisServer server;
   AnalysisDomainHandler handler;
 
@@ -425,7 +347,6 @@
   AnalysisTestHelper() {
     processRequiredPlugins();
     serverChannel = new MockServerChannel();
-    resourceProvider = new MemoryResourceProvider();
     // Create an SDK in the mock file system.
     new MockSdk(resourceProvider: resourceProvider);
     server = new AnalysisServer(
@@ -490,7 +411,7 @@
    * Creates an empty project `/project`.
    */
   void createEmptyProject() {
-    resourceProvider.newFolder('/project');
+    newFolder('/project');
     Request request =
         new AnalysisSetAnalysisRootsParams(['/project'], []).toRequest('0');
     handleSuccessfulRequest(request);
@@ -502,8 +423,8 @@
    */
   void createSingleFileProject(code) {
     this.testCode = _getCodeString(code);
-    resourceProvider.newFolder('/project');
-    resourceProvider.newFile(testFile, testCode);
+    newFolder('/project');
+    newFile(testFile, content: testCode);
     Request request =
         new AnalysisSetAnalysisRootsParams(['/project'], []).toRequest('0');
     handleSuccessfulRequest(request);
@@ -601,11 +522,6 @@
     handleSuccessfulRequest(request);
   }
 
-  String setFileContent(String path, String content) {
-    resourceProvider.newFile(path, content);
-    return path;
-  }
-
   /**
    * Stops the associated server.
    */
@@ -663,13 +579,11 @@
   }
 
   test_afterAnalysis_packageFile_external() async {
-    String pkgFile = '/packages/pkgA/lib/libA.dart';
-    resourceProvider.newFile(pkgFile, '''
+    String pkgFile = newFile('/packages/pkgA/lib/libA.dart', content: '''
 library lib_a;
 class A {}
-''');
-    resourceProvider.newFile(
-        '/project/.packages', 'pkgA:file:///packages/pkgA/lib');
+''').path;
+    newFile('/project/.packages', content: 'pkgA:file:///packages/pkgA/lib');
     //
     addTestFile('''
 import 'package:pkgA/libA.dart';
@@ -691,30 +605,23 @@
   test_afterAnalysis_packageFile_inRoot() async {
     String pkgA = '/pkgA';
     String pkgB = '/pkgA';
-    String pkgFileA = '$pkgA/lib/libA.dart';
-    String pkgFileB = '$pkgA/lib/libB.dart';
-    resourceProvider.newFile(pkgFileA, '''
+    String pkgFileA = newFile('$pkgA/lib/libA.dart', content: '''
 library lib_a;
 class A {}
-''');
-    resourceProvider.newFile(pkgFileB, '''
+''').path;
+    newFile('$pkgA/lib/libB.dart', content: '''
 import 'package:pkgA/libA.dart';
 main() {
   new A();
 }
 ''');
     packageMapProvider.packageMap = {
-      'pkgA': [
-        resourceProvider.newFolder('$pkgA/lib'),
-        resourceProvider.newFolder('$pkgB/lib')
-      ]
+      'pkgA': [newFolder('$pkgA/lib'), newFolder('$pkgB/lib')]
     };
     // add 'pkgA' and 'pkgB' as projects
-    {
-      resourceProvider.newFolder(projectPath);
-      handleSuccessfulRequest(
-          new AnalysisSetAnalysisRootsParams([pkgA, pkgB], []).toRequest('0'));
-    }
+    newFolder(projectPath);
+    handleSuccessfulRequest(
+        new AnalysisSetAnalysisRootsParams([pkgA, pkgB], []).toRequest('0'));
     // wait for analysis, no results initially
     await waitForTasksFinished();
     expect(filesHighlights[pkgFileA], isNull);
@@ -726,12 +633,11 @@
   }
 
   test_afterAnalysis_packageFile_notUsed() async {
-    String pkgFile = '/packages/pkgA/lib/libA.dart';
-    resourceProvider.newFile(pkgFile, '''
+    String pkgFile = newFile('/packages/pkgA/lib/libA.dart', content: '''
 library lib_a;
 class A {}
-''');
-    resourceProvider.newFile('/project/.packages', 'pkgA:/packages/pkgA/lib');
+''').path;
+    newFile('/project/.packages', content: 'pkgA:/packages/pkgA/lib');
     //
     addTestFile('// no "pkgA" reference');
     createProject();
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 5aad7e4..90b92b4 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -239,7 +239,7 @@
     //
     // We no longer support the analysis of non-dart files.
     //
-    testFile = '/project/web/test.html';
+    testFile = resourceProvider.convertPath('/project/web/test.html');
     addTestFile('''
       <html>^</html>
     ''');
@@ -251,7 +251,7 @@
   }
 
   test_import_uri_with_trailing() {
-    addFile('/project/bin/testA.dart', 'library libA;');
+    newFile('/project/bin/testA.dart', content: 'library libA;');
     addTestFile('''
       import '/project/bin/t^.dart';
       main() {}''');
@@ -499,7 +499,7 @@
   }
 
   test_inDartDoc_reference1() async {
-    addFile('/testA.dart', '''
+    newFile('/testA.dart', content: '''
   part of libA;
   foo(bar) => 0;''');
     addTestFile('''
@@ -528,7 +528,7 @@
   }
 
   test_inherited() {
-    addFile('/libA.dart', 'class A {m() {}}');
+    newFile('/libA.dart', content: 'class A {m() {}}');
     addTestFile('''
 import '/libA.dart';
 class B extends A {
@@ -606,7 +606,7 @@
   }
 
   test_local_override() {
-    addFile('/libA.dart', 'class A {m() {}}');
+    newFile('/libA.dart', content: 'class A {m() {}}');
     addTestFile('''
 import '/libA.dart';
 class B extends A {
@@ -649,7 +649,7 @@
   }
 
   test_overrides() {
-    addFile('/libA.dart', 'class A {m() {}}');
+    newFile('/libA.dart', content: 'class A {m() {}}');
     addTestFile('''
 import '/libA.dart';
 class B extends A {m() {^}}
@@ -663,7 +663,7 @@
   }
 
   test_partFile() {
-    addFile('/project/bin/testA.dart', '''
+    newFile('/project/bin/testA.dart', content: '''
       library libA;
       part "$testFile";
       import 'dart:html';
@@ -683,7 +683,7 @@
   }
 
   test_partFile2() {
-    addFile('/testA.dart', '''
+    newFile('/testA.dart', content: '''
       part of libA;
       class A { }''');
     addTestFile('''
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index 913294f..c3ff619 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -26,9 +26,8 @@
   }
 
   test_getDiagnostics() async {
-    String file = '/project/bin/test.dart';
-    resourceProvider.newFile('/project/pubspec.yaml', 'name: project');
-    resourceProvider.newFile(file, 'main() {}');
+    newFile('/project/pubspec.yaml', content: 'name: project');
+    newFile('/project/bin/test.dart', content: 'main() {}');
 
     server.setAnalysisRoots('0', ['/project/'], [], {});
 
diff --git a/pkg/analysis_server/test/domain_execution_test.dart b/pkg/analysis_server/test/domain_execution_test.dart
index b46daaa..8ccdb16 100644
--- a/pkg/analysis_server/test/domain_execution_test.dart
+++ b/pkg/analysis_server/test/domain_execution_test.dart
@@ -178,8 +178,7 @@
   }
 
   void test_mapUri_file() {
-    String path = '/a/b.dart';
-    resourceProvider.newFile(path, '');
+    String path = newFile('/a/b.dart').path;
     // map the file
     ExecutionMapUriResult result = _mapUri(file: path);
     expect(result.file, isNull);
@@ -189,7 +188,7 @@
   void test_mapUri_file_dartUriKind() {
     String path = server.findSdk().mapDartUri('dart:async').fullName;
     // hack - pretend that the SDK file exists in the project FS
-    resourceProvider.newFile(path, '// hack');
+    newFile(path, content: '// hack');
     // map file
     ExecutionMapUriResult result = _mapUri(file: path);
     expect(result.file, isNull);
@@ -198,7 +197,7 @@
 
   void test_mapUri_uri() {
     String path = '/a/b.dart';
-    resourceProvider.newFile(path, '');
+    newFile(path);
     // map the uri
     ExecutionMapUriResult result = _mapUri(uri: 'file://$path');
     expect(result.file, '/a/b.dart');
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 90732cd..684506f 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -111,20 +111,21 @@
 
   test_suggestImportFromDifferentAnalysisRoot() async {
     // Set up two projects.
-    resourceProvider..newFolder("/project1")..newFolder("/project2");
+    newFolder("/project1");
+    newFolder("/project2");
     handleSuccessfulRequest(
         new AnalysisSetAnalysisRootsParams(["/project1", "/project2"], [])
             .toRequest('0'),
         handler: analysisHandler);
 
     // Set up files.
-    testFile = "/project1/main.dart";
-    testCode = "main() { print(new Foo()); }";
+    testFile = resourceProvider.convertPath('/project1/main.dart');
+    testCode = 'main() { print(new Foo()); }';
     _addOverlay(testFile, testCode);
     // Add another file in the same project that imports the target file.
     // This ensures it will be analyzed as an implicit Source.
-    _addOverlay("/project1/another.dart", 'import "../project2/target.dart";');
-    _addOverlay("/project2/target.dart", "class Foo() {}");
+    _addOverlay('/project1/another.dart', 'import "../project2/target.dart";');
+    _addOverlay('/project2/target.dart', 'class Foo() {}');
 
     await waitForTasksFinished();
 
diff --git a/pkg/analysis_server/test/edit/organize_directives_test.dart b/pkg/analysis_server/test/edit/organize_directives_test.dart
index cf320de..351891f 100644
--- a/pkg/analysis_server/test/edit/organize_directives_test.dart
+++ b/pkg/analysis_server/test/edit/organize_directives_test.dart
@@ -84,8 +84,8 @@
   }
 
   Future test_OK_remove_unresolvedDirectives() {
-    addFile('$testFolder/existing_part1.dart', 'part of lib;');
-    addFile('$testFolder/existing_part2.dart', 'part of lib;');
+    newFile('$testFolder/existing_part1.dart', content: 'part of lib;');
+    newFile('$testFolder/existing_part2.dart', content: 'part of lib;');
     addTestFile('''
 library lib;
 
diff --git a/pkg/analysis_server/test/edit/refactoring_test.dart b/pkg/analysis_server/test/edit/refactoring_test.dart
index fd225c6..9fe5e02 100644
--- a/pkg/analysis_server/test/edit/refactoring_test.dart
+++ b/pkg/analysis_server/test/edit/refactoring_test.dart
@@ -271,8 +271,7 @@
 
   test_analysis_onlyOneFile() async {
     shouldWaitForFullAnalysis = false;
-    String otherFile = '$testFolder/other.dart';
-    addFile(otherFile, r'''
+    newFile('$testFolder/other.dart', content: r'''
 foo(int myName) {}
 ''');
     addTestFile('''
@@ -445,7 +444,7 @@
 
   test_resetOnAnalysisSetChanged_watch_otherFile() async {
     String otherFile = '$testFolder/other.dart';
-    addFile(otherFile, '// other 1');
+    newFile(otherFile, content: '// other 1');
     addTestFile('''
 main() {
   foo(1 + 2);
@@ -465,7 +464,7 @@
     // The refactoring is reset, even though it's a different file. It is up to
     // analyzer to track dependencies and provide resolved units fast when
     // possible.
-    addFile(otherFile, '// other 2');
+    newFile(otherFile, content: '// other 2');
     await pumpEventQueue();
     expect(test_resetCount, initialResetCount + 1);
   }
@@ -980,7 +979,7 @@
   test_analysis_onlyOneFile() async {
     shouldWaitForFullAnalysis = false;
     String otherFile = '$testFolder/other.dart';
-    addFile(otherFile, r'''
+    newFile(otherFile, content: r'''
 foo(int p) {}
 ''');
     addTestFile('''
@@ -1048,8 +1047,7 @@
   }
 
   test_resetOnAnalysisSetChanged() async {
-    String otherFile = '$testFolder/other.dart';
-    addFile(otherFile, '// other 1');
+    newFile('$testFolder/other.dart', content: '// other 1');
     addTestFile('''
 main() {
   int res = 1 + 2;
@@ -1217,7 +1215,7 @@
   @failingTest
   test_OK() {
     fail('The move file refactoring is not supported under the new driver');
-    resourceProvider.newFile('/project/bin/lib.dart', '');
+    newFile('/project/bin/lib.dart');
     addTestFile('''
 import 'dart:math';
 import 'lib.dart';
@@ -1754,7 +1752,7 @@
   }
 
   test_library_partOfDirective() {
-    addFile('$testFolder/my_lib.dart', '''
+    newFile('$testFolder/my_lib.dart', content: '''
 library aaa.bbb.ccc;
 part 'test.dart';
 ''');
diff --git a/pkg/analysis_server/test/edit/sort_members_test.dart b/pkg/analysis_server/test/edit/sort_members_test.dart
index abce2a0..d6b70c1 100644
--- a/pkg/analysis_server/test/edit/sort_members_test.dart
+++ b/pkg/analysis_server/test/edit/sort_members_test.dart
@@ -178,7 +178,7 @@
   }
 
   test_OK_genericFunctionType() async {
-    addFile(projectPath + '/analysis_options.yaml', '''
+    newFile('$projectPath/analysis_options.yaml', content: '''
 analyzer:
   strong-mode: true
 ''');
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index c2d1547..19e5b52 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -164,17 +164,16 @@
 
   test_class_extends_fileAndPackageUris() async {
     // prepare packages
-    String pkgFile = '/packages/pkgA/lib/libA.dart';
-    resourceProvider.newFile(pkgFile, '''
+    newFile('/packages/pkgA/lib/libA.dart', content: '''
 library lib_a;
 class A {}
 class B extends A {}
 ''');
-    resourceProvider.newFile(
-        '/packages/pkgA/.packages', 'pkgA:file:///packages/pkgA/lib');
+    newFile('/packages/pkgA/.packages',
+        content: 'pkgA:file:///packages/pkgA/lib');
     // reference the package from a project
-    resourceProvider.newFile(
-        '$projectPath/.packages', 'pkgA:file:///packages/pkgA/lib');
+    newFile('$projectPath/.packages',
+        content: 'pkgA:file:///packages/pkgA/lib');
     addTestFile('''
 import 'package:pkgA/libA.dart';
 class C extends A {}
@@ -696,7 +695,7 @@
   }
 
   test_member_method_private_differentLib() async {
-    addFile('$testFolder/lib.dart', r'''
+    newFile('$testFolder/lib.dart', content: r'''
 import 'test.dart';
 class A {
   void _m() {}
diff --git a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
index b578713..7f455ec 100644
--- a/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/common_usage_sorter_test.dart
@@ -84,8 +84,8 @@
 
   test_PrefixedIdentifier_field_inPart() async {
     // SimpleIdentifier  PrefixedIdentifier  ExpressionStatement
-    addFile('/project/bin/myLib.dart',
-        'library L; part "$testFile"; class A {static int s2;}');
+    newFile('/project/bin/myLib.dart',
+        content: 'library L; part "$testFile"; class A {static int s2;}');
     addTestFile('part of L; foo() {A.^}');
     await getSuggestionsWith({
       'L.A': ['s2']
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 469bc3a..2e3f899 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/generated/parser.dart' as analyzer;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
@@ -45,6 +46,8 @@
    */
   bool get isNullExpectedReturnTypeConsideredDynamic => true;
 
+  bool get usingFastaParser => analyzer.Parser.useFasta;
+
   void addTestSource(String content) {
     expect(completionOffset, isNull, reason: 'Call addTestUnit exactly once');
     completionOffset = content.indexOf('^');
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index d8a0b4b..da2dc8a 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -4,7 +4,6 @@
 
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
-import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:test/test.dart';
@@ -321,7 +320,7 @@
     // and reports a single function expression argument
     // while analyzer adds the closing paren before the `a`
     // and adds synthetic `;`s making `a` a statement.
-    if (request.target.entity is BlockFunctionBody) {
+    if (usingFastaParser) {
       assertSuggestKeywords([],
           pseudoKeywords: ['async', 'async*', 'sync*'],
           relevance: DART_RELEVANCE_HIGH);
@@ -363,9 +362,8 @@
     addTestSource('main() {foo("bar", () as^ => null');
     await computeSuggestions();
     assertSuggestKeywords([],
-        pseudoKeywords: request.target.entity is ExpressionFunctionBody
-            ? ['async']
-            : ['async', 'async*', 'sync*'],
+        pseudoKeywords:
+            usingFastaParser ? ['async'] : ['async', 'async*', 'sync*'],
         relevance: DART_RELEVANCE_HIGH);
   }
 
@@ -382,7 +380,7 @@
     await computeSuggestions();
     // Fasta interprets the argument as a function expression
     // while analyzer adds synthetic `;`s making `a` a statement.
-    if (request.target.entity is BlockFunctionBody) {
+    if (usingFastaParser) {
       assertSuggestKeywords([],
           pseudoKeywords: ['async', 'async*', 'sync*'],
           relevance: DART_RELEVANCE_HIGH);
@@ -740,7 +738,7 @@
     addTestSource('class A e^ implements foo');
     await computeSuggestions();
     assertSuggestKeywords(
-        request.target.containingNode is ClassDeclaration
+        usingFastaParser
             ? [Keyword.EXTENDS]
             : [Keyword.EXTENDS, Keyword.IMPLEMENTS],
         relevance: DART_RELEVANCE_HIGH);
@@ -750,7 +748,7 @@
     addTestSource('class A e^ implements foo { }');
     await computeSuggestions();
     assertSuggestKeywords(
-        request.target.containingNode is ClassDeclaration
+        usingFastaParser
             ? [Keyword.EXTENDS]
             : [Keyword.EXTENDS, Keyword.IMPLEMENTS],
         relevance: DART_RELEVANCE_HIGH);
@@ -919,7 +917,7 @@
   test_function_async() async {
     addTestSource('main()^');
     await computeSuggestions();
-    assertSuggestKeywords(DECLARATION_KEYWORDS,
+    assertSuggestKeywords(usingFastaParser ? [] : DECLARATION_KEYWORDS,
         pseudoKeywords: ['async', 'async*', 'sync*'],
         relevance: DART_RELEVANCE_HIGH);
   }
@@ -943,7 +941,7 @@
   test_function_async4() async {
     addTestSource('main()a^{}');
     await computeSuggestions();
-    assertSuggestKeywords(DECLARATION_KEYWORDS,
+    assertSuggestKeywords(usingFastaParser ? [] : DECLARATION_KEYWORDS,
         pseudoKeywords: ['async', 'async*', 'sync*'],
         relevance: DART_RELEVANCE_HIGH);
   }
@@ -1475,8 +1473,14 @@
   test_method_async4() async {
     addTestSource('class A { foo() a^{}}');
     await computeSuggestions();
-    assertSuggestKeywords(CLASS_BODY_KEYWORDS,
-        pseudoKeywords: ['async', 'async*', 'sync*']);
+    if (usingFastaParser) {
+      assertSuggestKeywords([],
+          pseudoKeywords: ['async', 'async*', 'sync*'],
+          relevance: DART_RELEVANCE_HIGH);
+    } else {
+      assertSuggestKeywords(CLASS_BODY_KEYWORDS,
+          pseudoKeywords: ['async', 'async*', 'sync*']);
+    }
   }
 
   test_method_async5() async {
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index 678806c..1e93e6a 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -8,13 +8,13 @@
 import 'package:analysis_server/src/services/search/search_engine_internal.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
 import 'package:analyzer/src/dart/analysis/file_state.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:front_end/src/api_prototype/byte_store.dart';
 import 'package:front_end/src/base/performance_logger.dart';
 import 'package:test/test.dart';
@@ -29,8 +29,7 @@
 }
 
 @reflectiveTest
-class SearchEngineImplTest {
-  final MemoryResourceProvider provider = new MemoryResourceProvider();
+class SearchEngineImplTest extends Object with ResourceProviderMixin {
   DartSdk sdk;
   final ByteStore byteStore = new MemoryByteStore();
   final FileContentOverlay contentOverlay = new FileContentOverlay();
@@ -41,36 +40,32 @@
   AnalysisDriverScheduler scheduler;
 
   void setUp() {
-    sdk = new MockSdk(resourceProvider: provider);
+    sdk = new MockSdk(resourceProvider: resourceProvider);
     logger = new PerformanceLog(logBuffer);
     scheduler = new AnalysisDriverScheduler(logger);
     scheduler.start();
   }
 
   test_membersOfSubtypes_hasMembers() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-    var c = _p('/test/c.dart');
-
-    provider.newFile(a, '''
+    var a = newFile('/test/a.dart', content: '''
 class A {
   void a() {}
   void b() {}
   void c() {}
 }
-''');
-    provider.newFile(b, '''
+''').path;
+    var b = newFile('/test/b.dart', content: '''
 import 'a.dart';
 class B extends A {
   void a() {}
 }
-''');
-    provider.newFile(c, '''
+''').path;
+    var c = newFile('/test/c.dart', content: '''
 import 'a.dart';
 class C extends A {
   void b() {}
 }
-''');
+''').path;
 
     var driver1 = _newDriver();
     var driver2 = _newDriver();
@@ -89,20 +84,17 @@
   }
 
   test_membersOfSubtypes_noMembers() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-
-    provider.newFile(a, '''
+    var a = newFile('/test/a.dart', content: '''
 class A {
   void a() {}
   void b() {}
   void c() {}
 }
-''');
-    provider.newFile(b, '''
+''').path;
+    var b = newFile('/test/b.dart', content: '''
 import 'a.dart';
 class B extends A {}
-''');
+''').path;
 
     var driver = _newDriver();
 
@@ -119,22 +111,19 @@
   }
 
   test_membersOfSubtypes_noSubtypes() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-
-    provider.newFile(a, '''
+    var a = newFile('/test/a.dart', content: '''
 class A {
   void a() {}
   void b() {}
   void c() {}
 }
-''');
-    provider.newFile(b, '''
+''').path;
+    var b = newFile('/test/b.dart', content: '''
 import 'a.dart';
 class B {
   void a() {}
 }
-''');
+''').path;
 
     var driver = _newDriver();
 
@@ -151,10 +140,7 @@
   }
 
   test_membersOfSubtypes_private() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-
-    provider.newFile(a, '''
+    var a = newFile('/test/a.dart', content: '''
 class A {
   void a() {}
   void _b() {}
@@ -163,8 +149,8 @@
 class B extends A {
   void _b() {}
 }
-''');
-    provider.newFile(b, '''
+''').path;
+    var b = newFile('/test/b.dart', content: '''
 import 'a.dart';
 class C extends A {
   void a() {}
@@ -173,7 +159,7 @@
 class D extends B {
   void _c() {}
 }
-''');
+''').path;
 
     var driver1 = _newDriver();
     var driver2 = _newDriver();
@@ -191,14 +177,12 @@
   }
 
   test_searchAllSubtypes() async {
-    var p = _p('/test.dart');
-
-    provider.newFile(p, '''
+    var p = newFile('/test.dart', content: '''
 class T {}
 class A extends T {}
 class B extends A {}
 class C implements B {}
-''');
+''').path;
 
     var driver = _newDriver();
     driver.addFile(p);
@@ -215,18 +199,15 @@
   }
 
   test_searchAllSubtypes_acrossDrivers() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-
-    provider.newFile(a, '''
+    var a = newFile('/test/a.dart', content: '''
 class T {}
 class A extends T {}
-''');
-    provider.newFile(b, '''
+''').path;
+    var b = newFile('/test/b.dart', content: '''
 import 'a.dart';
 class B extends A {}
 class C extends B {}
-''');
+''').path;
 
     var driver1 = _newDriver();
     var driver2 = _newDriver();
@@ -246,9 +227,6 @@
   }
 
   test_searchMemberDeclarations() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-
     var codeA = '''
 class A {
   int test; // 1
@@ -263,8 +241,8 @@
 int test;
 ''';
 
-    provider.newFile(a, codeA);
-    provider.newFile(b, codeB);
+    var a = newFile('/test/a.dart', content: codeA).path;
+    var b = newFile('/test/b.dart', content: codeB).path;
 
     var driver1 = _newDriver();
     var driver2 = _newDriver();
@@ -295,23 +273,20 @@
   }
 
   test_searchMemberReferences() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-
-    provider.newFile(a, '''
+    var a = newFile('/test/a.dart', content: '''
 class A {
   int test;
 }
 foo(p) {
   p.test;
 }
-''');
-    provider.newFile(b, '''
+''').path;
+    var b = newFile('/test/b.dart', content: '''
 import 'a.dart';
 bar(p) {
   p.test = 1;
 }
-''');
+''').path;
 
     var driver1 = _newDriver();
     var driver2 = _newDriver();
@@ -334,17 +309,14 @@
   }
 
   test_searchReferences() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-
-    provider.newFile(a, '''
+    var a = newFile('/test/a.dart', content: '''
 class T {}
 T a;
-''');
-    provider.newFile(b, '''
+''').path;
+    var b = newFile('/test/b.dart', content: '''
 import 'a.dart';
 T b;
-''');
+''').path;
 
     var driver1 = _newDriver();
     var driver2 = _newDriver();
@@ -365,17 +337,14 @@
   }
 
   test_searchTopLevelDeclarations() async {
-    var a = _p('/test/a.dart');
-    var b = _p('/test/b.dart');
-
-    provider.newFile(a, '''
+    var a = newFile('/test/a.dart', content: '''
 class A {}
 int a;
-''');
-    provider.newFile(b, '''
+''').path;
+    var b = newFile('/test/b.dart', content: '''
 class B {}
 get b => 42;
-''');
+''').path;
 
     var driver1 = _newDriver();
     var driver2 = _newDriver();
@@ -406,25 +375,23 @@
   }
 
   test_searchTopLevelDeclarations_dependentPackage() async {
-    var a = _p('/a/lib/a.dart');
-    provider.newFile(a, '''
+    var a = newFile('/a/lib/a.dart', content: '''
 class A {}
 ''');
     var driver1 = _newDriver();
-    driver1.addFile(a);
+    driver1.addFile(a.path);
 
     // The package:b uses the class A from the package:a,
     // so it sees the declaration the element A.
-    var b = _p('/b/lib/b.dart');
-    provider.newFile(b, '''
+    var b = newFile('/b/lib/b.dart', content: '''
 import 'package:a/a.dart';
 class B extends A {}
 ''');
     var driver2 = _newDriver(
-        packageUriResolver: new PackageMapUriResolver(provider, {
-      'a': [provider.getFile(a).parent]
+        packageUriResolver: new PackageMapUriResolver(resourceProvider, {
+      'a': [a.parent]
     }));
-    driver2.addFile(b);
+    driver2.addFile(b.path);
 
     while (scheduler.isAnalyzing) {
       await new Future.delayed(new Duration(milliseconds: 1));
@@ -451,23 +418,21 @@
   AnalysisDriver _newDriver({UriResolver packageUriResolver}) {
     var resolvers = <UriResolver>[
       new DartUriResolver(sdk),
-      new ResourceUriResolver(provider)
+      new ResourceUriResolver(resourceProvider)
     ];
     if (packageUriResolver != null) {
       resolvers.add(packageUriResolver);
     }
-    resolvers.add(new ResourceUriResolver(provider));
+    resolvers.add(new ResourceUriResolver(resourceProvider));
 
     return new AnalysisDriver(
         scheduler,
         logger,
-        provider,
+        resourceProvider,
         byteStore,
         contentOverlay,
         null,
-        new SourceFactory(resolvers, null, provider),
+        new SourceFactory(resolvers, null, resourceProvider),
         new AnalysisOptionsImpl()..strongMode = true);
   }
-
-  String _p(String path) => provider.convertPath(path);
 }
diff --git a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
index 38e71a9..db3d3f9 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_locator_test.dart
@@ -3,7 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/plugin/plugin_locator.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -14,17 +14,14 @@
 }
 
 @reflectiveTest
-class PluginLocatorTest {
-  MemoryResourceProvider resourceProvider;
+class PluginLocatorTest extends Object with ResourceProviderMixin {
   String packageRoot;
   String pubspecPath;
   String defaultDirPath;
   PluginLocator locator;
 
   void setUp() {
-    resourceProvider = new MemoryResourceProvider();
-    packageRoot = resourceProvider.convertPath('/package');
-    resourceProvider.newFolder(packageRoot);
+    packageRoot = newFolder('/package').path;
     locator = new PluginLocator(resourceProvider);
   }
 
@@ -66,25 +63,23 @@
   }
 
   void _createDefaultDir() {
-    defaultDirPath = resourceProvider.pathContext.join(packageRoot,
-        PluginLocator.toolsFolderName, PluginLocator.defaultPluginFolderName);
-    resourceProvider.newFolder(defaultDirPath);
+    defaultDirPath = newFolder(
+            '/package/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}')
+        .path;
   }
 
   void _createPubspec(String content) {
-    pubspecPath = resourceProvider.pathContext
-        .join(packageRoot, PluginLocator.pubspecFileName);
-    resourceProvider.newFile(pubspecPath, content);
+    pubspecPath =
+        newFile('/package/${PluginLocator.pubspecFileName}', content: content)
+            .path;
   }
 
   String _createPubspecWithKey() {
-    String nonDefaultPath =
-        resourceProvider.pathContext.join(packageRoot, 'pluginDir');
+    String nonDefaultPath = newFolder('/package/pluginDir').path;
     _createPubspec('''
 name: test_project
 ${PluginLocator.analyzerPluginKey}: $nonDefaultPath
 ''');
-    resourceProvider.newFolder(nonDefaultPath);
     return nonDefaultPath;
   }
 
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 c9665cd..5d3e5b9a 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_manager_test.dart
@@ -9,9 +9,9 @@
 import 'package:analysis_server/src/plugin/plugin_manager.dart';
 import 'package:analyzer/context/context_root.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:analyzer_plugin/channel/channel.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
@@ -105,7 +105,6 @@
 
 @reflectiveTest
 class DiscoveredPluginInfoTest {
-  MemoryResourceProvider resourceProvider;
   TestNotificationManager notificationManager;
   String pluginPath = '/pluginDir';
   String executionPath = '/pluginDir/bin/plugin.dart';
@@ -113,7 +112,6 @@
   DiscoveredPluginInfo plugin;
 
   void setUp() {
-    resourceProvider = new MemoryResourceProvider();
     notificationManager = new TestNotificationManager();
     plugin = new DiscoveredPluginInfo(pluginPath, executionPath, packagesPath,
         notificationManager, InstrumentationService.NULL_SERVICE);
@@ -401,15 +399,13 @@
 }
 
 @reflectiveTest
-class PluginManagerTest {
-  MemoryResourceProvider resourceProvider;
+class PluginManagerTest extends Object with ResourceProviderMixin {
   String byteStorePath;
   String sdkPath;
   TestNotificationManager notificationManager;
   PluginManager manager;
 
   void setUp() {
-    resourceProvider = new MemoryResourceProvider();
     byteStorePath = resourceProvider.convertPath('/byteStore');
     sdkPath = resourceProvider.convertPath('/sdk');
     notificationManager = new TestNotificationManager();
@@ -433,16 +429,13 @@
   }
 
   void test_pathsFor_withPackagesFile() {
-    path.Context context = resourceProvider.pathContext;
     //
     // Build the minimal directory structure for a plugin package that includes
     // a .packages file.
     //
-    String pluginDirPath = resourceProvider.convertPath('/plugin');
-    String pluginFilePath = context.join(pluginDirPath, 'bin', 'plugin.dart');
-    resourceProvider.newFile(pluginFilePath, '');
-    String packagesFilePath = context.join(pluginDirPath, '.packages');
-    resourceProvider.newFile(packagesFilePath, '');
+    String pluginDirPath = newFolder('/plugin').path;
+    String pluginFilePath = newFile('/plugin/bin/plugin.dart').path;
+    String packagesFilePath = newFile('/plugin/.packages').path;
     //
     // Test path computation.
     //
@@ -453,20 +446,17 @@
   }
 
   void test_pathsFor_withPubspec_inBazelWorkspace() {
-    path.Context context = resourceProvider.pathContext;
     //
     // Build a Bazel workspace containing four packages, including the plugin.
     //
-    String rootPath = resourceProvider.convertPath('/workspaceRoot');
-    resourceProvider.newFile(context.join(rootPath, 'WORKSPACE'), '');
-    resourceProvider.newFolder(context.join(rootPath, 'bazel-bin'));
-    resourceProvider.newFolder(context.join(rootPath, 'bazel-genfiles'));
+    newFile('/workspaceRoot/WORKSPACE');
+    newFolder('/workspaceRoot/bazel-bin');
+    newFolder('/workspaceRoot/bazel-genfiles');
 
     String newPackage(String packageName, [List<String> dependencies]) {
       String packageRoot =
-          context.join(rootPath, 'third_party', 'dart', packageName);
-      resourceProvider.newFile(
-          context.join(packageRoot, 'lib', packageName + '.dart'), '');
+          newFolder('/workspaceRoot/third_party/dart/$packageName').path;
+      newFile('$packageRoot/lib/$packageName.dart');
       StringBuffer buffer = new StringBuffer();
       if (dependencies != null) {
         buffer.writeln('dependencies:');
@@ -474,8 +464,7 @@
           buffer.writeln('  $dependency: any');
         }
       }
-      resourceProvider.newFile(
-          context.join(packageRoot, 'pubspec.yaml'), buffer.toString());
+      newFile('$packageRoot/pubspec.yaml', content: buffer.toString());
       return packageRoot;
     }
 
@@ -483,15 +472,14 @@
     newPackage('b', ['d']);
     newPackage('c', ['d']);
     newPackage('d');
-    String pluginFilePath = context.join(pluginDirPath, 'bin', 'plugin.dart');
-    resourceProvider.newFile(pluginFilePath, '');
+    String pluginFilePath = newFile('$pluginDirPath/bin/plugin.dart').path;
     //
     // Test path computation.
     //
     List<String> paths = manager.pathsFor(pluginDirPath);
     expect(paths, hasLength(2));
     expect(paths[0], pluginFilePath);
-    File packagesFile = resourceProvider.getFile(paths[1]);
+    File packagesFile = getFile(paths[1]);
     expect(packagesFile.exists, isTrue);
     String content = packagesFile.readAsStringSync();
     List<String> lines = content.split('\n');
@@ -539,8 +527,7 @@
 }
 
 @reflectiveTest
-class PluginSessionTest {
-  MemoryResourceProvider resourceProvider;
+class PluginSessionTest extends Object with ResourceProviderMixin {
   TestNotificationManager notificationManager;
   String pluginPath;
   String executionPath;
@@ -550,7 +537,6 @@
   PluginSession session;
 
   void setUp() {
-    resourceProvider = new MemoryResourceProvider();
     notificationManager = new TestNotificationManager();
     pluginPath = resourceProvider.convertPath('/pluginDir');
     executionPath = resourceProvider.convertPath('/pluginDir/bin/plugin.dart');
diff --git a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
index 27f99f5..2707c57 100644
--- a/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
+++ b/pkg/analysis_server/test/src/plugin/plugin_watcher_test.dart
@@ -17,6 +17,7 @@
 import 'package:analyzer/src/dart/analysis/session.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisOptionsImpl;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:front_end/src/api_prototype/byte_store.dart';
 import 'package:front_end/src/base/performance_logger.dart';
 import 'package:path/path.dart' as path;
@@ -32,29 +33,22 @@
 }
 
 @reflectiveTest
-class PluginWatcherTest {
-  MemoryResourceProvider resourceProvider;
+class PluginWatcherTest extends Object with ResourceProviderMixin {
   TestPluginManager manager;
   PluginWatcher watcher;
 
   void setUp() {
-    resourceProvider = new MemoryResourceProvider();
     manager = new TestPluginManager();
     watcher = new PluginWatcher(resourceProvider, manager);
   }
 
   test_addedDriver() async {
-    String pkg1Path = resourceProvider.convertPath('/pkg1');
-    resourceProvider.newFile(
-        resourceProvider.convertPath('/pkg1/lib/test1.dart'), '');
-    resourceProvider.newFile(
-        resourceProvider.convertPath('/pkg2/lib/pkg2.dart'), '');
-    resourceProvider.newFile(
-        resourceProvider.convertPath('/pkg2/pubspec.yaml'), 'name: pkg2');
-    resourceProvider.newFile(
-        resourceProvider.convertPath(
-            '/pkg2/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}/bin/plugin.dart'),
-        '');
+    String pkg1Path = newFolder('/pkg1').path;
+    newFile('/pkg1/lib/test1.dart');
+    newFile('/pkg2/lib/pkg2.dart');
+    newFile('/pkg2/pubspec.yaml', content: 'name: pkg2');
+    newFile(
+        '/pkg2/${PluginLocator.toolsFolderName}/${PluginLocator.defaultPluginFolderName}/bin/plugin.dart');
 
     ContextRoot contextRoot = new ContextRoot(pkg1Path, []);
     TestDriver driver = new TestDriver(resourceProvider, contextRoot);
@@ -82,9 +76,8 @@
   }
 
   test_addedDriver_missingPackage() async {
-    String pkg1Path = resourceProvider.convertPath('/pkg1');
-    resourceProvider.newFile(
-        resourceProvider.convertPath('/pkg1/lib/test1.dart'), '');
+    String pkg1Path = newFolder('/pkg1').path;
+    newFile('/pkg1/lib/test1.dart');
 
     ContextRoot contextRoot = new ContextRoot(pkg1Path, []);
     TestDriver driver = new TestDriver(resourceProvider, contextRoot);
@@ -106,7 +99,7 @@
   }
 
   test_removedDriver() {
-    String pkg1Path = resourceProvider.convertPath('/pkg1');
+    String pkg1Path = newFolder('/pkg1').path;
     ContextRoot contextRoot = new ContextRoot(pkg1Path, []);
     TestDriver driver = new TestDriver(resourceProvider, contextRoot);
     watcher.addedDriver(driver, contextRoot);
diff --git a/pkg/analysis_server/test/src/watch_manager_test.dart b/pkg/analysis_server/test/src/watch_manager_test.dart
index 19b72c9..2fe0471 100644
--- a/pkg/analysis_server/test/src/watch_manager_test.dart
+++ b/pkg/analysis_server/test/src/watch_manager_test.dart
@@ -6,7 +6,7 @@
 
 import 'package:analysis_server/src/watch_manager.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 import 'package:watcher/watcher.dart';
@@ -72,67 +72,66 @@
 }
 
 @reflectiveTest
-class WatchManagerTest {
-  MemoryResourceProvider provider;
+class WatchManagerTest extends Object with ResourceProviderMixin {
   WatchListener listener;
   WatchManager<Token> manager;
 
   void setUp() {
-    provider = new MemoryResourceProvider();
     listener = new WatchListener();
-    manager = new WatchManager<Token>(provider, listener.handleWatchEvent);
+    manager =
+        new WatchManager<Token>(resourceProvider, listener.handleWatchEvent);
   }
 
   Future test_addFolder_folderAndSubfolder() async {
-    Folder topFolder = provider.getFolder('/a/b');
-    Folder childFolder = provider.getFolder('/a/b/c/d');
+    Folder topFolder = getFolder('/a/b');
+    Folder childFolder = getFolder('/a/b/c/d');
     Token topToken = new Token('topToken');
     Token childToken = new Token('childToken');
     manager.addFolder(topFolder, topToken);
     manager.addFolder(childFolder, childToken);
 
-    File newFile1 = provider.newFile('/a/b/c/lib.dart', '');
+    File newFile1 = newFile('/a/b/c/lib.dart');
     await _expectEvent(ChangeType.ADD, newFile1.path, [topToken]);
 
-    File newFile2 = provider.newFile('/a/b/c/d/lib.dart', '');
+    File newFile2 = newFile('/a/b/c/d/lib.dart');
     return _expectEvent(ChangeType.ADD, newFile2.path, [topToken, childToken]);
   }
 
   Future test_addFolder_singleFolder_multipleTokens() {
-    Folder folder = provider.getFolder('/a/b');
+    Folder folder = getFolder('/a/b');
     Token token1 = new Token('token1');
     Token token2 = new Token('token2');
     manager.addFolder(folder, token1);
     manager.addFolder(folder, token2);
 
-    File newFile = provider.newFile('/a/b/lib.dart', '');
-    return _expectEvent(ChangeType.ADD, newFile.path, [token1, token2]);
+    File addedFile = newFile('/a/b/lib.dart');
+    return _expectEvent(ChangeType.ADD, addedFile.path, [token1, token2]);
   }
 
   Future test_addFolder_singleFolder_singleToken() async {
-    Folder folder = provider.getFolder('/a/b');
+    Folder folder = getFolder('/a/b');
     Token token = new Token('token');
     manager.addFolder(folder, token);
 
-    Folder newFolder = provider.newFolder('/a/b/c');
-    await _expectEvent(ChangeType.ADD, newFolder.path, [token]);
+    Folder addedFolder = newFolder('/a/b/c');
+    await _expectEvent(ChangeType.ADD, addedFolder.path, [token]);
 
-    File newFile = provider.newFile('/a/b/c/lib.dart', '');
-    return _expectEvent(ChangeType.ADD, newFile.path, [token]);
+    File addedFile = newFile('/a/b/c/lib.dart');
+    return _expectEvent(ChangeType.ADD, addedFile.path, [token]);
   }
 
   Future test_addFolder_unrelatedFolders() async {
-    Folder folder1 = provider.getFolder('/a/b');
-    Folder folder2 = provider.getFolder('/c/d');
+    Folder folder1 = getFolder('/a/b');
+    Folder folder2 = getFolder('/c/d');
     Token token1 = new Token('token1');
     Token token2 = new Token('token2');
     manager.addFolder(folder1, token1);
     manager.addFolder(folder2, token2);
 
-    File newFile1 = provider.newFile('/a/b/lib.dart', '');
+    File newFile1 = newFile('/a/b/lib.dart');
     await _expectEvent(ChangeType.ADD, newFile1.path, [token1]);
 
-    File newFile2 = provider.newFile('/c/d/lib.dart', '');
+    File newFile2 = newFile('/c/d/lib.dart');
     return _expectEvent(ChangeType.ADD, newFile2.path, [token2]);
   }
 
@@ -141,40 +140,40 @@
   }
 
   Future test_removeFolder_multipleTokens() {
-    Folder folder = provider.getFolder('/a/b');
+    Folder folder = getFolder('/a/b');
     Token token1 = new Token('token1');
     Token token2 = new Token('token2');
     manager.addFolder(folder, token1);
     manager.addFolder(folder, token2);
     manager.removeFolder(folder, token2);
 
-    File newFile = provider.newFile('/a/b/lib.dart', '');
-    return _expectEvent(ChangeType.ADD, newFile.path, [token1]);
+    File addedFile = newFile('/a/b/lib.dart');
+    return _expectEvent(ChangeType.ADD, addedFile.path, [token1]);
   }
 
   Future test_removeFolder_withChildren() async {
-    Folder topFolder = provider.getFolder('/a/b');
-    Folder childFolder = provider.getFolder('/a/b/c/d');
+    Folder topFolder = getFolder('/a/b');
+    Folder childFolder = getFolder('/a/b/c/d');
     Token topToken = new Token('topToken');
     Token childToken = new Token('childToken');
     manager.addFolder(topFolder, topToken);
     manager.addFolder(childFolder, childToken);
     manager.removeFolder(topFolder, topToken);
 
-    File newFile = provider.newFile('/a/b/c/d/lib.dart', '');
-    await _expectEvent(ChangeType.ADD, newFile.path, [childToken]);
+    File addedFile = newFile('/a/b/c/d/lib.dart');
+    await _expectEvent(ChangeType.ADD, addedFile.path, [childToken]);
 
-    provider.newFile('/a/b/lib.dart', '');
+    newFile('/a/b/lib.dart');
     return _expectNoEvent();
   }
 
   Future test_removeFolder_withNoChildren() {
-    Folder folder = provider.getFolder('/a/b');
+    Folder folder = getFolder('/a/b');
     Token token = new Token('token');
     manager.addFolder(folder, token);
     manager.removeFolder(folder, token);
 
-    provider.newFile('/a/b/lib.dart', '');
+    newFile('/a/b/lib.dart');
     return _expectNoEvent();
   }
 
@@ -197,11 +196,9 @@
 }
 
 @reflectiveTest
-class WatchNodeTest {
-  MemoryResourceProvider provider = new MemoryResourceProvider();
-
+class WatchNodeTest extends Object with ResourceProviderMixin {
   void test_creation_folder() {
-    Folder folder = provider.getFolder('/a/b');
+    Folder folder = getFolder('/a/b');
     WatchNode node = new WatchNode(folder);
     expect(node, isNotNull);
     expect(node.children, isEmpty);
@@ -223,9 +220,9 @@
 
   void test_delete_nested_child() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
-    WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
-    WatchNode grandchildNode = new WatchNode(provider.getFolder('/a/b/c/d/e'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
+    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
+    WatchNode grandchildNode = new WatchNode(getFolder('/a/b/c/d/e'));
     rootNode.insert(topNode);
     rootNode.insert(childNode);
     rootNode.insert(grandchildNode);
@@ -239,8 +236,8 @@
 
   void test_delete_nested_noChild() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
-    WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
+    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
     rootNode.insert(topNode);
     rootNode.insert(childNode);
 
@@ -252,8 +249,8 @@
 
   void test_delete_top_child() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
-    WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
+    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
     rootNode.insert(topNode);
     rootNode.insert(childNode);
 
@@ -264,7 +261,7 @@
 
   void test_delete_top_noChild() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
     rootNode.insert(topNode);
 
     topNode.delete();
@@ -273,7 +270,7 @@
 
   void test_findParent_childOfLeaf() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
     rootNode.insert(topNode);
 
     expect(rootNode.findParent('/a/b/c'), topNode);
@@ -281,8 +278,8 @@
 
   void test_findParent_childOfNonLeaf() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
-    WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
+    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
     rootNode.insert(topNode);
     rootNode.insert(childNode);
 
@@ -291,7 +288,7 @@
 
   void test_findParent_noMatch() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
     rootNode.insert(topNode);
 
     expect(rootNode.findParent('/c/d'), rootNode);
@@ -299,9 +296,9 @@
 
   void test_insert_intermediate_afterParentAndChild() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
-    WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
-    WatchNode intermediateNode = new WatchNode(provider.getFolder('/a/b/c'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
+    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
+    WatchNode intermediateNode = new WatchNode(getFolder('/a/b/c'));
 
     rootNode.insert(topNode);
     rootNode.insert(childNode);
@@ -316,8 +313,8 @@
 
   void test_insert_nested_afterParent() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
-    WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
+    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
 
     rootNode.insert(topNode);
     rootNode.insert(childNode);
@@ -328,8 +325,8 @@
 
   void test_insert_nested_beforeParent() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
-    WatchNode childNode = new WatchNode(provider.getFolder('/a/b/c/d'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
+    WatchNode childNode = new WatchNode(getFolder('/a/b/c/d'));
 
     rootNode.insert(childNode);
     rootNode.insert(topNode);
@@ -340,7 +337,7 @@
 
   void test_insert_top() {
     WatchNode rootNode = new WatchNode(null);
-    WatchNode topNode = new WatchNode(provider.getFolder('/a/b'));
+    WatchNode topNode = new WatchNode(getFolder('/a/b'));
 
     rootNode.insert(topNode);
     expect(rootNode.children, equals([topNode]));
diff --git a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
index 20bd277..b06f3f7 100644
--- a/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
+++ b/pkg/analyzer/lib/src/dart/analysis/library_analyzer.dart
@@ -551,6 +551,7 @@
         for (ImportElement importElement in _libraryElement.imports) {
           if (matchNodeElement(directive, importElement)) {
             directive.element = importElement;
+            directive.prefix?.staticElement = importElement.prefix;
             Source source = importElement.importedLibrary?.source;
             if (source != null && !_isLibrarySource(source)) {
               ErrorCode errorCode = importElement.isDeferred
@@ -1227,22 +1228,15 @@
       kernel.VariableDeclaration variable = kernelType.function.variable;
       FunctionElement element = declarationToElement[variable];
       return element.type;
-    } else if (kernelType is kernel.MemberInvocationDartType) {
-      kernel.Member member = kernelType.member;
-      if (member is kernel.Procedure &&
-          member.kind == kernel.ProcedureKind.Method) {
-        ExecutableElementImpl element =
-            resynthesizer.getElementFromCanonicalName(member.canonicalName);
-        return resynthesizer.instantiateFunctionType(
-            context,
-            element,
-            member.function,
-            member.function.functionType.withoutTypeParameters,
-            kernelType.type);
-      }
-      return DynamicTypeImpl.instance;
     } else if (kernelType is kernel.IndexAssignNullFunctionType) {
       return null;
+    } else if (kernelType is kernel.TypeArgumentsDartType) {
+      List<kernel.DartType> kernelTypes = kernelType.types;
+      var types = new List<DartType>(kernelTypes.length);
+      for (var i = 0; i < kernelTypes.length; i++) {
+        types[i] = translateType(kernelTypes[i]);
+      }
+      return new TypeArgumentsDartType(types);
     } else {
       return resynthesizer.getType(context, kernelType);
     }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 0f26c2c..8da11b2 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -8603,11 +8603,11 @@
 
   @override
   String get name {
-    if (_kernel != null) {
-      return _kernel.name;
-    }
-    if (_unlinkedImport != null) {
-      if (_name == null) {
+    if (_name == null) {
+      if (_kernel != null) {
+        return _name = _kernel.name;
+      }
+      if (_unlinkedImport != null) {
         LibraryElementImpl library = enclosingElement as LibraryElementImpl;
         int prefixId = _unlinkedImport.prefixReference;
         return _name = library._unlinkedDefiningUnit.references[prefixId].name;
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index f5c683c..61f5a19 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -19,7 +19,6 @@
         MemberKind,
         optional,
         Parser;
-import 'package:front_end/src/fasta/scanner/string_scanner.dart';
 import 'package:front_end/src/fasta/scanner.dart' hide StringToken;
 import 'package:front_end/src/scanner/token.dart'
     show
@@ -2696,83 +2695,10 @@
   }
 
   @override
-  Token injectGenericCommentTypeAssign(Token token) {
-    // TODO(paulberry,scheglov,ahe): figure out how to share these generic
-    // comment methods with BodyBuilder.
-    return _injectGenericComment(
-        token, TokenType.GENERIC_METHOD_TYPE_ASSIGN, 3);
-  }
-
-  @override
-  Token injectGenericCommentTypeList(Token token) {
-    return _injectGenericComment(token, TokenType.GENERIC_METHOD_TYPE_LIST, 2);
-  }
-
-  @override
-  Token replaceTokenWithGenericCommentTypeAssign(
-      Token tokenToStartReplacing, Token tokenWithComment) {
-    Token injected = injectGenericCommentTypeAssign(tokenWithComment);
-    if (!identical(injected, tokenWithComment)) {
-      Token prev = tokenToStartReplacing.previous;
-      prev.setNextWithoutSettingPrevious(injected);
-      tokenToStartReplacing = injected;
-      tokenToStartReplacing.previous = prev;
-    }
-    return tokenToStartReplacing;
-  }
-
-  @override
   void discardTypeReplacedWithCommentTypeAssign() {
     pop();
   }
 
-  /// Check if the given [token] has a comment token with the given [type],
-  /// which should be either [TokenType.GENERIC_METHOD_TYPE_ASSIGN] or
-  /// [TokenType.GENERIC_METHOD_TYPE_LIST].  If found, parse the comment
-  /// into tokens and inject into the token stream before the [token].
-  Token _injectGenericComment(Token token, TokenType type, int prefixLen) {
-    if (parseGenericMethodComments) {
-      CommentToken t = token.precedingComments;
-      for (; t != null; t = t.next) {
-        if (t.type == type) {
-          String code = t.lexeme.substring(prefixLen, t.lexeme.length - 2);
-          Token tokens = _scanGenericMethodComment(code, t.offset + prefixLen);
-          if (tokens != null) {
-            // Remove the token from the comment stream.
-            t.remove();
-            // Insert the tokens into the stream.
-            _injectTokenList(token, tokens);
-            return tokens;
-          }
-        }
-      }
-    }
-    return token;
-  }
-
-  void _injectTokenList(Token beforeToken, Token firstToken) {
-    // Scanner creates a cyclic EOF token.
-    Token lastToken = firstToken;
-    while (lastToken.next.type != TokenType.EOF) {
-      lastToken = lastToken.next;
-    }
-    // Inject these new tokens into the stream.
-    Token previous = beforeToken.previous;
-    lastToken.setNext(beforeToken);
-    previous.setNext(firstToken);
-    beforeToken = firstToken;
-  }
-
-  /// Scans the given [code], and returns the tokens, otherwise returns `null`.
-  Token _scanGenericMethodComment(String code, int offset) {
-    var scanner = new SubStringScanner(offset, code);
-    Token firstToken = scanner.tokenize();
-    if (scanner.hasErrors) {
-      return null;
-    }
-    return firstToken;
-  }
-
   @override
   void addCompileTimeError(Message message, int offset, int length) {
     if (directives.isEmpty &&
diff --git a/pkg/analyzer/lib/src/fasta/error_converter.dart b/pkg/analyzer/lib/src/fasta/error_converter.dart
index 02e3688..0976bb8 100644
--- a/pkg/analyzer/lib/src/fasta/error_converter.dart
+++ b/pkg/analyzer/lib/src/fasta/error_converter.dart
@@ -18,8 +18,10 @@
   /// [errorReporter].
   FastaErrorReporter(this.errorReporter);
 
-  void reportByCode(String analyzerCode, int offset, int length,
-      Map<String, dynamic> arguments) {
+  void reportByCode(
+      String analyzerCode, int offset, int length, Message message) {
+    Map<String, dynamic> arguments = message.arguments;
+
     String stringOrTokenLexeme() {
       var text = arguments['string'];
       if (text == null) {
@@ -293,8 +295,8 @@
             StrongModeCode.INVALID_CAST_NEW_EXPR, offset, length);
         return;
       case "INVALID_MODIFIER_ON_SETTER":
-        errorReporter?.reportErrorForOffset(
-            CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER, offset, length);
+        _reportByCode(CompileTimeErrorCode.INVALID_MODIFIER_ON_SETTER, message,
+            offset, length);
         return;
       case "INVALID_OPERATOR":
         String text = stringOrTokenLexeme();
@@ -302,8 +304,8 @@
             ParserErrorCode.INVALID_OPERATOR, offset, length, [text]);
         return;
       case "INVALID_OPERATOR_FOR_SUPER":
-        errorReporter?.reportErrorForOffset(
-            ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, offset, length);
+        _reportByCode(ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, message,
+            offset, length);
         return;
       case "LIBRARY_DIRECTIVE_NOT_FIRST":
         errorReporter?.reportErrorForOffset(
@@ -547,6 +549,19 @@
   void reportMessage(Message message, int offset, int length) {
     Code code = message.code;
 
-    reportByCode(code.analyzerCode, offset, length, message.arguments);
+    reportByCode(code.analyzerCode, offset, length, message);
+  }
+
+  void _reportByCode(
+      ErrorCode errorCode, Message message, int offset, int length) {
+    if (errorReporter != null) {
+      errorReporter.reportError(new AnalysisError.forValues(
+          errorReporter.source,
+          offset,
+          length,
+          errorCode,
+          message.message,
+          null));
+    }
   }
 }
diff --git a/pkg/analyzer/lib/src/fasta/resolution_applier.dart b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
index ccc7295..99dcdc7 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_applier.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_applier.dart
@@ -11,7 +11,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/fasta/resolution_storer.dart';
-import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:front_end/src/base/syntactic_entity.dart';
 import 'package:front_end/src/scanner/token.dart';
 import 'package:kernel/kernel.dart' as kernel;
@@ -95,6 +94,7 @@
         operatorType != TokenType.BAR_BAR) {
       node.staticElement = _getReferenceFor(node.operator);
       _getTypeFor(node.operator); // function type of the operator
+      _getTypeFor(node.operator); // type arguments
     }
 
     // Record the return type of the expression.
@@ -290,6 +290,7 @@
 
     // We cannot use the detached FunctionType of `[]` or `[]=`.
     _getTypeFor(node.leftBracket);
+    _getTypeFor(node.leftBracket); // type arguments
 
     node.staticType = _getTypeFor(node.leftBracket);
 
@@ -303,13 +304,14 @@
     DartType type = _getTypeFor(constructorName);
     ConstructorElement element = _getReferenceFor(constructorName);
 
+    constructorName.staticElement = element;
+
     node.staticElement = element;
     node.staticType = type;
 
     applyConstructorElement(type, element, constructorName);
 
     ArgumentList argumentList = node.argumentList;
-    _associateArgumentsWithParameters(element?.parameters, argumentList);
     _applyResolutionToArguments(argumentList);
   }
 
@@ -348,6 +350,7 @@
 
     Element invokeElement = _getReferenceFor(node.methodName);
     DartType invokeType = _getTypeFor(node.methodName);
+    DartType typeArgumentsDartType = _getTypeFor(argumentList);
     DartType resultType = _getTypeFor(argumentList);
 
     if (invokeElement is PropertyInducingElement) {
@@ -361,10 +364,11 @@
     node.methodName.staticType = invokeType;
 
     if (invokeType is FunctionType) {
-      if (node.typeArguments != null) {
-        _applyTypeArgumentsToList(invokeType, node.typeArguments.arguments);
+      if (node.typeArguments != null &&
+          typeArgumentsDartType is TypeArgumentsDartType) {
+        _applyTypeArgumentsToList(
+            typeArgumentsDartType, node.typeArguments.arguments);
       }
-      _associateArgumentsWithParameters(invokeType.parameters, argumentList);
     }
 
     _applyResolutionToArguments(argumentList);
@@ -415,6 +419,7 @@
       SyntacticEntity entity = node.operator;
       node.staticElement = _getReferenceFor(entity);
       _getTypeFor(entity); // The function type of the operator.
+      _getTypeFor(entity); // The type arguments (empty).
       node.staticType = _getTypeFor(entity);
     }
   }
@@ -436,7 +441,6 @@
     constructorName?.staticElement = element;
 
     ArgumentList argumentList = node.argumentList;
-    _associateArgumentsWithParameters(element?.parameters, argumentList);
     _applyResolutionToArguments(argumentList);
   }
 
@@ -543,33 +547,6 @@
     }
   }
 
-  /// Associate arguments of the [argumentList] with the [parameters].
-  void _associateArgumentsWithParameters(
-      List<ParameterElement> parameters, ArgumentList argumentList) {
-    if (parameters != null) {
-      List<Expression> arguments = argumentList.arguments;
-      var correspondingParameters =
-          new List<ParameterElement>(arguments.length);
-      for (int i = 0; i < arguments.length; i++) {
-        var argument = arguments[i];
-        if (argument is NamedExpression) {
-          for (var parameter in parameters) {
-            SimpleIdentifier label = argument.name.label;
-            if (parameter.parameterKind == ParameterKind.NAMED &&
-                parameter.name == label.name) {
-              label.staticElement = parameter;
-              correspondingParameters[i] = parameter;
-              break;
-            }
-          }
-        } else {
-          correspondingParameters[i] = parameters[i];
-        }
-      }
-      argumentList.correspondingStaticParameters = correspondingParameters;
-    }
-  }
-
   /// Return the [SyntacticEntity] with which the front-end associates
   /// assignment to the given [leftHandSide].
   SyntacticEntity _getAssignmentEntity(Expression leftHandSide) {
@@ -775,6 +752,24 @@
   }
 }
 
+/// A container with [typeArguments].
+class TypeArgumentsDartType implements ParameterizedType {
+  @override
+  final List<DartType> typeArguments;
+
+  TypeArgumentsDartType(this.typeArguments);
+
+  @override
+  bool get isUndefined => false;
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() {
+    return '<${typeArguments.join(', ')}>';
+  }
+}
+
 /// Context for translating types.
 abstract class TypeContext {
   /// The enclosing [ClassElement], or `null` if not in a class.
diff --git a/pkg/analyzer/lib/src/fasta/resolution_storer.dart b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
index d1d04a9..e059b8b 100644
--- a/pkg/analyzer/lib/src/fasta/resolution_storer.dart
+++ b/pkg/analyzer/lib/src/fasta/resolution_storer.dart
@@ -160,21 +160,6 @@
   }
 }
 
-/// Information about invocation of the [member] and its instantiated [type].
-class MemberInvocationDartType implements DartType {
-  final Member member;
-  final FunctionType type;
-
-  MemberInvocationDartType(this.member, this.type);
-
-  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
-
-  @override
-  String toString() {
-    return '($member, $type)';
-  }
-}
-
 /// A reference to the setter represented by the [member].
 /// The [member] might be either a setter itself, or a field.
 class MemberSetterNode implements TreeNode {
@@ -381,6 +366,7 @@
   void indexAssignAfterReceiver(Expression write, DartType typeContext) {
     _deferReference(write.fileOffset);
     _recordType(const IndexAssignNullFunctionType(), write.fileOffset);
+    _recordType(new TypeArgumentsDartType(<DartType>[]), write.fileOffset);
     _deferType(write.fileOffset);
   }
 
@@ -438,6 +424,7 @@
       _deferType(expression.fileOffset);
     }
     _deferType(expression.fileOffset);
+    _deferType(expression.fileOffset);
     super.methodInvocationBeforeArgs(expression, isImplicitCall);
   }
 
@@ -450,11 +437,11 @@
       FunctionType calleeType,
       Substitution substitution,
       DartType inferredType) {
-    _replaceType(
-        inferredType,
-        arguments.fileOffset != -1
-            ? arguments.fileOffset
-            : expression.fileOffset);
+    int resultOffset = arguments.fileOffset != -1
+        ? arguments.fileOffset
+        : expression.fileOffset;
+    _replaceType(inferredType, resultOffset);
+    _replaceType(new TypeArgumentsDartType(arguments.types), resultOffset);
     if (!isImplicitCall) {
       if (interfaceMember is ForwardingStub) {
         interfaceMember = ForwardingStub.getInterfaceTarget(interfaceMember);
@@ -463,7 +450,7 @@
       FunctionType invokeType = substitution == null
           ? calleeType
           : substitution.substituteType(calleeType.withoutTypeParameters);
-      _replaceType(new MemberInvocationDartType(interfaceMember, invokeType));
+      _replaceType(invokeType);
     }
     super.genericExpressionExit("methodInvocation", expression, inferredType);
   }
@@ -471,11 +458,11 @@
   @override
   void methodInvocationExitCall(Expression expression, Arguments arguments,
       bool isImplicitCall, DartType inferredType) {
-    _replaceType(
-        inferredType,
-        arguments.fileOffset != -1
-            ? arguments.fileOffset
-            : expression.fileOffset);
+    int resultOffset = arguments.fileOffset != -1
+        ? arguments.fileOffset
+        : expression.fileOffset;
+    _replaceType(inferredType, resultOffset);
+    _replaceType(new TypeArgumentsDartType(arguments.types), resultOffset);
     if (!isImplicitCall) {
       throw new UnimplementedError(); // TODO(scheglov): handle this case
     }
@@ -620,6 +607,7 @@
     // type later.
     _deferType(expression.fileOffset);
     _deferType(expression.arguments.fileOffset);
+    _deferType(expression.arguments.fileOffset);
     return super.staticInvocationEnter(
         expression, prefixName, targetOffset, targetClass, typeContext);
   }
@@ -632,10 +620,11 @@
       DartType inferredType) {
     _replaceType(inferredType);
     _replaceReference(expression.target);
+    _replaceType(new TypeArgumentsDartType(expression.arguments.types));
     FunctionType invokeType = substitution == null
         ? calleeType
         : substitution.substituteType(calleeType.withoutTypeParameters);
-    _replaceType(new MemberInvocationDartType(expression.target, invokeType));
+    _replaceType(invokeType);
     super.genericExpressionExit("staticInvocation", expression, inferredType);
   }
 
@@ -768,3 +757,17 @@
     _types[slot] = type;
   }
 }
+
+/// A [DartType] wrapper around invocation type arguments.
+class TypeArgumentsDartType implements DartType {
+  final List<DartType> types;
+
+  TypeArgumentsDartType(this.types);
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() {
+    return '<${types.join(', ')}>';
+  }
+}
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 1b8b79e..75a93ec 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -750,6 +750,11 @@
   static const String ANALYSIS_OPTIONS_YAML_FILE = 'analysis_options.yaml';
 
   /**
+   * The file name used for pubspec files.
+   */
+  static const String PUBSPEC_YAML_FILE = 'pubspec.yaml';
+
+  /**
    * The unique instance of this class.
    */
   static final AnalysisEngine instance = new AnalysisEngine._();
diff --git a/pkg/analyzer/lib/src/kernel/resynthesize.dart b/pkg/analyzer/lib/src/kernel/resynthesize.dart
index a3a6ee3..0b13b05 100644
--- a/pkg/analyzer/lib/src/kernel/resynthesize.dart
+++ b/pkg/analyzer/lib/src/kernel/resynthesize.dart
@@ -238,87 +238,13 @@
     }
 
     if (kernelType is kernel.FunctionType) {
-      var typedef = kernelType.typedef;
-      if (typedef != null) {
-        GenericTypeAliasElementImpl typedefElement =
-            getElementFromCanonicalName(typedef.canonicalName);
-        GenericFunctionTypeElementImpl functionElement =
-            typedefElement.function;
-        return instantiateFunctionType(
-            context, functionElement, typedef, typedef.type, kernelType);
-      }
-      var typeElement =
-          new GenericFunctionTypeElementImpl.forKernel(context, kernelType);
-      return typeElement.type;
+      return _getFunctionType(context, kernelType);
     }
 
     // TODO(scheglov) Support other kernel types.
     throw new UnimplementedError('For ${kernelType.runtimeType}');
   }
 
-  /// Given the [executable] element that corresponds to the [kernelNode],
-  /// and the [kernelType] that is the instantiated type of [kernelNode],
-  /// return the instantiated type of the [executable].
-  FunctionType instantiateFunctionType(
-      ElementImpl context,
-      FunctionTypedElement executable,
-      kernel.TreeNode kernelNode,
-      kernel.FunctionType kernelRawType,
-      kernel.FunctionType kernelType) {
-    // Prepare all kernel type parameters.
-    var kernelTypeParameters = <kernel.TypeParameter>[];
-    for (kernel.TreeNode node = kernelNode; node != null; node = node.parent) {
-      if (node is kernel.Class) {
-        kernelTypeParameters.addAll(node.typeParameters);
-      } else if (node is kernel.FunctionNode) {
-        kernelTypeParameters.addAll(node.typeParameters);
-      } else if (node is kernel.Typedef) {
-        kernelTypeParameters.addAll(node.typeParameters);
-      }
-    }
-
-    // If no type parameters, the raw type of the element will do.
-    FunctionTypeImpl rawType = executable.type;
-    if (kernelTypeParameters.isEmpty) {
-      return rawType;
-    }
-
-    // Compute type arguments for kernel type parameters.
-    var kernelMap = kernel.unifyTypes(
-        kernelRawType, kernelType, kernelTypeParameters.toSet());
-
-    // Prepare Analyzer type parameters, in the same order as kernel ones.
-    var astTypeParameters = <TypeParameterElement>[];
-    for (Element element = executable;
-        element != null;
-        element = element.enclosingElement) {
-      if (element is TypeParameterizedElement) {
-        astTypeParameters.addAll(element.typeParameters);
-      }
-    }
-
-    // Convert kernel type arguments into Analyzer types.
-    int length = astTypeParameters.length;
-    var usedTypeParameters = <TypeParameterElement>[];
-    var usedTypeArguments = <DartType>[];
-    for (var i = 0; i < length; i++) {
-      var kernelParameter = kernelTypeParameters[i];
-      var kernelArgument = kernelMap[kernelParameter];
-      if (kernelArgument != null) {
-        DartType astArgument = getType(context, kernelArgument);
-        usedTypeParameters.add(astTypeParameters[i]);
-        usedTypeArguments.add(astArgument);
-      }
-    }
-
-    if (usedTypeParameters.isEmpty) {
-      return rawType;
-    }
-
-    // Replace Analyzer type parameters with type arguments.
-    return rawType.substitute4(usedTypeParameters, usedTypeArguments);
-  }
-
   void _buildTypeProvider() {
     var coreLibrary = getLibrary('dart:core');
     var asyncLibrary = getLibrary('dart:async');
@@ -330,6 +256,44 @@
     asyncLibrary.createLoadLibraryFunction(_typeProvider);
   }
 
+  /// Return the [FunctionType] that corresponds to the given [kernelType].
+  FunctionType _getFunctionType(
+      ElementImpl context, kernel.FunctionType kernelType) {
+    if (kernelType.typedef != null) {
+      return _getTypedefType(context, kernelType);
+    }
+
+    var element = new FunctionElementImpl('', -1);
+    context.encloseElement(element);
+
+    // Set type parameters.
+    {
+      List<kernel.TypeParameter> typeParameters = kernelType.typeParameters;
+      int count = typeParameters.length;
+      var astTypeParameters = new List<TypeParameterElement>(count);
+      for (int i = 0; i < count; i++) {
+        astTypeParameters[i] =
+            new TypeParameterElementImpl.forKernel(element, typeParameters[i]);
+      }
+      element.typeParameters = astTypeParameters;
+    }
+
+    // Set formal parameters.
+    var parameters = _getFunctionTypeParameters(kernelType);
+    var positionalParameters = parameters[0];
+    var namedParameters = parameters[1];
+    var astParameters = ParameterElementImpl.forKernelParameters(
+        element,
+        kernelType.requiredParameterCount,
+        positionalParameters,
+        namedParameters);
+    element.parameters = astParameters;
+
+    element.returnType = getType(element, kernelType.returnType);
+
+    return new FunctionTypeImpl(element);
+  }
+
   InterfaceType _getInterfaceType(ElementImpl context,
       kernel.CanonicalName className, List<kernel.DartType> kernelArguments) {
     var libraryName = className.parent;
@@ -358,6 +322,52 @@
         uri, () => _analysisContext.sourceFactory.forUri(uri));
   }
 
+  /// Return the [FunctionType] for the given typedef based [kernelType].
+  FunctionType _getTypedefType(
+      ElementImpl context, kernel.FunctionType kernelType) {
+    kernel.Typedef typedef = kernelType.typedef;
+
+    GenericTypeAliasElementImpl typedefElement =
+        getElementFromCanonicalName(typedef.canonicalName);
+    GenericFunctionTypeElementImpl functionElement = typedefElement.function;
+
+    var kernelTypeParameters = typedef.typeParameters;
+
+    // If no type parameters, the raw type of the element will do.
+    FunctionTypeImpl rawType = functionElement.type;
+    if (kernelTypeParameters.isEmpty) {
+      return rawType;
+    }
+
+    // Compute type arguments for kernel type parameters.
+    var kernelMap = kernel.unifyTypes(
+        typedef.type, kernelType, kernelTypeParameters.toSet());
+
+    // Prepare Analyzer type parameters, in the same order as kernel ones.
+    var astTypeParameters = typedefElement.typeParameters;
+
+    // Convert kernel type arguments into Analyzer types.
+    int length = astTypeParameters.length;
+    var usedTypeParameters = <TypeParameterElement>[];
+    var usedTypeArguments = <DartType>[];
+    for (var i = 0; i < length; i++) {
+      var kernelParameter = kernelTypeParameters[i];
+      var kernelArgument = kernelMap[kernelParameter];
+      if (kernelArgument != null) {
+        DartType astArgument = getType(context, kernelArgument);
+        usedTypeParameters.add(astTypeParameters[i]);
+        usedTypeArguments.add(astArgument);
+      }
+    }
+
+    if (usedTypeParameters.isEmpty) {
+      return rawType;
+    }
+
+    // Replace Analyzer type parameters with type arguments.
+    return rawType.substitute4(usedTypeParameters, usedTypeArguments);
+  }
+
   /// Return the [TypeParameterElement] for the given [kernelTypeParameter].
   TypeParameterElement _getTypeParameter(
       ElementImpl context, kernel.TypeParameter kernelTypeParameter) {
@@ -391,6 +401,28 @@
     libraryElement.exportNamespace = new Namespace({});
     return libraryElement;
   }
+
+  /// Return the list with exactly two elements - positional and named
+  /// parameter lists.
+  static List<List<kernel.VariableDeclaration>> _getFunctionTypeParameters(
+      kernel.FunctionType type) {
+    int positionalCount = type.positionalParameters.length;
+    var positionalParameters =
+        new List<kernel.VariableDeclaration>(positionalCount);
+    for (int i = 0; i < positionalCount; i++) {
+      String name = i < type.positionalParameterNames.length
+          ? type.positionalParameterNames[i]
+          : 'arg_$i';
+      positionalParameters[i] = new kernel.VariableDeclaration(name,
+          type: type.positionalParameters[i]);
+    }
+
+    var namedParameters = type.namedParameters
+        .map((k) => new kernel.VariableDeclaration(k.name, type: k.type))
+        .toList(growable: false);
+
+    return [positionalParameters, namedParameters];
+  }
 }
 
 /**
@@ -1090,22 +1122,7 @@
   @override
   List<List<kernel.VariableDeclaration>> getFunctionTypeParameters(
       kernel.FunctionType type) {
-    int positionalCount = type.positionalParameters.length;
-    var positionalParameters =
-        new List<kernel.VariableDeclaration>(positionalCount);
-    for (int i = 0; i < positionalCount; i++) {
-      String name = i < type.positionalParameterNames.length
-          ? type.positionalParameterNames[i]
-          : 'arg_$i';
-      positionalParameters[i] = new kernel.VariableDeclaration(name,
-          type: type.positionalParameters[i]);
-    }
-
-    var namedParameters = type.namedParameters
-        .map((k) => new kernel.VariableDeclaration(k.name, type: k.type))
-        .toList(growable: false);
-
-    return [positionalParameters, namedParameters];
+    return KernelResynthesizer._getFunctionTypeParameters(type);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
new file mode 100644
index 0000000..3753998
--- /dev/null
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_validator.dart
@@ -0,0 +1,181 @@
+// 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/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:path/path.dart' as path;
+import 'package:source_span/src/span.dart';
+import 'package:yaml/yaml.dart';
+
+class PubspecValidator {
+  /**
+   * The name of the sub-field (under `flutter`) whose value is a list of assets
+   * available to Flutter apps at runtime.
+   */
+  static const String ASSETS_FIELD = 'assets';
+
+  /**
+   * The name of the field whose value is a map of dependencies.
+   */
+  static const String DEPENDENCIES_FIELD = 'dependencies';
+
+  /**
+   * The name of the field whose value is a map of development dependencies.
+   */
+  static const String DEV_DEPENDENCIES_FIELD = 'dev_dependencies';
+
+  /**
+   * The name of the field whose value is a specification of Flutter-specific
+   * configuration data.
+   */
+  static const String FLUTTER_FIELD = 'flutter';
+
+  /**
+   * The name of the field whose value is the name of the package.
+   */
+  static const String NAME_FIELD = 'name';
+
+  /**
+   * The resource provider used to access the file system.
+   */
+  final ResourceProvider provider;
+
+  /**
+   * The source representing the file being validated.
+   */
+  final Source source;
+
+  /**
+   * Initialize a newly create validator to validate the content of the given
+   * [source].
+   */
+  PubspecValidator(this.provider, this.source);
+
+  /**
+   * Validate the given [contents].
+   */
+  List<AnalysisError> validate(Map<dynamic, YamlNode> contents) {
+    RecordingErrorListener recorder = new RecordingErrorListener();
+    ErrorReporter reporter = new ErrorReporter(recorder, source);
+
+    _validateDependencies(reporter, contents);
+    _validateFlutter(reporter, contents);
+    _validateName(reporter, contents);
+
+    return recorder.errors;
+  }
+
+  /**
+   * Return a map whose keys are the names of declared dependencies and whose
+   * values are the specifications of those dependencies. The map is extracted
+   * from the given [contents] using the given [key].
+   */
+  Map<dynamic, YamlNode> _getDeclaredDependencies(
+      ErrorReporter reporter, Map<String, YamlNode> contents, String key) {
+    YamlNode field = contents[key];
+    if (field == null) {
+      return <String, YamlNode>{};
+    } else if (field is YamlMap) {
+      return field.nodes;
+    }
+    _reportErrorForNode(
+        reporter, field, PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP, [key]);
+    return <String, YamlNode>{};
+  }
+
+  /**
+   * Report an error for the given node.
+   */
+  void _reportErrorForNode(
+      ErrorReporter reporter, YamlNode node, ErrorCode errorCode,
+      [List<Object> arguments]) {
+    SourceSpan span = node.span;
+    reporter.reportErrorForOffset(
+        errorCode, span.start.offset, span.length, arguments);
+  }
+
+  /**
+   * Validate the value of the required `name` field.
+   */
+  void _validateDependencies(
+      ErrorReporter reporter, Map<dynamic, YamlNode> contents) {
+    Map<dynamic, YamlNode> declaredDependencies =
+        _getDeclaredDependencies(reporter, contents, DEPENDENCIES_FIELD);
+    Map<dynamic, YamlNode> declaredDevDependencies =
+        _getDeclaredDependencies(reporter, contents, DEV_DEPENDENCIES_FIELD);
+
+    for (YamlNode packageName in declaredDevDependencies.keys) {
+      if (declaredDependencies.containsKey(packageName)) {
+        _reportErrorForNode(reporter, packageName,
+            PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY, [packageName.value]);
+      }
+    }
+  }
+
+  /**
+   * Validate the value of the optional `flutter` field.
+   */
+  void _validateFlutter(
+      ErrorReporter reporter, Map<dynamic, YamlNode> contents) {
+    YamlNode flutterField = contents[FLUTTER_FIELD];
+    if (flutterField is YamlMap) {
+      YamlNode assetsField = flutterField.nodes[ASSETS_FIELD];
+      if (assetsField is YamlList) {
+        path.Context context = provider.pathContext;
+        String packageRoot = context.dirname(source.fullName);
+        for (YamlNode entryValue in assetsField.nodes) {
+          if (entryValue is YamlScalar) {
+            Object entry = entryValue.value;
+            if (entry is String) {
+              String normalizedEntry = context.joinAll(path.posix.split(entry));
+              String assetPath = context.join(packageRoot, normalizedEntry);
+              if (!provider.getFile(assetPath).exists) {
+                _reportErrorForNode(
+                    reporter,
+                    entryValue,
+                    PubspecWarningCode.ASSET_DOES_NOT_EXIST,
+                    [entryValue.value]);
+              }
+            } else {
+              _reportErrorForNode(
+                  reporter, entryValue, PubspecWarningCode.ASSET_NOT_STRING);
+            }
+          } else {
+            _reportErrorForNode(
+                reporter, entryValue, PubspecWarningCode.ASSET_NOT_STRING);
+          }
+        }
+      } else if (assetsField != null) {
+        _reportErrorForNode(
+            reporter, assetsField, PubspecWarningCode.ASSET_FIELD_NOT_LIST);
+      } else {
+        // TODO(brianwilkerson) Should we report an error if `assets` is
+        // missing?
+      }
+      if (flutterField.length > 1) {
+        // TODO(brianwilkerson) Should we report an error if `flutter` contains
+        // keys other than `assets`?
+      }
+    } else if (flutterField != null) {
+      _reportErrorForNode(
+          reporter, flutterField, PubspecWarningCode.FLUTTER_FIELD_NOT_MAP);
+    }
+  }
+
+  /**
+   * Validate the value of the required `name` field.
+   */
+  void _validateName(ErrorReporter reporter, Map<dynamic, YamlNode> contents) {
+    YamlNode nameField = contents[NAME_FIELD];
+    if (nameField == null) {
+      reporter.reportErrorForOffset(PubspecWarningCode.MISSING_NAME, 0, 0);
+    } else if (nameField is! YamlScalar || nameField.value is! String) {
+      _reportErrorForNode(
+          reporter, nameField, PubspecWarningCode.NAME_NOT_STRING);
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
new file mode 100644
index 0000000..6629300
--- /dev/null
+++ b/pkg/analyzer/lib/src/pubspec/pubspec_warning_code.dart
@@ -0,0 +1,102 @@
+// 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/error/error.dart';
+
+/**
+ * The error codes used for warnings in analysis options files. The convention
+ * for this class is for the name of the error code to indicate the problem that
+ * caused the error to be generated and for the error message to explain what is
+ * wrong and, when appropriate, how the problem can be corrected.
+ */
+class PubspecWarningCode extends ErrorCode {
+  /**
+   * A code indicating that a specified asset does not exist.
+   *
+   * Parameters:
+   * 0: the path to the asset as given in the file.
+   */
+  static const PubspecWarningCode ASSET_DOES_NOT_EXIST =
+      const PubspecWarningCode(
+          'ASSET_DOES_NOT_EXIST',
+          "The asset {0} does not exist.",
+          "Try creating the file or fixing the path to the file.");
+
+  /**
+   * A code indicating that the value of the asset field is not a list.
+   */
+  static const PubspecWarningCode ASSET_FIELD_NOT_LIST = const PubspecWarningCode(
+      'ASSET_FIELD_NOT_LIST',
+      "The value of the 'asset' field is expected to be a list of relative file paths.",
+      "Try converting the value to be a list of relative file paths.");
+
+  /**
+   * A code indicating that an element in the asset list is not a string.
+   */
+  static const PubspecWarningCode ASSET_NOT_STRING = const PubspecWarningCode(
+      'ASSET_NOT_STRING',
+      "Assets are expected to be a file paths (strings).",
+      "Try converting the value to be a string.");
+
+  /**
+   * A code indicating that the value of a dependencies field is not a map.
+   */
+  static const PubspecWarningCode DEPENDENCIES_FIELD_NOT_MAP =
+      const PubspecWarningCode(
+          'DEPENDENCIES_FIELD_NOT_MAP',
+          "The value of the '{0}' field is expected to be a map.",
+          "Try converting the value to be a map.");
+
+  /**
+   * A code indicating that the value of the flutter field is not a map.
+   */
+  static const PubspecWarningCode FLUTTER_FIELD_NOT_MAP =
+      const PubspecWarningCode(
+          'FLUTTER_FIELD_NOT_MAP',
+          "The value of the 'flutter' field is expected to be a map.",
+          "Try converting the value to be a map.");
+
+  /**
+   * A code indicating that the name field is missing.
+   */
+  static const PubspecWarningCode MISSING_NAME = const PubspecWarningCode(
+      'MISSING_NAME',
+      "The name field is required but missing.",
+      "Try adding a field named 'name'.");
+
+  /**
+   * A code indicating that the name field is not a string.
+   */
+  static const PubspecWarningCode NAME_NOT_STRING = const PubspecWarningCode(
+      'NAME_NOT_STRING',
+      "The value of the name field is expected to be a string.",
+      "Try converting the value to be a string.");
+
+  /**
+   * A code indicating that a package listed as a dev dependency is also listed
+   * as a normal dependency.
+   *
+   * Parameters:
+   * 0: the name of the package in the dev_dependency list.
+   */
+  static const PubspecWarningCode UNNECESSARY_DEV_DEPENDENCY =
+      const PubspecWarningCode(
+          'UNNECESSARY_DEV_DEPENDENCY',
+          "The dev dependency on {0} is unnecessary because there is also a "
+          "normal dependency on that package.",
+          "Try removing the dev dependency.");
+
+  /**
+   * Initialize a newly created warning code to have the given [name], [message]
+   * and [correction].
+   */
+  const PubspecWarningCode(String name, String message, [String correction])
+      : super(name, message, correction);
+
+  @override
+  ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
+
+  @override
+  ErrorType get type => ErrorType.STATIC_WARNING;
+}
diff --git a/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
new file mode 100644
index 0000000..a85b628
--- /dev/null
+++ b/pkg/analyzer/lib/src/test_utilities/resource_provider_mixin.dart
@@ -0,0 +1,55 @@
+// 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/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
+
+/**
+ * A mixin for test classes that adds a [ResourceProvider] and utility methods
+ * for manipulating the file system. The utility methods all take a posix style
+ * path and convert it as appropriate for the actual platform.
+ */
+class ResourceProviderMixin {
+  final MemoryResourceProvider resourceProvider = new MemoryResourceProvider();
+
+  void deleteFile(String path) {
+    String convertedPath = resourceProvider.convertPath(path);
+    resourceProvider.deleteFile(convertedPath);
+  }
+
+  void deleteFolder(String path) {
+    String convertedPath = resourceProvider.convertPath(path);
+    resourceProvider.deleteFolder(convertedPath);
+  }
+
+  File getFile(String path) {
+    String convertedPath = resourceProvider.convertPath(path);
+    return resourceProvider.getFile(convertedPath);
+  }
+
+  Folder getFolder(String path) {
+    String convertedPath = resourceProvider.convertPath(path);
+    return resourceProvider.getFolder(convertedPath);
+  }
+
+  void modifyFile(String path, String content) {
+    String convertedPath = resourceProvider.convertPath(path);
+    resourceProvider.modifyFile(convertedPath, content);
+  }
+
+  File newFile(String path, {String content = ''}) {
+    String convertedPath = resourceProvider.convertPath(path);
+    return resourceProvider.newFile(convertedPath, content);
+  }
+
+  File newFileWithBytes(String path, List<int> bytes) {
+    String convertedPath = resourceProvider.convertPath(path);
+    return resourceProvider.newFileWithBytes(convertedPath, bytes);
+  }
+
+  Folder newFolder(String path) {
+    String convertedPath = resourceProvider.convertPath(path);
+    return resourceProvider.newFolder(convertedPath);
+  }
+}
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
index dcd7eb6..5fcef73 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_kernel_test.dart
@@ -89,13 +89,6 @@
 
   @override
   @failingTest
-  test_async_used_as_identifier_in_suffix() async {
-    // Bad state: Expected element reference for analyzer offset 46; got one for kernel offset 48
-    await super.test_async_used_as_identifier_in_suffix();
-  }
-
-  @override
-  @failingTest
   test_async_used_as_identifier_in_switch_label() async {
     // Bad state: No reference information for async at 31
     await super.test_async_used_as_identifier_in_switch_label();
@@ -1716,48 +1709,6 @@
 
   @override
   @failingTest
-  test_invalidModifierOnSetter_member_async() async {
-    // AnalysisException: Element mismatch in /test.dart at /test.dart
-    await super.test_invalidModifierOnSetter_member_async();
-  }
-
-  @override
-  @failingTest
-  test_invalidModifierOnSetter_member_asyncStar() async {
-    // AnalysisException: Element mismatch in /test.dart at /test.dart
-    await super.test_invalidModifierOnSetter_member_asyncStar();
-  }
-
-  @override
-  @failingTest
-  test_invalidModifierOnSetter_member_syncStar() async {
-    // AnalysisException: Element mismatch in /test.dart at /test.dart
-    await super.test_invalidModifierOnSetter_member_syncStar();
-  }
-
-  @override
-  @failingTest
-  test_invalidModifierOnSetter_topLevel_async() async {
-    // AnalysisException: Element mismatch in /test.dart at /test.dart
-    await super.test_invalidModifierOnSetter_topLevel_async();
-  }
-
-  @override
-  @failingTest
-  test_invalidModifierOnSetter_topLevel_asyncStar() async {
-    // AnalysisException: Element mismatch in /test.dart at /test.dart
-    await super.test_invalidModifierOnSetter_topLevel_asyncStar();
-  }
-
-  @override
-  @failingTest
-  test_invalidModifierOnSetter_topLevel_syncStar() async {
-    // AnalysisException: Element mismatch in /test.dart at /test.dart
-    await super.test_invalidModifierOnSetter_topLevel_syncStar();
-  }
-
-  @override
-  @failingTest
   test_invalidReferenceToThis_factoryConstructor() async {
     // Expected 1 errors of type CompileTimeErrorCode.INVALID_REFERENCE_TO_THIS, found 0
     await super.test_invalidReferenceToThis_factoryConstructor();
diff --git a/pkg/analyzer/test/generated/hint_code_kernel_test.dart b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
index 7bbdb16..ef9fde2 100644
--- a/pkg/analyzer/test/generated/hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_kernel_test.dart
@@ -164,13 +164,6 @@
 
   @failingTest
   @override
-  test_importDeferredLibraryWithLoadFunction() async {
-    // ad state: Expected element reference for analyzer offset 60; got one for kernel offset 65
-    return super.test_importDeferredLibraryWithLoadFunction();
-  }
-
-  @failingTest
-  @override
   test_invalidAssignment_instanceVariable() async {
     // Expected 1 errors of type HintCode.INVALID_ASSIGNMENT, found 0
     return super.test_invalidAssignment_instanceVariable();
diff --git a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
index 6b1c577..7532ea0 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_kernel_test.dart
@@ -31,16 +31,17 @@
 
   @override
   @failingTest
-  @FastaProblem('https://github.com/dart-lang/sdk/issues/31625')
-  test_ambiguousImport_showCombinator() async {
-    return super.test_ambiguousImport_showCombinator();
+  @potentialAnalyzerProblem
+  test_abstractSuperMemberReference_superHasNoSuchMethod() async {
+    // super.m() is not resolved by front-end
+    return super.test_abstractSuperMemberReference_superHasNoSuchMethod();
   }
 
   @override
   @failingTest
-  @potentialAnalyzerProblem
-  test_assignmentToFinals_importWithPrefix() async {
-    return super.test_assignmentToFinals_importWithPrefix();
+  @FastaProblem('https://github.com/dart-lang/sdk/issues/31625')
+  test_ambiguousImport_showCombinator() async {
+    return super.test_ambiguousImport_showCombinator();
   }
 
   @override
@@ -136,13 +137,6 @@
 
   @override
   @failingTest
-  @potentialAnalyzerProblem
-  test_constEval_propertyExtraction_fieldStatic_targetType() async {
-    return super.test_constEval_propertyExtraction_fieldStatic_targetType();
-  }
-
-  @override
-  @failingTest
   @FastaProblem('https://github.com/dart-lang/sdk/issues/28434')
   test_constructorDeclaration_scope_signature() async {
     return super.test_constructorDeclaration_scope_signature();
@@ -199,7 +193,7 @@
 
   @override
   @failingTest
-  @FastaProblem('https://github.com/dart-lang/sdk/issues/30838')
+  @potentialAnalyzerProblem
   test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments() async {
     return super
         .test_genericTypeAlias_fieldAndReturnType_typeParameters_arguments();
@@ -207,7 +201,7 @@
 
   @override
   @failingTest
-  @FastaProblem('https://github.com/dart-lang/sdk/issues/30838')
+  @potentialAnalyzerProblem
   test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments() async {
     return super
         .test_genericTypeAlias_fieldAndReturnType_typeParameters_noArguments();
@@ -236,13 +230,6 @@
 
   @override
   @failingTest
-  @potentialAnalyzerProblem
-  test_importPrefixes_withFirstLetterDifference() async {
-    return super.test_importPrefixes_withFirstLetterDifference();
-  }
-
-  @override
-  @failingTest
   @FastaProblem('https://github.com/dart-lang/sdk/issues/31641')
   test_invalidAnnotation_constantVariable_field() async {
     return super.test_invalidAnnotation_constantVariable_field();
@@ -338,13 +325,6 @@
   @override
   @failingTest
   @potentialAnalyzerProblem
-  test_sharedDeferredPrefix() async {
-    return super.test_sharedDeferredPrefix();
-  }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
   test_staticAccessToInstanceMember_annotation() async {
     return super.test_staticAccessToInstanceMember_annotation();
   }
@@ -352,20 +332,6 @@
   @override
   @failingTest
   @potentialAnalyzerProblem
-  test_typeType_class_prefixed() async {
-    return super.test_typeType_class_prefixed();
-  }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
-  test_typeType_functionTypeAlias_prefixed() async {
-    return super.test_typeType_functionTypeAlias_prefixed();
-  }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
   test_undefinedIdentifier_synthetic_whenExpression() async {
     return super.test_undefinedIdentifier_synthetic_whenExpression();
   }
@@ -390,11 +356,4 @@
   test_undefinedMethod_functionExpression_directCall() async {
     return super.test_undefinedMethod_functionExpression_directCall();
   }
-
-  @override
-  @failingTest
-  @potentialAnalyzerProblem
-  test_undefinedSetter_importWithPrefix() async {
-    return super.test_undefinedSetter_importWithPrefix();
-  }
 }
diff --git a/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart b/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
index 9f45d2e..85e8b1c 100644
--- a/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_kernel_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/src/dart/error/hint_codes.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'non_hint_code_driver_test.dart';
@@ -18,6 +19,11 @@
 /// them, or know that this is an analyzer problem.
 const potentialAnalyzerProblem = const Object();
 
+/// Tests marked with this annotation fail because of a Fasta problem.
+class FastaProblem {
+  const FastaProblem(String issueUri);
+}
+
 @reflectiveTest
 class NonHintCodeTest_Kernel extends NonHintCodeTest_Driver {
   @override
@@ -52,14 +58,6 @@
     await super.test_duplicateImport_as();
   }
 
-  @failingTest
-  @override
-  @potentialAnalyzerProblem
-  test_importDeferredLibraryWithLoadFunction() async {
-    // Appears to be an issue with resolution of import prefixes.
-    await super.test_importDeferredLibraryWithLoadFunction();
-  }
-
   @override
   test_unnecessaryCast_generics() async {
     // dartbug.com/18953
@@ -76,6 +74,15 @@
     verify([source]);
   }
 
+  @override
+  @failingTest
+  @FastaProblem('https://github.com/dart-lang/sdk/issues/28434')
+  test_unusedImport_annotationOnDirective() async {
+    // TODO(scheglov) We don't yet parse annotations on import directives.
+    fail('This test fails in checked mode (indirectly)');
+//    await super.test_unusedImport_annotationOnDirective();
+  }
+
   @failingTest
   @override
   @potentialAnalyzerProblem
@@ -89,20 +96,4 @@
   test_unusedImport_metadata() async {
     await super.test_unusedImport_metadata();
   }
-
-  @failingTest
-  @override
-  @potentialAnalyzerProblem
-  test_unusedImport_prefix_topLevelFunction() async {
-    // Appears to be an issue with resolution of import prefixes.
-    await super.test_unusedImport_prefix_topLevelFunction();
-  }
-
-  @failingTest
-  @override
-  @potentialAnalyzerProblem
-  test_unusedImport_prefix_topLevelFunction2() async {
-    // Appears to be an issue with resolution of import prefixes.
-    await super.test_unusedImport_prefix_topLevelFunction2();
-  }
 }
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 9e4bdb6..eef6b16 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -55,14 +55,57 @@
 
 @reflectiveTest
 class ClassMemberParserTest_Fasta extends FastaParserTestCase
-    with ClassMemberParserTestMixin {}
+    with ClassMemberParserTestMixin {
+  @override
+  void test_parseClassMember_method_generic_comment_noReturnType() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseClassMember_method_generic_comment_parameterType() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseClassMember_method_generic_comment_returnType() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseClassMember_method_generic_comment_returnType_bound() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseClassMember_method_generic_comment_returnType_complex() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseClassMember_method_generic_comment_void() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseClassMember_method_static_generic_comment_returnType() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+}
 
 /**
  * Tests of the fasta parser based on [ComplexParserTestMixin].
  */
 @reflectiveTest
 class ComplexParserTest_Fasta extends FastaParserTestCase
-    with ComplexParserTestMixin {}
+    with ComplexParserTestMixin {
+  @override
+  @failingTest
+  void test_assignableExpression_arguments_normal_chain_typeArgumentComments() {
+    // Fasta does not support the generic comment syntax.
+    super
+        .test_assignableExpression_arguments_normal_chain_typeArgumentComments();
+  }
+}
 
 /**
  * Tests of the fasta parser based on [ErrorParserTest].
@@ -715,14 +758,6 @@
 
   @override
   @failingTest
-  void test_invalidOperatorAfterSuper_assignableExpression() {
-    // TODO(brianwilkerson) Wrong errors:
-    // Expected 1 errors of type ParserErrorCode.INVALID_OPERATOR_FOR_SUPER, found 0
-    super.test_invalidOperatorAfterSuper_assignableExpression();
-  }
-
-  @override
-  @failingTest
   void test_invalidOperatorAfterSuper_primaryExpression() {
     // TODO(brianwilkerson) Does not recover.
     //   Expected: true
@@ -1698,6 +1733,81 @@
 class ExpressionParserTest_Fasta extends FastaParserTestCase
     with ExpressionParserTestMixin {
   @override
+  void
+      test_parseAssignableExpression_expression_args_dot_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void
+      test_parseAssignableExpression_identifier_args_dot_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseCascadeSection_ia_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseCascadeSection_ii_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseCascadeSection_pa_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseCascadeSection_paa_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseCascadeSection_paapaa_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseConstExpression_listLiteral_typed_genericComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseConstExpression_mapLiteral_typed_genericComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseExpression_superMethodInvocation_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void
+      test_parseExpressionWithoutCascade_superMethodInvocation_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseFunctionExpression_typeParameterComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void
+      test_parseInstanceCreationExpression_qualifiedType_named_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void
+      test_parseInstanceCreationExpression_qualifiedType_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
   @failingTest
   void test_parseInstanceCreationExpression_type_named_typeArgumentComments() {
     // TODO(brianwilkerson) Does not inject generic type arguments.
@@ -1706,6 +1816,33 @@
   }
 
   @override
+  void test_parseInstanceCreationExpression_type_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void
+      test_parsePostfixExpression_none_methodInvocation_question_dot_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void
+      test_parsePostfixExpression_none_methodInvocation_typeArgumentComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parsePrimaryExpression_listLiteral_typed_genericComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parsePrimaryExpression_mapLiteral_typed_genericComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
   @failingTest
   void test_parseUnaryExpression_decrement_super() {
     // TODO(brianwilkerson) Does not recover.
@@ -1742,7 +1879,8 @@
   /**
    * Whether generic method comments should be enabled for the test.
    */
-  bool enableGenericMethodComments = false;
+  bool get enableGenericMethodComments => false;
+  void set enableGenericMethodComments(bool enable) {}
 
   @override
   set enableLazyAssignmentOperators(bool value) {
@@ -2216,6 +2354,21 @@
   }
 
   @override
+  void test_parseNormalFormalParameter_function_noType_typeParameterComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseNormalFormalParameter_function_type_typeParameterComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseNormalFormalParameter_function_void_typeParameterComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
   @failingTest
   void test_parseNormalFormalParameter_simple_const_noType() {
     // TODO(brianwilkerson) Wrong errors:
@@ -2547,13 +2700,6 @@
 
   @override
   @failingTest
-  void test_incompleteForEach() {
-    // TODO(brianwilkerson) reportUnrecoverableErrorWithToken
-    super.test_incompleteForEach();
-  }
-
-  @override
-  @failingTest
   void test_incompleteLocalVariable_beforeIdentifier() {
     // TODO(brianwilkerson) reportUnrecoverableErrorWithToken
     super.test_incompleteLocalVariable_beforeIdentifier();
@@ -2707,6 +2853,42 @@
     // Expected 1 errors of type ParserErrorCode.CONTINUE_OUTSIDE_OF_LOOP, found 0
     super.test_parseContinueStatement_noLabel();
   }
+
+  @override
+  void test_parseFunctionDeclarationStatement_typeParameterComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void
+      test_parseStatement_functionDeclaration_noReturnType_typeParameterComments() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseVariableDeclarationListAfterMetadata_const_typeComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseVariableDeclarationListAfterMetadata_dynamic_typeComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseVariableDeclarationListAfterMetadata_final_typeComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseVariableDeclarationListAfterMetadata_type_typeComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseVariableDeclarationListAfterMetadata_var_typeComment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
 }
 
 /**
@@ -2800,4 +2982,14 @@
     super.test_parseCompilationUnitMember_abstractAsPrefix();
     assertNoErrors();
   }
+
+  @override
+  void test_parseFunctionDeclaration_functionWithTypeParameters_comment() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
+
+  @override
+  void test_parseFunctionDeclaration_getter_generic_comment_returnType() {
+    // Ignored: Fasta does not support the generic comment syntax.
+  }
 }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index d0e036d..809fa22 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -834,6 +834,32 @@
     expect(method.body, isNotNull);
   }
 
+  void test_parseClassMember_method_generic_parameterType() {
+    createParser('m<T>(T p) => null;');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertNoErrors();
+    expect(member, new isInstanceOf<MethodDeclaration>());
+    MethodDeclaration method = member;
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNull);
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+
+    FormalParameterList parameters = method.parameters;
+    expect(parameters, isNotNull);
+    expect(parameters.parameters, hasLength(1));
+    var parameter = parameters.parameters[0] as SimpleFormalParameter;
+    var parameterType = parameter.type as TypeName;
+    expect(parameterType.name.name, 'T');
+
+    expect(method.body, isNotNull);
+  }
+
   void test_parseClassMember_method_generic_returnType() {
     createParser('T m<T>() {}');
     ClassMember member = parser.parseClassMember('C');
@@ -853,6 +879,79 @@
     expect(method.body, isNotNull);
   }
 
+  void test_parseClassMember_method_generic_returnType_bound() {
+    createParser('T m<T extends num>() {}');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertNoErrors();
+    expect(member, new isInstanceOf<MethodDeclaration>());
+    MethodDeclaration method = member;
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+    expect((method.returnType as TypeName).name.name, 'T');
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    TypeParameter tp = method.typeParameters.typeParameters[0];
+    expect(tp.name.name, 'T');
+    expect(tp.extendsKeyword, isNotNull);
+    expect((tp.bound as TypeName).name.name, 'num');
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_returnType_complex() {
+    createParser('Map<int, T> m<T>() => null;');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertNoErrors();
+    expect(member, new isInstanceOf<MethodDeclaration>());
+    MethodDeclaration method = member;
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNull);
+    expect(method.propertyKeyword, isNull);
+
+    {
+      var returnType = method.returnType as TypeName;
+      expect(returnType, isNotNull);
+      expect(returnType.name.name, 'Map');
+
+      List<TypeAnnotation> typeArguments = returnType.typeArguments.arguments;
+      expect(typeArguments, hasLength(2));
+      expect((typeArguments[0] as TypeName).name.name, 'int');
+      expect((typeArguments[1] as TypeName).name.name, 'T');
+    }
+
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
+  void test_parseClassMember_method_generic_returnType_static() {
+    createParser('static T m<T>() {}');
+    ClassMember member = parser.parseClassMember('C');
+    expect(member, isNotNull);
+    assertNoErrors();
+    expect(member, new isInstanceOf<MethodDeclaration>());
+    MethodDeclaration method = member;
+    expect(method.documentationComment, isNull);
+    expect(method.externalKeyword, isNull);
+    expect(method.modifierKeyword, isNotNull);
+    expect(method.propertyKeyword, isNull);
+    expect(method.returnType, isNotNull);
+    expect((method.returnType as TypeName).name.name, 'T');
+    expect(method.name, isNotNull);
+    expect(method.operatorKeyword, isNull);
+    expect(method.typeParameters, isNotNull);
+    expect(method.parameters, isNotNull);
+    expect(method.body, isNotNull);
+  }
+
   void test_parseClassMember_method_generic_void() {
     createParser('void m<T>() {}');
     ClassMember member = parser.parseClassMember('C');
@@ -4659,6 +4758,21 @@
                   ]);
   }
 
+  void test_switchCase_missingColon() {
+    SwitchStatement statement = parseStatement('switch (a) {case 1 return 0;}');
+    expect(statement, isNotNull);
+    listener
+        .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 19, 6)]);
+  }
+
+  void test_switchDefault_missingColon() {
+    SwitchStatement statement =
+        parseStatement('switch (a) {default return 0;}');
+    expect(statement, isNotNull);
+    listener
+        .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 6)]);
+  }
+
   void test_switchHasCaseAfterDefaultCase() {
     SwitchStatement statement =
         parseStatement('switch (a) {default: return 0; case 1: return 1;}');
@@ -4697,21 +4811,6 @@
     ]);
   }
 
-  void test_switchCase_missingColon() {
-    SwitchStatement statement = parseStatement('switch (a) {case 1 return 0;}');
-    expect(statement, isNotNull);
-    listener
-        .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 19, 6)]);
-  }
-
-  void test_switchDefault_missingColon() {
-    SwitchStatement statement =
-        parseStatement('switch (a) {default return 0;}');
-    expect(statement, isNotNull);
-    listener
-        .assertErrors([expectedError(ParserErrorCode.EXPECTED_TOKEN, 20, 6)]);
-  }
-
   void test_switchMissingBlock() {
     SwitchStatement statement =
         parseStatement('switch (a) return;', expectedEndOffset: 11);
@@ -10502,7 +10601,8 @@
     ForStatement statement = parseStatement('for (String item i) {}');
     listener.assertErrors([
       expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1),
-      expectedError(ParserErrorCode.EXPECTED_TOKEN, 17, 1)
+      expectedError(
+          ParserErrorCode.EXPECTED_TOKEN, usingFastaParser ? 18 : 17, 1)
     ]);
     expect(statement, new isInstanceOf<ForStatement>());
     expect(statement.toSource(), 'for (String item; i;) {}');
diff --git a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
index 8947061..9439e01 100644
--- a/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
+++ b/pkg/analyzer/test/generated/strong_mode_kernel_test.dart
@@ -221,27 +221,6 @@
 
   @override
   @failingTest
-  test_futureOrNull_no_return() async {
-    // Bad state: Found 2 argument types for 1 type arguments
-    await super.test_futureOrNull_no_return();
-  }
-
-  @override
-  @failingTest
-  test_futureOrNull_no_return_value() async {
-    // Bad state: Found 2 argument types for 1 type arguments
-    await super.test_futureOrNull_no_return_value();
-  }
-
-  @override
-  @failingTest
-  test_futureOrNull_return_null() async {
-    // Bad state: Found 2 argument types for 1 type arguments
-    await super.test_futureOrNull_return_null();
-  }
-
-  @override
-  @failingTest
   test_generic_partial() async {
     // AnalysisException: Element mismatch in /test.dart at class A<T>
     await super.test_generic_partial();
@@ -298,27 +277,6 @@
 
   @override
   @failingTest
-  test_inference_simplePolymorphicRecursion_function() async {
-    // Expected: 'T'
-    await super.test_inference_simplePolymorphicRecursion_function();
-  }
-
-  @override
-  @failingTest
-  test_inference_simplePolymorphicRecursion_interface() async {
-    // Expected: 'T'
-    await super.test_inference_simplePolymorphicRecursion_interface();
-  }
-
-  @override
-  @failingTest
-  test_inference_simplePolymorphicRecursion_simple() async {
-    // RangeError (index): Invalid value: Valid value range is empty: 0
-    await super.test_inference_simplePolymorphicRecursion_simple();
-  }
-
-  @override
-  @failingTest
   test_inferGenericInstantiation2() async {
     // Expected 1 errors of type StrongModeCode.STRONG_MODE_COULD_NOT_INFER, found 0;
     //          1 errors of type StaticWarningCode.ARGUMENT_TYPE_NOT_ASSIGNABLE, found 0
@@ -434,13 +392,6 @@
 
   @override
   @failingTest
-  test_genericMethod_max_doubleDouble_prefixed() async {
-    // Bad state: Expected element reference for analyzer offset 49; got one for kernel offset 54
-    await super.test_genericMethod_max_doubleDouble_prefixed();
-  }
-
-  @override
-  @failingTest
   test_genericMethod_nestedCapture() async {
     // Bad state: Found 2 argument types for 1 type arguments
     await super.test_genericMethod_nestedCapture();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
index 7dd81a7..e1a6eee 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_kernel_test.dart
@@ -25,18 +25,6 @@
 
   @override
   @failingTest
-  @potentialAnalyzerProblem
-  test_annotation_constructor_withNestedConstructorInvocation() async {
-    // This test is failing because analyzer and kernel disagree about how to
-    // resolve annotations and constructors. Kernel is consistent between
-    // annotations that invoke a constructor and other constructor invocations,
-    // while analyzer treats them differently. They also differ in terms of the
-    // resolution of the constructor name's element.
-    await super.test_annotation_constructor_withNestedConstructorInvocation();
-  }
-
-  @override
-  @failingTest
   @FastaProblem('https://github.com/dart-lang/sdk/issues/31605')
   test_constructor_redirected_generic() async {
     await super.test_constructor_redirected_generic();
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
index 09dbb38..7331a7d 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_test.dart
@@ -186,12 +186,19 @@
     var atD = AstFinder.getTopLevelFunction(result.unit, 'f').metadata[0];
     InstanceCreationExpression constC = atD.arguments.arguments[0];
 
-    expect(atD.name.staticElement, elementD);
-    expect(atD.element, constructorD);
+    if (previewDart2) {
+      expect(atD.name.staticElement, constructorD);
+      expect(atD.element, constructorD);
+    } else {
+      expect(atD.name.staticElement, elementD);
+      expect(atD.element, constructorD);
+    }
 
     expect(constC.staticElement, constructorC);
     expect(constC.staticType, elementC.type);
+
     expect(constC.constructorName.staticElement, constructorC);
+    expect(constC.constructorName.type.type, elementC.type);
   }
 
   test_annotation_kind_reference() async {
@@ -1355,14 +1362,10 @@
       expect(initializer.constructorName, isNull);
 
       List<Expression> arguments = initializer.argumentList.arguments;
-
-      Expression aArgument = arguments[0];
-      ParameterElement aElement = unnamedConstructor.parameters[0];
-      expect(aArgument.staticParameterElement, same(aElement));
-
-      Expression bArgument = arguments[1];
-      ParameterElement bElement = unnamedConstructor.parameters[1];
-      expect(bArgument.staticParameterElement, same(bElement));
+      _assertArgumentToParameter(
+          arguments[0], unnamedConstructor.parameters[0]);
+      _assertArgumentToParameter(
+          arguments[1], unnamedConstructor.parameters[1]);
     }
 
     {
@@ -1378,15 +1381,8 @@
       expect(constructorName.staticType, isNull);
 
       List<Expression> arguments = initializer.argumentList.arguments;
-
-      Expression aArgument = arguments[0];
-      ParameterElement aElement = namedConstructor.parameters[0];
-      expect(aArgument.staticParameterElement, same(aElement));
-
-      NamedExpression bArgument = arguments[1];
-      ParameterElement bElement = namedConstructor.parameters[1];
-      expect(bArgument.name.label.staticElement, same(bElement));
-      expect(bArgument.staticParameterElement, same(bElement));
+      _assertArgumentToParameter(arguments[0], namedConstructor.parameters[0]);
+      _assertArgumentToParameter(arguments[1], namedConstructor.parameters[1]);
     }
   }
 
@@ -1833,19 +1829,9 @@
 
     expect(creation.constructorName.name, isNull);
 
-    Expression aArgument = arguments[0];
-    ParameterElement aElement = constructorElement.parameters[0];
-    expect(aArgument.staticParameterElement, same(aElement));
-
-    NamedExpression bArgument = arguments[1];
-    ParameterElement bElement = constructorElement.parameters[1];
-    expect(bArgument.name.label.staticElement, same(bElement));
-    expect(bArgument.staticParameterElement, same(bElement));
-
-    NamedExpression cArgument = arguments[2];
-    ParameterElement cElement = constructorElement.parameters[2];
-    expect(cArgument.name.label.staticElement, same(cElement));
-    expect(cArgument.staticParameterElement, same(cElement));
+    _assertArgumentToParameter(arguments[0], constructorElement.parameters[0]);
+    _assertArgumentToParameter(arguments[1], constructorElement.parameters[1]);
+    _assertArgumentToParameter(arguments[2], constructorElement.parameters[2]);
   }
 
   test_instanceCreation_noTypeArguments() async {
@@ -1884,7 +1870,7 @@
       expect(value.constructorName.name, isNull);
 
       Expression argument = value.argumentList.arguments[0];
-      expect(argument.staticParameterElement, defaultConstructor.parameters[0]);
+      _assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
     }
 
     {
@@ -1906,7 +1892,7 @@
       expect(constructorName.staticType, isNull);
 
       Expression argument = value.argumentList.arguments[0];
-      expect(argument.staticParameterElement, namedConstructor.parameters[0]);
+      _assertArgumentToParameter(argument, namedConstructor.parameters[0]);
     }
   }
 
@@ -1960,7 +1946,7 @@
       expect(value.constructorName.name, isNull);
 
       Expression argument = value.argumentList.arguments[0];
-      expect(argument.staticParameterElement, defaultConstructor.parameters[0]);
+      _assertArgumentToParameter(argument, defaultConstructor.parameters[0]);
     }
 
     {
@@ -1995,7 +1981,7 @@
       expect(constructorName.staticType, isNull);
 
       Expression argument = value.argumentList.arguments[0];
-      expect(argument.staticParameterElement, namedConstructor.parameters[0]);
+      _assertArgumentToParameter(argument, namedConstructor.parameters[0]);
     }
   }
 
@@ -2284,19 +2270,9 @@
       MethodInvocation invocation = statement.expression;
       List<Expression> arguments = invocation.argumentList.arguments;
 
-      Expression aArgument = arguments[0];
-      ParameterElement aElement = fElement.parameters[0];
-      expect(aArgument.staticParameterElement, same(aElement));
-
-      NamedExpression bArgument = arguments[1];
-      ParameterElement bElement = fElement.parameters[1];
-      expect(bArgument.name.label.staticElement, same(bElement));
-      expect(bArgument.staticParameterElement, same(bElement));
-
-      NamedExpression cArgument = arguments[2];
-      ParameterElement cElement = fElement.parameters[2];
-      expect(cArgument.name.label.staticElement, same(cElement));
-      expect(cArgument.staticParameterElement, same(cElement));
+      _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+      _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+      _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
     }
   }
 
@@ -2394,18 +2370,9 @@
       expect(invocation.staticInvokeType.toString(), fTypeString);
 
       List<Expression> arguments = invocation.argumentList.arguments;
-
-      Expression aArgument = arguments[0];
-      ParameterElement aElement = fElement.parameters[0];
-      expect(aArgument.staticParameterElement, same(aElement));
-
-      Expression bArgument = arguments[1];
-      ParameterElement bElement = fElement.parameters[1];
-      expect(bArgument.staticParameterElement, same(bElement));
-
-      Expression cArgument = arguments[2];
-      ParameterElement cElement = fElement.parameters[2];
-      expect(cArgument.staticParameterElement, same(cElement));
+      _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+      _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+      _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
     }
   }
 
@@ -2902,21 +2869,11 @@
     BlockFunctionBody body = functionDeclaration.functionExpression.body;
     ExpressionStatement statement = body.block.statements[0];
     MethodInvocation invocation = statement.expression;
+
     List<Expression> arguments = invocation.argumentList.arguments;
-
-    Expression aArgument = arguments[0];
-    ParameterElement aElement = methodElement.parameters[0];
-    expect(aArgument.staticParameterElement, same(aElement));
-
-    NamedExpression bArgument = arguments[1];
-    ParameterElement bElement = methodElement.parameters[1];
-    expect(bArgument.name.label.staticElement, same(bElement));
-    expect(bArgument.staticParameterElement, same(bElement));
-
-    NamedExpression cArgument = arguments[2];
-    ParameterElement cElement = methodElement.parameters[2];
-    expect(cArgument.name.label.staticElement, same(cElement));
-    expect(cArgument.staticParameterElement, same(cElement));
+    _assertArgumentToParameter(arguments[0], methodElement.parameters[0]);
+    _assertArgumentToParameter(arguments[1], methodElement.parameters[1]);
+    _assertArgumentToParameter(arguments[2], methodElement.parameters[2]);
   }
 
   test_methodInvocation_instanceMethod_forwardingStub() async {
@@ -2973,13 +2930,13 @@
       expect(invocation.staticType.toString(), 'void');
       expect(invocation.staticInvokeType.toString(), invokeTypeStr);
       if (previewDart2) {
-        expect(invocation.staticInvokeType.element, same(mElement));
         expect(invocation.methodName.staticElement, same(mElement));
         expect(invocation.methodName.staticType.toString(), invokeTypeStr);
+      } else {
+        expect(invocation.staticInvokeType.element, same(mElement));
       }
 
-      Expression argument = arguments[0];
-      expect(argument.staticParameterElement, mElement.parameters[0]);
+      _assertArgumentToParameter(arguments[0], mElement.parameters[0]);
     }
   }
 
@@ -3009,23 +2966,23 @@
       expect(invocation.staticType.toString(), 'Map<int, double>');
       expect(invocation.staticInvokeType.toString(), invokeTypeStr);
       if (previewDart2) {
-        expect(invocation.staticInvokeType.element, same(mElement));
         expect(invocation.methodName.staticElement, same(mElement));
         expect(invocation.methodName.staticType.toString(), invokeTypeStr);
       }
 
-      Expression aArgument = arguments[0];
-      ParameterMember aArgumentParameter = aArgument.staticParameterElement;
-      ParameterElement aElement = mElement.parameters[0];
-      expect(aArgumentParameter.type, typeProvider.intType);
-      expect(aArgumentParameter.baseElement, same(aElement));
-
-      Expression bArgument = arguments[1];
-      ParameterMember bArgumentParameter = bArgument.staticParameterElement;
-      ParameterElement bElement = mElement.parameters[1];
-      expect(bArgumentParameter.type, typeProvider.doubleType);
       if (previewDart2) {
-        expect(bArgumentParameter.baseElement, same(bElement));
+        expect(arguments[0].staticParameterElement, isNull);
+        expect(arguments[1].staticParameterElement, isNull);
+      } else {
+        Expression aArgument = arguments[0];
+        ParameterMember aArgumentParameter = aArgument.staticParameterElement;
+        ParameterElement aElement = mElement.parameters[0];
+        expect(aArgumentParameter.type, typeProvider.intType);
+        expect(aArgumentParameter.baseElement, same(aElement));
+
+        Expression bArgument = arguments[1];
+        ParameterMember bArgumentParameter = bArgument.staticParameterElement;
+        expect(bArgumentParameter.type, typeProvider.doubleType);
       }
     }
   }
@@ -3047,19 +3004,9 @@
     MethodInvocation invocation = statement.expression;
     List<Expression> arguments = invocation.argumentList.arguments;
 
-    Expression aArgument = arguments[0];
-    ParameterElement aElement = fooElement.parameters[0];
-    expect(aArgument.staticParameterElement, same(aElement));
-
-    NamedExpression bArgument = arguments[1];
-    ParameterElement bElement = fooElement.parameters[1];
-    expect(bArgument.name.label.staticElement, same(bElement));
-    expect(bArgument.staticParameterElement, same(bElement));
-
-    NamedExpression cArgument = arguments[2];
-    ParameterElement cElement = fooElement.parameters[2];
-    expect(cArgument.name.label.staticElement, same(cElement));
-    expect(cArgument.staticParameterElement, same(cElement));
+    _assertArgumentToParameter(arguments[0], fooElement.parameters[0]);
+    _assertArgumentToParameter(arguments[1], fooElement.parameters[1]);
+    _assertArgumentToParameter(arguments[2], fooElement.parameters[2]);
   }
 
   test_methodInvocation_notFunction_field_dynamic() async {
@@ -3086,13 +3033,15 @@
     ExpressionStatement statement = fooStatements[0];
     MethodInvocation invocation = statement.expression;
     expect(invocation.methodName.staticElement, same(fElement.getter));
-    expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+    if (previewDart2) {
+      _assertDynamicFunctionType(invocation.staticInvokeType);
+    } else {
+      expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+    }
     expect(invocation.staticType, DynamicTypeImpl.instance);
 
     List<Expression> arguments = invocation.argumentList.arguments;
-
-    Expression argument = arguments[0];
-    expect(argument.staticParameterElement, isNull);
+    expect(arguments[0].staticParameterElement, isNull);
   }
 
   test_methodInvocation_notFunction_getter_dynamic() async {
@@ -3118,7 +3067,11 @@
     ExpressionStatement statement = fooStatements[0];
     MethodInvocation invocation = statement.expression;
     expect(invocation.methodName.staticElement, same(fElement));
-    expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+    if (previewDart2) {
+      _assertDynamicFunctionType(invocation.staticInvokeType);
+    } else {
+      expect(invocation.staticInvokeType, DynamicTypeImpl.instance);
+    }
     expect(invocation.staticType, DynamicTypeImpl.instance);
 
     List<Expression> arguments = invocation.argumentList.arguments;
@@ -3177,9 +3130,8 @@
     expect(invocation.staticType, typeProvider.stringType);
 
     List<Expression> arguments = invocation.argumentList.arguments;
-
-    Expression argument = arguments[0];
-    expect(argument.staticParameterElement, isNotNull);
+    _assertArgumentToParameter(
+        arguments[0], (fElement.type as FunctionType).parameters[0]);
   }
 
   test_methodInvocation_notFunction_topLevelVariable_dynamic() async {
@@ -3241,12 +3193,14 @@
       var invokeTypeStr = '(int) → void';
       expect(invocation.staticType.toString(), 'void');
       expect(invocation.staticInvokeType.toString(), invokeTypeStr);
-      expect(invocation.staticInvokeType.element, same(mElement));
+      if (!previewDart2) {
+        expect(invocation.staticInvokeType.element, same(mElement));
+      }
       expect(invocation.methodName.staticElement, same(mElement));
       expect(invocation.methodName.staticType.toString(), invokeTypeStr);
 
       Expression argument = arguments[0];
-      expect(argument.staticParameterElement, mElement.parameters[0]);
+      _assertArgumentToParameter(argument, mElement.parameters[0]);
     }
 
     {
@@ -3263,12 +3217,14 @@
       var invokeTypeStr = '(int) → void';
       expect(invocation.staticType.toString(), 'void');
       expect(invocation.staticInvokeType.toString(), invokeTypeStr);
-      expect(invocation.staticInvokeType.element, same(mElement));
+      if (!previewDart2) {
+        expect(invocation.staticInvokeType.element, same(mElement));
+      }
       expect(invocation.methodName.staticElement, same(mElement));
       expect(invocation.methodName.staticType.toString(), invokeTypeStr);
 
       Expression argument = arguments[0];
-      expect(argument.staticParameterElement, mElement.parameters[0]);
+      _assertArgumentToParameter(argument, mElement.parameters[0]);
     }
   }
 
@@ -3322,13 +3278,8 @@
     expect(invocation.staticType, same(doubleType));
     expect(invocation.staticInvokeType.toString(), fTypeString);
 
-    Expression aArgument = arguments[0];
-    ParameterElement aElement = fElement.parameters[0];
-    expect(aArgument.staticParameterElement, same(aElement));
-
-    Expression bArgument = arguments[1];
-    ParameterElement bElement = fElement.parameters[1];
-    expect(bArgument.staticParameterElement, same(bElement));
+    _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+    _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
   }
 
   test_methodInvocation_topLevelFunction_generic() async {
@@ -3378,21 +3329,10 @@
       expect(invocation.staticType, VoidTypeImpl.instance);
       expect(invocation.staticInvokeType.toString(), fTypeString);
 
-      Expression aArgument = arguments[0];
-      ParameterMember aArgumentParameter = aArgument.staticParameterElement;
-      ParameterElement aElement = fElement.parameters[0];
-      expect(aArgumentParameter.type, typeProvider.boolType);
-      if (previewDart2) {
-        expect(aArgumentParameter.baseElement, same(aElement));
-      }
-
-      Expression bArgument = arguments[1];
-      ParameterMember bArgumentParameter = bArgument.staticParameterElement;
-      ParameterElement bElement = fElement.parameters[1];
-      expect(bArgumentParameter.type, typeProvider.stringType);
-      if (previewDart2) {
-        expect(bArgumentParameter.baseElement, same(bElement));
-      }
+      _assertArgumentToParameter(arguments[0], fElement.parameters[0],
+          parameterMemberType: typeProvider.boolType);
+      _assertArgumentToParameter(arguments[1], fElement.parameters[1],
+          parameterMemberType: typeProvider.stringType);
     }
 
     // f(1, 2.3);
@@ -3409,21 +3349,10 @@
       expect(invocation.staticType, VoidTypeImpl.instance);
       expect(invocation.staticInvokeType.toString(), fTypeString);
 
-      Expression aArgument = arguments[0];
-      ParameterMember aArgumentParameter = aArgument.staticParameterElement;
-      ParameterElement aElement = fElement.parameters[0];
-      expect(aArgumentParameter.type, typeProvider.intType);
-      if (previewDart2) {
-        expect(aArgumentParameter.baseElement, same(aElement));
-      }
-
-      Expression bArgument = arguments[1];
-      ParameterMember bArgumentParameter = bArgument.staticParameterElement;
-      ParameterElement bElement = fElement.parameters[1];
-      expect(bArgumentParameter.type, typeProvider.doubleType);
-      if (previewDart2) {
-        expect(bArgumentParameter.baseElement, same(bElement));
-      }
+      _assertArgumentToParameter(arguments[0], fElement.parameters[0],
+          parameterMemberType: typeProvider.intType);
+      _assertArgumentToParameter(arguments[1], fElement.parameters[1],
+          parameterMemberType: typeProvider.doubleType);
     }
   }
 
@@ -4852,19 +4781,9 @@
     MethodInvocation invocation = statement.expression;
     List<Expression> arguments = invocation.argumentList.arguments;
 
-    Expression aArgument = arguments[0];
-    ParameterElement aElement = fElement.parameters[0];
-    expect(aArgument.staticParameterElement, same(aElement));
-
-    NamedExpression bArgument = arguments[1];
-    ParameterElement bElement = fElement.parameters[1];
-    expect(bArgument.name.label.staticElement, same(bElement));
-    expect(bArgument.staticParameterElement, same(bElement));
-
-    NamedExpression cArgument = arguments[2];
-    ParameterElement cElement = fElement.parameters[2];
-    expect(cArgument.name.label.staticElement, same(cElement));
-    expect(cArgument.staticParameterElement, same(cElement));
+    _assertArgumentToParameter(arguments[0], fElement.parameters[0]);
+    _assertArgumentToParameter(arguments[1], fElement.parameters[1]);
+    _assertArgumentToParameter(arguments[2], fElement.parameters[2]);
   }
 
   test_top_functionTypeAlias() async {
@@ -5141,6 +5060,39 @@
     }
   }
 
+  /// Assert that the [argument] is associated with the [expectedParameter],
+  /// if [previewDart2] is `null`. If the [argument] is a [NamedExpression],
+  /// the name must be resolved to the parameter in both cases.
+  void _assertArgumentToParameter(
+      Expression argument, ParameterElement expectedParameter,
+      {DartType parameterMemberType}) {
+    ParameterElement actualParameter = argument.staticParameterElement;
+    if (previewDart2) {
+      expect(actualParameter, isNull);
+    } else {
+      ParameterElement baseActualParameter;
+      if (actualParameter is ParameterMember) {
+        if (parameterMemberType != null) {
+          expect(actualParameter.type, parameterMemberType);
+        }
+        baseActualParameter = actualParameter.baseElement;
+        // Unwrap ParameterMember one more time.
+        // By some reason we wrap in twice.
+        if (baseActualParameter is ParameterMember) {
+          ParameterMember member = baseActualParameter;
+          baseActualParameter = member.baseElement;
+        }
+      } else {
+        baseActualParameter = actualParameter;
+      }
+      expect(baseActualParameter, same(expectedParameter));
+      // TODO(scheglov) Make this work for previewDart2 too.
+      if (argument is NamedExpression) {
+        expect(argument.name.label.staticElement, same(expectedParameter));
+      }
+    }
+  }
+
   void _assertDefaultParameter(
       DefaultFormalParameter node, ParameterElement element,
       {String name, int offset, ParameterKind kind, DartType type}) {
@@ -5150,6 +5102,12 @@
         name: name, offset: offset, kind: kind, type: type);
   }
 
+  /// Assert that the [type] is a function type `() -> dynamic`.
+  void _assertDynamicFunctionType(FunctionType type) {
+    expect(type.parameters, isEmpty);
+    expect(type.returnType, DynamicTypeImpl.instance);
+  }
+
   void _assertParameterElement(ParameterElement element,
       {String name, int offset, ParameterKind kind, DartType type}) {
     expect(element, isNotNull);
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
new file mode 100644
index 0000000..f8078ad
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/annotation_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
+
+import 'partial_code_support.dart';
+
+main() {
+  new AnnotationTest().buildAll();
+}
+
+class AnnotationTest extends PartialCodeTest {
+  buildAll() {
+    List<TestDescriptor> descriptors = <TestDescriptor>[
+      new TestDescriptor(
+          'ampersand', '@', [ParserErrorCode.MISSING_IDENTIFIER], '@_s_',
+          allFailing: true),
+      new TestDescriptor(
+          'leftParen', '@a(', [ParserErrorCode.EXPECTED_TOKEN], '@a()',
+          allFailing: true),
+    ];
+    buildTests('annotation_topLevel', descriptors,
+        PartialCodeTest.declarationSuffixes);
+    buildTests('annotation_classMember', descriptors,
+        PartialCodeTest.classMemberSuffixes,
+        head: 'class C { ', tail: ' }');
+    buildTests(
+        'annotation_local', descriptors, PartialCodeTest.statementSuffixes,
+        head: 'f() { ', tail: ' }');
+  }
+}
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 102cb02..e714b32 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
@@ -4,6 +4,7 @@
 
 import 'package:test/test.dart';
 
+import 'annotation_test.dart' as annotation;
 import 'assert_statement_test.dart' as assert_statement;
 import 'break_statement_test.dart' as break_statement;
 import 'class_declaration_test.dart' as class_declaration;
@@ -23,11 +24,13 @@
 import 'return_statement_test.dart' as return_statement;
 import 'switch_statement_test.dart' as switch_statement;
 import 'top_level_variable_test.dart' as top_level_variable;
+import 'try_statement_test.dart' as try_statement;
 import 'while_statement_test.dart' as while_statement;
 import 'yield_statement_test.dart' as yield_statement;
 
 main() {
   group('partial_code', () {
+    annotation.main();
     assert_statement.main();
     break_statement.main();
     class_declaration.main();
@@ -47,6 +50,7 @@
     return_statement.main();
     switch_statement.main();
     top_level_variable.main();
+    try_statement.main();
     while_statement.main();
     yield_statement.main();
   });
diff --git a/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
new file mode 100644
index 0000000..a6c927d
--- /dev/null
+++ b/pkg/analyzer/test/src/fasta/recovery/partial_code/try_statement_test.dart
@@ -0,0 +1,164 @@
+// 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 TryStatementTest().buildAll();
+}
+
+class TryStatementTest extends PartialCodeTest {
+  buildAll() {
+    buildTests(
+        'try_statement',
+        [
+          //
+          // No clauses.
+          //
+          new TestDescriptor(
+              'keyword',
+              'try',
+              [
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_CATCH_OR_FINALLY
+              ],
+              "try {} finally {}",
+              allFailing: true),
+          new TestDescriptor('noCatchOrFinally', 'try {}',
+              [ParserErrorCode.MISSING_CATCH_OR_FINALLY], "try {} finally {}",
+              allFailing: true),
+          //
+          // Single on clause.
+          //
+          new TestDescriptor(
+              'on',
+              'try {} on',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "try {} on _s_ {}",
+              allFailing: true),
+          new TestDescriptor('on_identifier', 'try {} on A',
+              [ParserErrorCode.EXPECTED_TOKEN], "try {} on A {}",
+              failing: ['block']),
+          //
+          // Single catch clause.
+          //
+          new TestDescriptor(
+              'catch',
+              'try {} catch',
+              [
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "try {} catch (e) {}",
+              allFailing: true),
+          new TestDescriptor(
+              'catch_leftParen',
+              'try {} catch (',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "try {} catch (e) {}",
+              allFailing: true),
+          new TestDescriptor(
+              'catch_identifier',
+              'try {} catch (e',
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              "try {} catch (e) {}",
+              allFailing: true),
+          new TestDescriptor(
+              'catch_identifierComma',
+              'try {} catch (e, ',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "try {} catch (e, _s_) {}",
+              allFailing: true),
+          new TestDescriptor(
+              'catch_identifierCommaIdentifier',
+              'try {} catch (e, s',
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              "try {} catch (e, s) {}",
+              allFailing: true),
+          new TestDescriptor('catch_rightParen', 'try {} catch (e, s)',
+              [ParserErrorCode.EXPECTED_TOKEN], "try {} catch (e, s) {}",
+              failing: ['block']),
+          //
+          // Single catch clause after an on clause.
+          //
+          new TestDescriptor(
+              'on_catch',
+              'try {} on A catch',
+              [
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "try {} on A catch (e) {}",
+              allFailing: true),
+          new TestDescriptor(
+              'on_catch_leftParen',
+              'try {} on A catch (',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "try {} on A catch (e) {}",
+              allFailing: true),
+          new TestDescriptor(
+              'on_catch_identifier',
+              'try {} on A catch (e',
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              "try {} on A catch (e) {}",
+              allFailing: true),
+          new TestDescriptor(
+              'on_catch_identifierComma',
+              'try {} on A catch (e, ',
+              [
+                ParserErrorCode.MISSING_IDENTIFIER,
+                ParserErrorCode.EXPECTED_TOKEN,
+                ParserErrorCode.EXPECTED_TOKEN
+              ],
+              "try {} on A catch (e, _s_) {}",
+              allFailing: true),
+          new TestDescriptor(
+              'on_catch_identifierCommaIdentifier',
+              'try {} on A catch (e, s',
+              [ParserErrorCode.EXPECTED_TOKEN, ParserErrorCode.EXPECTED_TOKEN],
+              "try {} on A catch (e, s) {}",
+              allFailing: true),
+          new TestDescriptor('on_catch_rightParen', 'try {} on A catch (e, s)',
+              [ParserErrorCode.EXPECTED_TOKEN], "try {} on A catch (e, s) {}",
+              failing: ['block']),
+          //
+          // Only a finally clause.
+          //
+          new TestDescriptor('finally_noCatch_noBlock', 'try {} finally',
+              [ParserErrorCode.EXPECTED_TOKEN], "try {} finally {}",
+              failing: ['block']),
+          //
+          // A catch and finally clause.
+          //
+          new TestDescriptor(
+              'finally_catch_noBlock',
+              'try {} catch (e) {} finally',
+              [ParserErrorCode.EXPECTED_TOKEN],
+              "try {} catch (e) {} finally {}",
+              failing: ['block']),
+        ],
+        PartialCodeTest.statementSuffixes,
+        head: 'f() { ',
+        tail: ' }');
+  }
+}
diff --git a/pkg/analyzer/test/src/fasta/resolution_applier_test.dart b/pkg/analyzer/test/src/fasta/resolution_applier_test.dart
index 6c720dd..bdd7051 100644
--- a/pkg/analyzer/test/src/fasta/resolution_applier_test.dart
+++ b/pkg/analyzer/test/src/fasta/resolution_applier_test.dart
@@ -74,6 +74,7 @@
     ], <DartType>[
       typeProvider.stringType,
       new FunctionTypeImpl(new FunctionElementImpl('+', -1)),
+      new TypeArgumentsDartType([]),
       typeProvider.intType,
       typeProvider.stringType,
     ]);
@@ -91,8 +92,10 @@
     ], <DartType>[
       typeProvider.objectType,
       typeProvider.objectType,
+      new TypeArgumentsDartType([]),
       typeProvider.objectType,
       typeProvider.objectType,
+      new TypeArgumentsDartType([]),
       typeProvider.objectType
     ]);
   }
@@ -257,6 +260,7 @@
     ], <DartType>[
       typeProvider.stringType,
       typeProvider.intType,
+      new TypeArgumentsDartType([]),
       typeProvider.intType,
       typeProvider.stringType,
       typeProvider.stringType
diff --git a/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
new file mode 100644
index 0000000..c2e11d0
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/pubspec_validator_test.dart
@@ -0,0 +1,240 @@
+// 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/error/error.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/pubspec/pubspec_validator.dart';
+import 'package:analyzer/src/pubspec/pubspec_warning_code.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:yaml/yaml.dart';
+
+import '../../generated/test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(PubspecValidatorTest);
+  });
+}
+
+@reflectiveTest
+class PubspecValidatorTest extends Object with ResourceProviderMixin {
+  PubspecValidator validator;
+
+  /**
+   * Assert that when the validator is used on the given [content] the
+   * [expectedErrorCodes] are produced.
+   */
+  void assertErrors(String content, List<ErrorCode> expectedErrorCodes) {
+    YamlNode node = loadYamlNode(content);
+    if (node is! YamlMap) {
+      // The file is empty.
+      node = new YamlMap();
+    }
+    List<AnalysisError> errors = validator.validate((node as YamlMap).nodes);
+    GatheringErrorListener listener = new GatheringErrorListener();
+    listener.addAll(errors);
+    listener.assertErrorsWithCodes(expectedErrorCodes);
+  }
+
+  /**
+   * Assert that when the validator is used on the given [content] no errors are
+   * produced.
+   */
+  void assertNoErrors(String content) {
+    assertErrors(content, []);
+  }
+
+  void setUp() {
+    File pubspecFile = getFile('/sample/pubspec.yaml');
+    Source source = pubspecFile.createSource();
+    validator = new PubspecValidator(resourceProvider, source);
+  }
+
+  test_assetDoesNotExist_error() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''', [PubspecWarningCode.ASSET_DOES_NOT_EXIST]);
+  }
+
+  test_assetDoesNotExist_noError() {
+    newFile('/sample/assets/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''');
+  }
+
+  test_assetFieldNotList_error_empty() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+''', [PubspecWarningCode.ASSET_FIELD_NOT_LIST]);
+  }
+
+  test_assetFieldNotList_error_string() {
+    assertErrors('''
+name: sample
+flutter:
+  assets: assets/my_icon.png
+''', [PubspecWarningCode.ASSET_FIELD_NOT_LIST]);
+  }
+
+  test_assetFieldNotList_noError() {
+    newFile('/sample/assets/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''');
+  }
+
+  test_assetNotString_error_int() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+    - 23
+''', [PubspecWarningCode.ASSET_NOT_STRING]);
+  }
+
+  test_assetNotString_error_map() {
+    assertErrors('''
+name: sample
+flutter:
+  assets:
+    - my_icon:
+      default: assets/my_icon.png
+      large: assets/large/my_icon.png
+''', [PubspecWarningCode.ASSET_NOT_STRING]);
+  }
+
+  test_assetNotString_noError() {
+    newFile('/sample/assets/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''');
+  }
+
+  test_dependenciesFieldNotMap_dev_error_bool() {
+    assertErrors('''
+name: sample
+dev_dependencies: true
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+  }
+
+  test_dependenciesFieldNotMap_dev_error_empty() {
+    assertErrors('''
+name: sample
+dev_dependencies:
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+  }
+
+  test_dependenciesFieldNotMap_dev_noError() {
+    assertNoErrors('''
+name: sample
+dev_dependencies:
+  a: any
+''');
+  }
+
+  test_dependenciesFieldNotMap_error_bool() {
+    assertErrors('''
+name: sample
+dependencies: true
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+  }
+
+  test_dependenciesFieldNotMap_error_empty() {
+    assertErrors('''
+name: sample
+dependencies:
+''', [PubspecWarningCode.DEPENDENCIES_FIELD_NOT_MAP]);
+  }
+
+  test_dependenciesFieldNotMap_noError() {
+    assertNoErrors('''
+name: sample
+dependencies:
+  a: any
+''');
+  }
+
+  test_flutterFieldNotMap_error_bool() {
+    assertErrors('''
+name: sample
+flutter: true
+''', [PubspecWarningCode.FLUTTER_FIELD_NOT_MAP]);
+  }
+
+  test_flutterFieldNotMap_error_empty() {
+    assertErrors('''
+name: sample
+flutter:
+''', [PubspecWarningCode.FLUTTER_FIELD_NOT_MAP]);
+  }
+
+  test_flutterFieldNotMap_noError() {
+    newFile('/sample/assets/my_icon.png');
+    assertNoErrors('''
+name: sample
+flutter:
+  assets:
+    - assets/my_icon.png
+''');
+  }
+
+  test_missingName_error() {
+    assertErrors('', [PubspecWarningCode.MISSING_NAME]);
+  }
+
+  test_missingName_noError() {
+    assertNoErrors('''
+name: sample
+''');
+  }
+
+  test_nameNotString_error_int() {
+    assertErrors('''
+name: 42
+''', [PubspecWarningCode.NAME_NOT_STRING]);
+  }
+
+  test_nameNotString_noError() {
+    assertNoErrors('''
+name: sample
+''');
+  }
+
+  test_unnecessaryDevDependency_error() {
+    assertErrors('''
+name: sample
+dependencies:
+  a: any
+dev_dependencies:
+  a: any
+''', [PubspecWarningCode.UNNECESSARY_DEV_DEPENDENCY]);
+  }
+
+  test_unnecessaryDevDependency_noError() {
+    assertNoErrors('''
+name: sample
+dependencies:
+  a: any
+dev_dependencies:
+  b: any
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/pubspec/test_all.dart b/pkg/analyzer/test/src/pubspec/test_all.dart
new file mode 100644
index 0000000..a7e7ebe
--- /dev/null
+++ b/pkg/analyzer/test/src/pubspec/test_all.dart
@@ -0,0 +1,13 @@
+// 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:test_reflective_loader/test_reflective_loader.dart';
+
+import 'pubspec_validator_test.dart' as pubspec_validator;
+
+main() {
+  defineReflectiveSuite(() {
+    pubspec_validator.main();
+  }, name: 'pubspec');
+}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 8db1a7e..14ef322d 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9525,31 +9525,19 @@
   test_typedef_type_parameters_bound_recursive() async {
     shouldCompareLibraryElements = false;
     var library = await checkLibrary('typedef void F<T extends F>();');
-    if (isSharedFrontEnd) {
-      // Typedefs cannot reference themselves.
-      checkElementText(library, r'''
-typedef F<T extends dynamic> = void Function();
-''');
-    } else {
-      checkElementText(library, r'''
+    // Typedefs cannot reference themselves.
+    checkElementText(library, r'''
 typedef F<T extends () → void> = void Function();
 ''');
-    }
   }
 
   test_typedef_type_parameters_bound_recursive2() async {
     shouldCompareLibraryElements = false;
     var library = await checkLibrary('typedef void F<T extends List<F>>();');
-    if (isSharedFrontEnd) {
-      // Typedefs cannot reference themselves.
-      checkElementText(library, r'''
-typedef F<T extends List<dynamic>> = void Function();
-''');
-    } else {
-      checkElementText(library, r'''
+    // Typedefs cannot reference themselves.
+    checkElementText(library, r'''
 typedef F<T extends List<() → void>> = void Function();
 ''');
-    }
   }
 
   test_typedef_type_parameters_f_bound_complex() async {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
index 9e05d71..40060b1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart
@@ -383,7 +383,7 @@
   }
 
   @failingTest
-  @FastaProblem('https://github.com/dart-lang/sdk/issues/31213')
+  @FastaProblem('https://github.com/dart-lang/sdk/issues/31711')
   test_typedef_generic_asFieldType() async {
     await super.test_typedef_generic_asFieldType();
   }
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index d6d0d19..369c7b9 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -9,6 +9,7 @@
 import 'dart/test_all.dart' as dart;
 import 'fasta/test_all.dart' as fasta;
 import 'lint/test_all.dart' as lint;
+import 'pubspec/test_all.dart' as pubspec;
 import 'source/test_all.dart' as source;
 import 'summary/test_all.dart' as summary;
 import 'task/test_all.dart' as task;
@@ -22,6 +23,7 @@
     dart.main();
     fasta.main();
     lint.main();
+    pubspec.main();
     source.main();
     summary.main();
     task.main();
diff --git a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
index 4313841..b0dac1f 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/completion/completion_target.dart
@@ -88,6 +88,17 @@
   final AstNode containingNode;
 
   /**
+   * The "dropped" identifier or keyword which the completed text will replace,
+   * or `null` if none.
+   *
+   * For the purposes of code completion, a "dropped" token is an identifier
+   * or keyword that is part of the token stream, but that the parser has
+   * skipped and not reported in to the parser listeners, meaning that it is
+   * not part of the AST.
+   */
+  Token droppedToken;
+
+  /**
    * The entity which the completed text will replace (or which will be
    * displaced once the completed text is inserted).  This may be an AstNode or
    * a Token, or it may be null if the cursor is after all tokens in the file.
@@ -235,7 +246,9 @@
       Object entity, this.isCommentText)
       : this.containingNode = containingNode,
         this.entity = entity,
-        this.argIndex = _computeArgIndex(containingNode, entity);
+        this.argIndex = _computeArgIndex(containingNode, entity),
+        this.droppedToken =
+            _computeDroppedToken(containingNode, entity, offset);
 
   /**
    * Return `true` if the [containingNode] is a cascade
@@ -263,7 +276,8 @@
     bool isKeywordOrIdentifier(Token token) =>
         token.type.isKeyword || token.type == TokenType.IDENTIFIER;
 
-    Token token = entity is AstNode ? (entity as AstNode).beginToken : entity;
+    Token token = droppedToken ??
+        (entity is AstNode ? (entity as AstNode).beginToken : entity);
     if (token != null && requestOffset < token.offset) {
       token = token.previous;
     }
@@ -388,6 +402,52 @@
     return null;
   }
 
+  static Token _computeDroppedToken(
+      AstNode containingNode, Object entity, int offset) {
+    // Find the last token of the member before the entity.
+    var previousMember;
+    for (var member in containingNode.childEntities) {
+      if (entity == member) {
+        break;
+      }
+      if (member is! Comment && member is! CommentToken) {
+        previousMember = member;
+      }
+    }
+    Token token;
+    if (previousMember is AstNode) {
+      token = previousMember.endToken;
+    } else if (previousMember is Token) {
+      token = previousMember;
+    }
+    if (token == null) {
+      return null;
+    }
+
+    // Find the first token of the entity (which may be the entity itself).
+    Token endSearch;
+    if (entity is AstNode) {
+      endSearch = entity.beginToken;
+    } else if (entity is Token) {
+      endSearch = entity;
+    }
+    if (endSearch == null) {
+      return null;
+    }
+
+    // Find a dropped token that overlaps the offset.
+    token = token.next;
+    while (token != endSearch && !token.isEof) {
+      if (token.isKeywordOrIdentifier &&
+          token.offset <= offset &&
+          offset <= token.end) {
+        return token;
+      }
+      token = token.next;
+    }
+    return null;
+  }
+
   /**
    * Determine if the offset is contained in a preceding comment token
    * and return that token, otherwise return `null`.
diff --git a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
index a555373..40c3fcd 100644
--- a/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/completion/completion_target_test.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/src/dart/analysis/driver.dart';
+import 'package:analyzer/src/generated/parser.dart' as analyzer;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:test/test.dart';
@@ -25,6 +26,8 @@
   int completionOffset;
   CompletionTarget target;
 
+  bool get usingFastaParser => analyzer.Parser.useFasta;
+
   Future<Null> addTestSource(String content) async {
     expect(completionOffset, isNull, reason: 'Call addTestSource exactly once');
     completionOffset = content.indexOf('^');
@@ -39,12 +42,16 @@
   }
 
   Future<Null> assertTarget(entityText, nodeText,
-      {int argIndex: null, bool isFunctionalArgument: false}) async {
+      {int argIndex: null,
+      bool isFunctionalArgument: false,
+      String droppedToken}) async {
     void assertCommon() {
       expect(target.entity.toString(), entityText, reason: 'entity');
       expect(target.containingNode.toString(), nodeText,
           reason: 'containingNode');
       expect(target.argIndex, argIndex, reason: 'argIndex');
+      expect(target.droppedToken?.toString(), droppedToken ?? isNull,
+          reason: 'droppedToken');
     }
 
     // Assert with parsed unit
@@ -403,6 +410,16 @@
         '// normal comment ', 'class C2 {zoo(z) {} String name;}');
   }
 
+  test_IfStatement_droppedToken() async {
+    // Comment  ClassDeclaration  CompilationUnit
+    await addTestSource('main() { if (v i^) }');
+    if (usingFastaParser) {
+      await assertTarget(')', '(v)', droppedToken: 'i');
+    } else {
+      await assertTarget('i;', 'if (v) i;');
+    }
+  }
+
   test_MethodDeclaration_inLineComment2() async {
     // Comment  ClassDeclaration  CompilationUnit
     await addTestSource('''
@@ -555,13 +572,13 @@
   test_SwitchStatement_c() async {
     // Token('c') SwitchStatement
     await addTestSource('main() { switch(x) {c^} }');
-    await assertTarget('}', 'switch (x) {}');
+    await assertTarget('}', 'switch (x) {}', droppedToken: 'c');
   }
 
   test_SwitchStatement_c2() async {
     // Token('c') SwitchStatement
     await addTestSource('main() { switch(x) { c^ } }');
-    await assertTarget('}', 'switch (x) {}');
+    await assertTarget('}', 'switch (x) {}', droppedToken: 'c');
   }
 
   test_SwitchStatement_empty() async {
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index c9319e4..7cbc7e7 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -37,6 +37,7 @@
   /// using the kernel representation.
   /// See [CompilerOptions.useKernel] for details.
   static const String useKernel = '--use-kernel';
+  static const String strongMode = '--strong';
   static const String platformBinaries = '--platform-binaries=.+';
 
   static const String minify = '--minify';
diff --git a/pkg/compiler/lib/src/constants/values.dart b/pkg/compiler/lib/src/constants/values.dart
index 8a189c9..115def6 100644
--- a/pkg/compiler/lib/src/constants/values.dart
+++ b/pkg/compiler/lib/src/constants/values.dart
@@ -8,6 +8,7 @@
 import '../common_elements.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
+import '../deferred_load.dart' show OutputUnit;
 import '../util/util.dart' show Hashing;
 
 enum ConstantValueKind {
@@ -24,6 +25,7 @@
   INTERCEPTOR,
   SYNTHETIC,
   DEFERRED,
+  DEFERRED_GLOBAL,
   NON_CONSTANT,
 }
 
@@ -45,6 +47,8 @@
       covariant InterceptorConstantValue constant, covariant A arg);
   R visitSynthetic(covariant SyntheticConstantValue constant, covariant A arg);
   R visitDeferred(covariant DeferredConstantValue constant, covariant A arg);
+  R visitDeferredGlobal(
+      covariant DeferredGlobalConstantValue constant, covariant A arg);
   R visitNonConstant(covariant NonConstantValue constant, covariant A arg);
 }
 
@@ -94,8 +98,8 @@
   /// expression from the value so the unparse of these is best effort.
   ///
   /// For the synthetic constants, [DeferredConstantValue],
-  /// [SyntheticConstantValue], [InterceptorConstantValue] the unparse is
-  /// descriptive only.
+  /// [DeferredGlobalConstantValue], [SyntheticConstantValue],
+  /// [InterceptorConstantValue] the unparse is descriptive only.
   String toDartText();
 
   /// Returns a structured representation of this constant suited for debugging.
@@ -752,7 +756,8 @@
 }
 
 /// A reference to a constant in another output unit.
-/// Used for referring to deferred constants.
+///
+/// Used for referring to deferred constants when evaluating constant values.
 class DeferredConstantValue extends ConstantValue {
   DeferredConstantValue(this.referenced, this.import);
 
@@ -784,6 +789,50 @@
   }
 }
 
+/// A reference to a constant in another output unit.
+///
+/// Used for referring to deferred constants that appear as initializers of
+/// final (non-const) global fields.
+///
+// TODO(sigmund): this should eventually not be a constant value. In particular,
+// [DeferredConstantValue] is introduced by the constant evaluator when it first
+// sees constants used in the program. [DeferredGlobalConstantValue] are
+// introduced later by the SSA builder and should be represented
+// with a dedicated JEntity instead. We currently model them as a regular
+// constant to take advantage of the machinery we already have in place to
+// generate deferred constants in the emitter.
+class DeferredGlobalConstantValue extends ConstantValue {
+  DeferredGlobalConstantValue(this.referenced, this.unit);
+
+  final ConstantValue referenced;
+  final OutputUnit unit;
+
+  bool get isReference => true;
+
+  bool operator ==(other) {
+    return other is DeferredGlobalConstantValue &&
+        referenced == other.referenced &&
+        unit == other.unit;
+  }
+
+  get hashCode => (referenced.hashCode * 17 + unit.hashCode) & 0x3fffffff;
+
+  List<ConstantValue> getDependencies() => <ConstantValue>[referenced];
+
+  accept(ConstantValueVisitor visitor, arg) =>
+      visitor.visitDeferredGlobal(this, arg);
+
+  DartType getType(CommonElements types) => referenced.getType(types);
+
+  ConstantValueKind get kind => ConstantValueKind.DEFERRED_GLOBAL;
+
+  String toDartText() => 'deferred_global(${referenced.toDartText()})';
+
+  String toStructuredText() {
+    return 'DeferredGlobalConstant(${referenced.toStructuredText()})';
+  }
+}
+
 /// A constant value resulting from a non constant or erroneous constant
 /// expression.
 // TODO(johnniwinther): Expand this to contain the error kind.
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 2fa6522..b016904 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -399,6 +399,7 @@
     new OptionHandler(Flags.useContentSecurityPolicy, passThrough),
     new OptionHandler(Flags.enableExperimentalMirrors, passThrough),
     new OptionHandler(Flags.enableAssertMessage, passThrough),
+    new OptionHandler(Flags.strongMode, passThrough),
 
     // TODO(floitsch): remove conditional directives flag.
     // We don't provide the info-message yet, since we haven't publicly
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index cbe47ff..8ba05a1 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -11,7 +11,11 @@
 import 'common_elements.dart' show ElementEnvironment;
 import 'compiler.dart' show Compiler;
 import 'constants/values.dart'
-    show ConstantValue, ConstructedConstantValue, DeferredConstantValue;
+    show
+        ConstantValue,
+        ConstructedConstantValue,
+        DeferredConstantValue,
+        DeferredGlobalConstantValue;
 import 'elements/types.dart';
 import 'elements/elements.dart'
     show AstElement, ClassElement, Element, MethodElement, LocalFunctionElement;
@@ -69,6 +73,8 @@
     return name.compareTo(other.name);
   }
 
+  Set<ImportEntity> get importsForTesting => _imports;
+
   String toString() => "OutputUnit($name, $_imports)";
 }
 
@@ -496,6 +502,8 @@
     for (ImportEntity import in allDeferredImports) {
       String result = computeImportDeferName(import, compiler);
       assert(result != null);
+      // Note: tools that process the json file to build multi-part initial load
+      // bundles depend on the fact that makeUnique appends only digits.
       _importDeferName[import] = makeUnique(result, usedImportNames);
     }
 
@@ -544,7 +552,7 @@
   ///
   /// The deferred loading algorithm maps elements and constants to an output
   /// unit. Each output unit is identified by a subset of deferred imports (an
-  /// [ImportSet]), and they will contain the elements that are inheretly used
+  /// [ImportSet]), and they will contain the elements that are inherently used
   /// by all those deferred imports. An element is used by a deferred import if
   /// it is either loaded by that import or transitively accessed by an element
   /// that the import loads.  An empty set represents the main output unit,
@@ -1091,13 +1099,6 @@
     if (!isProgramSplit) return mainOutputUnit;
     entity = entity is Element ? entity.implementation : entity;
     OutputUnit unit = _entityToUnit[entity];
-    // TODO(redemption): ensure any entity that is requested is in the map.
-    // Currently closure methods are not handled correctly. The old pipeline
-    // finds the appropriate output unit because the synthetic $call methods
-    // transitively have the member-context as an enclosing element, and those
-    // methods are found. The new pipeline doesn't expose that connection. We
-    // should handle this in the emitter or while translating OutputUnitData to
-    // the J-model.
     if (unit != null) return unit;
     if (entity is Element) {
       Element element = entity;
@@ -1171,11 +1172,11 @@
     return outputUnitTo._imports.containsAll(outputUnitFrom._imports);
   }
 
-  /// Registers that a constant is used in a deferred library.
+  /// Registers that a constant is used in the same deferred output unit as
+  /// [field].
   void registerConstantDeferredUse(
-      DeferredConstantValue constant, ImportEntity import) {
+      DeferredGlobalConstantValue constant, OutputUnit unit) {
     if (!isProgramSplit) return;
-    var unit = _importSets.singleton(import).unit;
     assert(
         _constantToUnit[constant] == null || _constantToUnit[constant] == unit);
     _constantToUnit[constant] = unit;
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 93747d9..bc3d0c0 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -10,7 +10,7 @@
 import 'package:dart2js_info/info.dart';
 
 import '../compiler_new.dart';
-import 'closure.dart';
+import 'common/names.dart';
 import 'common/tasks.dart' show CompilerTask;
 import 'common.dart';
 import 'common_elements.dart';
@@ -50,7 +50,8 @@
     compiler.dumpInfoTask._constantToNode.forEach((constant, node) {
       // TODO(sigmund): add dependencies on other constants
       var size = compiler.dumpInfoTask._nodeToSize[node];
-      var code = jsAst.prettyPrint(node, compiler.options);
+      var code = jsAst.prettyPrint(node,
+          enableMinification: compiler.options.enableMinification);
       var info = new ConstantInfo(
           size: size, code: code, outputUnit: _unitInfoForConstant(constant));
       _constantToInfo[constant] = info;
@@ -219,18 +220,17 @@
     return classInfo;
   }
 
-  ClosureInfo visitClosureClass(ClosureClassElement element) {
+  ClosureInfo visitClosureClass(ClassEntity element) {
     ClosureInfo closureInfo = new ClosureInfo(
         name: element.name,
         outputUnit: _unitInfoForEntity(element),
         size: compiler.dumpInfoTask.sizeOf(element));
     _entityToInfo[element] = closureInfo;
 
-    ClosureRepresentationInfo closureRepresentation =
-        compiler.backendStrategy.closureDataLookup.getClosureInfo(element.node);
-    assert(closureRepresentation.closureClassEntity == element);
+    FunctionEntity callMethod = closedWorld.elementEnvironment
+        .lookupClassMember(element, Identifiers.call);
 
-    FunctionInfo functionInfo = visitFunction(closureRepresentation.callMethod);
+    FunctionInfo functionInfo = visitFunction(callMethod);
     if (functionInfo == null) return null;
     closureInfo.function = functionInfo;
     functionInfo.parent = closureInfo;
@@ -544,7 +544,8 @@
     // Concatenate rendered ASTs.
     StringBuffer sb = new StringBuffer();
     for (jsAst.Node ast in code) {
-      sb.writeln(jsAst.prettyPrint(ast, compiler.options));
+      sb.writeln(jsAst.prettyPrint(ast,
+          enableMinification: compiler.options.enableMinification));
     }
     return sb.toString();
   }
@@ -615,6 +616,7 @@
 
     result.deferredFiles = compiler.deferredLoadTask.computeDeferredMap();
     stopwatch.stop();
+
     result.program = new ProgramInfo(
         entrypoint: infoCollector
             ._entityToInfo[closedWorld.elementEnvironment.mainFunction],
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index ad1ca0d..c282f29 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -948,6 +948,7 @@
 abstract class ImportElement extends Element implements ImportEntity {
   Uri get uri;
   LibraryElement get importedLibrary;
+  LibraryElement get enclosingLibrary => library;
   bool get isDeferred;
   PrefixElement get prefix;
   String get name;
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index 1e6207e..8d68752 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -38,6 +38,9 @@
 ///
 /// The [name] property corresponds to the prefix name, if any.
 abstract class ImportEntity extends Entity {
+  /// The library where this import occurs (where the import is declared).
+  LibraryEntity get enclosingLibrary;
+
   /// Whether the import is a deferred import.
   bool get isDeferred;
 
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 8ed5033..9d137e9 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -1002,6 +1002,9 @@
   Import get node => super.node;
 
   @override
+  LibraryElement get enclosingLibrary => library;
+
+  @override
   LibraryElement get importedLibrary => libraryDependency;
 
   @override
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
index 336e319..116eb19 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_dump.dart
@@ -99,11 +99,11 @@
   ///
   /// Will never return the a given filename more than once, even if called with
   /// the same element.
-  String filenameFromElement(MemberElement element) {
+  String filenameFromElement(MemberEntity element) {
     // The toString method of elements include characters that are unsuitable
     // for URIs and file systems.
     List<String> parts = <String>[];
-    parts.add(element.library?.libraryName);
+    parts.add(element.library.canonicalUri.pathSegments.last);
     parts.add(element.enclosingClass?.name);
     if (element.isGetter) {
       parts.add('get-${element.name}');
@@ -115,19 +115,10 @@
       } else {
         parts.add(element.name);
       }
-    } else if (element.isOperator) {
+    } else {
       parts.add(Elements
           .operatorNameToIdentifier(element.name)
           .replaceAll(r'$', '-'));
-    } else {
-      parts.add(element.name);
-    }
-    if (element != element) {
-      if (element.name.isEmpty) {
-        parts.add('anon${element.sourcePosition.begin}');
-      } else {
-        parts.add(element.name);
-      }
     }
     String filename = parts.where((x) => x != null && x != '').join('.');
     if (usedFilenames.add(filename)) return filename;
@@ -149,7 +140,7 @@
   final Map<TypeInformation, int> nodeId = <TypeInformation, int>{};
   int usedIds = 0;
   final OutputSink output;
-  final MemberElement element;
+  final MemberEntity element;
   TypeInformation returnValue;
 
   _GraphGenerator(this.global, this.element, this.output) {
diff --git a/pkg/compiler/lib/src/io/kernel_source_information.dart b/pkg/compiler/lib/src/io/kernel_source_information.dart
index 421ed12..da70b55 100644
--- a/pkg/compiler/lib/src/io/kernel_source_information.dart
+++ b/pkg/compiler/lib/src/io/kernel_source_information.dart
@@ -109,6 +109,40 @@
     return _buildTreeNode(node);
   }
 
+  /// Creates the source information for a [base] and end of [member]. If [base]
+  /// is not provided, the offset of [member] is used as the start position.
+  ///
+  /// This is used function declarations and return expressions which both point
+  /// to the end of the member as the closing position.
+  SourceInformation _buildFunctionEnd(MemberEntity member, [ir.TreeNode base]) {
+    MemberDefinition definition = _elementMap.getMemberDefinition(member);
+    ir.Node node = definition.node;
+    switch (definition.kind) {
+      case MemberKind.regular:
+        if (node is ir.Procedure) {
+          return _buildFunction(base ?? node, node.function);
+        }
+        break;
+      case MemberKind.constructor:
+      case MemberKind.constructorBody:
+        if (node is ir.Procedure) {
+          return _buildFunction(base ?? node, node.function);
+        } else if (node is ir.Constructor) {
+          return _buildFunction(base ?? node, node.function);
+        }
+        break;
+      case MemberKind.closureCall:
+        if (node is ir.FunctionDeclaration) {
+          return _buildFunction(base ?? node, node.function);
+        } else if (node is ir.FunctionExpression) {
+          return _buildFunction(base ?? node, node.function);
+        }
+        break;
+      default:
+    }
+    return _buildTreeNode(base ?? node);
+  }
+
   /// Creates the source information for exiting a function definition defined
   /// by the root [node] and its [functionNode].
   ///
@@ -207,8 +241,10 @@
   }
 
   /// Creates source information based on the location of [node].
-  SourceInformation _buildTreeNode(ir.TreeNode node) {
-    return new PositionSourceInformation(_getSourceLocation(node));
+  SourceInformation _buildTreeNode(ir.TreeNode node,
+      [SourceLocation closingPosition]) {
+    return new PositionSourceInformation(
+        _getSourceLocation(node), closingPosition);
   }
 
   @override
@@ -352,7 +388,7 @@
 
   @override
   SourceInformation buildReturn(ir.Node node) {
-    return _buildTreeNode(node);
+    return _buildFunctionEnd(_member, node);
   }
 
   @override
@@ -370,34 +406,7 @@
 
   @override
   SourceInformation buildDeclaration(MemberEntity member) {
-    MemberDefinition definition = _elementMap.getMemberDefinition(member);
-    switch (definition.kind) {
-      case MemberKind.regular:
-        ir.Node node = definition.node;
-        if (node is ir.Procedure) {
-          return _buildFunction(node, node.function);
-        }
-        break;
-      case MemberKind.constructor:
-      case MemberKind.constructorBody:
-        ir.Node node = definition.node;
-        if (node is ir.Procedure) {
-          return _buildFunction(node, node.function);
-        } else if (node is ir.Constructor) {
-          return _buildFunction(node, node.function);
-        }
-        break;
-      case MemberKind.closureCall:
-        ir.Node node = definition.node;
-        if (node is ir.FunctionDeclaration) {
-          return _buildFunction(node, node.function);
-        } else if (node is ir.FunctionExpression) {
-          return _buildFunction(node, node.function);
-        }
-        break;
-      default:
-    }
-    return _buildTreeNode(definition.node);
+    return _buildFunctionEnd(member);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/io/multi_information.dart b/pkg/compiler/lib/src/io/multi_information.dart
index 9f8d909..84c3421 100644
--- a/pkg/compiler/lib/src/io/multi_information.dart
+++ b/pkg/compiler/lib/src/io/multi_information.dart
@@ -310,7 +310,7 @@
   SourceLocation get endPosition => infos.first?.endPosition;
 
   @override
-  SourceLocation get closingPosition => infos.first?.closingPosition;
+  SourceLocation get innerPosition => infos.first?.innerPosition;
 
   @override
   SourceLocation get startPosition => infos.first?.startPosition;
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 4363274..4e1fd6c 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -25,9 +25,9 @@
   final SourceLocation startPosition;
 
   @override
-  final SourceLocation closingPosition;
+  final SourceLocation innerPosition;
 
-  PositionSourceInformation(this.startPosition, [this.closingPosition]);
+  PositionSourceInformation(this.startPosition, [this.innerPosition]);
 
   @override
   List<SourceLocation> get sourceLocations {
@@ -35,8 +35,8 @@
     if (startPosition != null) {
       list.add(startPosition);
     }
-    if (closingPosition != null) {
-      list.add(closingPosition);
+    if (innerPosition != null) {
+      list.add(innerPosition);
     }
     return list;
   }
@@ -44,7 +44,7 @@
   @override
   SourceSpan get sourceSpan {
     SourceLocation location =
-        startPosition != null ? startPosition : closingPosition;
+        startPosition != null ? startPosition : innerPosition;
     Uri uri = location.sourceUri;
     int offset = location.offset;
     return new SourceSpan(uri, offset, offset);
@@ -52,14 +52,14 @@
 
   int get hashCode {
     return 0x7FFFFFFF &
-        (startPosition.hashCode * 17 + closingPosition.hashCode * 19);
+        (startPosition.hashCode * 17 + innerPosition.hashCode * 19);
   }
 
   bool operator ==(other) {
     if (identical(this, other)) return true;
     if (other is! PositionSourceInformation) return false;
     return startPosition == other.startPosition &&
-        closingPosition == other.closingPosition;
+        innerPosition == other.innerPosition;
   }
 
   /// Create a textual representation of the source information using [uriText]
@@ -72,9 +72,9 @@
       sb.write('[${startPosition.line},'
           '${startPosition.column}]');
     }
-    if (closingPosition != null) {
-      sb.write('-[${closingPosition.line},'
-          '${closingPosition.column}]');
+    if (innerPosition != null) {
+      sb.write('-[${innerPosition.line},'
+          '${innerPosition.column}]');
     }
     return sb.toString();
   }
@@ -83,7 +83,7 @@
     if (startPosition != null) {
       return _computeText(startPosition.sourceUri.pathSegments.last);
     } else {
-      return _computeText(closingPosition.sourceUri.pathSegments.last);
+      return _computeText(innerPosition.sourceUri.pathSegments.last);
     }
   }
 
@@ -91,7 +91,7 @@
     if (startPosition != null) {
       return _computeText('${startPosition.sourceUri}');
     } else {
-      return _computeText('${closingPosition.sourceUri}');
+      return _computeText('${innerPosition.sourceUri}');
     }
   }
 }
@@ -194,7 +194,17 @@
   SourceInformation buildListLiteral(Node node) => buildBegin(node);
 
   @override
-  SourceInformation buildReturn(Node node) => buildBegin(node);
+  SourceInformation buildReturn(Node node) {
+    SourceFile sourceFile = computeSourceFile(resolvedAst);
+    SourceLocation startPosition = new OffsetSourceLocation(
+        sourceFile, node.getBeginToken().charOffset, name);
+    SourceLocation endPosition;
+    if (resolvedAst.kind == ResolvedAstKind.PARSED) {
+      endPosition = new OffsetSourceLocation(
+          sourceFile, resolvedAst.node.getEndToken().charOffset, name);
+    }
+    return new PositionSourceInformation(startPosition, endPosition);
+  }
 
   @override
   SourceInformation buildImplicitReturn(MemberElement element) {
@@ -446,8 +456,7 @@
     case SourcePositionKind.START:
       return sourceInformation.startPosition;
     case SourcePositionKind.INNER:
-      return sourceInformation.closingPosition ??
-          sourceInformation.startPosition;
+      return sourceInformation.innerPosition ?? sourceInformation.startPosition;
   }
 }
 
@@ -603,6 +612,55 @@
 
   PositionTraceListener(this.sourceMapper, this.reader);
 
+  /// Registers source information for [node] on the [offset] in the JavaScript
+  /// code using [kind] to determine what information to use.
+  ///
+  /// For most nodes the start position of the source information is used.
+  /// For instance a return expression points to the the start position of the
+  /// source information, typically the start of the return statement that
+  /// created the JavaScript return node:
+  ///
+  ///     JavaScript:                    Dart:
+  ///
+  ///     @return "foo";                 return "foo";
+  ///                                    ^
+  /// (@ marks the current JavaScript position and ^ point to the mapped Dart
+  /// code position.)
+  ///
+  ///
+  /// For [StepKind.CALL] the `CallPosition.getSemanticPositionForCall` method
+  /// is called to determine whether the start or the inner position should be
+  /// used. For instance if the receiver of the JavaScript call is a "simple"
+  /// expression then the start position of the source information is used:
+  ///
+  ///     JavaScript:                    Dart:
+  ///
+  ///     t1.@foo$0()                    local.foo()
+  ///                                    ^
+  ///
+  /// If the receiver of the JavaScript call is "complex" then the inner
+  /// position of the source information is used:
+  ///
+  ///     JavaScript:                    Dart:
+  ///
+  ///     get$bar().@foo()               bar.foo()
+  ///                                        ^
+  ///
+  /// For [StepKind.FUN_EXIT] the inner position of the source information
+  /// is used. For a JavaScript function without a return statement this maps
+  /// the end brace to the end brace of the corresponding Dart function. For a
+  /// JavaScript function exited through a return statement this maps the end of
+  /// the return statement to the end brace of the Dart function:
+  ///
+  ///     JavaScript:                    Dart:
+  ///
+  ///     foo: function() {              foo() {
+  ///     @}                             }
+  ///                                    ^
+  ///     foo: function() {              foo() {
+  ///       return 0;@                     return 0;
+  ///     }                              }
+  ///                                    ^
   @override
   void onStep(js.Node node, Offset offset, StepKind kind) {
     int codeLocation = offset.value;
@@ -663,13 +721,69 @@
 
 /// The position of a [js.Call] node.
 class CallPosition {
+  /// The call node for which the positions have been computed.
   final js.Node node;
+
+  /// The position for [node] used as the offset in the JavaScript code.
+  ///
+  /// This is either `CodePositionKind.START` for code like
+  ///
+  ///     t1.foo$0()
+  ///     ^
+  /// where the left-most offset of the receiver should be used, or
+  /// `CodePositionKind.CLOSING` for code like
+  ///
+  ///     get$bar().foo$0()
+  ///               ^
+  ///
+  /// where the name of the called method should be used (here the method
+  /// 'foo$0').
   final CodePositionKind codePositionKind;
+
+  /// The position from the [SourceInformation] used in the mapped Dart code.
+  ///
+  /// This is either `SourcePositionKind.START` for code like
+  ///
+  ///     JavaScript:                    Dart:
+  ///
+  ///     t1.@foo$0()                    local.foo()
+  ///                                    ^
+  ///
+  /// where the JavaScript receiver is a "simple" expression, or
+  /// `SourcePositionKind.CLOSING` for code like
+  ///
+  ///     JavaScript:                    Dart:
+  ///
+  ///     get$bar().@foo()               bar.foo()
+  ///                                        ^
+  ///
+  /// where the JavaScript receiver is a "complex" expression.
+  ///
+  /// (@ marks the current JavaScript position and ^ point to the mapped Dart
+  /// code position.)
   final SourcePositionKind sourcePositionKind;
 
   CallPosition(this.node, this.codePositionKind, this.sourcePositionKind);
 
-  /// Computes the [CallPosition] for [node].
+  /// Computes the [CallPosition] for the call [node].
+  ///
+  /// For instance if the receiver of the JavaScript call is a "simple"
+  /// expression then the start position of the source information is used:
+  ///
+  ///     JavaScript:                    Dart:
+  ///
+  ///     t1.@foo$0()                    local.foo()
+  ///                                    ^
+  ///
+  /// If the receiver of the JavaScript call is "complex" then the inner
+  /// position of the source information is used:
+  ///
+  ///     JavaScript:                    Dart:
+  ///
+  ///     get$bar().@foo()               bar.foo()
+  ///                                        ^
+  /// (@ marks the current JavaScript position and ^ point to the mapped Dart
+  /// code position.)
   static CallPosition getSemanticPositionForCall(js.Call node) {
     if (node.target is js.PropertyAccess) {
       js.PropertyAccess access = node.target;
@@ -728,6 +842,13 @@
   }
 }
 
+/// An offset of a JavaScript node within the output code.
+///
+/// This object holds three different values for the offset corresponding to
+/// three different ways browsers can compute the offset of a JavaScript node.
+///
+/// Currently [subexpressionOffset] is used since it corresponds the most to the
+/// offset used by most browsers.
 class Offset {
   /// The offset of the enclosing statement relative to the beginning of the
   /// file.
@@ -1153,6 +1274,9 @@
     visit(node.value);
     notifyStep(
         node, getOffsetForNode(node, getSyntaxOffset(node)), StepKind.RETURN);
+    Offset exitOffset = getOffsetForNode(
+        node, getSyntaxOffset(node, kind: CodePositionKind.CLOSING));
+    notifyStep(node, exitOffset, StepKind.FUN_EXIT);
     statementOffset = null;
     leftToRightOffset = null;
   }
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index ac33b01..34a80d7 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -28,8 +28,10 @@
   /// The source location associated with the start of the JS node.
   SourceLocation get startPosition => null;
 
-  /// The source location associated with the closing of the JS node.
-  SourceLocation get closingPosition => null;
+  /// The source location associated with an inner of the JS node.
+  ///
+  /// The inner position is for instance `foo()` in `o.foo()`.
+  SourceLocation get innerPosition => null;
 
   /// The source location associated with the end of the JS node.
   SourceLocation get endPosition => null;
diff --git a/pkg/compiler/lib/src/js/js.dart b/pkg/compiler/lib/src/js/js.dart
index 97c6069..9a819e8 100644
--- a/pkg/compiler/lib/src/js/js.dart
+++ b/pkg/compiler/lib/src/js/js.dart
@@ -15,12 +15,13 @@
 export 'package:js_ast/js_ast.dart';
 export 'js_debug.dart';
 
-String prettyPrint(Node node, CompilerOptions compilerOptions,
-    {bool allowVariableMinification: true,
+String prettyPrint(Node node,
+    {bool enableMinification: false,
+    bool allowVariableMinification: true,
     Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) {
   // TODO(johnniwinther): Do we need all the options here?
   JavaScriptPrintingOptions options = new JavaScriptPrintingOptions(
-      shouldCompressOutput: compilerOptions.enableMinification,
+      shouldCompressOutput: enableMinification,
       minifyLocalVariables: allowVariableMinification,
       renamerForNames: renamerForNames);
   SimpleJavaScriptPrintingContext context =
@@ -130,7 +131,7 @@
 /// for example by the lazy emitter or when generating code generators.
 class UnparsedNode extends DeferredString implements AstContainer {
   final Node tree;
-  final CompilerOptions _compilerOptions;
+  final bool _enableMinification;
   final bool _protectForEval;
   LiteralString _cachedLiteral;
 
@@ -141,11 +142,11 @@
   /// When its string [value] is requested, the node pretty-prints the given
   /// [ast] and, if [protectForEval] is true, wraps the resulting string in
   /// parenthesis. The result is also escaped.
-  UnparsedNode(this.tree, this._compilerOptions, this._protectForEval);
+  UnparsedNode(this.tree, this._enableMinification, this._protectForEval);
 
   LiteralString get _literal {
     if (_cachedLiteral == null) {
-      String text = prettyPrint(tree, _compilerOptions);
+      String text = prettyPrint(tree, enableMinification: _enableMinification);
       if (_protectForEval) {
         if (tree is Fun) text = '($text)';
         if (tree is LiteralExpression) {
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 35913d3..b2b61c8 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -871,7 +871,8 @@
   String getGeneratedCode(MemberEntity element) {
     assert(!(element is MemberElement && !element.isDeclaration),
         failedAt(element));
-    return jsAst.prettyPrint(generatedCode[element], compiler.options);
+    return jsAst.prettyPrint(generatedCode[element],
+        enableMinification: compiler.options.enableMinification);
   }
 
   /// Generates the output and returns the total size of the generated code.
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 605b8f8..d52f2f0 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -370,4 +370,10 @@
   jsAst.Expression visitDeferred(DeferredConstantValue constant, [_]) {
     return constantReferenceGenerator(constant.referenced);
   }
+
+  @override
+  jsAst.Expression visitDeferredGlobal(DeferredGlobalConstantValue constant,
+      [_]) {
+    return constantReferenceGenerator(constant.referenced);
+  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index 902fb2c..51e274e 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -1995,6 +1995,11 @@
   void visitDeferred(DeferredConstantValue constant, [_]) {
     addRoot('Deferred');
   }
+
+  @override
+  void visitDeferredGlobal(DeferredGlobalConstantValue constant, [_]) {
+    addRoot('Deferred');
+  }
 }
 
 /**
@@ -2116,6 +2121,12 @@
     return _combine(hash, _visit(constant.referenced));
   }
 
+  @override
+  int visitDeferredGlobal(DeferredGlobalConstantValue constant, [_]) {
+    int hash = constant.unit.hashCode;
+    return _combine(hash, _visit(constant.referenced));
+  }
+
   int _hashString(int hash, String s) {
     int length = s.length;
     hash = _combine(hash, length);
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 89ee3d0..79057a1 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -137,9 +137,6 @@
   /// is a function type.
   jsAst.Template get templateForIsFunctionType;
 
-  /// Returns the JavaScript template that creates at runtime a new function
-  /// type object.
-  jsAst.Template get templateForCreateFunctionType;
   jsAst.Name get getFunctionThatReturnsNullName;
 
   /// Returns a [jsAst.Expression] representing the given [type]. Type variables
@@ -801,13 +798,6 @@
     return _representationGenerator.templateForIsFunctionType;
   }
 
-  /// Returns the JavaScript template that creates at runtime a new function
-  /// type object.
-  @override
-  jsAst.Template get templateForCreateFunctionType {
-    return _representationGenerator.templateForCreateFunctionType;
-  }
-
   @override
   jsAst.Expression getTypeRepresentation(
       Emitter emitter, DartType type, OnVariableCallback onVariable,
@@ -1055,15 +1045,6 @@
     return jsAst.js.expressionTemplateFor("'${namer.functionTypeTag}' in #");
   }
 
-  /// Returns the JavaScript template that creates at runtime a new function
-  /// type object.
-  jsAst.Template get templateForCreateFunctionType {
-    // The value of the functionTypeTag can be anything. We use "dynaFunc" for
-    // easier debugging.
-    return jsAst.js
-        .expressionTemplateFor('{ ${namer.functionTypeTag}: "dynafunc" }');
-  }
-
   jsAst.Expression visitFunctionType(FunctionType type, Emitter emitter) {
     List<jsAst.Property> properties = <jsAst.Property>[];
 
diff --git a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
index a3774ff..7f65831 100644
--- a/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/class_stub_generator.dart
@@ -261,8 +261,8 @@
 
   jsAst.Statement tearOffGetter;
   if (!options.useContentSecurityPolicy) {
-    jsAst.Expression tearOffAccessText =
-        new jsAst.UnparsedNode(tearOffAccessExpression, options, false);
+    jsAst.Expression tearOffAccessText = new jsAst.UnparsedNode(
+        tearOffAccessExpression, options.enableMinification, false);
     tearOffGetter = js.statement('''
 function tearOffGetter(funcs, reflectionInfo, name, isIntercepted) {
   return isIntercepted
diff --git a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
index 48721d5..0b8e6a7 100644
--- a/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
+++ b/pkg/compiler/lib/src/js_emitter/constant_ordering.dart
@@ -233,6 +233,13 @@
     // TODO(sra): What kind of Entity is `prefix`?
     return compareElements(a.import, b.import);
   }
+
+  int visitDeferredGlobal(
+      DeferredGlobalConstantValue a, DeferredGlobalConstantValue b) {
+    int r = compareValues(a.referenced, b.referenced);
+    if (r != 0) return r;
+    return a.unit.compareTo(b.unit);
+  }
 }
 
 class _KindVisitor implements ConstantValueVisitor<int, Null> {
@@ -251,6 +258,7 @@
   static const int INTERCEPTOR = 11;
   static const int SYNTHETIC = 12;
   static const int DEFERRED = 13;
+  static const int DEFERRED_GLOBAL = 14;
   static const int NONCONSTANT = 13;
 
   static int kind(ConstantValue constant) =>
@@ -270,6 +278,7 @@
   int visitInterceptor(InterceptorConstantValue a, _) => INTERCEPTOR;
   int visitSynthetic(SyntheticConstantValue a, _) => SYNTHETIC;
   int visitDeferred(DeferredConstantValue a, _) => DEFERRED;
+  int visitDeferredGlobal(DeferredGlobalConstantValue a, _) => DEFERRED_GLOBAL;
 }
 
 /// Visitor for distinguishing types by kind.
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 d5b051b..c96a17c 100644
--- a/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/full_emitter/emitter.dart
@@ -342,9 +342,6 @@
       case JsBuiltin.rawRuntimeType:
         return jsAst.js.expressionTemplateFor("#.constructor");
 
-      case JsBuiltin.createFunctionTypeRti:
-        return backend.rtiEncoder.templateForCreateFunctionType;
-
       case JsBuiltin.isSubtype:
         // TODO(floitsch): move this closer to where is-check properties are
         // built.
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index 3f76e8b..d21e5e7 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -372,8 +372,9 @@
 
   _MetadataEntry _addGlobalMetadata(jsAst.Node node, OutputUnit outputUnit) {
     String nameToKey(jsAst.Name name) => "${name.key}";
-    String printed =
-        jsAst.prettyPrint(node, _options, renamerForNames: nameToKey);
+    String printed = jsAst.prettyPrint(node,
+        enableMinification: _options.enableMinification,
+        renamerForNames: nameToKey);
     _metadataMap[outputUnit] ??= new Map<String, _BoundMetadataEntry>();
     return _metadataMap[outputUnit].putIfAbsent(printed, () {
       return new _BoundMetadataEntry(node);
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 6d0d91e..4a14cc2 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
@@ -698,9 +698,7 @@
         _rtiSubstitutions,
         _jsInteropAnalysis);
 
-    void visitMember(ClassEntity declarer, MemberEntity member) {
-      if (cls != declarer) return;
-
+    void visitMember(MemberEntity member) {
       if (member.isInstanceMember && !member.isAbstract && !member.isField) {
         // TODO(herhut): Remove once _buildMethod can no longer return null.
         Method method = _buildMethod(member);
@@ -747,11 +745,10 @@
     // MixinApplications run through the members of their mixin. Here, we are
     // only interested in direct members.
     if (!onlyForRti && !_elementEnvironment.isMixinApplication(cls)) {
-      _elementEnvironment.forEachClassMember(cls, visitMember);
-      _elementEnvironment.forEachConstructorBody(
-          cls,
-          (ConstructorBodyEntity constructorBody) =>
-              visitMember(cls, constructorBody));
+      List<MemberEntity> members = <MemberEntity>[];
+      _elementEnvironment.forEachLocalClassMember(cls, members.add);
+      _elementEnvironment.forEachConstructorBody(cls, members.add);
+      _sorter.sortMembers(members).forEach(visitMember);
     }
     bool isInterceptedClass = _interceptorData.isInterceptedClass(cls);
     List<Field> instanceFields = onlyForRti
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 f4ff829..f1b2ad4 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/emitter.dart
@@ -132,9 +132,6 @@
       case JsBuiltin.rawRuntimeType:
         return js.js.expressionTemplateFor("#.constructor");
 
-      case JsBuiltin.createFunctionTypeRti:
-        return _backend.rtiEncoder.templateForCreateFunctionType;
-
       case JsBuiltin.isSubtype:
         // TODO(floitsch): move this closer to where is-check properties are
         // built.
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 5a95832..7f82042 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -168,7 +168,7 @@
         } else {
           failedAt(member, "Unexpected closure node ${node}");
         }
-        KernelClosureClass closureClass = _produceSyntheticElements(
+        KernelClosureClassInfo closureClassInfo = _produceSyntheticElements(
             closedWorldBuilder,
             member,
             functionNode,
@@ -177,8 +177,8 @@
             localFunctionsNeedingRti,
             classesNeedingRti);
         // Add also for the call method.
-        _scopeMap[closureClass.callMethod] = closureClass;
-        callMethods.add(closureClass.callMethod);
+        _scopeMap[closureClassInfo.callMethod] = closureClassInfo;
+        callMethods.add(closureClassInfo.callMethod);
       }
     });
     return callMethods;
@@ -190,7 +190,7 @@
   /// the closure accesses a variable that gets accessed at some point), then
   /// boxForCapturedVariables stores the local context for those variables.
   /// If no variables are captured, this parameter is null.
-  KernelClosureClass _produceSyntheticElements(
+  KernelClosureClassInfo _produceSyntheticElements(
       JsClosedWorldBuilder closedWorldBuilder,
       MemberEntity member,
       ir.FunctionNode node,
@@ -201,28 +201,24 @@
     _updateScopeBasedOnRtiNeed(
         info, node.parent, localFunctionsNeedingRti, classesNeedingRti, member);
     KernelToLocalsMap localsMap = _globalLocalsMap.getLocalsMap(member);
-    KernelClosureClass closureClass = closedWorldBuilder.buildClosureClass(
-        member,
-        node,
-        member.library,
-        boxedVariables,
-        info,
-        node.location,
-        localsMap);
+    KernelClosureClassInfo closureClassInfo =
+        closedWorldBuilder.buildClosureClass(member, node, member.library,
+            boxedVariables, info, node.location, localsMap);
 
     // We want the original declaration where that function is used to point
     // to the correct closure class.
-    _memberClosureRepresentationMap[closureClass.callMethod] = closureClass;
-    _globalLocalsMap.setLocalsMap(closureClass.callMethod, localsMap);
+    _memberClosureRepresentationMap[closureClassInfo.callMethod] =
+        closureClassInfo;
+    _globalLocalsMap.setLocalsMap(closureClassInfo.callMethod, localsMap);
     if (node.parent is ir.Member) {
       assert(_elementMap.getMember(node.parent) == member);
-      _memberClosureRepresentationMap[member] = closureClass;
+      _memberClosureRepresentationMap[member] = closureClassInfo;
     } else {
       assert(node.parent is ir.FunctionExpression ||
           node.parent is ir.FunctionDeclaration);
-      _localClosureRepresentationMap[node.parent] = closureClass;
+      _localClosureRepresentationMap[node.parent] = closureClassInfo;
     }
-    return closureClass;
+    return closureClassInfo;
   }
 
   @override
@@ -478,7 +474,7 @@
 }
 
 // TODO(johnniwinther): Add unittest for the computed [ClosureClass].
-class KernelClosureClass extends JsScopeInfo
+class KernelClosureClassInfo extends JsScopeInfo
     implements ClosureRepresentationInfo {
   JFunction callMethod;
   final Local closureEntity;
@@ -487,7 +483,7 @@
 
   final Map<Local, JField> localToFieldMap = new Map<Local, JField>();
 
-  KernelClosureClass.fromScopeInfo(
+  KernelClosureClassInfo.fromScopeInfo(
       this.closureClassEntity,
       ir.FunctionNode closureSourceNode,
       Map<Local, JRecordField> boxedVariables,
@@ -550,8 +546,8 @@
 
 class JClosureField extends JField implements PrivatelyNamedJSEntity {
   final Local _declaredEntity;
-  JClosureField(String name, KernelClosureClass containingClass, bool isConst,
-      bool isAssignable, this._declaredEntity)
+  JClosureField(String name, KernelClosureClassInfo containingClass,
+      bool isConst, bool isAssignable, this._declaredEntity)
       : super(
             containingClass.closureClassEntity.library,
             containingClass.closureClassEntity,
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index 4229b83..e9b84a1 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -9,7 +9,7 @@
 import '../elements/names.dart';
 import '../elements/types.dart';
 import '../kernel/indexed.dart';
-import 'closure.dart' show KernelClosureClass;
+import 'closure.dart' show KernelClosureClassInfo;
 
 /// Map from 'frontend' to 'backend' elements.
 ///
@@ -522,11 +522,11 @@
 }
 
 class JClosureCallMethod extends JMethod {
-  JClosureCallMethod(KernelClosureClass containingClass,
+  JClosureCallMethod(KernelClosureClassInfo closureClassInfo,
       ParameterStructure parameterStructure, AsyncMarker asyncMarker)
       : super(
-            containingClass.closureClassEntity.library,
-            containingClass.closureClassEntity,
+            closureClassInfo.closureClassEntity.library,
+            closureClassInfo.closureClassEntity,
             Names.call,
             parameterStructure,
             asyncMarker,
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 4d56126..0ee5d63 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -159,6 +159,7 @@
       SelectorConstraintsStrategy selectorConstraintsStrategy) {
     return new KernelCodegenWorldBuilder(
         elementMap,
+        _globalLocalsMap,
         closedWorld.elementEnvironment,
         nativeBasicData,
         closedWorld,
@@ -474,7 +475,7 @@
 
   /// Construct a closure class and set up the necessary class inference
   /// hierarchy.
-  KernelClosureClass buildClosureClass(
+  KernelClosureClassInfo buildClosureClass(
       MemberEntity member,
       ir.FunctionNode originalClosureFunctionNode,
       JLibrary enclosingLibrary,
@@ -484,7 +485,7 @@
       KernelToLocalsMap localsMap) {
     ClassEntity superclass = _commonElements.closureClass;
 
-    KernelClosureClass cls = _elementMap.constructClosureClass(
+    KernelClosureClassInfo closureClassInfo = _elementMap.constructClosureClass(
         member,
         originalClosureFunctionNode,
         enclosingLibrary,
@@ -497,13 +498,13 @@
     // Tell the hierarchy that this is the super class. then we can use
     // .getSupertypes(class)
     ClassHierarchyNode parentNode = _classHierarchyNodes[superclass];
-    ClassHierarchyNode node = new ClassHierarchyNode(
-        parentNode, cls.closureClassEntity, parentNode.hierarchyDepth + 1);
-    _classHierarchyNodes[cls.closureClassEntity] = node;
-    _classSets[cls.closureClassEntity] = new ClassSet(node);
+    ClassHierarchyNode node = new ClassHierarchyNode(parentNode,
+        closureClassInfo.closureClassEntity, parentNode.hierarchyDepth + 1);
+    _classHierarchyNodes[closureClassInfo.closureClassEntity] = node;
+    _classSets[closureClassInfo.closureClassEntity] = new ClassSet(node);
     node.isDirectlyInstantiated = true;
 
-    return cls;
+    return closureClassInfo;
   }
 }
 
@@ -622,10 +623,13 @@
   }
 
   ConstantValue visitDeferred(DeferredConstantValue constant, _) {
+    throw new UnsupportedError("DeferredConstantValue with --use-kernel");
+  }
+
+  ConstantValue visitDeferredGlobal(DeferredGlobalConstantValue constant, _) {
     var referenced = constant.referenced.accept(this, null);
     if (referenced == constant.referenced) return constant;
-    // TODO(sigmund): do we need a JImport entity?
-    return new DeferredConstantValue(referenced, constant.import);
+    return new DeferredGlobalConstantValue(referenced, constant.unit);
   }
 
   DartType _handleType(DartType type) {
diff --git a/pkg/compiler/lib/src/kernel/deferred_load.dart b/pkg/compiler/lib/src/kernel/deferred_load.dart
index ea96d26..f9d46c3 100644
--- a/pkg/compiler/lib/src/kernel/deferred_load.dart
+++ b/pkg/compiler/lib/src/kernel/deferred_load.dart
@@ -22,15 +22,42 @@
 
   @override
   Iterable<ImportEntity> importsTo(Entity element, LibraryEntity library) {
-    if (element is! MemberEntity) return const <ImportEntity>[];
+    ir.NamedNode node;
+    String nodeName;
+    ir.Library enclosingLibrary;
+    if (element is ClassEntity) {
+      ClassDefinition definition = _elementMap.getClassDefinition(element);
+      if (definition.kind != ClassKind.regular) {
+        // You can't import closures.
+        return const <ImportEntity>[];
+      }
+      ir.Class _node = definition.node;
+      nodeName = _node.name;
+      enclosingLibrary = _node.enclosingLibrary;
+      node = _node;
+    } else if (element is MemberEntity) {
+      ir.Member _node = _elementMap.getMemberDefinition(element).node;
+      nodeName = _node.name.name;
+      enclosingLibrary = _node.enclosingLibrary;
+      node = _node;
+    } else if (element is Local ||
+        element is LibraryEntity ||
+        element is TypeVariableEntity) {
+      return const <ImportEntity>[];
+    } else if (element is TypedefEntity) {
+      throw new UnimplementedError("KernelDeferredLoadTask.importsTo typedef");
+    } else {
+      throw new UnsupportedError(
+          "KernelDeferredLoadTask.importsTo unexpected entity type: "
+          "${element.runtimeType}");
+    }
     List<ImportEntity> imports = [];
     ir.Library source = _elementMap.getLibraryNode(library);
-    ir.Member member = _elementMap.getMemberDefinition(element).node;
     for (ir.LibraryDependency dependency in source.dependencies) {
       if (dependency.isExport) continue;
-      if (!_isVisible(dependency.combinators, member.name.name)) continue;
-      if (member.enclosingLibrary == dependency.targetLibrary ||
-          additionalExports(dependency.targetLibrary).contains(member)) {
+      if (!_isVisible(dependency.combinators, nodeName)) continue;
+      if (enclosingLibrary == dependency.targetLibrary ||
+          additionalExports(dependency.targetLibrary).contains(node)) {
         imports.add(_elementMap.getImport(dependency));
       }
     }
diff --git a/pkg/compiler/lib/src/kernel/element_map.dart b/pkg/compiler/lib/src/kernel/element_map.dart
index 9360a77..2d256cc 100644
--- a/pkg/compiler/lib/src/kernel/element_map.dart
+++ b/pkg/compiler/lib/src/kernel/element_map.dart
@@ -180,6 +180,9 @@
   /// Returns the definition information for [member].
   MemberDefinition getMemberDefinition(covariant MemberEntity member);
 
+  /// Returns the definition information for [cls].
+  ClassDefinition getClassDefinition(covariant ClassEntity cls);
+
   /// Return the [ImportEntity] corresponding to [node].
   ImportEntity getImport(ir.LibraryDependency node);
 }
@@ -276,7 +279,7 @@
 enum ClassKind {
   regular,
   closure,
-  // TODO(efortuna, johnniwinther): Container is not a class, but is
+  // TODO(efortuna, johnniwinther): Record is not a class, but is
   // masquerading as one currently for consistency with the old element model.
   record,
 }
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 2d6dc79..92e71cd 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -71,6 +71,7 @@
 }
 
 abstract class KernelToElementMapBase extends KernelToElementMapBaseMixin {
+  final CompilerOptions options;
   final DiagnosticReporter reporter;
   CommonElements _commonElements;
   ElementEnvironment _elementEnvironment;
@@ -92,7 +93,7 @@
   final EntityDataMap<IndexedTypedef, TypedefData> _typedefs =
       new EntityDataMap<IndexedTypedef, TypedefData>();
 
-  KernelToElementMapBase(this.reporter, Environment environment) {
+  KernelToElementMapBase(this.options, this.reporter, Environment environment) {
     _elementEnvironment = new KernelElementEnvironment(this);
     _commonElements = new CommonElements(_elementEnvironment);
     _constantEnvironment = new KernelConstantEnvironment(this, environment);
@@ -438,8 +439,7 @@
       namedParameterTypes.add(getDartType(variable.type));
     }
     List<FunctionTypeVariable> typeVariables;
-    if (node.typeParameters.isNotEmpty &&
-        DartTypeConverter.enableFunctionTypeVariables) {
+    if (node.typeParameters.isNotEmpty && options.strongMode) {
       List<DartType> typeParameters = <DartType>[];
       for (ir.TypeParameter typeParameter in node.typeParameters) {
         typeParameters
@@ -703,6 +703,9 @@
         'KernelToElementMapBase._forEachConstructorBody');
   }
 
+  void _forEachNestedClosure(
+      MemberEntity member, void f(FunctionEntity closure));
+
   void _forEachLocalClassMember(IndexedClass cls, void f(MemberEntity member)) {
     assert(checkFamily(cls));
     ClassEnv env = _classes.getEnv(cls);
@@ -790,7 +793,7 @@
 }
 
 /// Mixin that implements the abstract methods in [KernelToElementMapBase].
-abstract class ElementCreatorMixin {
+abstract class ElementCreatorMixin implements KernelToElementMapBase {
   ProgramEnv get _env;
   EntityDataEnvMap<IndexedLibrary, LibraryData, LibraryEnv> get _libraries;
   EntityDataEnvMap<IndexedClass, ClassData, ClassEnv> get _classes;
@@ -1012,11 +1015,8 @@
     int typeParameters = node.typeParameters.length;
     List<String> namedParameters =
         node.namedParameters.map((p) => p.name).toList()..sort();
-    return new ParameterStructure(
-        requiredParameters,
-        positionalParameters,
-        namedParameters,
-        DartTypeConverter.enableFunctionTypeVariables ? typeParameters : 0);
+    return new ParameterStructure(requiredParameters, positionalParameters,
+        namedParameters, options.strongMode ? typeParameters : 0);
   }
 
   IndexedLibrary createLibrary(String name, Uri canonicalUri);
@@ -1142,11 +1142,10 @@
         KElementCreatorMixin {
   native.BehaviorBuilder _nativeBehaviorBuilder;
   FrontendStrategy _frontendStrategy;
-  CompilerOptions _options;
 
   KernelToElementMapForImpactImpl(DiagnosticReporter reporter,
-      Environment environment, this._frontendStrategy, this._options)
-      : super(reporter, environment);
+      Environment environment, this._frontendStrategy, CompilerOptions options)
+      : super(options, reporter, environment);
 
   @override
   bool checkFamily(Entity entity) {
@@ -1158,6 +1157,13 @@
   }
 
   @override
+  void _forEachNestedClosure(
+      MemberEntity member, void f(FunctionEntity closure)) {
+    throw new UnsupportedError(
+        "KernelToElementMapForImpactImpl._forEachNestedClosure");
+  }
+
+  @override
   NativeBasicData get nativeBasicData => _frontendStrategy.nativeBasicData;
 
   /// Adds libraries in [program] to the set of libraries.
@@ -1171,7 +1177,7 @@
   @override
   native.BehaviorBuilder get nativeBehaviorBuilder =>
       _nativeBehaviorBuilder ??= new KernelBehaviorBuilder(elementEnvironment,
-          commonElements, nativeBasicData, reporter, _options);
+          commonElements, nativeBasicData, reporter, options);
 
   ResolutionImpact computeWorldImpact(KMember member) {
     return buildKernelImpact(
@@ -1180,7 +1186,7 @@
 
   ScopeModel computeScopeModel(KMember member) {
     ir.Member node = _members.getData(member).definition.node;
-    return KernelClosureAnalysis.computeScopeModel(member, node, _options);
+    return KernelClosureAnalysis.computeScopeModel(member, node, options);
   }
 
   /// Returns the kernel [ir.Procedure] node for the [method].
@@ -1255,6 +1261,11 @@
   MemberDefinition getMemberDefinition(MemberEntity member) {
     return _getMemberDefinition(member);
   }
+
+  @override
+  ClassDefinition getClassDefinition(ClassEntity cls) {
+    return _getClassDefinition(cls);
+  }
 }
 
 class KernelElementEnvironment extends ElementEnvironment {
@@ -1423,8 +1434,7 @@
   @override
   void forEachNestedClosure(
       MemberEntity member, void f(FunctionEntity closure)) {
-    throw new UnimplementedError(
-        'KernelElementEnvironment.forEachNestedClosure');
+    elementMap._forEachNestedClosure(member, f);
   }
 
   @override
@@ -1534,8 +1544,6 @@
 
 /// Visitor that converts kernel dart types into [DartType].
 class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
-  static bool enableFunctionTypeVariables = false;
-
   final KernelToElementMapBase elementMap;
   final Map<ir.TypeParameter, DartType> currentFunctionTypeParameters =
       <ir.TypeParameter, DartType>{};
@@ -1588,7 +1596,7 @@
     int index = 0;
     List<FunctionTypeVariable> typeVariables;
     for (ir.TypeParameter typeParameter in node.typeParameters) {
-      if (enableFunctionTypeVariables) {
+      if (elementMap.options.strongMode) {
         // TODO(johnniwinther): Support recursive type variable bounds, like
         // `void Function<T extends Foo<T>>(T t)` when #31531 is fixed.
         DartType bound = typeParameter.bound.accept(this);
@@ -2046,11 +2054,15 @@
         ElementCreatorMixin
     implements
         KernelToWorldBuilder {
+  /// Map from members to the call methods created for their nested closures.
+  Map<MemberEntity, List<FunctionEntity>> _nestedClosureMap =
+      <MemberEntity, List<FunctionEntity>>{};
+
   NativeBasicData nativeBasicData;
 
   JsKernelToElementMap(DiagnosticReporter reporter, Environment environment,
       KernelToElementMapForImpactImpl _elementMap)
-      : super(reporter, environment) {
+      : super(_elementMap.options, reporter, environment) {
     _env = _elementMap._env;
     for (int libraryIndex = 0;
         libraryIndex < _elementMap._libraries.length;
@@ -2122,6 +2134,13 @@
     }
   }
 
+  @override
+  void _forEachNestedClosure(
+      MemberEntity member, void f(FunctionEntity closure)) {
+    assert(checkFamily(member));
+    _nestedClosureMap[member]?.forEach(f);
+  }
+
   InterfaceType getMemberThisType(MemberEntity member) {
     return _members.getData(member).getMemberThisType(this);
   }
@@ -2321,7 +2340,7 @@
           Local local, Map<Local, JRecordField> recordFieldsVisibleInScope) =>
       recordFieldsVisibleInScope.containsKey(local);
 
-  KernelClosureClass constructClosureClass(
+  KernelClosureClassInfo constructClosureClass(
       MemberEntity member,
       ir.FunctionNode node,
       JLibrary enclosingLibrary,
@@ -2369,20 +2388,24 @@
       closureEntity = new JLocal('', localsMap.currentMember);
     }
 
-    KernelClosureClass cls = new KernelClosureClass.fromScopeInfo(
-        classEntity,
-        node,
-        <Local, JRecordField>{},
-        info,
-        localsMap,
-        closureEntity,
-        info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
-        this);
-    _buildClosureClassFields(cls, member, memberThisType, info, localsMap,
-        recordFieldsVisibleInScope, memberMap);
+    KernelClosureClassInfo closureClassInfo =
+        new KernelClosureClassInfo.fromScopeInfo(
+            classEntity,
+            node,
+            <Local, JRecordField>{},
+            info,
+            localsMap,
+            closureEntity,
+            info.hasThisLocal ? new ThisLocal(localsMap.currentMember) : null,
+            this);
+    _buildClosureClassFields(closureClassInfo, member, memberThisType, info,
+        localsMap, recordFieldsVisibleInScope, memberMap);
 
     FunctionEntity callMethod = new JClosureCallMethod(
-        cls, _getParameterStructure(node), getAsyncMarker(node));
+        closureClassInfo, _getParameterStructure(node), getAsyncMarker(node));
+    _nestedClosureMap
+        .putIfAbsent(member, () => <FunctionEntity>[])
+        .add(callMethod);
     _members.register<IndexedFunction, FunctionData>(
         callMethod,
         new ClosureFunctionData(
@@ -2392,12 +2415,12 @@
             getFunctionType(node),
             node,
             typeVariableAccess));
-    memberMap[callMethod.name] = cls.callMethod = callMethod;
-    return cls;
+    memberMap[callMethod.name] = closureClassInfo.callMethod = callMethod;
+    return closureClassInfo;
   }
 
   void _buildClosureClassFields(
-      KernelClosureClass cls,
+      KernelClosureClassInfo closureClassInfo,
       MemberEntity member,
       InterfaceType memberThisType,
       KernelScopeInfo info,
@@ -2420,7 +2443,7 @@
         if (_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
           bool constructedField = _constructClosureFieldForRecord(
               capturedLocal,
-              cls,
+              closureClassInfo,
               memberThisType,
               memberMap,
               variable,
@@ -2434,8 +2457,8 @@
     // Add a field for the captured 'this'.
     if (info.thisUsedAsFreeVariable) {
       _constructClosureField(
-          cls.thisLocal,
-          cls,
+          closureClassInfo.thisLocal,
+          closureClassInfo,
           memberThisType,
           memberMap,
           getClassDefinition(member.enclosingClass).node,
@@ -2453,7 +2476,7 @@
         if (!_isInRecord(capturedLocal, recordFieldsVisibleInScope)) {
           _constructClosureField(
               capturedLocal,
-              cls,
+              closureClassInfo,
               memberThisType,
               memberMap,
               variable,
@@ -2465,7 +2488,7 @@
       } else if (variable is TypeParameterTypeWithContext) {
         _constructClosureField(
             localsMap.getLocalTypeVariable(variable.type, this),
-            cls,
+            closureClassInfo,
             memberThisType,
             memberMap,
             variable.type.parameter,
@@ -2488,7 +2511,7 @@
   /// in the closure class.
   bool _constructClosureFieldForRecord(
       Local capturedLocal,
-      KernelClosureClass cls,
+      KernelClosureClassInfo closureClassInfo,
       InterfaceType memberThisType,
       Map<String, MemberEntity> memberMap,
       ir.TreeNode sourceNode,
@@ -2498,32 +2521,32 @@
 
     // Don't construct a new field if the box that holds this local already has
     // a field in the closure class.
-    if (cls.localToFieldMap.containsKey(recordField.box)) {
-      cls.boxedVariables[capturedLocal] = recordField;
+    if (closureClassInfo.localToFieldMap.containsKey(recordField.box)) {
+      closureClassInfo.boxedVariables[capturedLocal] = recordField;
       return false;
     }
 
     FieldEntity closureField = new JClosureField(
-        '_box_$fieldNumber', cls, true, false, recordField.box);
+        '_box_$fieldNumber', closureClassInfo, true, false, recordField.box);
 
     _members.register<IndexedField, FieldData>(
         closureField,
         new ClosureFieldData(
             new ClosureMemberDefinition(
-                cls.localToFieldMap[capturedLocal],
+                closureClassInfo.localToFieldMap[capturedLocal],
                 computeSourceSpanFromTreeNode(sourceNode),
                 MemberKind.closureField,
                 sourceNode),
             memberThisType));
     memberMap[closureField.name] = closureField;
-    cls.localToFieldMap[recordField.box] = closureField;
-    cls.boxedVariables[capturedLocal] = recordField;
+    closureClassInfo.localToFieldMap[recordField.box] = closureField;
+    closureClassInfo.boxedVariables[capturedLocal] = recordField;
     return true;
   }
 
   _constructClosureField(
       Local capturedLocal,
-      KernelClosureClass cls,
+      KernelClosureClassInfo closureClassInfo,
       InterfaceType memberThisType,
       Map<String, MemberEntity> memberMap,
       ir.TreeNode sourceNode,
@@ -2532,7 +2555,7 @@
       int fieldNumber) {
     FieldEntity closureField = new JClosureField(
         _getClosureVariableName(capturedLocal.name, fieldNumber),
-        cls,
+        closureClassInfo,
         isConst,
         isAssignable,
         capturedLocal);
@@ -2541,13 +2564,13 @@
         closureField,
         new ClosureFieldData(
             new ClosureMemberDefinition(
-                cls.localToFieldMap[capturedLocal],
+                closureClassInfo.localToFieldMap[capturedLocal],
                 computeSourceSpanFromTreeNode(sourceNode),
                 MemberKind.closureField,
                 sourceNode),
             memberThisType));
     memberMap[closureField.name] = closureField;
-    cls.localToFieldMap[capturedLocal] = closureField;
+    closureClassInfo.localToFieldMap[capturedLocal] = closureField;
   }
 
   // Returns a non-unique name for the given closure element.
diff --git a/pkg/compiler/lib/src/kernel/element_map_mixins.dart b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
index aa25d5e..9117831 100644
--- a/pkg/compiler/lib/src/kernel/element_map_mixins.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_mixins.dart
@@ -20,13 +20,14 @@
 import '../js_backend/namer.dart';
 import '../js_emitter/code_emitter_task.dart';
 import '../native/native.dart' as native;
+import '../options.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
 import 'element_map.dart';
-import 'element_map_impl.dart';
 import 'kernel_debug.dart';
 
 abstract class KernelToElementMapBaseMixin implements KernelToElementMap {
+  CompilerOptions get options;
   DiagnosticReporter get reporter;
   ElementEnvironment get elementEnvironment;
   LibraryEntity getLibrary(ir.Library node);
@@ -44,12 +45,8 @@
   CallStructure getCallStructure(ir.Arguments arguments) {
     int argumentCount = arguments.positional.length + arguments.named.length;
     List<String> namedArguments = arguments.named.map((e) => e.name).toList();
-    return new CallStructure(
-        argumentCount,
-        namedArguments,
-        DartTypeConverter.enableFunctionTypeVariables
-            ? arguments.types.length
-            : 0);
+    return new CallStructure(argumentCount, namedArguments,
+        options.strongMode ? arguments.types.length : 0);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/kernel/env.dart b/pkg/compiler/lib/src/kernel/env.dart
index 3083498..a4a9011 100644
--- a/pkg/compiler/lib/src/kernel/env.dart
+++ b/pkg/compiler/lib/src/kernel/env.dart
@@ -173,7 +173,10 @@
         dependencies.forEach((ir.LibraryDependency node) {
           if (node.isExport) return;
           imports[node] = new KImport(
-              node.isDeferred, node.name, node.targetLibrary.importUri);
+              node.isDeferred,
+              node.name,
+              node.targetLibrary.importUri,
+              elementMap.getLibrary(node.enclosingLibrary));
         });
       }
     }
diff --git a/pkg/compiler/lib/src/kernel/kelements.dart b/pkg/compiler/lib/src/kernel/kelements.dart
index fd9ec25..6f14b6e 100644
--- a/pkg/compiler/lib/src/kernel/kelements.dart
+++ b/pkg/compiler/lib/src/kernel/kelements.dart
@@ -25,8 +25,9 @@
   final bool isDeferred;
   final String name;
   final Uri uri;
+  final LibraryEntity enclosingLibrary;
 
-  KImport(this.isDeferred, this.name, this.uri);
+  KImport(this.isDeferred, this.name, this.uri, this.enclosingLibrary);
 
   String toString() =>
       '${kElementPrefix}import($name:${isDeferred ? ' deferred' : ''})';
diff --git a/pkg/compiler/lib/src/kernel/types.dart b/pkg/compiler/lib/src/kernel/types.dart
index d6ea085..cd97a06 100644
--- a/pkg/compiler/lib/src/kernel/types.dart
+++ b/pkg/compiler/lib/src/kernel/types.dart
@@ -99,6 +99,10 @@
             reporter: elementMap.reporter,
             objectType: elementMap.commonElements.objectType);
 
+  // TODO(sigmund): delete once Issue #31118 is fixed.
+  @override
+  bool get reportMultiInheritanceIssue => false;
+
   InterfaceType getThisType(ClassEntity cls) {
     return elementMap._getThisType(cls);
   }
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index b4d108f..b0e0610 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -863,7 +863,8 @@
       } else {
         initializedCompilerState = fe.initializeCompiler(
             initializedCompilerState,
-            new Dart2jsTarget(new TargetFlags()),
+            new Dart2jsTarget(
+                new TargetFlags(strongMode: _elementMap.options.strongMode)),
             platformBinaries.resolve("dart2js_platform.dill"),
             _packageConfig);
         program = await fe.compile(
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 466e63a..73650f6 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -213,11 +213,16 @@
   /// sources to kernel, and then continue compilation from the kernel
   /// representation.
   ///
-  /// When this flag is on, the compiler also acccepts reading .dill files from
+  /// 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.
   final bool useKernel;
 
+  /// Enables strong mode in dart2js.
+  ///
+  /// This is work-in-progress and will only be supported for [useKernel].
+  final bool strongMode;
+
   /// When obfuscating for minification, whether to use the frequency of a name
   /// as an heuristic to pick shorter names.
   final bool useFrequencyNamer;
@@ -325,6 +330,7 @@
         resolveOnly: _hasOption(options, Flags.resolveOnly),
         sourceMapUri: _extractUriOption(options, '--source-map='),
         strips: _extractCsvOption(options, '--force-strip='),
+        strongMode: _hasOption(options, Flags.strongMode),
         testMode: _hasOption(options, Flags.testMode),
         trustJSInteropTypeAnnotations:
             _hasOption(options, Flags.trustJSInteropTypeAnnotations),
@@ -390,6 +396,7 @@
       bool resolveOnly: false,
       Uri sourceMapUri: null,
       List<String> strips: const [],
+      bool strongMode: false,
       bool testMode: false,
       bool trustJSInteropTypeAnnotations: false,
       bool trustPrimitives: false,
@@ -470,6 +477,7 @@
         resolveOnly: resolveOnly,
         sourceMapUri: sourceMapUri,
         strips: strips,
+        strongMode: strongMode,
         testMode: testMode,
         trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations,
         trustPrimitives: trustPrimitives,
@@ -522,6 +530,7 @@
       this.compileOnly: false,
       this.sourceMapUri: null,
       this.strips: const [],
+      this.strongMode: false,
       this.testMode: false,
       this.trustJSInteropTypeAnnotations: false,
       this.trustPrimitives: false,
@@ -582,6 +591,7 @@
       compileOnly,
       sourceMapUri,
       strips,
+      strongMode,
       testMode,
       trustJSInteropTypeAnnotations,
       trustPrimitives,
@@ -649,6 +659,7 @@
         compileOnly: compileOnly ?? options.compileOnly,
         sourceMapUri: sourceMapUri ?? options.sourceMapUri,
         strips: strips ?? options.strips,
+        strongMode: strongMode ?? options.strongMode,
         testMode: testMode ?? options.testMode,
         trustJSInteropTypeAnnotations: trustJSInteropTypeAnnotations ??
             options.trustJSInteropTypeAnnotations,
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index b01dbf3..a134269 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -228,6 +228,9 @@
     }
   }
 
+  // TODO(sigmund): delete once Issue #31118 is fixed.
+  bool get reportMultiInheritanceIssue => true;
+
   void _addAtDepth(InterfaceType type, int depth) {
     LinkEntry<InterfaceType> prev = null;
     LinkEntry<InterfaceType> link = map[depth];
@@ -236,11 +239,13 @@
       if (existingType == type) return;
       if (existingType.element == type.element) {
         if (reporter != null) {
-          reporter.reportErrorMessage(cls, MessageKind.MULTI_INHERITANCE, {
-            'thisType': getThisType(cls),
-            'firstType': existingType,
-            'secondType': type
-          });
+          if (reportMultiInheritanceIssue) {
+            reporter.reportErrorMessage(cls, MessageKind.MULTI_INHERITANCE, {
+              'thisType': getThisType(cls),
+              'firstType': existingType,
+              'secondType': type
+            });
+          }
         } else {
           assert(false, failedAt(cls, 'Invalid ordered typeset for $cls'));
         }
diff --git a/pkg/compiler/lib/src/resolution/resolution_strategy.dart b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
index b47e1c6..1c4b55c 100644
--- a/pkg/compiler/lib/src/resolution/resolution_strategy.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_strategy.dart
@@ -533,13 +533,20 @@
   void forEachLocalClassMember(
       covariant ClassElement cls, void f(MemberElement member)) {
     cls.ensureResolved(_resolution);
-    cls.forEachLocalMember((_member) {
+
+    void handleMember(_member) {
       MemberElement member = _member;
       if (member.isSynthesized) return;
       if (member.isMalformed) return;
       if (member.isConstructor) return;
+      if (!member.isDeclaration) return;
       f(member);
-    });
+    }
+
+    cls.forEachLocalMember(handleMember);
+    if (cls.isPatched) {
+      cls.implementation.forEachLocalMember(handleMember);
+    }
   }
 
   @override
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index bb7a800..9fef23a 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -1032,6 +1032,20 @@
   }
 
   @override
+  bool visitDeferredGlobal(DeferredGlobalConstantValue value1,
+      covariant DeferredGlobalConstantValue value2) {
+    return strategy.testSets(
+            value1,
+            value2,
+            'imports',
+            value1.unit.importsForTesting,
+            value2.unit.importsForTesting,
+            strategy.elementEquivalence) &&
+        strategy.testConstantValues(
+            value1, value2, 'referenced', value1.referenced, value2.referenced);
+  }
+
+  @override
   bool visitNonConstant(
       NonConstantValue value1, covariant NonConstantValue value2) {
     return true;
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 773980d..34549ec 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -2330,6 +2330,8 @@
     }
   }
 
+  LibraryElement get enclosingLibrary => library;
+
   @override
   bool get isDeferred {
     _ensurePrefixResolved();
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index 559e4fb..0c2ea28 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -15,6 +15,7 @@
 import '../constants/constant_system.dart';
 import '../constants/expressions.dart';
 import '../constants/values.dart';
+import '../deferred_load.dart' show OutputUnit;
 import '../diagnostics/messages.dart' show Message, MessageTemplate;
 import '../dump_info.dart' show InfoReporter;
 import '../elements/elements.dart';
@@ -2184,8 +2185,10 @@
     ImportElement deferredImport =
         deferredLoadTask.deferredImportElement(node, elements);
     if (deferredImport != null) {
+      OutputUnit unit =
+          compiler.backend.outputUnitData.outputUnitForMember(field);
       instruction = graph.addDeferredConstant(
-          value, deferredImport, sourceInformation, compiler, closedWorld);
+          value, unit, sourceInformation, compiler, closedWorld);
     } else {
       instruction = graph.addConstant(value, closedWorld,
           sourceInformation: sourceInformation);
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 803a408..0f0724b 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -2530,8 +2530,18 @@
       ConstantValue value = _elementMap.getFieldConstantValue(field);
       if (value != null) {
         if (!field.isAssignable) {
-          stack.add(graph.addConstant(value, closedWorld,
-              sourceInformation: sourceInformation));
+          var unit = compiler.backend.outputUnitData.outputUnitForEntity(field);
+          // TODO(sigmund): this is not equivalent to what the old FE does: if
+          // there is no prefix the old FE wouldn't treat this in any special
+          // way. Also, if the prefix points to a constant in the main output
+          // unit, the old FE would still generate a deferred wrapper here.
+          if (!unit.isMainOutput) {
+            stack.add(graph.addDeferredConstant(
+                value, unit, sourceInformation, compiler, closedWorld));
+          } else {
+            stack.add(graph.addConstant(value, closedWorld,
+                sourceInformation: sourceInformation));
+          }
         } else {
           push(new HStatic(field, _typeInferenceMap.getInferredTypeOf(field),
               sourceInformation));
@@ -4790,7 +4800,7 @@
   // Invariant: *INSIDE_LOOP* > *OUTSIDE_LOOP*
   static const INLINING_NODES_OUTSIDE_LOOP = 15;
   static const INLINING_NODES_OUTSIDE_LOOP_ARG_FACTOR = 3;
-  static const INLINING_NODES_INSIDE_LOOP = 42;
+  static const INLINING_NODES_INSIDE_LOOP = 34;
   static const INLINING_NODES_INSIDE_LOOP_ARG_FACTOR = 4;
 
   static bool canBeInlined(KernelToElementMapForBuilding elementMap,
@@ -4838,6 +4848,7 @@
     return true;
   }
 
+  @override
   defaultNode(ir.Node node) {
     if (tooDifficult) return;
     if (!registerNode()) return;
@@ -4848,6 +4859,7 @@
     node.visitChildren(this);
   }
 
+  @override
   visitReturnStatement(ir.ReturnStatement node) {
     if (!registerNode()) return;
     if (seenReturn) {
@@ -4858,6 +4870,7 @@
     seenReturn = true;
   }
 
+  @override
   visitThrow(ir.Throw node) {
     if (!registerNode()) return;
     if (seenReturn) {
@@ -4876,42 +4889,51 @@
     // isn't in the AST based inline weeder.
   }
 
+  @override
   visitForStatement(ir.ForStatement node) {
     _handleLoop();
   }
 
+  @override
   visitForInStatement(ir.ForInStatement node) {
     _handleLoop();
   }
 
+  @override
   visitWhileStatement(ir.WhileStatement node) {
     _handleLoop();
   }
 
+  @override
   visitDoStatement(ir.DoStatement node) {
     _handleLoop();
   }
 
+  @override
   visitTryCatch(ir.TryCatch node) {
     if (tooDifficult) return;
     tooDifficultReason = 'try';
   }
 
+  @override
   visitTryFinally(ir.TryFinally node) {
     if (tooDifficult) return;
     tooDifficultReason = 'try';
   }
 
+  @override
   visitFunctionExpression(ir.FunctionExpression node) {
     if (!registerNode()) return;
     tooDifficultReason = 'closure';
   }
 
+  @override
   visitFunctionDeclaration(ir.FunctionDeclaration node) {
     if (!registerNode()) return;
     tooDifficultReason = 'closure';
   }
 
+  @override
   visitFunctionNode(ir.FunctionNode node) {
     if (node.asyncMarker != ir.AsyncMarker.Sync) {
       tooDifficultReason = 'async/await';
@@ -4919,6 +4941,36 @@
     }
     node.visitChildren(this);
   }
+
+  @override
+  visitConditionalExpression(ir.ConditionalExpression node) {
+    // Heuristic: In "parameter ? A : B" there is a high probability that
+    // parameter is a constant. Assuming the parameter is constant, we can
+    // compute a count that is bounded by the largest arm rather than the sum of
+    // both arms.
+    ir.Expression condition = node.condition;
+    condition.accept(this);
+    if (tooDifficult) return;
+    int commonPrefixCount = nodeCount;
+
+    node.then.accept(this);
+    if (tooDifficult) return;
+    int thenCount = nodeCount - commonPrefixCount;
+
+    nodeCount = commonPrefixCount;
+    node.otherwise.accept(this);
+    if (tooDifficult) return;
+    int elseCount = nodeCount - commonPrefixCount;
+
+    nodeCount = commonPrefixCount + thenCount + elseCount;
+    if (condition is ir.VariableGet &&
+        condition.variable.parent is ir.FunctionNode) {
+      nodeCount =
+          commonPrefixCount + (thenCount > elseCount ? thenCount : elseCount);
+    }
+    // This is last so that [tooDifficult] is always updated.
+    if (!registerNode()) return;
+  }
 }
 
 /// Class in charge of building try, catch and/or finally blocks. This handles
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index a373b52..2b98deb 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -8,6 +8,7 @@
 import '../compiler.dart' show Compiler;
 import '../constants/constant_system.dart';
 import '../constants/values.dart';
+import '../deferred_load.dart' show OutputUnit;
 import '../elements/entities.dart';
 import '../elements/jumps.dart';
 import '../elements/types.dart';
@@ -273,15 +274,12 @@
 
   HConstant addDeferredConstant(
       ConstantValue constant,
-      ImportEntity import,
+      OutputUnit unit,
       SourceInformation sourceInformation,
       Compiler compiler,
       ClosedWorld closedWorld) {
-    // TODO(sigurdm,johnniwinther): These deferred constants should be created
-    // by the constant evaluator.
-    ConstantValue wrapper = new DeferredConstantValue(constant, import);
-    compiler.backend.outputUnitData
-        .registerConstantDeferredUse(wrapper, import);
+    ConstantValue wrapper = new DeferredGlobalConstantValue(constant, unit);
+    compiler.backend.outputUnitData.registerConstantDeferredUse(wrapper, unit);
     return addConstant(wrapper, closedWorld,
         sourceInformation: sourceInformation);
   }
diff --git a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
index e13b834..d796db4 100644
--- a/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
+++ b/pkg/compiler/lib/src/ssa/value_range_analyzer.dart
@@ -684,6 +684,8 @@
     NumConstantValue constantNum;
     if (constant is DeferredConstantValue) {
       constantNum = constant.referenced;
+    } else if (constant is DeferredGlobalConstantValue) {
+      constantNum = constant.referenced;
     } else {
       constantNum = constant;
     }
diff --git a/pkg/compiler/lib/src/types/constants.dart b/pkg/compiler/lib/src/types/constants.dart
index 382a3e6..0bd4b32 100644
--- a/pkg/compiler/lib/src/types/constants.dart
+++ b/pkg/compiler/lib/src/types/constants.dart
@@ -35,6 +35,12 @@
   }
 
   @override
+  TypeMask visitDeferredGlobal(
+      DeferredGlobalConstantValue constant, ClosedWorld closedWorld) {
+    return constant.referenced.accept(this, closedWorld);
+  }
+
+  @override
   TypeMask visitDouble(DoubleConstantValue constant, ClosedWorld closedWorld) {
     // We have to recognize double constants that are 'is int'.
     if (closedWorld.constantSystem.isInt(constant)) {
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index 2649f62..7335b12 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -667,10 +667,12 @@
 }
 
 class KernelCodegenWorldBuilder extends CodegenWorldBuilderImpl {
-  KernelToWorldBuilder _elementMap;
+  final KernelToWorldBuilder _elementMap;
+  final GlobalLocalsMap _globalLocalsMap;
 
   KernelCodegenWorldBuilder(
       this._elementMap,
+      this._globalLocalsMap,
       ElementEnvironment elementEnvironment,
       NativeBasicData nativeBasicData,
       ClosedWorld world,
@@ -697,8 +699,7 @@
   @override
   void forEachParameterAsLocal(
       FunctionEntity function, void f(Local parameter)) {
-    throw new UnimplementedError(
-        'KernelCodegenWorldBuilder.forEachParameterAsLocal');
+    forEachOrderedParameter(_globalLocalsMap, _elementMap, function, f);
   }
 
   @override
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index a8501fb..c08d246 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -296,17 +296,28 @@
   Map<ClassEntity, _ClassUsage> get classUsageForTesting => _processedClasses;
 
   /// Map of registered usage of static members of live classes.
-  final Map<Entity, _MemberUsage> _staticMemberUsage = <Entity, _MemberUsage>{};
-
-  Map<Entity, _MemberUsage> get staticMemberUsageForTesting =>
-      _staticMemberUsage;
-
-  /// Map of registered usage of instance members of live classes.
-  final Map<MemberEntity, _MemberUsage> _instanceMemberUsage =
+  final Map<MemberEntity, _MemberUsage> _memberUsage =
       <MemberEntity, _MemberUsage>{};
 
-  Map<MemberEntity, _MemberUsage> get instanceMemberUsageForTesting =>
-      _instanceMemberUsage;
+  Map<MemberEntity, _MemberUsage> get staticMemberUsageForTesting {
+    Map<MemberEntity, _MemberUsage> map = <MemberEntity, _MemberUsage>{};
+    _memberUsage.forEach((MemberEntity member, _MemberUsage usage) {
+      if (!member.isInstanceMember) {
+        map[member] = usage;
+      }
+    });
+    return map;
+  }
+
+  Map<MemberEntity, _MemberUsage> get instanceMemberUsageForTesting {
+    Map<MemberEntity, _MemberUsage> map = <MemberEntity, _MemberUsage>{};
+    _memberUsage.forEach((MemberEntity member, _MemberUsage usage) {
+      if (member.isInstanceMember) {
+        map[member] = usage;
+      }
+    });
+    return map;
+  }
 
   /// Map containing instance members of live classes that are not yet live
   /// themselves.
@@ -616,7 +627,7 @@
 
     MemberEntity element = staticUse.element;
     EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
-    _MemberUsage usage = _staticMemberUsage.putIfAbsent(element, () {
+    _MemberUsage usage = _memberUsage.putIfAbsent(element, () {
       _MemberUsage usage = new _MemberUsage(element);
       useSet.addAll(usage.appliedUse);
       return usage;
@@ -749,7 +760,7 @@
     // its metadata parsed and analyzed.
     // Note: this assumes that there are no non-native fields on native
     // classes, which may not be the case when a native class is subclassed.
-    _instanceMemberUsage.putIfAbsent(member, () {
+    _memberUsage.putIfAbsent(member, () {
       bool isNative = _nativeBasicData.isNativeClass(cls);
       _MemberUsage usage = new _MemberUsage(member, isNative: isNative);
       EnumSet<MemberUse> useSet = new EnumSet<MemberUse>();
@@ -816,12 +827,7 @@
 
   @override
   bool isMemberUsed(MemberEntity member) {
-    if (member.isInstanceMember) {
-      _MemberUsage usage = _instanceMemberUsage[member];
-      if (usage != null && usage.hasUse) return true;
-    }
-    _MemberUsage usage = _staticMemberUsage[member];
-    return usage != null && usage.hasUse;
+    return _memberUsage[member]?.hasUse ?? false;
   }
 
   Map<ClassEntity, Set<ClassEntity>> populateHierarchyNodes() {
diff --git a/pkg/compiler/lib/src/universe/world_builder.dart b/pkg/compiler/lib/src/universe/world_builder.dart
index 8c3965d..a5b2922 100644
--- a/pkg/compiler/lib/src/universe/world_builder.dart
+++ b/pkg/compiler/lib/src/universe/world_builder.dart
@@ -24,6 +24,7 @@
 import '../js_backend/native_data.dart' show NativeBasicData, NativeDataBuilder;
 import '../js_backend/no_such_method_registry.dart';
 import '../js_backend/runtime_types.dart';
+import '../js_model/locals.dart';
 import '../kernel/element_map_impl.dart';
 import '../native/enqueue.dart' show NativeResolutionEnqueuer;
 import '../options.dart';
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index ef74950..a91d346 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -867,6 +867,7 @@
     }
 
     ClassSet classSet = getClassSet(base);
+    assert(classSet != null, failedAt(base, "No class set for $base."));
     ClassHierarchyNode node = classSet.node;
     if (query == ClassQuery.EXACT) {
       return node.isExplicitlyInstantiated && !hasConcreteMatch(base, selector);
diff --git a/pkg/compiler/testing_dart.json b/pkg/compiler/testing_dart.json
index 82bbdb7..736a55f 100644
--- a/pkg/compiler/testing_dart.json
+++ b/pkg/compiler/testing_dart.json
@@ -14,83 +14,45 @@
     ],
 
     "exclude": [
-      "^tests/compiler/dart2js/analyze_api_test\\.dart",
-      "^tests/compiler/dart2js/analyze_test_test\\.dart",
-      "^tests/compiler/dart2js/bad_output_io_test\\.dart",
-      "^tests/compiler/dart2js/boolified_operator_test\\.dart",
       "^tests/compiler/dart2js/codegen_helper\\.dart",
       "^tests/compiler/dart2js/constant_expression_evaluate_test\\.dart",
       "^tests/compiler/dart2js/constant_expression_test\\.dart",
-      "^tests/compiler/dart2js/dart2js_batch2_test\\.dart",
-      "^tests/compiler/dart2js/dart2js_batch_test\\.dart",
-      "^tests/compiler/dart2js/dart2js_resolver_test\\.dart",
-      "^tests/compiler/dart2js/data/dart2js_batch2_run\\.dart",
       "^tests/compiler/dart2js/data/mirrors_helper\\.dart",
       "^tests/compiler/dart2js/data/one_line_dart_program\\.dart",
-      "^tests/compiler/dart2js/deferred_custom_element_test\\.dart",
-      "^tests/compiler/dart2js/deferred_dont_inline_deferred_constants_test\\.dart",
-      "^tests/compiler/dart2js/deferred_dont_inline_deferred_globals_test\\.dart",
-      "^tests/compiler/dart2js/deferred_follow_constant_dependencies_test\\.dart",
-      "^tests/compiler/dart2js/deferred_follow_implicit_super_regression_test\\.dart",
-      "^tests/compiler/dart2js/deferred_inline_restrictions_test\\.dart",
-      "^tests/compiler/dart2js/deferred_load_graph_segmentation2_test\\.dart",
-      "^tests/compiler/dart2js/deferred_load_graph_segmentation_test\\.dart",
-      "^tests/compiler/dart2js/deferred_mirrors_test\\.dart",
-      "^tests/compiler/dart2js/deferred_not_in_main_test\\.dart",
-      "^tests/compiler/dart2js/embedded_category_api_boundary_test\\.dart",
-      "^tests/compiler/dart2js/exit_code_test\\.dart",
-      "^tests/compiler/dart2js/expect_annotations2_test\\.dart",
-      "^tests/compiler/dart2js/flatten_test\\.dart",
-      "^tests/compiler/dart2js/gvn_dynamic_field_get_test\\.dart",
-      "^tests/compiler/dart2js/import_mirrors_test\\.dart",
-      "^tests/compiler/dart2js/import_test\\.dart",
+      "^tests/compiler/dart2js/deferred/inline_restrictions_test\\.dart",
+      "^tests/compiler/dart2js/deferred/load_graph_segmentation2_test\\.dart",
+      "^tests/compiler/dart2js/deferred/load_graph_segmentation_test\\.dart",
+      "^tests/compiler/dart2js/mirrors/deferred_mirrors_test\\.dart",
+      "^tests/compiler/dart2js/deferred/not_in_main_test\\.dart",
       "^tests/compiler/dart2js/in_user_code_test\\.dart",
-      "^tests/compiler/dart2js/interop_anonymous_unreachable_test\\.dart",
-      "^tests/compiler/dart2js/js_constant_test\\.dart",
-      "^tests/compiler/dart2js/js_parser_statements_test\\.dart",
-      "^tests/compiler/dart2js/js_spec_optimization_test\\.dart",
       "^tests/compiler/dart2js/jsinterop/world_test\\.dart",
       "^tests/compiler/dart2js/kernel/class_hierarchy_test\\.dart",
       "^tests/compiler/dart2js/kernel/closed_world_test\\.dart",
       "^tests/compiler/dart2js/kernel/visitor_test\\.dart",
-      "^tests/compiler/dart2js/least_upper_bound_test\\.dart",
-      "^tests/compiler/dart2js/library_resolution_test\\.dart",
-      "^tests/compiler/dart2js/list_tracer2_test\\.dart",
-      "^tests/compiler/dart2js/list_tracer3_test\\.dart",
-      "^tests/compiler/dart2js/members_test\\.dart",
       "^tests/compiler/dart2js/memory_compiler\\.dart",
-      "^tests/compiler/dart2js/message_kind_helper\\.dart",
-      "^tests/compiler/dart2js/metadata_test\\.dart",
-      "^tests/compiler/dart2js/minimal_resolution_test\\.dart",
-      "^tests/compiler/dart2js/mirrors_used_test\\.dart",
+      "^tests/compiler/dart2js/old_frontend/message_kind_helper\\.dart",
+      "^tests/compiler/dart2js/old_frontend/metadata_test\\.dart",
+      "^tests/compiler/dart2js/mirrors/mirrors_used_test\\.dart",
       "^tests/compiler/dart2js/mixin_typevariable_test\\.dart",
-      "^tests/compiler/dart2js/mock_compiler\\.dart",
-      "^tests/compiler/dart2js/modulo_remainder_test\\.dart",
       "^tests/compiler/dart2js/needs_no_such_method_test\\.dart",
       "^tests/compiler/dart2js/no_such_method_enabled_test\\.dart",
       "^tests/compiler/dart2js/output_collector\\.dart",
-      "^tests/compiler/dart2js/override_inheritance_test\\.dart",
-      "^tests/compiler/dart2js/package_root_test\\.dart",
-      "^tests/compiler/dart2js/partial_parser_test\\.dart",
-      "^tests/compiler/dart2js/patch_test\\.dart",
+      "^tests/compiler/dart2js/old_frontend/patch_test\\.dart",
       "^tests/compiler/dart2js/quarantined/http_launch_data/http_launch_main_package\\.dart",
       "^tests/compiler/dart2js/quarantined/http_test\\.dart",
-      "^tests/compiler/dart2js/reexport_handled_test\\.dart",
-      "^tests/compiler/dart2js/resolution_test\\.dart",
-      "^tests/compiler/dart2js/resolver_test\\.dart",
+      "^tests/compiler/dart2js/old_frontend/reexport_handled_test\\.dart",
+      "^tests/compiler/dart2js/old_frontend/resolution_test\\.dart",
       "^tests/compiler/dart2js/serialization/analysis_test_helper\\.dart",
       "^tests/compiler/dart2js/serialization/compilation_test_helper\\.dart",
       "^tests/compiler/dart2js/serialization/duplicate_library_test\\.dart",
       "^tests/compiler/dart2js/serialization/equivalence_test\\.dart",
       "^tests/compiler/dart2js/serialization/model_test_helper\\.dart",
       "^tests/compiler/dart2js/serialization/test_helper\\.dart",
-      "^tests/compiler/dart2js/simple_inferrer_closure_test\\.dart",
-      "^tests/compiler/dart2js/simple_inferrer_const_closure2_test\\.dart",
-      "^tests/compiler/dart2js/simple_inferrer_const_closure_default_test\\.dart",
-      "^tests/compiler/dart2js/simple_inferrer_const_closure_test\\.dart",
-      "^tests/compiler/dart2js/simple_inferrer_global_field_closure_test\\.dart",
-      "^tests/compiler/dart2js/simple_inferrer_test\\.dart",
-      "^tests/compiler/dart2js/size_test\\.dart",
+      "^tests/compiler/dart2js/inference/simple_inferrer_closure_test\\.dart",
+      "^tests/compiler/dart2js/inference/simple_inferrer_const_closure2_test\\.dart",
+      "^tests/compiler/dart2js/inference/simple_inferrer_const_closure_test\\.dart",
+      "^tests/compiler/dart2js/inference/simple_inferrer_global_field_closure_test\\.dart",
+      "^tests/compiler/dart2js/inference/simple_inferrer_test\\.dart",
       "^tests/compiler/dart2js/sourcemaps/helpers/source_map_validator_helper\\.dart",
       "^tests/compiler/dart2js/sourcemaps/diff_view\\.dart",
       "^tests/compiler/dart2js/sourcemaps/html_parts\\.dart",
@@ -105,15 +67,9 @@
       "^tests/compiler/dart2js/sourcemaps/stacktrace_test\\.dart",
       "^tests/compiler/dart2js/subtype_test\\.dart",
       "^tests/compiler/dart2js/subtypeset_test\\.dart",
-      "^tests/compiler/dart2js/tdiv_test\\.dart",
       "^tests/compiler/dart2js/token_naming_test\\.dart",
-      "^tests/compiler/dart2js/trust_type_annotations_test\\.dart",
-      "^tests/compiler/dart2js/type_checker_test\\.dart",
-      "^tests/compiler/dart2js/type_equals_test\\.dart",
-      "^tests/compiler/dart2js/type_inference8_test\\.dart",
-      "^tests/compiler/dart2js/type_mask2_test\\.dart",
-      "^tests/compiler/dart2js/type_mask_test\\.dart",
-      "^tests/compiler/dart2js/type_order_test\\.dart",
+      "^tests/compiler/dart2js/inference/type_inference8_test\\.dart",
+      "^tests/compiler/dart2js/inference/type_mask2_test\\.dart",
       "^tests/compiler/dart2js/type_representation_test\\.dart",
       "^tests/compiler/dart2js/type_substitution_test\\.dart",
       "^tests/compiler/dart2js/type_variable_occurrence_test\\.dart",
diff --git a/pkg/dart_internal/lib/extract_type_arguments.dart b/pkg/dart_internal/lib/extract_type_arguments.dart
index 7c93e5f..218d075 100644
--- a/pkg/dart_internal/lib/extract_type_arguments.dart
+++ b/pkg/dart_internal/lib/extract_type_arguments.dart
@@ -9,6 +9,7 @@
 //
 // Only this exact special file is allowed to import "dart:_internal" without
 // causing a compile error.
+// ignore: import_internal_library
 import 'dart:_internal' as internal;
 
 /// Given an [Iterable], invokes [extract], passing the [iterable]'s type
diff --git a/pkg/dev_compiler/bin/dartdevk.dart b/pkg/dev_compiler/bin/dartdevk.dart
index 7a212de..b0d6aec 100755
--- a/pkg/dev_compiler/bin/dartdevk.dart
+++ b/pkg/dev_compiler/bin/dartdevk.dart
@@ -9,14 +9,18 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:bazel_worker/bazel_worker.dart';
 import 'package:dev_compiler/src/kernel/command.dart';
 import 'package:front_end/src/api_unstable/ddc.dart' as fe;
 
 Future main(List<String> args) async {
-  if (args.isNotEmpty && args.last == "--batch") {
-    await runBatch(args.sublist(0, args.length - 1));
+  var parsedArgs = _preprocessArgs(args);
+  if (parsedArgs.isBatch) {
+    await runBatch(parsedArgs.args);
+  } else if (parsedArgs.isWorker) {
+    await new _CompilerWorker(parsedArgs.args).run();
   } else {
-    var result = await compile(args);
+    var result = await compile(parsedArgs.args);
     var succeeded = result.result;
     exitCode = succeeded ? 0 : 1;
   }
@@ -60,3 +64,80 @@
   var time = watch.elapsedMilliseconds;
   print('>>> BATCH END (${tests - failed})/$tests ${time}ms');
 }
+
+/// Runs the compiler worker loop.
+class _CompilerWorker extends AsyncWorkerLoop {
+  /// The original args supplied to the executable.
+  final List<String> _startupArgs;
+
+  _CompilerWorker(this._startupArgs) : super();
+
+  /// Performs each individual work request.
+  Future<WorkResponse> performRequest(WorkRequest request) async {
+    var args = _startupArgs.toList()..addAll(request.arguments);
+
+    var output = new StringBuffer();
+    var result = await runZoned(() => compile(args), zoneSpecification:
+        new ZoneSpecification(print: (self, parent, zone, message) {
+      output.writeln(message.toString());
+    }));
+    return new WorkResponse()
+      ..exitCode = result.result ? 0 : 1
+      ..output = output.toString();
+  }
+}
+
+/// Preprocess arguments to determine whether DDK is used in batch mode or as a
+/// persistent worker.
+///
+/// When used in batch mode, we expect a `--batch` parameter last.
+///
+/// When used as a persistent bazel worker, the `--persistent_worker` might be
+/// present, and an argument of the form `@path/to/file` might be provided. The
+/// latter needs to be replaced by reading all the contents of the
+/// file and expanding them into the resulting argument list.
+_ParsedArgs _preprocessArgs(List<String> args) {
+  if (args.isEmpty) return new _ParsedArgs(false, false, args);
+
+  String lastArg = args.last;
+  if (lastArg == '--batch') {
+    return new _ParsedArgs(true, false, args.sublist(0, args.length - 1));
+  }
+
+  var newArgs = [];
+  bool isWorker = false;
+  var len = args.length;
+  for (int i = 0; i < len; i++) {
+    var arg = args[i];
+    if (i == len - 1 && arg.startsWith('@')) {
+      newArgs.addAll(_readLines(arg.substring(1)));
+    } else if (arg == '--persistent_worker') {
+      isWorker = true;
+    } else {
+      newArgs.add(arg);
+    }
+  }
+  return new _ParsedArgs(false, isWorker, newArgs);
+}
+
+/// Return all lines in a file found at [path].
+Iterable<String> _readLines(String path) {
+  try {
+    return new File(path)
+        .readAsStringSync()
+        .replaceAll('\r\n', '\n')
+        .replaceAll('\r', '\n')
+        .split('\n')
+        .where((String line) => line.isNotEmpty);
+  } on FileSystemException catch (e) {
+    throw new Exception('Failed to read $path: $e');
+  }
+}
+
+class _ParsedArgs {
+  final bool isBatch;
+  final bool isWorker;
+  final List<String> args;
+
+  _ParsedArgs(this.isBatch, this.isWorker, this.args);
+}
diff --git a/pkg/dev_compiler/web/web_command.dart b/pkg/dev_compiler/web/web_command.dart
index b50616f..857af1f 100644
--- a/pkg/dev_compiler/web/web_command.dart
+++ b/pkg/dev_compiler/web/web_command.dart
@@ -100,7 +100,9 @@
 
     try {
       sdkRequest = await HttpRequest.request(sdkUrl,
-          responseType: "arraybuffer", mimeType: "application/octet-stream");
+          responseType: "arraybuffer",
+          mimeType: "application/octet-stream",
+          withCredentials: true);
     } catch (error) {
       onError('Dart sdk summaries failed to load: $error. url: $sdkUrl');
       return null;
diff --git a/pkg/front_end/lib/src/api_prototype/summary_generator.dart b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
index 6557156..8bd633a 100644
--- a/pkg/front_end/lib/src/api_prototype/summary_generator.dart
+++ b/pkg/front_end/lib/src/api_prototype/summary_generator.dart
@@ -35,9 +35,14 @@
 /// are also listed in the build unit sources, otherwise an error results.  (It
 /// is not permitted to refer to a part file declared in another build unit).
 ///
+/// If [truncate] is true, the resulting summary doesn't include any references
+/// to libraries loaded from the input summaries, and only contains code that
+/// was compiled from sources.
+///
 /// The return value is a list of bytes to write to the summary file.
-Future<List<int>> summaryFor(List<Uri> sources, CompilerOptions options) async {
+Future<List<int>> summaryFor(List<Uri> sources, CompilerOptions options,
+    {bool truncate: false}) async {
   return (await generateKernel(new ProcessedOptions(options, true, sources),
-          buildSummary: true, buildProgram: false))
+          buildSummary: true, buildProgram: false, truncateSummary: truncate))
       ?.summary;
 }
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index fc92b87..a7adc1f 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -30,7 +30,7 @@
 
   CompilerOptions options = new CompilerOptions()
     ..target = target
-    ..strongMode = false
+    ..strongMode = target.strongMode
     ..linkedDependencies = [sdkUri]
     ..packagesFileUri = packagesFileUri;
 
diff --git a/pkg/front_end/lib/src/api_unstable/summary_worker.dart b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
new file mode 100644
index 0000000..33c09af
--- /dev/null
+++ b/pkg/front_end/lib/src/api_unstable/summary_worker.dart
@@ -0,0 +1,61 @@
+// 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.
+
+/// API needed by `utils/front_end/summary_worker.dart`, a tool used to compute
+/// summaries in build systems like bazel, pub-build, and package-build.
+
+import 'dart:async' show Future;
+
+import 'package:front_end/src/api_prototype/file_system.dart';
+import 'package:front_end/src/base/processed_options.dart';
+import 'package:front_end/src/kernel_generator_impl.dart';
+import 'package:kernel/target/targets.dart' show Target;
+
+import '../api_prototype/compiler_options.dart';
+import 'compiler_state.dart';
+
+export 'compiler_state.dart';
+
+export '../api_prototype/physical_file_system.dart' show PhysicalFileSystem;
+export '../fasta/fasta_codes.dart' show LocatedMessage;
+export '../fasta/severity.dart' show Severity;
+
+Future<InitializedCompilerState> initializeCompiler(
+    InitializedCompilerState oldState,
+    Uri sdkSummary,
+    Uri packagesFile,
+    List<Uri> inputSummaries,
+    Target target,
+    FileSystem fileSystem) async {
+  // TODO(sigmund): use incremental compiler when it supports our use case.
+  // Note: it is common for the summary worker to invoke the compiler with the
+  // same input summary URIs, but with different contents, so we'd need to be
+  // able to track shas or modification time-stamps to be able to invalidate the
+  // old state appropriately.
+  CompilerOptions options = new CompilerOptions()
+    ..sdkSummary = sdkSummary
+    ..packagesFileUri = packagesFile
+    ..inputSummaries = inputSummaries
+    ..target = target
+    ..fileSystem = fileSystem
+    ..chaseDependencies = true;
+
+  ProcessedOptions processedOpts = new ProcessedOptions(options, true, []);
+
+  return new InitializedCompilerState(options, processedOpts);
+}
+
+Future<List<int>> compile(InitializedCompilerState compilerState,
+    List<Uri> inputs, ProblemHandler problemHandler) async {
+  CompilerOptions options = compilerState.options;
+  options..onProblem = problemHandler;
+
+  ProcessedOptions processedOpts = compilerState.processedOpts;
+  processedOpts.inputs.clear();
+  processedOpts.inputs.addAll(inputs);
+
+  var result = await generateKernel(processedOpts,
+      buildSummary: true, buildProgram: false);
+  return result?.summary;
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/library_builder.dart b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
index dea20dc..7a77519 100644
--- a/pkg/front_end/lib/src/fasta/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/library_builder.dart
@@ -175,8 +175,10 @@
   int finishTypeVariables(ClassBuilder object) => 0;
 
   void becomeCoreLibrary(dynamicType) {
-    addBuilder("dynamic",
-        new DynamicTypeBuilder<T, dynamic>(dynamicType, this, -1), -1);
+    if (scope.local["dynamic"] == null) {
+      addBuilder("dynamic",
+          new DynamicTypeBuilder<T, dynamic>(dynamicType, this, -1), -1);
+    }
   }
 
   void forEach(void f(String name, Builder builder)) {
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 0268c43..dad91b9 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -2066,7 +2066,7 @@
     messageTemplate:
         r"""The integer literal #lexeme can't be represented in 64 bits.""",
     tipTemplate:
-        r"""Try using BigInt (from 'dart:typed_data' library) if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.""",
+        r"""Try using the BigInt class if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.""",
     withArguments: _withArgumentsIntegerLiteralIsOutOfRange);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2083,7 +2083,7 @@
       message:
           """The integer literal $lexeme can't be represented in 64 bits.""",
       tip:
-          """Try using BigInt (from 'dart:typed_data' library) if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.""",
+          """Try using the BigInt class if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808.""",
       arguments: {'token': token});
 }
 
@@ -4174,7 +4174,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageSuperAsExpression = const MessageCode(
     "SuperAsExpression",
-    message: r"""Super calls can't be used as expressions.""",
+    message: r"""Can't use 'super' as an expression.""",
     tip:
         r"""To delegate a constructor to a super constructor, put the super call as an initializer.""");
 
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index e210ad2..0a3c742 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -6,7 +6,8 @@
 
 import 'dart:async' show Future;
 
-import 'package:kernel/kernel.dart' show Program, loadProgramFromBytes;
+import 'package:kernel/kernel.dart'
+    show Library, Program, Source, loadProgramFromBytes;
 
 import '../api_prototype/incremental_kernel_generator.dart'
     show DeltaProgram, IncrementalKernelGenerator;
@@ -76,6 +77,7 @@
   @override
   Future<FastaDelta> computeDelta({Uri entryPoint}) async {
     ticker.reset();
+    entryPoint ??= context.options.inputs.single;
     return context.runInContext<Future<FastaDelta>>((CompilerContext c) async {
       if (platform == null) {
         UriTranslator uriTranslator = await c.options.getUriTranslator();
@@ -98,21 +100,37 @@
 
       List<LibraryBuilder> reusedLibraries =
           computeReusedLibraries(invalidatedUris);
-      ticker.logMs("Decided to reuse ${reusedLibraries.length} libraries");
+      if (userCode != null) {
+        ticker.logMs("Decided to reuse ${reusedLibraries.length}"
+            " of ${userCode.loader.builders.length} libraries");
+      }
 
       userCode = new KernelTarget(
           c.fileSystem, false, platform, platform.uriTranslator,
           uriToSource: c.uriToSource);
       for (LibraryBuilder library in reusedLibraries) {
         userCode.loader.builders[library.uri] = library;
+        if (library.uri.scheme == "dart" && library.uri.path == "core") {
+          userCode.loader.coreLibrary = library;
+        }
       }
 
       userCode.read(entryPoint);
 
       await userCode.buildOutlines();
 
-      return new FastaDelta(
-          await userCode.buildProgram(verify: c.options.verify));
+      // This is not the full program. It is the program including all
+      // libraries loaded from .dill files.
+      Program programWithDill =
+          await userCode.buildProgram(verify: c.options.verify);
+
+      // This is the incremental program.
+      Program program = new Program(
+          nameRoot: programWithDill.root,
+          libraries: new List<Library>.from(userCode.loader.libraries),
+          uriToSource: new Map<Uri, Source>.from(userCode.uriToSource));
+
+      return new FastaDelta(program);
     });
   }
 
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 7f5ddbf..40d70e2 100644
--- a/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/fasta_accessors.dart
@@ -13,6 +13,7 @@
     show
         messageInvalidInitializer,
         messageLoadLibraryTakesNoArguments,
+        messageSuperAsExpression,
         templateIntegerLiteralIsOutOfRange;
 
 import '../messages.dart' show Message;
@@ -352,8 +353,8 @@
     if (!isSuper) {
       return new ShadowThisExpression();
     } else {
-      return helper.deprecated_buildCompileTimeError(
-          "Can't use `super` as an expression.", offsetForToken(token));
+      return helper.buildCompileTimeError(
+          messageSuperAsExpression, offsetForToken(token));
     }
   }
 
@@ -406,6 +407,8 @@
   doInvocation(int offset, Arguments arguments) {
     if (isInitializer) {
       return buildConstructorInitializer(offset, new Name(""), arguments);
+    } else if (isSuper) {
+      return helper.buildCompileTimeError(messageSuperAsExpression, offset);
     } else {
       return helper.buildMethodInvocation(
           new ShadowThisExpression(), callName, arguments, offset,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
index eeb4bad..263fef7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_function_type_alias_builder.dart
@@ -66,7 +66,8 @@
       builtType.typedefReference = target.reference;
       if (typeVariables != null) {
         for (KernelTypeVariableBuilder tv in typeVariables) {
-          tv.parameter.bound = tv?.bound?.build(library);
+          // Follow bound in order to find all cycles
+          tv.bound?.build(library);
           target.typeParameters.add(tv.parameter..parent = target);
         }
       }
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 24a0534..431bd48 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -231,17 +231,18 @@
       loader.resolveTypes();
       List<SourceClassBuilder> myClasses = collectMyClasses();
       loader.checkSemantics(myClasses);
+      loader.finishTypeVariables(objectClassBuilder);
       loader.buildProgram();
       installDefaultSupertypes();
       installDefaultConstructors(myClasses);
       loader.resolveConstructors();
-      loader.finishTypeVariables(objectClassBuilder);
       program =
           link(new List<Library>.from(loader.libraries), nameRoot: nameRoot);
       if (metadataCollector != null) {
         program.addMetadataRepository(metadataCollector.repository);
       }
       loader.computeHierarchy(program);
+      computeCoreTypes();
       loader.checkOverrides(myClasses);
       if (!loader.target.disableTypeInference) {
         loader.prepareTopLevelInference(myClasses);
@@ -513,6 +514,41 @@
         isSyntheticDefault: true);
   }
 
+  void computeCoreTypes() {
+    List<Library> libraries = <Library>[];
+    for (String platformLibrary in const [
+      "dart:_internal",
+      "dart:async",
+      "dart:core",
+      "dart:mirrors"
+    ]) {
+      Uri uri = Uri.parse(platformLibrary);
+      LibraryBuilder library = loader.builders[uri];
+      if (library == null) {
+        // TODO(ahe): This is working around a bug in kernel_driver_test or
+        // kernel_driver.
+        bool found = false;
+        for (Library target in dillTarget.loader.libraries) {
+          if (target.importUri == uri) {
+            libraries.add(target);
+            found = true;
+            break;
+          }
+        }
+        if (!found && uri.path != "mirrors") {
+          // dart:mirrors is optional.
+          throw "Can't find $uri";
+        }
+      } else {
+        libraries.add(library.target);
+      }
+    }
+    Program plaformLibraries = new Program();
+    // Add libraries directly to prevent that their parents are changed.
+    plaformLibraries.libraries.addAll(libraries);
+    loader.computeCoreTypes(plaformLibraries);
+  }
+
   void finishAllConstructors(List<SourceClassBuilder> builders) {
     Class objectClass = this.objectClass;
     for (SourceClassBuilder builder in builders) {
diff --git a/pkg/front_end/lib/src/fasta/parser/class_member_parser.dart b/pkg/front_end/lib/src/fasta/parser/class_member_parser.dart
index 28904d0..381c598 100644
--- a/pkg/front_end/lib/src/fasta/parser/class_member_parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/class_member_parser.dart
@@ -6,8 +6,6 @@
 
 import '../../scanner/token.dart' show Token;
 
-import '../fasta_codes.dart' show Message;
-
 import 'assert.dart' show Assert;
 
 import 'listener.dart' show Listener;
@@ -38,16 +36,6 @@
     }
   }
 
-  @override
-  Token parseRecoverExpression(Token token, Message message) {
-    Token begin = token;
-    // TODO(brianwilkerson): Remove the invocation of `syntheticPreviousToken`
-    // when `parseRecoverExpression` accepts the last consumed token.
-    token = skipExpression(syntheticPreviousToken(token));
-    listener.handleRecoverExpression(begin, message);
-    return token;
-  }
-
   // This method is overridden for two reasons:
   // 1. Avoid generating events for arguments.
   // 2. Avoid calling skip expression for each argument (which doesn't work).
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index ff2104f..27989e2 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -1200,11 +1200,6 @@
   }
 
   @override
-  void handleRecoverExpression(Token token, Message message) {
-    listener?.handleRecoverExpression(token, message);
-  }
-
-  @override
   void handleRecoverableError(
       Message message, Token startToken, Token endToken) {
     listener?.handleRecoverableError(message, startToken, endToken);
@@ -1291,16 +1286,6 @@
   }
 
   @override
-  Token injectGenericCommentTypeAssign(Token token) {
-    return listener?.injectGenericCommentTypeAssign(token);
-  }
-
-  @override
-  Token injectGenericCommentTypeList(Token token) {
-    return listener?.injectGenericCommentTypeList(token);
-  }
-
-  @override
   void logEvent(String name) {
     listener?.logEvent(name);
   }
@@ -1314,13 +1299,6 @@
   List<ParserError> get recoverableErrors => listener?.recoverableErrors;
 
   @override
-  Token replaceTokenWithGenericCommentTypeAssign(
-      Token tokenToStartReplacing, Token tokenWithComment) {
-    return listener?.replaceTokenWithGenericCommentTypeAssign(
-        tokenToStartReplacing, tokenWithComment);
-  }
-
-  @override
   set suppressParseErrors(bool value) {
     listener?.suppressParseErrors = value;
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 8a9cf34..60f90dd 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -208,13 +208,6 @@
 
   void beginExpressionStatement(Token token) {}
 
-  /// Called by [ClassMemberParser] after skipping an expression as error
-  /// recovery. For a stack-based listener, the suggested action is to push
-  /// `null` or a synthetic erroneous expression.
-  void handleRecoverExpression(Token token, Message message) {
-    logEvent("RecoverExpression");
-  }
-
   /// Called by [Parser] after parsing an extraneous expression as error
   /// recovery. For a stack-based listener, the suggested action is to discard
   /// an expression from the stack.
@@ -1215,28 +1208,6 @@
     logEvent("Script");
   }
 
-  /// Matches a generic comment type substitution and injects it into the token
-  /// stream before the given [token].
-  Token injectGenericCommentTypeAssign(Token token) {
-    return token;
-  }
-
-  /// Matches a generic comment type variables or type arguments and injects
-  /// them into the token stream before the given [token].
-  Token injectGenericCommentTypeList(Token token) {
-    return token;
-  }
-
-  /// If the [tokenWithComment] has a type substitution comment /*=T*/, then
-  /// the comment should be scanned into new tokens, and these tokens inserted
-  /// instead of tokens from the [tokenToStartReplacing] to the
-  /// [tokenWithComment]. Returns the first newly inserted token, or the
-  /// original [tokenWithComment].
-  Token replaceTokenWithGenericCommentTypeAssign(
-      Token tokenToStartReplacing, Token tokenWithComment) {
-    return tokenToStartReplacing;
-  }
-
   /// A type has been just parsed, and the parser noticed that the next token
   /// has a type substitution comment /*=T*. So, the type that has been just
   /// parsed should be discarded, and a new type should be parsed instead.
diff --git a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
index c8920ee..b371988 100644
--- a/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
+++ b/pkg/front_end/lib/src/fasta/parser/modifier_context.dart
@@ -478,11 +478,7 @@
       } else if (identical(value, 'static')) {
         token = parseStaticRecovery(token);
       } else if (identical(value, 'typedef')) {
-        // TODO(brianwilkerson): Move this into a `parseTypedefRecovery` method
-        // that can be more sophisticated about skipping the rest of the typedef
-        // declaration.
-        parser.reportRecoverableError(token.next, fasta.messageTypedefInClass);
-        token = token.next;
+        token = parseTypedefRecovery(token);
       } else if (identical(value, 'var')) {
         token = parseVarRecovery(token);
       } else if (token.next.isModifier) {
@@ -637,6 +633,16 @@
     return next;
   }
 
+  Token parseTypedefRecovery(Token token) {
+    token = token.next;
+    assert(optional('typedef', token));
+    parser.reportRecoverableError(token, fasta.messageTypedefInClass);
+    // TODO(brianwilkerson): If the declaration appears to be a valid typedef
+    // then skip the entire declaration so that we generate a single error
+    // (above) rather than many unhelpful errors.
+    return token;
+  }
+
   Token parseVarRecovery(Token token) {
     token = token.next;
     if (token.next.isIdentifier && optional('(', token.next.next)) {
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 3548042..08cfbc2 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -604,14 +604,13 @@
     } else {
       // Recovery
       listener.endImport(importKeyword, null);
-      return parseImportRecovery(uri, token);
+      return parseImportRecovery(uri);
     }
   }
 
   /// Recover given out-of-order clauses in an import directive where [token] is
-  /// the import keyword and [recoveryStart] is the token on which main parsing
-  /// stopped.
-  Token parseImportRecovery(Token token, Token recoveryStart) {
+  /// the import keyword.
+  Token parseImportRecovery(Token token) {
     final primaryListener = listener;
     final recoveryListener = new ImportRecoveryListener(primaryListener);
 
@@ -739,10 +738,10 @@
     Token equalitySign;
     if (optional('==', token)) {
       equalitySign = token;
-      token = parseLiteralStringOrRecoverExpression(token).next;
+      token = ensureLiteralString(token).next;
     }
     expect(')', token);
-    token = parseLiteralStringOrRecoverExpression(token);
+    token = ensureLiteralString(token);
     listener.endConditionalUri(ifKeyword, leftParen, equalitySign);
     return token;
   }
@@ -889,7 +888,7 @@
     Token partKeyword = token.next;
     assert(optional('part', partKeyword));
     listener.beginPart(partKeyword);
-    token = parseLiteralStringOrRecoverExpression(partKeyword);
+    token = ensureLiteralString(partKeyword);
     token = ensureSemicolon(token);
     listener.endPart(partKeyword, token);
     return token;
@@ -911,7 +910,7 @@
       token = parseQualified(ofKeyword, IdentifierContext.partName,
           IdentifierContext.partNameContinuation);
     } else {
-      token = parseLiteralStringOrRecoverExpression(ofKeyword);
+      token = ensureLiteralString(ofKeyword);
     }
     token = ensureSemicolon(token);
     listener.endPartOf(partKeyword, ofKeyword, token, hasName);
@@ -924,12 +923,6 @@
   /// ;
   /// ```
   Token parseMetadataStar(Token token) {
-    // TODO(brianwilkerson): Either remove the invocation of `previous` by
-    // making `injectGenericCommentTypeAssign` accept and return the last
-    // consumed token, or remove the invocation of
-    // `injectGenericCommentTypeAssign` by invoking it outside this method where
-    // invoking it is necessary.
-    token = listener.injectGenericCommentTypeAssign(token.next).previous;
     listener.beginMetadataStar(token.next);
     int count = 0;
     while (optional('@', token.next)) {
@@ -1042,10 +1035,19 @@
   }
 
   Token skipFormalParameters(Token token, MemberKind kind) {
+    Token lastConsumed = token;
     token = token.next;
-    assert(optional('(', token));
     // TODO(ahe): Shouldn't this be `beginFormalParameters`?
     listener.beginOptionalFormalParameters(token);
+    if (!optional('(', token)) {
+      if (optional(';', token)) {
+        reportRecoverableError(token, fasta.messageExpectedOpenParens);
+        listener.endFormalParameters(0, token, token, kind);
+        return lastConsumed;
+      }
+      listener.endFormalParameters(0, token, token, kind);
+      return reportUnexpectedToken(token);
+    }
     Token closeBrace = closeBraceTokenFor(token);
     listener.endFormalParameters(0, token, closeBrace, kind);
     return closeBrace;
@@ -1450,7 +1452,7 @@
       // Recovery
       token = parseClassHeaderRecovery(start, begin, classKeyword);
     }
-    token = parseClassBody(token, start.next);
+    token = parseClassBody(token);
     listener.endClassDeclaration(begin, token);
     return token;
   }
@@ -2030,20 +2032,11 @@
         // analyze the tokens following the const keyword.
         assert(optional("const", token.next));
         beforeBegin = token;
-        token = listener.injectGenericCommentTypeAssign(token.next.next);
-        // TODO(brianwilkerson): Remove the invocation of `previous` when
-        // `injectGenericCommentTypeAssign` returns the last consumed token.
-        begin = beforeToken = token.previous;
-        // TODO(brianwilkerson): Figure out how to remove the invocation of
-        // `previous`.
-        beforeBegin = begin.previous;
-        assert(begin.next == token);
+        begin = beforeToken = token.next;
+        token = beforeToken.next;
       } else {
-        // Modify [begin] in case generic type are injected from a comment.
-        begin = token = listener.injectGenericCommentTypeAssign(token.next);
-        // TODO(brianwilkerson): Remove the invocation of `previous` when
-        // `injectGenericCommentTypeAssign` returns the last consumed token.
-        beforeToken = beforeBegin = begin.previous;
+        beforeToken = beforeBegin = token;
+        token = begin = token.next;
       }
 
       if (optional("void", token)) {
@@ -2140,18 +2133,6 @@
         listener.handleType(begin, token.next);
       }
 
-      {
-        Token newBegin = listener.replaceTokenWithGenericCommentTypeAssign(
-            begin, token.next);
-        if (!identical(newBegin, begin)) {
-          listener.discardTypeReplacedWithCommentTypeAssign();
-          // TODO(brianwilkerson): Remove the invocation of `previous` when
-          // `replaceTokenWithGenericCommentTypeAssign` returns the last
-          // consumed token.
-          return parseType(newBegin.previous);
-        }
-      }
-
       for (int i = 0; i < functionTypes; i++) {
         Token next = token.next;
         assert(optional('Function', next));
@@ -2408,9 +2389,7 @@
         return parseNamedFunctionRest(beforeName, begin, formals, true);
 
       case TypeContinuation.VariablesDeclarationOrExpression:
-        if (looksLikeType &&
-            token.isIdentifier &&
-            isOneOf4(token.next, '=', ';', ',', 'in')) {
+        if (looksLikeType && token.isIdentifier) {
           // TODO(ahe): Generate type events and call
           // parseVariablesDeclarationNoSemicolonRest instead.
           return parseVariablesDeclarationNoSemicolon(beforeBegin);
@@ -2512,11 +2491,6 @@
           reportRecoverableError(nameToken, fasta.messagePrivateNamedParameter);
         }
 
-        // TODO(brianwilkerson): Remove the invocation of `previous` when
-        // `injectGenericCommentTypeList` returns the last consumed token.
-        beforeToken = listener.injectGenericCommentTypeList(token).previous;
-        token = beforeToken.next;
-
         Token inlineFunctionTypeStart;
         if (optional("<", token)) {
           Token closer = closeBraceTokenFor(token);
@@ -2640,9 +2614,6 @@
   /// TODO(ahe): Clean this up.
   Token parseStuffOpt(Token token, Function beginStuff, Function stuffParser,
       Function endStuff, Function handleNoStuff) {
-    // TODO(brianwilkerson): Remove the invocation of `previous` when
-    // `injectGenericCommentTypeList` returns the last consumed token.
-    token = listener.injectGenericCommentTypeList(token.next).previous;
     Token next = token.next;
     if (optional('<', next)) {
       BeginToken begin = next;
@@ -2961,16 +2932,11 @@
       } else if (isGetter) {
         hasName = true;
       }
-      token = listener.injectGenericCommentTypeAssign(token);
-      // TODO(brianwilkerson): Remove the invocation of `previous` when
-      // `injectGenericCommentTypeAssign` returns the last consumed token.
-      previous = token.previous;
       identifiers = identifiers.prepend(previous);
 
       if (!isGeneralizedFunctionType(token)) {
         // Read a potential return type.
         if (isValidTypeReference(token)) {
-          Token type = token;
           // type ...
           if (optional('.', token.next)) {
             // type '.' ...
@@ -2994,22 +2960,6 @@
               }
             }
           }
-          // If the next token after a type has a type substitution comment
-          // /*=T*/, then the previous type tokens and the reference to them
-          // from the link should be replaced.
-          {
-            Token newType = listener.replaceTokenWithGenericCommentTypeAssign(
-                type, token.next);
-            if (!identical(newType, type)) {
-              identifiers = identifiers.tail;
-              token = newType;
-              // TODO(brianwilkerson): Remove the invocation of `previous` when
-              // `replaceTokenWithGenericCommentTypeAssign` returns the last
-              // consumed token.
-              previous = token.previous;
-              continue;
-            }
-          }
         } else if (token.type.isBuiltIn) {
           // Handle the edge case where a built-in keyword is being used
           // as the identifier, as in "abstract<T>() => 0;"
@@ -3314,23 +3264,6 @@
     return token;
   }
 
-  Token parseLiteralStringOrRecoverExpression(Token token) {
-    // TODO(brianwilkerson) Replace invocations of this method with invocations
-    // of `ensureParseLiteralString`.
-    Token next = token.next;
-    if (identical(next.kind, STRING_TOKEN)) {
-      return parseLiteralString(token);
-    } else if (next is ErrorToken) {
-      // TODO(brianwilkerson): Remove the invocation of `previous` when
-      // `reportErrorToken` returns the last consumed token.
-      return reportErrorToken(next, false).previous;
-    } else {
-      reportRecoverableErrorWithToken(next, fasta.templateExpectedString);
-      return parseRecoverExpression(
-          token, fasta.templateExpectedString.withArguments(next));
-    }
-  }
-
   Token expectSemicolon(Token token) {
     return expect(';', token);
   }
@@ -3438,12 +3371,7 @@
   ///   '{' classMember* '}'
   /// ;
   /// ```
-  ///
-  /// The [beforeBody] token is required to be a token that appears somewhere
-  /// before the [token] in the token stream.
-  Token parseClassBody(Token token, Token beforeBody) {
-    // TODO(brianwilkerson): Remove the parameter `beforeBody` because it is not
-    // being used.
+  Token parseClassBody(Token token) {
     Token previousToken = token;
     Token begin = token = token.next;
     listener.beginClassBody(token);
@@ -4376,10 +4304,6 @@
     return token;
   }
 
-  Token parseRecoverExpression(Token token, Message message) {
-    return parseExpression(token);
-  }
-
   int expressionDepth = 0;
   Token parseExpression(Token token) {
     if (expressionDepth++ > 500) {
@@ -4618,11 +4542,7 @@
         next = token.next;
       } else if (optional('(', next)) {
         if (typeArguments == null) {
-          next = listener.injectGenericCommentTypeList(next);
           if (isValidMethodTypeArguments(next)) {
-            // TODO(brianwilkerson): Remove the invocation of `previous` when
-            // `injectGenericCommentTypeList` (invoked above) returns the last
-            // consumed token.
             token = parseTypeArgumentsOpt(token);
             next = token.next;
           } else {
@@ -4641,9 +4561,6 @@
   }
 
   Token parsePrimary(Token token, IdentifierContext context) {
-    // TODO(brianwilkerson): Remove the invocation of `previous` when
-    // `injectGenericCommentTypeList` returns the last consumed token.
-    token = listener.injectGenericCommentTypeList(token.next).previous;
     final kind = token.next.kind;
     if (kind == IDENTIFIER_TOKEN) {
       return parseSendOrFunctionLiteral(token, context);
@@ -5026,11 +4943,8 @@
   /// ;
   /// ```
   Token parseConstExpression(Token token) {
-    Token constKeyword = token.next;
+    Token constKeyword = token = token.next;
     assert(optional('const', constKeyword));
-    // TODO(brianwilkerson) Remove the invocation of `previous` when
-    // `injectGenericCommentTypeList` returns the last consumed token.
-    token = listener.injectGenericCommentTypeList(constKeyword.next).previous;
     Token next = token.next;
     final String value = next.stringValue;
     if ((identical(value, '[')) || (identical(value, '[]'))) {
@@ -5209,10 +5123,7 @@
   }
 
   Token parseSend(Token token, IdentifierContext context) {
-    Token beginToken = ensureIdentifier(token, context);
-    // TODO(brianwilkerson): Remove the invocation of `previous` when
-    // `injectGenericCommentTypeList` returns the last consumed token.
-    token = listener.injectGenericCommentTypeList(beginToken.next).previous;
+    Token beginToken = token = ensureIdentifier(token, context);
     if (isValidMethodTypeArguments(token.next)) {
       token = parseTypeArgumentsOpt(token);
     } else {
@@ -5380,20 +5291,6 @@
   Token parseVariablesDeclarationMaybeSemicolon(
       Token token, bool endWithSemicolon) {
     token = parseMetadataStar(token);
-
-    // If the next token has a type substitution comment /*=T*/, then
-    // the current 'var' token should be repealed and replaced.
-    // TODO(brianwilkerson): Shouldn't this also work when the current token is
-    // something other than `var`, such as in `Object /*=T*/ v;`?
-    if (optional('var', token.next)) {
-      // TODO(brianwilkerson): Remove the invocation of `previous` when
-      // `replaceTokenWithGenericCommentTypeAssign` returns the last consumed
-      // token.
-      token = listener
-          .replaceTokenWithGenericCommentTypeAssign(token.next, token.next.next)
-          .previous;
-    }
-
     token = parseModifiers(token, MemberKind.Local, isVarAllowed: true);
     return parseVariablesDeclarationMaybeSemicolonRest(token, endWithSemicolon);
   }
@@ -5462,6 +5359,7 @@
   /// ;
   /// ```
   Token parseForStatement(Token awaitToken, Token token) {
+    // TODO(brianwilkerson): Consider moving `token` to be the first parameter.
     Token forKeyword = token.next;
     assert(awaitToken == null || optional('await', awaitToken));
     listener.beginForStatement(forKeyword);
@@ -5518,6 +5416,7 @@
   /// ;
   /// ```
   Token parseForRest(Token forToken, Token leftParenthesis, Token token) {
+    // TODO(brianwilkerson): Consider moving `token` to be the first parameter.
     Token leftSeparator = ensureSemicolon(token);
     if (optional(';', leftSeparator.next)) {
       token = parseEmptyStatement(leftSeparator);
@@ -5559,6 +5458,7 @@
   /// ```
   Token parseForInRest(
       Token awaitToken, Token forKeyword, Token leftParenthesis, Token token) {
+    // TODO(brianwilkerson): Consider moving `token` to be the first parameter.
     Token inKeyword = token.next;
     assert(optional('in', inKeyword) || optional(':', inKeyword));
     listener.beginForInExpression(inKeyword.next);
@@ -6047,7 +5947,7 @@
     Token next = token.next;
     if (optional(';', next)) {
       // Report and skip extra semicolons that appear between members.
-      // TODO(brianwilkerson) Provide a more specific error message.
+      // TODO(brianwilkerson): Provide a more specific error message.
       reportRecoverableError(
           next, fasta.templateExpectedClassMember.withArguments(next));
       listener.handleInvalidMember(next);
diff --git a/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart b/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
index e6a502d..6166889 100644
--- a/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
+++ b/pkg/front_end/lib/src/fasta/parser/recovery_listeners.dart
@@ -26,26 +26,12 @@
   RecoveryListener(this._primaryListener);
 
   @override
-  Token injectGenericCommentTypeAssign(Token token) =>
-      _primaryListener.injectGenericCommentTypeAssign(token);
-
-  @override
-  Token injectGenericCommentTypeList(Token token) =>
-      _primaryListener.injectGenericCommentTypeList(token);
-
-  @override
   Token handleUnrecoverableError(Token token, Message message) =>
       _primaryListener.handleUnrecoverableError(token, message);
 
   @override
   Token newSyntheticToken(Token next) =>
       _primaryListener.newSyntheticToken(next);
-
-  @override
-  Token replaceTokenWithGenericCommentTypeAssign(
-          Token tokenToStartReplacing, Token tokenWithComment) =>
-      _primaryListener.replaceTokenWithGenericCommentTypeAssign(
-          tokenToStartReplacing, tokenWithComment);
 }
 
 class ClassHeaderRecoveryListener extends RecoveryListener {
diff --git a/pkg/front_end/lib/src/fasta/parser/top_level_parser.dart b/pkg/front_end/lib/src/fasta/parser/top_level_parser.dart
index 33969af..98dc6fb 100644
--- a/pkg/front_end/lib/src/fasta/parser/top_level_parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/top_level_parser.dart
@@ -15,5 +15,5 @@
 class TopLevelParser extends ClassMemberParser {
   TopLevelParser(Listener listener) : super(listener);
 
-  Token parseClassBody(Token token, Token beforeBody) => skipClassBody(token);
+  Token parseClassBody(Token token) => skipClassBody(token);
 }
diff --git a/pkg/front_end/lib/src/fasta/source/diet_parser.dart b/pkg/front_end/lib/src/fasta/source/diet_parser.dart
index d3002d8..9f1bc91 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_parser.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_parser.dart
@@ -6,37 +6,13 @@
 
 import '../../scanner/token.dart' show Token;
 
-import '../fasta_codes.dart' show messageExpectedOpenParens;
-
-import '../parser.dart'
-    show ClassMemberParser, Listener, MemberKind, closeBraceTokenFor, optional;
+import '../parser.dart' show ClassMemberParser, Listener, MemberKind;
 
 // TODO(ahe): Move this to parser package.
 class DietParser extends ClassMemberParser {
   DietParser(Listener listener) : super(listener);
 
   Token parseFormalParameters(Token token, MemberKind kind) {
-    return skipFormals(token, kind);
-  }
-
-  // TODO(brianwilkerson): Move this method to Parser, and, if possible, merge
-  // it with skipFormalParameters.
-  Token skipFormals(Token token, MemberKind kind) {
-    token = token.next;
-    listener.beginOptionalFormalParameters(token);
-    if (!optional('(', token)) {
-      if (optional(';', token)) {
-        reportRecoverableError(token, messageExpectedOpenParens);
-        listener.endFormalParameters(0, token, token, kind);
-        // TODO(brianwilkerson): Until this method accepts the last consumed
-        // token, this returns the wrong token (it should be the token before
-        // `token`).
-        return token;
-      }
-      return reportUnexpectedToken(token);
-    }
-    Token closeBrace = closeBraceTokenFor(token);
-    listener.endFormalParameters(0, token, closeBrace, kind);
-    return closeBrace;
+    return skipFormalParameters(token, kind);
   }
 }
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index b59d33a..1bfbc7c 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -191,13 +191,6 @@
   }
 
   @override
-  void handleRecoverExpression(Token token, Message message) {
-    debugEvent("RecoverExpression");
-    push(NullValue.Expression);
-    push(token.charOffset);
-  }
-
-  @override
   void endPart(Token partKeyword, Token semicolon) {
     debugEvent("Part");
     int charOffset = popCharOffset();
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 5c71111..ac4e347 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -536,6 +536,9 @@
   void computeHierarchy(Program program) {
     hierarchy = new IncrementalClassHierarchy();
     ticker.logMs("Computed class hierarchy");
+  }
+
+  void computeCoreTypes(Program program) {
     coreTypes = new CoreTypes(program);
     ticker.logMs("Computed core types");
   }
diff --git a/pkg/front_end/lib/src/fasta/source/stack_listener.dart b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
index 6bb8712..7586246 100644
--- a/pkg/front_end/lib/src/fasta/source/stack_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/stack_listener.dart
@@ -305,11 +305,6 @@
   }
 
   @override
-  void handleRecoverExpression(Token token, Message message) {
-    debugEvent("RecoverExpression");
-  }
-
-  @override
   void handleDirectivesOnly() {
     pop(); // Discard the metadata.
   }
diff --git a/pkg/front_end/lib/src/fasta/util/link.dart b/pkg/front_end/lib/src/fasta/util/link.dart
index 87d6b2a..80e21ff 100644
--- a/pkg/front_end/lib/src/fasta/util/link.dart
+++ b/pkg/front_end/lib/src/fasta/util/link.dart
@@ -127,6 +127,7 @@
   // Unsupported Iterable<T> methods.
   //
   bool any(bool f(T e)) => _unsupported('any');
+  Iterable<T> cast<T>() => _unsupported('cast');
   T elementAt(int i) => _unsupported('elementAt');
   Iterable<K> expand<K>(Iterable<K> f(T e)) => _unsupported('expand');
   T firstWhere(bool f(T e), {T orElse()}) => _unsupported('firstWhere');
@@ -134,15 +135,18 @@
     return _unsupported('fold');
   }
 
+  Iterable<T> followedBy(Iterable<T> other) => _unsupported('followedBy');
   T get last => _unsupported('get:last');
   T lastWhere(bool f(T e), {T orElse()}) => _unsupported('lastWhere');
   String join([separator = '']) => _unsupported('join');
   T reduce(T combine(T a, T b)) => _unsupported('reduce');
-  T singleWhere(bool f(T e)) => _unsupported('singleWhere');
+  Iterable<T> retype<T>() => _unsupported('retype');
+  T singleWhere(bool f(T e), {T orElse()}) => _unsupported('singleWhere');
   Iterable<T> skipWhile(bool f(T e)) => _unsupported('skipWhile');
   Iterable<T> take(int n) => _unsupported('take');
   Iterable<T> takeWhile(bool f(T e)) => _unsupported('takeWhile');
   Set<T> toSet() => _unsupported('toSet');
+  Iterable<T> whereType<T>() => _unsupported('whereType');
   Iterable<T> where(bool f(T e)) => _unsupported('where');
 
   _unsupported(String method) => throw new UnsupportedError(method);
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 97effa6..ed9816d 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -15,7 +15,6 @@
 import 'fasta/compiler_context.dart' show CompilerContext;
 import 'fasta/deprecated_problems.dart' show deprecated_InputError, reportCrash;
 import 'fasta/dill/dill_target.dart' show DillTarget;
-import 'fasta/kernel/kernel_outline_shaker.dart';
 import 'fasta/kernel/kernel_target.dart' show KernelTarget;
 import 'fasta/kernel/utils.dart';
 import 'fasta/kernel/verifier.dart';
@@ -27,19 +26,19 @@
 Future<CompilerResult> generateKernel(ProcessedOptions options,
     {bool buildSummary: false,
     bool buildProgram: true,
-    bool trimDependencies: false}) async {
+    bool truncateSummary: false}) async {
   return await CompilerContext.runWithOptions(options, (_) async {
     return await generateKernelInternal(
         buildSummary: buildSummary,
         buildProgram: buildProgram,
-        trimDependencies: trimDependencies);
+        truncateSummary: truncateSummary);
   });
 }
 
 Future<CompilerResult> generateKernelInternal(
     {bool buildSummary: false,
     bool buildProgram: true,
-    bool trimDependencies: false}) async {
+    bool truncateSummary: false}) async {
   var options = CompilerContext.current.options;
   var fs = options.fileSystem;
   if (!await options.validateOptions()) return null;
@@ -100,17 +99,6 @@
         await kernelTarget.buildOutlines(nameRoot: nameRoot);
     List<int> summary = null;
     if (buildSummary) {
-      if (trimDependencies) {
-        // TODO(sigmund): see if it is worth supporting this. Note: trimming the
-        // program is destructive, so if we are emitting summaries and the
-        // program in a single API call, we would need to clone the program here
-        // to avoid deleting pieces that are needed by kernelTarget.buildProgram
-        // below.
-        assert(!buildProgram);
-        var excluded =
-            dillTarget.loader.libraries.map((lib) => lib.importUri).toSet();
-        trimProgram(summaryProgram, (uri) => !excluded.contains(uri));
-      }
       if (options.verify) {
         for (var error in verifyProgram(summaryProgram)) {
           options.report(error, Severity.error);
@@ -120,20 +108,23 @@
         printProgramText(summaryProgram,
             libraryFilter: kernelTarget.isSourceLibrary);
       }
-      if (kernelTarget.errors.isEmpty) {
-        summary = serializeProgram(summaryProgram, excludeUriToSource: true);
-      }
+
+      // Copy the program to exclude the uriToSource map from the summary.
+      //
+      // Note: we don't pass the library argument to the constructor to
+      // preserve the the libraries parent pointer (it should continue to point
+      // to the program within KernelTarget).
+      var trimmedSummaryProgram = new Program(nameRoot: summaryProgram.root)
+        ..libraries.addAll(truncateSummary
+            ? kernelTarget.loader.libraries
+            : summaryProgram.libraries);
+      summary = serializeProgram(trimmedSummaryProgram);
       options.ticker.logMs("Generated outline");
     }
 
     Program program;
     if (buildProgram && kernelTarget.errors.isEmpty) {
       program = await kernelTarget.buildProgram(verify: options.verify);
-      if (trimDependencies) {
-        var excluded =
-            dillTarget.loader.libraries.map((lib) => lib.importUri).toSet();
-        trimProgram(program, (uri) => !excluded.contains(uri));
-      }
       if (options.debugDump) {
         printProgramText(program, libraryFilter: kernelTarget.isSourceLibrary);
       }
diff --git a/pkg/front_end/lib/src/scanner/scanner.dart b/pkg/front_end/lib/src/scanner/scanner.dart
index bd01cfe..6091c28 100644
--- a/pkg/front_end/lib/src/scanner/scanner.dart
+++ b/pkg/front_end/lib/src/scanner/scanner.dart
@@ -557,7 +557,7 @@
     _tail = _tail.setNext(eofToken);
     if (_stackEnd >= 0) {
       _hasUnmatchedGroups = true;
-      // TODO(brianwilkerson) Fix the ungrouped tokens?
+      // TODO(brianwilkerson): Fix the ungrouped tokens?
     }
   }
 
diff --git a/pkg/front_end/lib/src/testing/compiler_common.dart b/pkg/front_end/lib/src/testing/compiler_common.dart
index 67eae73..81ac570 100644
--- a/pkg/front_end/lib/src/testing/compiler_common.dart
+++ b/pkg/front_end/lib/src/testing/compiler_common.dart
@@ -56,10 +56,13 @@
 ///
 /// Wraps [summaryFor] with some default testing options (see [setup]).
 Future<List<int>> summarize(List<String> inputs, Map<String, dynamic> sources,
-    {List<String> inputSummaries: const [], CompilerOptions options}) async {
+    {List<String> inputSummaries: const [],
+    CompilerOptions options,
+    bool truncate: false}) async {
   options ??= new CompilerOptions();
   await setup(options, sources, inputSummaries: inputSummaries);
-  return await summaryFor(inputs.map(toTestUri).toList(), options);
+  return await summaryFor(inputs.map(toTestUri).toList(), options,
+      truncate: truncate);
 }
 
 /// Defines a default set of options for testing:
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 494ec4e..b6047e9 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1446,7 +1446,7 @@
   template: "Expected identifier, but got 'super'."
 
 SuperAsExpression:
-  template: "Super calls can't be used as expressions."
+  template: "Can't use 'super' as an expression."
   tip: "To delegate a constructor to a super constructor, put the super call as an initializer."
 
 SwitchHasCaseAfterDefault:
@@ -1550,7 +1550,7 @@
 
 IntegerLiteralIsOutOfRange:
   template: "The integer literal #lexeme can't be represented in 64 bits."
-  tip: "Try using BigInt (from 'dart:typed_data' library) if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808."
+  tip: "Try using the BigInt class if you need an integer larger than 9,223,372,036,854,775,807 or less than -9,223,372,036,854,775,808."
 
 ColonInPlaceOfIn:
   template: "For-in loops use 'in' rather than a colon."
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index caf5c1c..7b6e9cc 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -18,7 +18,6 @@
 dev_dependencies:
   analyzer: '>=0.30.0 <0.32.0'
   args: '>=0.13.0 <2.0.0'
-  bazel_worker: ^0.1.4
   dart_style: '^1.0.7'
   json_rpc_2: ^2.0.4
   mockito: ^2.0.2
diff --git a/pkg/front_end/test/fasta/incremental_hello_test.dart b/pkg/front_end/test/fasta/incremental_hello_test.dart
new file mode 100644
index 0000000..97f02fc
--- /dev/null
+++ b/pkg/front_end/test/fasta/incremental_hello_test.dart
@@ -0,0 +1,82 @@
+// 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.md file.
+
+library fasta.test.incremental_dynamic_test;
+
+import 'package:async_helper/async_helper.dart' show asyncTest;
+
+import 'package:expect/expect.dart' show Expect;
+
+import "package:front_end/src/api_prototype/compiler_options.dart"
+    show CompilerOptions;
+
+import 'package:front_end/src/base/processed_options.dart'
+    show ProcessedOptions;
+
+import 'package:front_end/src/compute_platform_binaries_location.dart'
+    show computePlatformBinariesLocation;
+
+import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
+
+import 'package:front_end/src/fasta/fasta_codes.dart' show LocatedMessage;
+
+import 'package:front_end/src/fasta/incremental_compiler.dart'
+    show FastaDelta, IncrementalCompiler;
+
+import 'package:front_end/src/fasta/severity.dart' show Severity;
+
+void problemHandler(LocatedMessage message, Severity severity, String formatted,
+    int line, int column) {
+  throw "Unexpected message: $formatted";
+}
+
+test({bool sdkFromSource}) async {
+  final CompilerOptions optionBuilder = new CompilerOptions()
+    ..packagesFileUri = Uri.base.resolve(".packages")
+    ..strongMode = false
+    ..onProblem = problemHandler;
+
+  if (sdkFromSource) {
+    optionBuilder.librariesSpecificationUri =
+        Uri.base.resolve("sdk/lib/libraries.json");
+  } else {
+    optionBuilder.sdkSummary =
+        computePlatformBinariesLocation().resolve("vm_platform.dill");
+  }
+
+  final Uri helloDart = Uri.base.resolve("pkg/front_end/testcases/hello.dart");
+
+  final ProcessedOptions options =
+      new ProcessedOptions(optionBuilder, false, [helloDart]);
+
+  IncrementalCompiler compiler =
+      new IncrementalCompiler(new CompilerContext(options));
+
+  FastaDelta delta = await compiler.computeDelta();
+
+  if (sdkFromSource) {
+    // Expect that the new program contains at least the following libraries:
+    // dart:core, dart:async, and hello.dart.
+    Expect.isTrue(delta.newProgram.libraries.length > 2,
+        "${delta.newProgram.libraries.length} <= 2");
+  } else {
+    // Expect that the new program contains exactly hello.dart.
+    Expect.isTrue(delta.newProgram.libraries.length == 1,
+        "${delta.newProgram.libraries.length} != 1");
+  }
+
+  compiler.invalidate(helloDart);
+
+  delta = await compiler.computeDelta(entryPoint: helloDart);
+  // Expect that the new program contains exactly hello.dart
+  Expect.isTrue(delta.newProgram.libraries.length == 1,
+      "${delta.newProgram.libraries.length} != 1");
+}
+
+void main() {
+  asyncTest(() async {
+    await test(sdkFromSource: true);
+    await test(sdkFromSource: false);
+  });
+}
diff --git a/pkg/front_end/test/summary_generator_test.dart b/pkg/front_end/test/summary_generator_test.dart
index 052e616..36306a2 100644
--- a/pkg/front_end/test/summary_generator_test.dart
+++ b/pkg/front_end/test/summary_generator_test.dart
@@ -100,6 +100,22 @@
     checkDSummary(summaryD);
   });
 
+  test('dependencies not included in truncated summaries', () async {
+    // Note: by default this test is loading the SDK from summaries.
+    var summaryA = await summarize(['a.dart'], allSources, truncate: true);
+    var program = loadProgramFromBytes(summaryA);
+    expect(program.libraries.length, 1);
+    expect(program.libraries.single.importUri.path.endsWith('a.dart'), isTrue);
+
+    var sourcesWithA = new Map.from(allSources);
+    sourcesWithA['a.dill'] = summaryA;
+    var summaryB = await summarize(['b.dart'], sourcesWithA,
+        inputSummaries: ['a.dill'], truncate: true);
+    program = loadProgramFromBytes(summaryB);
+    expect(program.libraries.length, 1);
+    expect(program.libraries.single.importUri.path.endsWith('b.dart'), isTrue);
+  });
+
   test('summarization by default is hermetic', () async {
     var errors = [];
     var options = new CompilerOptions()..onError = (e) => errors.add(e);
diff --git a/pkg/front_end/testcases/ast_builder.status b/pkg/front_end/testcases/ast_builder.status
index 98b16fc..da87982 100644
--- a/pkg/front_end/testcases/ast_builder.status
+++ b/pkg/front_end/testcases/ast_builder.status
@@ -132,6 +132,7 @@
 regress/issue_29983: Crash
 regress/issue_29984: Crash
 regress/issue_29985: Crash
+regress/issue_30838: Crash
 regress/issue_31155: Crash # Issue 31155.
 regress/issue_31157: Crash
 regress/issue_31180: Crash
@@ -139,11 +140,13 @@
 regress/issue_31186: Crash
 regress/issue_31187: Crash
 regress/issue_31198: Crash
+regress/issue_31213: Crash
 reorder_super: Crash
 runtime_checks/implicit_downcast_assert_initializer: Crash
 runtime_checks/implicit_downcast_constructor_initializer: Crash
 runtime_checks_new/for_in_call_kinds: Crash
 statements: Crash
+super_call: Crash
 super_rasta_copy: Crash
 type_variable_as_super: Crash
 uninitialized_fields: Crash
diff --git a/pkg/front_end/testcases/incremental.status b/pkg/front_end/testcases/incremental.status
index d5feffe..c572cda 100644
--- a/pkg/front_end/testcases/incremental.status
+++ b/pkg/front_end/testcases/incremental.status
@@ -3,3 +3,5 @@
 # BSD-style license that can be found in the LICENSE.md file.
 
 # Status file for the test suite ../test/fasta/incremental_test.dart.
+
+dartino/change_in_part.incremental: Crash # Parts aren't handled correctly
diff --git a/pkg/front_end/testcases/rasta/super.dart.strong.expect b/pkg/front_end/testcases/rasta/super.dart.strong.expect
index e4997f7..4de50f1 100644
--- a/pkg/front_end/testcases/rasta/super.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/super.dart.strong.expect
@@ -51,8 +51,8 @@
     self::use(super.{self::A::~}());
     super.{self::A::unary-}();
     self::use(super.{self::A::unary-}());
-    (let final dynamic #t1 = this in let dynamic _ = null in const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:43:5: Error: The getter '' isn't defined for the class '#lib1::C'.\nTry correcting the name to the name of an existing getter, or defining a getter or field named ''.\n    +super;\n    ^"))).+(const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:43:6: Error: Can't use `super` as an expression.\n    +super;\n     ^")));
-    self::use((let final dynamic #t2 = this in let dynamic _ = null in const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:44:9: Error: The getter '' isn't defined for the class '#lib1::C'.\nTry correcting the name to the name of an existing getter, or defining a getter or field named ''.\n    use(+super);\n        ^"))).+(const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:44:10: Error: Can't use `super` as an expression.\n    use(+super);\n         ^"))));
+    (let final dynamic #t1 = this in let dynamic _ = null in const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:43:5: Error: The getter '' isn't defined for the class '#lib1::C'.\nTry correcting the name to the name of an existing getter, or defining a getter or field named ''.\n    +super;\n    ^"))).+(const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:43:6: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n    +super;\n     ^")));
+    self::use((let final dynamic #t2 = this in let dynamic _ = null in const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:44:9: Error: The getter '' isn't defined for the class '#lib1::C'.\nTry correcting the name to the name of an existing getter, or defining a getter or field named ''.\n    use(+super);\n        ^"))).+(const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/rasta/super.dart:44:10: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n    use(+super);\n         ^"))));
     super.{self::A::==}(87);
     self::use(super.{self::A::==}(87));
     !super.{self::A::==}(87);
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart b/pkg/front_end/testcases/regress/issue_30838.dart
new file mode 100644
index 0000000..3125604
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+typedef Foo<S> = S Function<T>(T x);
+int foo<T>(T x) => 3;
+Foo<int> bar() => foo;
+void test1() {
+  bar()<String>("hello");
+}
+
+class A {
+  Foo<int> f;
+  void test() {
+    f<String>("hello");
+  }
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.direct.expect b/pkg/front_end/testcases/regress/issue_30838.dart.direct.expect
new file mode 100644
index 0000000..bf351e8
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.direct.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<S extends core::Object> = <T extends core::Object>(T) → S;
+class A extends core::Object {
+  field <T extends core::Object>(T) → core::int f = null;
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    this.f<core::String>("hello");
+  }
+}
+static method foo<T extends core::Object>(self::foo::T x) → core::int
+  return 3;
+static method bar() → <T extends core::Object>(T) → core::int
+  return self::foo;
+static method test1() → void {
+  self::bar().call<core::String>("hello");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.outline.expect b/pkg/front_end/testcases/regress/issue_30838.dart.outline.expect
new file mode 100644
index 0000000..ea2077a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<S extends core::Object> = <T extends core::Object>(T) → S;
+class A extends core::Object {
+  field <T extends core::Object>(T) → core::int f;
+  default constructor •() → void
+    ;
+  method test() → void
+    ;
+}
+static method foo<T extends core::Object>(self::foo::T x) → core::int
+  ;
+static method bar() → <T extends core::Object>(T) → core::int
+  ;
+static method test1() → void
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/regress/issue_30838.dart.strong.expect b/pkg/front_end/testcases/regress/issue_30838.dart.strong.expect
new file mode 100644
index 0000000..a9dea91
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_30838.dart.strong.expect
@@ -0,0 +1,22 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef Foo<S extends core::Object> = <T extends core::Object>(T) → S;
+class A extends core::Object {
+  field <T extends core::Object>(T) → core::int f = null;
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method test() → void {
+    this.{self::A::f}<core::String>("hello");
+  }
+}
+static method foo<T extends core::Object>(self::foo::T x) → core::int
+  return 3;
+static method bar() → <T extends core::Object>(T) → core::int
+  return self::foo;
+static method test1() → void {
+  self::bar().call<core::String>("hello");
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31198.dart.direct.expect
index 2761375..072b91b 100644
--- a/pkg/front_end/testcases/regress/issue_31198.dart.direct.expect
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.direct.expect
@@ -9,7 +9,7 @@
 }
 class B extends self::A {
   constructor •() → void
-    : final dynamic #t1 = const core::_ConstantExpressionError::•()._throw(new core::_CompileTimeError::•("pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Super calls can't be used as expressions.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n  B(): super().foo() {}\n       ^")).foo() {}
+    : final dynamic #t1 = const core::_ConstantExpressionError::•()._throw(new core::_CompileTimeError::•("pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n  B(): super().foo() {}\n       ^")).foo() {}
 }
 static method bad() → dynamic {
   new self::B::•();
diff --git a/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
index 6dde538..ad0da2f 100644
--- a/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31198.dart.strong.expect
@@ -9,7 +9,7 @@
 }
 class B extends self::A {
   constructor •() → void
-    : final dynamic #t1 = const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Super calls can't be used as expressions.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n  B(): super().foo() {}\n       ^")).foo() {}
+    : final dynamic #t1 = const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/regress/issue_31198.dart:8:8: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n  B(): super().foo() {}\n       ^")).foo() {}
 }
 static method bad() → dynamic {
   new self::B::•();
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart b/pkg/front_end/testcases/regress/issue_31213.dart
new file mode 100644
index 0000000..f4b522a
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart
@@ -0,0 +1,16 @@
+// 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.
+
+typedef C<A, K> = int Function<B>(A x, K y, B v);
+typedef D<K> = C<A, K> Function<A>(int z);
+
+dynamic producer<K>() {
+  return <A>(int v1) {
+    return <B>(A v2, K v3, B v4) => 0;
+  };
+}
+
+main() {
+  assert(producer<String>() is D<String>);
+}
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.direct.expect b/pkg/front_end/testcases/regress/issue_31213.dart.direct.expect
new file mode 100644
index 0000000..860b081
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.direct.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef C<A extends core::Object, K extends core::Object> = <B extends core::Object>(A, K, B) → core::int;
+typedef D<K extends core::Object> = <A extends core::Object>(core::int) → <B extends core::Object>(A, K, B) → core::int;
+static method producer<K extends core::Object>() → dynamic {
+  return <A extends core::Object>(core::int v1) → dynamic {
+    return <B extends core::Object>(A v2, self::producer::K v3, B v4) → dynamic => 0;
+  };
+}
+static method main() → dynamic {
+  assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
+}
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect
new file mode 100644
index 0000000..ab22b45
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.outline.expect
@@ -0,0 +1,10 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef C<A extends core::Object, K extends core::Object> = <B extends core::Object>(A, K, B) → core::int;
+typedef D<K extends core::Object> = <A extends core::Object>(core::int) → <B extends core::Object>(A, K, B) → core::int;
+static method producer<K extends core::Object>() → dynamic
+  ;
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect
new file mode 100644
index 0000000..c6e0d5f
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_31213.dart.strong.expect
@@ -0,0 +1,14 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+typedef C<A extends core::Object, K extends core::Object> = <B extends core::Object>(A, K, B) → core::int;
+typedef D<K extends core::Object> = <A extends core::Object>(core::int) → <B extends core::Object>(A, K, B) → core::int;
+static method producer<K extends core::Object>() → dynamic {
+  return <A extends core::Object>(core::int v1) → <B extends core::Object>(A, self::producer::K, B) → core::int {
+    return <B extends core::Object>(A v2, self::producer::K v3, B v4) → core::int => 0;
+  };
+}
+static method main() → dynamic {
+  assert(self::producer<core::String>() is <A extends core::Object>(core::int) → <B extends core::Object>(A, core::String, B) → core::int);
+}
diff --git a/pkg/front_end/testcases/super_call.dart b/pkg/front_end/testcases/super_call.dart
new file mode 100644
index 0000000..6d9d0a1
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart
@@ -0,0 +1,20 @@
+// 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.
+class A {
+  int call(int x) => x * 2;
+}
+
+class B extends A {
+  int call(int x) => x * 3;
+
+  int call_super() {
+    // Assumes that super() means super.call().
+    // In reality, it is illegal to use it this way.
+    return super(5);
+  }
+}
+
+main() {
+  assert(new B().call_super() == 10);
+}
diff --git a/pkg/front_end/testcases/super_call.dart.direct.expect b/pkg/front_end/testcases/super_call.dart.direct.expect
new file mode 100644
index 0000000..b526f3a0
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.direct.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method call(core::int x) → core::int
+    return x.*(2);
+}
+class B extends self::A {
+  default constructor •() → void
+    : super self::A::•()
+    ;
+  method call(core::int x) → core::int
+    return x.*(3);
+  method call_super() → core::int {
+    return const core::_ConstantExpressionError::•()._throw(new core::_CompileTimeError::•("pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n    return super(5);\n           ^"));
+  }
+}
+static method main() → dynamic {
+  assert(new self::B::•().call_super().==(10));
+}
diff --git a/pkg/front_end/testcases/super_call.dart.outline.expect b/pkg/front_end/testcases/super_call.dart.outline.expect
new file mode 100644
index 0000000..a12055e
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  default constructor •() → void
+    ;
+  method call(core::int x) → core::int
+    ;
+}
+class B extends self::A {
+  default constructor •() → void
+    ;
+  method call(core::int x) → core::int
+    ;
+  method call_super() → core::int
+    ;
+}
+static method main() → dynamic
+  ;
diff --git a/pkg/front_end/testcases/super_call.dart.strong.expect b/pkg/front_end/testcases/super_call.dart.strong.expect
new file mode 100644
index 0000000..3c4e3e0
--- /dev/null
+++ b/pkg/front_end/testcases/super_call.dart.strong.expect
@@ -0,0 +1,24 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+class A extends core::Object {
+  default constructor •() → void
+    : super core::Object::•()
+    ;
+  method call(core::int x) → core::int
+    return x.{core::num::*}(2);
+}
+class B extends self::A {
+  default constructor •() → void
+    : super self::A::•()
+    ;
+  method call(core::int x) → core::int
+    return x.{core::num::*}(3);
+  method call_super() → core::int {
+    return const core::_ConstantExpressionError::•().{core::_ConstantExpressionError::_throw}(new core::_CompileTimeError::•("pkg/front_end/testcases/super_call.dart:14:12: Error: Can't use 'super' as an expression.\nTo delegate a constructor to a super constructor, put the super call as an initializer.\n    return super(5);\n           ^")) as{TypeError} core::int;
+  }
+}
+static method main() → dynamic {
+  assert(new self::B::•().{self::B::call_super}().{core::num::==}(10));
+}
diff --git a/pkg/front_end/tool/_fasta/entry_points.dart b/pkg/front_end/tool/_fasta/entry_points.dart
index db9b11f..d2304b1 100644
--- a/pkg/front_end/tool/_fasta/entry_points.dart
+++ b/pkg/front_end/tool/_fasta/entry_points.dart
@@ -10,6 +10,10 @@
 
 import 'dart:io' show File, exitCode;
 
+import 'package:compiler/src/kernel/dart2js_target.dart' show Dart2jsTarget;
+
+import 'package:kernel/target/targets.dart' show TargetFlags, targets;
+
 import 'package:front_end/src/fasta/compiler_context.dart' show CompilerContext;
 
 import 'package:front_end/src/fasta/deprecated_problems.dart'
@@ -38,6 +42,8 @@
 const int iterations = const int.fromEnvironment("iterations", defaultValue: 1);
 
 compileEntryPoint(List<String> arguments) async {
+  targets["dart2js"] = (TargetFlags flags) => new Dart2jsTarget(flags);
+
   // Timing results for each iteration
   List<double> elapsedTimes = <double>[];
 
diff --git a/pkg/js_ast/lib/src/printer.dart b/pkg/js_ast/lib/src/printer.dart
index f93fabc..82edc93 100644
--- a/pkg/js_ast/lib/src/printer.dart
+++ b/pkg/js_ast/lib/src/printer.dart
@@ -487,6 +487,8 @@
       visitNestedExpression(node.value, EXPRESSION,
           newInForInit: false, newAtStatementBegin: false);
     }
+    // Set the closing position to be before the optional semicolon.
+    currentNode.closingPosition = _charCount;
     outSemicolonLn();
   }
 
diff --git a/pkg/js_ast/test/printer_callback_test.dart b/pkg/js_ast/test/printer_callback_test.dart
index d142e83..6483d28 100644
--- a/pkg/js_ast/test/printer_callback_test.dart
+++ b/pkg/js_ast/test/printer_callback_test.dart
@@ -40,7 +40,7 @@
 }""",
     TestMode.DELIMITER: """
 function(a, b) {
-  return null;
+  return null@4;
 @0}""",
     TestMode.EXIT: """
 function(a@1, b@2) {
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 4e5135b..9300ef0 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -1507,6 +1507,7 @@
     this.isExternal = isExternal;
     this.isConst = isConst;
     this.isForwardingStub = isForwardingStub;
+    this.isForwardingSemiStub = isForwardingSemiStub;
     this.transformerFlags = transformerFlags;
   }
 
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index 5b2ab4e..60b6e3c 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -340,7 +340,7 @@
   TypeParameter freshTypeParameter(TypeParameter node) {
     var fresh = new TypeParameter(node.name);
     substitution[node] = new TypeParameterType(fresh);
-    fresh.bound = node.bound != null ? visit(node.bound) : null;
+    fresh.bound = visit(node.bound);
     return fresh;
   }
 }
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index cea0972..fbbfb81 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -145,6 +145,10 @@
   void declareTypeParameters(List<TypeParameter> parameters) {
     for (int i = 0; i < parameters.length; ++i) {
       var parameter = parameters[i];
+      if (parameter.bound == null) {
+        problem(
+            currentParent, "Missing bound for type parameter '$parameter'.");
+      }
       if (!typeParametersInScope.add(parameter)) {
         problem(parameter, "Type parameter '$parameter' redeclared.");
       }
@@ -577,7 +581,7 @@
       problem(
           currentParent,
           "Type parameter '$parameter' referenced from"
-          " static context, parent is '${parameter.parent}'.");
+          " static context, parent is: '${parameter.parent}'.");
     }
   }
 
diff --git a/pkg/kernel/test/verify_test.dart b/pkg/kernel/test/verify_test.dart
index 7c7c243..32b80f9 100644
--- a/pkg/kernel/test/verify_test.dart
+++ b/pkg/kernel/test/verify_test.dart
@@ -104,7 +104,7 @@
   negativeTest(
       'Class type parameter in static method',
       "Type parameter 'test_lib::TestClass::T' referenced from static context,"
-      " parent is 'test_lib::TestClass'.", (TestHarness test) {
+      " parent is: 'test_lib::TestClass'.", (TestHarness test) {
     return new Procedure(
         new Name('bar'),
         ProcedureKind.Method,
@@ -115,7 +115,7 @@
   negativeTest(
       'Class type parameter in static field',
       "Type parameter 'test_lib::TestClass::T' referenced from static context,"
-      " parent is 'test_lib::TestClass'.", (TestHarness test) {
+      " parent is: 'test_lib::TestClass'.", (TestHarness test) {
     return new Field(new Name('field'),
         initializer:
             new TypeLiteral(new TypeParameterType(test.classTypeParameter)),
diff --git a/pkg/sourcemap_testing/lib/src/stepping_helper.dart b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
index a906bd2..fad7ad9 100644
--- a/pkg/sourcemap_testing/lib/src/stepping_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
@@ -344,6 +344,7 @@
   List<_PointMapping> mappingsOnLines = [];
   for (var line in sourceMap.lines) {
     for (var entry in line.entries) {
+      if (entry.sourceLine == null) continue;
       if (entry.sourceLine >= breakOnLine &&
           entry.sourceLine < breakOnLine + 4) {
         mappingsOnLines.add(new _PointMapping(
diff --git a/pkg/vm/bin/gen_kernel.dart b/pkg/vm/bin/gen_kernel.dart
index 6f1ff40..2fc8bf6 100644
--- a/pkg/vm/bin/gen_kernel.dart
+++ b/pkg/vm/bin/gen_kernel.dart
@@ -12,7 +12,7 @@
 import 'package:kernel/src/tool/batch_util.dart' as batch_util;
 import 'package:kernel/target/targets.dart' show TargetFlags;
 import 'package:kernel/target/vm.dart' show VmTarget;
-import 'package:vm/kernel_front_end.dart' show compileToKernel;
+import 'package:vm/kernel_front_end.dart' show compileToKernel, ErrorDetector;
 
 final ArgParser _argParser = new ArgParser(allowTrailingOptions: true)
   ..addOption('platform',
@@ -60,7 +60,7 @@
   final bool strongMode = options['strong-mode'];
   final bool aot = options['aot'];
 
-  int errors = 0;
+  ErrorDetector errorDetector = new ErrorDetector();
 
   final CompilerOptions compilerOptions = new CompilerOptions()
     ..strongMode = strongMode
@@ -68,18 +68,13 @@
     ..linkedDependencies = <Uri>[Uri.base.resolve(platformKernel)]
     ..packagesFileUri = packages != null ? Uri.base.resolve(packages) : null
     ..reportMessages = true
-    ..onError = (CompilationMessage message) {
-      if ((message.severity != Severity.nit) &&
-          (message.severity != Severity.warning)) {
-        ++errors;
-      }
-    };
+    ..onError = errorDetector;
 
   Program program = await compileToKernel(
       Uri.base.resolve(filename), compilerOptions,
       aot: aot);
 
-  if ((errors > 0) || (program == null)) {
+  if (errorDetector.hasCompilationErrors || (program == null)) {
     return _compileTimeErrorExitCode;
   }
 
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 5ec3890..8df5e10 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -185,6 +185,8 @@
   final bool strong = request[5];
   final int isolateId = request[6];
   final List sourceFiles = request[7];
+  // TODO(bkonyi): this still needs to be hooked in.
+  // final bool suppressWarnings = request[8];
 
   Compiler compiler;
   // TODO(aam): There should be no need to have an option to choose
@@ -284,7 +286,8 @@
     false /* incremental */,
     false /* strong */,
     1 /* isolateId chosen randomly */,
-    null /* source files */
+    null /* source files */,
+    false /* suppress warnings */,
   ];
   _processLoadRequest(request);
 }
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 11506fc..7f7158b 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -7,13 +7,17 @@
 
 import 'dart:async';
 
-import 'package:front_end/src/api_prototype/compiler_options.dart';
+import 'package:front_end/src/api_prototype/compiler_options.dart'
+    show CompilerOptions, ErrorHandler;
 import 'package:front_end/src/api_prototype/kernel_generator.dart'
     show kernelForProgram;
+import 'package:front_end/src/api_prototype/compilation_message.dart'
+    show CompilationMessage, Severity;
+import 'package:front_end/src/fasta/severity.dart' show Severity;
 import 'package:kernel/ast.dart' show Program;
 import 'package:kernel/core_types.dart' show CoreTypes;
 
-import 'transformations/cha_devirtualization.dart' as chaDevirtualization
+import 'transformations/devirtualization.dart' as devirtualization
     show transformProgram;
 
 /// Generates a kernel representation of the program whose main library is in
@@ -23,9 +27,18 @@
 ///
 Future<Program> compileToKernel(Uri source, CompilerOptions options,
     {bool aot: false}) async {
+  // Replace error handler to detect if there are compilation errors.
+  final errorDetector =
+      new ErrorDetector(previousErrorHandler: options.onError);
+  options.onError = errorDetector;
+
   final program = await kernelForProgram(source, options);
 
-  if (aot && (program != null)) {
+  // Restore error handler (in case 'options' are reused).
+  options.onError = errorDetector.previousErrorHandler;
+
+  // Run global transformations only if program is correct.
+  if (aot && (program != null) && !errorDetector.hasCompilationErrors) {
     _runGlobalTransformations(program, options.strongMode);
   }
 
@@ -33,11 +46,25 @@
 }
 
 _runGlobalTransformations(Program program, bool strongMode) {
-  final coreTypes = new CoreTypes(program);
-
-  // TODO(alexmarkov): AOT-specific whole-program transformations.
-
   if (strongMode) {
-    chaDevirtualization.transformProgram(coreTypes, program);
+    final coreTypes = new CoreTypes(program);
+
+    devirtualization.transformProgram(coreTypes, program);
+  }
+}
+
+class ErrorDetector {
+  final ErrorHandler previousErrorHandler;
+  bool hasCompilationErrors = false;
+
+  ErrorDetector({this.previousErrorHandler});
+
+  void call(CompilationMessage message) {
+    if ((message.severity != Severity.nit) &&
+        (message.severity != Severity.warning)) {
+      hasCompilationErrors = true;
+    }
+
+    previousErrorHandler?.call(message);
   }
 }
diff --git a/pkg/vm/lib/transformations/cha_devirtualization.dart b/pkg/vm/lib/transformations/cha_devirtualization.dart
deleted file mode 100644
index cdc2ce4..0000000
--- a/pkg/vm/lib/transformations/cha_devirtualization.dart
+++ /dev/null
@@ -1,132 +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 vm.transformations.cha_devirtualization;
-
-import 'package:kernel/ast.dart';
-import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/class_hierarchy.dart' show ClosedWorldClassHierarchy;
-
-import '../metadata/direct_call.dart';
-
-/// Devirtualization of method invocations based on the class hierarchy
-/// analysis. Assumes strong mode and closed world.
-Program transformProgram(CoreTypes coreTypes, Program program) {
-  new _Devirtualization(coreTypes, program).visitProgram(program);
-  return program;
-}
-
-/// Resolves targets of instance method invocations, property getter
-/// invocations and property setters invocations using strong mode
-/// types / interface targets and closed-world class hierarchy analysis.
-/// If direct target is determined, the invocation node is annotated
-/// with direct call metadata.
-class _Devirtualization extends RecursiveVisitor<Null> {
-  /// Toggles tracing (useful for debugging).
-  static const _trace = const bool.fromEnvironment('trace.devirtualization');
-
-  final ClosedWorldClassHierarchy _hierarchy;
-  final DirectCallMetadataRepository _metadata;
-  Set<Name> _objectMemberNames;
-
-  _Devirtualization(CoreTypes coreTypes, Program program)
-      : _hierarchy = new ClosedWorldClassHierarchy(program),
-        _metadata = new DirectCallMetadataRepository() {
-    _objectMemberNames = new Set<Name>.from(_hierarchy
-        .getInterfaceMembers(coreTypes.objectClass)
-        .map((Member m) => m.name));
-    program.addMetadataRepository(_metadata);
-  }
-
-  bool _isMethod(Member member) => (member is Procedure) && !member.isGetter;
-
-  bool _isFieldOrGetter(Member member) =>
-      (member is Field) || ((member is Procedure) && member.isGetter);
-
-  bool _isLegalTargetForMethodInvocation(Member target, Arguments arguments) {
-    final FunctionNode func = target.function;
-
-    final positionalArgs = arguments.positional.length;
-    if ((positionalArgs < func.requiredParameterCount) ||
-        (positionalArgs > func.positionalParameters.length)) {
-      return false;
-    }
-
-    if (arguments.named.isNotEmpty) {
-      final names = arguments.named.map((v) => v.name).toSet();
-      names.removeAll(func.namedParameters.map((v) => v.name));
-      if (names.isNotEmpty) {
-        return false;
-      }
-    }
-
-    return true;
-  }
-
-  _makeDirectCall(TreeNode node, Member target, Member singleTarget) {
-    if (_trace) {
-      print("[devirt] Resolving ${target} to ${singleTarget}");
-    }
-    _metadata.mapping[node] = new DirectCallMetadata(singleTarget, true);
-  }
-
-  @override
-  visitLibrary(Library node) {
-    if (_trace) {
-      String external = node.isExternal ? " (external)" : "";
-      print("[devirt] Processing library ${node.name}${external}");
-    }
-    super.visitLibrary(node);
-  }
-
-  @override
-  visitMethodInvocation(MethodInvocation node) {
-    super.visitMethodInvocation(node);
-
-    Member target = node.interfaceTarget;
-    if ((target != null) &&
-        _isMethod(target) &&
-        !_objectMemberNames.contains(target.name)) {
-      Member singleTarget =
-          _hierarchy.getSingleTargetForInterfaceInvocation(target);
-      // TODO(dartbug.com/30480): Convert _isLegalTargetForMethodInvocation()
-      // check into an assertion once front-end implements override checks.
-      if ((singleTarget != null) &&
-          _isMethod(singleTarget) &&
-          _isLegalTargetForMethodInvocation(singleTarget, node.arguments)) {
-        _makeDirectCall(node, target, singleTarget);
-      }
-    }
-  }
-
-  @override
-  visitPropertyGet(PropertyGet node) {
-    super.visitPropertyGet(node);
-
-    Member target = node.interfaceTarget;
-    if ((target != null) &&
-        _isFieldOrGetter(target) &&
-        !_objectMemberNames.contains(target.name)) {
-      Member singleTarget =
-          _hierarchy.getSingleTargetForInterfaceInvocation(target);
-      if ((singleTarget != null) && _isFieldOrGetter(singleTarget)) {
-        _makeDirectCall(node, target, singleTarget);
-      }
-    }
-  }
-
-  @override
-  visitPropertySet(PropertySet node) {
-    super.visitPropertySet(node);
-
-    Member target = node.interfaceTarget;
-    if (target != null) {
-      Member singleTarget = _hierarchy
-          .getSingleTargetForInterfaceInvocation(target, setter: true);
-      if (singleTarget != null) {
-        _makeDirectCall(node, target, singleTarget);
-      }
-    }
-  }
-}
diff --git a/pkg/vm/lib/transformations/devirtualization.dart b/pkg/vm/lib/transformations/devirtualization.dart
new file mode 100644
index 0000000..9d8685b
--- /dev/null
+++ b/pkg/vm/lib/transformations/devirtualization.dart
@@ -0,0 +1,153 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library vm.transformations.cha_devirtualization;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/core_types.dart' show CoreTypes;
+import 'package:kernel/class_hierarchy.dart'
+    show ClassHierarchy, ClosedWorldClassHierarchy;
+
+import '../metadata/direct_call.dart';
+
+/// Devirtualization of method invocations based on the class hierarchy
+/// analysis. Assumes strong mode and closed world.
+Program transformProgram(CoreTypes coreTypes, Program program) {
+  new CHADevirtualization(
+          coreTypes, program, new ClosedWorldClassHierarchy(program))
+      .visitProgram(program);
+  return program;
+}
+
+/// Base class for implementing devirtualization of method invocations.
+/// Subclasses should implement particular devirtualization strategy in
+/// [getDirectCall] method. Once direct target is determined, the invocation
+/// node is annotated with direct call metadata.
+abstract class Devirtualization extends RecursiveVisitor<Null> {
+  /// Toggles tracing (useful for debugging).
+  static const _trace = const bool.fromEnvironment('trace.devirtualization');
+
+  final DirectCallMetadataRepository _metadata;
+  Set<Name> _objectMemberNames;
+
+  Devirtualization(
+      CoreTypes coreTypes, Program program, ClassHierarchy hierarchy)
+      : _metadata = new DirectCallMetadataRepository() {
+    _objectMemberNames = new Set<Name>.from(hierarchy
+        .getInterfaceMembers(coreTypes.objectClass)
+        .map((Member m) => m.name));
+    program.addMetadataRepository(_metadata);
+  }
+
+  bool isMethod(Member member) => (member is Procedure) && !member.isGetter;
+
+  bool isFieldOrGetter(Member member) =>
+      (member is Field) || ((member is Procedure) && member.isGetter);
+
+  bool isLegalTargetForMethodInvocation(Member target, Arguments arguments) {
+    final FunctionNode func = target.function;
+
+    final positionalArgs = arguments.positional.length;
+    if ((positionalArgs < func.requiredParameterCount) ||
+        (positionalArgs > func.positionalParameters.length)) {
+      return false;
+    }
+
+    if (arguments.named.isNotEmpty) {
+      final names = arguments.named.map((v) => v.name).toSet();
+      names.removeAll(func.namedParameters.map((v) => v.name));
+      if (names.isNotEmpty) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  DirectCallMetadata getDirectCall(TreeNode node, Member target,
+      {bool setter = false});
+
+  makeDirectCall(TreeNode node, Member target, DirectCallMetadata directCall) {
+    if (_trace) {
+      print("[devirt] Resolving ${target} to ${directCall.target}"
+          " at ${node.location}");
+    }
+    _metadata.mapping[node] = directCall;
+  }
+
+  @override
+  visitLibrary(Library node) {
+    if (_trace) {
+      String external = node.isExternal ? " (external)" : "";
+      print("[devirt] Processing library ${node.name}${external}");
+    }
+    super.visitLibrary(node);
+  }
+
+  @override
+  visitMethodInvocation(MethodInvocation node) {
+    super.visitMethodInvocation(node);
+
+    Member target = node.interfaceTarget;
+    if ((target != null) &&
+        isMethod(target) &&
+        !_objectMemberNames.contains(target.name)) {
+      DirectCallMetadata directCall = getDirectCall(node, target);
+      // TODO(dartbug.com/30480): Convert _isLegalTargetForMethodInvocation()
+      // check into an assertion once front-end implements override checks.
+      if ((directCall != null) &&
+          isMethod(directCall.target) &&
+          isLegalTargetForMethodInvocation(directCall.target, node.arguments)) {
+        makeDirectCall(node, target, directCall);
+      }
+    }
+  }
+
+  @override
+  visitPropertyGet(PropertyGet node) {
+    super.visitPropertyGet(node);
+
+    Member target = node.interfaceTarget;
+    if ((target != null) &&
+        isFieldOrGetter(target) &&
+        !_objectMemberNames.contains(target.name)) {
+      DirectCallMetadata directCall = getDirectCall(node, target);
+      if ((directCall != null) && isFieldOrGetter(directCall.target)) {
+        makeDirectCall(node, target, directCall);
+      }
+    }
+  }
+
+  @override
+  visitPropertySet(PropertySet node) {
+    super.visitPropertySet(node);
+
+    Member target = node.interfaceTarget;
+    if (target != null) {
+      DirectCallMetadata directCall = getDirectCall(node, target, setter: true);
+      if (directCall != null) {
+        makeDirectCall(node, target, directCall);
+      }
+    }
+  }
+}
+
+/// Devirtualization based on the closed-world class hierarchy analysis.
+class CHADevirtualization extends Devirtualization {
+  final ClosedWorldClassHierarchy _hierarchy;
+
+  CHADevirtualization(CoreTypes coreTypes, Program program, this._hierarchy)
+      : super(coreTypes, program, _hierarchy);
+
+  @override
+  DirectCallMetadata getDirectCall(TreeNode node, Member target,
+      {bool setter = false}) {
+    Member singleTarget = _hierarchy
+        .getSingleTargetForInterfaceInvocation(target, setter: setter);
+    if (singleTarget == null) {
+      return null;
+    }
+    return new DirectCallMetadata(singleTarget, true);
+  }
+}
diff --git a/pkg/vm/tool/dart_precompiled_runtime2 b/pkg/vm/tool/dart_precompiled_runtime2
index d8c490a..eeb33e3 100755
--- a/pkg/vm/tool/dart_precompiled_runtime2
+++ b/pkg/vm/tool/dart_precompiled_runtime2
@@ -36,4 +36,5 @@
 exec "$BIN_DIR"/dart_precompiled_runtime               \
      --strong                                          \
      --reify-generic-functions                         \
+     --limit-ints-to-64-bits                           \
      "$@"
diff --git a/pkg/vm/tool/gen_kernel b/pkg/vm/tool/gen_kernel
index 5b96047..e5687b8 100755
--- a/pkg/vm/tool/gen_kernel
+++ b/pkg/vm/tool/gen_kernel
@@ -8,6 +8,13 @@
 
 set -e
 
+# Enable Dart 2.0 fixed-size integers for gen_kernel if running in strong mode.
+for arg in "$@"; do
+  if [ "$arg" == "--strong-mode" ]; then
+    DART_VM_FLAGS="--limit-ints-to-64-bits $DART_VM_FLAGS"
+  fi
+done
+
 function follow_links() {
   file="$1"
   while [ -h "$file" ]; do
@@ -35,4 +42,4 @@
   OUT_DIR="$SDK_DIR/out"
 fi
 
-exec "$DART" "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" $@
+exec "$DART" $DART_VM_FLAGS "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart" $@
diff --git a/pkg/vm/tool/precompiler2 b/pkg/vm/tool/precompiler2
index a3aee3a..faf92c0 100755
--- a/pkg/vm/tool/precompiler2
+++ b/pkg/vm/tool/precompiler2
@@ -67,7 +67,9 @@
 BIN_DIR="$OUT_DIR/$DART_CONFIGURATION"
 
 # Step 1: Generate Kernel binary from the input Dart source.
-"$BIN_DIR"/dart "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart"                        \
+"$BIN_DIR"/dart                                                                \
+     --limit-ints-to-64-bits                                                   \
+     "${SDK_DIR}/pkg/vm/bin/gen_kernel.dart"                                   \
      --platform "${BIN_DIR}/vm_platform_strong.dill"                           \
      --aot                                                                     \
      $PACKAGES                                                                 \
@@ -78,6 +80,7 @@
 exec "$BIN_DIR"/dart_bootstrap                                                 \
      --strong                                                                  \
      --reify-generic-functions                                                 \
+     --limit-ints-to-64-bits                                                   \
      --snapshot-kind=app-aot                                                   \
      --use-blobs                                                               \
      --snapshot="$SNAPSHOT_FILE"                                               \
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 192a332..b1141b2 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -84,13 +84,56 @@
   return Dart_NewExternalTypedData(Dart_TypedData_kUint64, kernel_program, 1);
 }
 
+class WindowsPathSanitizer {
+ public:
+  explicit WindowsPathSanitizer(const char* path) {
+    // For Windows we need to massage the paths a bit according to
+    // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
+    //
+    // Convert
+    // C:\one\two\three
+    // to
+    // /C:/one/two/three
+    //
+    // (see builtin.dart#_sanitizeWindowsPath)
+    intptr_t len = strlen(path);
+    sanitized_uri_ = reinterpret_cast<char*>(malloc(len + 1 + 1));
+    if (sanitized_uri_ == NULL) {
+      OUT_OF_MEMORY();
+    }
+    char* s = sanitized_uri_;
+    if (len > 2 && path[1] == ':') {
+      *s++ = '/';
+    }
+    for (const char *p = path; *p; ++p, ++s) {
+      *s = *p == '\\' ? '/' : *p;
+    }
+    *s = '\0';
+  }
+  ~WindowsPathSanitizer() { free(sanitized_uri_); }
+
+  const char* sanitized_uri() { return sanitized_uri_; }
+
+ private:
+  char* sanitized_uri_;
+
+  DISALLOW_COPY_AND_ASSIGN(WindowsPathSanitizer);
+};
+
 void* DFE::CompileAndReadScript(const char* script_uri,
                                 char** error,
                                 int* exit_code) {
   // TODO(aam): When Frontend is ready, VM should be passing vm_outline.dill
   // instead of vm_platform.dill to Frontend for compilation.
+#if defined(HOST_OS_WINDOWS)
+  WindowsPathSanitizer path_sanitizer(script_uri);
+  const char* sanitized_uri = path_sanitizer.sanitized_uri();
+#else
+  const char* sanitized_uri = script_uri;
+#endif
+
   Dart_KernelCompilationResult result =
-      Dart_CompileToKernel(script_uri, GetPlatformBinaryFilename());
+      Dart_CompileToKernel(sanitized_uri, GetPlatformBinaryFilename());
   switch (result.status) {
     case Dart_KernelCompilationStatus_Ok:
       return Dart_ReadKernelBinary(result.kernel, result.kernel_size,
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 57d33f8..56139f95 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -1425,10 +1425,6 @@
       return kErrorExitCode;
     }
 
-    if (commandline_packages_file != NULL) {
-      AddDependency(commandline_packages_file);
-    }
-
     Dart_QualifiedFunctionName* entry_points =
         ParseEntryPointsManifestIfPresent();
     SetupStubNativeResolversForPrecompilation(entry_points);
diff --git a/runtime/observatory/tests/service/break_on_default_constructor_test.dart b/runtime/observatory/tests/service/break_on_default_constructor_test.dart
new file mode 100644
index 0000000..93901a8
--- /dev/null
+++ b/runtime/observatory/tests/service/break_on_default_constructor_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:async';
+
+import 'package:observatory/debugger.dart';
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/service.dart' as S;
+
+import 'service_test_common.dart';
+import 'test_helper.dart';
+
+class Foo {}
+
+code() {
+  new Foo();
+}
+
+class TestDebugger extends Debugger {
+  TestDebugger(this.isolate, this.stack);
+
+  VM get vm => isolate.vm;
+  Isolate isolate;
+  ServiceMap stack;
+  int currentFrame = 0;
+}
+
+Future<Debugger> initDebugger(Isolate isolate) {
+  return isolate.getStack().then((stack) {
+    return new TestDebugger(isolate, stack);
+  });
+}
+
+List<String> stops = [];
+
+var tests = [
+  hasPausedAtStart,
+  // Load the isolate's libraries
+  (Isolate isolate) async {
+    for (var lib in isolate.libraries) {
+      await lib.load();
+    }
+  },
+
+  (Isolate isolate) async {
+    var debugger = await initDebugger(isolate);
+    var loc = await DebuggerLocation.parse(debugger, 'Foo');
+
+    if (loc.valid) {
+      if (loc.function != null) {
+        try {
+          await debugger.isolate.addBreakpointAtEntry(loc.function);
+        } on S.ServerRpcException catch (e) {
+          if (e.code == S.ServerRpcException.kCannotAddBreakpoint) {
+            // Expected
+          } else {
+            fail("Got unexpected error $e");
+          }
+        }
+      } else {
+        fail("Expected to find function");
+      }
+    } else {
+      fail("Expected to find function");
+    }
+
+    isolate.resume();
+  },
+];
+
+main(args) {
+  runIsolateTestsSynchronous(args, tests,
+      testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/observatory/tests/service/step_through_constructor_test.dart b/runtime/observatory/tests/service/step_through_constructor_test.dart
new file mode 100644
index 0000000..42fc5d6
--- /dev/null
+++ b/runtime/observatory/tests/service/step_through_constructor_test.dart
@@ -0,0 +1,38 @@
+// 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 'test_helper.dart';
+import 'service_test_common.dart';
+
+const int LINE = 17;
+const String file = "step_through_constructor_test.dart";
+
+code() {
+  new Foo();
+}
+
+class Foo {
+  Foo() {
+    print("Hello from Foo!");
+  }
+}
+
+List<String> stops = [];
+List<String> expected = [
+  "$file:${LINE+0}:5", // on 'print'
+  "$file:${LINE+1}:3", // on ending '}'
+];
+
+var tests = [
+  hasPausedAtStart,
+  setBreakpointAtLine(LINE),
+  runStepIntoThroughProgramRecordingStops(stops),
+  checkRecordedStops(stops, expected,
+      debugPrint: true, debugPrintFile: file, debugPrintLine: LINE)
+];
+
+main(args) {
+  runIsolateTestsSynchronous(args, tests,
+      testeeConcurrent: code, pause_on_start: true, pause_on_exit: true);
+}
diff --git a/runtime/tests/vm/dart/single_target_and_method_extractors_test.dart b/runtime/tests/vm/dart/single_target_and_method_extractors_test.dart
new file mode 100644
index 0000000..eb82966
--- /dev/null
+++ b/runtime/tests/vm/dart/single_target_and_method_extractors_test.dart
@@ -0,0 +1,49 @@
+// 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:expect/expect.dart";
+
+// Note: below we are using tear-offs instead of calling methods directly
+// to guarantee very specific compilation order:
+//
+//    - compile main, add get:methodM and get:callMethodM to selector set.
+//    - compile A.callMethodM and add get:createB to selector set.
+//    - compile A.createB and mark B as allocated.
+//
+// Class B is not marked as allocated until A.createB is compiled, which means
+// that when A.callMethodM is compiled only class A has get:methodM method
+// extractor injected.
+//
+// This test is verifying that optimizing compiler does not treat this method
+// extractor as a single target for this.get:methodM call.
+main() {
+  // This adds selector 'get:methodM' into the sent selector set and
+  // marks class A as allocated.
+  new A().methodM;
+
+  // This adds get:callMethodM to the sent selector set.
+  final callMethodMOnA = new A().callMethodM;
+  final b = callMethodMOnA("A");
+  final callMethodMOnB = b.callMethodM;
+  callMethodMOnB("B");
+}
+
+class A {
+  B callMethodM(String expected) {
+    final f = methodM;
+    Expect.equals(expected, f());
+
+    final newB = createB;
+    return newB();
+  }
+
+  B createB() => new B();
+
+  String methodM() => 'A';
+}
+
+class B extends A {
+  @override
+  String methodM() => 'B';
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 407b338..63981da 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -67,9 +67,6 @@
 cc/Mixin_PrivateSuperResolution: Skip
 cc/Mixin_PrivateSuperResolutionCrossLibraryShouldFail: Skip
 
-[ $compiler == dartkp ]
-dart/truncating_ints_test: CompileTimeError # Issue 31339
-
 [ $compiler == precompiler ]
 dart/byte_array_test: Skip # Incompatible flag --disable_alloc_stubs_after_gc
 
@@ -353,6 +350,9 @@
 dart/spawn_infinite_loop_test: Crash # Please triage.
 dart/truncating_ints_test: CompileTimeError # Please triage.
 
+[ $compiler == dartkp && !$strong ]
+dart/truncating_ints_test: Skip # This test cannot be run in dartkp/legacy mode (gen_kernel does not pass --limit-ints-to-64-bits in legacy mode).
+
 [ $compiler == dartkp && ($runtime == dart_precompiled || $runtime == vm) ]
 dart/data_uri_import_test/base64: CompileTimeError
 dart/data_uri_import_test/nocharset: CompileTimeError
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index bc75dd7..1f74a04 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -75,6 +75,10 @@
         # TODO(zra): When the platform-specific timeline code is moved out to
         # the embedder, this can go away.
         "//zircon/system/ulib/fbl",
+        # TODO(US-399): Remove time_service specific code when it is no longer
+        # necessary.
+        "//garnet/public/lib/time_service/fidl",
+        "//garnet/public/lib/app/cpp",
       ]
     }
     public_configs = [ ":libdart_vm_config" ]
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 2db84f6..13190f9 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -719,10 +719,18 @@
       for (intptr_t i = 0; i < class_ids.length(); i++) {
         const intptr_t cid = class_ids[i];
         cls = isolate()->class_table()->At(cid);
+        // Even if we are resolving get:M on a class that has method M
+        // ResolveForReceiverClass would not inject a method extractor into
+        // a class becuase FLAG_lazy_dispatchers is set to false during AOT
+        // compilation. Precompiler however does inject method extractors
+        // (see Precompiler::CheckForNewDynamicFunctions). This means that that
+        // lookup for get:m might overlook a method M in subclass and return
+        // get:m (method extractor for M) from a superclass.
+        // For this reason we abort optimization if lookup returns any
+        // artificial functions that can be inserted lazily.
         target = instr->ResolveForReceiverClass(cls);
-        if (target.IsNull()) {
-          // Can't resolve the target. It might be a noSuchMethod,
-          // call through getter or closurization.
+        if (target.IsNull() || target.IsMethodExtractor() ||
+            target.IsInvokeFieldDispatcher()) {
           single_target = Function::null();
           ic_data = ICData::null();
           break;
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 675351a..a85c3bc 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -878,8 +878,7 @@
   // To check that, we compute value & ~object and skip the write barrier
   // if the bit is not set. We can't destroy the object.
   bic(TMP, value, Operand(object));
-  tsti(TMP, Immediate(kNewObjectAlignmentOffset));
-  b(no_update, EQ);
+  tbz(no_update, TMP, kNewObjectBitPosition);
 }
 
 // Preserves object and value registers.
@@ -888,11 +887,10 @@
                                       Label* no_update) {
   // For the value we are only interested in the new/old bit and the tag bit.
   // And the new bit with the tag bit. The resulting bit will be 0 for a Smi.
-  and_(TMP, value, Operand(value, LSL, kObjectAlignmentLog2 - 1));
+  and_(TMP, value, Operand(value, LSL, kNewObjectBitPosition));
   // And the result with the negated space bit of the object.
   bic(TMP, TMP, Operand(object));
-  tsti(TMP, Immediate(kNewObjectAlignmentOffset));
-  b(no_update, EQ);
+  tbz(no_update, TMP, kNewObjectBitPosition);
 }
 
 void Assembler::StoreIntoObjectOffset(Register object,
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index af1079b..363261f 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -1856,18 +1856,12 @@
 void Assembler::StoreIntoObjectFilter(Register object,
                                       Register value,
                                       Label* no_update) {
-  // For the value we are only interested in the new/old bit and the tag bit.
-  andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag));
-  // Shift the tag bit into the carry.
-  shrl(value, Immediate(1));
-  // Add the tag bits together, if the value is not a Smi the addition will
-  // overflow into the next bit, leaving us with a zero low bit.
-  adcl(value, object);
-  // Mask out higher, uninteresting bits which were polluted by dest.
-  andl(value, Immediate(kObjectAlignment - 1));
-  // Compare with the expected bit pattern.
-  cmpl(value, Immediate((kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
-                        kOldObjectAlignmentOffset + kHeapObjectTag));
+  ASSERT(kNewObjectAlignmentOffset == 4);
+  ASSERT(kHeapObjectTag == 1);
+  // Detect value being ...101 and object being ...001.
+  andl(value, Immediate(7));
+  leal(value, Address(value, object, TIMES_2, 9));
+  testl(value, Immediate(0xf));
   j(NOT_ZERO, no_update, Assembler::kNearJump);
 }
 
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index 74dae8e..123ce31 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -1199,18 +1199,12 @@
 void Assembler::StoreIntoObjectFilter(Register object,
                                       Register value,
                                       Label* no_update) {
-  // For the value we are only interested in the new/old bit and the tag bit.
-  andl(value, Immediate(kNewObjectAlignmentOffset | kHeapObjectTag));
-  // Shift the tag bit into the carry.
-  shrl(value, Immediate(1));
-  // Add the tag bits together, if the value is not a Smi the addition will
-  // overflow into the next bit, leaving us with a zero low bit.
-  adcl(value, object);
-  // Mask out higher, uninteresting bits which were polluted by dest.
-  andl(value, Immediate(kObjectAlignment - 1));
-  // Compare with the expected bit pattern.
-  cmpl(value, Immediate((kNewObjectAlignmentOffset >> 1) + kHeapObjectTag +
-                        kOldObjectAlignmentOffset + kHeapObjectTag));
+  ASSERT(kNewObjectAlignmentOffset == 8);
+  ASSERT(kHeapObjectTag == 1);
+  // Detect value being ...1001 and object being ...0001.
+  andl(value, Immediate(0xf));
+  leal(value, Address(value, object, TIMES_2, 0x15));
+  testl(value, Immediate(0x1f));
   j(NOT_ZERO, no_update, Assembler::kNearJump);
 }
 
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 5a9e9b0..32d0160 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -406,6 +406,7 @@
   RA(Q, movq, 0x8B)
   RR(L, movl, 0x8B)
   RA(Q, leaq, 0x8D)
+  RA(L, leal, 0x8D)
   AR(L, cmpxchgl, 0xB1, 0x0F)
   AR(Q, cmpxchgq, 0xB1, 0x0F)
   RA(L, cmpxchgl, 0xB1, 0x0F)
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index d30b351..35bc55b 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -9207,6 +9207,9 @@
   } else if (tag == kField) {
     FieldHelper field_helper(this);
     field_helper.ReadUntilExcluding(FieldHelper::kEnd);
+  } else if (tag == kClass) {
+    ClassHelper class_helper(this);
+    class_helper.ReadUntilExcluding(ClassHelper::kEnd);
   } else {
     H.ReportError("Unsupported tag at this point: %d.", tag);
     UNREACHABLE();
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 3035c75..9196276 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -322,6 +322,7 @@
   enum Flag {
     kConst = 1 << 0,
     kExternal = 1 << 1,
+    kSyntheticDefault = 1 << 2,
   };
 
   explicit ConstructorHelper(StreamingFlowGraphBuilder* builder) {
@@ -340,6 +341,7 @@
 
   bool IsExternal() { return (flags_ & kExternal) != 0; }
   bool IsConst() { return (flags_ & kConst) != 0; }
+  bool IsSyntheticDefault() { return (flags_ & kSyntheticDefault) != 0; }
 
   NameIndex canonical_name_;
   TokenPosition position_;
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index def0b90..9e776f9 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -2676,35 +2676,53 @@
       if (entry.IsClass()) {
         const Class& klass = Class::Cast(entry);
         entry_script = klass.script();
-        if (!entry_script.IsNull() && script.kernel_script_index() ==
-                                          entry_script.kernel_script_index()) {
+        if (!entry_script.IsNull() &&
+            (script.kernel_script_index() ==
+             entry_script.kernel_script_index()) &&
+            (script.kernel_string_offsets() ==
+             entry_script.kernel_string_offsets())) {
           token_positions.Add(klass.token_pos().value());
         }
-        Array& array = Array::Handle(zone_, klass.fields());
-        Field& field = Field::Handle(Z);
-        for (intptr_t i = 0; i < array.Length(); ++i) {
-          field ^= array.At(i);
-          if (field.kernel_offset() <= 0) {
-            // Skip artificially injected fields.
-            continue;
+        if (klass.is_finalized()) {
+          Array& array = Array::Handle(Z, klass.fields());
+          Field& field = Field::Handle(Z);
+          for (intptr_t i = 0; i < array.Length(); ++i) {
+            field ^= array.At(i);
+            if (field.kernel_offset() <= 0) {
+              // Skip artificially injected fields.
+              continue;
+            }
+            data = field.KernelData();
+            entry_script = field.Script();
+            ProcessTokenPositionsEntry(
+                data, script, entry_script, field.kernel_offset(),
+                field.KernelDataProgramOffset(), Z, &helper, &token_positions,
+                &yield_positions);
           }
-          data = field.KernelData();
-          entry_script = field.Script();
-          ProcessTokenPositionsEntry(
-              data, script, entry_script, field.kernel_offset(),
-              field.KernelDataProgramOffset(), zone_, &helper, &token_positions,
-              &yield_positions);
-        }
-        array = klass.functions();
-        Function& function = Function::Handle(Z);
-        for (intptr_t i = 0; i < array.Length(); ++i) {
-          function ^= array.At(i);
-          data = function.KernelData();
-          entry_script = function.script();
-          ProcessTokenPositionsEntry(
-              data, script, entry_script, function.kernel_offset(),
-              function.KernelDataProgramOffset(), zone_, &helper,
-              &token_positions, &yield_positions);
+          array = klass.functions();
+          Function& function = Function::Handle(Z);
+          for (intptr_t i = 0; i < array.Length(); ++i) {
+            function ^= array.At(i);
+            data = function.KernelData();
+            entry_script = function.script();
+            ProcessTokenPositionsEntry(
+                data, script, entry_script, function.kernel_offset(),
+                function.KernelDataProgramOffset(), Z, &helper,
+                &token_positions, &yield_positions);
+          }
+        } else {
+          // Class isn't finalized yet: read the data attached to it.
+          ASSERT(klass.kernel_offset() > 0);
+          data = lib.kernel_data();
+          ASSERT(!data.IsNull());
+          const intptr_t library_kernel_offset = lib.kernel_offset();
+          ASSERT(library_kernel_offset > 0);
+          const intptr_t class_offset = klass.kernel_offset();
+
+          entry_script = klass.script();
+          ProcessTokenPositionsEntry(data, script, entry_script, class_offset,
+                                     library_kernel_offset, Z, &helper,
+                                     &token_positions, &yield_positions);
         }
       } else if (entry.IsFunction()) {
         const Function& function = Function::Cast(entry);
@@ -2712,7 +2730,7 @@
         entry_script = function.script();
         ProcessTokenPositionsEntry(data, script, entry_script,
                                    function.kernel_offset(),
-                                   function.KernelDataProgramOffset(), zone_,
+                                   function.KernelDataProgramOffset(), Z,
                                    &helper, &token_positions, &yield_positions);
       } else if (entry.IsField()) {
         const Field& field = Field::Cast(entry);
@@ -2724,8 +2742,8 @@
         entry_script = field.Script();
         ProcessTokenPositionsEntry(data, script, entry_script,
                                    field.kernel_offset(),
-                                   field.KernelDataProgramOffset(), zone_,
-                                   &helper, &token_positions, &yield_positions);
+                                   field.KernelDataProgramOffset(), Z, &helper,
+                                   &token_positions, &yield_positions);
       }
     }
   }
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 16e5074..7043b36 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -978,7 +978,7 @@
   EXPECT_VALID(result);
   EXPECT(fits);
 
-  Dart_Handle above_max = Dart_NewIntegerFromHexCString("0x8000000000000000");
+  Dart_Handle above_max = Dart_NewIntegerFromHexCString("0x10000000000000000");
   if (FLAG_limit_ints_to_64_bits) {
     EXPECT(Dart_IsApiError(above_max));
   } else {
@@ -996,7 +996,7 @@
   EXPECT_VALID(result);
   EXPECT(fits);
 
-  Dart_Handle below_min = Dart_NewIntegerFromHexCString("-0x8000000000000001");
+  Dart_Handle below_min = Dart_NewIntegerFromHexCString("-0x10000000000000001");
   if (FLAG_limit_ints_to_64_bits) {
     EXPECT(Dart_IsApiError(below_min));
   } else {
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 6a868de..5c508f0 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -2827,6 +2827,10 @@
   BreakpointLocation* bpt_location = SetBreakpoint(
       script, target_function.token_pos(), target_function.end_token_pos(), -1,
       -1 /* no requested line/col */);
+  if (bpt_location == NULL) {
+    return NULL;
+  }
+
   if (single_shot) {
     return bpt_location->AddSingleShot(this);
   } else {
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index f74e67a..9b804c7 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -34,6 +34,10 @@
             show_kernel_isolate,
             false,
             "Show Kernel service isolate as normal isolate.");
+DEFINE_FLAG(bool,
+            suppress_fe_warnings,
+            false,
+            "Suppress warnings from the FE.");
 
 const char* KernelIsolate::kName = DART_KERNEL_ISOLATE_NAME;
 Dart_IsolateCreateCallback KernelIsolate::create_callback_ = NULL;
@@ -361,6 +365,11 @@
     } else {
       files.type = Dart_CObject_kNull;
     }
+
+    Dart_CObject suppress_warnings;
+    suppress_warnings.type = Dart_CObject_kBool;
+    suppress_warnings.value.as_bool = FLAG_suppress_fe_warnings;
+
     Dart_CObject* message_arr[] = {&tag,
                                    &send_port,
                                    &uri,
@@ -368,7 +377,8 @@
                                    &dart_incremental,
                                    &dart_strong,
                                    &isolate_id,
-                                   &files};
+                                   &files,
+                                   &suppress_warnings};
     message.value.as_array.values = message_arr;
     message.value.as_array.length = ARRAY_SIZE(message_arr);
     // Send the message.
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 50fa689..5d8388c 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -986,6 +986,10 @@
                                      true,   // is_method
                                      false,  // is_closure
                                      &function_node_helper);
+    if (constructor_helper.IsSyntheticDefault()) {
+      function.set_is_debuggable(false);
+    }
+
     function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
     constructor_helper.SetJustRead(ConstructorHelper::kFunction);
     constructor_helper.ReadUntilExcluding(ConstructorHelper::kEnd);
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 1e98057..090091d 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -3565,16 +3565,37 @@
 }
 
 TokenPosition Class::ComputeEndTokenPos() const {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  return TokenPosition::kNoSource;
+#else
   // Return the begin token for synthetic classes.
   if (is_synthesized_class() || IsMixinApplication() || IsTopLevel()) {
     return token_pos();
   }
 
-  Zone* zone = Thread::Current()->zone();
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
   const Script& scr = Script::Handle(zone, script());
   ASSERT(!scr.IsNull());
 
   if (scr.kind() == RawScript::kKernelTag) {
+    ASSERT(kernel_offset() > 0);
+    const Library& lib = Library::Handle(zone, library());
+    const TypedData& kernel_data = TypedData::Handle(zone, lib.kernel_data());
+    ASSERT(!kernel_data.IsNull());
+    const intptr_t library_kernel_offset = lib.kernel_offset();
+    ASSERT(library_kernel_offset > 0);
+    const intptr_t class_offset = kernel_offset();
+
+    kernel::TranslationHelper helper(thread);
+    helper.InitFromScript(scr);
+    kernel::StreamingFlowGraphBuilder builder_(&helper, scr, zone, kernel_data,
+                                               0);
+    builder_.SetOffset(class_offset);
+    kernel::ClassHelper class_helper(&builder_);
+    class_helper.ReadUntilIncluding(kernel::ClassHelper::kEndPosition);
+    if (class_helper.end_position_.IsReal()) return class_helper.end_position_;
+
     TokenPosition largest_seen = token_pos();
 
     // Walk through all functions and get their end_tokens to find the classes
@@ -3613,6 +3634,7 @@
   }
   UNREACHABLE();
   return TokenPosition::kNoSource;
+#endif
 }
 
 int32_t Class::SourceFingerprint() const {
@@ -3799,13 +3821,19 @@
 }
 
 bool Class::IsFutureClass() const {
-  return (library() == Library::AsyncLibrary()) &&
-         (Name() == Symbols::Future().raw());
+  // Looking up future_class in the object store would not work, because
+  // this function is called during class finalization, before the object store
+  // field would be initialized by InitKnownObjects().
+  return (Name() == Symbols::Future().raw()) &&
+         (library() == Library::AsyncLibrary());
 }
 
 bool Class::IsFutureOrClass() const {
-  return (library() == Library::AsyncLibrary()) &&
-         (Name() == Symbols::FutureOr().raw());
+  // Looking up future_or_class in the object store would not work, because
+  // this function is called during class finalization, before the object store
+  // field would be initialized by InitKnownObjects().
+  return (Name() == Symbols::FutureOr().raw()) &&
+         (library() == Library::AsyncLibrary());
 }
 
 // If test_kind == kIsSubtypeOf, checks if type S is a subtype of type T.
@@ -3829,10 +3857,10 @@
   Isolate* isolate = thread->isolate();
   Class& this_class = Class::Handle(zone, cls.raw());
   while (true) {
-    // Check for DynamicType.
     // Each occurrence of DynamicType in type T is interpreted as the dynamic
-    // type, a supertype of all types.
-    if (other.IsDynamicClass()) {
+    // type, a supertype of all types. So are Object and void types.
+    if (other.IsDynamicClass() || other.IsObjectClass() ||
+        other.IsVoidClass()) {
       return true;
     }
     // Check for NullType, which, as of Dart 1.5, is a subtype of (and is more
@@ -3858,11 +3886,6 @@
     if (this_class.IsDynamicClass()) {
       return !isolate->strong() && (test_kind == Class::kIsSubtypeOf);
     }
-    // Check for ObjectType. Any type that is not NullType or DynamicType
-    // (already checked above), is more specific than ObjectType/VoidType.
-    if (other.IsObjectClass() || other.IsVoidClass()) {
-      return true;
-    }
     // If other is neither Object, dynamic or void, then ObjectType/VoidType
     // can't be a subtype of other.
     if (this_class.IsObjectClass() || this_class.IsVoidClass()) {
@@ -3880,7 +3903,7 @@
       // below), we only check a subvector of the proper length.
       // Check for covariance.
       if (other_type_arguments.IsNull() ||
-          other_type_arguments.IsRaw(from_index, num_type_params)) {
+          other_type_arguments.IsTopTypes(from_index, num_type_params)) {
         return true;
       }
       if (type_arguments.IsNull() ||
@@ -4003,8 +4026,7 @@
     }
     const AbstractType& other_type_arg =
         AbstractType::Handle(zone, other_type_arguments.TypeAt(0));
-    if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() ||
-        other_type_arg.IsVoidType()) {
+    if (other_type_arg.IsTopType()) {
       return true;
     }
     if (!type_arguments.IsNull() && IsFutureClass()) {
@@ -4776,6 +4798,18 @@
   return true;
 }
 
+bool TypeArguments::IsTopTypes(intptr_t from_index, intptr_t len) const {
+  ASSERT(Length() >= (from_index + len));
+  AbstractType& type = AbstractType::Handle();
+  for (intptr_t i = 0; i < len; i++) {
+    type = TypeAt(from_index + i);
+    if (type.IsNull() || !type.IsTopType()) {
+      return false;
+    }
+  }
+  return true;
+}
+
 bool TypeArguments::TypeTest(TypeTestKind test_kind,
                              const TypeArguments& other,
                              intptr_t from_index,
@@ -6587,7 +6621,7 @@
   if (Isolate::Current()->strong()) {
     const AbstractType& param_type =
         AbstractType::Handle(ParameterTypeAt(parameter_position));
-    if (param_type.IsDynamicType()) {
+    if (param_type.IsTopType()) {
       return true;
     }
     const AbstractType& other_param_type =
@@ -6687,14 +6721,20 @@
   // Check the result type.
   const AbstractType& other_res_type =
       AbstractType::Handle(zone, other.result_type());
-  if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
-    const AbstractType& res_type = AbstractType::Handle(zone, result_type());
-    if (isolate->strong()) {
+  if (isolate->strong()) {
+    // In strong mode, 'void Function()' is a subtype of 'Object Function()'.
+    if (!other_res_type.IsTopType()) {
+      const AbstractType& res_type = AbstractType::Handle(zone, result_type());
       if (!res_type.IsSubtypeOf(other_res_type, bound_error, bound_trail,
                                 space)) {
         return false;
       }
-    } else {
+    }
+  } else {
+    // In Dart 1.0, 'void Function()' is not a subtype of 'Object Function()',
+    // but it is a subtype of 'dynamic Function()' and of 'void Function()'.
+    if (!other_res_type.IsDynamicType() && !other_res_type.IsVoidType()) {
+      const AbstractType& res_type = AbstractType::Handle(zone, result_type());
       if (res_type.IsVoidType()) {
         return false;
       }
@@ -11521,7 +11561,7 @@
     lib_url = lib.url();
     map.InsertNewOrGetValue(lib_url, lib);
   }
-  // Now rememeber these in the isolate's object store.
+  // Now remember these in the isolate's object store.
   isolate->object_store()->set_libraries(libs);
   isolate->object_store()->set_libraries_map(map.Release());
 }
@@ -15737,7 +15777,7 @@
   Isolate* isolate = thread->isolate();
   const Class& cls = Class::Handle(zone, clazz());
   if (cls.IsClosureClass()) {
-    if (other.IsObjectType() || other.IsDartFunctionType() ||
+    if (other.IsTopType() || other.IsDartFunctionType() ||
         other.IsDartClosureType()) {
       return true;
     }
@@ -15754,9 +15794,7 @@
       if (instantiated_other.IsTypeRef()) {
         instantiated_other = TypeRef::Cast(instantiated_other).type();
       }
-      if (instantiated_other.IsDynamicType() ||
-          instantiated_other.IsObjectType() ||
-          instantiated_other.IsVoidType() ||
+      if (instantiated_other.IsTopType() ||
           instantiated_other.IsDartFunctionType()) {
         return true;
       }
@@ -15812,8 +15850,7 @@
     if (instantiated_other.IsTypeRef()) {
       instantiated_other = TypeRef::Cast(instantiated_other).type();
     }
-    if (instantiated_other.IsDynamicType() ||
-        instantiated_other.IsObjectType() || instantiated_other.IsVoidType()) {
+    if (instantiated_other.IsTopType()) {
       return true;
     }
   }
@@ -15877,8 +15914,7 @@
         TypeArguments::Handle(zone, other.arguments());
     const AbstractType& other_type_arg =
         AbstractType::Handle(zone, other_type_arguments.TypeAt(0));
-    if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() ||
-        other_type_arg.IsVoidType()) {
+    if (other_type_arg.IsTopType()) {
       return true;
     }
     if (Class::Handle(zone, clazz()).IsFutureClass()) {
@@ -16448,76 +16484,93 @@
   if (IsCanonical()) {
     return raw() == Object::dynamic_type().raw();
   }
-  return HasResolvedTypeClass() && (type_class() == Object::dynamic_class());
+  return HasResolvedTypeClass() && (type_class_id() == kDynamicCid);
 }
 
 bool AbstractType::IsVoidType() const {
+  // The void type is always canonical, because void is a keyword.
   return raw() == Object::void_type().raw();
 }
 
+bool AbstractType::IsObjectType() const {
+  return HasResolvedTypeClass() && (type_class_id() == kInstanceCid);
+}
+
+bool AbstractType::IsTopType() const {
+  if (IsVoidType()) {
+    return true;
+  }
+  if (!HasResolvedTypeClass()) {
+    return false;
+  }
+  classid_t cid = type_class_id();
+  return (cid == kDynamicCid) || (cid == kInstanceCid);
+}
+
 bool AbstractType::IsNullType() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
-         (type_class() == Isolate::Current()->object_store()->null_class());
+  return HasResolvedTypeClass() && (type_class_id() == kNullCid);
 }
 
 bool AbstractType::IsBoolType() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
-         (type_class() == Isolate::Current()->object_store()->bool_class());
+  return HasResolvedTypeClass() && (type_class_id() == kBoolCid);
 }
 
 bool AbstractType::IsIntType() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
+  return HasResolvedTypeClass() &&
          (type_class() == Type::Handle(Type::IntType()).type_class());
 }
 
 bool AbstractType::IsInt64Type() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
+  return HasResolvedTypeClass() &&
          (type_class() == Type::Handle(Type::Int64Type()).type_class());
 }
 
 bool AbstractType::IsDoubleType() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
+  return HasResolvedTypeClass() &&
          (type_class() == Type::Handle(Type::Double()).type_class());
 }
 
 bool AbstractType::IsFloat32x4Type() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
+  // kFloat32x4Cid refers to the private class and cannot be used here.
+  return HasResolvedTypeClass() &&
          (type_class() == Type::Handle(Type::Float32x4()).type_class());
 }
 
 bool AbstractType::IsFloat64x2Type() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
+  // kFloat64x2Cid refers to the private class and cannot be used here.
+  return HasResolvedTypeClass() &&
          (type_class() == Type::Handle(Type::Float64x2()).type_class());
 }
 
 bool AbstractType::IsInt32x4Type() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
+  // kInt32x4Cid refers to the private class and cannot be used here.
+  return HasResolvedTypeClass() &&
          (type_class() == Type::Handle(Type::Int32x4()).type_class());
 }
 
 bool AbstractType::IsNumberType() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
-         (type_class() == Type::Handle(Type::Number()).type_class());
+  return HasResolvedTypeClass() && (type_class_id() == kNumberCid);
 }
 
 bool AbstractType::IsSmiType() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
-         (type_class() == Type::Handle(Type::SmiType()).type_class());
+  return HasResolvedTypeClass() && (type_class_id() == kSmiCid);
 }
 
 bool AbstractType::IsStringType() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
+  return HasResolvedTypeClass() &&
          (type_class() == Type::Handle(Type::StringType()).type_class());
 }
 
 bool AbstractType::IsDartFunctionType() const {
-  return !IsFunctionType() && HasResolvedTypeClass() &&
+  return HasResolvedTypeClass() &&
          (type_class() == Type::Handle(Type::DartFunctionType()).type_class());
 }
 
 bool AbstractType::IsDartClosureType() const {
+  // Non-typedef function types have '_Closure' class as type class, but are not
+  // the Dart '_Closure' type.
   return !IsFunctionType() && HasResolvedTypeClass() &&
-         (type_class() == Isolate::Current()->object_store()->closure_class());
+         (type_class_id() == kClosureCid);
 }
 
 bool AbstractType::TypeTest(TypeTestKind test_kind,
@@ -16558,8 +16611,7 @@
   // comparing function-types).
   // As of Dart 1.5, the Null type is a subtype of (and is more specific than)
   // any type.
-  if (other.IsObjectType() || other.IsDynamicType() || other.IsVoidType() ||
-      IsNullType()) {
+  if (other.IsTopType() || IsNullType()) {
     return true;
   }
   Thread* thread = Thread::Current();
@@ -16724,8 +16776,7 @@
         TypeArguments::Handle(zone, other.arguments());
     const AbstractType& other_type_arg =
         AbstractType::Handle(zone, other_type_arguments.TypeAt(0));
-    if (other_type_arg.IsObjectType() || other_type_arg.IsDynamicType() ||
-        other_type_arg.IsVoidType()) {
+    if (other_type_arg.IsTopType()) {
       return true;
     }
     // Retry the TypeTest function after unwrapping type arg of FutureOr.
@@ -17105,7 +17156,7 @@
   if (IsMalbounded() != other_type.IsMalbounded()) {
     return false;  // Do not drop bound error.
   }
-  if (type_class() != other_type.type_class()) {
+  if (type_class_id() != other_type.type_class_id()) {
     return false;
   }
   if (!IsFinalized() || !other_type.IsFinalized()) {
@@ -17413,13 +17464,11 @@
 
   // Since void is a keyword, we never have to canonicalize the void type after
   // it is canonicalized once by the vm isolate. The parser does the mapping.
-  ASSERT((type_class() != Object::void_class()) ||
-         (isolate == Dart::vm_isolate()));
+  ASSERT((type_class_id() != kVoidCid) || (isolate == Dart::vm_isolate()));
 
   // Since dynamic is not a keyword, the parser builds a type that requires
   // canonicalization.
-  if ((type_class() == Object::dynamic_class()) &&
-      (isolate != Dart::vm_isolate())) {
+  if ((type_class_id() == kDynamicCid) && (isolate != Dart::vm_isolate())) {
     ASSERT(Object::dynamic_type().IsCanonical());
     return Object::dynamic_type().raw();
   }
@@ -17527,7 +17576,7 @@
   if (IsMalformed() || IsRecursive()) {
     return true;
   }
-  if (type_class() == Object::dynamic_class()) {
+  if (type_class_id() == kDynamicCid) {
     return (raw() == Object::dynamic_type().raw());
   }
   Zone* zone = thread->zone();
@@ -17593,7 +17642,7 @@
   ASSERT(IsFinalized());
   uint32_t result = 1;
   if (IsMalformed()) return result;
-  result = CombineHashes(result, Class::Handle(type_class()).id());
+  result = CombineHashes(result, type_class_id());
   result = CombineHashes(result, TypeArguments::Handle(arguments()).Hash());
   if (IsFunctionType()) {
     const Function& sig_fun = Function::Handle(signature());
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 9da8f8c..5b9fdea 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -5665,6 +5665,11 @@
     return IsDynamicTypes(true, 0, len);
   }
 
+  // Check if the subvector of length 'len' starting at 'from_index' of this
+  // type argument vector consists solely of DynamicType, ObjectType, or
+  // VoidType.
+  bool IsTopTypes(intptr_t from_index, intptr_t len) const;
+
   // Check the subtype relationship, considering only a subvector of length
   // 'len' starting at 'from_index'.
   bool IsSubtypeOf(const TypeArguments& other,
@@ -5985,10 +5990,12 @@
   // Check if this type represents the 'Null' type.
   bool IsNullType() const;
 
-  bool IsObjectType() const {
-    return !IsFunctionType() && HasResolvedTypeClass() &&
-           Class::Handle(type_class()).IsObjectClass();
-  }
+  // Check if this type represents the 'Object' type.
+  bool IsObjectType() const;
+
+  // Check if this type represents a top type, i.e. 'dynamic', 'Object', or
+  // 'void' type.
+  bool IsTopType() const;
 
   // Check if this type represents the 'bool' type.
   bool IsBoolType() const;
@@ -6265,6 +6272,9 @@
   }
   RawAbstractType* type() const { return raw_ptr()->type_; }
   void set_type(const AbstractType& value) const;
+  virtual classid_t type_class_id() const {
+    return AbstractType::Handle(type()).type_class_id();
+  }
   virtual RawClass* type_class() const {
     return AbstractType::Handle(type()).type_class();
   }
@@ -6440,6 +6450,9 @@
   virtual bool HasResolvedTypeClass() const {
     return AbstractType::Handle(type()).HasResolvedTypeClass();
   }
+  virtual classid_t type_class_id() const {
+    return AbstractType::Handle(type()).type_class_id();
+  }
   virtual RawClass* type_class() const {
     return AbstractType::Handle(type()).type_class();
   }
diff --git a/runtime/vm/os_fuchsia.cc b/runtime/vm/os_fuchsia.cc
index becd0b8..4c030df 100644
--- a/runtime/vm/os_fuchsia.cc
+++ b/runtime/vm/os_fuchsia.cc
@@ -8,14 +8,20 @@
 #include "vm/os.h"
 
 #include <errno.h>
+#include <fdio/util.h>
 #include <zircon/process.h>
 #include <zircon/syscalls.h>
 #include <zircon/syscalls/object.h>
 #include <zircon/types.h>
 
+#include "lib/app/cpp/environment_services.h"
+#include "lib/time_service/fidl/time_service.fidl.h"
+
 #include "platform/assert.h"
 #include "vm/zone.h"
 
+static constexpr char kTimeServiceName[] = "time_service::TimeService";
+
 namespace dart {
 
 #ifndef PRODUCT
@@ -35,36 +41,53 @@
   return static_cast<intptr_t>(getpid());
 }
 
-static bool LocalTime(int64_t seconds_since_epoch, tm* tm_result) {
-  time_t seconds = static_cast<time_t>(seconds_since_epoch);
-  if (seconds != seconds_since_epoch) {
-    return false;
+static zx_status_t GetTimeServicePtr(
+    time_service::TimeServiceSyncPtr* time_svc) {
+  zx::channel service_root = app::subtle::CreateStaticServiceRootHandle();
+  zx::channel time_svc_channel = GetSynchronousProxy(time_svc).PassChannel();
+  return fdio_service_connect_at(service_root.get(), kTimeServiceName,
+                                 time_svc_channel.release());
+}
+
+static zx_status_t GetLocalAndDstOffsetInSeconds(int64_t seconds_since_epoch,
+                                                 int32_t* local_offset,
+                                                 int32_t* dst_offset) {
+  time_service::TimeServiceSyncPtr time_svc;
+  zx_status_t status = GetTimeServicePtr(&time_svc);
+  if (status == ZX_OK) {
+    time_svc->GetTimezoneOffsetMinutes(seconds_since_epoch * 1000, local_offset,
+                                       dst_offset);
+    *local_offset *= 60;
+    *dst_offset *= 60;
   }
-  struct tm* error_code = localtime_r(&seconds, tm_result);
-  return error_code != NULL;
+  return status;
 }
 
 const char* OS::GetTimeZoneName(int64_t seconds_since_epoch) {
-  tm decomposed;
-  bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
-  // If unsuccessful, return an empty string like V8 does.
-  return (succeeded && (decomposed.tm_zone != NULL)) ? decomposed.tm_zone : "";
+  time_service::TimeServiceSyncPtr time_svc;
+  if (GetTimeServicePtr(&time_svc) == ZX_OK) {
+    fidl::String res;
+    time_svc->GetTimezoneId(&res);
+    char* tz_name = Thread::Current()->zone()->Alloc<char>(res.size() + 1);
+    memmove(tz_name, res.get().c_str(), res.size());
+    tz_name[res.size()] = '\0';
+    return tz_name;
+  }
+  return "";
 }
 
 int OS::GetTimeZoneOffsetInSeconds(int64_t seconds_since_epoch) {
-  tm decomposed;
-  bool succeeded = LocalTime(seconds_since_epoch, &decomposed);
-  // Even if the offset was 24 hours it would still easily fit into 32 bits.
-  // If unsuccessful, return zero like V8 does.
-  return succeeded ? static_cast<int>(decomposed.tm_gmtoff) : 0;
+  int32_t local_offset, dst_offset;
+  zx_status_t status = GetLocalAndDstOffsetInSeconds(
+      seconds_since_epoch, &local_offset, &dst_offset);
+  return status == ZX_OK ? local_offset + dst_offset : 0;
 }
 
 int OS::GetLocalTimeZoneAdjustmentInSeconds() {
-  // TODO(floitsch): avoid excessive calls to tzset?
-  tzset();
-  // Even if the offset was 24 hours it would still easily fit into 32 bits.
-  // Note that Unix and Dart disagree on the sign.
-  return static_cast<int>(-timezone);
+  int32_t local_offset, dst_offset;
+  zx_status_t status = GetLocalAndDstOffsetInSeconds(
+      zx_time_get(ZX_CLOCK_UTC) / ZX_SEC(1), &local_offset, &dst_offset);
+  return status == ZX_OK ? local_offset : 0;
 }
 
 int64_t OS::GetCurrentTimeMillis() {
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index e2bcab8..da39187 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -223,6 +223,7 @@
   // Alignment offsets are used to determine object age.
   kNewObjectAlignmentOffset = kWordSize,
   kOldObjectAlignmentOffset = 0,
+  kNewObjectBitPosition = kWordSizeLog2,
   // Object sizes are aligned to kObjectAlignment.
   kObjectAlignment = 2 * kWordSize,
   kObjectAlignmentLog2 = kWordSizeLog2 + 1,
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 7d21d3d..0a0dd08 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -44,7 +44,7 @@
 # ........dartfmt.dart.snapshot
 # ........dartdevc.dart.snapshot
 # ........dartdevk.dart.snapshot
-# ........front_end_worker.dart.snapshot
+# ........kernel_summary_worker.dart.snapshot
 # ........pub.dart.snapshot
 # ........utils_wrapper.dart.snapshot
 #.........resources/
@@ -163,8 +163,8 @@
     "../utils/dartfmt",
   ],
   [
-    "front_end_worker",
-    "../utils/front_end:front_end_worker",
+    "kernel_summary_worker",
+    "../utils/bazel:kernel_summary_worker",
   ],
   [
     "pub",
@@ -315,50 +315,58 @@
 }
 
 # Copies the Dart VM binary into bin/
-copy("copy_dart") {
-  visibility = [ ":create_common_sdk" ]
-  deps = [
-    "../runtime/bin:dart",
-  ]
-  dart_out = get_label_info("../runtime/bin:dart", "root_out_dir")
-  if (is_win) {
-    sources = [
-      "$dart_out/dart.exe",
+if (is_fuchsia_host) {
+  # In the Fuchsia build, this has to use a symlink for two reasons.
+  # First, it makes the lookup of shared libraries relative to $ORIGIN
+  # (Linux) or @loader_path (macOS) find the libraries where they are,
+  # since those lookups use the directory of the symlink target rather
+  # than of the link itself (as they would for a copy or hard link).
+  # Second, when the dart binary is built as a "variant" (e.g. with a
+  # sanitizer), then $root_out_dir/dart is itself a symlink to the real
+  # binary in the selected variant toolchain's $root_out_dir and since
+  # the "copy" tool is actually a hard link rather than a copy, it will
+  # make a link to the symlink rather than the symlink's target, and the
+  # relative symlink interpreted from a different containing directory
+  # will not find the actual binary.
+  action("copy_dart") {
+    visibility = [ ":create_common_sdk" ]
+    dart_label = "../runtime/bin:dart"
+    deps = [
+      dart_label,
     ]
-  } else {
+    dart_out = get_label_info(dart_label, "root_out_dir")
     sources = [
       "$dart_out/$dart_stripped_binary",
     ]
+    outputs = [
+      "$root_out_dir/dart-sdk/bin/$dart_stripped_binary",
+    ]
+    script = "/bin/ln"
+    args = [
+      "-snf",
+      rebase_path(sources[0], get_path_info(outputs[0], "dir")),
+      rebase_path(outputs[0]),
+    ]
   }
-  if (is_win) {
-    sources += [ "$dart_out/dart.lib" ]
-  }
-  outputs = [
-    "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
-  ]
-}
-
-# Copies dynamically linked libraries into bin/. This is currently only needed
-# for Fuchsia when building for Linux hosts.
-if (is_fuchsia_host && is_linux) {
-  copy("copy_dylibs") {
+} else {
+  copy("copy_dart") {
     visibility = [ ":create_common_sdk" ]
     deps = [
-      "//third_party/boringssl:crypto",
-      "//third_party/boringssl:ssl",
-      "//third_party/zlib",
+      "../runtime/bin:dart",
     ]
-    crypto_out =
-        get_label_info("//third_party/boringssl:crypto", "root_out_dir")
-    crypto_name = get_label_info("//third_party/boringssl:crypto", "name")
-    ssl_out = get_label_info("//third_party/boringssl:ssl", "root_out_dir")
-    ssl_name = get_label_info("//third_party/boringssl:ssl", "name")
-    zlib_out = get_label_info("//third_party/zlib", "root_out_dir")
-    sources = [
-      "$crypto_out/lib${crypto_name}.so",
-      "$ssl_out/lib${ssl_name}.so",
-      "$zlib_out/libz.so",
-    ]
+    dart_out = get_label_info("../runtime/bin:dart", "root_out_dir")
+    if (is_win) {
+      sources = [
+        "$dart_out/dart.exe",
+      ]
+    } else {
+      sources = [
+        "$dart_out/$dart_stripped_binary",
+      ]
+    }
+    if (is_win) {
+      sources += [ "$dart_out/dart.lib" ]
+    }
     outputs = [
       "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
     ]
@@ -557,8 +565,8 @@
   ]
   gen_dir = get_label_info("../utils/dartdevc:dartdevc_sdk", "target_gen_dir")
   sources = [
-    "$gen_dir/ddc_sdk.sum",
     "$gen_dir/ddc_sdk.dill",
+    "$gen_dir/ddc_sdk.sum",
   ]
   outputs = [
     "$root_out_dir/dart-sdk/lib/_internal/{{source_file_part}}",
@@ -830,22 +838,19 @@
     ":copy_api_readme",
     ":copy_dart",
     ":copy_dartdoc_files",
-    ":copy_vm_dill_files",
     ":copy_headers",
     ":copy_libraries_dart",
     ":copy_license",
     ":copy_platform_files",
     ":copy_pub_assets",
     ":copy_readme",
+    ":copy_vm_dill_files",
     ":write_revision_file",
     ":write_version_file",
   ]
   if (is_win) {
     deps += [ ":copy_7zip" ]
   }
-  if (is_fuchsia_host && is_linux) {
-    deps += [ ":copy_dylibs" ]
-  }
 }
 
 # Parts specific to the platform SDK.
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index a0d0bc8..b2603af 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -95,14 +95,6 @@
       'returns:bool;effects:none;depends:none', JsBuiltin.isFunctionType, type);
 }
 
-/// Creates a function type object.
-// TODO(floitsch): move this to foreign_helper.dart or similar.
-@ForceInline()
-createDartFunctionTypeRti() {
-  return JS_BUILTIN('returns:=Object;effects:none;depends:none',
-      JsBuiltin.createFunctionTypeRti);
-}
-
 /// Retrieves the class name from type information stored on the constructor of
 /// [type].
 // TODO(floitsch): move this to foreign_helper.dart or similar.
diff --git a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
index 2fff7ec..5b40739 100644
--- a/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
+++ b/sdk/lib/_internal/js_runtime/lib/shared/embedded_names.dart
@@ -387,11 +387,6 @@
   ///     JS_BUILTIN('bool', JsBuiltin.isFunctionType, o)
   isFunctionType,
 
-  /// Returns a new function type object.
-  ///
-  ///     JS_BUILTIN('=Object', JsBuiltin.createFunctionType)
-  createFunctionTypeRti,
-
   /// Returns the JavaScript-constructor name given an rti encoding.
   ///
   ///     JS_BUILTIN('String', JsBuiltin.rawRtiToJsConstructorName, rti)
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 09a775c..0eb0458 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -30324,8 +30324,8 @@
     var completer = new Completer();
     _setLocalDescription(description, () {
       completer.complete();
-    }, (error) {
-      completer.completeError(error);
+    }, (exception) {
+      completer.completeError(exception);
     });
     return completer.future;
   }
@@ -30344,8 +30344,8 @@
     var completer = new Completer();
     _setRemoteDescription(description, () {
       completer.complete();
-    }, (error) {
-      completer.completeError(error);
+    }, (exception) {
+      completer.completeError(exception);
     });
     return completer.future;
   }
@@ -37965,6 +37965,8 @@
   @DocsEditable()
   void _moveTo(int x, int y) native;
 
+  @JSName('openDatabase')
+
   /// *Deprecated.*
   @DomName('Window.openDatabase')
   @DocsEditable()
@@ -37974,7 +37976,7 @@
   // http://www.w3.org/TR/webdatabase/
   @Experimental() // deprecated
   @Creates('SqlDatabase')
-  SqlDatabase openDatabase(
+  SqlDatabase _openDatabase(
       String name, String version, String displayName, int estimatedSize,
       [DatabaseCallback creationCallback]) native;
 
@@ -38921,6 +38923,28 @@
     _moveTo(p.x, p.y);
   }
 
+  @JSName('openDatabase')
+  @DomName('Window.openDatabase')
+  @DocsEditable()
+  @SupportedBrowser(SupportedBrowser.CHROME)
+  @SupportedBrowser(SupportedBrowser.SAFARI)
+  @Experimental()
+  @Creates('SqlDatabase')
+  SqlDatabase openDatabase(
+      String name, String version, String displayName, int estimatedSize,
+      [DatabaseCallback creationCallback]) {
+    var db;
+    if (creationCallback == null)
+      db = _openDatabase(name, version, displayName, estimatedSize);
+    else
+      db = _openDatabase(
+          name, version, displayName, estimatedSize, creationCallback);
+
+    applyExtension('Database', db);
+
+    return db;
+  }
+
   @DomName('Window.pageXOffset')
   @DocsEditable()
   int get pageXOffset => JS('num', '#.pageXOffset', this).round();
diff --git a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
index 69af259..9a84406 100644
--- a/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
+++ b/sdk/lib/web_sql/dart2js/web_sql_dart2js.dart
@@ -23,6 +23,7 @@
 
 import 'dart:_js_helper'
     show
+        applyExtension,
         convertDartClosureToJS,
         Creates,
         JSName,
@@ -128,6 +129,20 @@
   void transaction(SqlTransactionCallback callback,
       [SqlTransactionErrorCallback errorCallback,
       VoidCallback successCallback]) native;
+
+  @JSName('transaction')
+  @DomName('Database.transaction')
+  @DocsEditable()
+  Future<SqlTransaction> transaction_future() {
+    var completer = new Completer<SqlTransaction>();
+    transaction((value) {
+      applyExtension('SQLTransaction', value);
+      completer.complete(value);
+    }, (error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
 }
 // Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
@@ -304,10 +319,26 @@
     throw new UnsupportedError("Not supported");
   }
 
+  @JSName('executeSql')
   @DomName('SQLTransaction.executeSql')
   @DocsEditable()
-  void executeSql(String sqlStatement,
+  void _executeSql(String sqlStatement,
       [List arguments,
       SqlStatementCallback callback,
       SqlStatementErrorCallback errorCallback]) native;
+
+  @JSName('executeSql')
+  @DomName('SQLTransaction.executeSql')
+  @DocsEditable()
+  Future<SqlResultSet> executeSql(String sqlStatement, [List arguments]) {
+    var completer = new Completer<SqlResultSet>();
+    _executeSql(sqlStatement, arguments, (transaction, resultSet) {
+      applyExtension('SQLResultSet', resultSet);
+      applyExtension('SQLResultSetRowList', resultSet.rows);
+      completer.complete(resultSet);
+    }, (transaction, error) {
+      completer.completeError(error);
+    });
+    return completer.future;
+  }
 }
diff --git a/tests/compiler/dart2js/async_await_js_transform_test.dart b/tests/compiler/dart2js/async_await/async_await_js_transform_test.dart
similarity index 100%
rename from tests/compiler/dart2js/async_await_js_transform_test.dart
rename to tests/compiler/dart2js/async_await/async_await_js_transform_test.dart
diff --git a/tests/compiler/dart2js/class_codegen_test.dart b/tests/compiler/dart2js/class_codegen_test.dart
deleted file mode 100644
index d744468..0000000
--- a/tests/compiler/dart2js/class_codegen_test.dart
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// Test that parameters keep their names in the output.
-
-import "package:expect/expect.dart";
-import "package:async_helper/async_helper.dart";
-import 'compiler_helper.dart';
-
-const String TEST_ONE = r"""
-class A { }
-class B { }
-
-main() {
-  new A();
-  new B();
-}
-""";
-
-const String TEST_TWO = r"""
-class A { }
-class B extends A { }
-
-main() {
-  new A();
-  new B();
-}
-""";
-
-const String TEST_THREE = r"""
-class B extends A { }
-class A { }
-
-main() {
-  new B();
-  new A();
-}
-""";
-
-const String TEST_FOUR = r"""
-class A {
-  var x;
-}
-
-class B extends A {
-  var y;
-  var z;
-}
-
-main() {
-  new B();
-}
-""";
-
-const String TEST_FIVE = r"""
-class A {
-  var a;
-  A(a) : this.a = a {}
-}
-
-main() {
-  new A(3);
-}
-""";
-
-twoClasses() {
-  asyncTest(() => compileAll(TEST_ONE).then((generated) {
-        Expect.isTrue(
-            generated.contains(new RegExp('A: {[ \n]*"\\^": "Object;"')));
-        Expect.isTrue(
-            generated.contains(new RegExp('B: {[ \n]*"\\^": "Object;"')));
-      }));
-}
-
-subClass() {
-  checkOutput(String generated) {
-    Expect.isTrue(generated.contains(new RegExp('A: {[ \n]*"\\^": "Object;"')));
-    Expect.isTrue(generated.contains(new RegExp('B: {[ \n]*"\\^": "A;"')));
-  }
-
-  asyncTest(() => compileAll(TEST_TWO).then(checkOutput));
-  asyncTest(() => compileAll(TEST_THREE).then(checkOutput));
-}
-
-fieldTest() {
-  asyncTest(() => compileAll(TEST_FOUR).then((generated) {
-        Expect.isTrue(generated
-            .contains(new RegExp('B: {[ \n]*"\\^": "A;y,z,x",[ \n]*static:')));
-      }));
-}
-
-constructor1() {
-  asyncTest(() => compileAll(TEST_FIVE).then((generated) {
-        Expect.isTrue(generated.contains(new RegExp(r"new [$A-Z]+\.A\(a\);")));
-      }));
-}
-
-main() {
-  twoClasses();
-  subClass();
-  fieldTest();
-  constructor1();
-}
diff --git a/tests/compiler/dart2js/class_set_test.dart b/tests/compiler/dart2js/class_set_test.dart
index 8a9fe87..6f446e6 100644
--- a/tests/compiler/dart2js/class_set_test.dart
+++ b/tests/compiler/dart2js/class_set_test.dart
@@ -17,7 +17,9 @@
 
 void main() {
   asyncTest(() async {
+    print('--test from ast---------------------------------------------------');
     await testAll(CompileMode.memory);
+    print('--test from kernel------------------------------------------------');
     await testAll(CompileMode.kernel);
   });
 }
diff --git a/tests/compiler/dart2js/closure_codegen_test.dart b/tests/compiler/dart2js/closure_codegen_test.dart
deleted file mode 100644
index 6f947e6..0000000
--- a/tests/compiler/dart2js/closure_codegen_test.dart
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-// Test that parameters keep their names in the output.
-
-import 'dart:async';
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
-
-const String TEST_INVOCATION0 = r"""
-main() {
-  var o = null;
-  o();
-}
-""";
-
-const String TEST_INVOCATION1 = r"""
-main() {
-  var o = null;
-  o(1);
-}
-""";
-
-const String TEST_INVOCATION2 = r"""
-main() {
-  var o = null;
-  o(1, 2);
-}
-""";
-
-const String TEST_BAILOUT = r"""
-class A {
-  var x;
-  foo(_) { // make sure only g has no arguments
-    var f = () { return 499;  };
-    return 499 + x + f();
-  }
-}
-
-main() { new A().foo(1); }
-""";
-
-Future closureInvocation(bool minify, String prefix) {
-  return Future.wait([
-    compile(TEST_INVOCATION0, minify: minify, check: (String generated) {
-      Expect.isTrue(generated.contains(".$prefix\$0()"));
-    }),
-    compile(TEST_INVOCATION1, minify: minify, check: (String generated) {
-      Expect.isTrue(generated.contains(".$prefix\$1(1)"));
-    }),
-    compile(TEST_INVOCATION2, minify: minify, check: (String generated) {
-      Expect.isTrue(generated.contains(".$prefix\$2(1,${minify ? "" : " "}2)"));
-    })
-  ]);
-}
-
-// Make sure that the bailout version does not introduce a second version of
-// the closure.
-Future closureBailout(bool minify, String prefix) {
-  return compileAll(TEST_BAILOUT, minify: minify).then((generated) {
-    RegExp regexp = new RegExp("$prefix\\\$0:${minify ? "" : " "}function");
-    Iterator<Match> matches = regexp.allMatches(generated).iterator;
-    checkNumberOfMatches(matches, 1);
-  });
-}
-
-main() {
-  asyncTest(() => Future.wait([
-        closureInvocation(false, "call"),
-        closureInvocation(true, ""),
-        closureBailout(false, "call"),
-        closureBailout(true, ""),
-      ]));
-}
diff --git a/tests/compiler/dart2js/closure_tracer_28919_test.dart b/tests/compiler/dart2js/closure_tracer_28919_test.dart
deleted file mode 100644
index 122ba8b..0000000
--- a/tests/compiler/dart2js/closure_tracer_28919_test.dart
+++ /dev/null
@@ -1,91 +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.
-
-import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
-
-import 'compiler_helper.dart';
-import 'type_mask_test_helper.dart';
-import 'package:compiler/src/types/types.dart';
-
-bool isContainer(TypeMask mask) {
-  return mask is ContainerTypeMask;
-}
-
-const String TEST = '''
-
-foo1() {
-  final methods = [];
-  var res, sum;
-  for (int i = 0; i != 3; i++) {
-    methods.add((int x) { res = x; sum = x + i; });
-  }
-  methods[0](499);
-  probe1res(res);
-  probe1sum(sum);
-  probe1methods(methods);
-}
-probe1res(x) => x;
-probe1sum(x) => x;
-probe1methods(x) => x;
-
-nonContainer(choice) {
-  var m = choice == 0 ? [] : "<String>";
-  if (m is !List) throw 123;
-  // The union then filter leaves us with a non-container type.
-  return m;
-}
-
-foo2(int choice) {
-  final methods = nonContainer(choice);
-  var res, sum;
-  for (int i = 0; i != 3; i++) {
-    methods.add((int x) { res = x; sum = x + i; });
-  }
-  methods[0](499);
-  probe2res(res);
-  probe2methods(methods);
-}
-probe2res(x) => x;
-probe2methods(x) => x;
-
-main() {
-  foo1();
-  foo2(0);
-  foo2(1);
-}
-''';
-
-void main() {
-  Uri uri = new Uri(scheme: 'source');
-  var compiler = compilerFor(TEST, uri);
-  asyncTest(() => compiler.run(uri).then((_) {
-        var typesInferrer = compiler.globalInference.typesInferrerInternal;
-        var closedWorld = typesInferrer.closedWorld;
-        var commonMasks = closedWorld.commonMasks;
-
-        typeOf(String name) {
-          MemberElement member = findElement(compiler, name);
-          return typesInferrer.getReturnTypeOfMember(member);
-        }
-
-        checkType(String name, type) {
-          var mask = typeOf(name);
-          Expect.equals(type.nullable(), simplify(mask, closedWorld), name);
-        }
-
-        checkContainer(String name, bool value) {
-          var mask = typeOf(name);
-          Expect.equals(
-              value, isContainer(mask), '$name is container (mask: $mask)');
-        }
-
-        checkContainer('probe1methods', true);
-        checkType('probe1res', commonMasks.uint31Type);
-        checkType('probe1sum', commonMasks.positiveIntType);
-
-        checkContainer('probe2methods', false);
-        checkType('probe2res', commonMasks.dynamicType);
-      }));
-}
diff --git a/tests/compiler/dart2js/code_motion_test.dart b/tests/compiler/dart2js/code_motion_test.dart
deleted file mode 100644
index 69f1800..0000000
--- a/tests/compiler/dart2js/code_motion_test.dart
+++ /dev/null
@@ -1,31 +0,0 @@
-// Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
-
-const String TEST_ONE = r"""
-foo(int a, int b, bool param2) {
-  // Make sure a and b become numbers.
-  var c = a - b;
-  for (int i = 0; i < 1; i++) {
-    if (param2) {
-      print(a + b);
-    } else {
-      print(a + b);
-    }
-  }
-  return c;
-}
-""";
-
-main() {
-  asyncTest(() => compile(TEST_ONE, entry: 'foo', check: (String generated) {
-        RegExp regexp = new RegExp('a \\+ b');
-        Iterator matches = regexp.allMatches(generated).iterator;
-        Expect.isTrue(matches.moveNext());
-        Expect.isFalse(matches.moveNext());
-      }));
-}
diff --git a/tests/compiler/dart2js/arithmetic_simplification_test.dart b/tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
similarity index 83%
rename from tests/compiler/dart2js/arithmetic_simplification_test.dart
rename to tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
index 6c2d57d..f213526 100644
--- a/tests/compiler/dart2js/arithmetic_simplification_test.dart
+++ b/tests/compiler/dart2js/codegen/arithmetic_simplification_test.dart
@@ -4,7 +4,7 @@
 // Test constant folding on numbers.
 
 import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
+import '../compiler_helper.dart';
 
 const String INT_PLUS_ZERO = """
 int foo(x) => x;
@@ -78,29 +78,29 @@
   var timesOne = new RegExp(r"\* 1");
   var oneTimes = new RegExp(r"1 \*");
 
-  test(CompileMode compileMode) async {
+  test({bool useKernel}) async {
     await compileAndDoNotMatch(INT_PLUS_ZERO, 'main', plusZero,
-        compileMode: compileMode);
+        useKernel: useKernel);
     await compileAndDoNotMatch(ZERO_PLUS_INT, 'main', zeroPlus,
-        compileMode: compileMode);
+        useKernel: useKernel);
     await compileAndMatch(NUM_PLUS_ZERO, 'main', plusZero,
-        compileMode: compileMode);
+        useKernel: useKernel);
     await compileAndMatch(ZERO_PLUS_NUM, 'main', zeroPlus,
-        compileMode: compileMode);
+        useKernel: useKernel);
     await compileAndDoNotMatch(INT_TIMES_ONE, 'main', timesOne,
-        compileMode: compileMode);
+        useKernel: useKernel);
     await compileAndDoNotMatch(ONE_TIMES_INT, 'main', oneTimes,
-        compileMode: compileMode);
+        useKernel: useKernel);
     await compileAndDoNotMatch(NUM_TIMES_ONE, 'main', timesOne,
-        compileMode: compileMode);
+        useKernel: useKernel);
     await compileAndDoNotMatch(ONE_TIMES_NUM, 'main', oneTimes,
-        compileMode: compileMode);
+        useKernel: useKernel);
   }
 
   asyncTest(() async {
     print('--test from ast---------------------------------------------------');
-    await test(CompileMode.memory);
+    await test(useKernel: false);
     print('--test from kernel------------------------------------------------');
-    await test(CompileMode.kernel);
+    await test(useKernel: true);
   });
 }
diff --git a/tests/compiler/dart2js/array_static_intercept_test.dart b/tests/compiler/dart2js/codegen/array_static_intercept_test.dart
similarity index 80%
rename from tests/compiler/dart2js/array_static_intercept_test.dart
rename to tests/compiler/dart2js/codegen/array_static_intercept_test.dart
index 0ad768d..95bddad 100644
--- a/tests/compiler/dart2js/array_static_intercept_test.dart
+++ b/tests/compiler/dart2js/codegen/array_static_intercept_test.dart
@@ -4,7 +4,7 @@
 
 import 'package:expect/expect.dart';
 import 'package:async_helper/async_helper.dart';
-import 'compiler_helper.dart';
+import '../compiler_helper.dart';
 
 const String TEST_ONE = r"""
 foo(a) {
@@ -15,8 +15,8 @@
 """;
 
 main() {
-  test(CompileMode compileMode) async {
-    await compile(TEST_ONE, entry: 'foo', compileMode: compileMode,
+  test({bool useKernel}) async {
+    await compile(TEST_ONE, entry: 'foo', useKernel: useKernel,
         check: (String generated) {
       Expect.isTrue(generated.contains(r'.add$1('));