Version 1.17.0-dev.5.0

Merge '7bdf01560a70e089774b47c2cbd5823da790374e' into dev
diff --git a/DEPS b/DEPS
index 7753d5f..138d463 100644
--- a/DEPS
+++ b/DEPS
@@ -49,7 +49,7 @@
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.4",
   "dartdoc_tag" : "@v0.9.0",
-  "dev_compiler_rev": "@1f00327fdf8fe11ab8e9b3d5b0fc958025ede592",
+  "dev_compiler_rev": "@adda29b31dc8fe2f8d1a5c1304384988503384c8",
   "fixnum_tag": "@0.10.5",
   "func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index a00ab31..c52f5a9 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -1639,8 +1639,8 @@
     }
 
     // If no embedded URI resolver was provided, defer to a locator-backed one.
-    embedderUriResolver ??=
-        new EmbedderUriResolver(context.embedderYamlLocator.embedderYamls);
+    embedderUriResolver ??= new EmbedderUriResolver(
+        new EmbedderSdk(context.embedderYamlLocator.embedderYamls));
     if (embedderUriResolver.length == 0) {
       // The embedder uri resolver has no mappings. Use the default Dart SDK
       // uri resolver.
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index 44c3595..975cd09 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -917,7 +917,8 @@
                   .where((r) => r is! DartUriResolver)
                   .toList();
               // Add an embedded URI resolver in its place.
-              resolvers.add(new EmbedderUriResolver(embedderYamls));
+              resolvers
+                  .add(new EmbedderUriResolver(new EmbedderSdk(embedderYamls)));
 
               // Set a new source factory.
               SourceFactoryImpl newFactory = sourceFactory.clone();
@@ -1174,8 +1175,8 @@
     }
 
     // If no embedded URI resolver was provided, defer to a locator-backed one.
-    embedderUriResolver ??=
-        new EmbedderUriResolver(context.embedderYamlLocator.embedderYamls);
+    embedderUriResolver ??= new EmbedderUriResolver(
+        new EmbedderSdk(context.embedderYamlLocator.embedderYamls));
     if (embedderUriResolver.length == 0) {
       // The embedder uri resolver has no mappings. Use the default Dart SDK
       // uri resolver.
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index db85fcd..b6a5903 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -2658,8 +2658,8 @@
     if (currentContext is InternalAnalysisContext) {
       EmbedderYamlLocator embedderYamlLocator =
           (currentContext as InternalAnalysisContext).embedderYamlLocator;
-      EmbedderUriResolver embedderUriResolver =
-          new EmbedderUriResolver(embedderYamlLocator.embedderYamls);
+      EmbedderUriResolver embedderUriResolver = new EmbedderUriResolver(
+          new EmbedderSdk(embedderYamlLocator.embedderYamls));
       if (embedderUriResolver.length > 0) {
         // We have some embedder dart: uri mappings, add the resolver
         // to the list.
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index 0454992..c4642e8 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -112,7 +112,7 @@
   return unit;
 }
 
-/// A simple error listener that collects errors into an [AnalysisErrorGroup].
+/// A simple error listener that collects errors into an [AnalyzerErrorGroup].
 class _ErrorCollector extends AnalysisErrorListener {
   final _errors = <AnalysisError>[];
 
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 7b645cc..6754062 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -373,7 +373,7 @@
 
   /**
    * Set the condition that is being asserted to be `true` to the given
-   * [expression].
+   * [condition].
    */
   void set condition(Expression condition);
 
@@ -1188,7 +1188,7 @@
   Expression get target;
 
   /**
-   * Set the target of the cascade sections to the given [expression].
+   * Set the target of the cascade sections to the given [target].
    */
   void set target(Expression target);
 }
@@ -1394,7 +1394,7 @@
   void set abstractKeyword(Token token);
 
   /**
-   * Return the token representing the 'class' keyword to the given [token].
+   * Return the token representing the 'class' keyword.
    */
   Token get classKeyword;
 
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index e7091ab..13fbe48 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -763,7 +763,7 @@
   /**
    * Return a display name for the given element that includes the path to the
    * compilation unit in which the type is defined. If [shortName] is `null`
-   * then [getDisplayName] will be used as the name of this element. Otherwise
+   * then [displayName] will be used as the name of this element. Otherwise
    * the provided name will be used.
    */
   // TODO(brianwilkerson) Make the parameter optional.
diff --git a/pkg/analyzer/lib/instrumentation/instrumentation.dart b/pkg/analyzer/lib/instrumentation/instrumentation.dart
index 92638f7..eaf95ba 100644
--- a/pkg/analyzer/lib/instrumentation/instrumentation.dart
+++ b/pkg/analyzer/lib/instrumentation/instrumentation.dart
@@ -85,7 +85,7 @@
 
   /**
    * Initialize a newly created instrumentation service to communicate with the
-   * given [instrumentationServer].
+   * given [_instrumentationServer].
    */
   InstrumentationService(this._instrumentationServer);
 
@@ -320,9 +320,10 @@
   String _join(List<String> fields) {
     StringBuffer buffer = new StringBuffer();
     buffer.write(_timestamp);
-    for (String field in fields) {
+    int length = fields.length;
+    for (int i = 0; i < length; i++) {
       buffer.write(':');
-      _escape(buffer, field);
+      _escape(buffer, fields[i]);
     }
     return buffer.toString();
   }
diff --git a/pkg/analyzer/lib/source/analysis_options_provider.dart b/pkg/analyzer/lib/source/analysis_options_provider.dart
index 2acab1d..fbacdfb 100644
--- a/pkg/analyzer/lib/source/analysis_options_provider.dart
+++ b/pkg/analyzer/lib/source/analysis_options_provider.dart
@@ -14,8 +14,9 @@
 
 /// Provide the options found in the analysis options file.
 class AnalysisOptionsProvider {
-  /// Provide the options found in either [root]/[ANALYSIS_OPTIONS_FILE] or
-  /// [root]/[ANALYSIS_OPTIONS_YAML_FILE].
+  /// Provide the options found in either
+  /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_FILE] or
+  /// [root]/[AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE].
   /// Return an empty options map if the file does not exist.
   Map<String, YamlNode> getOptions(Folder root, {bool crawlUp: false}) {
     Resource resource;
diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart
index 78ba661..a1b4ea6 100644
--- a/pkg/analyzer/lib/source/embedder.dart
+++ b/pkg/analyzer/lib/source/embedder.dart
@@ -8,6 +8,8 @@
 import 'dart:core' hide Resource;
 
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/package_map_provider.dart'
+    show PackageMapProvider;
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -24,26 +26,33 @@
 /// Check if this map defines embedded libraries.
 bool definesEmbeddedLibs(Map map) => map[_EMBEDDED_LIB_MAP_KEY] != null;
 
+/// An SDK backed by URI mappings derived from an `_embedder.yaml` file.
 class EmbedderSdk implements DartSdk {
-  // TODO(danrubel) Refactor this with DirectoryBasedDartSdk
-
-  /// The resolver associated with this embedder sdk.
+  /// The resolver associated with this SDK.
   EmbedderUriResolver _resolver;
 
-  /// The [AnalysisContext] which is used for all of the sources in this sdk.
+  /// The [AnalysisContext] used for this SDK's sources.
   InternalAnalysisContext _analysisContext;
 
-  /// The library map that is populated by visiting the AST structure parsed from
-  /// the contents of the libraries file.
   final LibraryMap _librariesMap = new LibraryMap();
 
+  final Map<String, String> _urlMappings = new HashMap<String, String>();
+
+  /// Analysis options for this SDK.
+  AnalysisOptions analysisOptions;
+
+  EmbedderSdk([Map<Folder, YamlMap> embedderYamls]) {
+    embedderYamls?.forEach(_processEmbedderYaml);
+    _resolver = new EmbedderUriResolver(this);
+  }
+
   @override
   AnalysisContext get context {
     if (_analysisContext == null) {
-      _analysisContext = new SdkAnalysisContext(null);
+      _analysisContext = new SdkAnalysisContext(analysisOptions);
       SourceFactory factory = new SourceFactory([_resolver]);
       _analysisContext.sourceFactory = factory;
-      List<String> uris = this.uris;
+
       ChangeSet changeSet = new ChangeSet();
       for (String uri in uris) {
         changeSet.addedSource(factory.forUri(uri));
@@ -63,6 +72,9 @@
   @override
   List<String> get uris => _librariesMap.uris;
 
+  /// The url mappings for this SDK.
+  Map<String, String> get urlMappings => _urlMappings;
+
   @override
   Source fromFileUri(Uri uri) {
     JavaFile file = new JavaFile.fromUri(uri);
@@ -72,7 +84,7 @@
     for (SdkLibrary library in _librariesMap.sdkLibraries) {
       String libraryPath = library.path.replaceAll('/', JavaFile.separator);
       if (filePath == libraryPath) {
-        path = '$_DART_COLON_PREFIX${library.shortName}';
+        path = library.shortName;
         break;
       }
     }
@@ -90,7 +102,7 @@
         var relPath = filePath
             .substring(prefix.length)
             .replaceAll(JavaFile.separator, '/');
-        path = '$_DART_COLON_PREFIX${library.shortName}/$relPath';
+        path = '${library.shortName}/$relPath';
         break;
       }
     }
@@ -150,9 +162,39 @@
       return null;
     }
   }
+
+  /// Install the mapping from [name] to [libDir]/[file].
+  void _processEmbeddedLibs(String name, String file, Folder libDir) {
+    if (!name.startsWith(_DART_COLON_PREFIX)) {
+      // SDK libraries must begin with 'dart:'.
+      return;
+    }
+    String libPath = libDir.canonicalizePath(file);
+    _urlMappings[name] = libPath;
+    SdkLibraryImpl library = new SdkLibraryImpl(name);
+    library.path = libPath;
+    _librariesMap.setLibrary(name, library);
+  }
+
+  /// Given the 'embedderYamls' from [EmbedderYamlLocator] check each one for the
+  /// top level key 'embedded_libs'. Under the 'embedded_libs' key are key value
+  /// pairs. Each key is a 'dart:' library uri and each value is a path
+  /// (relative to the directory containing `_embedder.yaml`) to a dart script
+  /// for the given library. For example:
+  ///
+  /// embedded_libs:
+  ///   'dart:io': '../../sdk/io/io.dart'
+  ///
+  /// If a key doesn't begin with `dart:` it is ignored.
+  void _processEmbedderYaml(Folder libDir, YamlMap map) {
+    YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
+    if (embedded_libs is YamlMap) {
+      embedded_libs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
+    }
+  }
 }
 
-/// Given the [embedderYamls] from [EmbedderYamlLocator] check each one for the
+/// Given the 'embedderYamls' from [EmbedderYamlLocator] check each one for the
 /// top level key 'embedded_libs'. Under the 'embedded_libs' key are key value
 /// pairs. Each key is a 'dart:' library uri and each value is a path
 /// (relative to the directory containing `_embedder.yaml`) to a dart script
@@ -163,22 +205,25 @@
 ///
 /// If a key doesn't begin with `dart:` it is ignored.
 ///
-class EmbedderUriResolver extends DartUriResolver {
-  final Map<String, String> _urlMappings = <String, String>{};
+class EmbedderUriResolver implements DartUriResolver {
+  EmbedderSdk _embedderSdk;
+  DartUriResolver _dartUriResolver;
 
   /// Construct a [EmbedderUriResolver] from a package map
   /// (see [PackageMapProvider]).
-  EmbedderUriResolver(Map<Folder, YamlMap> embedderYamls)
-      : super(new EmbedderSdk()) {
-    (dartSdk as EmbedderSdk)._resolver = this;
-    if (embedderYamls == null) {
-      return;
-    }
-    embedderYamls.forEach(_processEmbedderYaml);
+  EmbedderUriResolver(this._embedderSdk) {
+    _dartUriResolver = new DartUriResolver(_embedderSdk);
   }
 
+  @override
+  DartSdk get dartSdk => _embedderSdk;
+
   /// Number of embedded libraries.
-  int get length => _urlMappings.length;
+  int get length => _embedderSdk?.urlMappings?.length ?? 0;
+
+  @override
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) =>
+      _dartUriResolver.resolveAbsolute(uri, actualUri);
 
   @override
   Uri restoreAbsolute(Source source) {
@@ -189,32 +234,6 @@
     Source sdkSource = dartSdk.fromFileUri(Uri.parse('file://$path'));
     return sdkSource?.uri;
   }
-
-  /// Install the mapping from [name] to [libDir]/[file].
-  void _processEmbeddedLibs(String name, String file, Folder libDir) {
-    if (!name.startsWith(_DART_COLON_PREFIX)) {
-      // SDK libraries must begin with 'dart:'.
-      // TODO(pquitslund): Notify developer that something is wrong with the
-      // _embedder.yaml file in libDir.
-      return;
-    }
-    String libPath = libDir.canonicalizePath(file);
-    _urlMappings[name] = libPath;
-    String shortName = name.substring(_DART_COLON_PREFIX.length);
-    SdkLibraryImpl library = new SdkLibraryImpl(shortName);
-    library.path = libPath;
-    (dartSdk as EmbedderSdk)._librariesMap.setLibrary(name, library);
-  }
-
-  void _processEmbedderYaml(Folder libDir, YamlMap map) {
-    YamlNode embedded_libs = map[_EMBEDDED_LIB_MAP_KEY];
-    if (embedded_libs == null) {
-      return;
-    }
-    if (embedded_libs is YamlMap) {
-      embedded_libs.forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
-    }
-  }
 }
 
 /// Given a packageMap, check in each package's lib directory for the
@@ -223,8 +242,7 @@
 class EmbedderYamlLocator {
   static const String EMBEDDER_FILE_NAME = '_embedder.yaml';
 
-  // Map from package's library directory to the parsed
-  // YamlMap.
+  /// Map from package's library directory to the parsed YamlMap.
   final Map<Folder, YamlMap> embedderYamls = new HashMap<Folder, YamlMap>();
 
   EmbedderYamlLocator(Map<String, List<Folder>> packageMap) {
@@ -254,18 +272,9 @@
     try {
       yaml = loadYaml(embedderYaml);
     } catch (_) {
-      // TODO(pquitslund): Notify developer that something is wrong with the
-      // _embedder.yaml file in libDir.
-      return;
-    }
-    if (yaml == null) {
-      // TODO(pquitslund): Notify developer that something is wrong with the
-      // _embedder.yaml file in libDir.
       return;
     }
     if (yaml is! YamlMap) {
-      // TODO(pquitslund): Notify developer that something is wrong with the
-      // _embedder.yaml file in libDir.
       return;
     }
     embedderYamls[libDir] = yaml;
diff --git a/pkg/analyzer/lib/source/sdk_ext.dart b/pkg/analyzer/lib/source/sdk_ext.dart
index 126d3b6..f4bcdb9 100644
--- a/pkg/analyzer/lib/source/sdk_ext.dart
+++ b/pkg/analyzer/lib/source/sdk_ext.dart
@@ -8,6 +8,8 @@
 import 'dart:core' hide Resource;
 
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/source/package_map_provider.dart'
+    show PackageMapProvider;
 import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 7dbe398..36df855 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -54,6 +54,7 @@
    */
   AnalysisCache(this._partitions) {
     for (CachePartition partition in _partitions) {
+      partition.containingCaches.add(this);
       ReentrantSynchronousStreamSubscription<InvalidatedResult> subscription =
           partition.onResultInvalidated.listen((InvalidatedResult event) {
         onResultInvalidated.add(event);
@@ -96,6 +97,9 @@
         in onResultInvalidatedPartitionSubscriptions) {
       subscription.cancel();
     }
+    for (CachePartition partition in _partitions) {
+      partition.containingCaches.remove(this);
+    }
   }
 
   /**
@@ -349,12 +353,18 @@
    * Notifies the entry that the client is going to stop using it.
    */
   void dispose() {
-    _resultMap.forEach((descriptor, data) {
+    _resultMap.forEach((ResultDescriptor descriptor, ResultData data) {
       TargetedResult result = new TargetedResult(target, descriptor);
       for (TargetedResult dependedOnResult in data.dependedOnResults) {
-        ResultData dependedOnData = _partition._getDataFor(dependedOnResult);
-        if (dependedOnData != null) {
-          dependedOnData.dependentResults.remove(result);
+        for (AnalysisCache cache in _partition.containingCaches) {
+          CacheEntry entry = cache.get(dependedOnResult.target);
+          if (entry != null) {
+            ResultData data =
+                entry.getResultDataOrNull(dependedOnResult.result);
+            if (data != null) {
+              data.dependentResults.remove(result);
+            }
+          }
         }
       }
     });
@@ -375,14 +385,21 @@
   }
 
   /**
-   * Look up the [ResultData] of [descriptor], or add a new one if it isn't
-   * there.
+   * Return the result data associated with the [descriptor], creating one if it
+   * isn't there.
    */
   ResultData getResultData(ResultDescriptor descriptor) {
     return _resultMap.putIfAbsent(descriptor, () => new ResultData(descriptor));
   }
 
   /**
+   * Return the result data associated with the [descriptor], or `null` if there
+   * is no data currently associated with the descriptor.
+   */
+  ResultData getResultDataOrNull(ResultDescriptor descriptor) =>
+      _resultMap[descriptor];
+
+  /**
    * Return the state of the result represented by the given [descriptor].
    */
   CacheState getState(ResultDescriptor descriptor) {
@@ -584,11 +601,25 @@
 //      }
     }
     // Stop depending on other results.
-    TargetedResult thisResult = new TargetedResult(target, descriptor);
-    for (TargetedResult dependedOnResult in thisData.dependedOnResults) {
-      ResultData data = _partition._getDataFor(dependedOnResult);
-      if (data != null && deltaResult != DeltaResult.KEEP_CONTINUE) {
-        data.dependentResults.remove(thisResult);
+    if (deltaResult != DeltaResult.KEEP_CONTINUE) {
+      TargetedResult thisResult = new TargetedResult(target, descriptor);
+      List<AnalysisCache> caches = _partition.containingCaches;
+      int cacheLength = caches.length;
+      List<TargetedResult> results = thisData.dependedOnResults;
+      int resultLength = results.length;
+      for (int i = 0; i < resultLength; i++) {
+        TargetedResult dependedOnResult = results[i];
+        for (int j = 0; j < cacheLength; j++) {
+          AnalysisCache cache = caches[j];
+          CacheEntry entry = cache.get(dependedOnResult.target);
+          if (entry != null) {
+            ResultData data =
+                entry.getResultDataOrNull(dependedOnResult.result);
+            if (data != null) {
+              data.dependentResults.remove(thisResult);
+            }
+          }
+        }
       }
     }
     // Invalidate results that depend on this result.
@@ -611,7 +642,9 @@
    */
   void _invalidateAll() {
     List<ResultDescriptor> results = _resultMap.keys.toList();
-    for (ResultDescriptor result in results) {
+    int length = results.length;
+    for (int i = 0; i < length; i++) {
+      ResultDescriptor result = results[i];
       _invalidate(nextInvalidateId++, result, null, 0);
     }
   }
@@ -621,11 +654,20 @@
    */
   void _invalidateDependentResults(
       int id, ResultData thisData, Delta delta, int level) {
+    // It is necessary to copy the results to a list to avoid a concurrent
+    // modification of the set of dependent results.
+    List<AnalysisCache> caches = _partition.containingCaches;
+    int cacheLength = caches.length;
     List<TargetedResult> dependentResults = thisData.dependentResults.toList();
-    for (TargetedResult dependentResult in dependentResults) {
-      CacheEntry entry = _partition.get(dependentResult.target);
-      if (entry != null) {
-        entry._invalidate(id, dependentResult.result, delta, level);
+    int resultLength = dependentResults.length;
+    for (int i = 0; i < resultLength; i++) {
+      TargetedResult dependentResult = dependentResults[i];
+      for (int j = 0; j < cacheLength; j++) {
+        AnalysisCache cache = caches[j];
+        CacheEntry entry = cache.get(dependentResult.target);
+        if (entry != null) {
+          entry._invalidate(id, dependentResult.result, delta, level);
+        }
       }
     }
   }
@@ -644,19 +686,39 @@
    */
   void _setDependedOnResults(ResultData thisData, TargetedResult thisResult,
       List<TargetedResult> dependedOn) {
-    thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) {
-      ResultData data = _partition._getDataFor(dependedOnResult);
-      if (data != null) {
-        data.dependentResults.remove(thisResult);
+    List<AnalysisCache> caches = _partition.containingCaches;
+    int cacheLength = caches.length;
+
+    List<TargetedResult> oldResults = thisData.dependedOnResults;
+    int oldLength = oldResults.length;
+    for (int i = 0; i < oldLength; i++) {
+      TargetedResult dependedOnResult = oldResults[i];
+      for (int j = 0; j < cacheLength; j++) {
+        AnalysisCache cache = caches[j];
+        CacheEntry entry = cache.get(dependedOnResult.target);
+        if (entry != null) {
+          ResultData data = entry.getResultDataOrNull(dependedOnResult.result);
+          if (data != null) {
+            data.dependentResults.remove(thisResult);
+          }
+        }
       }
-    });
+    }
     thisData.dependedOnResults = dependedOn;
-    thisData.dependedOnResults.forEach((TargetedResult dependedOnResult) {
-      ResultData data = _partition._getDataFor(dependedOnResult);
-      if (data != null) {
-        data.dependentResults.add(thisResult);
+    int newLength = dependedOn.length;
+    for (int i = 0; i < newLength; i++) {
+      TargetedResult dependedOnResult = dependedOn[i];
+      for (int j = 0; j < cacheLength; j++) {
+        AnalysisCache cache = caches[j];
+        CacheEntry entry = cache.get(dependedOnResult.target);
+        if (entry != null) {
+          ResultData data = entry.getResultDataOrNull(dependedOnResult.result);
+          if (data != null) {
+            data.dependentResults.add(thisResult);
+          }
+        }
       }
-    });
+    }
   }
 
   /**
@@ -670,9 +732,16 @@
     thisData.state = CacheState.ERROR;
     thisData.value = descriptor.defaultValue;
     // Propagate the error state.
+    List<AnalysisCache> caches = _partition.containingCaches;
+    int cacheLength = caches.length;
     thisData.dependentResults.forEach((TargetedResult dependentResult) {
-      CacheEntry entry = _partition.get(dependentResult.target);
-      entry._setErrorState(dependentResult.result, exception);
+      for (int i = 0; i < cacheLength; i++) {
+        AnalysisCache cache = caches[i];
+        CacheEntry entry = cache.get(dependentResult.target);
+        if (entry != null) {
+          entry._setErrorState(dependentResult.result, exception);
+        }
+      }
     });
   }
 
@@ -865,6 +934,12 @@
   final InternalAnalysisContext context;
 
   /**
+   * A list of the caches that contain this partition. This includes the cache
+   * associated with the context that owns this partition.
+   */
+  final List<AnalysisCache> containingCaches = <AnalysisCache>[];
+
+  /**
    * A table mapping caching policies to the cache flush managers.
    */
   final HashMap<ResultCachingPolicy, CacheFlushManager> _flushManagerMap =
@@ -1013,11 +1088,6 @@
     }
   }
 
-  ResultData _getDataFor(TargetedResult result) {
-    CacheEntry entry = context.analysisCache.get(result.target);
-    return entry != null ? entry._resultMap[result.result] : null;
-  }
-
   /**
    * Return the [CacheFlushManager] for the given [descriptor], not `null`.
    */
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index f5464b1..23cae4a 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -116,6 +116,12 @@
    */
   AnalysisCache _cache;
 
+  @override
+  final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
+      new ReentrantSynchronousStream<InvalidatedResult>();
+
+  ReentrantSynchronousStreamSubscription onResultInvalidatedSubscription = null;
+
   /**
    * Configuration data associated with this context.
    */
@@ -215,7 +221,7 @@
 
   /**
    * The result of incremental resolution result of
-   * [incrementalResolutionValidation_lastSource].
+   * [incrementalResolutionValidation_lastUnitSource].
    */
   CompilationUnit incrementalResolutionValidation_lastUnit;
 
@@ -421,6 +427,7 @@
     }
     factory.context = this;
     _sourceFactory = factory;
+    _cache?.dispose();
     _cache = createCacheFromSourceFactory(factory);
     for (WorkManager workManager in workManagers) {
       workManager.onSourceFactoryChanged();
@@ -678,18 +685,25 @@
    * Create an analysis cache based on the given source [factory].
    */
   AnalysisCache createCacheFromSourceFactory(SourceFactory factory) {
-    if (factory == null) {
-      return new AnalysisCache(<CachePartition>[_privatePartition]);
+    AnalysisCache createCache() {
+      if (factory == null) {
+        return new AnalysisCache(<CachePartition>[_privatePartition]);
+      }
+      DartSdk sdk = factory.dartSdk;
+      if (sdk == null) {
+        return new AnalysisCache(<CachePartition>[_privatePartition]);
+      }
+      return new AnalysisCache(<CachePartition>[
+        AnalysisEngine.instance.partitionManager.forSdk(sdk),
+        _privatePartition
+      ]);
     }
-    DartSdk sdk = factory.dartSdk;
-    if (sdk == null) {
-      return new AnalysisCache(<CachePartition>[_privatePartition]);
-    }
-    AnalysisCache cache = new AnalysisCache(<CachePartition>[
-      AnalysisEngine.instance.partitionManager.forSdk(sdk),
-      _privatePartition
-    ]);
-    cache.onResultInvalidated.listen((InvalidatedResult event) {
+
+    AnalysisCache cache = createCache();
+    onResultInvalidatedSubscription?.cancel();
+    onResultInvalidatedSubscription =
+        cache.onResultInvalidated.listen((InvalidatedResult event) {
+      onResultInvalidated.add(event);
       StreamController<ResultChangedEvent> controller =
           _resultChangedControllers[event.descriptor];
       if (controller != null) {
@@ -1079,6 +1093,7 @@
    * to do.
    */
   void invalidateCachedResults() {
+    _cache?.dispose();
     _cache = createCacheFromSourceFactory(_sourceFactory);
     for (WorkManager workManager in workManagers) {
       workManager.onAnalysisOptionsChanged();
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
index dcd413a..0c9a84f 100644
--- a/pkg/analyzer/lib/src/context/source.dart
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -15,6 +15,7 @@
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
+import 'package:analyzer/src/util/fast_uri.dart';
 import 'package:package_config/packages.dart';
 
 /**
@@ -22,9 +23,6 @@
  * against an existing [Source].
  */
 class SourceFactoryImpl implements SourceFactory {
-  /**
-   * The analysis context that this source factory is associated with.
-   */
   @override
   AnalysisContext context;
 
@@ -57,23 +55,19 @@
 
   /**
    * Initialize a newly created source factory with the given absolute URI
-   * [resolvers] and optional [packages] resolution helper.
+   * [resolvers] and optional [_packages] resolution helper.
    */
   SourceFactoryImpl(this.resolvers,
       [this._packages, ResourceProvider resourceProvider])
       : _resourceProvider =
             resourceProvider ?? PhysicalResourceProvider.INSTANCE;
 
-  /**
-   * Return the [DartSdk] associated with this [SourceFactory], or `null` if
-   * there is no such SDK.
-   *
-   * @return the [DartSdk] associated with this [SourceFactory], or `null` if
-   *         there is no such SDK
-   */
   @override
   DartSdk get dartSdk {
-    for (UriResolver resolver in resolvers) {
+    List<UriResolver> resolvers = this.resolvers;
+    int length = resolvers.length;
+    for (int i = 0; i < length; i++) {
+      UriResolver resolver = resolvers[i];
       if (resolver is DartUriResolver) {
         DartUriResolver dartUriResolver = resolver;
         return dartUriResolver.dartSdk;
@@ -82,18 +76,11 @@
     return null;
   }
 
-  /**
-   * Sets the [LocalSourcePredicate].
-   *
-   * @param localSourcePredicate the predicate to determine is [Source] is local
-   */
   @override
   void set localSourcePredicate(LocalSourcePredicate localSourcePredicate) {
     this._localSourcePredicate = localSourcePredicate;
   }
 
-  /// A table mapping package names to paths of directories containing
-  /// the package (or [null] if there is no registered package URI resolver).
   @override
   Map<String, List<Folder>> get packageMap {
     // Start by looking in .packages.
@@ -115,10 +102,6 @@
     return resolver?.packageMap;
   }
 
-  /**
-   * Return a source factory that will resolve URI's in the same way that this
-   * source factory does.
-   */
   @override
   SourceFactory clone() {
     SourceFactory factory =
@@ -127,17 +110,10 @@
     return factory;
   }
 
-  /**
-   * Return a source object representing the given absolute URI, or `null` if
-   * the URI is not a valid URI or if it is not an absolute URI.
-   *
-   * @param absoluteUri the absolute URI to be resolved
-   * @return a source object representing the absolute URI
-   */
   @override
   Source forUri(String absoluteUri) {
     try {
-      Uri uri = parseUriWithException(absoluteUri);
+      Uri uri = FastUri.parse(absoluteUri);
       if (uri.isAbsolute) {
         return _internalResolveUri(null, uri);
       }
@@ -149,13 +125,6 @@
     return null;
   }
 
-  /**
-   * Return a source object representing the given absolute URI, or `null` if
-   * the URI is not an absolute URI.
-   *
-   * @param absoluteUri the absolute URI to be resolved
-   * @return a source object representing the absolute URI
-   */
   @override
   Source forUri2(Uri absoluteUri) {
     if (absoluteUri.isAbsolute) {
@@ -170,15 +139,6 @@
     return null;
   }
 
-  /**
-   * Return a source object that is equal to the source object used to obtain
-   * the given encoding.
-   *
-   * @param encoding the encoding of a source object
-   * @return a source object that is described by the given encoding
-   * @throws IllegalArgumentException if the argument is not a valid encoding
-   * See [Source.encoding].
-   */
   @override
   Source fromEncoding(String encoding) {
     Source source = forUri(encoding);
@@ -189,22 +149,9 @@
     return source;
   }
 
-  /**
-   * Determines if the given [Source] is local.
-   *
-   * @param source the [Source] to analyze
-   * @return `true` if the given [Source] is local
-   */
   @override
   bool isLocalSource(Source source) => _localSourcePredicate.isLocal(source);
 
-  /**
-   * Return a source representing the URI that results from resolving the given
-   * (possibly relative) [containedUri] against the URI associated with the
-   * [containingSource], whether or not the resulting source exists, or `null`
-   * if either the [containedUri] is invalid or if it cannot be resolved against
-   * the [containingSource]'s URI.
-   */
   @override
   Source resolveUri(Source containingSource, String containedUri) {
     if (containedUri == null || containedUri.isEmpty) {
@@ -212,8 +159,7 @@
     }
     try {
       // Force the creation of an escaped URI to deal with spaces, etc.
-      return _internalResolveUri(
-          containingSource, parseUriWithException(containedUri));
+      return _internalResolveUri(containingSource, FastUri.parse(containedUri));
     } on URISyntaxException {
       return null;
     } catch (exception, stackTrace) {
@@ -227,13 +173,6 @@
     }
   }
 
-  /**
-   * Return an absolute URI that represents the given source, or `null` if a
-   * valid URI cannot be computed.
-   *
-   * @param source the source to get URI for
-   * @return the absolute URI representing the given source
-   */
   @override
   Uri restoreUri(Source source) {
     // First see if a resolver can restore the URI.
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 2ed3515..5e2b646 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -2131,7 +2131,7 @@
 
   /**
    * Initialize a newly created comment. The list of [tokens] must contain at
-   * least one token. The [type] is the type of the comment. The list of
+   * least one token. The [_type] is the type of the comment. The list of
    * [references] can be empty if the comment does not contain any embedded
    * references.
    */
diff --git a/pkg/analyzer/lib/src/dart/ast/token.dart b/pkg/analyzer/lib/src/dart/ast/token.dart
index 39a3ab5..9828113 100644
--- a/pkg/analyzer/lib/src/dart/ast/token.dart
+++ b/pkg/analyzer/lib/src/dart/ast/token.dart
@@ -45,7 +45,7 @@
   /**
    * Initialize a newly created token to have the given [type] at the given
    * [offset] and to be preceded by the comments reachable from the given
-   * [comment].
+   * [_precedingComment].
    */
   BeginTokenWithComment(TokenType type, int offset, this._precedingComment)
       : super(type, offset) {
@@ -174,7 +174,7 @@
   /**
    * Initialize a newly created token to to represent the given [keyword] at the
    * given [offset] and to be preceded by the comments reachable from the given
-   * [comment].
+   * [_precedingComment].
    */
   KeywordTokenWithComment(Keyword keyword, int offset, this._precedingComment)
       : super(keyword, offset) {
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index ddcad2b..78d0f5f 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/src/generated/constant.dart' show EvaluationResultImpl;
 import 'package:analyzer/src/generated/engine.dart'
     show AnalysisContext, AnalysisEngine;
+import 'package:analyzer/src/generated/error.dart' show CompileTimeErrorCode;
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -429,9 +430,8 @@
   @override
   List<ElementAnnotation> get metadata {
     if (_unlinkedClass != null) {
-      return _metadata ??= _unlinkedClass.annotations
-          .map(enclosingUnit.resynthesizerContext.buildAnnotation)
-          .toList();
+      return _metadata ??=
+          _buildAnnotations(enclosingUnit, _unlinkedClass.annotations);
     }
     return super.metadata;
   }
@@ -474,6 +474,9 @@
   }
 
   @override
+  TypeParameterizedElementMixin get typeParameterContext => this;
+
+  @override
   List<TypeParameterElement> get typeParameters {
     if (_unlinkedClass != null) {
       return super.typeParameters;
@@ -614,7 +617,9 @@
 
   @override
   PropertyAccessorElement getGetter(String getterName) {
-    for (PropertyAccessorElement accessor in _accessors) {
+    int length = _accessors.length;
+    for (int i = 0; i < length; i++) {
+      PropertyAccessorElement accessor = _accessors[i];
       if (accessor.isGetter && accessor.name == getterName) {
         return accessor;
       }
@@ -624,7 +629,9 @@
 
   @override
   MethodElement getMethod(String methodName) {
-    for (MethodElement method in _methods) {
+    int length = _methods.length;
+    for (int i = 0; i < length; i++) {
+      MethodElement method = _methods[i];
       if (method.name == methodName) {
         return method;
       }
@@ -1085,7 +1092,7 @@
    * A list containing all of the top-level accessors (getters and setters)
    * contained in this compilation unit.
    */
-  List<PropertyAccessorElement> _accessors = PropertyAccessorElement.EMPTY_LIST;
+  List<PropertyAccessorElement> _accessors;
 
   /**
    * A list containing all of the enums contained in this compilation unit.
@@ -1096,7 +1103,7 @@
    * A list containing all of the top-level functions contained in this
    * compilation unit.
    */
-  List<FunctionElement> _functions = FunctionElement.EMPTY_LIST;
+  List<FunctionElement> _functions;
 
   /**
    * A list containing all of the function type aliases contained in this
@@ -1113,7 +1120,7 @@
   /**
    * A list containing all of the variables contained in this compilation unit.
    */
-  List<TopLevelVariableElement> _variables = TopLevelVariableElement.EMPTY_LIST;
+  List<TopLevelVariableElement> _variables;
 
   /**
    * A map from offsets to elements of this unit at these offsets.
@@ -1121,6 +1128,24 @@
   final Map<int, Element> _offsetToElementMap = new HashMap<int, Element>();
 
   /**
+   * Resynthesized explicit top-level property accessors.
+   */
+  UnitExplicitTopLevelAccessors _explicitTopLevelAccessors;
+
+  /**
+   * Resynthesized explicit top-level variables.
+   */
+  UnitExplicitTopLevelVariables _explicitTopLevelVariables;
+
+  /**
+   * Description of top-level variable replacements that should be applied
+   * to implicit top-level variables because of re-linking top-level property
+   * accessors between different unit of the same library.
+   */
+  Map<TopLevelVariableElement, TopLevelVariableElement>
+      _topLevelVariableReplaceMap;
+
+  /**
    * Initialize a newly created compilation unit element to have the given
    * [name].
    */
@@ -1146,7 +1171,22 @@
   }
 
   @override
-  List<PropertyAccessorElement> get accessors => _accessors;
+  List<PropertyAccessorElement> get accessors {
+    if (_unlinkedUnit != null) {
+      if (_accessors == null) {
+        _explicitTopLevelAccessors ??=
+            resynthesizerContext.buildTopLevelAccessors();
+        _explicitTopLevelVariables ??=
+            resynthesizerContext.buildTopLevelVariables();
+        List<PropertyAccessorElementImpl> accessors =
+            <PropertyAccessorElementImpl>[];
+        accessors.addAll(_explicitTopLevelAccessors.accessors);
+        accessors.addAll(_explicitTopLevelVariables.implicitAccessors);
+        _accessors = accessors;
+      }
+    }
+    return _accessors ?? PropertyAccessorElement.EMPTY_LIST;
+  }
 
   /**
    * Set the top-level accessors (getters and setters) contained in this
@@ -1198,7 +1238,12 @@
   }
 
   @override
-  List<FunctionElement> get functions => _functions;
+  List<FunctionElement> get functions {
+    if (_unlinkedUnit != null) {
+      _functions ??= resynthesizerContext.buildTopLevelFunctions();
+    }
+    return _functions ?? FunctionElement.EMPTY_LIST;
+  }
 
   /**
    * Set the top-level functions contained in this compilation unit to the given
@@ -1219,8 +1264,9 @@
 
   @override
   bool get hasLoadLibraryFunction {
-    for (int i = 0; i < _functions.length; i++) {
-      if (_functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
+    List<FunctionElement> functions = this.functions;
+    for (int i = 0; i < functions.length; i++) {
+      if (functions[i].name == FunctionElement.LOAD_LIBRARY_NAME) {
         return true;
       }
     }
@@ -1236,23 +1282,47 @@
   @override
   List<ElementAnnotation> get metadata {
     if (_unlinkedPart != null) {
-      CompilationUnitElementImpl definingUnit =
-          library.definingCompilationUnit as CompilationUnitElementImpl;
-      return _metadata ??= _unlinkedPart.annotations
-          .map(definingUnit.resynthesizerContext.buildAnnotation)
-          .toList();
+      return _metadata ??= _buildAnnotations(
+          library.definingCompilationUnit as CompilationUnitElementImpl,
+          _unlinkedPart.annotations);
     }
     return super.metadata;
   }
 
   @override
-  List<TopLevelVariableElement> get topLevelVariables => _variables;
+  List<TopLevelVariableElement> get topLevelVariables {
+    if (_unlinkedUnit != null) {
+      if (_variables == null) {
+        _explicitTopLevelAccessors ??=
+            resynthesizerContext.buildTopLevelAccessors();
+        _explicitTopLevelVariables ??=
+            resynthesizerContext.buildTopLevelVariables();
+        List<TopLevelVariableElementImpl> variables =
+            <TopLevelVariableElementImpl>[];
+        variables.addAll(_explicitTopLevelVariables.variables);
+        variables.addAll(_explicitTopLevelAccessors.implicitVariables);
+        // Ensure that getters and setters in different units use
+        // the same top-level variables.
+        (enclosingElement as LibraryElementImpl)
+            .resynthesizerContext
+            .patchTopLevelAccessors();
+        _variables = variables;
+        _topLevelVariableReplaceMap?.forEach((from, to) {
+          int index = _variables.indexOf(from);
+          _variables[index] = to;
+        });
+        _topLevelVariableReplaceMap = null;
+      }
+    }
+    return _variables ?? TopLevelVariableElement.EMPTY_LIST;
+  }
 
   /**
    * Set the top-level variables contained in this compilation unit to the given
    * [variables].
    */
   void set topLevelVariables(List<TopLevelVariableElement> variables) {
+    assert(!isResynthesized);
     for (TopLevelVariableElement field in variables) {
       (field as TopLevelVariableElementImpl).enclosingElement = this;
     }
@@ -1271,6 +1341,9 @@
   }
 
   @override
+  TypeParameterizedElementMixin get typeParameterContext => null;
+
+  @override
   List<ClassElement> get types => _types;
 
   /**
@@ -1334,19 +1407,19 @@
     // thrown a CCE if any of the elements in the arrays were not of the
     // expected types.
     //
-    for (PropertyAccessorElement accessor in _accessors) {
+    for (PropertyAccessorElement accessor in accessors) {
       PropertyAccessorElementImpl accessorImpl = accessor;
       if (accessorImpl.identifier == identifier) {
         return accessorImpl;
       }
     }
-    for (TopLevelVariableElement variable in _variables) {
+    for (TopLevelVariableElement variable in topLevelVariables) {
       TopLevelVariableElementImpl variableImpl = variable;
       if (variableImpl.identifier == identifier) {
         return variableImpl;
       }
     }
-    for (FunctionElement function in _functions) {
+    for (FunctionElement function in functions) {
       FunctionElementImpl functionImpl = function;
       if (functionImpl.identifier == identifier) {
         return functionImpl;
@@ -1360,7 +1433,7 @@
     }
     for (ClassElement type in _types) {
       ClassElementImpl typeImpl = type;
-      if (typeImpl.identifier == identifier) {
+      if (typeImpl.name == identifier) {
         return typeImpl;
       }
     }
@@ -1406,8 +1479,17 @@
    */
   void replaceTopLevelVariable(
       TopLevelVariableElement from, TopLevelVariableElement to) {
-    int index = _variables.indexOf(from);
-    _variables[index] = to;
+    if (_unlinkedUnit != null) {
+      // Getters and setter in different units should be patched to use the
+      // same variables before these variables were asked and returned.
+      assert(_variables == null);
+      _topLevelVariableReplaceMap ??=
+          <TopLevelVariableElement, TopLevelVariableElement>{};
+      _topLevelVariableReplaceMap[from] = to;
+    } else {
+      int index = _variables.indexOf(from);
+      _variables[index] = to;
+    }
   }
 
   /**
@@ -1422,12 +1504,12 @@
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
-    safelyVisitChildren(_accessors, visitor);
+    safelyVisitChildren(accessors, visitor);
     safelyVisitChildren(_enums, visitor);
-    safelyVisitChildren(_functions, visitor);
+    safelyVisitChildren(functions, visitor);
     safelyVisitChildren(_typeAliases, visitor);
     safelyVisitChildren(_types, visitor);
-    safelyVisitChildren(_variables, visitor);
+    safelyVisitChildren(topLevelVariables, visitor);
   }
 }
 
@@ -1452,6 +1534,13 @@
    * Initialize a newly created field element to have the given [name].
    */
   ConstFieldElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  ConstFieldElementImpl.forSerialized(
+      UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
+      : super.forSerialized(unlinkedVariable, enclosingElement);
 }
 
 /**
@@ -1541,6 +1630,10 @@
   @override
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
 
+  @override
+  TypeParameterizedElementMixin get enclosingTypeParameterContext =>
+      super.enclosingElement as ClassElementImpl;
+
   /**
    * Set whether this constructor represents a factory method.
    */
@@ -1639,6 +1732,13 @@
    */
   ConstTopLevelVariableElementImpl.forNode(Identifier name)
       : super.forNode(name);
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  ConstTopLevelVariableElementImpl.forSerialized(
+      UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
+      : super.forSerialized(unlinkedVariable, enclosingElement);
 }
 
 /**
@@ -1721,8 +1821,8 @@
    * Initialize using the given serialized information.
    */
   DefaultParameterElementImpl.forSerialized(
-      UnlinkedParam unlinkedParam, ExecutableElementImpl enclosingExecutable)
-      : super.forSerialized(unlinkedParam, enclosingExecutable);
+      UnlinkedParam unlinkedParam, ElementImpl enclosingElement)
+      : super.forSerialized(unlinkedParam, enclosingElement);
 
   @override
   Expression get constantInitializer {
@@ -1731,8 +1831,8 @@
       if (defaultValue == null) {
         return null;
       }
-      return super.constantInitializer ??=
-          enclosingUnit.resynthesizerContext.buildExpression(defaultValue);
+      return super.constantInitializer ??= enclosingUnit.resynthesizerContext
+          .buildExpression(this, defaultValue);
     }
     return super.constantInitializer;
   }
@@ -1765,7 +1865,7 @@
    * Initialize a newly created instance of this class. Instances of this class
    * should <b>not</b> be created except as part of creating the type associated
    * with this element. The single instance of this class should be accessed
-   * through the method [getInstance].
+   * through the method [instance].
    */
   DynamicElementImpl() : super(Keyword.DYNAMIC.syntax, -1) {
     setModifier(Modifier.SYNTHETIC, true);
@@ -2263,6 +2363,15 @@
     setModifier(Modifier.SYNTHETIC, isSynthetic);
   }
 
+  /**
+   * Return the context to resolve type parameters in, or `null` if neither this
+   * element nor any of its ancestors is of a kind that can declare type
+   * parameters.
+   */
+  TypeParameterizedElementMixin get typeParameterContext {
+    return _enclosingElement?.typeParameterContext;
+  }
+
   @override
   CompilationUnit get unit => context.resolveCompilationUnit(source, library);
 
@@ -2431,6 +2540,24 @@
   }
 
   /**
+   * Return annotations for the given [unlinkedConsts] in the [unit].
+   */
+  List<ElementAnnotation> _buildAnnotations(
+      CompilationUnitElementImpl unit, List<UnlinkedConst> unlinkedConsts) {
+    int length = unlinkedConsts.length;
+    if (length != 0) {
+      List<ElementAnnotation> annotations = new List<ElementAnnotation>(length);
+      ResynthesizerContext context = unit.resynthesizerContext;
+      for (int i = 0; i < length; i++) {
+        annotations[i] = context.buildAnnotation(this, unlinkedConsts[i]);
+      }
+      return annotations;
+    } else {
+      return const <ElementAnnotation>[];
+    }
+  }
+
+  /**
    *  Updates cached values after an input changed.
    *
    *  Throws [FrozenHashCodeException] if not allowed.
@@ -2615,6 +2742,7 @@
  * A base class for concrete implementations of an [ExecutableElement].
  */
 abstract class ExecutableElementImpl extends ElementImpl
+    with TypeParameterizedElementMixin
     implements ExecutableElement {
   /**
    * The unlinked representation of the executable in the summary.
@@ -2849,9 +2977,8 @@
   @override
   List<ElementAnnotation> get metadata {
     if (serializedExecutable != null) {
-      return _metadata ??= serializedExecutable.annotations
-          .map(enclosingUnit.resynthesizerContext.buildAnnotation)
-          .toList();
+      return _metadata ??=
+          _buildAnnotations(enclosingUnit, serializedExecutable.annotations);
     }
     return super.metadata;
   }
@@ -2887,6 +3014,9 @@
   }
 
   @override
+  TypeParameterizedElementMixin get typeParameterContext => this;
+
+  @override
   List<TypeParameterElement> get typeParameters => _typeParameters;
 
   /**
@@ -2901,6 +3031,10 @@
   }
 
   @override
+  List<UnlinkedTypeParam> get unlinkedTypeParams =>
+      serializedExecutable.typeParameters;
+
+  @override
   void appendTo(StringBuffer buffer) {
     if (this.kind != ElementKind.GETTER) {
       int typeParameterCount = _typeParameters.length;
@@ -2997,20 +3131,69 @@
 class ExportElementImpl extends UriReferencedElementImpl
     implements ExportElement {
   /**
+   * The unlinked representation of the export in the summary.
+   */
+  final UnlinkedExportPublic _unlinkedExportPublic;
+
+  /**
+   * The unlinked representation of the export in the summary.
+   */
+  final UnlinkedExportNonPublic _unlinkedExportNonPublic;
+
+  /**
    * The library that is exported from this library by this export directive.
    */
-  LibraryElement exportedLibrary;
+  LibraryElement _exportedLibrary;
 
   /**
    * The combinators that were specified as part of the export directive in the
    * order in which they were specified.
    */
-  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
+  List<NamespaceCombinator> _combinators;
 
   /**
    * Initialize a newly created export element at the given [offset].
    */
-  ExportElementImpl(int offset) : super(null, offset);
+  ExportElementImpl(int offset)
+      : _unlinkedExportPublic = null,
+        _unlinkedExportNonPublic = null,
+        super(null, offset);
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  ExportElementImpl.forSerialized(this._unlinkedExportPublic,
+      this._unlinkedExportNonPublic, LibraryElementImpl enclosingLibrary)
+      : super.forSerialized(enclosingLibrary);
+
+  @override
+  List<NamespaceCombinator> get combinators {
+    if (_unlinkedExportPublic != null && _combinators == null) {
+      _combinators = ImportElementImpl
+          ._buildCombinators(_unlinkedExportPublic.combinators);
+    }
+    return _combinators ?? const <NamespaceCombinator>[];
+  }
+
+  void set combinators(List<NamespaceCombinator> combinators) {
+    assert(_unlinkedExportPublic == null);
+    _combinators = combinators;
+  }
+
+  @override
+  LibraryElement get exportedLibrary {
+    if (_unlinkedExportNonPublic != null && _exportedLibrary == null) {
+      LibraryElementImpl library = enclosingElement as LibraryElementImpl;
+      _exportedLibrary = library.resynthesizerContext
+          .buildExportedLibrary(_unlinkedExportPublic.uri);
+    }
+    return _exportedLibrary;
+  }
+
+  void set exportedLibrary(LibraryElement exportedLibrary) {
+    assert(_unlinkedExportNonPublic == null);
+    _exportedLibrary = exportedLibrary;
+  }
 
   @override
   String get identifier => exportedLibrary.name;
@@ -3019,6 +3202,71 @@
   ElementKind get kind => ElementKind.EXPORT;
 
   @override
+  List<ElementAnnotation> get metadata {
+    if (_unlinkedExportNonPublic != null) {
+      return _metadata ??= _buildAnnotations(
+          library.definingCompilationUnit as CompilationUnitElementImpl,
+          _unlinkedExportNonPublic.annotations);
+    }
+    return super.metadata;
+  }
+
+  void set metadata(List<ElementAnnotation> metadata) {
+    assert(_unlinkedExportNonPublic == null);
+    super.metadata = metadata;
+  }
+
+  @override
+  int get nameOffset {
+    if (_unlinkedExportNonPublic != null) {
+      return _unlinkedExportNonPublic.offset;
+    }
+    return super.nameOffset;
+  }
+
+  @override
+  String get uri {
+    if (_unlinkedExportPublic != null) {
+      return _unlinkedExportPublic.uri;
+    }
+    return super.uri;
+  }
+
+  @override
+  void set uri(String uri) {
+    assert(_unlinkedExportPublic == null);
+    super.uri = uri;
+  }
+
+  @override
+  int get uriEnd {
+    if (_unlinkedExportNonPublic != null) {
+      return _unlinkedExportNonPublic.uriEnd;
+    }
+    return super.uriEnd;
+  }
+
+  @override
+  void set uriEnd(int uriEnd) {
+    assert(_unlinkedExportNonPublic == null);
+    super.uriEnd = uriEnd;
+  }
+
+  @override
+  int get uriOffset {
+    if (_unlinkedExportNonPublic != null) {
+      return _unlinkedExportNonPublic.uriOffset;
+    }
+    return super.uriOffset;
+  }
+
+  @override
+  void set uriOffset(int uriOffset) {
+    assert(_unlinkedExportNonPublic == null);
+    super.uriOffset = uriOffset;
+  }
+
+  @override
   accept(ElementVisitor visitor) => visitor.visitExportElement(this);
 
   @override
@@ -3044,6 +3292,13 @@
    */
   FieldElementImpl.forNode(Identifier name) : super.forNode(name);
 
+  /**
+   * Initialize using the given serialized information.
+   */
+  FieldElementImpl.forSerialized(
+      UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
+      : super.forSerialized(unlinkedVariable, enclosingElement);
+
   @override
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
 
@@ -3147,7 +3402,7 @@
 
   /**
    * Initialize a newly created function element to have no name and the given
-   * [offset]. This is used for function expressions, that have no name.
+   * [nameOffset]. This is used for function expressions, that have no name.
    */
   FunctionElementImpl.forOffset(int nameOffset) : super("", nameOffset);
 
@@ -3173,6 +3428,11 @@
   }
 
   @override
+  TypeParameterizedElementMixin get enclosingTypeParameterContext {
+    return (enclosingElement as ElementImpl).typeParameterContext;
+  }
+
+  @override
   String get identifier {
     String identifier = super.identifier;
     if (!isStatic) {
@@ -3357,9 +3617,8 @@
   @override
   List<ElementAnnotation> get metadata {
     if (_unlinkedTypedef != null) {
-      return _metadata ??= _unlinkedTypedef.annotations
-          .map(enclosingUnit.resynthesizerContext.buildAnnotation)
-          .toList();
+      return _metadata ??=
+          _buildAnnotations(enclosingUnit, _unlinkedTypedef.annotations);
     }
     return super.metadata;
   }
@@ -3396,6 +3655,9 @@
   }
 
   @override
+  TypeParameterizedElementMixin get typeParameterContext => this;
+
+  @override
   List<TypeParameterElement> get typeParameters {
     if (_unlinkedTypedef != null) {
       return super.typeParameters;
@@ -3489,10 +3751,35 @@
  */
 class HideElementCombinatorImpl implements HideElementCombinator {
   /**
+   * The unlinked representation of the combinator in the summary.
+   */
+  final UnlinkedCombinator _unlinkedCombinator;
+
+  /**
    * The names that are not to be made visible in the importing library even if
    * they are defined in the imported library.
    */
-  List<String> hiddenNames = StringUtilities.EMPTY_ARRAY;
+  List<String> _hiddenNames;
+
+  HideElementCombinatorImpl() : _unlinkedCombinator = null;
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  HideElementCombinatorImpl.forSerialized(this._unlinkedCombinator);
+
+  @override
+  List<String> get hiddenNames {
+    if (_unlinkedCombinator != null) {
+      _hiddenNames ??= _unlinkedCombinator.hides.toList(growable: false);
+    }
+    return _hiddenNames ?? const <String>[];
+  }
+
+  void set hiddenNames(List<String> hiddenNames) {
+    assert(_unlinkedCombinator == null);
+    _hiddenNames = hiddenNames;
+  }
 
   @override
   String toString() {
@@ -3515,38 +3802,72 @@
 class ImportElementImpl extends UriReferencedElementImpl
     implements ImportElement {
   /**
+   * The unlinked representation of the import in the summary.
+   */
+  final UnlinkedImport _unlinkedImport;
+
+  /**
+   * The index of the dependency in the `imports` list.
+   */
+  final int _linkedDependency;
+
+  /**
    * The offset of the prefix of this import in the file that contains the this
    * import directive, or `-1` if this import is synthetic.
    */
-  int prefixOffset = 0;
+  int _prefixOffset = 0;
 
   /**
    * The library that is imported into this library by this import directive.
    */
-  LibraryElement importedLibrary;
+  LibraryElement _importedLibrary;
 
   /**
    * The combinators that were specified as part of the import directive in the
    * order in which they were specified.
    */
-  List<NamespaceCombinator> combinators = NamespaceCombinator.EMPTY_LIST;
+  List<NamespaceCombinator> _combinators;
 
   /**
    * The prefix that was specified as part of the import directive, or `null` if
    * there was no prefix specified.
    */
-  PrefixElement prefix;
+  PrefixElement _prefix;
 
   /**
    * Initialize a newly created import element at the given [offset].
    * The offset may be `-1` if the import is synthetic.
    */
-  ImportElementImpl(int offset) : super(null, offset);
+  ImportElementImpl(int offset)
+      : _unlinkedImport = null,
+        _linkedDependency = null,
+        super(null, offset);
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  ImportElementImpl.forSerialized(this._unlinkedImport, this._linkedDependency,
+      LibraryElementImpl enclosingLibrary)
+      : super.forSerialized(enclosingLibrary);
+
+  @override
+  List<NamespaceCombinator> get combinators {
+    if (_unlinkedImport != null && _combinators == null) {
+      _combinators = _buildCombinators(_unlinkedImport.combinators);
+    }
+    return _combinators ?? const <NamespaceCombinator>[];
+  }
+
+  void set combinators(List<NamespaceCombinator> combinators) {
+    assert(_unlinkedImport == null);
+    _combinators = combinators;
+  }
 
   /**
    * Set whether this import is for a deferred library.
    */
   void set deferred(bool isDeferred) {
+    assert(_unlinkedImport == null);
     setModifier(Modifier.DEFERRED, isDeferred);
   }
 
@@ -3554,12 +3875,151 @@
   String get identifier => "${importedLibrary.identifier}@$nameOffset";
 
   @override
-  bool get isDeferred => hasModifier(Modifier.DEFERRED);
+  LibraryElement get importedLibrary {
+    if (_linkedDependency != null) {
+      if (_importedLibrary == null) {
+        LibraryElementImpl library = enclosingElement as LibraryElementImpl;
+        if (_linkedDependency == 0) {
+          _importedLibrary = library;
+        } else {
+          _importedLibrary = library.resynthesizerContext
+              .buildImportedLibrary(_linkedDependency);
+        }
+      }
+    }
+    return _importedLibrary;
+  }
+
+  void set importedLibrary(LibraryElement importedLibrary) {
+    assert(_unlinkedImport == null);
+    _importedLibrary = importedLibrary;
+  }
+
+  @override
+  bool get isDeferred {
+    if (_unlinkedImport != null) {
+      return _unlinkedImport.isDeferred;
+    }
+    return hasModifier(Modifier.DEFERRED);
+  }
+
+  @override
+  bool get isSynthetic {
+    if (_unlinkedImport != null) {
+      return _unlinkedImport.isImplicit;
+    }
+    return super.isSynthetic;
+  }
 
   @override
   ElementKind get kind => ElementKind.IMPORT;
 
   @override
+  List<ElementAnnotation> get metadata {
+    if (_unlinkedImport != null) {
+      return _metadata ??= _buildAnnotations(
+          library.definingCompilationUnit as CompilationUnitElementImpl,
+          _unlinkedImport.annotations);
+    }
+    return super.metadata;
+  }
+
+  void set metadata(List<ElementAnnotation> metadata) {
+    assert(_unlinkedImport == null);
+    super.metadata = metadata;
+  }
+
+  @override
+  int get nameOffset {
+    if (_unlinkedImport != null) {
+      if (_unlinkedImport.isImplicit) {
+        return -1;
+      }
+      return _unlinkedImport.offset;
+    }
+    return super.nameOffset;
+  }
+
+  PrefixElement get prefix {
+    if (_unlinkedImport != null) {
+      if (_unlinkedImport.prefixReference != 0 && _prefix == null) {
+        LibraryElementImpl library = enclosingElement as LibraryElementImpl;
+        _prefix = new PrefixElementImpl.forSerialized(_unlinkedImport, library);
+      }
+    }
+    return _prefix;
+  }
+
+  void set prefix(PrefixElement prefix) {
+    assert(_unlinkedImport == null);
+    _prefix = prefix;
+  }
+
+  @override
+  int get prefixOffset {
+    if (_unlinkedImport != null) {
+      return _unlinkedImport.prefixOffset;
+    }
+    return _prefixOffset;
+  }
+
+  void set prefixOffset(int prefixOffset) {
+    assert(_unlinkedImport == null);
+    _prefixOffset = prefixOffset;
+  }
+
+  @override
+  String get uri {
+    if (_unlinkedImport != null) {
+      if (_unlinkedImport.isImplicit) {
+        return null;
+      }
+      return _unlinkedImport.uri;
+    }
+    return super.uri;
+  }
+
+  @override
+  void set uri(String uri) {
+    assert(_unlinkedImport == null);
+    super.uri = uri;
+  }
+
+  @override
+  int get uriEnd {
+    if (_unlinkedImport != null) {
+      if (_unlinkedImport.isImplicit) {
+        return -1;
+      }
+      return _unlinkedImport.uriEnd;
+    }
+    return super.uriEnd;
+  }
+
+  @override
+  void set uriEnd(int uriEnd) {
+    assert(_unlinkedImport == null);
+    super.uriEnd = uriEnd;
+  }
+
+  @override
+  int get uriOffset {
+    if (_unlinkedImport != null) {
+      if (_unlinkedImport.isImplicit) {
+        return -1;
+      }
+      return _unlinkedImport.uriOffset;
+    }
+    return super.uriOffset;
+  }
+
+  @override
+  void set uriOffset(int uriOffset) {
+    assert(_unlinkedImport == null);
+    super.uriOffset = uriOffset;
+  }
+
+  @override
   accept(ElementVisitor visitor) => visitor.visitImportElement(this);
 
   @override
@@ -3573,6 +4033,24 @@
     super.visitChildren(visitor);
     prefix?.accept(visitor);
   }
+
+  static List<NamespaceCombinator> _buildCombinators(
+      List<UnlinkedCombinator> unlinkedCombinators) {
+    int length = unlinkedCombinators.length;
+    if (length != 0) {
+      List<NamespaceCombinator> combinators =
+          new List<NamespaceCombinator>(length);
+      for (int i = 0; i < length; i++) {
+        UnlinkedCombinator unlinkedCombinator = unlinkedCombinators[i];
+        combinators[i] = unlinkedCombinator.shows.isNotEmpty
+            ? new ShowElementCombinatorImpl.forSerialized(unlinkedCombinator)
+            : new HideElementCombinatorImpl.forSerialized(unlinkedCombinator);
+      }
+      return combinators;
+    } else {
+      return const <NamespaceCombinator>[];
+    }
+  }
 }
 
 /**
@@ -3605,8 +4083,8 @@
 
   /**
    * Initialize a newly created label element to have the given [name].
-   * [onSwitchStatement] should be `true` if this label is associated with a
-   * `switch` statement and [onSwitchMember] should be `true` if this label is
+   * [_onSwitchStatement] should be `true` if this label is associated with a
+   * `switch` statement and [_onSwitchMember] should be `true` if this label is
    * associated with a `switch` member.
    */
   LabelElementImpl.forNode(
@@ -3644,6 +4122,10 @@
    */
   final AnalysisContext context;
 
+  final LibraryResynthesizerContext resynthesizerContext;
+
+  final UnlinkedUnit _unlinkedDefiningUnit;
+
   /**
    * The compilation unit that defines this library.
    */
@@ -3653,19 +4135,19 @@
    * The entry point for this library, or `null` if this library does not have
    * an entry point.
    */
-  FunctionElement entryPoint;
+  FunctionElement _entryPoint;
 
   /**
    * A list containing specifications of all of the imports defined in this
    * library.
    */
-  List<ImportElement> _imports = ImportElement.EMPTY_LIST;
+  List<ImportElement> _imports;
 
   /**
    * A list containing specifications of all of the exports defined in this
    * library.
    */
-  List<ExportElement> _exports = ExportElement.EMPTY_LIST;
+  List<ExportElement> _exports;
 
   /**
    * A list containing the strongly connected component in the import/export
@@ -3695,22 +4177,32 @@
    * The export [Namespace] of this library, `null` if it has not been
    * computed yet.
    */
-  @override
-  Namespace exportNamespace;
+  Namespace _exportNamespace;
 
   /**
    * The public [Namespace] of this library, `null` if it has not been
    * computed yet.
    */
-  @override
-  Namespace publicNamespace;
+  Namespace _publicNamespace;
+
+  /**
+   * A bit-encoded form of the capabilities associated with this library.
+   */
+  int _resolutionCapabilities = 0;
+
+  /**
+   * The cached list of prefixes.
+   */
+  List<PrefixElement> _prefixes;
 
   /**
    * Initialize a newly created library element in the given [context] to have
    * the given [name] and [offset].
    */
   LibraryElementImpl(this.context, String name, int offset, this.nameLength)
-      : super(name, offset);
+      : resynthesizerContext = null,
+        _unlinkedDefiningUnit = null,
+        super(name, offset);
 
   /**
    * Initialize a newly created library element in the given [context] to have
@@ -3718,8 +4210,24 @@
    */
   LibraryElementImpl.forNode(this.context, LibraryIdentifier name)
       : nameLength = name != null ? name.length : 0,
+        resynthesizerContext = null,
+        _unlinkedDefiningUnit = null,
         super.forNode(name);
 
+  /**
+   * Initialize using the given serialized information.
+   */
+  LibraryElementImpl.forSerialized(this.context, String name, int offset,
+      this.nameLength, this.resynthesizerContext, this._unlinkedDefiningUnit)
+      : super.forSerialized(null) {
+    _name = name;
+    _nameOffset = offset;
+    setResolutionCapability(
+        LibraryResolutionCapability.resolvedTypeNames, true);
+    setResolutionCapability(
+        LibraryResolutionCapability.constantExpressions, true);
+  }
+
   @override
   int get codeLength {
     CompilationUnitElement unit = _definingCompilationUnit;
@@ -3753,9 +4261,40 @@
   }
 
   @override
+  SourceRange get docRange {
+    if (_unlinkedDefiningUnit != null) {
+      UnlinkedDocumentationComment comment =
+          _unlinkedDefiningUnit.libraryDocumentationComment;
+      return comment != null
+          ? new SourceRange(comment.offset, comment.length)
+          : null;
+    }
+    return super.docRange;
+  }
+
+  @override
+  String get documentationComment {
+    if (_unlinkedDefiningUnit != null) {
+      return _unlinkedDefiningUnit?.libraryDocumentationComment?.text;
+    }
+    return super.documentationComment;
+  }
+
+  FunctionElement get entryPoint {
+    if (resynthesizerContext != null) {
+      _entryPoint ??= resynthesizerContext.findEntryPoint();
+    }
+    return _entryPoint;
+  }
+
+  void set entryPoint(FunctionElement entryPoint) {
+    _entryPoint = entryPoint;
+  }
+
+  @override
   List<LibraryElement> get exportedLibraries {
     HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
-    for (ExportElement element in _exports) {
+    for (ExportElement element in exports) {
       LibraryElement library = element.exportedLibrary;
       if (library != null) {
         libraries.add(library);
@@ -3765,13 +4304,51 @@
   }
 
   @override
-  List<ExportElement> get exports => _exports;
+  Namespace get exportNamespace {
+    if (resynthesizerContext != null) {
+      _exportNamespace ??= resynthesizerContext.buildExportNamespace();
+    }
+    return _exportNamespace;
+  }
+
+  void set exportNamespace(Namespace exportNamespace) {
+    _exportNamespace = exportNamespace;
+  }
+
+  @override
+  List<ExportElement> get exports {
+    if (_unlinkedDefiningUnit != null && _exports == null) {
+      List<UnlinkedExportNonPublic> unlinkedNonPublicExports =
+          _unlinkedDefiningUnit.exports;
+      List<UnlinkedExportPublic> unlinkedPublicExports =
+          _unlinkedDefiningUnit.publicNamespace.exports;
+      assert(
+          _unlinkedDefiningUnit.exports.length == unlinkedPublicExports.length);
+      int length = unlinkedNonPublicExports.length;
+      if (length != 0) {
+        List<ExportElement> exports = new List<ExportElement>(length);
+        for (int i = 0; i < length; i++) {
+          UnlinkedExportPublic serializedExportPublic =
+              unlinkedPublicExports[i];
+          UnlinkedExportNonPublic serializedExportNonPublic =
+              unlinkedNonPublicExports[i];
+          exports[i] = new ExportElementImpl.forSerialized(
+              serializedExportPublic, serializedExportNonPublic, library);
+        }
+        _exports = exports;
+      } else {
+        _exports = const <ExportElement>[];
+      }
+    }
+    return _exports ?? const <ExportElement>[];
+  }
 
   /**
    * Set the specifications of all of the exports defined in this library to the
    * given list of [exports].
    */
   void set exports(List<ExportElement> exports) {
+    assert(_unlinkedDefiningUnit == null);
     for (ExportElement exportElement in exports) {
       (exportElement as ExportElementImpl).enclosingElement = this;
     }
@@ -3807,7 +4384,7 @@
   @override
   List<LibraryElement> get importedLibraries {
     HashSet<LibraryElement> libraries = new HashSet<LibraryElement>();
-    for (ImportElement element in _imports) {
+    for (ImportElement element in imports) {
       LibraryElement library = element.importedLibrary;
       if (library != null) {
         libraries.add(library);
@@ -3817,13 +4394,31 @@
   }
 
   @override
-  List<ImportElement> get imports => _imports;
+  List<ImportElement> get imports {
+    if (_unlinkedDefiningUnit != null && _imports == null) {
+      List<UnlinkedImport> unlinkedImports = _unlinkedDefiningUnit.imports;
+      int length = unlinkedImports.length;
+      if (length != 0) {
+        List<ImportElement> imports = new List<ImportElement>(length);
+        LinkedLibrary linkedLibrary = resynthesizerContext.linkedLibrary;
+        for (int i = 0; i < length; i++) {
+          imports[i] = new ImportElementImpl.forSerialized(
+              unlinkedImports[i], linkedLibrary.importDependencies[i], library);
+        }
+        _imports = imports;
+      } else {
+        _imports = const <ImportElement>[];
+      }
+    }
+    return _imports ?? ImportElement.EMPTY_LIST;
+  }
 
   /**
    * Set the specifications of all of the imports defined in this library to the
    * given list of [imports].
    */
   void set imports(List<ImportElement> imports) {
+    assert(_unlinkedDefiningUnit == null);
     for (ImportElement importElement in imports) {
       (importElement as ImportElementImpl).enclosingElement = this;
       PrefixElementImpl prefix = importElement.prefix as PrefixElementImpl;
@@ -3832,6 +4427,7 @@
       }
     }
     this._imports = imports;
+    this._prefixes = null;
   }
 
   @override
@@ -3878,9 +4474,7 @@
 
   @override
   bool get isResynthesized {
-    CompilationUnitElement definingUnit = _definingCompilationUnit;
-    return definingUnit is CompilationUnitElementImpl &&
-        definingUnit.resynthesizerContext != null;
+    return resynthesizerContext != null;
   }
 
   @override
@@ -3973,6 +4567,17 @@
   }
 
   @override
+  List<ElementAnnotation> get metadata {
+    if (_unlinkedDefiningUnit != null) {
+      _metadata ??= _buildAnnotations(
+          _definingCompilationUnit as CompilationUnitElementImpl,
+          _unlinkedDefiningUnit.libraryAnnotations);
+      return _metadata;
+    }
+    return super.metadata;
+  }
+
+  @override
   List<CompilationUnitElement> get parts => _parts;
 
   /**
@@ -3990,14 +4595,29 @@
 
   @override
   List<PrefixElement> get prefixes {
-    HashSet<PrefixElement> prefixes = new HashSet<PrefixElement>();
-    for (ImportElement element in _imports) {
-      PrefixElement prefix = element.prefix;
-      if (prefix != null) {
-        prefixes.add(prefix);
+    if (_prefixes == null) {
+      HashSet<PrefixElement> prefixes = new HashSet<PrefixElement>();
+      for (ImportElement element in imports) {
+        PrefixElement prefix = element.prefix;
+        if (prefix != null) {
+          prefixes.add(prefix);
+        }
       }
+      _prefixes = prefixes.toList();
     }
-    return new List.from(prefixes);
+    return _prefixes;
+  }
+
+  @override
+  Namespace get publicNamespace {
+    if (resynthesizerContext != null) {
+      _publicNamespace ??= resynthesizerContext.buildPublicNamespace();
+    }
+    return _publicNamespace;
+  }
+
+  void set publicNamespace(Namespace publicNamespace) {
+    _publicNamespace = publicNamespace;
   }
 
   @override
@@ -4052,13 +4672,13 @@
         return partImpl;
       }
     }
-    for (ImportElement importElement in _imports) {
+    for (ImportElement importElement in imports) {
       ImportElementImpl importElementImpl = importElement;
       if (importElementImpl.identifier == identifier) {
         return importElementImpl;
       }
     }
-    for (ExportElement exportElement in _exports) {
+    for (ExportElement exportElement in exports) {
       ExportElementImpl exportElementImpl = exportElement;
       if (exportElementImpl.identifier == identifier) {
         return exportElementImpl;
@@ -4069,11 +4689,12 @@
 
   @override
   List<ImportElement> getImportsWithPrefix(PrefixElement prefixElement) {
-    int count = _imports.length;
+    var imports = this.imports;
+    int count = imports.length;
     List<ImportElement> importList = new List<ImportElement>();
     for (int i = 0; i < count; i++) {
-      if (identical(_imports[i].prefix, prefixElement)) {
-        importList.add(_imports[i]);
+      if (identical(imports[i].prefix, prefixElement)) {
+        importList.add(imports[i]);
       }
     }
     return importList;
@@ -4154,12 +4775,22 @@
     return _safeIsUpToDate(this, timeStamp, visitedLibraries);
   }
 
+  /**
+   * Set whether the library has the given [capability] to
+   * correspond to the given [value].
+   */
+  void setResolutionCapability(
+      LibraryResolutionCapability capability, bool value) {
+    _resolutionCapabilities =
+        BooleanArray.set(_resolutionCapabilities, capability.index, value);
+  }
+
   @override
   void visitChildren(ElementVisitor visitor) {
     super.visitChildren(visitor);
     _definingCompilationUnit?.accept(visitor);
-    safelyVisitChildren(_exports, visitor);
-    safelyVisitChildren(_imports, visitor);
+    safelyVisitChildren(exports, visitor);
+    safelyVisitChildren(imports, visitor);
     safelyVisitChildren(_parts, visitor);
   }
 
@@ -4174,7 +4805,7 @@
       return;
     }
     // add imported libraries
-    for (ImportElement importElement in _imports) {
+    for (ImportElement importElement in imports) {
       LibraryElement importedLibrary = importElement.importedLibrary;
       if (importedLibrary != null) {
         (importedLibrary as LibraryElementImpl)
@@ -4183,7 +4814,7 @@
     }
     // add exported libraries
     if (includeExports) {
-      for (ExportElement exportElement in _exports) {
+      for (ExportElement exportElement in exports) {
         LibraryElement exportedLibrary = exportElement.exportedLibrary;
         if (exportedLibrary != null) {
           (exportedLibrary as LibraryElementImpl)
@@ -4194,6 +4825,15 @@
   }
 
   /**
+   * Return `true` if the [library] has the given [capability].
+   */
+  static bool hasResolutionCapability(
+      LibraryElement library, LibraryResolutionCapability capability) {
+    return library is LibraryElementImpl &&
+        BooleanArray.get(library._resolutionCapabilities, capability.index);
+  }
+
+  /**
    * Return `true` if the given [library] is up to date with respect to the
    * given [timeStamp]. The set of [visitedLibraries] is used to prevent
    * infinite recursion in the case of mutually dependent libraries.
@@ -4233,6 +4873,65 @@
 }
 
 /**
+ * Enum of possible resolution capabilities that a [LibraryElementImpl] has.
+ */
+enum LibraryResolutionCapability {
+  /**
+   * All elements have their types resolved.
+   */
+  resolvedTypeNames,
+
+  /**
+   * All (potentially) constants expressions are set into corresponding
+   * elements.
+   */
+  constantExpressions,
+}
+
+/**
+ * The context in which the library is resynthesized.
+ */
+abstract class LibraryResynthesizerContext {
+  /**
+   * Return the [LinkedLibrary] that corresponds to the library being
+   * resynthesized.
+   */
+  LinkedLibrary get linkedLibrary;
+
+  /**
+   * Return the exported [LibraryElement] for with the given [relativeUri].
+   */
+  LibraryElement buildExportedLibrary(String relativeUri);
+
+  /**
+   * Return the export namespace of the library.
+   */
+  Namespace buildExportNamespace();
+
+  /**
+   * Return the imported [LibraryElement] for the given dependency in the
+   * linked library.
+   */
+  LibraryElement buildImportedLibrary(int dependency);
+
+  /**
+   * Return the public namespace of the library.
+   */
+  Namespace buildPublicNamespace();
+
+  /**
+   * Find the entry point of the library.
+   */
+  FunctionElement findEntryPoint();
+
+  /**
+   * Ensure that getters and setters in different units use the same
+   * top-level variables.
+   */
+  void patchTopLevelAccessors();
+}
+
+/**
  * A concrete implementation of a [LocalVariableElement].
  */
 class LocalVariableElementImpl extends NonParameterVariableElementImpl
@@ -4358,6 +5057,10 @@
   ClassElement get enclosingElement => super.enclosingElement as ClassElement;
 
   @override
+  TypeParameterizedElementMixin get enclosingTypeParameterContext =>
+      super.enclosingElement as ClassElementImpl;
+
+  @override
   bool get isOperator {
     String name = displayName;
     if (name.isEmpty) {
@@ -4795,6 +5498,9 @@
   }
 
   @override
+  TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
+
+  @override
   List<ExecutableElement> get inheritedElements => _elements;
 
   void set inheritedElements(List<ExecutableElement> elements) {
@@ -4856,6 +5562,26 @@
   }
 
   @override
+  SourceRange get docRange {
+    if (_unlinkedVariable != null) {
+      UnlinkedDocumentationComment comment =
+          _unlinkedVariable.documentationComment;
+      return comment != null
+          ? new SourceRange(comment.offset, comment.length)
+          : null;
+    }
+    return super.docRange;
+  }
+
+  @override
+  String get documentationComment {
+    if (_unlinkedVariable != null) {
+      return _unlinkedVariable?.documentationComment?.text;
+    }
+    return super.documentationComment;
+  }
+
+  @override
   void set final2(bool isFinal) {
     assert(_unlinkedVariable == null);
     super.final2 = isFinal;
@@ -4894,9 +5620,8 @@
   @override
   List<ElementAnnotation> get metadata {
     if (_unlinkedVariable != null) {
-      return _metadata ??= _unlinkedVariable.annotations
-          .map(enclosingUnit.resynthesizerContext.buildAnnotation)
-          .toList();
+      return _metadata ??=
+          _buildAnnotations(enclosingUnit, _unlinkedVariable.annotations);
     }
     return super.metadata;
   }
@@ -4983,8 +5708,8 @@
    * Initialize using the given serialized information.
    */
   ParameterElementImpl.forSerialized(
-      this._unlinkedParam, ElementImpl enclosingExecutable)
-      : super.forSerialized(enclosingExecutable);
+      this._unlinkedParam, ElementImpl enclosingElement)
+      : super.forSerialized(enclosingElement);
 
   /**
    * Creates a synthetic parameter with [name], [type] and [kind].
@@ -5090,12 +5815,8 @@
   @override
   List<ElementAnnotation> get metadata {
     if (_unlinkedParam != null) {
-      if (_unlinkedParam.annotations.isEmpty) {
-        return const <ElementAnnotation>[];
-      }
-      return _metadata ??= _unlinkedParam.annotations
-          .map(enclosingUnit.resynthesizerContext.buildAnnotation)
-          .toList();
+      return _metadata ??=
+          _buildAnnotations(enclosingUnit, _unlinkedParam.annotations);
     }
     return super.metadata;
   }
@@ -5243,15 +5964,34 @@
  */
 class PrefixElementImpl extends ElementImpl implements PrefixElement {
   /**
-   * Initialize a newly created method element to have the given [name] and
-   * [offset].
+   * The unlinked representation of the import in the summary.
    */
-  PrefixElementImpl(String name, int nameOffset) : super(name, nameOffset);
+  final UnlinkedImport _unlinkedImport;
+
+  /**
+   * Initialize a newly created method element to have the given [name] and
+   * [nameOffset].
+   */
+  PrefixElementImpl(String name, int nameOffset)
+      : _unlinkedImport = null,
+        super(name, nameOffset);
 
   /**
    * Initialize a newly created prefix element to have the given [name].
    */
-  PrefixElementImpl.forNode(Identifier name) : super.forNode(name);
+  PrefixElementImpl.forNode(Identifier name)
+      : _unlinkedImport = null,
+        super.forNode(name);
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  PrefixElementImpl.forSerialized(
+      this._unlinkedImport, LibraryElementImpl enclosingLibrary)
+      : super.forSerialized(enclosingLibrary);
+
+  @override
+  String get displayName => name;
 
   @override
   LibraryElement get enclosingElement =>
@@ -5267,6 +6007,26 @@
   ElementKind get kind => ElementKind.PREFIX;
 
   @override
+  String get name {
+    if (_unlinkedImport != null) {
+      if (_name == null) {
+        LibraryElementImpl library = enclosingElement as LibraryElementImpl;
+        int prefixId = _unlinkedImport.prefixReference;
+        return _name = library._unlinkedDefiningUnit.references[prefixId].name;
+      }
+    }
+    return super.name;
+  }
+
+  @override
+  int get nameOffset {
+    if (_unlinkedImport != null) {
+      return _unlinkedImport.prefixOffset;
+    }
+    return super.nameOffset;
+  }
+
+  @override
   accept(ElementVisitor visitor) => visitor.visitPrefixElement(this);
 
   @override
@@ -5350,6 +6110,11 @@
     return super.displayName;
   }
 
+  @override
+  TypeParameterizedElementMixin get enclosingTypeParameterContext {
+    return (enclosingElement as ElementImpl).typeParameterContext;
+  }
+
   /**
    * Set whether this accessor is a getter.
    */
@@ -5490,6 +6255,13 @@
    * Initialize a newly created element to have the given [name].
    */
   PropertyInducingElementImpl.forNode(Identifier name) : super.forNode(name);
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  PropertyInducingElementImpl.forSerialized(
+      UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
+      : super.forSerialized(unlinkedVariable, enclosingElement);
 }
 
 /**
@@ -5499,12 +6271,27 @@
   /**
    * Build [ElementAnnotationImpl] for the given [UnlinkedConst].
    */
-  ElementAnnotationImpl buildAnnotation(UnlinkedConst uc);
+  ElementAnnotationImpl buildAnnotation(ElementImpl context, UnlinkedConst uc);
 
   /**
    * Build [Expression] for the given [UnlinkedConst].
    */
-  Expression buildExpression(UnlinkedConst uc);
+  Expression buildExpression(ElementImpl context, UnlinkedConst uc);
+
+  /**
+   * Build explicit top-level property accessors.
+   */
+  UnitExplicitTopLevelAccessors buildTopLevelAccessors();
+
+  /**
+   * Build top-level functions.
+   */
+  List<FunctionElementImpl> buildTopLevelFunctions();
+
+  /**
+   * Build explicit top-level variables.
+   */
+  UnitExplicitTopLevelVariables buildTopLevelVariables();
 
   /**
    * Resolve an [EntityRef] into a type.  If the reference is
@@ -5523,21 +6310,72 @@
  */
 class ShowElementCombinatorImpl implements ShowElementCombinator {
   /**
+   * The unlinked representation of the combinator in the summary.
+   */
+  final UnlinkedCombinator _unlinkedCombinator;
+
+  /**
    * The names that are to be made visible in the importing library if they are
    * defined in the imported library.
    */
-  List<String> shownNames = StringUtilities.EMPTY_ARRAY;
+  List<String> _shownNames;
 
   /**
    * The offset of the character immediately following the last character of
    * this node.
    */
-  int end = -1;
+  int _end = -1;
 
   /**
    * The offset of the 'show' keyword of this element.
    */
-  int offset = 0;
+  int _offset = 0;
+
+  ShowElementCombinatorImpl() : _unlinkedCombinator = null;
+
+  /**
+   * Initialize using the given serialized information.
+   */
+  ShowElementCombinatorImpl.forSerialized(this._unlinkedCombinator);
+
+  @override
+  int get end {
+    if (_unlinkedCombinator != null) {
+      return _unlinkedCombinator.end;
+    }
+    return _end;
+  }
+
+  void set end(int end) {
+    assert(_unlinkedCombinator == null);
+    _end = end;
+  }
+
+  @override
+  int get offset {
+    if (_unlinkedCombinator != null) {
+      return _unlinkedCombinator.offset;
+    }
+    return _offset;
+  }
+
+  void set offset(int offset) {
+    assert(_unlinkedCombinator == null);
+    _offset = offset;
+  }
+
+  @override
+  List<String> get shownNames {
+    if (_unlinkedCombinator != null) {
+      _shownNames ??= _unlinkedCombinator.shows.toList(growable: false);
+    }
+    return _shownNames ?? const <String>[];
+  }
+
+  void set shownNames(List<String> shownNames) {
+    assert(_unlinkedCombinator == null);
+    _shownNames = shownNames;
+  }
 
   @override
   String toString() {
@@ -5571,6 +6409,13 @@
    */
   TopLevelVariableElementImpl.forNode(Identifier name) : super.forNode(name);
 
+  /**
+   * Initialize using the given serialized information.
+   */
+  TopLevelVariableElementImpl.forSerialized(
+      UnlinkedVariable unlinkedVariable, ElementImpl enclosingElement)
+      : super.forSerialized(unlinkedVariable, enclosingElement);
+
   @override
   bool get isStatic => true;
 
@@ -5710,9 +6555,8 @@
   @override
   List<ElementAnnotation> get metadata {
     if (_unlinkedTypeParam != null) {
-      return _metadata ??= _unlinkedTypeParam.annotations
-          .map(enclosingUnit.resynthesizerContext.buildAnnotation)
-          .toList();
+      return _metadata ??=
+          _buildAnnotations(enclosingUnit, _unlinkedTypeParam.annotations);
     }
     return super.metadata;
   }
@@ -5819,6 +6663,21 @@
   List<UnlinkedTypeParam> get unlinkedTypeParams;
 
   /**
+   * Determine the default value of type argument [i]. in most cases this will
+   * be `dynamic`, but sometimes it will be the bound of the ith type parameter.
+   */
+  DartType computeDefaultTypeArgument(int i) {
+    // If strong mode is off, or we can tell quickly from the summary that there
+    // is no bound, then the default type argument is `dynamic`; we don't have
+    // to call `typeParameters` to find that out.
+    if (!context.analysisOptions.strongMode ||
+        (unlinkedTypeParams != null && unlinkedTypeParams[i].bound == null)) {
+      return DynamicTypeImpl.instance;
+    }
+    return typeParameters[i].bound ?? DynamicTypeImpl.instance;
+  }
+
+  /**
    * Convert the given [index] into a type parameter type.
    */
   TypeParameterType getTypeParameterType(int index) {
@@ -5851,6 +6710,32 @@
 }
 
 /**
+ * Container with information about explicit top-level property accessors and
+ * corresponding implicit top-level variables.
+ */
+class UnitExplicitTopLevelAccessors {
+  final List<PropertyAccessorElementImpl> accessors =
+      <PropertyAccessorElementImpl>[];
+  final List<TopLevelVariableElementImpl> implicitVariables =
+      <TopLevelVariableElementImpl>[];
+}
+
+/**
+ * Container with information about explicit top-level variables and
+ * corresponding implicit top-level property accessors.
+ */
+class UnitExplicitTopLevelVariables {
+  final List<TopLevelVariableElementImpl> variables;
+  final List<PropertyAccessorElementImpl> implicitAccessors =
+      <PropertyAccessorElementImpl>[];
+
+  UnitExplicitTopLevelVariables(int numberOfVariables)
+      : variables = numberOfVariables != 0
+            ? new List<TopLevelVariableElementImpl>(numberOfVariables)
+            : const <TopLevelVariableElementImpl>[];
+}
+
+/**
  * A concrete implementation of a [UriReferencedElement].
  */
 abstract class UriReferencedElementImpl extends ElementImpl
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 42c8498..0ee0b97 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -860,17 +860,20 @@
 
   /**
    * Invokes [callback] for each parameter of [kind] with the parameter's [name]
-   * and [type] after any type parameters have been applied.
+   * and type after any type parameters have been applied.
    */
   void _forEachParameterType(
       ParameterKind kind, callback(String name, DartType type)) {
-    if (baseParameters.isEmpty) {
+    List<ParameterElement> parameters = baseParameters;
+    if (parameters.isEmpty) {
       return;
     }
 
     List<DartType> typeParameters =
         TypeParameterTypeImpl.getTypes(this.typeParameters);
-    for (ParameterElement parameter in baseParameters) {
+    int length = parameters.length;
+    for (int i = 0; i < length; i++) {
+      ParameterElement parameter = parameters[i];
       if (parameter.parameterKind == kind) {
         TypeImpl type = parameter.type ?? DynamicTypeImpl.instance;
         if (typeArguments.length != 0 &&
@@ -1184,13 +1187,12 @@
   InterfaceTypeImpl._(Element element, String name, this.prunedTypedefs)
       : super(element, name);
 
-
   @override
   List<PropertyAccessorElement> get accessors {
     if (_accessors == null) {
       List<PropertyAccessorElement> accessors = element.accessors;
       List<PropertyAccessorElement> members =
-      new List<PropertyAccessorElement>(accessors.length);
+          new List<PropertyAccessorElement>(accessors.length);
       for (int i = 0; i < accessors.length; i++) {
         members[i] = PropertyAccessorMember.from(accessors[i], this);
       }
@@ -1199,7 +1201,6 @@
     return _accessors;
   }
 
-
   @override
   List<ConstructorElement> get constructors {
     if (_constructors == null) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
index 6bdabc9..0e0229c 100644
--- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
@@ -525,7 +525,9 @@
     //
     // Interface elements
     //
-    for (InterfaceType interfaceType in interfaces) {
+    int interfaceLength = interfaces.length;
+    for (int i = 0; i < interfaceLength; i++) {
+      InterfaceType interfaceType = interfaces[i];
       ClassElement interfaceElement = interfaceType.element;
       if (interfaceElement != null) {
         if (!visitedInterfaces.contains(interfaceElement)) {
@@ -561,26 +563,27 @@
   }
 
   /**
-   * Given some [ClassElement], this method finds and returns the [ExecutableElement] of
-   * the passed name in the class element. Static members, members in super types and members not
-   * accessible from the current library are not considered.
-   *
-   * @param classElt the class element to query
-   * @param memberName the name of the member to lookup in the class
-   * @return the found [ExecutableElement], or `null` if no such member was found
+   * Given some [classElement], this method finds and returns the executable
+   * element with the given [memberName] in the class element. Static members,
+   * members in super types and members not accessible from the current library
+   * are not considered.
    */
   ExecutableElement _lookupMemberInClass(
-      ClassElement classElt, String memberName) {
-    List<MethodElement> methods = classElt.methods;
-    for (MethodElement method in methods) {
+      ClassElement classElement, String memberName) {
+    List<MethodElement> methods = classElement.methods;
+    int methodLength = methods.length;
+    for (int i = 0; i < methodLength; i++) {
+      MethodElement method = methods[i];
       if (memberName == method.name &&
           method.isAccessibleIn(_library) &&
           !method.isStatic) {
         return method;
       }
     }
-    List<PropertyAccessorElement> accessors = classElt.accessors;
-    for (PropertyAccessorElement accessor in accessors) {
+    List<PropertyAccessorElement> accessors = classElement.accessors;
+    int accessorLength = accessors.length;
+    for (int i = 0; i < accessorLength; i++) {
+      PropertyAccessorElement accessor = accessors[i];
       if (memberName == accessor.name &&
           accessor.isAccessibleIn(_library) &&
           !accessor.isStatic) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/scope.dart b/pkg/analyzer/lib/src/dart/resolver/scope.dart
index 0b17d71..e90ba86 100644
--- a/pkg/analyzer/lib/src/dart/resolver/scope.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/scope.dart
@@ -57,11 +57,15 @@
    * Define the instance members defined by the given [classElement].
    */
   void _defineMembers(ClassElement classElement) {
-    for (PropertyAccessorElement accessor in classElement.accessors) {
-      define(accessor);
+    List<PropertyAccessorElement> accessors = classElement.accessors;
+    int accessorLength = accessors.length;
+    for (int i = 0; i < accessorLength; i++) {
+      define(accessors[i]);
     }
-    for (MethodElement method in classElement.methods) {
-      define(method);
+    List<MethodElement> methods = classElement.methods;
+    int methodLength = methods.length;
+    for (int i = 0; i < methodLength; i++) {
+      define(methods[i]);
     }
   }
 }
@@ -174,7 +178,10 @@
     }
     _parametersDefined = true;
     Scope parameterScope = enclosingScope;
-    for (ParameterElement parameter in _functionElement.parameters) {
+    List<ParameterElement> parameters = _functionElement.parameters;
+    int length = parameters.length;
+    for (int i = 0; i < length; i++) {
+      ParameterElement parameter = parameters[i];
       if (!parameter.isInitializingFormal) {
         parameterScope.define(parameter);
       }
@@ -186,8 +193,10 @@
    */
   void _defineTypeParameters() {
     Scope typeParameterScope = enclosingScope.enclosingScope;
-    for (TypeParameterElement typeParameter
-        in _functionElement.typeParameters) {
+    List<TypeParameterElement> typeParameters = _functionElement.typeParameters;
+    int length = typeParameters.length;
+    for (int i = 0; i < length; i++) {
+      TypeParameterElement typeParameter = typeParameters[i];
       typeParameterScope.define(typeParameter);
     }
   }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 972043a..6d41c4fb 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1953,6 +1953,12 @@
   List<AnalysisTarget> get explicitTargets;
 
   /**
+   * Return the [StreamController] reporting [InvalidatedResult]s for everything
+   * in this context's cache.
+   */
+  ReentrantSynchronousStream<InvalidatedResult> get onResultInvalidated;
+
+  /**
    * Return a list containing all of the sources that have been marked as
    * priority sources. Clients must not modify the returned list.
    */
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index c21e7e6..9fb06c5 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -21,6 +21,7 @@
 import 'package:analyzer/src/task/model.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:source_span/source_span.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 
 /**
  * The descriptor used to associate error processors with analysis contexts in
@@ -893,7 +894,7 @@
    * 1: the number of type parameters that were declared
    * 2: the number of type arguments provided
    *
-   * See [CompileTimeErrorCode.NEW_WITH_INVALID_TYPE_PARAMETERS], and
+   * See [StaticWarningCode.NEW_WITH_INVALID_TYPE_PARAMETERS], and
    * [StaticTypeWarningCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS].
    */
   static const CompileTimeErrorCode CONST_WITH_INVALID_TYPE_PARAMETERS =
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index d201e96..78b7cf3 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -3813,7 +3813,9 @@
         }
         // Check methods.
         List<MethodElement> methodElements = superclassElement.methods;
-        for (MethodElement methodElement in methodElements) {
+        int length = methodElements.length;
+        for (int i = 0; i < length; i++) {
+          MethodElement methodElement = methodElements[i];
           // We need the same name.
           if (methodElement.name != executableElementName) {
             continue;
diff --git a/pkg/analyzer/lib/src/generated/java_core.dart b/pkg/analyzer/lib/src/generated/java_core.dart
index 752475d..bedb35f 100644
--- a/pkg/analyzer/lib/src/generated/java_core.dart
+++ b/pkg/analyzer/lib/src/generated/java_core.dart
@@ -21,7 +21,7 @@
 }
 
 /**
- * Inserts the given [args] into [pattern].
+ * Inserts the given [arguments] into [pattern].
  *
  *     format('Hello, {0}!', ['John']) = 'Hello, John!'
  *     format('{0} are you {1}ing?', ['How', 'do']) = 'How are you doing?'
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 7f9657f..cf2ced8 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -3470,6 +3470,11 @@
    */
   bool _enclosingBlockContainsBreak = false;
 
+  /**
+   * Add node when a labelled `break` is encountered.
+   */
+  Set<AstNode> _enclosingBlockBreaksLabel = new Set<AstNode>();
+
   @override
   bool visitArgumentList(ArgumentList node) =>
       _visitExpressions(node.arguments);
@@ -3545,6 +3550,9 @@
   @override
   bool visitBreakStatement(BreakStatement node) {
     _enclosingBlockContainsBreak = true;
+    if (node.label != null) {
+      _enclosingBlockBreaksLabel.add(node.target);
+    }
     return false;
   }
 
@@ -3634,13 +3642,13 @@
       if (_visitExpressions(node.updaters)) {
         return true;
       }
+      bool blockReturns = _nodeExits(node.body);
       // TODO(jwren) Do we want to take all constant expressions into account?
       // If for(; true; ) (or for(;;)), and the body doesn't return or the body
       // doesn't have a break, then return true.
       bool implicitOrExplictTrue = conditionExpression == null ||
           (conditionExpression is BooleanLiteral && conditionExpression.value);
       if (implicitOrExplictTrue) {
-        bool blockReturns = _nodeExits(node.body);
         if (blockReturns || !_enclosingBlockContainsBreak) {
           return true;
         }
@@ -3680,17 +3688,19 @@
     // TODO(jwren) Do we want to take all constant expressions into account?
     if (conditionExpression is BooleanLiteral) {
       if (conditionExpression.value) {
-        // if(true) ...
+        // if (true) ...
         return _nodeExits(thenStatement);
       } else if (elseStatement != null) {
         // if (false) ...
         return _nodeExits(elseStatement);
       }
     }
+    bool thenExits = _nodeExits(thenStatement);
+    bool elseExits = _nodeExits(elseStatement);
     if (thenStatement == null || elseStatement == null) {
       return false;
     }
-    return _nodeExits(thenStatement) && _nodeExits(elseStatement);
+    return thenExits && elseExits;
   }
 
   @override
@@ -3716,8 +3726,16 @@
   bool visitLabel(Label node) => false;
 
   @override
-  bool visitLabeledStatement(LabeledStatement node) =>
-      node.statement.accept(this);
+  bool visitLabeledStatement(LabeledStatement node) {
+    try {
+      bool statementExits = _nodeExits(node.statement);
+      bool neverBrokeFromLabel =
+          !_enclosingBlockBreaksLabel.contains(node.statement);
+      return statementExits && neverBrokeFromLabel;
+    } finally {
+      _enclosingBlockBreaksLabel.remove(node.statement);
+    }
+  }
 
   @override
   bool visitLiteral(Literal node) => false;
@@ -3871,11 +3889,11 @@
       if (conditionExpression.accept(this)) {
         return true;
       }
+      bool blockReturns = node.body.accept(this);
       // TODO(jwren) Do we want to take all constant expressions into account?
       if (conditionExpression is BooleanLiteral) {
         // If while(true), and the body doesn't return or the body doesn't have
         // a break, then return true.
-        bool blockReturns = node.body.accept(this);
         if (conditionExpression.value &&
             (blockReturns || !_enclosingBlockContainsBreak)) {
           return true;
@@ -3910,7 +3928,7 @@
   }
 
   bool _visitStatements(NodeList<Statement> statements) {
-    for (int i = statements.length - 1; i >= 0; i--) {
+    for (int i = 0; i < statements.length; i++) {
       if (statements[i].accept(this)) {
         return true;
       }
@@ -6301,8 +6319,11 @@
     }
     // Clone the ASTs for default formal parameters, so that we can use them
     // during constant evaluation.
-    (element as ConstVariableElement).constantInitializer =
-        new ConstantAstCloner().cloneNode(node.defaultValue);
+    if (!LibraryElementImpl.hasResolutionCapability(
+        definingLibrary, LibraryResolutionCapability.constantExpressions)) {
+      (element as ConstVariableElement).constantInitializer =
+          new ConstantAstCloner().cloneNode(node.defaultValue);
+    }
     return null;
   }
 
@@ -7189,7 +7210,10 @@
    * Try to infer types of parameters of the [FunctionExpression] arguments.
    */
   void _inferFunctionExpressionsParametersTypes(ArgumentList argumentList) {
-    for (Expression argument in argumentList.arguments) {
+    NodeList<Expression> arguments = argumentList.arguments;
+    int length = arguments.length;
+    for (int i = 0; i < length; i++) {
+      Expression argument = arguments[i];
       ParameterElement parameter = argument.propagatedParameterElement;
       if (parameter == null) {
         parameter = argument.staticParameterElement;
@@ -9190,15 +9214,20 @@
       for (TypeParameter typeParameter in typeParameters.typeParameters) {
         TypeName bound = typeParameter.bound;
         if (bound != null) {
-          libraryScope ??= new LibraryScope(library, errorListener);
-          typeParametersScope ??= createTypeParametersScope();
-          typeNameResolver ??= new TypeNameResolver(new TypeSystemImpl(),
-              typeProvider, library, source, errorListener);
-          typeNameResolver.nameScope = typeParametersScope;
-          _resolveTypeName(bound);
           Element typeParameterElement = typeParameter.name.staticElement;
           if (typeParameterElement is TypeParameterElementImpl) {
-            typeParameterElement.bound = bound.type;
+            if (LibraryElementImpl.hasResolutionCapability(
+                library, LibraryResolutionCapability.resolvedTypeNames)) {
+              bound.type = typeParameterElement.bound;
+            } else {
+              libraryScope ??= new LibraryScope(library, errorListener);
+              typeParametersScope ??= createTypeParametersScope();
+              typeNameResolver ??= new TypeNameResolver(new TypeSystemImpl(),
+                  typeProvider, library, source, errorListener);
+              typeNameResolver.nameScope = typeParametersScope;
+              _resolveTypeName(bound);
+              typeParameterElement.bound = bound.type;
+            }
           }
         }
       }
@@ -9930,7 +9959,10 @@
     // types of field formal parameters can be correctly resolved.
     //
     List<ClassMember> nonFields = new List<ClassMember>();
-    for (ClassMember member in node.members) {
+    NodeList<ClassMember> members = node.members;
+    int length = members.length;
+    for (int i = 0; i < length; i++) {
+      ClassMember member = members[i];
       if (member is ConstructorDeclaration) {
         nonFields.add(member);
       } else {
diff --git a/pkg/analyzer/lib/src/generated/sdk.dart b/pkg/analyzer/lib/src/generated/sdk.dart
index 8e1abb2..6f50b44 100644
--- a/pkg/analyzer/lib/src/generated/sdk.dart
+++ b/pkg/analyzer/lib/src/generated/sdk.dart
@@ -372,10 +372,6 @@
    */
   static int VM_PLATFORM = 2;
 
-  /**
-   * The short name of the library. This is the name used after 'dart:' in a
-   * URI.
-   */
   @override
   final String shortName;
 
diff --git a/pkg/analyzer/lib/src/generated/utilities_dart.dart b/pkg/analyzer/lib/src/generated/utilities_dart.dart
index 2e4abf1..1409cd5 100644
--- a/pkg/analyzer/lib/src/generated/utilities_dart.dart
+++ b/pkg/analyzer/lib/src/generated/utilities_dart.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
 
 /**
  * Resolve the [containedUri] against [baseUri] using Dart rules.
@@ -33,12 +34,12 @@
       if (scheme == DartUriResolver.DART_SCHEME && part.indexOf('/') < 0) {
         part = "$part/$part.dart";
       }
-      baseUri = parseUriWithException("$scheme:/$part");
+      baseUri = FastUri.parse("$scheme:/$part");
     }
     Uri result = baseUri.resolveUri(containedUri);
     if (isOpaque) {
       result =
-          parseUriWithException("${result.scheme}:${result.path.substring(1)}");
+          FastUri.parse("${result.scheme}:${result.path.substring(1)}");
     }
     return result;
   } catch (exception, stackTrace) {
diff --git a/pkg/analyzer/lib/src/summary/flat_buffers.dart b/pkg/analyzer/lib/src/summary/flat_buffers.dart
index d573693..81bd2db 100644
--- a/pkg/analyzer/lib/src/summary/flat_buffers.dart
+++ b/pkg/analyzer/lib/src/summary/flat_buffers.dart
@@ -21,7 +21,8 @@
   int get size => 4;
 
   @override
-  List<bool> read(BufferPointer bp) => new _FbBoolList(bp.derefObject());
+  List<bool> read(BufferContext bc, int offset) =>
+      new _FbBoolList(bc, bc.derefObject(offset));
 }
 
 /**
@@ -34,51 +35,45 @@
   int get size => 1;
 
   @override
-  bool read(BufferPointer bp) => bp._getInt8() != 0;
+  bool read(BufferContext bc, int offset) => bc._getInt8(offset) != 0;
 }
 
 /**
- * A pointer to some data.
+ * Buffer with data and some context about it.
  */
-class BufferPointer {
+class BufferContext {
   final ByteData _buffer;
-  final int _offset;
 
-  factory BufferPointer.fromBytes(List<int> byteList, [int offset = 0]) {
+  factory BufferContext.fromBytes(List<int> byteList) {
     Uint8List uint8List = _asUint8List(byteList);
-    ByteData buf = new ByteData.view(uint8List.buffer);
-    return new BufferPointer._(buf, uint8List.offsetInBytes + offset);
+    ByteData buf = new ByteData.view(uint8List.buffer, uint8List.offsetInBytes);
+    return new BufferContext._(buf);
   }
 
-  BufferPointer._(this._buffer, this._offset);
+  BufferContext._(this._buffer);
 
-  BufferPointer derefObject() {
-    int uOffset = _getUint32();
-    return _advance(uOffset);
+  int derefObject(int offset) {
+    return offset + _getUint32(offset);
   }
 
-  @override
-  String toString() => _offset.toString();
+  Uint8List _asUint8LIst(int offset, int length) =>
+      _buffer.buffer.asUint8List(_buffer.offsetInBytes + offset, length);
 
-  BufferPointer _advance(int delta) {
-    return new BufferPointer._(_buffer, _offset + delta);
-  }
+  double _getFloat64(int offset) =>
+      _buffer.getFloat64(offset, Endianness.LITTLE_ENDIAN);
 
-  double _getFloat64([int delta = 0]) =>
-      _buffer.getFloat64(_offset + delta, Endianness.LITTLE_ENDIAN);
+  int _getInt32(int offset) =>
+      _buffer.getInt32(offset, Endianness.LITTLE_ENDIAN);
 
-  int _getInt32([int delta = 0]) =>
-      _buffer.getInt32(_offset + delta, Endianness.LITTLE_ENDIAN);
+  int _getInt8(int offset) => _buffer.getInt8(offset);
 
-  int _getInt8([int delta = 0]) => _buffer.getInt8(_offset + delta);
+  int _getUint16(int offset) =>
+      _buffer.getUint16(offset, Endianness.LITTLE_ENDIAN);
 
-  int _getUint16([int delta = 0]) =>
-      _buffer.getUint16(_offset + delta, Endianness.LITTLE_ENDIAN);
+  int _getUint32(int offset) =>
+      _buffer.getUint32(offset, Endianness.LITTLE_ENDIAN);
 
-  int _getUint32([int delta = 0]) =>
-      _buffer.getUint32(_offset + delta, Endianness.LITTLE_ENDIAN);
-
-  int _getUint8([int delta = 0]) => _buffer.getUint8(_offset + delta);
+  int _getUint8(int offset) => _buffer.getUint8(offset);
 
   /**
    * If the [byteList] is already a [Uint8List] return it.
@@ -563,7 +558,8 @@
   int get size => 4;
 
   @override
-  List<double> read(BufferPointer bp) => new _FbFloat64List(bp.derefObject());
+  List<double> read(BufferContext bc, int offset) =>
+      new _FbFloat64List(bc, bc.derefObject(offset));
 }
 
 /**
@@ -576,7 +572,7 @@
   int get size => 4;
 
   @override
-  int read(BufferPointer bp) => bp._getInt32();
+  int read(BufferContext bc, int offset) => bc._getInt32(offset);
 }
 
 /**
@@ -589,7 +585,7 @@
   int get size => 1;
 
   @override
-  int read(BufferPointer bp) => bp._getInt8();
+  int read(BufferContext bc, int offset) => bc._getInt8(offset);
 }
 
 /**
@@ -606,8 +602,8 @@
   int get size => 4;
 
   @override
-  List<E> read(BufferPointer bp) =>
-      new _FbGenericList<E>(_elementReader, bp.derefObject());
+  List<E> read(BufferContext bc, int offset) =>
+      new _FbGenericList<E>(_elementReader, bc, bc.derefObject(offset));
 }
 
 /**
@@ -620,7 +616,7 @@
 }
 
 /**
- * Object that can read a value at a [BufferPointer].
+ * Object that can read a value at a [BufferContext].
  */
 abstract class Reader<T> {
   const Reader();
@@ -631,23 +627,23 @@
   int get size;
 
   /**
-   * Read the value at the given pointer.
+   * Read the value at the given [offset] in [bc].
    */
-  T read(BufferPointer bp);
+  T read(BufferContext bc, int offset);
 
   /**
    * Read the value of the given [field] in the given [object].
    */
-  T vTableGet(BufferPointer object, int field, [T defaultValue]) {
-    int vTableSOffset = object._getInt32();
-    BufferPointer vTable = object._advance(-vTableSOffset);
-    int vTableSize = vTable._getUint16();
+  T vTableGet(BufferContext object, int offset, int field, [T defaultValue]) {
+    int vTableSOffset = object._getInt32(offset);
+    int vTableOffset = offset - vTableSOffset;
+    int vTableSize = object._getUint16(vTableOffset);
     int vTableFieldOffset = (1 + 1 + field) * 2;
     if (vTableFieldOffset < vTableSize) {
-      int fieldOffsetInObject = vTable._getUint16(vTableFieldOffset);
+      int fieldOffsetInObject =
+          object._getUint16(vTableOffset + vTableFieldOffset);
       if (fieldOffsetInObject != 0) {
-        BufferPointer fieldPointer = object._advance(fieldOffsetInObject);
-        return read(fieldPointer);
+        return read(object, offset + fieldOffsetInObject);
       }
     }
     return defaultValue;
@@ -664,11 +660,24 @@
   int get size => 4;
 
   @override
-  String read(BufferPointer ref) {
-    BufferPointer object = ref.derefObject();
-    int length = object._getUint32();
-    return UTF8
-        .decode(ref._buffer.buffer.asUint8List(object._offset + 4, length));
+  String read(BufferContext bc, int offset) {
+    int strOffset = bc.derefObject(offset);
+    int length = bc._getUint32(strOffset);
+    Uint8List bytes = bc._asUint8LIst(strOffset + 4, length);
+    if (_isLatin(bytes)) {
+      return new String.fromCharCodes(bytes);
+    }
+    return UTF8.decode(bytes);
+  }
+
+  static bool _isLatin(Uint8List bytes) {
+    int length = bytes.length;
+    for (int i = 0; i < length; i++) {
+      if (bytes[i] > 127) {
+        return false;
+      }
+    }
+    return true;
   }
 }
 
@@ -682,14 +691,14 @@
   int get size => 4;
 
   /**
-   * Return the object at [bp].
+   * Return the object at [offset].
    */
-  T createObject(BufferPointer bp);
+  T createObject(BufferContext bc, int offset);
 
   @override
-  T read(BufferPointer bp) {
-    bp = bp.derefObject();
-    return createObject(bp);
+  T read(BufferContext bp, int offset) {
+    int objectOffset = bp.derefObject(offset);
+    return createObject(bp, objectOffset);
   }
 }
 
@@ -705,7 +714,8 @@
   int get size => 4;
 
   @override
-  List<int> read(BufferPointer bp) => new _FbUint32List(bp.derefObject());
+  List<int> read(BufferContext bc, int offset) =>
+      new _FbUint32List(bc, bc.derefObject(offset));
 }
 
 /**
@@ -718,7 +728,7 @@
   int get size => 4;
 
   @override
-  int read(BufferPointer bp) => bp._getUint32();
+  int read(BufferContext bc, int offset) => bc._getUint32(offset);
 }
 
 /**
@@ -733,7 +743,8 @@
   int get size => 4;
 
   @override
-  List<int> read(BufferPointer bp) => new _FbUint8List(bp.derefObject());
+  List<int> read(BufferContext bc, int offset) =>
+      new _FbUint8List(bc, bc.derefObject(offset));
 }
 
 /**
@@ -746,22 +757,23 @@
   int get size => 1;
 
   @override
-  int read(BufferPointer bp) => bp._getUint8();
+  int read(BufferContext bc, int offset) => bc._getUint8(offset);
 }
 
 /**
  * List of booleans backed by 8-bit unsigned integers.
  */
 class _FbBoolList extends Object with ListMixin<bool> implements List<bool> {
-  final BufferPointer bp;
+  final BufferContext bc;
+  final int offset;
   int _length;
 
-  _FbBoolList(this.bp);
+  _FbBoolList(this.bc, this.offset);
 
   @override
   int get length {
     if (_length == null) {
-      int byteLength = bp._getUint32();
+      int byteLength = bc._getUint32(offset);
       _length = (byteLength - 1) * 8 - _getByte(byteLength - 1);
     }
     return _length;
@@ -782,18 +794,18 @@
   void operator []=(int i, bool e) =>
       throw new StateError('Attempt to modify immutable list');
 
-  int _getByte(int index) => bp._getUint8(4 + index);
+  int _getByte(int index) => bc._getUint8(offset + 4 + index);
 }
 
 /**
  * The list backed by 64-bit values - Uint64 length and Float64.
  */
 class _FbFloat64List extends _FbList<double> {
-  _FbFloat64List(BufferPointer bp) : super(bp);
+  _FbFloat64List(BufferContext bc, int offset) : super(bc, offset);
 
   @override
   double operator [](int i) {
-    return bp._getFloat64(8 + 8 * i);
+    return bc._getFloat64(offset + 8 + 8 * i);
   }
 }
 
@@ -805,15 +817,15 @@
 
   List<E> _items;
 
-  _FbGenericList(this.elementReader, BufferPointer bp) : super(bp);
+  _FbGenericList(this.elementReader, BufferContext bp, int offset)
+      : super(bp, offset);
 
   @override
   E operator [](int i) {
     _items ??= new List<E>(length);
     E item = _items[i];
     if (item == null) {
-      BufferPointer ref = bp._advance(4 + elementReader.size * i);
-      item = elementReader.read(ref);
+      item = elementReader.read(bc, offset + 4 + elementReader.size * i);
       _items[i] = item;
     }
     return item;
@@ -824,14 +836,15 @@
  * The base class for immutable lists read from flat buffers.
  */
 abstract class _FbList<E> extends Object with ListMixin<E> implements List<E> {
-  final BufferPointer bp;
+  final BufferContext bc;
+  final int offset;
   int _length;
 
-  _FbList(this.bp);
+  _FbList(this.bc, this.offset);
 
   @override
   int get length {
-    _length ??= bp._getUint32();
+    _length ??= bc._getUint32(offset);
     return _length;
   }
 
@@ -848,11 +861,11 @@
  * List backed by 32-bit unsigned integers.
  */
 class _FbUint32List extends _FbList<int> {
-  _FbUint32List(BufferPointer bp) : super(bp);
+  _FbUint32List(BufferContext bc, int offset) : super(bc, offset);
 
   @override
   int operator [](int i) {
-    return bp._getUint32(4 + 4 * i);
+    return bc._getUint32(offset + 4 + 4 * i);
   }
 }
 
@@ -860,11 +873,11 @@
  * List backed by 8-bit unsigned integers.
  */
 class _FbUint8List extends _FbList<int> {
-  _FbUint8List(BufferPointer bp) : super(bp);
+  _FbUint8List(BufferContext bc, int offset) : super(bc, offset);
 
   @override
   int operator [](int i) {
-    return bp._getUint8(4 + i);
+    return bc._getUint8(offset + 4 + i);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 9b80057..7a60450 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -18,8 +18,8 @@
   int get size => 1;
 
   @override
-  idl.CacheSourceKind read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.CacheSourceKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.CacheSourceKind.values.length ? idl.CacheSourceKind.values[index] : idl.CacheSourceKind.library;
   }
 }
@@ -31,8 +31,8 @@
   int get size => 1;
 
   @override
-  idl.IndexNameKind read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.IndexNameKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.IndexNameKind.values.length ? idl.IndexNameKind.values[index] : idl.IndexNameKind.topLevel;
   }
 }
@@ -44,8 +44,8 @@
   int get size => 1;
 
   @override
-  idl.IndexRelationKind read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.IndexRelationKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.IndexRelationKind.values.length ? idl.IndexRelationKind.values[index] : idl.IndexRelationKind.IS_ANCESTOR_OF;
   }
 }
@@ -57,8 +57,8 @@
   int get size => 1;
 
   @override
-  idl.IndexSyntheticElementKind read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.IndexSyntheticElementKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.IndexSyntheticElementKind.values.length ? idl.IndexSyntheticElementKind.values[index] : idl.IndexSyntheticElementKind.notSynthetic;
   }
 }
@@ -70,8 +70,8 @@
   int get size => 1;
 
   @override
-  idl.ReferenceKind read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.ReferenceKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.ReferenceKind.values.length ? idl.ReferenceKind.values[index] : idl.ReferenceKind.classOrEnum;
   }
 }
@@ -83,8 +83,8 @@
   int get size => 1;
 
   @override
-  idl.UnlinkedConstOperation read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.UnlinkedConstOperation read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.UnlinkedConstOperation.values.length ? idl.UnlinkedConstOperation.values[index] : idl.UnlinkedConstOperation.pushInt;
   }
 }
@@ -96,8 +96,8 @@
   int get size => 1;
 
   @override
-  idl.UnlinkedConstructorInitializerKind read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.UnlinkedConstructorInitializerKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.UnlinkedConstructorInitializerKind.values.length ? idl.UnlinkedConstructorInitializerKind.values[index] : idl.UnlinkedConstructorInitializerKind.field;
   }
 }
@@ -109,8 +109,8 @@
   int get size => 1;
 
   @override
-  idl.UnlinkedExecutableKind read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.UnlinkedExecutableKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.UnlinkedExecutableKind.values.length ? idl.UnlinkedExecutableKind.values[index] : idl.UnlinkedExecutableKind.functionOrMethod;
   }
 }
@@ -122,8 +122,8 @@
   int get size => 1;
 
   @override
-  idl.UnlinkedExprAssignOperator read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.UnlinkedExprAssignOperator read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.UnlinkedExprAssignOperator.values.length ? idl.UnlinkedExprAssignOperator.values[index] : idl.UnlinkedExprAssignOperator.assign;
   }
 }
@@ -135,8 +135,8 @@
   int get size => 1;
 
   @override
-  idl.UnlinkedParamKind read(fb.BufferPointer bp) {
-    int index = const fb.Uint8Reader().read(bp);
+  idl.UnlinkedParamKind read(fb.BufferContext bc, int offset) {
+    int index = const fb.Uint8Reader().read(bc, offset);
     return index < idl.UnlinkedParamKind.values.length ? idl.UnlinkedParamKind.values[index] : idl.UnlinkedParamKind.required;
   }
 }
@@ -246,21 +246,22 @@
 }
 
 idl.CacheSourceContent readCacheSourceContent(List<int> buffer) {
-  fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
-  return const _CacheSourceContentReader().read(rootRef);
+  fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
+  return const _CacheSourceContentReader().read(rootRef, 0);
 }
 
 class _CacheSourceContentReader extends fb.TableReader<_CacheSourceContentImpl> {
   const _CacheSourceContentReader();
 
   @override
-  _CacheSourceContentImpl createObject(fb.BufferPointer bp) => new _CacheSourceContentImpl(bp);
+  _CacheSourceContentImpl createObject(fb.BufferContext bc, int offset) => new _CacheSourceContentImpl(bc, offset);
 }
 
 class _CacheSourceContentImpl extends Object with _CacheSourceContentMixin implements idl.CacheSourceContent {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _CacheSourceContentImpl(this._bp);
+  _CacheSourceContentImpl(this._bc, this._bcOffset);
 
   List<String> _exportedUris;
   List<String> _importedUris;
@@ -269,25 +270,25 @@
 
   @override
   List<String> get exportedUris {
-    _exportedUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 2, const <String>[]);
+    _exportedUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 2, const <String>[]);
     return _exportedUris;
   }
 
   @override
   List<String> get importedUris {
-    _importedUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    _importedUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 1, const <String>[]);
     return _importedUris;
   }
 
   @override
   idl.CacheSourceKind get kind {
-    _kind ??= const _CacheSourceKindReader().vTableGet(_bp, 0, idl.CacheSourceKind.library);
+    _kind ??= const _CacheSourceKindReader().vTableGet(_bc, _bcOffset, 0, idl.CacheSourceKind.library);
     return _kind;
   }
 
   @override
   List<String> get partUris {
-    _partUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 3, const <String>[]);
+    _partUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 3, const <String>[]);
     return _partUris;
   }
 }
@@ -373,26 +374,27 @@
   const _CodeRangeReader();
 
   @override
-  _CodeRangeImpl createObject(fb.BufferPointer bp) => new _CodeRangeImpl(bp);
+  _CodeRangeImpl createObject(fb.BufferContext bc, int offset) => new _CodeRangeImpl(bc, offset);
 }
 
 class _CodeRangeImpl extends Object with _CodeRangeMixin implements idl.CodeRange {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _CodeRangeImpl(this._bp);
+  _CodeRangeImpl(this._bc, this._bcOffset);
 
   int _length;
   int _offset;
 
   @override
   int get length {
-    _length ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _length ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _length;
   }
 
   @override
   int get offset {
-    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _offset;
   }
 }
@@ -622,13 +624,14 @@
   const _EntityRefReader();
 
   @override
-  _EntityRefImpl createObject(fb.BufferPointer bp) => new _EntityRefImpl(bp);
+  _EntityRefImpl createObject(fb.BufferContext bc, int offset) => new _EntityRefImpl(bc, offset);
 }
 
 class _EntityRefImpl extends Object with _EntityRefMixin implements idl.EntityRef {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _EntityRefImpl(this._bp);
+  _EntityRefImpl(this._bc, this._bcOffset);
 
   List<int> _implicitFunctionTypeIndices;
   int _paramReference;
@@ -640,43 +643,43 @@
 
   @override
   List<int> get implicitFunctionTypeIndices {
-    _implicitFunctionTypeIndices ??= const fb.Uint32ListReader().vTableGet(_bp, 4, const <int>[]);
+    _implicitFunctionTypeIndices ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 4, const <int>[]);
     return _implicitFunctionTypeIndices;
   }
 
   @override
   int get paramReference {
-    _paramReference ??= const fb.Uint32Reader().vTableGet(_bp, 3, 0);
+    _paramReference ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
     return _paramReference;
   }
 
   @override
   int get reference {
-    _reference ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _reference ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _reference;
   }
 
   @override
   int get slot {
-    _slot ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _slot ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _slot;
   }
 
   @override
   List<idl.UnlinkedParam> get syntheticParams {
-    _syntheticParams ??= const fb.ListReader<idl.UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 6, const <idl.UnlinkedParam>[]);
+    _syntheticParams ??= const fb.ListReader<idl.UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bc, _bcOffset, 6, const <idl.UnlinkedParam>[]);
     return _syntheticParams;
   }
 
   @override
   idl.EntityRef get syntheticReturnType {
-    _syntheticReturnType ??= const _EntityRefReader().vTableGet(_bp, 5, null);
+    _syntheticReturnType ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 5, null);
     return _syntheticReturnType;
   }
 
   @override
   List<idl.EntityRef> get typeArguments {
-    _typeArguments ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bp, 1, const <idl.EntityRef>[]);
+    _typeArguments ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bc, _bcOffset, 1, const <idl.EntityRef>[]);
     return _typeArguments;
   }
 }
@@ -779,26 +782,27 @@
   const _LinkedDependencyReader();
 
   @override
-  _LinkedDependencyImpl createObject(fb.BufferPointer bp) => new _LinkedDependencyImpl(bp);
+  _LinkedDependencyImpl createObject(fb.BufferContext bc, int offset) => new _LinkedDependencyImpl(bc, offset);
 }
 
 class _LinkedDependencyImpl extends Object with _LinkedDependencyMixin implements idl.LinkedDependency {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _LinkedDependencyImpl(this._bp);
+  _LinkedDependencyImpl(this._bc, this._bcOffset);
 
   List<String> _parts;
   String _uri;
 
   @override
   List<String> get parts {
-    _parts ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    _parts ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 1, const <String>[]);
     return _parts;
   }
 
   @override
   String get uri {
-    _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _uri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _uri;
   }
 }
@@ -921,13 +925,14 @@
   const _LinkedExportNameReader();
 
   @override
-  _LinkedExportNameImpl createObject(fb.BufferPointer bp) => new _LinkedExportNameImpl(bp);
+  _LinkedExportNameImpl createObject(fb.BufferContext bc, int offset) => new _LinkedExportNameImpl(bc, offset);
 }
 
 class _LinkedExportNameImpl extends Object with _LinkedExportNameMixin implements idl.LinkedExportName {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _LinkedExportNameImpl(this._bp);
+  _LinkedExportNameImpl(this._bc, this._bcOffset);
 
   int _dependency;
   idl.ReferenceKind _kind;
@@ -936,25 +941,25 @@
 
   @override
   int get dependency {
-    _dependency ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _dependency ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _dependency;
   }
 
   @override
   idl.ReferenceKind get kind {
-    _kind ??= const _ReferenceKindReader().vTableGet(_bp, 3, idl.ReferenceKind.classOrEnum);
+    _kind ??= const _ReferenceKindReader().vTableGet(_bc, _bcOffset, 3, idl.ReferenceKind.classOrEnum);
     return _kind;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 1, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
     return _name;
   }
 
   @override
   int get unit {
-    _unit ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _unit ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _unit;
   }
 }
@@ -1171,21 +1176,22 @@
 }
 
 idl.LinkedLibrary readLinkedLibrary(List<int> buffer) {
-  fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
-  return const _LinkedLibraryReader().read(rootRef);
+  fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
+  return const _LinkedLibraryReader().read(rootRef, 0);
 }
 
 class _LinkedLibraryReader extends fb.TableReader<_LinkedLibraryImpl> {
   const _LinkedLibraryReader();
 
   @override
-  _LinkedLibraryImpl createObject(fb.BufferPointer bp) => new _LinkedLibraryImpl(bp);
+  _LinkedLibraryImpl createObject(fb.BufferContext bc, int offset) => new _LinkedLibraryImpl(bc, offset);
 }
 
 class _LinkedLibraryImpl extends Object with _LinkedLibraryMixin implements idl.LinkedLibrary {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _LinkedLibraryImpl(this._bp);
+  _LinkedLibraryImpl(this._bc, this._bcOffset);
 
   List<idl.LinkedDependency> _dependencies;
   List<int> _exportDependencies;
@@ -1197,43 +1203,43 @@
 
   @override
   List<idl.LinkedDependency> get dependencies {
-    _dependencies ??= const fb.ListReader<idl.LinkedDependency>(const _LinkedDependencyReader()).vTableGet(_bp, 0, const <idl.LinkedDependency>[]);
+    _dependencies ??= const fb.ListReader<idl.LinkedDependency>(const _LinkedDependencyReader()).vTableGet(_bc, _bcOffset, 0, const <idl.LinkedDependency>[]);
     return _dependencies;
   }
 
   @override
   List<int> get exportDependencies {
-    _exportDependencies ??= const fb.Uint32ListReader().vTableGet(_bp, 6, const <int>[]);
+    _exportDependencies ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 6, const <int>[]);
     return _exportDependencies;
   }
 
   @override
   List<idl.LinkedExportName> get exportNames {
-    _exportNames ??= const fb.ListReader<idl.LinkedExportName>(const _LinkedExportNameReader()).vTableGet(_bp, 4, const <idl.LinkedExportName>[]);
+    _exportNames ??= const fb.ListReader<idl.LinkedExportName>(const _LinkedExportNameReader()).vTableGet(_bc, _bcOffset, 4, const <idl.LinkedExportName>[]);
     return _exportNames;
   }
 
   @override
   bool get fallbackMode {
-    _fallbackMode ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    _fallbackMode ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
     return _fallbackMode;
   }
 
   @override
   List<int> get importDependencies {
-    _importDependencies ??= const fb.Uint32ListReader().vTableGet(_bp, 1, const <int>[]);
+    _importDependencies ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]);
     return _importDependencies;
   }
 
   @override
   int get numPrelinkedDependencies {
-    _numPrelinkedDependencies ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _numPrelinkedDependencies ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _numPrelinkedDependencies;
   }
 
   @override
   List<idl.LinkedUnit> get units {
-    _units ??= const fb.ListReader<idl.LinkedUnit>(const _LinkedUnitReader()).vTableGet(_bp, 3, const <idl.LinkedUnit>[]);
+    _units ??= const fb.ListReader<idl.LinkedUnit>(const _LinkedUnitReader()).vTableGet(_bc, _bcOffset, 3, const <idl.LinkedUnit>[]);
     return _units;
   }
 }
@@ -1439,13 +1445,14 @@
   const _LinkedReferenceReader();
 
   @override
-  _LinkedReferenceImpl createObject(fb.BufferPointer bp) => new _LinkedReferenceImpl(bp);
+  _LinkedReferenceImpl createObject(fb.BufferContext bc, int offset) => new _LinkedReferenceImpl(bc, offset);
 }
 
 class _LinkedReferenceImpl extends Object with _LinkedReferenceMixin implements idl.LinkedReference {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _LinkedReferenceImpl(this._bp);
+  _LinkedReferenceImpl(this._bc, this._bcOffset);
 
   int _containingReference;
   int _dependency;
@@ -1457,43 +1464,43 @@
 
   @override
   int get containingReference {
-    _containingReference ??= const fb.Uint32Reader().vTableGet(_bp, 5, 0);
+    _containingReference ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
     return _containingReference;
   }
 
   @override
   int get dependency {
-    _dependency ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _dependency ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _dependency;
   }
 
   @override
   idl.ReferenceKind get kind {
-    _kind ??= const _ReferenceKindReader().vTableGet(_bp, 2, idl.ReferenceKind.classOrEnum);
+    _kind ??= const _ReferenceKindReader().vTableGet(_bc, _bcOffset, 2, idl.ReferenceKind.classOrEnum);
     return _kind;
   }
 
   @override
   int get localIndex {
-    _localIndex ??= const fb.Uint32Reader().vTableGet(_bp, 6, 0);
+    _localIndex ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
     return _localIndex;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 3, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
     return _name;
   }
 
   @override
   int get numTypeParameters {
-    _numTypeParameters ??= const fb.Uint32Reader().vTableGet(_bp, 4, 0);
+    _numTypeParameters ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
     return _numTypeParameters;
   }
 
   @override
   int get unit {
-    _unit ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _unit ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _unit;
   }
 }
@@ -1621,13 +1628,14 @@
   const _LinkedUnitReader();
 
   @override
-  _LinkedUnitImpl createObject(fb.BufferPointer bp) => new _LinkedUnitImpl(bp);
+  _LinkedUnitImpl createObject(fb.BufferContext bc, int offset) => new _LinkedUnitImpl(bc, offset);
 }
 
 class _LinkedUnitImpl extends Object with _LinkedUnitMixin implements idl.LinkedUnit {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _LinkedUnitImpl(this._bp);
+  _LinkedUnitImpl(this._bc, this._bcOffset);
 
   List<int> _constCycles;
   List<idl.LinkedReference> _references;
@@ -1635,19 +1643,19 @@
 
   @override
   List<int> get constCycles {
-    _constCycles ??= const fb.Uint32ListReader().vTableGet(_bp, 2, const <int>[]);
+    _constCycles ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
     return _constCycles;
   }
 
   @override
   List<idl.LinkedReference> get references {
-    _references ??= const fb.ListReader<idl.LinkedReference>(const _LinkedReferenceReader()).vTableGet(_bp, 0, const <idl.LinkedReference>[]);
+    _references ??= const fb.ListReader<idl.LinkedReference>(const _LinkedReferenceReader()).vTableGet(_bc, _bcOffset, 0, const <idl.LinkedReference>[]);
     return _references;
   }
 
   @override
   List<idl.EntityRef> get types {
-    _types ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bp, 1, const <idl.EntityRef>[]);
+    _types ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bc, _bcOffset, 1, const <idl.EntityRef>[]);
     return _types;
   }
 }
@@ -1840,21 +1848,22 @@
 }
 
 idl.PackageBundle readPackageBundle(List<int> buffer) {
-  fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
-  return const _PackageBundleReader().read(rootRef);
+  fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
+  return const _PackageBundleReader().read(rootRef, 0);
 }
 
 class _PackageBundleReader extends fb.TableReader<_PackageBundleImpl> {
   const _PackageBundleReader();
 
   @override
-  _PackageBundleImpl createObject(fb.BufferPointer bp) => new _PackageBundleImpl(bp);
+  _PackageBundleImpl createObject(fb.BufferContext bc, int offset) => new _PackageBundleImpl(bc, offset);
 }
 
 class _PackageBundleImpl extends Object with _PackageBundleMixin implements idl.PackageBundle {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _PackageBundleImpl(this._bp);
+  _PackageBundleImpl(this._bc, this._bcOffset);
 
   List<idl.LinkedLibrary> _linkedLibraries;
   List<String> _linkedLibraryUris;
@@ -1866,43 +1875,43 @@
 
   @override
   List<idl.LinkedLibrary> get linkedLibraries {
-    _linkedLibraries ??= const fb.ListReader<idl.LinkedLibrary>(const _LinkedLibraryReader()).vTableGet(_bp, 0, const <idl.LinkedLibrary>[]);
+    _linkedLibraries ??= const fb.ListReader<idl.LinkedLibrary>(const _LinkedLibraryReader()).vTableGet(_bc, _bcOffset, 0, const <idl.LinkedLibrary>[]);
     return _linkedLibraries;
   }
 
   @override
   List<String> get linkedLibraryUris {
-    _linkedLibraryUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    _linkedLibraryUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 1, const <String>[]);
     return _linkedLibraryUris;
   }
 
   @override
   int get majorVersion {
-    _majorVersion ??= const fb.Uint32Reader().vTableGet(_bp, 5, 0);
+    _majorVersion ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
     return _majorVersion;
   }
 
   @override
   int get minorVersion {
-    _minorVersion ??= const fb.Uint32Reader().vTableGet(_bp, 6, 0);
+    _minorVersion ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
     return _minorVersion;
   }
 
   @override
   List<String> get unlinkedUnitHashes {
-    _unlinkedUnitHashes ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 4, const <String>[]);
+    _unlinkedUnitHashes ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 4, const <String>[]);
     return _unlinkedUnitHashes;
   }
 
   @override
   List<idl.UnlinkedUnit> get unlinkedUnits {
-    _unlinkedUnits ??= const fb.ListReader<idl.UnlinkedUnit>(const _UnlinkedUnitReader()).vTableGet(_bp, 2, const <idl.UnlinkedUnit>[]);
+    _unlinkedUnits ??= const fb.ListReader<idl.UnlinkedUnit>(const _UnlinkedUnitReader()).vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedUnit>[]);
     return _unlinkedUnits;
   }
 
   @override
   List<String> get unlinkedUnitUris {
-    _unlinkedUnitUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 3, const <String>[]);
+    _unlinkedUnitUris ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 3, const <String>[]);
     return _unlinkedUnitUris;
   }
 }
@@ -2119,21 +2128,22 @@
 }
 
 idl.PackageIndex readPackageIndex(List<int> buffer) {
-  fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
-  return const _PackageIndexReader().read(rootRef);
+  fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
+  return const _PackageIndexReader().read(rootRef, 0);
 }
 
 class _PackageIndexReader extends fb.TableReader<_PackageIndexImpl> {
   const _PackageIndexReader();
 
   @override
-  _PackageIndexImpl createObject(fb.BufferPointer bp) => new _PackageIndexImpl(bp);
+  _PackageIndexImpl createObject(fb.BufferContext bc, int offset) => new _PackageIndexImpl(bc, offset);
 }
 
 class _PackageIndexImpl extends Object with _PackageIndexMixin implements idl.PackageIndex {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _PackageIndexImpl(this._bp);
+  _PackageIndexImpl(this._bc, this._bcOffset);
 
   List<idl.IndexSyntheticElementKind> _elementKinds;
   List<int> _elementOffsets;
@@ -2145,43 +2155,43 @@
 
   @override
   List<idl.IndexSyntheticElementKind> get elementKinds {
-    _elementKinds ??= const fb.ListReader<idl.IndexSyntheticElementKind>(const _IndexSyntheticElementKindReader()).vTableGet(_bp, 5, const <idl.IndexSyntheticElementKind>[]);
+    _elementKinds ??= const fb.ListReader<idl.IndexSyntheticElementKind>(const _IndexSyntheticElementKindReader()).vTableGet(_bc, _bcOffset, 5, const <idl.IndexSyntheticElementKind>[]);
     return _elementKinds;
   }
 
   @override
   List<int> get elementOffsets {
-    _elementOffsets ??= const fb.Uint32ListReader().vTableGet(_bp, 1, const <int>[]);
+    _elementOffsets ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]);
     return _elementOffsets;
   }
 
   @override
   List<int> get elementUnits {
-    _elementUnits ??= const fb.Uint32ListReader().vTableGet(_bp, 0, const <int>[]);
+    _elementUnits ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 0, const <int>[]);
     return _elementUnits;
   }
 
   @override
   List<String> get strings {
-    _strings ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 6, const <String>[]);
+    _strings ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 6, const <String>[]);
     return _strings;
   }
 
   @override
   List<int> get unitLibraryUris {
-    _unitLibraryUris ??= const fb.Uint32ListReader().vTableGet(_bp, 2, const <int>[]);
+    _unitLibraryUris ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
     return _unitLibraryUris;
   }
 
   @override
   List<idl.UnitIndex> get units {
-    _units ??= const fb.ListReader<idl.UnitIndex>(const _UnitIndexReader()).vTableGet(_bp, 4, const <idl.UnitIndex>[]);
+    _units ??= const fb.ListReader<idl.UnitIndex>(const _UnitIndexReader()).vTableGet(_bc, _bcOffset, 4, const <idl.UnitIndex>[]);
     return _units;
   }
 
   @override
   List<int> get unitUnitUris {
-    _unitUnitUris ??= const fb.Uint32ListReader().vTableGet(_bp, 3, const <int>[]);
+    _unitUnitUris ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 3, const <int>[]);
     return _unitUnitUris;
   }
 }
@@ -2516,13 +2526,14 @@
   const _UnitIndexReader();
 
   @override
-  _UnitIndexImpl createObject(fb.BufferPointer bp) => new _UnitIndexImpl(bp);
+  _UnitIndexImpl createObject(fb.BufferContext bc, int offset) => new _UnitIndexImpl(bc, offset);
 }
 
 class _UnitIndexImpl extends Object with _UnitIndexMixin implements idl.UnitIndex {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnitIndexImpl(this._bp);
+  _UnitIndexImpl(this._bc, this._bcOffset);
 
   List<idl.IndexNameKind> _definedNameKinds;
   List<int> _definedNameOffsets;
@@ -2540,79 +2551,79 @@
 
   @override
   List<idl.IndexNameKind> get definedNameKinds {
-    _definedNameKinds ??= const fb.ListReader<idl.IndexNameKind>(const _IndexNameKindReader()).vTableGet(_bp, 6, const <idl.IndexNameKind>[]);
+    _definedNameKinds ??= const fb.ListReader<idl.IndexNameKind>(const _IndexNameKindReader()).vTableGet(_bc, _bcOffset, 6, const <idl.IndexNameKind>[]);
     return _definedNameKinds;
   }
 
   @override
   List<int> get definedNameOffsets {
-    _definedNameOffsets ??= const fb.Uint32ListReader().vTableGet(_bp, 7, const <int>[]);
+    _definedNameOffsets ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 7, const <int>[]);
     return _definedNameOffsets;
   }
 
   @override
   List<int> get definedNames {
-    _definedNames ??= const fb.Uint32ListReader().vTableGet(_bp, 5, const <int>[]);
+    _definedNames ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 5, const <int>[]);
     return _definedNames;
   }
 
   @override
   int get unit {
-    _unit ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _unit ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _unit;
   }
 
   @override
   List<bool> get usedElementIsQualifiedFlags {
-    _usedElementIsQualifiedFlags ??= const fb.BoolListReader().vTableGet(_bp, 11, const <bool>[]);
+    _usedElementIsQualifiedFlags ??= const fb.BoolListReader().vTableGet(_bc, _bcOffset, 11, const <bool>[]);
     return _usedElementIsQualifiedFlags;
   }
 
   @override
   List<idl.IndexRelationKind> get usedElementKinds {
-    _usedElementKinds ??= const fb.ListReader<idl.IndexRelationKind>(const _IndexRelationKindReader()).vTableGet(_bp, 4, const <idl.IndexRelationKind>[]);
+    _usedElementKinds ??= const fb.ListReader<idl.IndexRelationKind>(const _IndexRelationKindReader()).vTableGet(_bc, _bcOffset, 4, const <idl.IndexRelationKind>[]);
     return _usedElementKinds;
   }
 
   @override
   List<int> get usedElementLengths {
-    _usedElementLengths ??= const fb.Uint32ListReader().vTableGet(_bp, 1, const <int>[]);
+    _usedElementLengths ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]);
     return _usedElementLengths;
   }
 
   @override
   List<int> get usedElementOffsets {
-    _usedElementOffsets ??= const fb.Uint32ListReader().vTableGet(_bp, 2, const <int>[]);
+    _usedElementOffsets ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
     return _usedElementOffsets;
   }
 
   @override
   List<int> get usedElements {
-    _usedElements ??= const fb.Uint32ListReader().vTableGet(_bp, 3, const <int>[]);
+    _usedElements ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 3, const <int>[]);
     return _usedElements;
   }
 
   @override
   List<bool> get usedNameIsQualifiedFlags {
-    _usedNameIsQualifiedFlags ??= const fb.BoolListReader().vTableGet(_bp, 12, const <bool>[]);
+    _usedNameIsQualifiedFlags ??= const fb.BoolListReader().vTableGet(_bc, _bcOffset, 12, const <bool>[]);
     return _usedNameIsQualifiedFlags;
   }
 
   @override
   List<idl.IndexRelationKind> get usedNameKinds {
-    _usedNameKinds ??= const fb.ListReader<idl.IndexRelationKind>(const _IndexRelationKindReader()).vTableGet(_bp, 10, const <idl.IndexRelationKind>[]);
+    _usedNameKinds ??= const fb.ListReader<idl.IndexRelationKind>(const _IndexRelationKindReader()).vTableGet(_bc, _bcOffset, 10, const <idl.IndexRelationKind>[]);
     return _usedNameKinds;
   }
 
   @override
   List<int> get usedNameOffsets {
-    _usedNameOffsets ??= const fb.Uint32ListReader().vTableGet(_bp, 9, const <int>[]);
+    _usedNameOffsets ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 9, const <int>[]);
     return _usedNameOffsets;
   }
 
   @override
   List<int> get usedNames {
-    _usedNames ??= const fb.Uint32ListReader().vTableGet(_bp, 8, const <int>[]);
+    _usedNames ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 8, const <int>[]);
     return _usedNames;
   }
 }
@@ -2961,13 +2972,14 @@
   const _UnlinkedClassReader();
 
   @override
-  _UnlinkedClassImpl createObject(fb.BufferPointer bp) => new _UnlinkedClassImpl(bp);
+  _UnlinkedClassImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedClassImpl(bc, offset);
 }
 
 class _UnlinkedClassImpl extends Object with _UnlinkedClassMixin implements idl.UnlinkedClass {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedClassImpl(this._bp);
+  _UnlinkedClassImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   idl.CodeRange _codeRange;
@@ -2986,85 +2998,85 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 5, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 5, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   idl.CodeRange get codeRange {
-    _codeRange ??= const _CodeRangeReader().vTableGet(_bp, 13, null);
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 13, null);
     return _codeRange;
   }
 
   @override
   idl.UnlinkedDocumentationComment get documentationComment {
-    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 6, null);
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bc, _bcOffset, 6, null);
     return _documentationComment;
   }
 
   @override
   List<idl.UnlinkedExecutable> get executables {
-    _executables ??= const fb.ListReader<idl.UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bp, 2, const <idl.UnlinkedExecutable>[]);
+    _executables ??= const fb.ListReader<idl.UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedExecutable>[]);
     return _executables;
   }
 
   @override
   List<idl.UnlinkedVariable> get fields {
-    _fields ??= const fb.ListReader<idl.UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bp, 4, const <idl.UnlinkedVariable>[]);
+    _fields ??= const fb.ListReader<idl.UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bc, _bcOffset, 4, const <idl.UnlinkedVariable>[]);
     return _fields;
   }
 
   @override
   bool get hasNoSupertype {
-    _hasNoSupertype ??= const fb.BoolReader().vTableGet(_bp, 12, false);
+    _hasNoSupertype ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 12, false);
     return _hasNoSupertype;
   }
 
   @override
   List<idl.EntityRef> get interfaces {
-    _interfaces ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bp, 7, const <idl.EntityRef>[]);
+    _interfaces ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bc, _bcOffset, 7, const <idl.EntityRef>[]);
     return _interfaces;
   }
 
   @override
   bool get isAbstract {
-    _isAbstract ??= const fb.BoolReader().vTableGet(_bp, 8, false);
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 8, false);
     return _isAbstract;
   }
 
   @override
   bool get isMixinApplication {
-    _isMixinApplication ??= const fb.BoolReader().vTableGet(_bp, 11, false);
+    _isMixinApplication ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 11, false);
     return _isMixinApplication;
   }
 
   @override
   List<idl.EntityRef> get mixins {
-    _mixins ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bp, 10, const <idl.EntityRef>[]);
+    _mixins ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bc, _bcOffset, 10, const <idl.EntityRef>[]);
     return _mixins;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _nameOffset;
   }
 
   @override
   idl.EntityRef get supertype {
-    _supertype ??= const _EntityRefReader().vTableGet(_bp, 3, null);
+    _supertype ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 3, null);
     return _supertype;
   }
 
   @override
   List<idl.UnlinkedTypeParam> get typeParameters {
-    _typeParameters ??= const fb.ListReader<idl.UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 9, const <idl.UnlinkedTypeParam>[]);
+    _typeParameters ??= const fb.ListReader<idl.UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bc, _bcOffset, 9, const <idl.UnlinkedTypeParam>[]);
     return _typeParameters;
   }
 }
@@ -3214,13 +3226,14 @@
   const _UnlinkedCombinatorReader();
 
   @override
-  _UnlinkedCombinatorImpl createObject(fb.BufferPointer bp) => new _UnlinkedCombinatorImpl(bp);
+  _UnlinkedCombinatorImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedCombinatorImpl(bc, offset);
 }
 
 class _UnlinkedCombinatorImpl extends Object with _UnlinkedCombinatorMixin implements idl.UnlinkedCombinator {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedCombinatorImpl(this._bp);
+  _UnlinkedCombinatorImpl(this._bc, this._bcOffset);
 
   int _end;
   List<String> _hides;
@@ -3229,25 +3242,25 @@
 
   @override
   int get end {
-    _end ??= const fb.Uint32Reader().vTableGet(_bp, 3, 0);
+    _end ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
     return _end;
   }
 
   @override
   List<String> get hides {
-    _hides ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    _hides ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 1, const <String>[]);
     return _hides;
   }
 
   @override
   int get offset {
-    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _offset;
   }
 
   @override
   List<String> get shows {
-    _shows ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 0, const <String>[]);
+    _shows ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 0, const <String>[]);
     return _shows;
   }
 }
@@ -3445,13 +3458,14 @@
   const _UnlinkedConstReader();
 
   @override
-  _UnlinkedConstImpl createObject(fb.BufferPointer bp) => new _UnlinkedConstImpl(bp);
+  _UnlinkedConstImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedConstImpl(bc, offset);
 }
 
 class _UnlinkedConstImpl extends Object with _UnlinkedConstMixin implements idl.UnlinkedConst {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedConstImpl(this._bp);
+  _UnlinkedConstImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedExprAssignOperator> _assignmentOperators;
   List<double> _doubles;
@@ -3463,43 +3477,43 @@
 
   @override
   List<idl.UnlinkedExprAssignOperator> get assignmentOperators {
-    _assignmentOperators ??= const fb.ListReader<idl.UnlinkedExprAssignOperator>(const _UnlinkedExprAssignOperatorReader()).vTableGet(_bp, 6, const <idl.UnlinkedExprAssignOperator>[]);
+    _assignmentOperators ??= const fb.ListReader<idl.UnlinkedExprAssignOperator>(const _UnlinkedExprAssignOperatorReader()).vTableGet(_bc, _bcOffset, 6, const <idl.UnlinkedExprAssignOperator>[]);
     return _assignmentOperators;
   }
 
   @override
   List<double> get doubles {
-    _doubles ??= const fb.Float64ListReader().vTableGet(_bp, 4, const <double>[]);
+    _doubles ??= const fb.Float64ListReader().vTableGet(_bc, _bcOffset, 4, const <double>[]);
     return _doubles;
   }
 
   @override
   List<int> get ints {
-    _ints ??= const fb.Uint32ListReader().vTableGet(_bp, 1, const <int>[]);
+    _ints ??= const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]);
     return _ints;
   }
 
   @override
   bool get isValidConst {
-    _isValidConst ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    _isValidConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
     return _isValidConst;
   }
 
   @override
   List<idl.UnlinkedConstOperation> get operations {
-    _operations ??= const fb.ListReader<idl.UnlinkedConstOperation>(const _UnlinkedConstOperationReader()).vTableGet(_bp, 0, const <idl.UnlinkedConstOperation>[]);
+    _operations ??= const fb.ListReader<idl.UnlinkedConstOperation>(const _UnlinkedConstOperationReader()).vTableGet(_bc, _bcOffset, 0, const <idl.UnlinkedConstOperation>[]);
     return _operations;
   }
 
   @override
   List<idl.EntityRef> get references {
-    _references ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bp, 2, const <idl.EntityRef>[]);
+    _references ??= const fb.ListReader<idl.EntityRef>(const _EntityRefReader()).vTableGet(_bc, _bcOffset, 2, const <idl.EntityRef>[]);
     return _references;
   }
 
   @override
   List<String> get strings {
-    _strings ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 3, const <String>[]);
+    _strings ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 3, const <String>[]);
     return _strings;
   }
 }
@@ -3536,25 +3550,13 @@
 class UnlinkedConstructorInitializerBuilder extends Object with _UnlinkedConstructorInitializerMixin implements idl.UnlinkedConstructorInitializer {
   bool _finished = false;
 
-  List<UnlinkedConstBuilder> _arguments;
   List<String> _argumentNames;
+  List<UnlinkedConstBuilder> _arguments;
   UnlinkedConstBuilder _expression;
   idl.UnlinkedConstructorInitializerKind _kind;
   String _name;
 
   @override
-  List<UnlinkedConstBuilder> get arguments => _arguments ??= <UnlinkedConstBuilder>[];
-
-  /**
-   * If [kind] is `thisInvocation` or `superInvocation`, the arguments of the
-   * invocation.  Otherwise empty.
-   */
-  void set arguments(List<UnlinkedConstBuilder> _value) {
-    assert(!_finished);
-    _arguments = _value;
-  }
-
-  @override
   List<String> get argumentNames => _argumentNames ??= <String>[];
 
   /**
@@ -3568,6 +3570,18 @@
   }
 
   @override
+  List<UnlinkedConstBuilder> get arguments => _arguments ??= <UnlinkedConstBuilder>[];
+
+  /**
+   * If [kind] is `thisInvocation` or `superInvocation`, the arguments of the
+   * invocation.  Otherwise empty.
+   */
+  void set arguments(List<UnlinkedConstBuilder> _value) {
+    assert(!_finished);
+    _arguments = _value;
+  }
+
+  @override
   UnlinkedConstBuilder get expression => _expression;
 
   /**
@@ -3604,9 +3618,9 @@
     _name = _value;
   }
 
-  UnlinkedConstructorInitializerBuilder({List<UnlinkedConstBuilder> arguments, List<String> argumentNames, UnlinkedConstBuilder expression, idl.UnlinkedConstructorInitializerKind kind, String name})
-    : _arguments = arguments,
-      _argumentNames = argumentNames,
+  UnlinkedConstructorInitializerBuilder({List<String> argumentNames, List<UnlinkedConstBuilder> arguments, UnlinkedConstBuilder expression, idl.UnlinkedConstructorInitializerKind kind, String name})
+    : _argumentNames = argumentNames,
+      _arguments = arguments,
       _expression = expression,
       _kind = kind,
       _name = name;
@@ -3622,16 +3636,16 @@
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
-    fb.Offset offset_arguments;
     fb.Offset offset_argumentNames;
+    fb.Offset offset_arguments;
     fb.Offset offset_expression;
     fb.Offset offset_name;
-    if (!(_arguments == null || _arguments.isEmpty)) {
-      offset_arguments = fbBuilder.writeList(_arguments.map((b) => b.finish(fbBuilder)).toList());
-    }
     if (!(_argumentNames == null || _argumentNames.isEmpty)) {
       offset_argumentNames = fbBuilder.writeList(_argumentNames.map((b) => fbBuilder.writeString(b)).toList());
     }
+    if (!(_arguments == null || _arguments.isEmpty)) {
+      offset_arguments = fbBuilder.writeList(_arguments.map((b) => b.finish(fbBuilder)).toList());
+    }
     if (_expression != null) {
       offset_expression = _expression.finish(fbBuilder);
     }
@@ -3639,12 +3653,12 @@
       offset_name = fbBuilder.writeString(_name);
     }
     fbBuilder.startTable();
-    if (offset_arguments != null) {
-      fbBuilder.addOffset(3, offset_arguments);
-    }
     if (offset_argumentNames != null) {
       fbBuilder.addOffset(4, offset_argumentNames);
     }
+    if (offset_arguments != null) {
+      fbBuilder.addOffset(3, offset_arguments);
+    }
     if (offset_expression != null) {
       fbBuilder.addOffset(1, offset_expression);
     }
@@ -3662,47 +3676,48 @@
   const _UnlinkedConstructorInitializerReader();
 
   @override
-  _UnlinkedConstructorInitializerImpl createObject(fb.BufferPointer bp) => new _UnlinkedConstructorInitializerImpl(bp);
+  _UnlinkedConstructorInitializerImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedConstructorInitializerImpl(bc, offset);
 }
 
 class _UnlinkedConstructorInitializerImpl extends Object with _UnlinkedConstructorInitializerMixin implements idl.UnlinkedConstructorInitializer {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedConstructorInitializerImpl(this._bp);
+  _UnlinkedConstructorInitializerImpl(this._bc, this._bcOffset);
 
-  List<idl.UnlinkedConst> _arguments;
   List<String> _argumentNames;
+  List<idl.UnlinkedConst> _arguments;
   idl.UnlinkedConst _expression;
   idl.UnlinkedConstructorInitializerKind _kind;
   String _name;
 
   @override
-  List<idl.UnlinkedConst> get arguments {
-    _arguments ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 3, const <idl.UnlinkedConst>[]);
-    return _arguments;
-  }
-
-  @override
   List<String> get argumentNames {
-    _argumentNames ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 4, const <String>[]);
+    _argumentNames ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 4, const <String>[]);
     return _argumentNames;
   }
 
   @override
+  List<idl.UnlinkedConst> get arguments {
+    _arguments ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 3, const <idl.UnlinkedConst>[]);
+    return _arguments;
+  }
+
+  @override
   idl.UnlinkedConst get expression {
-    _expression ??= const _UnlinkedConstReader().vTableGet(_bp, 1, null);
+    _expression ??= const _UnlinkedConstReader().vTableGet(_bc, _bcOffset, 1, null);
     return _expression;
   }
 
   @override
   idl.UnlinkedConstructorInitializerKind get kind {
-    _kind ??= const _UnlinkedConstructorInitializerKindReader().vTableGet(_bp, 2, idl.UnlinkedConstructorInitializerKind.field);
+    _kind ??= const _UnlinkedConstructorInitializerKindReader().vTableGet(_bc, _bcOffset, 2, idl.UnlinkedConstructorInitializerKind.field);
     return _kind;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 }
@@ -3711,8 +3726,8 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
-    if (arguments.isNotEmpty) _result["arguments"] = arguments.map((_value) => _value.toJson()).toList();
     if (argumentNames.isNotEmpty) _result["argumentNames"] = argumentNames;
+    if (arguments.isNotEmpty) _result["arguments"] = arguments.map((_value) => _value.toJson()).toList();
     if (expression != null) _result["expression"] = expression.toJson();
     if (kind != idl.UnlinkedConstructorInitializerKind.field) _result["kind"] = kind.toString().split('.')[1];
     if (name != '') _result["name"] = name;
@@ -3721,8 +3736,8 @@
 
   @override
   Map<String, Object> toMap() => {
-    "arguments": arguments,
     "argumentNames": argumentNames,
+    "arguments": arguments,
     "expression": expression,
     "kind": kind,
     "name": name,
@@ -3814,13 +3829,14 @@
   const _UnlinkedDocumentationCommentReader();
 
   @override
-  _UnlinkedDocumentationCommentImpl createObject(fb.BufferPointer bp) => new _UnlinkedDocumentationCommentImpl(bp);
+  _UnlinkedDocumentationCommentImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedDocumentationCommentImpl(bc, offset);
 }
 
 class _UnlinkedDocumentationCommentImpl extends Object with _UnlinkedDocumentationCommentMixin implements idl.UnlinkedDocumentationComment {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedDocumentationCommentImpl(this._bp);
+  _UnlinkedDocumentationCommentImpl(this._bc, this._bcOffset);
 
   int _length;
   int _offset;
@@ -3828,19 +3844,19 @@
 
   @override
   int get length {
-    _length ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _length ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _length;
   }
 
   @override
   int get offset {
-    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _offset;
   }
 
   @override
   String get text {
-    _text ??= const fb.StringReader().vTableGet(_bp, 1, '');
+    _text ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
     return _text;
   }
 }
@@ -4013,13 +4029,14 @@
   const _UnlinkedEnumReader();
 
   @override
-  _UnlinkedEnumImpl createObject(fb.BufferPointer bp) => new _UnlinkedEnumImpl(bp);
+  _UnlinkedEnumImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedEnumImpl(bc, offset);
 }
 
 class _UnlinkedEnumImpl extends Object with _UnlinkedEnumMixin implements idl.UnlinkedEnum {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedEnumImpl(this._bp);
+  _UnlinkedEnumImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   idl.CodeRange _codeRange;
@@ -4030,37 +4047,37 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 4, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 4, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   idl.CodeRange get codeRange {
-    _codeRange ??= const _CodeRangeReader().vTableGet(_bp, 5, null);
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 5, null);
     return _codeRange;
   }
 
   @override
   idl.UnlinkedDocumentationComment get documentationComment {
-    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 3, null);
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bc, _bcOffset, 3, null);
     return _documentationComment;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _nameOffset;
   }
 
   @override
   List<idl.UnlinkedEnumValue> get values {
-    _values ??= const fb.ListReader<idl.UnlinkedEnumValue>(const _UnlinkedEnumValueReader()).vTableGet(_bp, 2, const <idl.UnlinkedEnumValue>[]);
+    _values ??= const fb.ListReader<idl.UnlinkedEnumValue>(const _UnlinkedEnumValueReader()).vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedEnumValue>[]);
     return _values;
   }
 }
@@ -4176,13 +4193,14 @@
   const _UnlinkedEnumValueReader();
 
   @override
-  _UnlinkedEnumValueImpl createObject(fb.BufferPointer bp) => new _UnlinkedEnumValueImpl(bp);
+  _UnlinkedEnumValueImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedEnumValueImpl(bc, offset);
 }
 
 class _UnlinkedEnumValueImpl extends Object with _UnlinkedEnumValueMixin implements idl.UnlinkedEnumValue {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedEnumValueImpl(this._bp);
+  _UnlinkedEnumValueImpl(this._bc, this._bcOffset);
 
   idl.UnlinkedDocumentationComment _documentationComment;
   String _name;
@@ -4190,19 +4208,19 @@
 
   @override
   idl.UnlinkedDocumentationComment get documentationComment {
-    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 2, null);
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bc, _bcOffset, 2, null);
     return _documentationComment;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _nameOffset;
   }
 }
@@ -4232,6 +4250,7 @@
   bool _finished = false;
 
   List<UnlinkedConstBuilder> _annotations;
+  UnlinkedConstBuilder _bodyExpr;
   CodeRangeBuilder _codeRange;
   List<UnlinkedConstructorInitializerBuilder> _constantInitializers;
   int _constCycleSlot;
@@ -4273,6 +4292,19 @@
   }
 
   @override
+  UnlinkedConstBuilder get bodyExpr => _bodyExpr;
+
+  /**
+   * If this executable's function body is declared using `=>`, the expression
+   * to the right of the `=>`.  May be omitted if neither type inference nor
+   * constant evaluation depends on the function body.
+   */
+  void set bodyExpr(UnlinkedConstBuilder _value) {
+    assert(!_finished);
+    _bodyExpr = _value;
+  }
+
+  @override
   CodeRangeBuilder get codeRange => _codeRange;
 
   /**
@@ -4620,8 +4652,9 @@
     _visibleOffset = _value;
   }
 
-  UnlinkedExecutableBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, List<UnlinkedConstructorInitializerBuilder> constantInitializers, int constCycleSlot, UnlinkedDocumentationCommentBuilder documentationComment, int inferredReturnTypeSlot, bool isAbstract, bool isAsynchronous, bool isConst, bool isExternal, bool isFactory, bool isGenerator, bool isRedirectedConstructor, bool isStatic, idl.UnlinkedExecutableKind kind, List<UnlinkedExecutableBuilder> localFunctions, List<UnlinkedLabelBuilder> localLabels, List<UnlinkedVariableBuilder> localVariables, String name, int nameEnd, int nameOffset, List<UnlinkedParamBuilder> parameters, int periodOffset, EntityRefBuilder redirectedConstructor, String redirectedConstructorName, EntityRefBuilder returnType, List<UnlinkedTypeParamBuilder> typeParameters, int visibleLength, int visibleOffset})
+  UnlinkedExecutableBuilder({List<UnlinkedConstBuilder> annotations, UnlinkedConstBuilder bodyExpr, CodeRangeBuilder codeRange, List<UnlinkedConstructorInitializerBuilder> constantInitializers, int constCycleSlot, UnlinkedDocumentationCommentBuilder documentationComment, int inferredReturnTypeSlot, bool isAbstract, bool isAsynchronous, bool isConst, bool isExternal, bool isFactory, bool isGenerator, bool isRedirectedConstructor, bool isStatic, idl.UnlinkedExecutableKind kind, List<UnlinkedExecutableBuilder> localFunctions, List<UnlinkedLabelBuilder> localLabels, List<UnlinkedVariableBuilder> localVariables, String name, int nameEnd, int nameOffset, List<UnlinkedParamBuilder> parameters, int periodOffset, EntityRefBuilder redirectedConstructor, String redirectedConstructorName, EntityRefBuilder returnType, List<UnlinkedTypeParamBuilder> typeParameters, int visibleLength, int visibleOffset})
     : _annotations = annotations,
+      _bodyExpr = bodyExpr,
       _codeRange = codeRange,
       _constantInitializers = constantInitializers,
       _constCycleSlot = constCycleSlot,
@@ -4656,6 +4689,7 @@
    */
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
+    _bodyExpr?.flushInformative();
     _codeRange = null;
     _constantInitializers?.forEach((b) => b.flushInformative());
     _documentationComment = null;
@@ -4677,6 +4711,7 @@
     assert(!_finished);
     _finished = true;
     fb.Offset offset_annotations;
+    fb.Offset offset_bodyExpr;
     fb.Offset offset_codeRange;
     fb.Offset offset_constantInitializers;
     fb.Offset offset_documentationComment;
@@ -4692,6 +4727,9 @@
     if (!(_annotations == null || _annotations.isEmpty)) {
       offset_annotations = fbBuilder.writeList(_annotations.map((b) => b.finish(fbBuilder)).toList());
     }
+    if (_bodyExpr != null) {
+      offset_bodyExpr = _bodyExpr.finish(fbBuilder);
+    }
     if (_codeRange != null) {
       offset_codeRange = _codeRange.finish(fbBuilder);
     }
@@ -4732,6 +4770,9 @@
     if (offset_annotations != null) {
       fbBuilder.addOffset(6, offset_annotations);
     }
+    if (offset_bodyExpr != null) {
+      fbBuilder.addOffset(29, offset_bodyExpr);
+    }
     if (offset_codeRange != null) {
       fbBuilder.addOffset(26, offset_codeRange);
     }
@@ -4824,15 +4865,17 @@
   const _UnlinkedExecutableReader();
 
   @override
-  _UnlinkedExecutableImpl createObject(fb.BufferPointer bp) => new _UnlinkedExecutableImpl(bp);
+  _UnlinkedExecutableImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedExecutableImpl(bc, offset);
 }
 
 class _UnlinkedExecutableImpl extends Object with _UnlinkedExecutableMixin implements idl.UnlinkedExecutable {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedExecutableImpl(this._bp);
+  _UnlinkedExecutableImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
+  idl.UnlinkedConst _bodyExpr;
   idl.CodeRange _codeRange;
   List<idl.UnlinkedConstructorInitializer> _constantInitializers;
   int _constCycleSlot;
@@ -4864,175 +4907,181 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 6, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 6, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
+  idl.UnlinkedConst get bodyExpr {
+    _bodyExpr ??= const _UnlinkedConstReader().vTableGet(_bc, _bcOffset, 29, null);
+    return _bodyExpr;
+  }
+
+  @override
   idl.CodeRange get codeRange {
-    _codeRange ??= const _CodeRangeReader().vTableGet(_bp, 26, null);
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 26, null);
     return _codeRange;
   }
 
   @override
   List<idl.UnlinkedConstructorInitializer> get constantInitializers {
-    _constantInitializers ??= const fb.ListReader<idl.UnlinkedConstructorInitializer>(const _UnlinkedConstructorInitializerReader()).vTableGet(_bp, 14, const <idl.UnlinkedConstructorInitializer>[]);
+    _constantInitializers ??= const fb.ListReader<idl.UnlinkedConstructorInitializer>(const _UnlinkedConstructorInitializerReader()).vTableGet(_bc, _bcOffset, 14, const <idl.UnlinkedConstructorInitializer>[]);
     return _constantInitializers;
   }
 
   @override
   int get constCycleSlot {
-    _constCycleSlot ??= const fb.Uint32Reader().vTableGet(_bp, 25, 0);
+    _constCycleSlot ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 25, 0);
     return _constCycleSlot;
   }
 
   @override
   idl.UnlinkedDocumentationComment get documentationComment {
-    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 7, null);
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bc, _bcOffset, 7, null);
     return _documentationComment;
   }
 
   @override
   int get inferredReturnTypeSlot {
-    _inferredReturnTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 5, 0);
+    _inferredReturnTypeSlot ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
     return _inferredReturnTypeSlot;
   }
 
   @override
   bool get isAbstract {
-    _isAbstract ??= const fb.BoolReader().vTableGet(_bp, 10, false);
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 10, false);
     return _isAbstract;
   }
 
   @override
   bool get isAsynchronous {
-    _isAsynchronous ??= const fb.BoolReader().vTableGet(_bp, 27, false);
+    _isAsynchronous ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 27, false);
     return _isAsynchronous;
   }
 
   @override
   bool get isConst {
-    _isConst ??= const fb.BoolReader().vTableGet(_bp, 12, false);
+    _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 12, false);
     return _isConst;
   }
 
   @override
   bool get isExternal {
-    _isExternal ??= const fb.BoolReader().vTableGet(_bp, 11, false);
+    _isExternal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 11, false);
     return _isExternal;
   }
 
   @override
   bool get isFactory {
-    _isFactory ??= const fb.BoolReader().vTableGet(_bp, 8, false);
+    _isFactory ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 8, false);
     return _isFactory;
   }
 
   @override
   bool get isGenerator {
-    _isGenerator ??= const fb.BoolReader().vTableGet(_bp, 28, false);
+    _isGenerator ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 28, false);
     return _isGenerator;
   }
 
   @override
   bool get isRedirectedConstructor {
-    _isRedirectedConstructor ??= const fb.BoolReader().vTableGet(_bp, 13, false);
+    _isRedirectedConstructor ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 13, false);
     return _isRedirectedConstructor;
   }
 
   @override
   bool get isStatic {
-    _isStatic ??= const fb.BoolReader().vTableGet(_bp, 9, false);
+    _isStatic ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 9, false);
     return _isStatic;
   }
 
   @override
   idl.UnlinkedExecutableKind get kind {
-    _kind ??= const _UnlinkedExecutableKindReader().vTableGet(_bp, 4, idl.UnlinkedExecutableKind.functionOrMethod);
+    _kind ??= const _UnlinkedExecutableKindReader().vTableGet(_bc, _bcOffset, 4, idl.UnlinkedExecutableKind.functionOrMethod);
     return _kind;
   }
 
   @override
   List<idl.UnlinkedExecutable> get localFunctions {
-    _localFunctions ??= const fb.ListReader<idl.UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bp, 18, const <idl.UnlinkedExecutable>[]);
+    _localFunctions ??= const fb.ListReader<idl.UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bc, _bcOffset, 18, const <idl.UnlinkedExecutable>[]);
     return _localFunctions;
   }
 
   @override
   List<idl.UnlinkedLabel> get localLabels {
-    _localLabels ??= const fb.ListReader<idl.UnlinkedLabel>(const _UnlinkedLabelReader()).vTableGet(_bp, 22, const <idl.UnlinkedLabel>[]);
+    _localLabels ??= const fb.ListReader<idl.UnlinkedLabel>(const _UnlinkedLabelReader()).vTableGet(_bc, _bcOffset, 22, const <idl.UnlinkedLabel>[]);
     return _localLabels;
   }
 
   @override
   List<idl.UnlinkedVariable> get localVariables {
-    _localVariables ??= const fb.ListReader<idl.UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bp, 19, const <idl.UnlinkedVariable>[]);
+    _localVariables ??= const fb.ListReader<idl.UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bc, _bcOffset, 19, const <idl.UnlinkedVariable>[]);
     return _localVariables;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 1, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
     return _name;
   }
 
   @override
   int get nameEnd {
-    _nameEnd ??= const fb.Uint32Reader().vTableGet(_bp, 23, 0);
+    _nameEnd ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 23, 0);
     return _nameEnd;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _nameOffset;
   }
 
   @override
   List<idl.UnlinkedParam> get parameters {
-    _parameters ??= const fb.ListReader<idl.UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 2, const <idl.UnlinkedParam>[]);
+    _parameters ??= const fb.ListReader<idl.UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedParam>[]);
     return _parameters;
   }
 
   @override
   int get periodOffset {
-    _periodOffset ??= const fb.Uint32Reader().vTableGet(_bp, 24, 0);
+    _periodOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 24, 0);
     return _periodOffset;
   }
 
   @override
   idl.EntityRef get redirectedConstructor {
-    _redirectedConstructor ??= const _EntityRefReader().vTableGet(_bp, 15, null);
+    _redirectedConstructor ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 15, null);
     return _redirectedConstructor;
   }
 
   @override
   String get redirectedConstructorName {
-    _redirectedConstructorName ??= const fb.StringReader().vTableGet(_bp, 17, '');
+    _redirectedConstructorName ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 17, '');
     return _redirectedConstructorName;
   }
 
   @override
   idl.EntityRef get returnType {
-    _returnType ??= const _EntityRefReader().vTableGet(_bp, 3, null);
+    _returnType ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 3, null);
     return _returnType;
   }
 
   @override
   List<idl.UnlinkedTypeParam> get typeParameters {
-    _typeParameters ??= const fb.ListReader<idl.UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 16, const <idl.UnlinkedTypeParam>[]);
+    _typeParameters ??= const fb.ListReader<idl.UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bc, _bcOffset, 16, const <idl.UnlinkedTypeParam>[]);
     return _typeParameters;
   }
 
   @override
   int get visibleLength {
-    _visibleLength ??= const fb.Uint32Reader().vTableGet(_bp, 20, 0);
+    _visibleLength ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 20, 0);
     return _visibleLength;
   }
 
   @override
   int get visibleOffset {
-    _visibleOffset ??= const fb.Uint32Reader().vTableGet(_bp, 21, 0);
+    _visibleOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 21, 0);
     return _visibleOffset;
   }
 }
@@ -5042,6 +5091,7 @@
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
     if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
+    if (bodyExpr != null) _result["bodyExpr"] = bodyExpr.toJson();
     if (codeRange != null) _result["codeRange"] = codeRange.toJson();
     if (constantInitializers.isNotEmpty) _result["constantInitializers"] = constantInitializers.map((_value) => _value.toJson()).toList();
     if (constCycleSlot != 0) _result["constCycleSlot"] = constCycleSlot;
@@ -5076,6 +5126,7 @@
   @override
   Map<String, Object> toMap() => {
     "annotations": annotations,
+    "bodyExpr": bodyExpr,
     "codeRange": codeRange,
     "constantInitializers": constantInitializers,
     "constCycleSlot": constCycleSlot,
@@ -5211,13 +5262,14 @@
   const _UnlinkedExportNonPublicReader();
 
   @override
-  _UnlinkedExportNonPublicImpl createObject(fb.BufferPointer bp) => new _UnlinkedExportNonPublicImpl(bp);
+  _UnlinkedExportNonPublicImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedExportNonPublicImpl(bc, offset);
 }
 
 class _UnlinkedExportNonPublicImpl extends Object with _UnlinkedExportNonPublicMixin implements idl.UnlinkedExportNonPublic {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedExportNonPublicImpl(this._bp);
+  _UnlinkedExportNonPublicImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   int _offset;
@@ -5226,25 +5278,25 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 3, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 3, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   int get offset {
-    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _offset;
   }
 
   @override
   int get uriEnd {
-    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _uriEnd;
   }
 
   @override
   int get uriOffset {
-    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _uriOffset;
   }
 }
@@ -5337,26 +5389,27 @@
   const _UnlinkedExportPublicReader();
 
   @override
-  _UnlinkedExportPublicImpl createObject(fb.BufferPointer bp) => new _UnlinkedExportPublicImpl(bp);
+  _UnlinkedExportPublicImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedExportPublicImpl(bc, offset);
 }
 
 class _UnlinkedExportPublicImpl extends Object with _UnlinkedExportPublicMixin implements idl.UnlinkedExportPublic {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedExportPublicImpl(this._bp);
+  _UnlinkedExportPublicImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedCombinator> _combinators;
   String _uri;
 
   @override
   List<idl.UnlinkedCombinator> get combinators {
-    _combinators ??= const fb.ListReader<idl.UnlinkedCombinator>(const _UnlinkedCombinatorReader()).vTableGet(_bp, 1, const <idl.UnlinkedCombinator>[]);
+    _combinators ??= const fb.ListReader<idl.UnlinkedCombinator>(const _UnlinkedCombinatorReader()).vTableGet(_bc, _bcOffset, 1, const <idl.UnlinkedCombinator>[]);
     return _combinators;
   }
 
   @override
   String get uri {
-    _uri ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _uri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _uri;
   }
 }
@@ -5594,13 +5647,14 @@
   const _UnlinkedImportReader();
 
   @override
-  _UnlinkedImportImpl createObject(fb.BufferPointer bp) => new _UnlinkedImportImpl(bp);
+  _UnlinkedImportImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedImportImpl(bc, offset);
 }
 
 class _UnlinkedImportImpl extends Object with _UnlinkedImportMixin implements idl.UnlinkedImport {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedImportImpl(this._bp);
+  _UnlinkedImportImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   List<idl.UnlinkedCombinator> _combinators;
@@ -5615,61 +5669,61 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 8, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 8, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   List<idl.UnlinkedCombinator> get combinators {
-    _combinators ??= const fb.ListReader<idl.UnlinkedCombinator>(const _UnlinkedCombinatorReader()).vTableGet(_bp, 4, const <idl.UnlinkedCombinator>[]);
+    _combinators ??= const fb.ListReader<idl.UnlinkedCombinator>(const _UnlinkedCombinatorReader()).vTableGet(_bc, _bcOffset, 4, const <idl.UnlinkedCombinator>[]);
     return _combinators;
   }
 
   @override
   bool get isDeferred {
-    _isDeferred ??= const fb.BoolReader().vTableGet(_bp, 9, false);
+    _isDeferred ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 9, false);
     return _isDeferred;
   }
 
   @override
   bool get isImplicit {
-    _isImplicit ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    _isImplicit ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
     return _isImplicit;
   }
 
   @override
   int get offset {
-    _offset ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _offset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _offset;
   }
 
   @override
   int get prefixOffset {
-    _prefixOffset ??= const fb.Uint32Reader().vTableGet(_bp, 6, 0);
+    _prefixOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 6, 0);
     return _prefixOffset;
   }
 
   @override
   int get prefixReference {
-    _prefixReference ??= const fb.Uint32Reader().vTableGet(_bp, 7, 0);
+    _prefixReference ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 7, 0);
     return _prefixReference;
   }
 
   @override
   String get uri {
-    _uri ??= const fb.StringReader().vTableGet(_bp, 1, '');
+    _uri ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
     return _uri;
   }
 
   @override
   int get uriEnd {
-    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _uriEnd;
   }
 
   @override
   int get uriOffset {
-    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bp, 3, 0);
+    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
     return _uriOffset;
   }
 }
@@ -5804,13 +5858,14 @@
   const _UnlinkedLabelReader();
 
   @override
-  _UnlinkedLabelImpl createObject(fb.BufferPointer bp) => new _UnlinkedLabelImpl(bp);
+  _UnlinkedLabelImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedLabelImpl(bc, offset);
 }
 
 class _UnlinkedLabelImpl extends Object with _UnlinkedLabelMixin implements idl.UnlinkedLabel {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedLabelImpl(this._bp);
+  _UnlinkedLabelImpl(this._bc, this._bcOffset);
 
   bool _isOnSwitchMember;
   bool _isOnSwitchStatement;
@@ -5819,25 +5874,25 @@
 
   @override
   bool get isOnSwitchMember {
-    _isOnSwitchMember ??= const fb.BoolReader().vTableGet(_bp, 2, false);
+    _isOnSwitchMember ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 2, false);
     return _isOnSwitchMember;
   }
 
   @override
   bool get isOnSwitchStatement {
-    _isOnSwitchStatement ??= const fb.BoolReader().vTableGet(_bp, 3, false);
+    _isOnSwitchStatement ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 3, false);
     return _isOnSwitchStatement;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _nameOffset;
   }
 }
@@ -6188,13 +6243,14 @@
   const _UnlinkedParamReader();
 
   @override
-  _UnlinkedParamImpl createObject(fb.BufferPointer bp) => new _UnlinkedParamImpl(bp);
+  _UnlinkedParamImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedParamImpl(bc, offset);
 }
 
 class _UnlinkedParamImpl extends Object with _UnlinkedParamMixin implements idl.UnlinkedParam {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedParamImpl(this._bp);
+  _UnlinkedParamImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   idl.CodeRange _codeRange;
@@ -6214,91 +6270,91 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 9, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 9, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   idl.CodeRange get codeRange {
-    _codeRange ??= const _CodeRangeReader().vTableGet(_bp, 14, null);
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 14, null);
     return _codeRange;
   }
 
   @override
   idl.UnlinkedConst get defaultValue {
-    _defaultValue ??= const _UnlinkedConstReader().vTableGet(_bp, 7, null);
+    _defaultValue ??= const _UnlinkedConstReader().vTableGet(_bc, _bcOffset, 7, null);
     return _defaultValue;
   }
 
   @override
   String get defaultValueCode {
-    _defaultValueCode ??= const fb.StringReader().vTableGet(_bp, 13, '');
+    _defaultValueCode ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 13, '');
     return _defaultValueCode;
   }
 
   @override
   int get inferredTypeSlot {
-    _inferredTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _inferredTypeSlot ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _inferredTypeSlot;
   }
 
   @override
   idl.UnlinkedExecutable get initializer {
-    _initializer ??= const _UnlinkedExecutableReader().vTableGet(_bp, 12, null);
+    _initializer ??= const _UnlinkedExecutableReader().vTableGet(_bc, _bcOffset, 12, null);
     return _initializer;
   }
 
   @override
   bool get isFunctionTyped {
-    _isFunctionTyped ??= const fb.BoolReader().vTableGet(_bp, 5, false);
+    _isFunctionTyped ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
     return _isFunctionTyped;
   }
 
   @override
   bool get isInitializingFormal {
-    _isInitializingFormal ??= const fb.BoolReader().vTableGet(_bp, 6, false);
+    _isInitializingFormal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
     return _isInitializingFormal;
   }
 
   @override
   idl.UnlinkedParamKind get kind {
-    _kind ??= const _UnlinkedParamKindReader().vTableGet(_bp, 4, idl.UnlinkedParamKind.required);
+    _kind ??= const _UnlinkedParamKindReader().vTableGet(_bc, _bcOffset, 4, idl.UnlinkedParamKind.required);
     return _kind;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _nameOffset;
   }
 
   @override
   List<idl.UnlinkedParam> get parameters {
-    _parameters ??= const fb.ListReader<idl.UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 8, const <idl.UnlinkedParam>[]);
+    _parameters ??= const fb.ListReader<idl.UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bc, _bcOffset, 8, const <idl.UnlinkedParam>[]);
     return _parameters;
   }
 
   @override
   idl.EntityRef get type {
-    _type ??= const _EntityRefReader().vTableGet(_bp, 3, null);
+    _type ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 3, null);
     return _type;
   }
 
   @override
   int get visibleLength {
-    _visibleLength ??= const fb.Uint32Reader().vTableGet(_bp, 10, 0);
+    _visibleLength ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 10, 0);
     return _visibleLength;
   }
 
   @override
   int get visibleOffset {
-    _visibleOffset ??= const fb.Uint32Reader().vTableGet(_bp, 11, 0);
+    _visibleOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0);
     return _visibleOffset;
   }
 }
@@ -6431,13 +6487,14 @@
   const _UnlinkedPartReader();
 
   @override
-  _UnlinkedPartImpl createObject(fb.BufferPointer bp) => new _UnlinkedPartImpl(bp);
+  _UnlinkedPartImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedPartImpl(bc, offset);
 }
 
 class _UnlinkedPartImpl extends Object with _UnlinkedPartMixin implements idl.UnlinkedPart {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedPartImpl(this._bp);
+  _UnlinkedPartImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   int _uriEnd;
@@ -6445,19 +6502,19 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 2, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   int get uriEnd {
-    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bp, 0, 0);
+    _uriEnd ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 0, 0);
     return _uriEnd;
   }
 
   @override
   int get uriOffset {
-    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _uriOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _uriOffset;
   }
 }
@@ -6587,13 +6644,14 @@
   const _UnlinkedPublicNameReader();
 
   @override
-  _UnlinkedPublicNameImpl createObject(fb.BufferPointer bp) => new _UnlinkedPublicNameImpl(bp);
+  _UnlinkedPublicNameImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedPublicNameImpl(bc, offset);
 }
 
 class _UnlinkedPublicNameImpl extends Object with _UnlinkedPublicNameMixin implements idl.UnlinkedPublicName {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedPublicNameImpl(this._bp);
+  _UnlinkedPublicNameImpl(this._bc, this._bcOffset);
 
   idl.ReferenceKind _kind;
   List<idl.UnlinkedPublicName> _members;
@@ -6602,25 +6660,25 @@
 
   @override
   idl.ReferenceKind get kind {
-    _kind ??= const _ReferenceKindReader().vTableGet(_bp, 1, idl.ReferenceKind.classOrEnum);
+    _kind ??= const _ReferenceKindReader().vTableGet(_bc, _bcOffset, 1, idl.ReferenceKind.classOrEnum);
     return _kind;
   }
 
   @override
   List<idl.UnlinkedPublicName> get members {
-    _members ??= const fb.ListReader<idl.UnlinkedPublicName>(const _UnlinkedPublicNameReader()).vTableGet(_bp, 2, const <idl.UnlinkedPublicName>[]);
+    _members ??= const fb.ListReader<idl.UnlinkedPublicName>(const _UnlinkedPublicNameReader()).vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedPublicName>[]);
     return _members;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get numTypeParameters {
-    _numTypeParameters ??= const fb.Uint32Reader().vTableGet(_bp, 3, 0);
+    _numTypeParameters ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 3, 0);
     return _numTypeParameters;
   }
 }
@@ -6739,21 +6797,22 @@
 }
 
 idl.UnlinkedPublicNamespace readUnlinkedPublicNamespace(List<int> buffer) {
-  fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
-  return const _UnlinkedPublicNamespaceReader().read(rootRef);
+  fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
+  return const _UnlinkedPublicNamespaceReader().read(rootRef, 0);
 }
 
 class _UnlinkedPublicNamespaceReader extends fb.TableReader<_UnlinkedPublicNamespaceImpl> {
   const _UnlinkedPublicNamespaceReader();
 
   @override
-  _UnlinkedPublicNamespaceImpl createObject(fb.BufferPointer bp) => new _UnlinkedPublicNamespaceImpl(bp);
+  _UnlinkedPublicNamespaceImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedPublicNamespaceImpl(bc, offset);
 }
 
 class _UnlinkedPublicNamespaceImpl extends Object with _UnlinkedPublicNamespaceMixin implements idl.UnlinkedPublicNamespace {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedPublicNamespaceImpl(this._bp);
+  _UnlinkedPublicNamespaceImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedExportPublic> _exports;
   List<idl.UnlinkedPublicName> _names;
@@ -6761,19 +6820,19 @@
 
   @override
   List<idl.UnlinkedExportPublic> get exports {
-    _exports ??= const fb.ListReader<idl.UnlinkedExportPublic>(const _UnlinkedExportPublicReader()).vTableGet(_bp, 2, const <idl.UnlinkedExportPublic>[]);
+    _exports ??= const fb.ListReader<idl.UnlinkedExportPublic>(const _UnlinkedExportPublicReader()).vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedExportPublic>[]);
     return _exports;
   }
 
   @override
   List<idl.UnlinkedPublicName> get names {
-    _names ??= const fb.ListReader<idl.UnlinkedPublicName>(const _UnlinkedPublicNameReader()).vTableGet(_bp, 0, const <idl.UnlinkedPublicName>[]);
+    _names ??= const fb.ListReader<idl.UnlinkedPublicName>(const _UnlinkedPublicNameReader()).vTableGet(_bc, _bcOffset, 0, const <idl.UnlinkedPublicName>[]);
     return _names;
   }
 
   @override
   List<String> get parts {
-    _parts ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 1, const <String>[]);
+    _parts ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bc, _bcOffset, 1, const <String>[]);
     return _parts;
   }
 }
@@ -6867,26 +6926,27 @@
   const _UnlinkedReferenceReader();
 
   @override
-  _UnlinkedReferenceImpl createObject(fb.BufferPointer bp) => new _UnlinkedReferenceImpl(bp);
+  _UnlinkedReferenceImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedReferenceImpl(bc, offset);
 }
 
 class _UnlinkedReferenceImpl extends Object with _UnlinkedReferenceMixin implements idl.UnlinkedReference {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedReferenceImpl(this._bp);
+  _UnlinkedReferenceImpl(this._bc, this._bcOffset);
 
   String _name;
   int _prefixReference;
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get prefixReference {
-    _prefixReference ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _prefixReference ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _prefixReference;
   }
 }
@@ -7099,13 +7159,14 @@
   const _UnlinkedTypedefReader();
 
   @override
-  _UnlinkedTypedefImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypedefImpl(bp);
+  _UnlinkedTypedefImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedTypedefImpl(bc, offset);
 }
 
 class _UnlinkedTypedefImpl extends Object with _UnlinkedTypedefMixin implements idl.UnlinkedTypedef {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedTypedefImpl(this._bp);
+  _UnlinkedTypedefImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   idl.CodeRange _codeRange;
@@ -7118,49 +7179,49 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 4, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 4, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   idl.CodeRange get codeRange {
-    _codeRange ??= const _CodeRangeReader().vTableGet(_bp, 7, null);
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 7, null);
     return _codeRange;
   }
 
   @override
   idl.UnlinkedDocumentationComment get documentationComment {
-    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 6, null);
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bc, _bcOffset, 6, null);
     return _documentationComment;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _nameOffset;
   }
 
   @override
   List<idl.UnlinkedParam> get parameters {
-    _parameters ??= const fb.ListReader<idl.UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bp, 3, const <idl.UnlinkedParam>[]);
+    _parameters ??= const fb.ListReader<idl.UnlinkedParam>(const _UnlinkedParamReader()).vTableGet(_bc, _bcOffset, 3, const <idl.UnlinkedParam>[]);
     return _parameters;
   }
 
   @override
   idl.EntityRef get returnType {
-    _returnType ??= const _EntityRefReader().vTableGet(_bp, 2, null);
+    _returnType ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 2, null);
     return _returnType;
   }
 
   @override
   List<idl.UnlinkedTypeParam> get typeParameters {
-    _typeParameters ??= const fb.ListReader<idl.UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bp, 5, const <idl.UnlinkedTypeParam>[]);
+    _typeParameters ??= const fb.ListReader<idl.UnlinkedTypeParam>(const _UnlinkedTypeParamReader()).vTableGet(_bc, _bcOffset, 5, const <idl.UnlinkedTypeParam>[]);
     return _typeParameters;
   }
 }
@@ -7322,13 +7383,14 @@
   const _UnlinkedTypeParamReader();
 
   @override
-  _UnlinkedTypeParamImpl createObject(fb.BufferPointer bp) => new _UnlinkedTypeParamImpl(bp);
+  _UnlinkedTypeParamImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedTypeParamImpl(bc, offset);
 }
 
 class _UnlinkedTypeParamImpl extends Object with _UnlinkedTypeParamMixin implements idl.UnlinkedTypeParam {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedTypeParamImpl(this._bp);
+  _UnlinkedTypeParamImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   idl.EntityRef _bound;
@@ -7338,31 +7400,31 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 3, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 3, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   idl.EntityRef get bound {
-    _bound ??= const _EntityRefReader().vTableGet(_bp, 2, null);
+    _bound ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 2, null);
     return _bound;
   }
 
   @override
   idl.CodeRange get codeRange {
-    _codeRange ??= const _CodeRangeReader().vTableGet(_bp, 4, null);
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 4, null);
     return _codeRange;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _nameOffset;
   }
 }
@@ -7780,21 +7842,22 @@
 }
 
 idl.UnlinkedUnit readUnlinkedUnit(List<int> buffer) {
-  fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);
-  return const _UnlinkedUnitReader().read(rootRef);
+  fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);
+  return const _UnlinkedUnitReader().read(rootRef, 0);
 }
 
 class _UnlinkedUnitReader extends fb.TableReader<_UnlinkedUnitImpl> {
   const _UnlinkedUnitReader();
 
   @override
-  _UnlinkedUnitImpl createObject(fb.BufferPointer bp) => new _UnlinkedUnitImpl(bp);
+  _UnlinkedUnitImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedUnitImpl(bc, offset);
 }
 
 class _UnlinkedUnitImpl extends Object with _UnlinkedUnitMixin implements idl.UnlinkedUnit {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedUnitImpl(this._bp);
+  _UnlinkedUnitImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedClass> _classes;
   idl.CodeRange _codeRange;
@@ -7816,103 +7879,103 @@
 
   @override
   List<idl.UnlinkedClass> get classes {
-    _classes ??= const fb.ListReader<idl.UnlinkedClass>(const _UnlinkedClassReader()).vTableGet(_bp, 2, const <idl.UnlinkedClass>[]);
+    _classes ??= const fb.ListReader<idl.UnlinkedClass>(const _UnlinkedClassReader()).vTableGet(_bc, _bcOffset, 2, const <idl.UnlinkedClass>[]);
     return _classes;
   }
 
   @override
   idl.CodeRange get codeRange {
-    _codeRange ??= const _CodeRangeReader().vTableGet(_bp, 15, null);
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 15, null);
     return _codeRange;
   }
 
   @override
   List<idl.UnlinkedEnum> get enums {
-    _enums ??= const fb.ListReader<idl.UnlinkedEnum>(const _UnlinkedEnumReader()).vTableGet(_bp, 12, const <idl.UnlinkedEnum>[]);
+    _enums ??= const fb.ListReader<idl.UnlinkedEnum>(const _UnlinkedEnumReader()).vTableGet(_bc, _bcOffset, 12, const <idl.UnlinkedEnum>[]);
     return _enums;
   }
 
   @override
   List<idl.UnlinkedExecutable> get executables {
-    _executables ??= const fb.ListReader<idl.UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bp, 4, const <idl.UnlinkedExecutable>[]);
+    _executables ??= const fb.ListReader<idl.UnlinkedExecutable>(const _UnlinkedExecutableReader()).vTableGet(_bc, _bcOffset, 4, const <idl.UnlinkedExecutable>[]);
     return _executables;
   }
 
   @override
   List<idl.UnlinkedExportNonPublic> get exports {
-    _exports ??= const fb.ListReader<idl.UnlinkedExportNonPublic>(const _UnlinkedExportNonPublicReader()).vTableGet(_bp, 13, const <idl.UnlinkedExportNonPublic>[]);
+    _exports ??= const fb.ListReader<idl.UnlinkedExportNonPublic>(const _UnlinkedExportNonPublicReader()).vTableGet(_bc, _bcOffset, 13, const <idl.UnlinkedExportNonPublic>[]);
     return _exports;
   }
 
   @override
   String get fallbackModePath {
-    _fallbackModePath ??= const fb.StringReader().vTableGet(_bp, 16, '');
+    _fallbackModePath ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 16, '');
     return _fallbackModePath;
   }
 
   @override
   List<idl.UnlinkedImport> get imports {
-    _imports ??= const fb.ListReader<idl.UnlinkedImport>(const _UnlinkedImportReader()).vTableGet(_bp, 5, const <idl.UnlinkedImport>[]);
+    _imports ??= const fb.ListReader<idl.UnlinkedImport>(const _UnlinkedImportReader()).vTableGet(_bc, _bcOffset, 5, const <idl.UnlinkedImport>[]);
     return _imports;
   }
 
   @override
   List<idl.UnlinkedConst> get libraryAnnotations {
-    _libraryAnnotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 14, const <idl.UnlinkedConst>[]);
+    _libraryAnnotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 14, const <idl.UnlinkedConst>[]);
     return _libraryAnnotations;
   }
 
   @override
   idl.UnlinkedDocumentationComment get libraryDocumentationComment {
-    _libraryDocumentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 9, null);
+    _libraryDocumentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bc, _bcOffset, 9, null);
     return _libraryDocumentationComment;
   }
 
   @override
   String get libraryName {
-    _libraryName ??= const fb.StringReader().vTableGet(_bp, 6, '');
+    _libraryName ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 6, '');
     return _libraryName;
   }
 
   @override
   int get libraryNameLength {
-    _libraryNameLength ??= const fb.Uint32Reader().vTableGet(_bp, 7, 0);
+    _libraryNameLength ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 7, 0);
     return _libraryNameLength;
   }
 
   @override
   int get libraryNameOffset {
-    _libraryNameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 8, 0);
+    _libraryNameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 8, 0);
     return _libraryNameOffset;
   }
 
   @override
   List<idl.UnlinkedPart> get parts {
-    _parts ??= const fb.ListReader<idl.UnlinkedPart>(const _UnlinkedPartReader()).vTableGet(_bp, 11, const <idl.UnlinkedPart>[]);
+    _parts ??= const fb.ListReader<idl.UnlinkedPart>(const _UnlinkedPartReader()).vTableGet(_bc, _bcOffset, 11, const <idl.UnlinkedPart>[]);
     return _parts;
   }
 
   @override
   idl.UnlinkedPublicNamespace get publicNamespace {
-    _publicNamespace ??= const _UnlinkedPublicNamespaceReader().vTableGet(_bp, 0, null);
+    _publicNamespace ??= const _UnlinkedPublicNamespaceReader().vTableGet(_bc, _bcOffset, 0, null);
     return _publicNamespace;
   }
 
   @override
   List<idl.UnlinkedReference> get references {
-    _references ??= const fb.ListReader<idl.UnlinkedReference>(const _UnlinkedReferenceReader()).vTableGet(_bp, 1, const <idl.UnlinkedReference>[]);
+    _references ??= const fb.ListReader<idl.UnlinkedReference>(const _UnlinkedReferenceReader()).vTableGet(_bc, _bcOffset, 1, const <idl.UnlinkedReference>[]);
     return _references;
   }
 
   @override
   List<idl.UnlinkedTypedef> get typedefs {
-    _typedefs ??= const fb.ListReader<idl.UnlinkedTypedef>(const _UnlinkedTypedefReader()).vTableGet(_bp, 10, const <idl.UnlinkedTypedef>[]);
+    _typedefs ??= const fb.ListReader<idl.UnlinkedTypedef>(const _UnlinkedTypedefReader()).vTableGet(_bc, _bcOffset, 10, const <idl.UnlinkedTypedef>[]);
     return _typedefs;
   }
 
   @override
   List<idl.UnlinkedVariable> get variables {
-    _variables ??= const fb.ListReader<idl.UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bp, 3, const <idl.UnlinkedVariable>[]);
+    _variables ??= const fb.ListReader<idl.UnlinkedVariable>(const _UnlinkedVariableReader()).vTableGet(_bc, _bcOffset, 3, const <idl.UnlinkedVariable>[]);
     return _variables;
   }
 }
@@ -7971,7 +8034,6 @@
 
   List<UnlinkedConstBuilder> _annotations;
   CodeRangeBuilder _codeRange;
-  UnlinkedConstBuilder _constExpr;
   UnlinkedDocumentationCommentBuilder _documentationComment;
   int _inferredTypeSlot;
   UnlinkedExecutableBuilder _initializer;
@@ -8008,19 +8070,6 @@
   }
 
   @override
-  UnlinkedConstBuilder get constExpr => _constExpr;
-
-  /**
-   * If [isConst] is true, and the variable has an initializer, the constant
-   * expression in the initializer.  Note that the presence of this expression
-   * does not mean that it is a valid, check [UnlinkedConst.isInvalid].
-   */
-  void set constExpr(UnlinkedConstBuilder _value) {
-    assert(!_finished);
-    _constExpr = _value;
-  }
-
-  @override
   UnlinkedDocumentationCommentBuilder get documentationComment => _documentationComment;
 
   /**
@@ -8171,10 +8220,9 @@
     _visibleOffset = _value;
   }
 
-  UnlinkedVariableBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, UnlinkedConstBuilder constExpr, UnlinkedDocumentationCommentBuilder documentationComment, int inferredTypeSlot, UnlinkedExecutableBuilder initializer, bool isConst, bool isFinal, bool isStatic, String name, int nameOffset, int propagatedTypeSlot, EntityRefBuilder type, int visibleLength, int visibleOffset})
+  UnlinkedVariableBuilder({List<UnlinkedConstBuilder> annotations, CodeRangeBuilder codeRange, UnlinkedDocumentationCommentBuilder documentationComment, int inferredTypeSlot, UnlinkedExecutableBuilder initializer, bool isConst, bool isFinal, bool isStatic, String name, int nameOffset, int propagatedTypeSlot, EntityRefBuilder type, int visibleLength, int visibleOffset})
     : _annotations = annotations,
       _codeRange = codeRange,
-      _constExpr = constExpr,
       _documentationComment = documentationComment,
       _inferredTypeSlot = inferredTypeSlot,
       _initializer = initializer,
@@ -8194,7 +8242,6 @@
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _codeRange = null;
-    _constExpr?.flushInformative();
     _documentationComment = null;
     _initializer?.flushInformative();
     _nameOffset = null;
@@ -8206,7 +8253,6 @@
     _finished = true;
     fb.Offset offset_annotations;
     fb.Offset offset_codeRange;
-    fb.Offset offset_constExpr;
     fb.Offset offset_documentationComment;
     fb.Offset offset_initializer;
     fb.Offset offset_name;
@@ -8217,9 +8263,6 @@
     if (_codeRange != null) {
       offset_codeRange = _codeRange.finish(fbBuilder);
     }
-    if (_constExpr != null) {
-      offset_constExpr = _constExpr.finish(fbBuilder);
-    }
     if (_documentationComment != null) {
       offset_documentationComment = _documentationComment.finish(fbBuilder);
     }
@@ -8237,10 +8280,7 @@
       fbBuilder.addOffset(8, offset_annotations);
     }
     if (offset_codeRange != null) {
-      fbBuilder.addOffset(14, offset_codeRange);
-    }
-    if (offset_constExpr != null) {
-      fbBuilder.addOffset(5, offset_constExpr);
+      fbBuilder.addOffset(5, offset_codeRange);
     }
     if (offset_documentationComment != null) {
       fbBuilder.addOffset(10, offset_documentationComment);
@@ -8286,17 +8326,17 @@
   const _UnlinkedVariableReader();
 
   @override
-  _UnlinkedVariableImpl createObject(fb.BufferPointer bp) => new _UnlinkedVariableImpl(bp);
+  _UnlinkedVariableImpl createObject(fb.BufferContext bc, int offset) => new _UnlinkedVariableImpl(bc, offset);
 }
 
 class _UnlinkedVariableImpl extends Object with _UnlinkedVariableMixin implements idl.UnlinkedVariable {
-  final fb.BufferPointer _bp;
+  final fb.BufferContext _bc;
+  final int _bcOffset;
 
-  _UnlinkedVariableImpl(this._bp);
+  _UnlinkedVariableImpl(this._bc, this._bcOffset);
 
   List<idl.UnlinkedConst> _annotations;
   idl.CodeRange _codeRange;
-  idl.UnlinkedConst _constExpr;
   idl.UnlinkedDocumentationComment _documentationComment;
   int _inferredTypeSlot;
   idl.UnlinkedExecutable _initializer;
@@ -8312,91 +8352,85 @@
 
   @override
   List<idl.UnlinkedConst> get annotations {
-    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bp, 8, const <idl.UnlinkedConst>[]);
+    _annotations ??= const fb.ListReader<idl.UnlinkedConst>(const _UnlinkedConstReader()).vTableGet(_bc, _bcOffset, 8, const <idl.UnlinkedConst>[]);
     return _annotations;
   }
 
   @override
   idl.CodeRange get codeRange {
-    _codeRange ??= const _CodeRangeReader().vTableGet(_bp, 14, null);
+    _codeRange ??= const _CodeRangeReader().vTableGet(_bc, _bcOffset, 5, null);
     return _codeRange;
   }
 
   @override
-  idl.UnlinkedConst get constExpr {
-    _constExpr ??= const _UnlinkedConstReader().vTableGet(_bp, 5, null);
-    return _constExpr;
-  }
-
-  @override
   idl.UnlinkedDocumentationComment get documentationComment {
-    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bp, 10, null);
+    _documentationComment ??= const _UnlinkedDocumentationCommentReader().vTableGet(_bc, _bcOffset, 10, null);
     return _documentationComment;
   }
 
   @override
   int get inferredTypeSlot {
-    _inferredTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 9, 0);
+    _inferredTypeSlot ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 9, 0);
     return _inferredTypeSlot;
   }
 
   @override
   idl.UnlinkedExecutable get initializer {
-    _initializer ??= const _UnlinkedExecutableReader().vTableGet(_bp, 13, null);
+    _initializer ??= const _UnlinkedExecutableReader().vTableGet(_bc, _bcOffset, 13, null);
     return _initializer;
   }
 
   @override
   bool get isConst {
-    _isConst ??= const fb.BoolReader().vTableGet(_bp, 6, false);
+    _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
     return _isConst;
   }
 
   @override
   bool get isFinal {
-    _isFinal ??= const fb.BoolReader().vTableGet(_bp, 7, false);
+    _isFinal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 7, false);
     return _isFinal;
   }
 
   @override
   bool get isStatic {
-    _isStatic ??= const fb.BoolReader().vTableGet(_bp, 4, false);
+    _isStatic ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 4, false);
     return _isStatic;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bp, 0, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
     return _name;
   }
 
   @override
   int get nameOffset {
-    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bp, 1, 0);
+    _nameOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 1, 0);
     return _nameOffset;
   }
 
   @override
   int get propagatedTypeSlot {
-    _propagatedTypeSlot ??= const fb.Uint32Reader().vTableGet(_bp, 2, 0);
+    _propagatedTypeSlot ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 2, 0);
     return _propagatedTypeSlot;
   }
 
   @override
   idl.EntityRef get type {
-    _type ??= const _EntityRefReader().vTableGet(_bp, 3, null);
+    _type ??= const _EntityRefReader().vTableGet(_bc, _bcOffset, 3, null);
     return _type;
   }
 
   @override
   int get visibleLength {
-    _visibleLength ??= const fb.Uint32Reader().vTableGet(_bp, 11, 0);
+    _visibleLength ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0);
     return _visibleLength;
   }
 
   @override
   int get visibleOffset {
-    _visibleOffset ??= const fb.Uint32Reader().vTableGet(_bp, 12, 0);
+    _visibleOffset ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
     return _visibleOffset;
   }
 }
@@ -8407,7 +8441,6 @@
     Map<String, Object> _result = <String, Object>{};
     if (annotations.isNotEmpty) _result["annotations"] = annotations.map((_value) => _value.toJson()).toList();
     if (codeRange != null) _result["codeRange"] = codeRange.toJson();
-    if (constExpr != null) _result["constExpr"] = constExpr.toJson();
     if (documentationComment != null) _result["documentationComment"] = documentationComment.toJson();
     if (inferredTypeSlot != 0) _result["inferredTypeSlot"] = inferredTypeSlot;
     if (initializer != null) _result["initializer"] = initializer.toJson();
@@ -8427,7 +8460,6 @@
   Map<String, Object> toMap() => {
     "annotations": annotations,
     "codeRange": codeRange,
-    "constExpr": constExpr,
     "documentationComment": documentationComment,
     "inferredTypeSlot": inferredTypeSlot,
     "initializer": initializer,
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 8df99fe..92accd5 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1472,12 +1472,6 @@
  */
 table UnlinkedConstructorInitializer {
   /**
-   * If [kind] is `thisInvocation` or `superInvocation`, the arguments of the
-   * invocation.  Otherwise empty.
-   */
-  arguments:[UnlinkedConst] (id: 3);
-
-  /**
    * If there are `m` [arguments] and `n` [argumentNames], then each argument
    * from [arguments] with index `i` such that `n + i - m >= 0`, should be used
    * with the name at `n + i - m`.
@@ -1485,6 +1479,12 @@
   argumentNames:[string] (id: 4);
 
   /**
+   * If [kind] is `thisInvocation` or `superInvocation`, the arguments of the
+   * invocation.  Otherwise empty.
+   */
+  arguments:[UnlinkedConst] (id: 3);
+
+  /**
    * If [kind] is `field`, the expression of the field initializer.
    * Otherwise `null`.
    */
@@ -1597,6 +1597,13 @@
   annotations:[UnlinkedConst] (id: 6);
 
   /**
+   * If this executable's function body is declared using `=>`, the expression
+   * to the right of the `=>`.  May be omitted if neither type inference nor
+   * constant evaluation depends on the function body.
+   */
+  bodyExpr:UnlinkedConst (id: 29);
+
+  /**
    * Code range of the executable.
    */
   codeRange:CodeRange (id: 26);
@@ -2296,14 +2303,7 @@
   /**
    * Code range of the variable.
    */
-  codeRange:CodeRange (id: 14);
-
-  /**
-   * If [isConst] is true, and the variable has an initializer, the constant
-   * expression in the initializer.  Note that the presence of this expression
-   * does not mean that it is a valid, check [UnlinkedConst.isInvalid].
-   */
-  constExpr:UnlinkedConst (id: 5);
+  codeRange:CodeRange (id: 5);
 
   /**
    * Documentation comment for the variable, or `null` if there is no
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 65b092d..de2ef57 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -41,6 +41,8 @@
  */
 library analyzer.tool.summary.idl;
 
+import 'package:analyzer/dart/element/element.dart';
+
 import 'base.dart' as base;
 import 'base.dart' show Id, TopLevel;
 import 'format.dart' as generated;
@@ -1468,13 +1470,6 @@
  */
 abstract class UnlinkedConstructorInitializer extends base.SummaryClass {
   /**
-   * If [kind] is `thisInvocation` or `superInvocation`, the arguments of the
-   * invocation.  Otherwise empty.
-   */
-  @Id(3)
-  List<UnlinkedConst> get arguments;
-
-  /**
    * If there are `m` [arguments] and `n` [argumentNames], then each argument
    * from [arguments] with index `i` such that `n + i - m >= 0`, should be used
    * with the name at `n + i - m`.
@@ -1483,6 +1478,13 @@
   List<String> get argumentNames;
 
   /**
+   * If [kind] is `thisInvocation` or `superInvocation`, the arguments of the
+   * invocation.  Otherwise empty.
+   */
+  @Id(3)
+  List<UnlinkedConst> get arguments;
+
+  /**
    * If [kind] is `field`, the expression of the field initializer.
    * Otherwise `null`.
    */
@@ -1636,6 +1638,14 @@
   List<UnlinkedConst> get annotations;
 
   /**
+   * If this executable's function body is declared using `=>`, the expression
+   * to the right of the `=>`.  May be omitted if neither type inference nor
+   * constant evaluation depends on the function body.
+   */
+  @Id(29)
+  UnlinkedConst get bodyExpr;
+
+  /**
    * Code range of the executable.
    */
   @informative
@@ -2620,16 +2630,8 @@
    * Code range of the variable.
    */
   @informative
-  @Id(14)
-  CodeRange get codeRange;
-
-  /**
-   * If [isConst] is true, and the variable has an initializer, the constant
-   * expression in the initializer.  Note that the presence of this expression
-   * does not mean that it is a valid, check [UnlinkedConst.isInvalid].
-   */
   @Id(5)
-  UnlinkedConst get constExpr;
+  CodeRange get codeRange;
 
   /**
    * Documentation comment for the variable, or `null` if there is no
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index 6dc797a..ef54267 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -314,6 +314,21 @@
 typedef UnlinkedUnit GetUnitCallback(String absoluteUri);
 
 /**
+ * Stub implementation of [AnalysisOptions] used during linking.
+ */
+class AnalysisOptionsForLink implements AnalysisOptions {
+  final Linker _linker;
+
+  AnalysisOptionsForLink(this._linker);
+
+  @override
+  bool get strongMode => _linker.strongMode;
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
  * Element representing a class or enum resynthesized from a summary
  * during linking.
  */
@@ -346,6 +361,9 @@
   List<ConstructorElementForLink> get constructors;
 
   @override
+  CompilationUnitElementForLink get enclosingUnit => enclosingElement;
+
+  @override
   List<FieldElementForLink> get fields;
 
   /**
@@ -482,6 +500,9 @@
   }
 
   @override
+  ContextForLink get context => enclosingUnit.context;
+
+  @override
   String get displayName => _unlinkedClass.name;
 
   @override
@@ -574,7 +595,8 @@
       return new InterfaceTypeImpl.elementWithNameAndArgs(this, name, () {
         List<DartType> typeArguments = new List<DartType>(numTypeParameters);
         for (int i = 0; i < numTypeParameters; i++) {
-          typeArguments[i] = getTypeArgument(i);
+          typeArguments[i] =
+              getTypeArgument(i) ?? computeDefaultTypeArgument(i);
         }
         return typeArguments;
       });
@@ -814,6 +836,9 @@
   }
 
   @override
+  ContextForLink get context => library.context;
+
+  @override
   LibraryElementForLink get enclosingElement;
 
   @override
@@ -945,6 +970,55 @@
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
+  /**
+   * Return the element referred to by the given [index] in
+   * [UnlinkedUnit.references].  If the reference is unresolved,
+   * return [UndefinedElementForLink.instance].
+   */
+  ReferenceableElementForLink resolveRef(int index) {
+    if (_references[index] == null) {
+      UnlinkedReference unlinkedReference =
+          index < _unlinkedUnit.references.length
+              ? _unlinkedUnit.references[index]
+              : null;
+      LinkedReference linkedReference = _linkedUnit.references[index];
+      String name = unlinkedReference == null
+          ? linkedReference.name
+          : unlinkedReference.name;
+      int containingReference = unlinkedReference == null
+          ? linkedReference.containingReference
+          : unlinkedReference.prefixReference;
+      if (containingReference != 0 &&
+          _linkedUnit.references[containingReference].kind !=
+              ReferenceKind.prefix) {
+        if (linkedReference.kind == ReferenceKind.function) {
+          // Local function
+          _references[index] = resolveRef(containingReference)
+                  .getLocalFunction(linkedReference.localIndex) ??
+              UndefinedElementForLink.instance;
+        } else {
+          _references[index] =
+              resolveRef(containingReference).getContainedName(name);
+        }
+      } else if (linkedReference.dependency == 0) {
+        if (name == 'void') {
+          _references[index] = enclosingElement._linker.voidElement;
+        } else if (name == '*bottom*') {
+          _references[index] = enclosingElement._linker.bottomElement;
+        } else if (name == 'dynamic') {
+          _references[index] = enclosingElement._linker.dynamicElement;
+        } else {
+          _references[index] = enclosingElement.getContainedName(name);
+        }
+      } else {
+        LibraryElementForLink dependency =
+            enclosingElement._getDependency(linkedReference.dependency);
+        _references[index] = dependency.getContainedName(name);
+      }
+    }
+    return _references[index];
+  }
+
   @override
   DartType resolveTypeRef(
       EntityRef type, TypeParameterizedElementMixin typeParameterContext,
@@ -968,11 +1042,14 @@
       DartType getTypeArgument(int i) {
         if (i < type.typeArguments.length) {
           return resolveTypeRef(type.typeArguments[i], typeParameterContext);
-        } else {
+        } else if (!instantiateToBoundsAllowed) {
+          // Do not allow buildType to instantiate the bounds; force dynamic.
           return DynamicTypeImpl.instance;
+        } else {
+          return null;
         }
       }
-      ReferenceableElementForLink element = _resolveRef(type.reference);
+      ReferenceableElementForLink element = resolveRef(type.reference);
       return element.buildType(
           getTypeArgument, type.implicitFunctionTypeIndices);
     }
@@ -980,55 +1057,6 @@
 
   @override
   String toString() => enclosingElement.toString();
-
-  /**
-   * Return the element referred to by the given [index] in
-   * [UnlinkedUnit.references].  If the reference is unresolved,
-   * return [UndefinedElementForLink.instance].
-   */
-  ReferenceableElementForLink _resolveRef(int index) {
-    if (_references[index] == null) {
-      UnlinkedReference unlinkedReference =
-          index < _unlinkedUnit.references.length
-              ? _unlinkedUnit.references[index]
-              : null;
-      LinkedReference linkedReference = _linkedUnit.references[index];
-      String name = unlinkedReference == null
-          ? linkedReference.name
-          : unlinkedReference.name;
-      int containingReference = unlinkedReference == null
-          ? linkedReference.containingReference
-          : unlinkedReference.prefixReference;
-      if (containingReference != 0 &&
-          _linkedUnit.references[containingReference].kind !=
-              ReferenceKind.prefix) {
-        if (linkedReference.kind == ReferenceKind.function) {
-          // Local function
-          _references[index] = _resolveRef(containingReference)
-                  .getLocalFunction(linkedReference.localIndex) ??
-              UndefinedElementForLink.instance;
-        } else {
-          _references[index] =
-              _resolveRef(containingReference).getContainedName(name);
-        }
-      } else if (linkedReference.dependency == 0) {
-        if (name == 'void') {
-          _references[index] = enclosingElement._linker.voidElement;
-        } else if (name == '*bottom*') {
-          _references[index] = enclosingElement._linker.bottomElement;
-        } else if (name == 'dynamic') {
-          _references[index] = enclosingElement._linker.dynamicElement;
-        } else {
-          _references[index] = enclosingElement.getContainedName(name);
-        }
-      } else {
-        LibraryElementForLink dependency =
-            enclosingElement._getDependency(linkedReference.dependency);
-        _references[index] = dependency.getContainedName(name);
-      }
-    }
-    return _references[index];
-  }
 }
 
 /**
@@ -1173,8 +1201,10 @@
           kind: ReferenceKind.topLevelPropertyAccessor);
     } else if (element is FieldElementForLink_ClassField) {
       ClassElementForLink_Class enclosingClass = element.enclosingElement;
-      // TODO(paulberry): do we need to set numTypeParameters to nonzero if the
-      // class has type parameters?
+      // Note: even if the class has type parameters, we don't need to set
+      // numTypeParameters because numTypeParameters does not count type
+      // parameters of parent elements (see
+      // [LinkedReference.numTypeParameters]).
       return addRawReference(element.name,
           containingReference: addReference(enclosingClass),
           kind: ReferenceKind.propertyAccessor);
@@ -1408,7 +1438,7 @@
         constructorElement._unlinkedExecutable.redirectedConstructor;
     if (redirectedConstructor != null) {
       return constructorElement.compilationUnit
-          ._resolveRef(redirectedConstructor.reference)
+          .resolveRef(redirectedConstructor.reference)
           .asConstructor;
     } else {
       return null;
@@ -1467,7 +1497,7 @@
         case UnlinkedConstOperation.invokeMethodRef:
           EntityRef ref = unlinkedConst.references[refPtr++];
           ConstVariableNode variable =
-              compilationUnit._resolveRef(ref.reference).asConstVariable;
+              compilationUnit.resolveRef(ref.reference).asConstVariable;
           if (variable != null) {
             dependencies.add(variable);
           }
@@ -1481,7 +1511,7 @@
         case UnlinkedConstOperation.invokeConstructor:
           EntityRef ref = unlinkedConst.references[refPtr++];
           ConstructorElementForLink element =
-              compilationUnit._resolveRef(ref.reference).asConstructor;
+              compilationUnit.resolveRef(ref.reference).asConstructor;
           if (element?._constNode != null) {
             dependencies.add(element._constNode);
           }
@@ -1600,7 +1630,7 @@
     List<ConstNode> dependencies = <ConstNode>[];
     collectDependencies(
         dependencies,
-        variableElement.unlinkedVariable.constExpr,
+        variableElement.unlinkedVariable.initializer?.bodyExpr,
         variableElement.compilationUnit);
     return dependencies;
   }
@@ -1616,6 +1646,9 @@
   ContextForLink(this._linker);
 
   @override
+  AnalysisOptionsForLink get analysisOptions => _linker.analysisOptions;
+
+  @override
   TypeSystem get typeSystem => _linker.typeSystem;
 
   @override
@@ -1771,6 +1804,9 @@
 
   ExecutableElementForLink(this.compilationUnit, this._unlinkedExecutable);
 
+  @override
+  ContextForLink get context => compilationUnit.context;
+
   /**
    * If the executable element had an explicitly declared return type, return
    * it.  Otherwise return `null`.
@@ -1957,7 +1993,7 @@
     library = unit.enclosingElement;
     linker = library._linker;
     typeProvider = linker.typeProvider;
-    unlinkedConst = variableElement.unlinkedVariable.constExpr;
+    unlinkedConst = variableElement.unlinkedVariable.initializer?.bodyExpr;
   }
 
   DartType compute() {
@@ -2146,7 +2182,8 @@
   void _computePrefixExpressionType(String operatorName) {
     DartType operand = stack.removeLast();
     if (operand is InterfaceType) {
-      MethodElement method = operand.lookUpMethod(operatorName, library);
+      MethodElement method =
+          operand.lookUpInheritedMethod(operatorName, library: library);
       if (method != null) {
         DartType type = method.returnType;
         stack.add(type);
@@ -2232,7 +2269,8 @@
     DartType target = stack.removeLast();
     stack.add(() {
       if (target is InterfaceType) {
-        MethodElement method = target.lookUpMethod('[]', library);
+        MethodElement method =
+            target.lookUpInheritedMethod('[]', library: library);
         if (method != null) {
           return method.returnType;
         }
@@ -2246,14 +2284,15 @@
     String propertyName = _getNextString();
     stack.add(() {
       if (target is InterfaceType) {
-        PropertyAccessorElement getter =
-            target.lookUpGetter(propertyName, library);
-        if (getter != null) {
-          return getter.returnType;
-        }
-        MethodElement method = target.lookUpMethod(propertyName, library);
-        if (method != null) {
-          return method.type;
+        ExecutableElement element = target
+            .lookUpInheritedGetterOrMethod(propertyName, library: library);
+        if (element != null) {
+          if (element is PropertyAccessorElement) {
+            return element.returnType;
+          } else {
+            // Method tear-off
+            return element.type;
+          }
         }
       }
       return DynamicTypeImpl.instance;
@@ -2269,7 +2308,7 @@
     strPtr += numNamed;
     EntityRef ref = _getNextRef();
     ConstructorElementForLink element =
-        unit._resolveRef(ref.reference).asConstructor;
+        unit.resolveRef(ref.reference).asConstructor;
     if (element != null) {
       ClassElementForLink_Class enclosingClass = element.enclosingClass;
       stack.add(enclosingClass.buildType((int i) {
@@ -2277,16 +2316,9 @@
         if (i < ref.typeArguments.length) {
           return unit.resolveTypeRef(
               ref.typeArguments[i], variable._typeParameterContext);
+        } else {
+          return null;
         }
-        // In strong mode, type argument defaults to bound (if any).
-        if (linker.strongMode) {
-          TypeParameterElement typeParameter = enclosingClass.typeParameters[i];
-          if (typeParameter.bound != null) {
-            return typeParameter.bound;
-          }
-        }
-        // Otherwise type argument defaults to `dynamic`.
-        return DynamicTypeImpl.instance;
       }, const []));
     } else {
       stack.add(DynamicTypeImpl.instance);
@@ -2305,7 +2337,8 @@
     DartType target = stack.removeLast();
     stack.add(() {
       if (target is InterfaceType) {
-        MethodElement method = target.lookUpMethod(methodName, library);
+        MethodElement method =
+            target.lookUpInheritedMethod(methodName, library: library);
         FunctionType rawType = method?.type;
         FunctionType inferredType = _inferExecutableType(rawType, numNamed,
             numPositional, namedArgNames, namedArgTypeList, positionalArgTypes);
@@ -2324,7 +2357,7 @@
     List<DartType> namedArgTypeList = _popList(numNamed);
     List<DartType> positionalArgTypes = _popList(numPositional);
     EntityRef ref = _getNextRef();
-    ReferenceableElementForLink element = unit._resolveRef(ref.reference);
+    ReferenceableElementForLink element = unit.resolveRef(ref.reference);
     stack.add(() {
       DartType rawType = element.asStaticType;
       if (rawType is FunctionType) {
@@ -2390,7 +2423,7 @@
       // Nor can implicit function types derived from
       // function-typed parameters.
       assert(ref.implicitFunctionTypeIndices.isEmpty);
-      ReferenceableElementForLink element = unit._resolveRef(ref.reference);
+      ReferenceableElementForLink element = unit.resolveRef(ref.reference);
       stack.add(element.asStaticType);
     }
   }
@@ -2425,7 +2458,9 @@
    */
   DartType _getPropertyType(DartType targetType, String propertyName) {
     return targetType is InterfaceType
-        ? targetType.lookUpGetter(propertyName, library)?.returnType
+        ? targetType
+            .lookUpInheritedGetter(propertyName, library: library)
+            ?.returnType
         : DynamicTypeImpl.instance;
   }
 
@@ -2489,7 +2524,8 @@
   void _pushBinaryOperatorType(
       DartType left, TokenType operator, DartType right) {
     if (left is InterfaceType) {
-      MethodElement method = left.lookUpMethod(operator.lexeme, library);
+      MethodElement method =
+          left.lookUpInheritedMethod(operator.lexeme, library: library);
       if (method != null) {
         DartType type = method.returnType;
         type = linker.typeSystem.refineBinaryExpressionType(
@@ -2860,6 +2896,9 @@
   }
 
   @override
+  ContextForLink get context => enclosingElement.context;
+
+  @override
   TypeParameterizedElementMixin get enclosingTypeParameterContext => null;
 
   @override
@@ -2901,7 +2940,7 @@
     if (numTypeParameters != 0) {
       List<DartType> typeArguments = new List<DartType>(numTypeParameters);
       for (int i = 0; i < numTypeParameters; i++) {
-        typeArguments[i] = getTypeArgument(i);
+        typeArguments[i] = getTypeArgument(i) ?? computeDefaultTypeArgument(i);
       }
       return new FunctionTypeImpl.elementWithNameAndArgs(
           this, name, typeArguments, true);
@@ -2912,6 +2951,9 @@
 
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() => '$enclosingElement.$name';
 }
 
 /**
@@ -3364,6 +3406,7 @@
   SpecialTypeElementForLink _dynamicElement;
   SpecialTypeElementForLink _bottomElement;
   ContextForLink _context;
+  AnalysisOptionsForLink _analysisOptions;
 
   Linker(Map<String, LinkedLibraryBuilder> linkedLibraries, this.getDependency,
       this.getUnit, this.strongMode) {
@@ -3378,6 +3421,12 @@
   }
 
   /**
+   * Get an instance of [AnalysisOptions] for use during linking.
+   */
+  AnalysisOptionsForLink get analysisOptions =>
+      _analysisOptions ??= new AnalysisOptionsForLink(this);
+
+  /**
    * Get the library element for `dart:async`.
    */
   LibraryElementForLink get asyncLibrary =>
@@ -3566,14 +3615,15 @@
     if (_library._linker.strongMode) {
       DartType targetType = _target.asStaticType;
       if (targetType is InterfaceType) {
-        PropertyAccessorElement getter =
-            targetType.lookUpGetter(_name, _library);
-        if (getter != null) {
-          return getter.returnType;
-        }
-        MethodElement method = targetType.lookUpMethod(_name, _library);
-        if (method != null) {
-          return method.type;
+        ExecutableElement element =
+            targetType.lookUpInheritedGetterOrMethod(_name, library: _library);
+        if (element != null) {
+          if (element is PropertyAccessorElement) {
+            return element.returnType;
+          } else {
+            // Method tear-off
+            return element.type;
+          }
         }
       }
       // TODO(paulberry): handle .call on function types and .toString or
@@ -3590,6 +3640,12 @@
   ReferenceableElementForLink getContainedName(String name) {
     return new NonstaticMemberElementForLink(_library, this, name);
   }
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() => '$_target.(dynamic)$_name';
 }
 
 /**
@@ -4053,7 +4109,7 @@
  * When used as a mixin, implements the default behavior shared by most
  * elements.
  */
-class ReferenceableElementForLink {
+abstract class ReferenceableElementForLink implements Element {
   /**
    * If this element can be used in a constructor invocation context,
    * return the associated constructor (which may be `this` or some
@@ -4085,6 +4141,10 @@
    * Return the type indicated by this element when it is used in a
    * type instantiation context.  If this element can't legally be
    * instantiated as a type, return the dynamic type.
+   *
+   * If the type is parameterized, [getTypeArgument] will be called to retrieve
+   * the type parameters.  It should return `null` for unspecified type
+   * parameters.
    */
   DartType buildType(DartType getTypeArgument(int i),
           List<int> implicitFunctionTypeIndices) =>
@@ -4128,6 +4188,12 @@
       DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
     return type;
   }
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() => type.toString();
 }
 
 /**
@@ -4186,6 +4252,9 @@
 
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() => '$enclosingElement.$name';
 }
 
 /**
@@ -4281,7 +4350,7 @@
           // TODO(paulberry): cache these resolved references for
           // later use by evaluate().
           TypeInferenceNode dependency =
-              compilationUnit._resolveRef(ref.reference).asTypeInferenceNode;
+              compilationUnit.resolveRef(ref.reference).asTypeInferenceNode;
           if (dependency != null) {
             dependencies.add(dependency);
           }
@@ -4319,7 +4388,7 @@
     List<TypeInferenceNode> dependencies = <TypeInferenceNode>[];
     collectDependencies(
         dependencies,
-        variableElement.unlinkedVariable.constExpr,
+        variableElement.unlinkedVariable.initializer?.bodyExpr,
         variableElement.compilationUnit);
     return dependencies;
   }
@@ -4491,6 +4560,9 @@
       new UndefinedElementForLink._();
 
   UndefinedElementForLink._();
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 }
 
 /**
@@ -4530,7 +4602,8 @@
   final CompilationUnitElementForLink compilationUnit;
 
   VariableElementForLink(this.unlinkedVariable, this.compilationUnit) {
-    if (compilationUnit.isInBuildUnit && unlinkedVariable.constExpr != null) {
+    if (compilationUnit.isInBuildUnit &&
+        unlinkedVariable.initializer?.bodyExpr != null) {
       _constNode = new ConstVariableNode(this);
       if (unlinkedVariable.type == null) {
         _typeInferenceNode = new TypeInferenceNode(this);
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index dfcaa98..d0d4819 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -62,8 +62,8 @@
    * are the first two elements of the element's location (the library URI and
    * the compilation unit URI).
    */
-  final Map<String, Map<String, CompilationUnitElement>> _resynthesizedUnits =
-      <String, Map<String, CompilationUnitElement>>{};
+  final Map<String, Map<String, CompilationUnitElementImpl>>
+      _resynthesizedUnits = <String, Map<String, CompilationUnitElementImpl>>{};
 
   /**
    * Map of top level elements resynthesized from summaries.  The three map
@@ -125,18 +125,45 @@
       }
       return element;
     } else if (components.length == 3 || components.length == 4) {
-      Map<String, Map<String, Element>> libraryMap =
+      String unitUri = components[1];
+      // Prepare elements-in-units in the library.
+      Map<String, Map<String, Element>> unitsInLibrary =
           _resynthesizedElements[libraryUri];
-      if (libraryMap == null) {
-        getLibraryElement(libraryUri);
-        libraryMap = _resynthesizedElements[libraryUri];
-        assert(libraryMap != null);
+      if (unitsInLibrary == null) {
+        unitsInLibrary = new HashMap<String, Map<String, Element>>();
+        _resynthesizedElements[libraryUri] = unitsInLibrary;
       }
-      Map<String, Element> compilationUnitElements = libraryMap[components[1]];
-      Element element;
-      if (compilationUnitElements != null) {
-        element = compilationUnitElements[components[2]];
+      // Prepare elements in the unit.
+      Map<String, Element> elementsInUnit = unitsInLibrary[unitUri];
+      if (elementsInUnit == null) {
+        // Prepare the CompilationUnitElementImpl.
+        Map<String, CompilationUnitElementImpl> libraryMap =
+            _resynthesizedUnits[libraryUri];
+        if (libraryMap == null) {
+          getLibraryElement(libraryUri);
+          libraryMap = _resynthesizedUnits[libraryUri];
+          assert(libraryMap != null);
+        }
+        CompilationUnitElementImpl unitElement = libraryMap[unitUri];
+        // Fill elements in the unit map.
+        if (unitElement != null) {
+          elementsInUnit = new HashMap<String, Element>();
+          void putElement(Element e) {
+            String id =
+                e is PropertyAccessorElementImpl ? e.identifier : e.name;
+            elementsInUnit[id] = e;
+          }
+          unitElement.accessors.forEach(putElement);
+          unitElement.enums.forEach(putElement);
+          unitElement.functions.forEach(putElement);
+          unitElement.functionTypeAliases.forEach(putElement);
+          unitElement.topLevelVariables.forEach(putElement);
+          unitElement.types.forEach(putElement);
+          unitsInLibrary[unitUri] = elementsInUnit;
+        }
       }
+      // Get the element.
+      Element element = elementsInUnit[components[2]];
       if (element != null && components.length == 4) {
         String name = components[3];
         Element parentElement = element;
@@ -193,7 +220,6 @@
           this, serializedLibrary, serializedUnits, librarySource);
       LibraryElement library = libraryResynthesizer.buildLibrary();
       _resynthesizedUnits[uri] = libraryResynthesizer.resynthesizedUnits;
-      _resynthesizedElements[uri] = libraryResynthesizer.resynthesizedElements;
       return library;
     });
   }
@@ -273,6 +299,7 @@
  */
 class _ConstExprBuilder {
   final _UnitResynthesizer resynthesizer;
+  final ElementImpl context;
   final UnlinkedConst uc;
 
   int intPtr = 0;
@@ -281,7 +308,7 @@
   int refPtr = 0;
   final List<Expression> stack = <Expression>[];
 
-  _ConstExprBuilder(this.resynthesizer, this.uc);
+  _ConstExprBuilder(this.resynthesizer, this.context, this.uc);
 
   Expression build() {
     if (!uc.isValidConst) {
@@ -592,8 +619,8 @@
         throw new StateError('Unsupported element for invokeConstructor '
             '${info.element?.runtimeType}');
       }
-      InterfaceType definingType =
-          resynthesizer._createConstructorDefiningType(info, ref.typeArguments);
+      InterfaceType definingType = resynthesizer._createConstructorDefiningType(
+          context?.typeParameterContext, info, ref.typeArguments);
       constructorElement =
           resynthesizer._createConstructorElement(definingType, info);
       typeNode = _buildTypeAst(definingType);
@@ -1025,16 +1052,8 @@
    * Map of compilation unit elements that have been resynthesized so far.  The
    * key is the URI of the compilation unit.
    */
-  final Map<String, CompilationUnitElement> resynthesizedUnits =
-      <String, CompilationUnitElement>{};
-
-  /**
-   * Map of top level elements that have been resynthesized so far.  The first
-   * key is the URI of the compilation unit; the second is the name of the top
-   * level element.
-   */
-  final Map<String, Map<String, Element>> resynthesizedElements =
-      <String, Map<String, Element>>{};
+  final Map<String, CompilationUnitElementImpl> resynthesizedUnits =
+      <String, CompilationUnitElementImpl>{};
 
   /**
    * Types with implicit type arguments, which are the same as type parameter
@@ -1054,49 +1073,13 @@
    */
   NamespaceCombinator buildCombinator(UnlinkedCombinator serializedCombinator) {
     if (serializedCombinator.shows.isNotEmpty) {
-      ShowElementCombinatorImpl combinator = new ShowElementCombinatorImpl();
-      // Note: we call toList() so that we don't retain a reference to the
-      // deserialized data structure.
-      combinator.shownNames = serializedCombinator.shows.toList();
-      combinator.offset = serializedCombinator.offset;
-      combinator.end = serializedCombinator.end;
-      return combinator;
+      return new ShowElementCombinatorImpl.forSerialized(serializedCombinator);
     } else {
-      HideElementCombinatorImpl combinator = new HideElementCombinatorImpl();
-      // Note: we call toList() so that we don't retain a reference to the
-      // deserialized data structure.
-      combinator.hiddenNames = serializedCombinator.hides.toList();
-      return combinator;
+      return new HideElementCombinatorImpl.forSerialized(serializedCombinator);
     }
   }
 
   /**
-   * Resynthesize an [ExportElement],
-   */
-  ExportElement buildExport(
-      _UnitResynthesizer definingUnitResynthesizer,
-      UnlinkedExportPublic serializedExportPublic,
-      UnlinkedExportNonPublic serializedExportNonPublic) {
-    ExportElementImpl exportElement =
-        new ExportElementImpl(serializedExportNonPublic.offset);
-    String exportedLibraryUri = summaryResynthesizer.sourceFactory
-        .resolveUri(librarySource, serializedExportPublic.uri)
-        .uri
-        .toString();
-    exportElement.exportedLibrary = new LibraryElementHandle(
-        summaryResynthesizer,
-        new ElementLocationImpl.con3(<String>[exportedLibraryUri]));
-    exportElement.uri = serializedExportPublic.uri;
-    exportElement.combinators =
-        serializedExportPublic.combinators.map(buildCombinator).toList();
-    exportElement.uriOffset = serializedExportNonPublic.uriOffset;
-    exportElement.uriEnd = serializedExportNonPublic.uriEnd;
-    definingUnitResynthesizer.buildAnnotations(
-        exportElement, serializedExportNonPublic.annotations);
-    return exportElement;
-  }
-
-  /**
    * Build an [ElementHandle] referring to the entity referred to by the given
    * [exportName].
    */
@@ -1153,68 +1136,22 @@
   }
 
   /**
-   * Resynthesize an [ImportElement].
-   */
-  ImportElement buildImport(
-      _UnitResynthesizer definingUnitResynthesizer,
-      UnlinkedImport serializedImport,
-      int dependency,
-      LibraryElement libraryBeingResynthesized) {
-    bool isSynthetic = serializedImport.isImplicit;
-    ImportElementImpl importElement =
-        new ImportElementImpl(isSynthetic ? -1 : serializedImport.offset);
-    if (dependency == 0) {
-      importElement.importedLibrary = libraryBeingResynthesized;
-    } else {
-      String absoluteUri = summaryResynthesizer.sourceFactory
-          .resolveUri(librarySource, linkedLibrary.dependencies[dependency].uri)
-          .uri
-          .toString();
-      importElement.importedLibrary = new LibraryElementHandle(
-          summaryResynthesizer,
-          new ElementLocationImpl.con3(<String>[absoluteUri]));
-    }
-    if (isSynthetic) {
-      importElement.synthetic = true;
-    } else {
-      importElement.uri = serializedImport.uri;
-      importElement.uriOffset = serializedImport.uriOffset;
-      importElement.uriEnd = serializedImport.uriEnd;
-      importElement.deferred = serializedImport.isDeferred;
-      definingUnitResynthesizer.buildAnnotations(
-          importElement, serializedImport.annotations);
-    }
-    importElement.prefixOffset = serializedImport.prefixOffset;
-    if (serializedImport.prefixReference != 0) {
-      UnlinkedReference serializedPrefix =
-          unlinkedUnits[0].references[serializedImport.prefixReference];
-      importElement.prefix = new PrefixElementImpl(
-          serializedPrefix.name, serializedImport.prefixOffset);
-    }
-    importElement.combinators =
-        serializedImport.combinators.map(buildCombinator).toList();
-    return importElement;
-  }
-
-  /**
    * Main entry point.  Resynthesize the [LibraryElement] and return it.
    */
   LibraryElement buildLibrary() {
     // Create LibraryElementImpl.
     bool hasName = unlinkedUnits[0].libraryName.isNotEmpty;
-    library = new LibraryElementImpl(
+    library = new LibraryElementImpl.forSerialized(
         summaryResynthesizer.context,
         unlinkedUnits[0].libraryName,
         hasName ? unlinkedUnits[0].libraryNameOffset : -1,
-        unlinkedUnits[0].libraryNameLength);
+        unlinkedUnits[0].libraryNameLength,
+        new _LibraryResynthesizerContext(this),
+        unlinkedUnits[0]);
     // Create the defining unit.
     _UnitResynthesizer definingUnitResynthesizer =
         createUnitResynthesizer(0, librarySource, null);
     CompilationUnitElementImpl definingUnit = definingUnitResynthesizer.unit;
-    definingUnitResynthesizer.buildDocumentation(
-        library, unlinkedUnits[0].libraryDocumentationComment);
-    definingUnitResynthesizer.buildAnnotations(
-        library, unlinkedUnits[0].libraryAnnotations);
     library.definingCompilationUnit = definingUnit;
     definingUnit.source = librarySource;
     definingUnit.librarySource = librarySource;
@@ -1232,33 +1169,11 @@
       partResynthesizers.add(partResynthesizer);
     }
     library.parts = partResynthesizers.map((r) => r.unit).toList();
-    // Create imports.
-    List<ImportElement> imports = <ImportElement>[];
-    for (int i = 0; i < unlinkedDefiningUnit.imports.length; i++) {
-      imports.add(buildImport(
-          definingUnitResynthesizer,
-          unlinkedDefiningUnit.imports[i],
-          linkedLibrary.importDependencies[i],
-          library));
-    }
-    library.imports = imports;
-    // Create exports.
-    List<ExportElement> exports = <ExportElement>[];
-    assert(unlinkedDefiningUnit.exports.length ==
-        unlinkedDefiningUnit.publicNamespace.exports.length);
-    for (int i = 0; i < unlinkedDefiningUnit.exports.length; i++) {
-      exports.add(buildExport(
-          definingUnitResynthesizer,
-          unlinkedDefiningUnit.publicNamespace.exports[i],
-          unlinkedDefiningUnit.exports[i]));
-    }
-    library.exports = exports;
     // Populate units.
     populateUnit(definingUnitResynthesizer);
     for (_UnitResynthesizer partResynthesizer in partResynthesizers) {
       populateUnit(partResynthesizer);
     }
-    BuildLibraryElementUtils.patchTopLevelAccessors(library);
     // Update delayed Object class references.
     if (isCoreLibrary) {
       ClassElement objectElement = library.getType('Object');
@@ -1267,18 +1182,6 @@
         classElement.supertype = objectElement.type;
       }
     }
-    // Compute namespaces.
-    library.publicNamespace =
-        new NamespaceBuilder().createPublicNamespaceForLibrary(library);
-    library.exportNamespace = buildExportNamespace(
-        library.publicNamespace, linkedLibrary.exportNames);
-    // Find the entry point.  Note: we can't use element.isEntryPoint because
-    // that will trigger resynthesis of exported libraries.
-    Element entryPoint =
-        library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME);
-    if (entryPoint is FunctionElement) {
-      library.entryPoint = entryPoint;
-    }
     // Create the synthetic element for `loadLibrary`.
     // Until the client received dart:core and dart:async, we cannot do this,
     // because the TypeProvider is not fully initialized. So, it is up to the
@@ -1362,11 +1265,71 @@
    * contained in it.
    */
   void populateUnit(_UnitResynthesizer unitResynthesized) {
-    // TODO(scheglov)
     unitResynthesized.populateUnit();
     String absoluteUri = unitResynthesized.unit.source.uri.toString();
     resynthesizedUnits[absoluteUri] = unitResynthesized.unit;
-    resynthesizedElements[absoluteUri] = unitResynthesized.elementMap;
+  }
+}
+
+/**
+ * Implementation of [LibraryResynthesizerContext] for [_LibraryResynthesizer].
+ */
+class _LibraryResynthesizerContext implements LibraryResynthesizerContext {
+  final _LibraryResynthesizer resynthesizer;
+
+  _LibraryResynthesizerContext(this.resynthesizer);
+
+  @override
+  LinkedLibrary get linkedLibrary => resynthesizer.linkedLibrary;
+
+  @override
+  LibraryElement buildExportedLibrary(String relativeUri) {
+    return _getLibraryByRelativeUri(relativeUri);
+  }
+
+  @override
+  Namespace buildExportNamespace() {
+    LibraryElementImpl library = resynthesizer.library;
+    return resynthesizer.buildExportNamespace(
+        library.publicNamespace, resynthesizer.linkedLibrary.exportNames);
+  }
+
+  @override
+  LibraryElement buildImportedLibrary(int dependency) {
+    String depUri = resynthesizer.linkedLibrary.dependencies[dependency].uri;
+    return _getLibraryByRelativeUri(depUri);
+  }
+
+  @override
+  Namespace buildPublicNamespace() {
+    LibraryElementImpl library = resynthesizer.library;
+    return new NamespaceBuilder().createPublicNamespaceForLibrary(library);
+  }
+
+  @override
+  FunctionElement findEntryPoint() {
+    LibraryElementImpl library = resynthesizer.library;
+    Element entryPoint =
+        library.exportNamespace.get(FunctionElement.MAIN_FUNCTION_NAME);
+    if (entryPoint is FunctionElement) {
+      return entryPoint;
+    }
+    return null;
+  }
+
+  @override
+  void patchTopLevelAccessors() {
+    LibraryElementImpl library = resynthesizer.library;
+    BuildLibraryElementUtils.patchTopLevelAccessors(library);
+  }
+
+  LibraryElementHandle _getLibraryByRelativeUri(String depUri) {
+    String absoluteUri = resynthesizer.summaryResynthesizer.sourceFactory
+        .resolveUri(resynthesizer.librarySource, depUri)
+        .uri
+        .toString();
+    return new LibraryElementHandle(resynthesizer.summaryResynthesizer,
+        new ElementLocationImpl.con3(<String>[absoluteUri]));
   }
 }
 
@@ -1558,13 +1521,28 @@
   _ResynthesizerContext(this._unitResynthesizer);
 
   @override
-  ElementAnnotationImpl buildAnnotation(UnlinkedConst uc) {
-    return _unitResynthesizer.buildAnnotation(uc);
+  ElementAnnotationImpl buildAnnotation(ElementImpl context, UnlinkedConst uc) {
+    return _unitResynthesizer.buildAnnotation(context, uc);
   }
 
   @override
-  Expression buildExpression(UnlinkedConst uc) {
-    return _unitResynthesizer._buildConstExpression(uc);
+  Expression buildExpression(ElementImpl context, UnlinkedConst uc) {
+    return _unitResynthesizer._buildConstExpression(context, uc);
+  }
+
+  @override
+  UnitExplicitTopLevelAccessors buildTopLevelAccessors() {
+    return _unitResynthesizer.buildUnitExplicitTopLevelAccessors();
+  }
+
+  @override
+  List<FunctionElementImpl> buildTopLevelFunctions() {
+    return _unitResynthesizer.buildTopLevelFunctions();
+  }
+
+  @override
+  UnitExplicitTopLevelVariables buildTopLevelVariables() {
+    return _unitResynthesizer.buildUnitExplicitTopLevelVariables();
   }
 
   @override
@@ -1611,12 +1589,6 @@
   final ElementHolder unitHolder = new ElementHolder();
 
   /**
-   * Map of top-level elements that have been resynthesized so far.  The key is
-   * the name of the top level element.
-   */
-  Map<String, Element> elementMap = <String, Element>{};
-
-  /**
    * Map from slot id to the corresponding [EntityRef] object for linked types
    * (i.e. propagated and inferred types).
    */
@@ -1709,9 +1681,9 @@
   /**
    * Build [ElementAnnotationImpl] for the given [UnlinkedConst].
    */
-  ElementAnnotationImpl buildAnnotation(UnlinkedConst uc) {
+  ElementAnnotationImpl buildAnnotation(ElementImpl context, UnlinkedConst uc) {
     ElementAnnotationImpl elementAnnotation = new ElementAnnotationImpl(unit);
-    Expression constExpr = _buildConstExpression(uc);
+    Expression constExpr = _buildConstExpression(context, uc);
     if (constExpr is Identifier) {
       elementAnnotation.element = constExpr.staticElement;
       elementAnnotation.annotationAst = AstFactory.annotation(constExpr);
@@ -1740,7 +1712,9 @@
   void buildAnnotations(
       ElementImpl element, List<UnlinkedConst> serializedAnnotations) {
     if (serializedAnnotations.isNotEmpty) {
-      element.metadata = serializedAnnotations.map(buildAnnotation).toList();
+      element.metadata = serializedAnnotations
+          .map((a) => buildAnnotation(element, a))
+          .toList();
     }
   }
 
@@ -1770,7 +1744,7 @@
     ElementHolder memberHolder = new ElementHolder();
     fields = <String, FieldElementImpl>{};
     for (UnlinkedVariable serializedVariable in serializedClass.fields) {
-      buildVariable(serializedVariable, memberHolder);
+      buildVariable(classElement, serializedVariable, memberHolder);
     }
     bool constructorFound = false;
     constructors = <String, ConstructorElementImpl>{};
@@ -1881,7 +1855,7 @@
 
   /**
    * Resynthesize a [ConstructorElement] and place it in the given [holder].
-   * [classType] is the type of the class for which this element is a
+   * [classElement] is the element of the class for which this element is a
    * constructor.
    */
   void buildConstructor(UnlinkedExecutable serializedExecutable,
@@ -1903,7 +1877,7 @@
     buildExecutableCommonParts(currentConstructor, serializedExecutable);
     currentConstructor.constantInitializers = serializedExecutable
         .constantInitializers
-        .map(buildConstructorInitializer)
+        .map((i) => buildConstructorInitializer(currentConstructor, i))
         .toList();
     if (serializedExecutable.isRedirectedConstructor) {
       if (serializedExecutable.isFactory) {
@@ -1912,7 +1886,8 @@
         _ReferenceInfo info = getReferenceInfo(redirectedConstructor.reference);
         List<EntityRef> typeArguments = redirectedConstructor.typeArguments;
         currentConstructor.redirectedConstructor = _createConstructorElement(
-            _createConstructorDefiningType(info, typeArguments), info);
+            _createConstructorDefiningType(classElement, info, typeArguments),
+            info);
       } else {
         List<String> locationComponents = unit.location.components.toList();
         locationComponents.add(classElement.name);
@@ -1933,6 +1908,7 @@
    * [currentConstructor], which is used to resolve constructor parameter names.
    */
   ConstructorInitializer buildConstructorInitializer(
+      ConstructorElementImpl enclosingConstructor,
       UnlinkedConstructorInitializer serialized) {
     UnlinkedConstructorInitializerKind kind = serialized.kind;
     String name = serialized.name;
@@ -1941,7 +1917,8 @@
       int numArguments = serialized.arguments.length;
       int numNames = serialized.argumentNames.length;
       for (int i = 0; i < numArguments; i++) {
-        Expression expression = _buildConstExpression(serialized.arguments[i]);
+        Expression expression = _buildConstExpression(
+            enclosingConstructor, serialized.arguments[i]);
         int nameIndex = numNames + i - numArguments;
         if (nameIndex >= 0) {
           expression = AstFactory.namedExpression2(
@@ -1952,8 +1929,8 @@
     }
     switch (kind) {
       case UnlinkedConstructorInitializerKind.field:
-        return AstFactory.constructorFieldInitializer(
-            false, name, _buildConstExpression(serialized.expression));
+        return AstFactory.constructorFieldInitializer(false, name,
+            _buildConstExpression(enclosingConstructor, serialized.expression));
       case UnlinkedConstructorInitializerKind.superInvocation:
         return AstFactory.superConstructorInvocation2(
             name.isNotEmpty ? name : null, arguments);
@@ -2059,11 +2036,7 @@
     switch (kind) {
       case UnlinkedExecutableKind.functionOrMethod:
         if (isTopLevel) {
-          FunctionElementImpl executableElement =
-              new FunctionElementImpl.forSerialized(
-                  serializedExecutable, enclosingElement);
-          buildExecutableCommonParts(executableElement, serializedExecutable);
-          holder.addFunction(executableElement);
+          // Created lazily.
         } else {
           MethodElementImpl executableElement =
               new MethodElementImpl.forSerialized(
@@ -2074,6 +2047,11 @@
         break;
       case UnlinkedExecutableKind.getter:
       case UnlinkedExecutableKind.setter:
+        // Top-level accessors are created lazily.
+        if (isTopLevel) {
+          break;
+        }
+        // Class member accessors.
         PropertyAccessorElementImpl executableElement =
             new PropertyAccessorElementImpl.forSerialized(
                 serializedExecutable, enclosingElement);
@@ -2085,19 +2063,13 @@
           type = executableElement.parameters[0].type;
         }
         holder.addAccessor(executableElement);
-        PropertyInducingElementImpl implicitVariable;
-        if (isTopLevel) {
-          implicitVariable = buildImplicitTopLevelVariable(name, kind, holder);
-        } else {
-          FieldElementImpl field = buildImplicitField(name, type, kind, holder);
-          field.static = serializedExecutable.isStatic;
-          implicitVariable = field;
-        }
-        executableElement.variable = implicitVariable;
+        FieldElementImpl field = buildImplicitField(name, type, kind, holder);
+        field.static = serializedExecutable.isStatic;
+        executableElement.variable = field;
         if (kind == UnlinkedExecutableKind.getter) {
-          implicitVariable.getter = executableElement;
+          field.getter = executableElement;
         } else {
-          implicitVariable.setter = executableElement;
+          field.setter = executableElement;
         }
         break;
       default:
@@ -2116,9 +2088,19 @@
       UnlinkedExecutable serializedExecutable) {
     executableElement.typeParameters =
         buildTypeParameters(serializedExecutable.typeParameters);
-    executableElement.parameters = serializedExecutable.parameters
-        .map((p) => buildParameter(p, executableElement))
-        .toList();
+    {
+      List<UnlinkedParam> unlinkedParameters = serializedExecutable.parameters;
+      int length = unlinkedParameters.length;
+      if (length != 0) {
+        List<ParameterElementImpl> parameters =
+            new List<ParameterElementImpl>(length);
+        for (int i = 0; i < length; i++) {
+          parameters[i] =
+              buildParameter(unlinkedParameters[i], executableElement);
+        }
+        executableElement.parameters = parameters;
+      }
+    }
     if (serializedExecutable.kind == UnlinkedExecutableKind.constructor) {
       // Caller handles setting the return type.
       assert(serializedExecutable.returnType == null);
@@ -2134,14 +2116,45 @@
     }
     executableElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
         executableElement, null, getCurrentTypeArguments(skipLevels: 1), false);
-    executableElement.functions = serializedExecutable.localFunctions
-        .map((f) => buildLocalFunction(f, executableElement))
-        .toList();
-    executableElement.labels =
-        serializedExecutable.localLabels.map(buildLocalLabel).toList();
-    executableElement.localVariables = serializedExecutable.localVariables
-        .map((v) => buildLocalVariable(v, executableElement))
-        .toList();
+    {
+      List<UnlinkedExecutable> unlinkedFunctions =
+          serializedExecutable.localFunctions;
+      int length = unlinkedFunctions.length;
+      if (length != 0) {
+        List<FunctionElementImpl> localFunctions =
+            new List<FunctionElementImpl>(length);
+        for (int i = 0; i < length; i++) {
+          localFunctions[i] =
+              buildLocalFunction(unlinkedFunctions[i], executableElement);
+        }
+        executableElement.functions = localFunctions;
+      }
+    }
+    {
+      List<UnlinkedLabel> unlinkedLabels = serializedExecutable.localLabels;
+      int length = unlinkedLabels.length;
+      if (length != 0) {
+        List<LabelElementImpl> localLabels = new List<LabelElementImpl>(length);
+        for (int i = 0; i < length; i++) {
+          localLabels[i] = buildLocalLabel(unlinkedLabels[i]);
+        }
+        executableElement.labels = localLabels;
+      }
+    }
+    {
+      List<UnlinkedVariable> unlinkedVariables =
+          serializedExecutable.localVariables;
+      int length = unlinkedVariables.length;
+      if (length != 0) {
+        List<LocalVariableElementImpl> localVariables =
+            new List<LocalVariableElementImpl>(length);
+        for (int i = 0; i < length; i++) {
+          localVariables[i] =
+              buildLocalVariable(unlinkedVariables[i], executableElement);
+        }
+        executableElement.localVariables = localVariables;
+      }
+    }
     currentTypeParameters.removeLast();
   }
 
@@ -2154,33 +2167,12 @@
     String name = element.name;
     DartType type = element.type;
     PropertyAccessorElementImpl getter =
-        new PropertyAccessorElementImpl(name, element.nameOffset);
-    getter.getter = true;
-    getter.static = element.isStatic;
-    getter.synthetic = true;
-    getter.returnType = type;
-    getter.type = new FunctionTypeImpl(getter);
-    getter.variable = element;
-    getter.hasImplicitReturnType = element.hasImplicitType;
-    holder.addAccessor(getter);
-    element.getter = getter;
+        buildImplicitGetter(element, name, type);
+    holder?.addAccessor(getter);
     if (!(element.isConst || element.isFinal)) {
       PropertyAccessorElementImpl setter =
-          new PropertyAccessorElementImpl(name, element.nameOffset);
-      setter.setter = true;
-      setter.static = element.isStatic;
-      setter.synthetic = true;
-      setter.parameters = <ParameterElement>[
-        new ParameterElementImpl('_$name', element.nameOffset)
-          ..synthetic = true
-          ..type = type
-          ..parameterKind = ParameterKind.REQUIRED
-      ];
-      setter.returnType = VoidTypeImpl.instance;
-      setter.type = new FunctionTypeImpl(setter);
-      setter.variable = element;
-      holder.addAccessor(setter);
-      element.setter = setter;
+          buildImplicitSetter(element, name, type);
+      holder?.addAccessor(setter);
     }
   }
 
@@ -2206,23 +2198,48 @@
   }
 
   /**
-   * Build the implicit top level variable associated with a getter or setter,
-   * and place it in [holder].
+   * Build an implicit getter for the given [property] and bind it to the
+   * [property] and to its enclosing element.
    */
-  PropertyInducingElementImpl buildImplicitTopLevelVariable(
-      String name, UnlinkedExecutableKind kind, ElementHolder holder) {
-    TopLevelVariableElementImpl variable = holder.getTopLevelVariable(name);
-    if (variable == null) {
-      variable = new TopLevelVariableElementImpl(name, -1);
-      variable.synthetic = true;
-      variable.final2 = kind == UnlinkedExecutableKind.getter;
-      holder.addTopLevelVariable(variable);
-      return variable;
-    } else {
-      // TODO(paulberry): what if the getter and setter have a type mismatch?
-      variable.final2 = false;
-      return variable;
-    }
+  PropertyAccessorElementImpl buildImplicitGetter(
+      PropertyInducingElementImpl property, String name, DartType type) {
+    PropertyAccessorElementImpl getter =
+        new PropertyAccessorElementImpl(name, property.nameOffset);
+    getter.enclosingElement = property.enclosingElement;
+    getter.getter = true;
+    getter.static = property.isStatic;
+    getter.synthetic = true;
+    getter.returnType = type;
+    getter.type = new FunctionTypeImpl(getter);
+    getter.variable = property;
+    getter.hasImplicitReturnType = property.hasImplicitType;
+    property.getter = getter;
+    return getter;
+  }
+
+  /**
+   * Build an implicit setter for the given [property] and bind it to the
+   * [property] and to its enclosing element.
+   */
+  PropertyAccessorElementImpl buildImplicitSetter(
+      PropertyInducingElementImpl property, String name, DartType type) {
+    PropertyAccessorElementImpl setter =
+        new PropertyAccessorElementImpl(name, property.nameOffset);
+    setter.enclosingElement = property.enclosingElement;
+    setter.setter = true;
+    setter.static = property.isStatic;
+    setter.synthetic = true;
+    setter.parameters = <ParameterElement>[
+      new ParameterElementImpl('_$name', property.nameOffset)
+        ..synthetic = true
+        ..type = type
+        ..parameterKind = ParameterKind.REQUIRED
+    ];
+    setter.returnType = VoidTypeImpl.instance;
+    setter.type = new FunctionTypeImpl(setter);
+    setter.variable = property;
+    property.setter = setter;
+    return setter;
   }
 
   /**
@@ -2276,13 +2293,14 @@
   LocalVariableElement buildLocalVariable(UnlinkedVariable serializedVariable,
       ExecutableElementImpl enclosingExecutable) {
     LocalVariableElementImpl element;
-    if (serializedVariable.constExpr != null && serializedVariable.isConst) {
+    if (serializedVariable.initializer?.bodyExpr != null &&
+        serializedVariable.isConst) {
       ConstLocalVariableElementImpl constElement =
           new ConstLocalVariableElementImpl.forSerialized(
               serializedVariable, enclosingExecutable);
       element = constElement;
-      constElement.constantInitializer =
-          _buildConstExpression(serializedVariable.constExpr);
+      constElement.constantInitializer = _buildConstExpression(
+          enclosingExecutable, serializedVariable.initializer.bodyExpr);
     } else {
       element = new LocalVariableElementImpl.forSerialized(
           serializedVariable, enclosingExecutable);
@@ -2291,8 +2309,7 @@
       element.setVisibleRange(
           serializedVariable.visibleOffset, serializedVariable.visibleLength);
     }
-    buildVariableCommonParts(element, serializedVariable,
-        isLazilyResynthesized: true);
+    buildVariableCommonParts(element, serializedVariable);
     return element;
   }
 
@@ -2316,8 +2333,8 @@
                 serializedParameter.name, nameOffset);
         initializingParameter = defaultParameter;
         if (serializedParameter.defaultValue != null) {
-          defaultParameter.constantInitializer =
-              _buildConstExpression(serializedParameter.defaultValue);
+          defaultParameter.constantInitializer = _buildConstExpression(
+              enclosingElement, serializedParameter.defaultValue);
           defaultParameter.defaultValueCode =
               serializedParameter.defaultValueCode;
         }
@@ -2412,6 +2429,20 @@
         _currentTypeParameterizedElement);
   }
 
+  List<FunctionElementImpl> buildTopLevelFunctions() {
+    List<FunctionElementImpl> functions = <FunctionElementImpl>[];
+    List<UnlinkedExecutable> executables = unlinkedUnit.executables;
+    for (UnlinkedExecutable unlinkedExecutable in executables) {
+      if (unlinkedExecutable.kind == UnlinkedExecutableKind.functionOrMethod) {
+        FunctionElementImpl function =
+            new FunctionElementImpl.forSerialized(unlinkedExecutable, unit);
+        buildExecutableCommonParts(function, unlinkedExecutable);
+        functions.add(function);
+      }
+    }
+    return functions;
+  }
+
   /**
    * Build a [DartType] object based on a [EntityRef].  This [DartType]
    * may refer to elements in other libraries than the library being
@@ -2508,49 +2539,128 @@
    */
   List<TypeParameterElement> buildTypeParameters(
       List<UnlinkedTypeParam> serializedTypeParameters) {
-    List<TypeParameterElement> typeParameters =
-        serializedTypeParameters.map(buildTypeParameter).toList();
-    currentTypeParameters.add(typeParameters);
-    for (int i = 0; i < serializedTypeParameters.length; i++) {
-      finishTypeParameter(serializedTypeParameters[i], typeParameters[i]);
+    int length = serializedTypeParameters.length;
+    if (length != 0) {
+      List<TypeParameterElement> typeParameters =
+          new List<TypeParameterElement>(length);
+      for (int i = 0; i < length; i++) {
+        typeParameters[i] = buildTypeParameter(serializedTypeParameters[i]);
+      }
+      currentTypeParameters.add(typeParameters);
+      for (int i = 0; i < length; i++) {
+        finishTypeParameter(serializedTypeParameters[i], typeParameters[i]);
+      }
+      return typeParameters;
+    } else {
+      List<TypeParameterElement> typeParameters =
+          const <TypeParameterElement>[];
+      currentTypeParameters.add(typeParameters);
+      return typeParameters;
     }
-    return typeParameters;
+  }
+
+  UnitExplicitTopLevelAccessors buildUnitExplicitTopLevelAccessors() {
+    HashMap<String, TopLevelVariableElementImpl> implicitVariables =
+        new HashMap<String, TopLevelVariableElementImpl>();
+    UnitExplicitTopLevelAccessors accessorsData =
+        new UnitExplicitTopLevelAccessors();
+    for (UnlinkedExecutable unlinkedExecutable in unlinkedUnit.executables) {
+      UnlinkedExecutableKind kind = unlinkedExecutable.kind;
+      if (kind == UnlinkedExecutableKind.getter ||
+          kind == UnlinkedExecutableKind.setter) {
+        // name
+        String name = unlinkedExecutable.name;
+        if (kind == UnlinkedExecutableKind.setter) {
+          assert(name.endsWith('='));
+          name = name.substring(0, name.length - 1);
+        }
+        // create
+        PropertyAccessorElementImpl accessor =
+            new PropertyAccessorElementImpl.forSerialized(
+                unlinkedExecutable, unit);
+        accessorsData.accessors.add(accessor);
+        buildExecutableCommonParts(accessor, unlinkedExecutable);
+        // implicit variable
+        TopLevelVariableElementImpl variable = implicitVariables[name];
+        if (variable == null) {
+          variable = new TopLevelVariableElementImpl(name, -1);
+          variable.enclosingElement = unit;
+          implicitVariables[name] = variable;
+          accessorsData.implicitVariables.add(variable);
+          variable.synthetic = true;
+          variable.final2 = kind == UnlinkedExecutableKind.getter;
+        } else {
+          variable.final2 = false;
+        }
+        accessor.variable = variable;
+        // link
+        if (kind == UnlinkedExecutableKind.getter) {
+          variable.getter = accessor;
+        } else {
+          variable.setter = accessor;
+        }
+      }
+    }
+    return accessorsData;
+  }
+
+  UnitExplicitTopLevelVariables buildUnitExplicitTopLevelVariables() {
+    List<UnlinkedVariable> unlinkedVariables = unlinkedUnit.variables;
+    int numberOfVariables = unlinkedVariables.length;
+    UnitExplicitTopLevelVariables variablesData =
+        new UnitExplicitTopLevelVariables(numberOfVariables);
+    for (int i = 0; i < numberOfVariables; i++) {
+      UnlinkedVariable unlinkedVariable = unlinkedVariables[i];
+      TopLevelVariableElementImpl element;
+      if (unlinkedVariable.initializer?.bodyExpr != null &&
+          unlinkedVariable.isConst) {
+        ConstTopLevelVariableElementImpl constElement =
+            new ConstTopLevelVariableElementImpl.forSerialized(
+                unlinkedVariable, unit);
+        element = constElement;
+        constElement.constantInitializer =
+            _buildConstExpression(null, unlinkedVariable.initializer.bodyExpr);
+      } else {
+        element = new TopLevelVariableElementImpl.forSerialized(
+            unlinkedVariable, unit);
+      }
+      buildPropertyIntroducingElementCommonParts(element, unlinkedVariable);
+      variablesData.variables[i] = element;
+      // implicit accessors
+      String name = element.name;
+      DartType type = element.type;
+      variablesData.implicitAccessors
+          .add(buildImplicitGetter(element, name, type));
+      if (!(element.isConst || element.isFinal)) {
+        variablesData.implicitAccessors
+            .add(buildImplicitSetter(element, name, type));
+      }
+    }
+    return variablesData;
   }
 
   /**
    * Resynthesize a [TopLevelVariableElement] or [FieldElement].
    */
-  void buildVariable(UnlinkedVariable serializedVariable,
+  void buildVariable(
+      ClassElementImpl enclosingClass, UnlinkedVariable serializedVariable,
       [ElementHolder holder]) {
     if (holder == null) {
-      TopLevelVariableElementImpl element;
-      if (serializedVariable.constExpr != null && serializedVariable.isConst) {
-        ConstTopLevelVariableElementImpl constElement =
-            new ConstTopLevelVariableElementImpl(
-                serializedVariable.name, serializedVariable.nameOffset);
-        element = constElement;
-        constElement.constantInitializer =
-            _buildConstExpression(serializedVariable.constExpr);
-      } else {
-        element = new TopLevelVariableElementImpl(
-            serializedVariable.name, serializedVariable.nameOffset);
-      }
-      buildPropertyIntroducingElementCommonParts(element, serializedVariable);
-      unitHolder.addTopLevelVariable(element);
-      buildImplicitAccessors(element, unitHolder);
+      throw new UnimplementedError('Must be lazy');
     } else {
       FieldElementImpl element;
-      if (serializedVariable.constExpr != null &&
+      if (serializedVariable.initializer?.bodyExpr != null &&
           (serializedVariable.isConst ||
               serializedVariable.isFinal && !serializedVariable.isStatic)) {
-        ConstFieldElementImpl constElement = new ConstFieldElementImpl(
-            serializedVariable.name, serializedVariable.nameOffset);
+        ConstFieldElementImpl constElement =
+            new ConstFieldElementImpl.forSerialized(
+                serializedVariable, enclosingClass);
         element = constElement;
-        constElement.constantInitializer =
-            _buildConstExpression(serializedVariable.constExpr);
+        constElement.constantInitializer = _buildConstExpression(
+            enclosingClass, serializedVariable.initializer.bodyExpr);
       } else {
-        element = new FieldElementImpl(
-            serializedVariable.name, serializedVariable.nameOffset);
+        element = new FieldElementImpl.forSerialized(
+            serializedVariable, enclosingClass);
       }
       buildPropertyIntroducingElementCommonParts(element, serializedVariable);
       element.static = serializedVariable.isStatic;
@@ -2564,19 +2674,10 @@
    * Handle the parts that are common to variables.
    */
   void buildVariableCommonParts(
-      VariableElementImpl element, UnlinkedVariable serializedVariable,
-      {bool isLazilyResynthesized: false}) {
+      VariableElementImpl element, UnlinkedVariable serializedVariable) {
     element.type = buildLinkedType(serializedVariable.inferredTypeSlot,
             _currentTypeParameterizedElement) ??
         buildType(serializedVariable.type, _currentTypeParameterizedElement);
-    if (!isLazilyResynthesized) {
-      element.const3 = serializedVariable.isConst;
-      element.final2 = serializedVariable.isFinal;
-      element.hasImplicitType = serializedVariable.type == null;
-      buildDocumentation(element, serializedVariable.documentationComment);
-      buildAnnotations(element, serializedVariable.annotations);
-      buildCodeRange(element, serializedVariable.codeRange);
-    }
     buildVariableInitializer(element, serializedVariable.initializer);
   }
 
@@ -2767,12 +2868,8 @@
   void populateUnit() {
     unlinkedUnit.classes.forEach(buildClass);
     unlinkedUnit.enums.forEach(buildEnum);
-    unlinkedUnit.executables.forEach((e) => buildExecutable(e, unit));
     unlinkedUnit.typedefs.forEach(buildTypedef);
-    unlinkedUnit.variables.forEach(buildVariable);
-    unit.accessors = unitHolder.accessors;
     unit.enums = unitHolder.enums;
-    unit.functions = unitHolder.functions;
     List<FunctionTypeAliasElement> typeAliases = unitHolder.typeAliases;
     for (FunctionTypeAliasElementImpl typeAlias in typeAliases) {
       if (typeAlias.isSynthetic) {
@@ -2781,22 +2878,6 @@
     }
     unit.typeAliases = typeAliases.where((e) => !e.isSynthetic).toList();
     unit.types = unitHolder.types;
-    unit.topLevelVariables = unitHolder.topLevelVariables;
-    for (ClassElement cls in unit.types) {
-      elementMap[cls.name] = cls;
-    }
-    for (ClassElement cls in unit.enums) {
-      elementMap[cls.name] = cls;
-    }
-    for (FunctionTypeAliasElement typeAlias in unit.functionTypeAliases) {
-      elementMap[typeAlias.name] = typeAlias;
-    }
-    for (FunctionElement function in unit.functions) {
-      elementMap[function.name] = function;
-    }
-    for (PropertyAccessorElementImpl accessor in unit.accessors) {
-      elementMap[accessor.identifier] = accessor;
-    }
     assert(currentTypeParameters.isEmpty);
   }
 
@@ -2828,8 +2909,8 @@
     }
   }
 
-  Expression _buildConstExpression(UnlinkedConst uc) {
-    return new _ConstExprBuilder(this, uc).build();
+  Expression _buildConstExpression(ElementImpl context, UnlinkedConst uc) {
+    return new _ConstExprBuilder(this, context, uc).build();
   }
 
   /**
@@ -2837,11 +2918,13 @@
    * [typeArgumentRefs] to the given linked [info].
    */
   InterfaceType _createConstructorDefiningType(
-      _ReferenceInfo info, List<EntityRef> typeArgumentRefs) {
+      TypeParameterizedElementMixin typeParameterContext,
+      _ReferenceInfo info,
+      List<EntityRef> typeArgumentRefs) {
     bool isClass = info.element is ClassElement;
     _ReferenceInfo classInfo = isClass ? info : info.enclosing;
     List<DartType> typeArguments = typeArgumentRefs
-        .map((t) => buildType(t, _currentTypeParameterizedElement))
+        .map((t) => buildType(t, typeParameterContext))
         .toList();
     return classInfo.buildType(true, typeArguments.length, (i) {
       if (i < typeArguments.length) {
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index f5dd314..7c359c3 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -901,7 +901,8 @@
           variables.type == null) {
         Expression initializer = variable.initializer;
         if (initializer != null) {
-          b.constExpr = serializeConstExpr(localClosureIndexMap, initializer);
+          b.initializer.bodyExpr =
+              serializeConstExpr(localClosureIndexMap, initializer);
         }
       }
       if (variable.initializer != null &&
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index cd2adec..432d414 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -1133,11 +1133,15 @@
     b.isConst = variable.isConst;
     b.documentationComment = serializeDocumentation(variable);
     b.annotations = serializeAnnotations(variable);
+    // TODO(scheglov) VariableMember.initializer is not implemented
+    if (variable is! VariableMember && variable.initializer != null) {
+      b.initializer = serializeExecutable(variable.initializer);
+    }
     if (variable is ConstVariableElement) {
       ConstVariableElement constVariable = variable as ConstVariableElement;
       Expression initializer = constVariable.constantInitializer;
       if (initializer != null) {
-        b.constExpr =
+        b.initializer?.bodyExpr =
             serializeConstExpr(variable, variable.initializer, initializer);
       }
     }
@@ -1162,10 +1166,6 @@
         b.visibleLength = visibleRange.length;
       }
     }
-    // TODO(scheglov) VariableMember.initializer is not implemented
-    if (variable is! VariableMember && variable.initializer != null) {
-      b.initializer = serializeExecutable(variable.initializer);
-    }
     return b;
   }
 
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 8c8176a..3d6dc33 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -82,7 +82,7 @@
    * Initialize a newly created manager.
    */
   DartWorkManager(this.context) {
-    analysisCache.onResultInvalidated.listen((InvalidatedResult event) {
+    context.onResultInvalidated.listen((InvalidatedResult event) {
       if (event.descriptor == LIBRARY_ERRORS_READY) {
         CacheEntry entry = event.entry;
         if (entry.explicitlyAdded &&
diff --git a/pkg/analyzer/lib/src/task/driver.dart b/pkg/analyzer/lib/src/task/driver.dart
index b0cabae..70ebe3b 100644
--- a/pkg/analyzer/lib/src/task/driver.dart
+++ b/pkg/analyzer/lib/src/task/driver.dart
@@ -280,7 +280,10 @@
       if (task.caughtException == null) {
         List<TargetedResult> dependedOn = item.inputTargetedResults.toList();
         Map<ResultDescriptor, dynamic> outputs = task.outputs;
-        for (ResultDescriptor result in task.descriptor.results) {
+        List<ResultDescriptor> results = task.descriptor.results;
+        int resultLength = results.length;
+        for (int i = 0; i < resultLength; i++) {
+          ResultDescriptor result = results[i];
           // TODO(brianwilkerson) We could check here that a value was produced
           // and throw an exception if not (unless we want to allow null values).
           entry.setValue(result, outputs[result], dependedOn);
diff --git a/pkg/analyzer/lib/src/task/inputs.dart b/pkg/analyzer/lib/src/task/inputs.dart
index cb497b6..7bc5fa1 100644
--- a/pkg/analyzer/lib/src/task/inputs.dart
+++ b/pkg/analyzer/lib/src/task/inputs.dart
@@ -432,7 +432,7 @@
 
   /**
    * Initialize a newly created task input that computes the input by accessing
-   * the given [result] associated with the given [target].
+   * the given [baseInput] associated with the given [mapper].
    */
   ObjectToListTaskInput(this.baseInput, this.mapper);
 
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 6b0049b..4566e6a 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -992,7 +992,7 @@
         includeParents: false);
   }
 
-  /// Check that individual methods and fields in [subType] correctly override
+  /// Check that individual methods and fields in [node] correctly override
   /// the declarations in [baseType].
   ///
   /// The [errorLocation] node indicates where errors are reported, see
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 70d31aa..2e3d3c0 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -54,7 +54,7 @@
 }
 
 /**
- * A function that returns `true` if the given [variable] passes the filter.
+ * A function that returns `true` if the given [element] passes the filter.
  */
 typedef bool VariableFilter(VariableElement element);
 
@@ -165,7 +165,7 @@
   }
 
   /**
-   * Given a [method], return the type of the parameter in the method that
+   * Given a method, return the type of the parameter in the method that
    * corresponds to the given [parameter]. If the parameter is positional, then
    * it appears at the given [index] in its enclosing element's list of
    * parameters.
diff --git a/pkg/analyzer/lib/src/util/fast_uri.dart b/pkg/analyzer/lib/src/util/fast_uri.dart
new file mode 100644
index 0000000..8af548c
--- /dev/null
+++ b/pkg/analyzer/lib/src/util/fast_uri.dart
@@ -0,0 +1,291 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:collection';
+
+/**
+ * Implementation of [Uri] that understands only a limited set of valid
+ * URI formats, but works fast. In practice Dart code almost always uses such
+ * limited URI format, so almost always can be processed fast.
+ */
+class FastUri implements Uri {
+  /***
+   * The maximum [_cache] length before we flush it and start a new generation.
+   */
+  static const int _MAX_CACHE_LENGTH_BEFORE_FLUSH = 50000;
+
+  static HashMap<String, Uri> _cache = new HashMap<String, Uri>();
+  static int _currentCacheLength = 0;
+  static int _currentCacheGeneration = 0;
+
+  final int _cacheGeneration;
+  final String _text;
+  final String _scheme;
+  final bool _hasEmptyAuthority;
+  final String _path;
+
+  /**
+   * The offset of the last `/` in [_text], or `null` if there isn't any.
+   */
+  final int _lastSlashIndex;
+
+  /**
+   * The cached hashcode.
+   */
+  int _hashCode;
+
+  Uri _cachedFallbackUri;
+
+  FastUri._(this._cacheGeneration, this._text, this._scheme,
+      this._hasEmptyAuthority, this._path, this._lastSlashIndex);
+
+  @override
+  String get authority => '';
+
+  @override
+  UriData get data => null;
+
+  @override
+  String get fragment => '';
+
+  @override
+  bool get hasAbsolutePath => path.startsWith('/');
+
+  @override
+  bool get hasAuthority => _hasEmptyAuthority;
+
+  @override
+  bool get hasEmptyPath => _path.isEmpty;
+
+  @override
+  bool get hasFragment => false;
+
+  @override
+  int get hashCode {
+    // This code is copied from the standard Uri implementation.
+    // It is important that Uri and FastUri generate compatible hashCodes
+    // because Uri and FastUri may be used as keys in the same map.
+    int combine(part, current) {
+      // The sum is truncated to 30 bits to make sure it fits into a Smi.
+      return (current * 31 + part.hashCode) & 0x3FFFFFFF;
+    }
+    return _hashCode ??= combine(
+        scheme,
+        combine(
+            userInfo,
+            combine(
+                host,
+                combine(port,
+                    combine(path, combine(query, combine(fragment, 1)))))));
+  }
+
+  @override
+  bool get hasPort => false;
+
+  @override
+  bool get hasQuery => false;
+
+  @override
+  bool get hasScheme => _scheme.isNotEmpty;
+
+  @override
+  String get host => '';
+
+  @override
+  bool get isAbsolute => hasScheme;
+
+  @override
+  String get origin => _fallbackUri.origin;
+
+  @override
+  String get path => _path;
+
+  @override
+  List<String> get pathSegments => _fallbackUri.pathSegments;
+
+  @override
+  int get port => 0;
+
+  @override
+  String get query => '';
+
+  @override
+  Map<String, String> get queryParameters => const <String, String>{};
+
+  @override
+  Map<String, List<String>> get queryParametersAll =>
+      const <String, List<String>>{};
+
+  @override
+  String get scheme => _scheme;
+
+  @override
+  String get userInfo => '';
+
+  /**
+   * Full [Uri] object computed on demand; we fall back to this for some of the
+   * more complex methods of [Uri] that are less in need of a fast
+   * implementation.
+   */
+  Uri get _fallbackUri => _cachedFallbackUri ??= Uri.parse(_text);
+
+  @override
+  bool operator ==(other) {
+    if (other is FastUri) {
+      if (other._cacheGeneration == _cacheGeneration) {
+        return identical(other, this);
+      }
+      return _text == other._text;
+    } else if (other is Uri) {
+      return _fallbackUri == other;
+    }
+    return false;
+  }
+
+  @override
+  Uri normalizePath() {
+    return this;
+  }
+
+  @override
+  Uri removeFragment() {
+    return this;
+  }
+
+  @override
+  Uri replace(
+      {String scheme,
+      String userInfo,
+      String host,
+      int port,
+      String path,
+      Iterable<String> pathSegments,
+      String query,
+      Map<String, dynamic> queryParameters,
+      String fragment}) {
+    return _fallbackUri.replace(
+        scheme: scheme,
+        userInfo: userInfo,
+        host: host,
+        port: port,
+        path: path,
+        pathSegments: pathSegments,
+        query: query,
+        queryParameters: queryParameters,
+        fragment: fragment);
+  }
+
+  @override
+  Uri resolve(String reference) {
+    // TODO: maybe implement faster
+    return _fallbackUri.resolve(reference);
+  }
+
+  @override
+  Uri resolveUri(Uri reference) {
+    if (reference.hasScheme) {
+      return reference;
+    }
+    String refPath = reference.path;
+    if (refPath.startsWith('./')) {
+      refPath = refPath.substring(2);
+    }
+    if (refPath.startsWith('../') ||
+        refPath.contains('/../') ||
+        refPath.contains('/./')) {
+      Uri slowResult = _fallbackUri.resolveUri(reference);
+      return FastUri.parse(slowResult.toString());
+    }
+    String newText;
+    if (_lastSlashIndex != null) {
+      newText = _text.substring(0, _lastSlashIndex + 1) + refPath;
+    } else {
+      newText = _text + '/' + refPath;
+    }
+    return FastUri.parse(newText);
+  }
+
+  @override
+  String toFilePath({bool windows}) {
+    return _fallbackUri.toFilePath(windows: windows);
+  }
+
+  @override
+  String toString() => _text;
+
+  /**
+   * Parse the given URI [text] and return the corresponding [Uri] instance.  If
+   * the [text] can be represented as a [FastUri], then it is returned.  If the
+   * [text] is more complex, then `dart:core` [Uri] is created and returned.
+   * This method also performs memoization, so that usually the same instance
+   * of [FastUri] or [Uri] is returned for the same [text].
+   */
+  static Uri parse(String text) {
+    Uri uri = _cache[text];
+    if (uri == null) {
+      uri = _parse(text);
+      uri ??= Uri.parse(text);
+      _cache[text] = uri;
+      _currentCacheLength++;
+      // If the cache is too big, start a new generation.
+      if (_currentCacheLength > _MAX_CACHE_LENGTH_BEFORE_FLUSH) {
+        _cache.clear();
+        _currentCacheLength = 0;
+        _currentCacheGeneration++;
+      }
+    }
+    return uri;
+  }
+
+  static bool _isAlphabetic(int char) {
+    return char >= 'A'.codeUnitAt(0) && char <= 'Z'.codeUnitAt(0) ||
+        char >= 'a'.codeUnitAt(0) && char <= 'z'.codeUnitAt(0);
+  }
+
+  static bool _isDigit(int char) {
+    return char >= '0'.codeUnitAt(0) && char <= '9'.codeUnitAt(0);
+  }
+
+  /**
+   * Parse the given [text] into a new [FastUri].  If the [text] uses URI
+   * features that are not supported by [FastUri], return `null`.
+   */
+  static FastUri _parse(String text) {
+    int schemeEnd = null;
+    int pathStart = 0;
+    int lastSlashIndex = null;
+    for (int i = 0; i < text.length; i++) {
+      int char = text.codeUnitAt(i);
+      if (_isAlphabetic(char) ||
+          _isDigit(char) ||
+          char == '.'.codeUnitAt(0) ||
+          char == '-'.codeUnitAt(0) ||
+          char == '_'.codeUnitAt(0)) {
+        // Valid characters.
+      } else if (char == '/'.codeUnitAt(0)) {
+        lastSlashIndex = i;
+      } else if (char == ':'.codeUnitAt(0)) {
+        if (schemeEnd != null) {
+          return null;
+        }
+        schemeEnd = i;
+        pathStart = i + 1;
+      } else {
+        return null;
+      }
+    }
+    String scheme = schemeEnd != null ? text.substring(0, schemeEnd) : '';
+    bool hasEmptyAuthority = false;
+    String path = text.substring(pathStart);
+    if (path.startsWith('//')) {
+      hasEmptyAuthority = true;
+      path = path.substring(2);
+      if (!path.startsWith('/')) {
+        return null;
+      }
+    }
+    return new FastUri._(_currentCacheGeneration, text, scheme,
+        hasEmptyAuthority, path, lastSlashIndex);
+  }
+}
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 541d5fc..2d03ea2 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.27.4-alpha.6
+version: 0.27.4-alpha.7
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 04481ef..c4a47ca 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -3531,6 +3531,10 @@
     _assertFalse("for (;;) { break; }");
   }
 
+  void test_forStatement_implicitTrue_if_break() {
+    _assertFalse("{ for (;;) { if (1==2) { var a = 1; } else { break; } } }");
+  }
+
   void test_forStatement_initialization() {
     _assertTrue("for (i = throw 0;;) {}");
   }
@@ -3852,6 +3856,20 @@
  */
 @reflectiveTest
 class ExitDetectorTest2 extends ResolverTestCase {
+  void test_forStatement_implicitTrue_breakWithLabel() {
+    Source source = addSource(r'''
+void f() {
+  x: for (;;) {
+    if (1 < 2) {
+      break x;
+    }
+    return;
+  }
+}
+''');
+    _assertNthStatementDoesNotExit(source, 0);
+  }
+
   void test_switch_withEnum_false_noDefault() {
     Source source = addSource(r'''
 enum E { A, B }
@@ -3866,12 +3884,7 @@
   return x;
 }
 ''');
-    LibraryElement element = resolve2(source);
-    CompilationUnit unit = resolveCompilationUnit(source, element);
-    FunctionDeclaration function = unit.declarations.last;
-    BlockFunctionBody body = function.functionExpression.body;
-    Statement statement = body.block.statements[1];
-    expect(ExitDetector.exits(statement), false);
+    _assertNthStatementDoesNotExit(source, 1);
   }
 
   void test_switch_withEnum_false_withDefault() {
@@ -3888,12 +3901,7 @@
   return x;
 }
 ''');
-    LibraryElement element = resolve2(source);
-    CompilationUnit unit = resolveCompilationUnit(source, element);
-    FunctionDeclaration function = unit.declarations.last;
-    BlockFunctionBody body = function.functionExpression.body;
-    Statement statement = body.block.statements[1];
-    expect(ExitDetector.exits(statement), false);
+    _assertNthStatementDoesNotExit(source, 1);
   }
 
   void test_switch_withEnum_true_noDefault() {
@@ -3908,12 +3916,7 @@
   }
 }
 ''');
-    LibraryElement element = resolve2(source);
-    CompilationUnit unit = resolveCompilationUnit(source, element);
-    FunctionDeclaration function = unit.declarations.last;
-    BlockFunctionBody body = function.functionExpression.body;
-    Statement statement = body.block.statements[0];
-    expect(ExitDetector.exits(statement), true);
+    _assertNthStatementExits(source, 0);
   }
 
   void test_switch_withEnum_true_withDefault() {
@@ -3928,12 +3931,56 @@
   }
 }
 ''');
+    _assertNthStatementExits(source, 0);
+  }
+
+  void test_whileStatement_breakWithLabel() {
+    Source source = addSource(r'''
+void f() {
+  x: while (true) {
+    if (1 < 2) {
+      break x;
+    }
+    return;
+  }
+}
+''');
+    _assertNthStatementDoesNotExit(source, 0);
+  }
+
+  void test_whileStatement_breakWithLabel_afterExting() {
+    Source source = addSource(r'''
+void f() {
+  x: while (true) {
+    return;
+    if (1 < 2) {
+      break x;
+    }
+  }
+}
+''');
+    _assertNthStatementExits(source, 0);
+  }
+
+  void _assertHasReturn(bool expectedResult, Source source, int n) {
     LibraryElement element = resolve2(source);
     CompilationUnit unit = resolveCompilationUnit(source, element);
     FunctionDeclaration function = unit.declarations.last;
     BlockFunctionBody body = function.functionExpression.body;
-    Statement statement = body.block.statements[0];
-    expect(ExitDetector.exits(statement), true);
+    Statement statement = body.block.statements[n];
+    expect(ExitDetector.exits(statement), expectedResult);
+  }
+
+  // Assert that the [n]th statement in the last function declaration of
+  // [source] exits.
+  void _assertNthStatementExits(Source source, int n) {
+    _assertHasReturn(true, source, n);
+  }
+
+  // Assert that the [n]th statement in the last function declaration of
+  // [source] does not exit.
+  void _assertNthStatementDoesNotExit(Source source, int n) {
+    _assertHasReturn(false, source, n);
   }
 }
 
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index 04560c2..cca5d3b 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -512,17 +512,19 @@
 }
 
 class TestPackageUriResolver extends UriResolver {
-  Map<Uri, Source> sourceMap = new HashMap<Uri, Source>();
+  Map<String, Source> sourceMap = new HashMap<String, Source>();
 
   TestPackageUriResolver(Map<String, String> map) {
     map.forEach((String uri, String contents) {
-      sourceMap[Uri.parse(uri)] =
-          new StringSource(contents, '/test_pkg_source.dart');
+      sourceMap[uri] = new StringSource(contents, '/test_pkg_source.dart');
     });
   }
 
   @override
-  Source resolveAbsolute(Uri uri, [Uri actualUri]) => sourceMap[uri];
+  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
+    String uriString = uri.toString();
+    return sourceMap[uriString];
+  }
 
   @override
   Uri restoreAbsolute(Source source) => throw new UnimplementedError();
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index f922d25..e679466 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -190,11 +190,15 @@
 }
 
 /**
- * Instances of the class `TestAnalysisContext` implement an analysis context in which every
- * method will cause a test to fail when invoked.
+ * An analysis context in which almost every method will cause a test to fail
+ * when invoked.
  */
 class TestAnalysisContext implements InternalAnalysisContext {
   @override
+  final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
+      new ReentrantSynchronousStream<InvalidatedResult>();
+
+  @override
   ResultProvider resultProvider;
 
   @override
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
index 898aa1f..9bc4671 100644
--- a/pkg/analyzer/test/source/embedder_test.dart
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -28,19 +28,20 @@
     });
     test('test_NullEmbedderYamls', () {
       var resolver = new EmbedderUriResolver(null);
-      expect(resolver.length, equals(0));
+      expect(resolver.length, 0);
     });
     test('test_NoEmbedderYamls', () {
       var locator = new EmbedderYamlLocator({
         'fox': [pathTranslator.getResource('/empty')]
       });
-      expect(locator.embedderYamls.length, equals(0));
+      expect(locator.embedderYamls.length, 0);
     });
     test('test_EmbedderYaml', () {
       var locator = new EmbedderYamlLocator({
         'fox': [pathTranslator.getResource('/tmp')]
       });
-      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var resolver =
+          new EmbedderUriResolver(new EmbedderSdk(locator.embedderYamls));
 
       expectResolved(dartUri, posixPath) {
         Source source = resolver.resolveAbsolute(Uri.parse(dartUri));
@@ -48,9 +49,10 @@
         expect(source.fullName, posixToOSPath(posixPath));
       }
 
-      // We have four mappings.
-      expect(resolver.length, equals(4));
+      // We have five mappings.
+      expect(resolver.length, 5);
       // Check that they map to the correct paths.
+      expectResolved('dart:core', '/tmp/core.dart');
       expectResolved('dart:fox', '/tmp/slippy.dart');
       expectResolved('dart:bear', '/tmp/grizzly.dart');
       expectResolved('dart:relative', '/relative.dart');
@@ -59,13 +61,14 @@
     test('test_BadYAML', () {
       var locator = new EmbedderYamlLocator(null);
       locator.addEmbedderYaml(null, r'''{{{,{{}}},}}''');
-      expect(locator.embedderYamls.length, equals(0));
+      expect(locator.embedderYamls.length, 0);
     });
     test('test_restoreAbsolute', () {
       var locator = new EmbedderYamlLocator({
         'fox': [pathTranslator.getResource('/tmp')]
       });
-      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var resolver =
+          new EmbedderUriResolver(new EmbedderSdk(locator.embedderYamls));
 
       expectRestore(String dartUri, [String expected]) {
         var parsedUri = Uri.parse(dartUri);
@@ -75,10 +78,10 @@
         var restoreUri = resolver.restoreAbsolute(source);
         expect(restoreUri, isNotNull, reason: dartUri);
         // Verify that it is 'dart:fox'.
-        expect(restoreUri.toString(), equals(expected ?? dartUri));
+        expect(restoreUri.toString(), expected ?? dartUri);
         List<String> split = (expected ?? dartUri).split(':');
-        expect(restoreUri.scheme, equals(split[0]));
-        expect(restoreUri.path, equals(split[1]));
+        expect(restoreUri.scheme, split[0]);
+        expect(restoreUri.path, split[1]);
       }
 
       expectRestore('dart:deep');
@@ -91,7 +94,8 @@
       var locator = new EmbedderYamlLocator({
         'fox': [pathTranslator.getResource('/tmp')]
       });
-      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var resolver =
+          new EmbedderUriResolver(new EmbedderSdk(locator.embedderYamls));
       var sdk = resolver.dartSdk;
 
       expectSource(String posixPath, String dartUri) {
@@ -110,18 +114,20 @@
       var locator = new EmbedderYamlLocator({
         'fox': [pathTranslator.getResource('/tmp')]
       });
-      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var resolver =
+          new EmbedderUriResolver(new EmbedderSdk(locator.embedderYamls));
       var sdk = resolver.dartSdk;
       var lib = sdk.getSdkLibrary('dart:fox');
       expect(lib, isNotNull);
       expect(lib.path, posixToOSPath('/tmp/slippy.dart'));
-      expect(lib.shortName, 'fox');
+      expect(lib.shortName, 'dart:fox');
     });
     test('test_EmbedderSdk_mapDartUri', () {
       var locator = new EmbedderYamlLocator({
         'fox': [pathTranslator.getResource('/tmp')]
       });
-      var resolver = new EmbedderUriResolver(locator.embedderYamls);
+      var resolver =
+          new EmbedderUriResolver(new EmbedderSdk(locator.embedderYamls));
       var sdk = resolver.dartSdk;
 
       expectSource(String dartUri, String posixPath) {
@@ -131,6 +137,7 @@
         expect(source.fullName, posixToOSPath(posixPath));
       }
 
+      expectSource('dart:core', '/tmp/core.dart');
       expectSource('dart:fox', '/tmp/slippy.dart');
       expectSource('dart:deep', '/tmp/deep/directory/file.dart');
       expectSource('dart:deep/part.dart', '/tmp/deep/directory/part.dart');
@@ -151,6 +158,7 @@
         '/tmp/_embedder.yaml',
         r'''
 embedded_libs:
+  "dart:core" : "core.dart"
   "dart:fox": "slippy.dart"
   "dart:bear": "grizzly.dart"
   "dart:relative": "../relative.dart"
diff --git a/pkg/analyzer/test/src/context/cache_test.dart b/pkg/analyzer/test/src/context/cache_test.dart
index 3c44f09..57ff94e 100644
--- a/pkg/analyzer/test/src/context/cache_test.dart
+++ b/pkg/analyzer/test/src/context/cache_test.dart
@@ -266,6 +266,7 @@
     ResultDescriptor result = new ResultDescriptor('test', null);
     CaughtException exception = new CaughtException(null, null);
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     entry.setErrorState(exception, <ResultDescriptor>[result]);
     entry.fixExceptionState();
     expect(entry.getState(result), CacheState.ERROR);
@@ -352,6 +353,7 @@
     ResultDescriptor result = new ResultDescriptor('test', null);
     CaughtException exception = new CaughtException(null, null);
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     entry.setErrorState(exception, <ResultDescriptor>[result]);
     expect(entry.hasErrorState(), true);
   }
@@ -360,6 +362,7 @@
     AnalysisTarget target = new TestSource();
     ResultDescriptor result = new ResultDescriptor('test', null);
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     entry.setValue(result, 'value', TargetedResult.EMPTY_LIST);
     entry.invalidateAllInformation();
     expect(entry.getState(result), CacheState.INVALID);
@@ -373,6 +376,7 @@
     ResultDescriptor result3 = new ResultDescriptor('res3', 3);
     // prepare some good state
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     entry.setValue(result1, 10, TargetedResult.EMPTY_LIST);
     entry.setValue(result2, 20, TargetedResult.EMPTY_LIST);
     entry.setValue(result3, 30, TargetedResult.EMPTY_LIST);
@@ -460,6 +464,7 @@
     AnalysisTarget target = new TestSource();
     ResultDescriptor result = new ResultDescriptor('test', null);
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     entry.setValue(result, 42, TargetedResult.EMPTY_LIST);
     // an invalid state change
     expect(() {
@@ -474,6 +479,7 @@
     AnalysisTarget target = new TestSource();
     ResultDescriptor result = new ResultDescriptor('test', 1);
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     // set VALID
     entry.setValue(result, 10, TargetedResult.EMPTY_LIST);
     expect(entry.getState(result), CacheState.VALID);
@@ -488,6 +494,7 @@
     AnalysisTarget target = new TestSource();
     ResultDescriptor result = new ResultDescriptor('test', 1);
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     // set VALID
     entry.setValue(result, 10, TargetedResult.EMPTY_LIST);
     expect(entry.getState(result), CacheState.VALID);
@@ -674,6 +681,7 @@
     ResultDescriptor result = new ResultDescriptor('test', null);
     String value = 'value';
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     entry.setValue(result, value, TargetedResult.EMPTY_LIST);
     expect(entry.getState(result), CacheState.VALID);
     expect(entry.getValue(result), value);
@@ -769,6 +777,7 @@
     AnalysisTarget target = new TestSource();
     ResultDescriptor result = new ResultDescriptor('test', null);
     CacheEntry entry = new CacheEntry(target);
+    cache.put(entry);
     entry.setValue(result, 42, TargetedResult.EMPTY_LIST);
     expect(entry.toString(), isNotNull);
   }
diff --git a/pkg/analyzer/test/src/summary/flat_buffers_test.dart b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
index b17dc14..40b0479 100644
--- a/pkg/analyzer/test/src/summary/flat_buffers_test.dart
+++ b/pkg/analyzer/test/src/summary/flat_buffers_test.dart
@@ -109,11 +109,12 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer object = new BufferPointer.fromBytes(byteList).derefObject();
+    BufferContext buffer = new BufferContext.fromBytes(byteList);
+    int objectOffset = buffer.derefObject(0);
     // was not written, so uses the new default value
-    expect(const Int32Reader().vTableGet(object, 0, 15), 15);
+    expect(const Int32Reader().vTableGet(buffer, objectOffset, 0, 15), 15);
     // has the written value
-    expect(const Int32Reader().vTableGet(object, 1, 15), 20);
+    expect(const Int32Reader().vTableGet(buffer, objectOffset, 1, 15), 20);
   }
 
   void test_table_format() {
@@ -149,6 +150,27 @@
     }
   }
 
+  void test_table_string() {
+    String latinString = 'test';
+    String unicodeString = 'Проба пера';
+    List<int> byteList;
+    {
+      Builder builder = new Builder(initialSize: 0);
+      Offset<String> latinStringOffset = builder.writeString(latinString);
+      Offset<String> unicodeStringOffset = builder.writeString(unicodeString);
+      builder.startTable();
+      builder.addOffset(0, latinStringOffset);
+      builder.addOffset(1, unicodeStringOffset);
+      Offset offset = builder.endTable();
+      byteList = builder.finish(offset);
+    }
+    // read and verify
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    int objectOffset = buf.derefObject(0);
+    expect(const StringReader().vTableGet(buf, objectOffset, 0), latinString);
+    expect(const StringReader().vTableGet(buf, objectOffset, 1), unicodeString);
+  }
+
   void test_table_types() {
     List<int> byteList;
     {
@@ -166,14 +188,15 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer object = new BufferPointer.fromBytes(byteList).derefObject();
-    expect(const BoolReader().vTableGet(object, 0), true);
-    expect(const Int8Reader().vTableGet(object, 1), 10);
-    expect(const Int32Reader().vTableGet(object, 2), 20);
-    expect(const StringReader().vTableGet(object, 3), '12345');
-    expect(const Int32Reader().vTableGet(object, 4), 40);
-    expect(const Uint32Reader().vTableGet(object, 5), 0x9ABCDEF0);
-    expect(const Uint8Reader().vTableGet(object, 6), 0x9A);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    int objectOffset = buf.derefObject(0);
+    expect(const BoolReader().vTableGet(buf, objectOffset, 0), true);
+    expect(const Int8Reader().vTableGet(buf, objectOffset, 1), 10);
+    expect(const Int32Reader().vTableGet(buf, objectOffset, 2), 20);
+    expect(const StringReader().vTableGet(buf, objectOffset, 3), '12345');
+    expect(const Int32Reader().vTableGet(buf, objectOffset, 4), 40);
+    expect(const Uint32Reader().vTableGet(buf, objectOffset, 5), 0x9ABCDEF0);
+    expect(const Uint8Reader().vTableGet(buf, objectOffset, 6), 0x9A);
   }
 
   void test_writeList_of_Uint32() {
@@ -186,8 +209,8 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer root = new BufferPointer.fromBytes(byteList);
-    List<int> items = const Uint32ListReader().read(root);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint32ListReader().read(buf, 0);
     expect(items, hasLength(4));
     expect(items, orderedEquals(values));
   }
@@ -206,8 +229,8 @@
         byteList = builder.finish(offset);
       }
       // read and verify
-      BufferPointer root = new BufferPointer.fromBytes(byteList);
-      List<bool> items = const BoolListReader().read(root);
+      BufferContext buf = new BufferContext.fromBytes(byteList);
+      List<bool> items = const BoolListReader().read(buf, 0);
       expect(items, hasLength(len));
       for (int i = 0; i < items.length; i++) {
         expect(items[i], trueBits.contains(i), reason: 'bit $i of $len');
@@ -243,8 +266,8 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer root = new BufferPointer.fromBytes(byteList);
-    List<double> items = const Float64ListReader().read(root);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<double> items = const Float64ListReader().read(buf, 0);
     expect(items, hasLength(5));
     expect(items, orderedEquals(values));
   }
@@ -257,8 +280,8 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer root = new BufferPointer.fromBytes(byteList);
-    List<int> items = const ListReader<int>(const Int32Reader()).read(root);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const ListReader<int>(const Int32Reader()).read(buf, 0);
     expect(items, hasLength(5));
     expect(items, orderedEquals(<int>[1, 2, 3, 4, 5]));
   }
@@ -288,9 +311,9 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
     List<TestPointImpl> items =
-        const ListReader<TestPointImpl>(const TestPointReader()).read(root);
+        const ListReader<TestPointImpl>(const TestPointReader()).read(buf, 0);
     expect(items, hasLength(2));
     expect(items[0].x, 10);
     expect(items[0].y, 20);
@@ -308,9 +331,9 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer root = new BufferPointer.fromBytes(byteList);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
     List<String> items =
-        const ListReader<String>(const StringReader()).read(root);
+        const ListReader<String>(const StringReader()).read(buf, 0);
     expect(items, hasLength(2));
     expect(items, contains('12345'));
     expect(items, contains('ABC'));
@@ -328,8 +351,8 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer root = new BufferPointer.fromBytes(byteList);
-    StringListWrapperImpl reader = new StringListWrapperReader().read(root);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    StringListWrapperImpl reader = new StringListWrapperReader().read(buf, 0);
     List<String> items = reader.items;
     expect(items, hasLength(2));
     expect(items, contains('12345'));
@@ -344,8 +367,8 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer root = new BufferPointer.fromBytes(byteList);
-    List<int> items = const Uint32ListReader().read(root);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint32ListReader().read(buf, 0);
     expect(items, hasLength(3));
     expect(items, orderedEquals(<int>[1, 2, 0x9ABCDEF0]));
   }
@@ -358,46 +381,48 @@
       byteList = builder.finish(offset);
     }
     // read and verify
-    BufferPointer root = new BufferPointer.fromBytes(byteList);
-    List<int> items = const Uint8ListReader().read(root);
+    BufferContext buf = new BufferContext.fromBytes(byteList);
+    List<int> items = const Uint8ListReader().read(buf, 0);
     expect(items, hasLength(5));
     expect(items, orderedEquals(<int>[1, 2, 3, 4, 0x9A]));
   }
 }
 
 class StringListWrapperImpl {
-  final BufferPointer bp;
+  final BufferContext bp;
+  final int offset;
 
-  StringListWrapperImpl(this.bp);
+  StringListWrapperImpl(this.bp, this.offset);
 
   List<String> get items =>
-      const ListReader<String>(const StringReader()).vTableGet(bp, 0);
+      const ListReader<String>(const StringReader()).vTableGet(bp, offset, 0);
 }
 
 class StringListWrapperReader extends TableReader<StringListWrapperImpl> {
   const StringListWrapperReader();
 
   @override
-  StringListWrapperImpl createObject(BufferPointer object) {
-    return new StringListWrapperImpl(object);
+  StringListWrapperImpl createObject(BufferContext object, int offset) {
+    return new StringListWrapperImpl(object, offset);
   }
 }
 
 class TestPointImpl {
-  final BufferPointer bp;
+  final BufferContext bp;
+  final int offset;
 
-  TestPointImpl(this.bp);
+  TestPointImpl(this.bp, this.offset);
 
-  int get x => const Int32Reader().vTableGet(bp, 0, 0);
+  int get x => const Int32Reader().vTableGet(bp, offset, 0, 0);
 
-  int get y => const Int32Reader().vTableGet(bp, 1, 0);
+  int get y => const Int32Reader().vTableGet(bp, offset, 1, 0);
 }
 
 class TestPointReader extends TableReader<TestPointImpl> {
   const TestPointReader();
 
   @override
-  TestPointImpl createObject(BufferPointer object) {
-    return new TestPointImpl(object);
+  TestPointImpl createObject(BufferContext object, int offset) {
+    return new TestPointImpl(object, offset);
   }
 }
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index c067a9e..f64a448 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -508,6 +508,56 @@
         'int');
   }
 
+  void test_instantiate_param_of_param_to_bounds() {
+    createLinker('''
+class C<T> {}
+class D<T extends num> {}
+final x = new C<D>();
+''');
+    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    library.libraryCycleForLink.ensureLinked();
+    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
+    ParameterizedType type1 = x.returnType;
+    expect(type1.element.name, 'C');
+    expect(type1.typeArguments, hasLength(1));
+    ParameterizedType type2 = type1.typeArguments[0];
+    expect(type2.element.name, 'D');
+    expect(type2.typeArguments, hasLength(1));
+    DartType type3 = type2.typeArguments[0];
+    expect(type3.toString(), 'num');
+  }
+
+  void test_instantiate_param_to_bounds_class() {
+    createLinker('''
+class C<T extends num> {}
+final x = new C();
+''');
+    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    library.libraryCycleForLink.ensureLinked();
+    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
+    ParameterizedType type1 = x.returnType;
+    expect(type1.element.name, 'C');
+    expect(type1.typeArguments, hasLength(1));
+    DartType type2 = type1.typeArguments[0];
+    expect(type2.toString(), 'num');
+  }
+
+  void test_instantiate_param_to_bounds_typedef() {
+    createLinker('''
+typedef T F<T extends num>();
+final x = new List<F>();
+''');
+    LibraryElementForLink library = linker.getLibrary(linkerInputs.testDartUri);
+    library.libraryCycleForLink.ensureLinked();
+    PropertyAccessorElementForLink_Variable x = library.getContainedName('x');
+    ParameterizedType type1 = x.returnType;
+    expect(type1.element.name, 'List');
+    expect(type1.typeArguments, hasLength(1));
+    FunctionType type2 = type1.typeArguments[0];
+    expect(type2.element.name, 'F');
+    expect(type2.returnType.toString(), 'num');
+  }
+
   void test_leastUpperBound_functionAndClass() {
     createLinker('''
 class C {}
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index cf9d727..164d8a7 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -511,6 +511,19 @@
     super.test_inferenceInCyclesIsDeterministic();
   }
 
+  @override
+  @failingTest
+  void test_inferredType_opAssignToProperty_prefixedIdentifier() {
+    super.test_inferredType_opAssignToProperty_prefixedIdentifier();
+  }
+
+  @override
+  @failingTest
+  void test_inferredType_opAssignToProperty_prefixedIdentifier_viaInterface() {
+    super
+        .test_inferredType_opAssignToProperty_prefixedIdentifier_viaInterface();
+  }
+
   void test_invokeMethod_notGeneric_genericClass() {
     var unit = checkFile(r'''
 class C<T> {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index e4f296e..b104092 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -110,16 +110,18 @@
     expect(resynthesized.hasExtUri, original.hasExtUri);
     compareCompilationUnitElements(resynthesized.definingCompilationUnit,
         original.definingCompilationUnit);
-    expect(resynthesized.parts.length, original.parts.length);
+    expect(resynthesized.parts.length, original.parts.length, reason: 'parts');
     for (int i = 0; i < resynthesized.parts.length; i++) {
       compareCompilationUnitElements(resynthesized.parts[i], original.parts[i]);
     }
-    expect(resynthesized.imports.length, original.imports.length);
+    expect(resynthesized.imports.length, original.imports.length,
+        reason: 'imports');
     for (int i = 0; i < resynthesized.imports.length; i++) {
       compareImportElements(resynthesized.imports[i], original.imports[i],
           'import ${original.imports[i].uri}');
     }
-    expect(resynthesized.exports.length, original.exports.length);
+    expect(resynthesized.exports.length, original.exports.length,
+        reason: 'exports');
     for (int i = 0; i < resynthesized.exports.length; i++) {
       compareExportElements(resynthesized.exports[i], original.exports[i],
           'export ${original.exports[i].uri}');
@@ -260,13 +262,15 @@
     compareUriReferencedElements(resynthesized, original, desc);
     expect(resynthesized.source, original.source);
     expect(resynthesized.librarySource, original.librarySource);
-    expect(resynthesized.types.length, original.types.length);
+    expect(resynthesized.types.length, original.types.length,
+        reason: '$desc types');
     for (int i = 0; i < resynthesized.types.length; i++) {
       compareClassElements(
           resynthesized.types[i], original.types[i], original.types[i].name);
     }
     expect(resynthesized.topLevelVariables.length,
-        original.topLevelVariables.length);
+        original.topLevelVariables.length,
+        reason: '$desc topLevelVariables');
     for (int i = 0; i < resynthesized.topLevelVariables.length; i++) {
       String name = resynthesized.topLevelVariables[i].name;
       compareTopLevelVariableElements(
@@ -275,25 +279,29 @@
               .singleWhere((TopLevelVariableElement e) => e.name == name),
           'variable $name');
     }
-    expect(resynthesized.functions.length, original.functions.length);
+    expect(resynthesized.functions.length, original.functions.length,
+        reason: '$desc functions');
     for (int i = 0; i < resynthesized.functions.length; i++) {
       compareFunctionElements(resynthesized.functions[i], original.functions[i],
           'function ${original.functions[i].name}');
     }
     expect(resynthesized.functionTypeAliases.length,
-        original.functionTypeAliases.length);
+        original.functionTypeAliases.length,
+        reason: '$desc functionTypeAliases');
     for (int i = 0; i < resynthesized.functionTypeAliases.length; i++) {
       compareFunctionTypeAliasElements(
           resynthesized.functionTypeAliases[i],
           original.functionTypeAliases[i],
           original.functionTypeAliases[i].name);
     }
-    expect(resynthesized.enums.length, original.enums.length);
+    expect(resynthesized.enums.length, original.enums.length,
+        reason: '$desc enums');
     for (int i = 0; i < resynthesized.enums.length; i++) {
       compareClassElements(
           resynthesized.enums[i], original.enums[i], original.enums[i].name);
     }
-    expect(resynthesized.accessors.length, original.accessors.length);
+    expect(resynthesized.accessors.length, original.accessors.length,
+        reason: '$desc accessors');
     for (int i = 0; i < resynthesized.accessors.length; i++) {
       String name = resynthesized.accessors[i].name;
       if (original.accessors[i].isGetter) {
@@ -509,8 +517,13 @@
         expect(rType, isNotNull, reason: desc);
         compareConstAsts(rType.name, oType.name, desc);
         compareConstAsts(rConstructor.name, oConstructor.name, desc);
-        compareConstAstLists(rType.typeArguments?.arguments,
-            oType.typeArguments?.arguments, desc);
+        // In strong mode type inference is performed, so that
+        // `C<int> v = new C();` is serialized as `C<int> v = new C<int>();`.
+        // So, if there are not type arguments originally, not need to check.
+        if (oType.typeArguments?.arguments?.isNotEmpty ?? false) {
+          compareConstAstLists(rType.typeArguments?.arguments,
+              oType.typeArguments?.arguments, desc);
+        }
         compareConstAstLists(
             r.argumentList.arguments, o.argumentList.arguments, desc);
       } else if (o is AnnotationImpl && r is AnnotationImpl) {
@@ -772,15 +785,18 @@
       ImportElementImpl original, String desc) {
     compareUriReferencedElements(resynthesized, original, desc);
     expect(resynthesized.importedLibrary.location,
-        original.importedLibrary.location);
-    expect(resynthesized.prefixOffset, original.prefixOffset);
+        original.importedLibrary.location,
+        reason: '$desc importedLibrary location');
+    expect(resynthesized.prefixOffset, original.prefixOffset,
+        reason: '$desc prefixOffset');
     if (original.prefix == null) {
-      expect(resynthesized.prefix, isNull);
+      expect(resynthesized.prefix, isNull, reason: '$desc prefix');
     } else {
       comparePrefixElements(
           resynthesized.prefix, original.prefix, original.prefix.name);
     }
-    expect(resynthesized.combinators.length, original.combinators.length);
+    expect(resynthesized.combinators.length, original.combinators.length,
+        reason: '$desc combinators');
     for (int i = 0; i < resynthesized.combinators.length; i++) {
       compareNamespaceCombinators(
           resynthesized.combinators[i], original.combinators[i]);
@@ -847,12 +863,14 @@
       NamespaceCombinator resynthesized, NamespaceCombinator original) {
     if (original is ShowElementCombinatorImpl &&
         resynthesized is ShowElementCombinatorImpl) {
-      expect(resynthesized.shownNames, original.shownNames);
-      expect(resynthesized.offset, original.offset);
-      expect(resynthesized.end, original.end);
+      expect(resynthesized.shownNames, original.shownNames,
+          reason: 'shownNames');
+      expect(resynthesized.offset, original.offset, reason: 'offset');
+      expect(resynthesized.end, original.end, reason: 'end');
     } else if (original is HideElementCombinatorImpl &&
         resynthesized is HideElementCombinatorImpl) {
-      expect(resynthesized.hiddenNames, original.hiddenNames);
+      expect(resynthesized.hiddenNames, original.hiddenNames,
+          reason: 'hiddenNames');
     } else if (resynthesized.runtimeType != original.runtimeType) {
       fail(
           'Type mismatch: expected ${original.runtimeType}, got ${resynthesized.runtimeType}');
@@ -1071,9 +1089,10 @@
   void compareUriReferencedElements(UriReferencedElementImpl resynthesized,
       UriReferencedElementImpl original, String desc) {
     compareElements(resynthesized, original, desc);
-    expect(resynthesized.uri, original.uri);
-    expect(resynthesized.uriOffset, original.uriOffset, reason: desc);
-    expect(resynthesized.uriEnd, original.uriEnd, reason: desc);
+    expect(resynthesized.uri, original.uri, reason: '$desc uri');
+    expect(resynthesized.uriOffset, original.uriOffset,
+        reason: '$desc uri uriOffset');
+    expect(resynthesized.uriEnd, original.uriEnd, reason: '$desc uriEnd');
   }
 
   void compareVariableElements(
@@ -2876,6 +2895,71 @@
 ''');
   }
 
+  test_defaultValue_refersToGenericClass_constructor() {
+    checkLibrary('''
+class B<T> {
+  const B();
+}
+class C<T> {
+  const C([B<T> b = const B()]);
+}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_constructor2() {
+    checkLibrary('''
+abstract class A<T> {}
+class B<T> implements A<T> {
+  const B();
+}
+class C<T> implements A<Iterable<T>> {
+  const C([A<T> a = const B()]);
+}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_functionG() {
+    checkLibrary('''
+class B<T> {
+  const B();
+}
+void foo<T>([B<T> b = const B()]) {}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_methodG() {
+    checkLibrary('''
+class B<T> {
+  const B();
+}
+class C {
+  void foo<T>([B<T> b = const B()]) {}
+}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_methodG_classG() {
+    checkLibrary('''
+class B<T1, T2> {
+  const B();
+}
+class C<E1> {
+  void foo<E2>([B<E1, E2> b = const B()]) {}
+}
+''');
+  }
+
+  test_defaultValue_refersToGenericClass_methodNG() {
+    checkLibrary('''
+class B<T> {
+  const B();
+}
+class C<T> {
+  void foo([B<T> b = const B()]) {}
+}
+''');
+  }
+
   test_enum_documented() {
     checkLibrary('''
 // Extra comment so doc comment offset != 0
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 9c50c86..27bebab 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -1484,7 +1484,7 @@
 
   test_constExpr_binary_add() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 + 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.add
@@ -1497,7 +1497,7 @@
   test_constExpr_binary_and() {
     UnlinkedVariable variable =
         serializeVariableText('const v = true && false;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushTrue,
       UnlinkedConstOperation.pushFalse,
       UnlinkedConstOperation.and
@@ -1506,7 +1506,7 @@
 
   test_constExpr_binary_bitAnd() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 & 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.bitAnd
@@ -1518,7 +1518,7 @@
 
   test_constExpr_binary_bitOr() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 | 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.bitOr
@@ -1530,7 +1530,7 @@
 
   test_constExpr_binary_bitShiftLeft() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 << 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.bitShiftLeft
@@ -1542,7 +1542,7 @@
 
   test_constExpr_binary_bitShiftRight() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 >> 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.bitShiftRight
@@ -1554,7 +1554,7 @@
 
   test_constExpr_binary_bitXor() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 ^ 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.bitXor
@@ -1566,7 +1566,7 @@
 
   test_constExpr_binary_divide() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 / 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.divide
@@ -1578,7 +1578,7 @@
 
   test_constExpr_binary_equal() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 == 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.equal
@@ -1590,7 +1590,7 @@
 
   test_constExpr_binary_equal_not() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 != 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.notEqual
@@ -1602,7 +1602,7 @@
 
   test_constExpr_binary_floorDivide() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 ~/ 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.floorDivide
@@ -1614,7 +1614,7 @@
 
   test_constExpr_binary_greater() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 > 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.greater
@@ -1626,7 +1626,7 @@
 
   test_constExpr_binary_greaterEqual() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 >= 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.greaterEqual
@@ -1638,7 +1638,7 @@
 
   test_constExpr_binary_less() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 < 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.less
@@ -1650,7 +1650,7 @@
 
   test_constExpr_binary_lessEqual() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 <= 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.lessEqual
@@ -1662,7 +1662,7 @@
 
   test_constExpr_binary_modulo() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 % 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.modulo
@@ -1674,7 +1674,7 @@
 
   test_constExpr_binary_multiply() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 * 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.multiply
@@ -1687,7 +1687,7 @@
   test_constExpr_binary_or() {
     UnlinkedVariable variable =
         serializeVariableText('const v = false || true;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushFalse,
       UnlinkedConstOperation.pushTrue,
       UnlinkedConstOperation.or
@@ -1696,7 +1696,7 @@
 
   test_constExpr_binary_subtract() {
     UnlinkedVariable variable = serializeVariableText('const v = 1 - 2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.subtract
@@ -1736,7 +1736,7 @@
   test_constExpr_conditional() {
     UnlinkedVariable variable =
         serializeVariableText('const v = true ? 1 : 2;', allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushTrue,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
@@ -1780,20 +1780,24 @@
 const v = foo(5, () => 42);
 foo(a, b) {}
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushLocalFunctionReference,
-      UnlinkedConstOperation.invokeMethodRef
-    ], ints: [
-      5,
-      0,
-      0,
-      0,
-      2
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'foo',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushLocalFunctionReference,
+          UnlinkedConstOperation.invokeMethodRef
+        ],
+        ints: [
+          5,
+          0,
+          0,
+          0,
+          2
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+              expectedKind: ReferenceKind.topLevelFunction)
+        ]);
   }
 
   test_constExpr_functionExpression_asArgument_multiple() {
@@ -1804,23 +1808,27 @@
 const v = foo(5, () => 42, () => 43);
 foo(a, b, c) {}
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushLocalFunctionReference,
-      UnlinkedConstOperation.pushLocalFunctionReference,
-      UnlinkedConstOperation.invokeMethodRef
-    ], ints: [
-      5,
-      0,
-      0,
-      0,
-      1,
-      0,
-      3
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'foo',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushLocalFunctionReference,
+          UnlinkedConstOperation.pushLocalFunctionReference,
+          UnlinkedConstOperation.invokeMethodRef
+        ],
+        ints: [
+          5,
+          0,
+          0,
+          0,
+          1,
+          0,
+          3
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+              expectedKind: ReferenceKind.topLevelFunction)
+        ]);
   }
 
   test_constExpr_functionExpression_inConstructorInitializers() {
@@ -1851,7 +1859,7 @@
 }
 const v = const C<int, String>.named();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -1883,7 +1891,7 @@
 import 'a.dart';
 const v = const C<int, String>.named();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -1917,7 +1925,7 @@
 import 'a.dart' as p;
 const v = const p.C<int, String>.named();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -1947,7 +1955,7 @@
 }
 const v = const C<int, String>();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -1976,7 +1984,7 @@
 import 'a.dart';
 const v = const C<int, String>();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2005,7 +2013,7 @@
 import 'a.dart' as p;
 const v = const p.C<int, String>();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2032,7 +2040,7 @@
 }
 const v = const C.named();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2058,7 +2066,7 @@
 import 'a.dart';
 const v = const C.named();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2085,7 +2093,7 @@
 import 'a.dart' as p;
 const v = const p.C.named();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2112,7 +2120,7 @@
     // Ints: ^pointer 3 4
     // Doubles: ^pointer
     // Strings: ^pointer 'e' 'g' 'f' ''
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushDouble,
@@ -2154,7 +2162,7 @@
 import 'a.dart';
 const v = const C();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2177,7 +2185,7 @@
 import 'a.dart' as p;
 const v = const p.C();
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2198,7 +2206,7 @@
 const v = const C.foo();
 ''',
         allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2219,7 +2227,7 @@
 const v = const C.foo();
 ''',
         allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2247,7 +2255,7 @@
 const v = const p.C.foo();
 ''',
         allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2272,7 +2280,7 @@
 const v = const p.C.foo();
 ''',
         allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2294,7 +2302,7 @@
 const v = const Foo();
 ''',
         allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.invokeConstructor,
     ], ints: [
       0,
@@ -2309,7 +2317,7 @@
   test_constExpr_invokeMethodRef_identical() {
     UnlinkedVariable variable =
         serializeVariableText('const v = identical(42, null);');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushNull,
       UnlinkedConstOperation.invokeMethodRef
@@ -2332,7 +2340,7 @@
 }
 const int v = C.length;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
@@ -2355,7 +2363,7 @@
 import 'a.dart' as p;
 const int v = p.C.length;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
@@ -2373,7 +2381,7 @@
 const String a = 'aaa';
 const int v = a.length;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
@@ -2393,7 +2401,7 @@
 }
 const int v = C.F.length;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
@@ -2416,7 +2424,7 @@
 import 'a.dart';
 const int v = a.length;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
@@ -2440,7 +2448,7 @@
 import 'a.dart' as p;
 const int v = p.a.length;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
@@ -2458,7 +2466,7 @@
   test_constExpr_length_parenthesizedBinaryTarget() {
     UnlinkedVariable variable =
         serializeVariableText('const v = ("abc" + "edf").length;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.add,
@@ -2473,7 +2481,7 @@
   test_constExpr_length_parenthesizedStringTarget() {
     UnlinkedVariable variable =
         serializeVariableText('const v = ("abc").length;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.extractProperty
     ], strings: [
@@ -2485,7 +2493,7 @@
   test_constExpr_length_stringLiteralTarget() {
     UnlinkedVariable variable =
         serializeVariableText('const v = "abc".length;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.extractProperty
     ], strings: [
@@ -2496,14 +2504,14 @@
 
   test_constExpr_makeSymbol() {
     UnlinkedVariable variable = serializeVariableText('const v = #a.bb.ccc;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.makeSymbol], strings: ['a.bb.ccc']);
   }
 
   test_constExpr_makeTypedList() {
     UnlinkedVariable variable =
         serializeVariableText('const v = const <int>[11, 22, 33];');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
@@ -2522,7 +2530,7 @@
   test_constExpr_makeTypedList_dynamic() {
     UnlinkedVariable variable =
         serializeVariableText('const v = const <dynamic>[11, 22, 33];');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
@@ -2540,7 +2548,7 @@
   test_constExpr_makeTypedMap() {
     UnlinkedVariable variable = serializeVariableText(
         'const v = const <int, String>{11: "aaa", 22: "bbb", 33: "ccc"};');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.pushInt,
@@ -2568,7 +2576,7 @@
   test_constExpr_makeTypedMap_dynamic() {
     UnlinkedVariable variable = serializeVariableText(
         'const v = const <dynamic, dynamic>{11: "aaa", 22: "bbb", 33: "ccc"};');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.pushInt,
@@ -2594,7 +2602,7 @@
   test_constExpr_makeUntypedList() {
     UnlinkedVariable variable =
         serializeVariableText('const v = const [11, 22, 33];');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
@@ -2610,7 +2618,7 @@
   test_constExpr_makeUntypedMap() {
     UnlinkedVariable variable = serializeVariableText(
         'const v = const {11: "aaa", 22: "bbb", 33: "ccc"};');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.pushInt,
@@ -2632,7 +2640,7 @@
 
   test_constExpr_parenthesized() {
     UnlinkedVariable variable = serializeVariableText('const v = (1 + 2) * 3;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.add,
@@ -2647,7 +2655,7 @@
 
   test_constExpr_prefix_complement() {
     UnlinkedVariable variable = serializeVariableText('const v = ~2;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.complement
     ], ints: [
@@ -2657,7 +2665,7 @@
 
   test_constExpr_prefix_negate() {
     UnlinkedVariable variable = serializeVariableText('const v = -(2);');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.negate
     ], ints: [
@@ -2667,7 +2675,7 @@
 
   test_constExpr_prefix_not() {
     UnlinkedVariable variable = serializeVariableText('const v = !true;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushTrue,
       UnlinkedConstOperation.not
     ]);
@@ -2675,31 +2683,31 @@
 
   test_constExpr_pushDouble() {
     UnlinkedVariable variable = serializeVariableText('const v = 123.4567;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushDouble], doubles: [123.4567]);
   }
 
   test_constExpr_pushFalse() {
     UnlinkedVariable variable = serializeVariableText('const v = false;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushFalse]);
   }
 
   test_constExpr_pushInt() {
     UnlinkedVariable variable = serializeVariableText('const v = 1;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushInt], ints: [1]);
   }
 
   test_constExpr_pushInt_max() {
     UnlinkedVariable variable = serializeVariableText('const v = 0xFFFFFFFF;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushInt,], ints: [0xFFFFFFFF]);
   }
 
   test_constExpr_pushInt_negative() {
     UnlinkedVariable variable = serializeVariableText('const v = -5;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.negate
     ], ints: [
@@ -2710,27 +2718,27 @@
   test_constExpr_pushLongInt() {
     UnlinkedVariable variable =
         serializeVariableText('const v = 0xA123456789ABCDEF012345678;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushLongInt],
         ints: [4, 0xA, 0x12345678, 0x9ABCDEF0, 0x12345678]);
   }
 
   test_constExpr_pushLongInt_min2() {
     UnlinkedVariable variable = serializeVariableText('const v = 0x100000000;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushLongInt], ints: [2, 1, 0,]);
   }
 
   test_constExpr_pushLongInt_min3() {
     UnlinkedVariable variable =
         serializeVariableText('const v = 0x10000000000000000;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushLongInt], ints: [3, 1, 0, 0,]);
   }
 
   test_constExpr_pushNull() {
     UnlinkedVariable variable = serializeVariableText('const v = null;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushNull]);
   }
 
@@ -2739,7 +2747,7 @@
 class C {}
 const v = C;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'C',
@@ -2752,7 +2760,7 @@
 enum C {V1, V2, V3}
 const v = C;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'C',
@@ -2765,7 +2773,7 @@
 enum C {V1, V2, V3}
 const v = C.V1;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'V1',
@@ -2786,7 +2794,7 @@
 import 'a.dart';
 const v = C.V1;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'V1',
@@ -2803,7 +2811,7 @@
 enum C {V1, V2, V3}
 const v = C.values;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'values',
@@ -2824,7 +2832,7 @@
 import 'a.dart';
 const v = C.values;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'values',
@@ -2843,7 +2851,7 @@
 }
 const v = C.F;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'F',
@@ -2866,7 +2874,7 @@
 import 'a.dart';
 const v = C.F;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'F',
@@ -2890,7 +2898,7 @@
 import 'a.dart' as p;
 const v = p.C.F;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'F',
@@ -2910,7 +2918,7 @@
   static const b = null;
 }
 ''').fields[0];
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'b',
@@ -2928,7 +2936,7 @@
 }
 const v = C.x;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'x',
@@ -2951,7 +2959,7 @@
 import 'a.dart';
 const v = C.x;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'x',
@@ -2975,7 +2983,7 @@
 import 'a.dart' as p;
 const v = p.C.x;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'x',
@@ -2995,7 +3003,7 @@
 }
 const v = C.m;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'm',
@@ -3018,7 +3026,7 @@
 import 'a.dart';
 const v = C.m;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'm',
@@ -3042,7 +3050,7 @@
 import 'a.dart' as p;
 const v = p.C.m;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'm',
@@ -3062,7 +3070,7 @@
   static m() {}
 }
 ''').fields[0];
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'm',
@@ -3078,7 +3086,7 @@
 f() {}
 const v = f;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'f',
@@ -3096,7 +3104,7 @@
 import 'a.dart';
 const v = f;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'f',
@@ -3114,7 +3122,7 @@
 import 'a.dart' as p;
 const v = p.f;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'f',
@@ -3130,7 +3138,7 @@
 int get x => null;
 const v = x;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'x',
@@ -3144,7 +3152,7 @@
 import 'a.dart';
 const v = x;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'x',
@@ -3158,7 +3166,7 @@
 import 'a.dart' as p;
 const v = p.x;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'x',
@@ -3172,7 +3180,7 @@
 const int a = 1;
 const v = a;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'a',
@@ -3186,7 +3194,7 @@
 import 'a.dart';
 const v = a;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
@@ -3200,7 +3208,7 @@
 import 'a.dart' as p;
 const v = p.a;
 ''');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) {
@@ -3219,7 +3227,7 @@
 ''';
     UnlinkedVariable variable =
         serializeClassText(text, allowErrors: true).fields[0];
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) {
@@ -3234,7 +3242,7 @@
 const v = foo;
 ''',
         allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -3250,7 +3258,7 @@
 const v = C.foo;
 ''',
         allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -3274,7 +3282,7 @@
 const v = p.C.foo;
 ''',
         allowErrors: true);
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -3291,14 +3299,14 @@
   test_constExpr_pushString_adjacent() {
     UnlinkedVariable variable =
         serializeVariableText('const v = "aaa" "b" "ccc";');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushString], strings: ['aaabccc']);
   }
 
   test_constExpr_pushString_adjacent_interpolation() {
     UnlinkedVariable variable =
         serializeVariableText(r'const v = "aaa" "bb ${42} bbb" "cccc";');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.pushInt,
@@ -3321,7 +3329,7 @@
   test_constExpr_pushString_interpolation() {
     UnlinkedVariable variable =
         serializeVariableText(r'const v = "aaa ${42} bbb";');
-    _assertUnlinkedConst(variable.constExpr, operators: [
+    _assertUnlinkedConst(variable.initializer.bodyExpr, operators: [
       UnlinkedConstOperation.pushString,
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushString,
@@ -3337,13 +3345,13 @@
 
   test_constExpr_pushString_simple() {
     UnlinkedVariable variable = serializeVariableText('const v = "abc";');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushString], strings: ['abc']);
   }
 
   test_constExpr_pushTrue() {
     UnlinkedVariable variable = serializeVariableText('const v = true;');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushTrue]);
   }
 
@@ -6345,26 +6353,32 @@
 A a = new A();
 final v = (a.b.c.f[1] = 5);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushReference,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToIndex,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      5,
-      1
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'f',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
-                new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
-                new _PrefixExpectation(
-                    ReferenceKind.topLevelPropertyAccessor, 'a')
-              ])
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushReference,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToIndex,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          5,
+          1
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'f',
+                  expectedKind: ReferenceKind.unresolved,
+                  prefixExpectations: [
+                    new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
+                    new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
+                    new _PrefixExpectation(
+                        ReferenceKind.topLevelPropertyAccessor, 'a')
+                  ])
+        ]);
   }
 
   test_expr_assignToIndex_ofIndexExpression() {
@@ -6384,37 +6398,45 @@
 A a = new A();
 final v = (a.b[1].c[2].f[3] = 5);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      // 5
-      UnlinkedConstOperation.pushInt,
-      // a.b[1]
-      UnlinkedConstOperation.pushReference,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.extractIndex,
-      // c[2]
-      UnlinkedConstOperation.extractProperty,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.extractIndex,
-      // f[3] = 5
-      UnlinkedConstOperation.extractProperty,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToIndex,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      5,
-      1,
-      2,
-      3,
-    ], strings: [
-      'c',
-      'f'
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null,
-              'b', expectedKind: ReferenceKind.unresolved, prefixExpectations: [
-            new _PrefixExpectation(ReferenceKind.topLevelPropertyAccessor, 'a')
-          ])
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          // 5
+          UnlinkedConstOperation.pushInt,
+          // a.b[1]
+          UnlinkedConstOperation.pushReference,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.extractIndex,
+          // c[2]
+          UnlinkedConstOperation.extractProperty,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.extractIndex,
+          // f[3] = 5
+          UnlinkedConstOperation.extractProperty,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToIndex,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          5,
+          1,
+          2,
+          3,
+        ],
+        strings: [
+          'c',
+          'f'
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'b',
+                  expectedKind: ReferenceKind.unresolved,
+                  prefixExpectations: [
+                    new _PrefixExpectation(
+                        ReferenceKind.topLevelPropertyAccessor, 'a')
+                  ])
+        ]);
   }
 
   test_expr_assignToIndex_ofTopLevelVariable() {
@@ -6425,20 +6447,26 @@
 List<int> a = <int>[0, 1, 2];
 final v = (a[1] = 5);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushReference,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToIndex,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      5,
-      1,
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushReference,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToIndex,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          5,
+          1,
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'a',
+              expectedKind: ReferenceKind.topLevelPropertyAccessor)
+        ]);
   }
 
   test_expr_assignToProperty_ofInstanceCreation() {
@@ -6451,22 +6479,28 @@
 }
 final v = (new C().f = 5);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.invokeConstructor,
-      UnlinkedConstOperation.assignToProperty,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      5,
-      0,
-      0,
-    ], strings: [
-      'f'
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'C',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.invokeConstructor,
+          UnlinkedConstOperation.assignToProperty,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          5,
+          0,
+          0,
+        ],
+        strings: [
+          'f'
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'C',
+              expectedKind: ReferenceKind.classOrEnum)
+        ]);
   }
 
   test_expr_assignToRef_classStaticField() {
@@ -6479,20 +6513,26 @@
 }
 final v = (C.f = 1);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToRef,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      1,
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'f',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToRef,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          1,
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'f',
+                  expectedKind: ReferenceKind.unresolved,
+                  prefixExpectations: [
+                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+                  ])
+        ]);
   }
 
   test_expr_assignToRef_fieldSequence() {
@@ -6512,23 +6552,29 @@
 A a = new A();
 final v = (a.b.c.f = 1);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToRef,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      1,
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'f',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
-                new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
-                new _PrefixExpectation(
-                    ReferenceKind.topLevelPropertyAccessor, 'a')
-              ])
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToRef,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          1,
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'f',
+                  expectedKind: ReferenceKind.unresolved,
+                  prefixExpectations: [
+                    new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
+                    new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
+                    new _PrefixExpectation(
+                        ReferenceKind.topLevelPropertyAccessor, 'a')
+                  ])
+        ]);
   }
 
   test_expr_assignToRef_postfixDecrement() {
@@ -6559,17 +6605,23 @@
 int a = 0;
 final v = (a = 1);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToRef,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      1,
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToRef,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          1,
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'a',
+              expectedKind: ReferenceKind.topLevelPropertyAccessor)
+        ]);
   }
 
   test_expr_assignToRef_topLevelVariable_imported() {
@@ -6585,17 +6637,23 @@
 import 'a.dart';
 final v = (a = 1);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToRef,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      1,
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToRef,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          1,
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
+              expectedKind: ReferenceKind.topLevelPropertyAccessor)
+        ]);
   }
 
   test_expr_assignToRef_topLevelVariable_imported_withPrefix() {
@@ -6611,20 +6669,26 @@
 import 'a.dart' as p;
 final v = (p.a = 1);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToRef,
-    ], assignmentOperators: [
-      (UnlinkedExprAssignOperator.assign)
-    ], ints: [
-      1,
-    ], strings: [], referenceValidators: [
-      (EntityRef r) {
-        return checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
-            expectedKind: ReferenceKind.topLevelPropertyAccessor,
-            expectedPrefix: 'p');
-      }
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToRef,
+        ],
+        assignmentOperators: [
+          (UnlinkedExprAssignOperator.assign)
+        ],
+        ints: [
+          1,
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) {
+            return checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'a',
+                expectedKind: ReferenceKind.topLevelPropertyAccessor,
+                expectedPrefix: 'p');
+          }
+        ]);
   }
 
   test_expr_cascadeSection_assignToIndex() {
@@ -6638,28 +6702,34 @@
 final C c = new C();
 final v = c.items..[1] = 2;
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushReference,
-      //   ..[1] = 2
-      UnlinkedConstOperation.cascadeSectionBegin,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToIndex,
-      // c
-      UnlinkedConstOperation.cascadeSectionEnd,
-    ], assignmentOperators: [
-      UnlinkedExprAssignOperator.assign,
-    ], ints: [
-      2,
-      1
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'items',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(
-                    ReferenceKind.topLevelPropertyAccessor, 'c'),
-              ])
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushReference,
+          //   ..[1] = 2
+          UnlinkedConstOperation.cascadeSectionBegin,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToIndex,
+          // c
+          UnlinkedConstOperation.cascadeSectionEnd,
+        ],
+        assignmentOperators: [
+          UnlinkedExprAssignOperator.assign,
+        ],
+        ints: [
+          2,
+          1
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'items',
+                  expectedKind: ReferenceKind.unresolved,
+                  prefixExpectations: [
+                    new _PrefixExpectation(
+                        ReferenceKind.topLevelPropertyAccessor, 'c'),
+                  ])
+        ]);
   }
 
   test_expr_cascadeSection_assignToProperty() {
@@ -6673,35 +6743,41 @@
 }
 final v = new C()..f1 = 1..f2 += 2;
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      // new C()
-      UnlinkedConstOperation.invokeConstructor,
-      //   ..f1 = 1
-      UnlinkedConstOperation.cascadeSectionBegin,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToProperty,
-      // C
-      UnlinkedConstOperation.cascadeSectionEnd,
-      //   ..f2 += 2
-      UnlinkedConstOperation.cascadeSectionBegin,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToProperty,
-      // C
-      UnlinkedConstOperation.cascadeSectionEnd,
-    ], assignmentOperators: [
-      UnlinkedExprAssignOperator.assign,
-      UnlinkedExprAssignOperator.plus,
-    ], ints: [
-      0, 0, // new C()
-      1, // f1 = 1
-      2, // f2 += 2
-    ], strings: [
-      'f1',
-      'f2',
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'C',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          // new C()
+          UnlinkedConstOperation.invokeConstructor,
+          //   ..f1 = 1
+          UnlinkedConstOperation.cascadeSectionBegin,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToProperty,
+          // C
+          UnlinkedConstOperation.cascadeSectionEnd,
+          //   ..f2 += 2
+          UnlinkedConstOperation.cascadeSectionBegin,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToProperty,
+          // C
+          UnlinkedConstOperation.cascadeSectionEnd,
+        ],
+        assignmentOperators: [
+          UnlinkedExprAssignOperator.assign,
+          UnlinkedExprAssignOperator.plus,
+        ],
+        ints: [
+          0, 0, // new C()
+          1, // f1 = 1
+          2, // f2 += 2
+        ],
+        strings: [
+          'f1',
+          'f2',
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'C',
+              expectedKind: ReferenceKind.classOrEnum)
+        ]);
   }
 
   test_expr_cascadeSection_embedded() {
@@ -6722,55 +6798,61 @@
   ..b = (new B()..fb = 2)
   ..fa2 = 3;
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      // new A()
-      UnlinkedConstOperation.invokeConstructor,
-      // ..fa1 = 1
-      UnlinkedConstOperation.cascadeSectionBegin,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToProperty,
-      UnlinkedConstOperation.cascadeSectionEnd,
-      // ..b
-      UnlinkedConstOperation.cascadeSectionBegin,
-      //   new B()
-      UnlinkedConstOperation.invokeConstructor,
-      //   ..fb = 2
-      UnlinkedConstOperation.cascadeSectionBegin,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToProperty,
-      UnlinkedConstOperation.cascadeSectionEnd,
-      // ..b = <pop value>
-      UnlinkedConstOperation.assignToProperty,
-      UnlinkedConstOperation.cascadeSectionEnd,
-      // ..fa2 = 3
-      UnlinkedConstOperation.cascadeSectionBegin,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.assignToProperty,
-      UnlinkedConstOperation.cascadeSectionEnd,
-    ], assignmentOperators: [
-      UnlinkedExprAssignOperator.assign,
-      UnlinkedExprAssignOperator.assign,
-      UnlinkedExprAssignOperator.assign,
-      UnlinkedExprAssignOperator.assign,
-    ], ints: [
-      0,
-      0,
-      1,
-      0,
-      0,
-      2,
-      3,
-    ], strings: [
-      'fa1',
-      'fb',
-      'b',
-      'fa2',
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'A',
-          expectedKind: ReferenceKind.classOrEnum),
-      (EntityRef r) => checkTypeRef(r, null, null, 'B',
-          expectedKind: ReferenceKind.classOrEnum),
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          // new A()
+          UnlinkedConstOperation.invokeConstructor,
+          // ..fa1 = 1
+          UnlinkedConstOperation.cascadeSectionBegin,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToProperty,
+          UnlinkedConstOperation.cascadeSectionEnd,
+          // ..b
+          UnlinkedConstOperation.cascadeSectionBegin,
+          //   new B()
+          UnlinkedConstOperation.invokeConstructor,
+          //   ..fb = 2
+          UnlinkedConstOperation.cascadeSectionBegin,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToProperty,
+          UnlinkedConstOperation.cascadeSectionEnd,
+          // ..b = <pop value>
+          UnlinkedConstOperation.assignToProperty,
+          UnlinkedConstOperation.cascadeSectionEnd,
+          // ..fa2 = 3
+          UnlinkedConstOperation.cascadeSectionBegin,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.assignToProperty,
+          UnlinkedConstOperation.cascadeSectionEnd,
+        ],
+        assignmentOperators: [
+          UnlinkedExprAssignOperator.assign,
+          UnlinkedExprAssignOperator.assign,
+          UnlinkedExprAssignOperator.assign,
+          UnlinkedExprAssignOperator.assign,
+        ],
+        ints: [
+          0,
+          0,
+          1,
+          0,
+          0,
+          2,
+          3,
+        ],
+        strings: [
+          'fa1',
+          'fb',
+          'b',
+          'fa2',
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'A',
+              expectedKind: ReferenceKind.classOrEnum),
+          (EntityRef r) => checkTypeRef(r, null, null, 'B',
+              expectedKind: ReferenceKind.classOrEnum),
+        ]);
   }
 
   test_expr_cascadeSection_invokeMethod() {
@@ -6784,35 +6866,40 @@
 final A a = new A();
 final v = a..m(5).abs()..m(6);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      // a
-      UnlinkedConstOperation.pushReference,
-      //   ..m(5)
-      UnlinkedConstOperation.cascadeSectionBegin,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.invokeMethod,
-      //   ..abs()
-      UnlinkedConstOperation.invokeMethod,
-      // a
-      UnlinkedConstOperation.cascadeSectionEnd,
-      //   ..m(6)
-      UnlinkedConstOperation.cascadeSectionBegin,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.invokeMethod,
-      // a
-      UnlinkedConstOperation.cascadeSectionEnd,
-    ], ints: [
-      5, 0, 1, // m(5)
-      0, 0, // abs()
-      6, 0, 1, // m(5)
-    ], strings: [
-      'm',
-      'abs',
-      'm',
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor),
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          // a
+          UnlinkedConstOperation.pushReference,
+          //   ..m(5)
+          UnlinkedConstOperation.cascadeSectionBegin,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.invokeMethod,
+          //   ..abs()
+          UnlinkedConstOperation.invokeMethod,
+          // a
+          UnlinkedConstOperation.cascadeSectionEnd,
+          //   ..m(6)
+          UnlinkedConstOperation.cascadeSectionBegin,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.invokeMethod,
+          // a
+          UnlinkedConstOperation.cascadeSectionEnd,
+        ],
+        ints: [
+          5, 0, 1, // m(5)
+          0, 0, // abs()
+          6, 0, 1, // m(5)
+        ],
+        strings: [
+          'm',
+          'abs',
+          'm',
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'a',
+              expectedKind: ReferenceKind.topLevelPropertyAccessor),
+        ]);
   }
 
   test_expr_extractIndex_ofClassField() {
@@ -6825,21 +6912,26 @@
 }
 final v = new C().items[5];
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.invokeConstructor,
-      UnlinkedConstOperation.extractProperty,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.extractIndex,
-    ], ints: [
-      0,
-      0,
-      5
-    ], strings: [
-      'items'
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'C',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.invokeConstructor,
+          UnlinkedConstOperation.extractProperty,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.extractIndex,
+        ],
+        ints: [
+          0,
+          0,
+          5
+        ],
+        strings: [
+          'items'
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'C',
+              expectedKind: ReferenceKind.classOrEnum)
+        ]);
   }
 
   test_expr_extractProperty_ofInvokeConstructor() {
@@ -6852,18 +6944,23 @@
 }
 final v = new C().f;
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.invokeConstructor,
-      UnlinkedConstOperation.extractProperty,
-    ], ints: [
-      0,
-      0
-    ], strings: [
-      'f'
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'C',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.invokeConstructor,
+          UnlinkedConstOperation.extractProperty,
+        ],
+        ints: [
+          0,
+          0
+        ],
+        strings: [
+          'f'
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'C',
+              expectedKind: ReferenceKind.classOrEnum)
+        ]);
   }
 
   test_expr_functionExpression_asArgument() {
@@ -6874,20 +6971,24 @@
 final v = foo(5, () => 42);
 foo(a, b) {}
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushLocalFunctionReference,
-      UnlinkedConstOperation.invokeMethodRef
-    ], ints: [
-      5,
-      0,
-      0,
-      0,
-      2
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'foo',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushLocalFunctionReference,
+          UnlinkedConstOperation.invokeMethodRef
+        ],
+        ints: [
+          5,
+          0,
+          0,
+          0,
+          2
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+              expectedKind: ReferenceKind.topLevelFunction)
+        ]);
   }
 
   test_expr_functionExpression_asArgument_multiple() {
@@ -6898,23 +6999,27 @@
 final v = foo(5, () => 42, () => 43);
 foo(a, b, c) {}
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushLocalFunctionReference,
-      UnlinkedConstOperation.pushLocalFunctionReference,
-      UnlinkedConstOperation.invokeMethodRef
-    ], ints: [
-      5,
-      0,
-      0,
-      0,
-      1,
-      0,
-      3
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'foo',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushLocalFunctionReference,
+          UnlinkedConstOperation.pushLocalFunctionReference,
+          UnlinkedConstOperation.invokeMethodRef
+        ],
+        ints: [
+          5,
+          0,
+          0,
+          0,
+          1,
+          0,
+          3
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+              expectedKind: ReferenceKind.topLevelFunction)
+        ]);
   }
 
   test_expr_functionExpression_withBlockBody() {
@@ -6924,7 +7029,7 @@
     UnlinkedVariable variable = serializeVariableText('''
 final v = () { return 42; };
 ''');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         isValidConst: false,
         operators: [UnlinkedConstOperation.pushLocalFunctionReference],
         ints: [0, 0]);
@@ -6937,7 +7042,7 @@
     UnlinkedVariable variable = serializeVariableText('''
 final v = () => 42;
 ''');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         isValidConst: false,
         operators: [UnlinkedConstOperation.pushLocalFunctionReference],
         ints: [0, 0]);
@@ -6950,7 +7055,7 @@
     UnlinkedVariable variable = serializeVariableText('''
 final v = ((a, b) {return 42;})(1, 2);
 ''');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
   }
 
@@ -6961,7 +7066,7 @@
     UnlinkedVariable variable = serializeVariableText('''
 final v = ((a, b) => 42)(1, 2);
 ''');
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
   }
 
@@ -6975,28 +7080,33 @@
 }
 final v = new C().m(1, b: 2, c: 3);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.invokeConstructor,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.invokeMethod,
-    ], ints: [
-      0,
-      0,
-      1,
-      2,
-      3,
-      2,
-      1
-    ], strings: [
-      'b',
-      'c',
-      'm'
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'C',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.invokeConstructor,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.invokeMethod,
+        ],
+        ints: [
+          0,
+          0,
+          1,
+          2,
+          3,
+          2,
+          1
+        ],
+        strings: [
+          'b',
+          'c',
+          'm'
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'C',
+              expectedKind: ReferenceKind.classOrEnum)
+        ]);
   }
 
   test_expr_invokeMethodRef_instance() {
@@ -7016,25 +7126,30 @@
 A a = new A();
 final v = a.b.c.m(10, 20);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.invokeMethodRef,
-    ], ints: [
-      10,
-      20,
-      0,
-      2
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'm',
-              expectedKind: ReferenceKind.unresolved,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
-                new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
-                new _PrefixExpectation(
-                    ReferenceKind.topLevelPropertyAccessor, 'a')
-              ])
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.invokeMethodRef,
+        ],
+        ints: [
+          10,
+          20,
+          0,
+          2
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'm',
+                  expectedKind: ReferenceKind.unresolved,
+                  prefixExpectations: [
+                    new _PrefixExpectation(ReferenceKind.unresolved, 'c'),
+                    new _PrefixExpectation(ReferenceKind.unresolved, 'b'),
+                    new _PrefixExpectation(
+                        ReferenceKind.topLevelPropertyAccessor, 'a')
+                  ])
+        ]);
   }
 
   test_expr_invokeMethodRef_static_importedWithPrefix() {
@@ -7052,20 +7167,25 @@
 import 'a.dart' as p;
 final v = p.C.m();
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.invokeMethodRef,
-    ], ints: [
-      0,
-      0
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'm',
-              expectedKind: ReferenceKind.method,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
-                    absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
-                new _PrefixExpectation(ReferenceKind.prefix, 'p')
-              ])
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.invokeMethodRef,
+        ],
+        ints: [
+          0,
+          0
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'm',
+                  expectedKind: ReferenceKind.method,
+                  prefixExpectations: [
+                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+                        absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
+                    new _PrefixExpectation(ReferenceKind.prefix, 'p')
+                  ])
+        ]);
   }
 
   test_expr_invokeMethodRef_with_reference_arg() {
@@ -7077,18 +7197,22 @@
 final u = null;
 final v = f(u);
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushReference,
-      UnlinkedConstOperation.invokeMethodRef
-    ], ints: [
-      0,
-      1
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'u',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor),
-      (EntityRef r) => checkTypeRef(r, null, null, 'f',
-          expectedKind: ReferenceKind.topLevelFunction)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushReference,
+          UnlinkedConstOperation.invokeMethodRef
+        ],
+        ints: [
+          0,
+          1
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'u',
+              expectedKind: ReferenceKind.topLevelPropertyAccessor),
+          (EntityRef r) => checkTypeRef(r, null, null, 'f',
+              expectedKind: ReferenceKind.topLevelFunction)
+        ]);
   }
 
   test_expr_throwException() {
@@ -7098,15 +7222,18 @@
     UnlinkedVariable variable = serializeVariableText('''
 final v = throw 1 + 2;
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.add,
-      UnlinkedConstOperation.throwException,
-    ], ints: [
-      1,
-      2
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.add,
+          UnlinkedConstOperation.throwException,
+        ],
+        ints: [
+          1,
+          2
+        ]);
   }
 
   test_expr_typeCast() {
@@ -7116,15 +7243,19 @@
     UnlinkedVariable variable = serializeVariableText('''
 final v = 42 as num;
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.typeCast,
-    ], ints: [
-      42
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.typeCast,
+        ],
+        ints: [
+          42
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num',
+              expectedKind: ReferenceKind.classOrEnum)
+        ]);
   }
 
   test_expr_typeCheck() {
@@ -7134,15 +7265,19 @@
     UnlinkedVariable variable = serializeVariableText('''
 final v = 42 is num;
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.typeCheck,
-    ], ints: [
-      42
-    ], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num',
-          expectedKind: ReferenceKind.classOrEnum)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.typeCheck,
+        ],
+        ints: [
+          42
+        ],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, 'dart:core', 'dart:core', 'num',
+              expectedKind: ReferenceKind.classOrEnum)
+        ]);
   }
 
   test_field() {
@@ -7152,7 +7287,7 @@
     expect(variable.isConst, isFalse);
     expect(variable.isStatic, isFalse);
     expect(variable.isFinal, isFalse);
-    expect(variable.constExpr, isNull);
+    expect(variable.initializer, isNull);
     expect(findExecutable('i', executables: cls.executables), isNull);
     expect(findExecutable('i=', executables: cls.executables), isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
@@ -7164,7 +7299,7 @@
     UnlinkedVariable variable =
         serializeClassText('class C { static const int i = 0; }').fields[0];
     expect(variable.isConst, isTrue);
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushInt], ints: [0]);
   }
 
@@ -7185,7 +7320,7 @@
     UnlinkedVariable variable =
         serializeClassText('class C { final int i = 0; }').fields[0];
     expect(variable.isFinal, isTrue);
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.pushInt], ints: [0]);
   }
 
@@ -7196,21 +7331,26 @@
   static int m() => 42;
 }''').fields[0];
     expect(variable.isFinal, isTrue);
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.invokeMethodRef,
-      UnlinkedConstOperation.add,
-    ], ints: [
-      1,
-      0,
-      0
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'm',
-              expectedKind: ReferenceKind.method,
-              prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
-              ])
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.invokeMethodRef,
+          UnlinkedConstOperation.add,
+        ],
+        ints: [
+          1,
+          0,
+          0
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'm',
+                  expectedKind: ReferenceKind.method,
+                  prefixExpectations: [
+                    new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
+                  ])
+        ]);
   }
 
   test_field_final_typeParameter() {
@@ -7219,7 +7359,7 @@
   final f = <T>[];
 }''').fields[0];
     expect(variable.isFinal, isTrue);
-    _assertUnlinkedConst(variable.constExpr,
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
         operators: [UnlinkedConstOperation.makeTypedList],
         ints: [0],
         referenceValidators: [(EntityRef r) => checkParamTypeRef(r, 1)]);
@@ -7307,7 +7447,7 @@
     UnlinkedVariable variable =
         serializeClassText('class C { static int i; }').fields[0];
     expect(variable.isStatic, isTrue);
-    expect(variable.constExpr, isNull);
+    expect(variable.initializer, isNull);
     expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
     expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
     expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1));
@@ -7326,7 +7466,7 @@
         serializeClassText('class C { static final int i = 0; }').fields[0];
     expect(variable.isStatic, isTrue);
     expect(variable.isFinal, isTrue);
-    expect(variable.constExpr, isNull);
+    expect(variable.initializer.bodyExpr, isNull);
   }
 
   test_field_static_final_untyped() {
@@ -7337,7 +7477,7 @@
     }
     UnlinkedVariable variable =
         serializeClassText('class C { static final x = 0; }').fields[0];
-    expect(variable.constExpr, isNotNull);
+    expect(variable.initializer.bodyExpr, isNotNull);
   }
 
   test_field_untyped() {
@@ -7348,7 +7488,7 @@
     }
     UnlinkedVariable variable =
         serializeClassText('class C { var x = 0; }').fields[0];
-    expect(variable.constExpr, isNotNull);
+    expect(variable.initializer.bodyExpr, isNotNull);
   }
 
   test_fully_linked_references_follow_other_references() {
@@ -9757,7 +9897,7 @@
     UnlinkedVariable variable =
         serializeVariableText('final int i = 0;', variableName: 'i');
     expect(variable.isFinal, isTrue);
-    expect(variable.constExpr, isNull);
+    expect(variable.initializer.bodyExpr, isNull);
   }
 
   test_variable_final_top_level_untyped() {
@@ -9767,7 +9907,7 @@
       return;
     }
     UnlinkedVariable variable = serializeVariableText('final v = 0;');
-    expect(variable.constExpr, isNotNull);
+    expect(variable.initializer.bodyExpr, isNotNull);
   }
 
   test_variable_implicit_dynamic() {
@@ -10002,23 +10142,29 @@
 int a = 0;
 final v = $expr;
     ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.add,
-      UnlinkedConstOperation.assignToRef,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.add,
-    ], assignmentOperators: [
-      expectedAssignOperator
-    ], ints: [
-      1,
-      2,
-      3
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.add,
+          UnlinkedConstOperation.assignToRef,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.add,
+        ],
+        assignmentOperators: [
+          expectedAssignOperator
+        ],
+        ints: [
+          1,
+          2,
+          3
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'a',
+              expectedKind: ReferenceKind.topLevelPropertyAccessor)
+        ]);
   }
 
   void _assertCodeRange(CodeRange codeRange, int offset, int length) {
@@ -10063,18 +10209,24 @@
 int a = 0;
 final v = $expr;
 ''');
-    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
-      UnlinkedConstOperation.assignToRef,
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.add,
-    ], assignmentOperators: [
-      expectedAssignmentOperator
-    ], ints: [
-      2
-    ], strings: [], referenceValidators: [
-      (EntityRef r) => checkTypeRef(r, null, null, 'a',
-          expectedKind: ReferenceKind.topLevelPropertyAccessor)
-    ]);
+    _assertUnlinkedConst(variable.initializer.bodyExpr,
+        isValidConst: false,
+        operators: [
+          UnlinkedConstOperation.assignToRef,
+          UnlinkedConstOperation.pushInt,
+          UnlinkedConstOperation.add,
+        ],
+        assignmentOperators: [
+          expectedAssignmentOperator
+        ],
+        ints: [
+          2
+        ],
+        strings: [],
+        referenceValidators: [
+          (EntityRef r) => checkTypeRef(r, null, null, 'a',
+              expectedKind: ReferenceKind.topLevelPropertyAccessor)
+        ]);
   }
 
   /**
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index cb8fb46..da36f87 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -774,9 +774,16 @@
 
   Map<Source, ChangeNoticeImpl> _pendingNotices = <Source, ChangeNoticeImpl>{};
 
+  @override
+  final ReentrantSynchronousStream<InvalidatedResult> onResultInvalidated =
+      new ReentrantSynchronousStream<InvalidatedResult>();
+
   _InternalAnalysisContextMock() {
     privateAnalysisCachePartition = new UniversalCachePartition(this);
     analysisCache = new AnalysisCache([privateAnalysisCachePartition]);
+    analysisCache.onResultInvalidated.listen((InvalidatedResult event) {
+      onResultInvalidated.add(event);
+    });
   }
 
   @override
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index a4bc6b7..a686740 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -2318,6 +2318,168 @@
     expect(f.type.toString(), '() → dynamic');
   }
 
+  void test_inferredType_customBinaryOp() {
+    var mainUnit = checkFile('''
+class C {
+  bool operator*(C other) => true;
+}
+C c;
+var x = c*c;
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_customBinaryOp_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  bool operator*(C other) => true;
+}
+abstract class C implements I {}
+C c;
+var x = c*c;
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_customIndexOp() {
+    var mainUnit = checkFile('''
+class C {
+  bool operator[](int index) => true;
+}
+C c;
+var x = c[0];
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_customIndexOp_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  bool operator[](int index) => true;
+}
+abstract class C implements I {}
+C c;
+var x = c[0];
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_customUnaryOp() {
+    var mainUnit = checkFile('''
+class C {
+  bool operator-() => true;
+}
+C c;
+var x = -c;
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_customUnaryOp_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  bool operator-() => true;
+}
+abstract class C implements I {}
+C c;
+var x = -c;
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_extractMethodTearOff() {
+    var mainUnit = checkFile('''
+class C {
+  bool g() => true;
+}
+C f() => null;
+var x = f().g;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), '() → bool');
+  }
+
+  void test_inferredType_extractMethodTearOff_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  bool g() => true;
+}
+abstract class C implements I {}
+C f() => null;
+var x = f().g;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), '() → bool');
+  }
+
+  void test_inferredType_extractProperty() {
+    var mainUnit = checkFile('''
+class C {
+  bool b;
+}
+C f() => null;
+var x = f().b;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_extractProperty_prefixedIdentifier() {
+    var mainUnit = checkFile('''
+class C {
+  bool b;
+}
+C c;
+var x = c.b;
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_extractProperty_prefixedIdentifier_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  bool b;
+}
+abstract class C implements I {}
+C c;
+var x = c.b;
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_extractProperty_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  bool b;
+}
+abstract class C implements I {}
+C f() => null;
+var x = f().b;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
   void test_inferredType_fromTopLevelExecutableTearoff() {
     var mainUnit = checkFile('''
 var v = print;
@@ -2326,6 +2488,33 @@
     expect(v.type.toString(), '(Object) → void');
   }
 
+  void test_inferredType_invokeMethod() {
+    var mainUnit = checkFile('''
+class C {
+  bool g() => true;
+}
+C f() => null;
+var x = f().g();
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
+  void test_inferredType_invokeMethod_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  bool g() => true;
+}
+abstract class C implements I {}
+C f() => null;
+var x = f().g();
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'bool');
+  }
+
   void test_inferredType_isEnum() {
     var mainUnit = checkFile('''
 enum E { v1 }
@@ -2362,6 +2551,60 @@
     expect(x.type.toString(), 'Map<String, () → int>');
   }
 
+  void test_inferredType_opAssignToProperty_prefixedIdentifier() {
+    var mainUnit = checkFile('''
+class C {
+  num n;
+}
+C c;
+var x = (c.n *= null);
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'num');
+  }
+
+  void test_inferredType_opAssignToProperty_prefixedIdentifier_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  num n;
+}
+abstract class C implements I {}
+C c;
+var x = (c.n *= null);
+''');
+    var x = mainUnit.topLevelVariables[1];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'num');
+  }
+
+  void test_inferredType_opAssignToProperty() {
+    var mainUnit = checkFile('''
+class C {
+  num n;
+}
+C f() => null;
+var x = (f().n *= null);
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'num');
+  }
+
+  void test_inferredType_opAssignToProperty_viaInterface() {
+    var mainUnit = checkFile('''
+class I {
+  num n;
+}
+abstract class C implements I {}
+C f() => null;
+var x = (f().n *= null);
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'num');
+  }
+
   void test_inferStaticsTransitively() {
     addFile(
         '''
diff --git a/pkg/analyzer/test/src/util/fast_uri_test.dart b/pkg/analyzer/test/src/util/fast_uri_test.dart
new file mode 100644
index 0000000..060904e
--- /dev/null
+++ b/pkg/analyzer/test/src/util/fast_uri_test.dart
@@ -0,0 +1,169 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.test.src.util.fast_uri_test;
+
+import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+import '../../utils.dart';
+
+main() {
+  initializeTestEnvironment();
+  runReflectiveTests(_FastUriTest);
+}
+
+@reflectiveTest
+class _FastUriTest {
+  static final isInstanceOf<FastUri> isFastUri = new isInstanceOf<FastUri>();
+
+  void test_parse_absolute_dart() {
+    _compareTextWithCoreUri('dart:core');
+  }
+
+  void test_parse_absolute_file() {
+    _compareTextWithCoreUri('file:///Users/scheglov/util/fast_uri.dart');
+  }
+
+  void test_parse_absolute_folder_withSlashAtTheEnd() {
+    _compareTextWithCoreUri('file:///Users/scheglov/util/');
+  }
+
+  void test_parse_absolute_package() {
+    _compareTextWithCoreUri('package:analyzer/src/util/fast_uri.dart');
+  }
+
+  void test_parse_notFast_hasAuthority() {
+    Uri uri = FastUri.parse('http://www.google.com/pages/about.html');
+    expect(uri, isNot(isFastUri));
+  }
+
+  void test_parse_notFast_hasPort() {
+    Uri uri = FastUri.parse('http://www.google.com:8080/pages/about.html');
+    expect(uri, isNot(isFastUri));
+  }
+
+  void test_parse_relative_down() {
+    _compareTextWithCoreUri('util/fast_uri.dart');
+  }
+
+  void test_parse_relative_up() {
+    _compareTextWithCoreUri('../util/fast_uri.dart');
+  }
+
+  void test_resolve() {
+    Uri uri1 = FastUri.parse('package:analyzer/aaa/bbbb/c.dart');
+    Uri uri2 = uri1.resolve('dd.dart');
+    _compareUris(uri2, Uri.parse('package:analyzer/aaa/bbbb/dd.dart'));
+  }
+
+  void test_resolveUri_absolute() {
+    _checkResolveUri('package:analyzer/aaa/b.dart', 'package:path/style.dart',
+        'package:path/style.dart');
+  }
+
+  void test_resolveUri_endWithSlash_onlyName() {
+    _checkResolveUri('package:analyzer/aaa/bbbb/', 'cc.dart',
+        'package:analyzer/aaa/bbbb/cc.dart');
+  }
+
+  void test_resolveUri_nameStartsWithOneDot() {
+    _checkResolveUri('package:analyzer/aaa/bbbb/ccc.dart', '.name.dart',
+        'package:analyzer/aaa/bbbb/.name.dart');
+  }
+
+  void test_resolveUri_nameStartsWithTwoDots() {
+    _checkResolveUri('package:analyzer/aaa/bbbb/ccc.dart', '..name.dart',
+        'package:analyzer/aaa/bbbb/..name.dart');
+  }
+
+  void test_resolveUri_noSlash_onlyName() {
+    _checkResolveUri('dart:core', 'int.dart', 'dart:core/int.dart');
+  }
+
+  void test_resolveUri_onlyName() {
+    _checkResolveUri('package:analyzer/aaa/bbbb/ccc.dart', 'dd.dart',
+        'package:analyzer/aaa/bbbb/dd.dart');
+  }
+
+  void test_resolveUri_pathHasOneDot() {
+    _checkResolveUri('package:analyzer/aaa/bbbb/ccc.dart', 'dd/./ee.dart',
+        'package:analyzer/aaa/bbbb/dd/ee.dart');
+  }
+
+  void test_resolveUri_pathHasTwoDots() {
+    _checkResolveUri('package:analyzer/aaa/bbbb/ccc.dart', 'dd/../ee.dart',
+        'package:analyzer/aaa/bbbb/ee.dart');
+  }
+
+  void test_resolveUri_pathStartsWithOneDot() {
+    _checkResolveUri('package:analyzer/aaa/bbbb/ccc.dart', './ddd.dart',
+        'package:analyzer/aaa/bbbb/ddd.dart');
+  }
+
+  void test_resolveUri_pathStartsWithTwoDots() {
+    _checkResolveUri('package:analyzer/aaa/bbbb/ccc.dart', '../ddd.dart',
+        'package:analyzer/aaa/ddd.dart');
+  }
+
+  void test_resolveUri_pathWithSubFolder() {
+    Uri uri1 = FastUri.parse('package:analyzer/aaa/bbbb/ccc.dart');
+    Uri uri2 = FastUri.parse('dd/eeee.dart');
+    expect(uri1, isFastUri);
+    expect(uri2, isFastUri);
+    Uri uri3 = uri1.resolveUri(uri2);
+    expect(uri3, isFastUri);
+    _compareUris(uri3, Uri.parse('package:analyzer/aaa/bbbb/dd/eeee.dart'));
+  }
+
+  void _checkResolveUri(String srcText, String relText, String targetText) {
+    Uri src = FastUri.parse(srcText);
+    Uri rel = FastUri.parse(relText);
+    expect(src, isFastUri);
+    expect(rel, isFastUri);
+    Uri target = src.resolveUri(rel);
+    expect(target, isFastUri);
+    _compareUris(target, Uri.parse(targetText));
+  }
+
+  void _compareTextWithCoreUri(String text, {bool isFast: true}) {
+    Uri fastUri = FastUri.parse(text);
+    Uri coreUri = Uri.parse(text);
+    if (isFast) {
+      expect(fastUri, isFastUri);
+    }
+    _compareUris(fastUri, coreUri);
+  }
+
+  void _compareUris(Uri fastUri, Uri coreUri) {
+    expect(fastUri.authority, coreUri.authority);
+    expect(fastUri.data, coreUri.data);
+    expect(fastUri.fragment, coreUri.fragment);
+    expect(fastUri.hasAbsolutePath, coreUri.hasAbsolutePath);
+    expect(fastUri.hasAuthority, coreUri.hasAuthority);
+    expect(fastUri.hasEmptyPath, coreUri.hasEmptyPath);
+    expect(fastUri.hasFragment, coreUri.hasFragment);
+    expect(fastUri.hasPort, coreUri.hasPort);
+    expect(fastUri.hasQuery, coreUri.hasQuery);
+    expect(fastUri.hasScheme, coreUri.hasScheme);
+    expect(fastUri.host, coreUri.host);
+    expect(fastUri.isAbsolute, coreUri.isAbsolute);
+    if (coreUri.scheme == 'http' || coreUri.scheme == 'https') {
+      expect(fastUri.origin, coreUri.origin);
+    }
+    expect(fastUri.path, coreUri.path);
+    expect(fastUri.pathSegments, coreUri.pathSegments);
+    expect(fastUri.port, coreUri.port);
+    expect(fastUri.query, coreUri.query);
+    expect(fastUri.queryParameters, coreUri.queryParameters);
+    expect(fastUri.queryParametersAll, coreUri.queryParametersAll);
+    expect(fastUri.scheme, coreUri.scheme);
+    expect(fastUri.userInfo, coreUri.userInfo);
+    // Object
+    expect(fastUri.hashCode, coreUri.hashCode);
+    expect(fastUri == coreUri, isTrue);
+    expect(coreUri == fastUri, isTrue);
+  }
+}
diff --git a/pkg/analyzer/test/src/util/test_all.dart b/pkg/analyzer/test/src/util/test_all.dart
index d992264..6091c5b 100644
--- a/pkg/analyzer/test/src/util/test_all.dart
+++ b/pkg/analyzer/test/src/util/test_all.dart
@@ -9,6 +9,7 @@
 import '../../utils.dart';
 import 'absolute_path_test.dart' as absolute_path_test;
 import 'asserts_test.dart' as asserts_test;
+import 'fast_uri_test.dart' as fast_uri_test;
 import 'glob_test.dart' as glob_test;
 import 'lru_map_test.dart' as lru_map_test;
 import 'yaml_test.dart' as yaml_test;
@@ -19,6 +20,7 @@
   group('util tests', () {
     absolute_path_test.main();
     asserts_test.main();
+    fast_uri_test.main();
     glob_test.main();
     lru_map_test.main();
     yaml_test.main();
diff --git a/pkg/analyzer/tool/summary/build_sdk_summaries.dart b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
index 9d1c34b..1bbd4da 100644
--- a/pkg/analyzer/tool/summary/build_sdk_summaries.dart
+++ b/pkg/analyzer/tool/summary/build_sdk_summaries.dart
@@ -139,9 +139,10 @@
  */
 void _extractSingleOutput(String inputPath, int field, String outputPath) {
   List<int> bytes = new File(inputPath).readAsBytesSync();
-  fb.BufferPointer root = new fb.BufferPointer.fromBytes(bytes);
-  fb.BufferPointer table = root.derefObject();
-  List<int> fieldBytes = const fb.Uint8ListReader().vTableGet(table, field);
+  fb.BufferContext root = new fb.BufferContext.fromBytes(bytes);
+  int tableOffset = root.derefObject(0);
+  List<int> fieldBytes =
+      const fb.Uint8ListReader().vTableGet(root, tableOffset, field);
   new File(outputPath).writeAsBytesSync(fieldBytes, mode: FileMode.WRITE_ONLY);
 }
 
diff --git a/pkg/analyzer/tool/summary/dump_inferred_types.dart b/pkg/analyzer/tool/summary/dump_inferred_types.dart
index 135783e..1ff2c6e 100644
--- a/pkg/analyzer/tool/summary/dump_inferred_types.dart
+++ b/pkg/analyzer/tool/summary/dump_inferred_types.dart
@@ -5,9 +5,13 @@
 import 'dart:convert';
 import 'dart:io';
 
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/base.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/link.dart';
 import 'package:analyzer/src/summary/package_bundle_reader.dart';
 
 /**
@@ -16,7 +20,9 @@
  */
 main(List<String> args) {
   SummaryDataStore summaryDataStore = new SummaryDataStore(args);
-  InferredTypeCollector collector = new InferredTypeCollector();
+  InferredTypeCollector collector = new InferredTypeCollector(
+      (String uri) => summaryDataStore.linkedMap[uri],
+      (String uri) => summaryDataStore.unlinkedMap[uri]);
   collector.visitSummaryDataStore(summaryDataStore);
   collector.dumpCollectedTypes();
 }
@@ -28,8 +34,14 @@
 class InferredTypeCollector {
   UnlinkedUnit unlinkedUnit;
   LinkedUnit linkedUnit;
+  CompilationUnitElementForLink unitForLink;
   final Map<String, String> inferredTypes = <String, String>{};
   List<String> typeParamsInScope = <String>[];
+  final Linker _linker;
+
+  InferredTypeCollector(
+      GetDependencyCallback getDependency, GetUnitCallback getUnit)
+      : _linker = new Linker({}, getDependency, getUnit, true);
 
   /**
    * If an inferred type exists matching the given [slot], record that it is the
@@ -88,6 +100,67 @@
   }
 
   /**
+   * Format the given [type] as a string.  Unlike the type's [toString] method,
+   * this formats types using their complete URI to avoid ambiguity.
+   */
+  String formatDartType(DartType type) {
+    if (type is FunctionType) {
+      List<String> argStrings =
+          type.normalParameterTypes.map(formatDartType).toList();
+      List<DartType> optionalParameterTypes = type.optionalParameterTypes;
+      if (optionalParameterTypes.isNotEmpty) {
+        List<String> optionalArgStrings =
+            optionalParameterTypes.map(formatDartType).toList();
+        argStrings.add('[${optionalArgStrings.join(', ')}]');
+      }
+      Map<String, DartType> namedParameterTypes = type.namedParameterTypes;
+      if (namedParameterTypes.isNotEmpty) {
+        List<String> namedArgStrings = <String>[];
+        namedParameterTypes.forEach((String name, DartType type) {
+          namedArgStrings.add('$name: ${formatDartType(type)}');
+        });
+        argStrings.add('{${namedArgStrings.join(', ')}}');
+      }
+      return '(${argStrings.join(', ')}) → ${formatDartType(type.returnType)}';
+    } else if (type is InterfaceType) {
+      if (type.typeArguments.isNotEmpty) {
+        // TODO(paulberry): implement.
+        throw new UnimplementedError('type args');
+      }
+      return formatElement(type.element);
+    } else if (type is DynamicTypeImpl) {
+      return type.toString();
+    } else {
+      // TODO(paulberry): implement.
+      throw new UnimplementedError(
+          "Don't know how to format type of type ${type.runtimeType}");
+    }
+  }
+
+  /**
+   * Format the given [element] as a string, assuming it represents a type.
+   * Unlike the element's [toString] method, this formats elements using their
+   * complete URI to avoid ambiguity.
+   */
+  String formatElement(Element element) {
+    if (element is ClassElementForLink_Class ||
+        element is MethodElementForLink ||
+        element is ClassElementForLink_Enum ||
+        element is SpecialTypeElementForLink ||
+        element is FunctionTypeAliasElementForLink ||
+        element is TopLevelFunctionElementForLink) {
+      return element.toString();
+    } else if (element is FunctionElementForLink_Local_NonSynthetic) {
+      return formatDartType(element.type);
+    } else if (element is UndefinedElementForLink) {
+      return '???';
+    } else {
+      throw new UnimplementedError(
+          "Don't know how to format reference of type ${element.runtimeType}");
+    }
+  }
+
+  /**
    * Interpret the given [param] as a parameter in a synthetic typedef, and
    * format it as a string.
    */
@@ -117,47 +190,8 @@
    * `typeof()` for clarity.
    */
   String formatReference(int index, {bool typeOf: false}) {
-    LinkedReference linkedRef = linkedUnit.references[index];
-    switch (linkedRef.kind) {
-      case ReferenceKind.classOrEnum:
-      case ReferenceKind.function:
-      case ReferenceKind.propertyAccessor:
-      case ReferenceKind.topLevelFunction:
-      case ReferenceKind.method:
-      case ReferenceKind.typedef:
-      case ReferenceKind.prefix:
-      case ReferenceKind.topLevelPropertyAccessor:
-        break;
-      default:
-        // TODO(paulberry): fix this case.
-        return 'BAD(${JSON.encode(linkedRef.toJson())})';
-    }
-    int containingReference;
-    String name;
-    if (index < unlinkedUnit.references.length) {
-      containingReference = unlinkedUnit.references[index].prefixReference;
-      name = unlinkedUnit.references[index].name;
-    } else {
-      containingReference = linkedRef.containingReference;
-      name = linkedRef.name;
-    }
-    String result;
-    if (containingReference != 0) {
-      result = '${formatReference(containingReference)}.$name';
-    } else {
-      result = name;
-    }
-    if (linkedRef.kind == ReferenceKind.function) {
-      assert(name.isEmpty);
-      result += 'localFunction[${linkedRef.localIndex}]';
-    }
-    if (!typeOf ||
-        linkedRef.kind == ReferenceKind.classOrEnum ||
-        linkedRef.kind == ReferenceKind.typedef) {
-      return result;
-    } else {
-      return 'typeof($result)';
-    }
+    ReferenceableElementForLink element = unitForLink.resolveRef(index);
+    return formatElement(element);
   }
 
   /**
@@ -260,12 +294,16 @@
       if (partOfUris.contains(libraryUriString)) {
         return;
       }
+      if (libraryUriString.startsWith('dart:')) {
+        // Don't bother dumping inferred types from the SDK.
+        return;
+      }
       Uri libraryUri = Uri.parse(libraryUriString);
       UnlinkedUnit definingUnlinkedUnit =
           summaryDataStore.unlinkedMap[libraryUriString];
       if (definingUnlinkedUnit != null) {
         visitUnit(
-            definingUnlinkedUnit, linkedLibrary.units[0], libraryUriString);
+            definingUnlinkedUnit, linkedLibrary.units[0], libraryUriString, 0);
         for (int i = 0;
             i < definingUnlinkedUnit.publicNamespace.parts.length;
             i++) {
@@ -276,8 +314,8 @@
           UnlinkedUnit unlinkedUnit =
               summaryDataStore.unlinkedMap[unitUriString];
           if (unlinkedUnit != null) {
-            visitUnit(
-                unlinkedUnit, linkedLibrary.units[i + 1], libraryUriString);
+            visitUnit(unlinkedUnit, linkedLibrary.units[i + 1],
+                libraryUriString, i + 1);
           }
         }
       }
@@ -289,11 +327,14 @@
    * by [unlinkedUnit] and [linkedUnit], which has URI [libraryUriString].
    */
   void visitUnit(UnlinkedUnit unlinkedUnit, LinkedUnit linkedUnit,
-      String libraryUriString) {
+      String libraryUriString, int unitNum) {
     this.unlinkedUnit = unlinkedUnit;
     this.linkedUnit = linkedUnit;
+    this.unitForLink =
+        _linker.getLibrary(Uri.parse(libraryUriString)).units[unitNum];
     visit(unlinkedUnit, unlinkedUnit.toMap(), libraryUriString);
     this.unlinkedUnit = null;
     this.linkedUnit = null;
+    this.unitForLink = null;
   }
 }
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index 51dad39..4f9018e 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -749,9 +749,9 @@
       out('int get size => 1;');
       out();
       out('@override');
-      out('${idlPrefix(name)} read(fb.BufferPointer bp) {');
+      out('${idlPrefix(name)} read(fb.BufferContext bc, int offset) {');
       indent(() {
-        out('int index = const fb.Uint8Reader().read(bp);');
+        out('int index = const fb.Uint8Reader().read(bc, offset);');
         out('return index < $count ? ${idlPrefix(name)}.values[index] : $def;');
       });
       out('}');
@@ -766,9 +766,10 @@
     out('class $implName extends Object with $mixinName'
         ' implements ${idlPrefix(name)} {');
     indent(() {
-      out('final fb.BufferPointer _bp;');
+      out('final fb.BufferContext _bc;');
+      out('final int _bcOffset;');
       out();
-      out('$implName(this._bp);');
+      out('$implName(this._bc, this._bcOffset);');
       out();
       // Write cache fields.
       for (idlModel.FieldDeclaration field in cls.fields) {
@@ -824,7 +825,7 @@
         } else {
           out('$returnType get $fieldName {');
           indent(() {
-            String readExpr = '$readCode.vTableGet(_bp, $index, $def)';
+            String readExpr = '$readCode.vTableGet(_bc, _bcOffset, $index, $def)';
             out('_$fieldName ??= $readExpr;');
             out('return _$fieldName;');
           });
@@ -906,7 +907,7 @@
       out('const $readerName();');
       out();
       out('@override');
-      out('$implName createObject(fb.BufferPointer bp) => new $implName(bp);');
+      out('$implName createObject(fb.BufferContext bc, int offset) => new $implName(bc, offset);');
     });
     out('}');
   }
@@ -915,8 +916,8 @@
     String name = cls.name;
     out('${idlPrefix(name)} read$name(List<int> buffer) {');
     indent(() {
-      out('fb.BufferPointer rootRef = new fb.BufferPointer.fromBytes(buffer);');
-      out('return const _${name}Reader().read(rootRef);');
+      out('fb.BufferContext rootRef = new fb.BufferContext.fromBytes(buffer);');
+      out('return const _${name}Reader().read(rootRef, 0);');
     });
     out('}');
   }
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 4d80c61..2c6b74e 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -397,7 +397,7 @@
 
     // Setup embedding.
     EmbedderUriResolver embedderUriResolver =
-        new EmbedderUriResolver(embedderMap);
+        new EmbedderUriResolver(new EmbedderSdk(embedderMap));
     if (embedderUriResolver.length == 0) {
       // The embedder uri resolver has no mappings. Use the default Dart SDK
       // uri resolver.
diff --git a/pkg/compiler/lib/src/apiimpl.dart b/pkg/compiler/lib/src/apiimpl.dart
index 631d29b..98d931a 100644
--- a/pkg/compiler/lib/src/apiimpl.dart
+++ b/pkg/compiler/lib/src/apiimpl.dart
@@ -31,6 +31,7 @@
 /// Implements the [Compiler] using a [api.CompilerInput] for supplying the
 /// sources.
 class CompilerImpl extends Compiler {
+  final Measurer measurer;
   api.CompilerInput provider;
   api.CompilerDiagnostics handler;
   Packages packages;
@@ -50,7 +51,10 @@
   CompilerImpl(this.provider, api.CompilerOutput outputProvider, this.handler,
       CompilerOptions options,
       {MakeBackendFuncion makeBackend, MakeReporterFunction makeReporter})
-      : resolvedUriTranslator = new ForwardingResolvedUriTranslator(),
+      // NOTE: allocating measurer is done upfront to ensure the wallclock is
+      // started before other computations.
+      : measurer = new Measurer(enableTaskMeasurements: options.verbose),
+        resolvedUriTranslator = new ForwardingResolvedUriTranslator(),
         super(
             options: options,
             outputProvider: outputProvider,
@@ -60,9 +64,10 @@
     _Environment env = environment;
     env.compiler = this;
     tasks.addAll([
-      userHandlerTask = new GenericTask('Diagnostic handler', this),
-      userProviderTask = new GenericTask('Input provider', this),
-      userPackagesDiscoveryTask = new GenericTask('Package discovery', this),
+      userHandlerTask = new GenericTask('Diagnostic handler', measurer),
+      userProviderTask = new GenericTask('Input provider', measurer),
+      userPackagesDiscoveryTask =
+          new GenericTask('Package discovery', measurer),
     ]);
   }
 
@@ -205,11 +210,13 @@
 
   Future<Null> setupSdk() {
     Future future = new Future.value(null);
-    if (options.resolutionInput != null) {
-      reporter.log('Reading serialized data from ${options.resolutionInput}');
-      future = callUserProvider(options.resolutionInput)
-          .then((SourceFile sourceFile) {
-        serialization.deserializeFromText(sourceFile.slowText());
+    if (options.resolutionInputs != null) {
+      future = Future.forEach(options.resolutionInputs, (Uri resolutionInput) {
+        reporter.log('Reading serialized data from ${resolutionInput}');
+        return callUserProvider(resolutionInput).then((SourceFile sourceFile) {
+          serialization.deserializeFromText(
+              resolutionInput, sourceFile.slowText());
+        });
       });
     }
     if (resolvedUriTranslator.isNotSet) {
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index 4e0c2ef..b0f01b8 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -24,12 +24,16 @@
 
 class ClosureTask extends CompilerTask {
   Map<Node, ClosureClassMap> closureMappingCache;
+  Compiler compiler;
   ClosureTask(Compiler compiler)
       : closureMappingCache = new Map<Node, ClosureClassMap>(),
-        super(compiler);
+        compiler = compiler,
+        super(compiler.measurer);
 
   String get name => "Closure Simplifier";
 
+  DiagnosticReporter get reporter => compiler.reporter;
+
   ClosureClassMap computeClosureToClassMapping(ResolvedAst resolvedAst) {
     return measure(() {
       Element element = resolvedAst.element;
@@ -171,6 +175,9 @@
   List<FunctionElement> get nestedClosures => const <FunctionElement>[];
 
   @override
+  bool get hasConstant => false;
+
+  @override
   ConstantExpression get constant => null;
 }
 
@@ -310,6 +317,9 @@
   }
 
   @override
+  bool get hasConstant => false;
+
+  @override
   ConstantExpression get constant => null;
 }
 
@@ -1050,7 +1060,7 @@
     MemberElement enclosing = element.memberContext;
     enclosing.nestedClosures.add(callElement);
     globalizedElement.addMember(callElement, reporter);
-    globalizedElement.computeAllClassMembers(compiler);
+    globalizedElement.computeAllClassMembers(compiler.resolution);
     // The nested function's 'this' is the same as the one for the outer
     // function. It could be [null] if we are inside a static method.
     ThisLocal thisElement = closureData.thisLocal;
diff --git a/pkg/compiler/lib/src/commandline_options.dart b/pkg/compiler/lib/src/commandline_options.dart
index fba8401..013e997 100644
--- a/pkg/compiler/lib/src/commandline_options.dart
+++ b/pkg/compiler/lib/src/commandline_options.dart
@@ -52,6 +52,17 @@
   static const String conditionalDirectives = '--conditional-directives';
 
   // Experimental flags.
+
+  // Considerations about this feature (esp. locations where generalizations
+  // or changes are required for full support of generic methods) are marked
+  // with 'GENERIC_METHODS'. The approach taken is to parse generic methods,
+  // introduce AST nodes for them, generate corresponding types (such that
+  // front end treatment is consistent with the code that programmers wrote),
+  // but considering all method type variables to have bound `dynamic` no
+  // matter which bound they have syntactically (such that their value as types
+  // is unchecked), and then replacing method type variables by a `DynamicType`
+  // (such that the backend does not need to take method type arguments into
+  // account).
   static const String genericMethodSyntax = '--generic-method-syntax';
   static const String resolveOnly = '--resolve-only';
 }
diff --git a/pkg/compiler/lib/src/common/backend_api.dart b/pkg/compiler/lib/src/common/backend_api.dart
index e7f3632..080a03b 100644
--- a/pkg/compiler/lib/src/common/backend_api.dart
+++ b/pkg/compiler/lib/src/common/backend_api.dart
@@ -8,7 +8,7 @@
 
 import '../common.dart';
 import '../common/codegen.dart' show CodegenImpact;
-import '../common/resolution.dart' show ResolutionImpact, Frontend;
+import '../common/resolution.dart' show ResolutionImpact, Frontend, Target;
 import '../compile_time_constants.dart'
     show BackendConstantEnvironment, ConstantCompilerTask;
 import '../compiler.dart' show Compiler;
@@ -44,7 +44,7 @@
 import 'tasks.dart' show CompilerTask;
 import 'work.dart' show ItemCompilationContext;
 
-abstract class Backend {
+abstract class Backend implements Target {
   final Compiler compiler;
 
   Backend(this.compiler);
@@ -256,10 +256,8 @@
   /// defines the implementation of [element].
   MethodElement resolveExternalFunction(MethodElement element) => element;
 
-  /// Returns `true` if [library] is a backend specific library whose members
-  /// have special treatment, such as being allowed to extends blacklisted
-  /// classes or member being eagerly resolved.
-  bool isBackendLibrary(LibraryElement library) {
+  @override
+  bool isTargetSpecificLibrary(LibraryElement library) {
     // TODO(johnniwinther): Remove this when patching is only done by the
     // JavaScript backend.
     Uri canonicalUri = library.canonicalUri;
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 53f6190..7380911 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -7,8 +7,8 @@
 import '../common.dart';
 import '../compiler.dart' show Compiler;
 import '../constants/expressions.dart' show ConstantExpression;
-import '../core_types.dart' show CoreTypes;
-import '../dart_types.dart' show DartType, InterfaceType;
+import '../core_types.dart' show CoreClasses, CoreTypes;
+import '../dart_types.dart' show DartType, InterfaceType, Types;
 import '../elements/elements.dart'
     show
         AstElement,
@@ -17,6 +17,7 @@
         ExecutableElement,
         FunctionElement,
         FunctionSignature,
+        LibraryElement,
         MetadataAnnotation,
         ResolvedAst,
         TypedefElement;
@@ -195,11 +196,22 @@
   ResolutionImpact getResolutionImpact(Element element);
 }
 
+/// Interface defining target-specific behavior for resolution.
+abstract class Target {
+  /// Returns `true` if [library] is a target specific library whose members
+  /// have special treatment, such as being allowed to extends blacklisted
+  /// classes or members being eagerly resolved.
+  bool isTargetSpecificLibrary(LibraryElement element);
+}
+
 // TODO(johnniwinther): Rename to `Resolver` or `ResolverContext`.
 abstract class Resolution implements Frontend {
   ParsingContext get parsingContext;
   DiagnosticReporter get reporter;
+  CoreClasses get coreClasses;
   CoreTypes get coreTypes;
+  Types get types;
+  Target get target;
 
   /// If set to `true` resolution caches will not be cleared. Use this only for
   /// testing.
diff --git a/pkg/compiler/lib/src/common/tasks.dart b/pkg/compiler/lib/src/common/tasks.dart
index 42d5e7b..f1d3426 100644
--- a/pkg/compiler/lib/src/common/tasks.dart
+++ b/pkg/compiler/lib/src/common/tasks.dart
@@ -7,43 +7,36 @@
 import 'dart:async'
     show Future, Zone, ZoneDelegate, ZoneSpecification, runZoned;
 
-import '../common.dart';
-import '../compiler.dart' show Compiler;
-import '../elements/elements.dart' show Element;
-
-typedef void DeferredAction();
-
-class DeferredTask {
-  final Element element;
-  final DeferredAction action;
-
-  DeferredTask(this.element, this.action);
-}
-
-/// A [CompilerTask] is used to measure where time is spent in the compiler.
-/// The main entry points are [measure] and [measureIo].
-class CompilerTask {
-  final Compiler compiler;
-  final Stopwatch watch;
+/// Used to measure where time is spent in the compiler.
+///
+/// This exposes [measure] and [measureIo], which wrap an action and associate
+/// the time spent during that action with this task. Nested measurementsccan be
+/// introduced by using [measureSubtask].
+// TODO(sigmund): rename to MeasurableTask
+abstract class CompilerTask {
+  final Measurer measurer;
+  final Stopwatch _watch;
   final Map<String, GenericTask> _subtasks = <String, GenericTask>{};
 
   int asyncCount = 0;
 
-  CompilerTask(Compiler compiler)
-      : this.compiler = compiler,
-        watch = (compiler.options.verbose) ? new Stopwatch() : null;
+  CompilerTask(Measurer measurer)
+      : measurer = measurer,
+        _watch = measurer.enableTaskMeasurements ? new Stopwatch() : null;
 
-  DiagnosticReporter get reporter => compiler.reporter;
+  /// Whether measurement is disabled. The functions [measure] and [measureIo]
+  /// only measure time if measurements are enabled.
+  bool get _isDisabled => _watch == null;
 
-  Measurer get measurer => compiler.measurer;
-
+  /// Name to use for reporting timing information. Subclasses should override
+  /// this with a proper name, otherwise we use the runtime type of the task.
   String get name => "Unknown task '${this.runtimeType}'";
 
-  bool get isRunning => watch?.isRunning == true;
+  bool get isRunning => _watch?.isRunning == true;
 
   int get timing {
-    if (watch == null) return 0;
-    int total = watch.elapsedMilliseconds;
+    if (_isDisabled) return 0;
+    int total = _watch.elapsedMilliseconds;
     for (GenericTask subtask in _subtasks.values) {
       total += subtask.timing;
     }
@@ -51,40 +44,40 @@
   }
 
   Duration get duration {
-    if (watch == null) return Duration.ZERO;
-    Duration total = watch.elapsed;
+    if (_isDisabled) return Duration.ZERO;
+    Duration total = _watch.elapsed;
     for (GenericTask subtask in _subtasks.values) {
       total += subtask.duration;
     }
     return total;
   }
 
-  /// Perform [action] and use [watch] to measure its runtime (including any
-  /// asynchronous callbacks, such as, [Future.then], but excluding code
-  /// measured by other tasks).
-  measure(action()) => watch == null ? action() : measureZoned(action);
+  /// Perform [action] and measure its runtime (including any asynchronous
+  /// callbacks, such as, [Future.then], but excluding code measured by other
+  /// tasks).
+  measure(action()) => _isDisabled ? action() : _measureZoned(action);
 
   /// Helper method that starts measuring with this [CompilerTask], that is,
   /// make this task the currently measured task.
-  CompilerTask start() {
-    if (watch == null) return null;
+  CompilerTask _start() {
+    if (_isDisabled) return null;
     CompilerTask previous = measurer.currentTask;
     measurer.currentTask = this;
-    if (previous != null) previous.watch.stop();
+    if (previous != null) previous._watch.stop();
     // Regardless of whether [previous] is `null` we've returned from the
     // eventloop.
     measurer.stopAsyncWallClock();
-    watch.start();
+    _watch.start();
     return previous;
   }
 
   /// Helper method that stops measuring with this [CompilerTask], that is,
   /// make [previous] the currently measured task.
-  void stop(CompilerTask previous) {
-    if (watch == null) return;
-    watch.stop();
+  void _stop(CompilerTask previous) {
+    if (_isDisabled) return;
+    _watch.stop();
     if (previous != null) {
-      previous.watch.start();
+      previous._watch.start();
     } else {
       // If there's no previous task, we're about to return control to the
       // event loop. Start counting that as waiting asynchronous I/O.
@@ -93,55 +86,53 @@
     measurer.currentTask = previous;
   }
 
-  /// Helper method for [measure]. Don't call this method directly as it
-  /// assumes that [watch] isn't null.
-  measureZoned(action()) {
+  _measureZoned(action()) {
     // Using zones, we're able to track asynchronous operations correctly, as
     // our zone will be asked to invoke `then` blocks. Then blocks (the closure
     // passed to runZoned, and other closures) are run via the `run` functions
     // below.
 
-    assert(watch != null);
+    assert(_watch != null);
 
     // The current zone is already measuring `this` task.
     if (Zone.current[measurer] == this) return action();
 
     /// Run [f] in [zone]. Running must be delegated to [parent] to ensure that
     /// various state is set up correctly (in particular that `Zone.current`
-    /// has the right value). Since [measureZoned] can be called recursively
+    /// has the right value). Since [_measureZoned] can be called recursively
     /// (synchronously), some of the measuring zones we create will be parents
     /// of other measuring zones, but we still need to call through the parent
     /// chain. Consequently, we use a zone value keyed by [measurer] to see if
     /// we should measure or not when delegating.
     run(Zone self, ZoneDelegate parent, Zone zone, f()) {
       if (zone[measurer] != this) return parent.run(zone, f);
-      CompilerTask previous = start();
+      CompilerTask previous = _start();
       try {
         return parent.run(zone, f);
       } finally {
-        stop(previous);
+        _stop(previous);
       }
     }
 
     /// Same as [run] except that [f] takes one argument, [arg].
     runUnary(Zone self, ZoneDelegate parent, Zone zone, f(arg), arg) {
       if (zone[measurer] != this) return parent.runUnary(zone, f, arg);
-      CompilerTask previous = start();
+      CompilerTask previous = _start();
       try {
         return parent.runUnary(zone, f, arg);
       } finally {
-        stop(previous);
+        _stop(previous);
       }
     }
 
     /// Same as [run] except that [f] takes two arguments ([a1] and [a2]).
     runBinary(Zone self, ZoneDelegate parent, Zone zone, f(a1, a2), a1, a2) {
       if (zone[measurer] != this) return parent.runBinary(zone, f, a1, a2);
-      CompilerTask previous = start();
+      CompilerTask previous = _start();
       try {
         return parent.runBinary(zone, f, a1, a2);
       } finally {
-        stop(previous);
+        _stop(previous);
       }
     }
 
@@ -159,13 +150,8 @@
   /// provider, but it could be used by other tasks as long as the input
   /// provider will not be called by those tasks.
   measureIo(Future action()) {
-    return watch == null ? action() : measureIoHelper(action);
-  }
+    if (_isDisabled) return action();
 
-  /// Helper method for [measureIo]. Don't call this directly as it assumes
-  /// that [watch] isn't null.
-  Future measureIoHelper(Future action()) {
-    assert(watch != null);
     if (measurer.currentAsyncTask == null) {
       measurer.currentAsyncTask = this;
     } else if (measurer.currentAsyncTask != this) {
@@ -179,36 +165,16 @@
     });
   }
 
-  /// Convenience function for combining
-  /// [DiagnosticReporter.withCurrentElement] and [measure].
-  measureElement(Element element, action()) {
-    return watch == null
-        ? reporter.withCurrentElement(element, action)
-        : measureElementHelper(element, action);
-  }
-
-  /// Helper method for [measureElement]. Don't call this directly as it
-  /// assumes that [watch] isn't null.
-  measureElementHelper(Element element, action()) {
-    assert(watch != null);
-    return reporter.withCurrentElement(element, () => measure(action));
-  }
-
   /// Measure the time spent in [action] (if in verbose mode) and accumulate it
   /// under a subtask with the given name.
   measureSubtask(String name, action()) {
-    return watch == null ? action() : measureSubtaskHelper(name, action);
-  }
+    if (_isDisabled) return action();
 
-  /// Helper method for [measureSubtask]. Don't call this directly as it
-  /// assumes that [watch] isn't null.
-  measureSubtaskHelper(String name, action()) {
-    assert(watch != null);
     // Use a nested CompilerTask for the measurement to ensure nested [measure]
     // calls work correctly. The subtasks will never themselves have nested
     // subtasks because they are not accessible outside.
     GenericTask subtask =
-        _subtasks.putIfAbsent(name, () => new GenericTask(name, compiler));
+        _subtasks.putIfAbsent(name, () => new GenericTask(name, measurer));
     return subtask.measure(action);
   }
 
@@ -217,24 +183,36 @@
   int getSubtaskTime(String subtask) => _subtasks[subtask].timing;
 
   bool getSubtaskIsRunning(String subtask) => _subtasks[subtask].isRunning;
+
+  /// Used by the dart2js_incremental to provide measurements on each
+  /// incremental compile.
+  clearMeasurements() {
+    if (_isDisabled) return;
+    _watch.reset();
+    _subtasks.values.forEach((s) => s.clearMeasurements());
+  }
 }
 
 class GenericTask extends CompilerTask {
   final String name;
-
-  GenericTask(this.name, Compiler compiler) : super(compiler);
+  GenericTask(this.name, Measurer measurer) : super(measurer);
 }
 
 class Measurer {
   /// Measures the total runtime from this object was constructed.
   ///
-  /// Note: MUST be first field to ensure [wallclock] is started before other
-  /// computations.
+  /// Note: MUST be the first field of this class to ensure [wallclock] is
+  /// started before other computations.
   final Stopwatch wallClock = new Stopwatch()..start();
 
   /// Measures gaps between zoned closures due to asynchronicity.
   final Stopwatch asyncWallClock = new Stopwatch();
 
+  /// Whether measurement of tasks is enabled.
+  final bool enableTaskMeasurements;
+
+  Measurer({this.enableTaskMeasurements: false});
+
   /// The currently running task, that is, the task whose [Stopwatch] is
   /// currently running.
   CompilerTask currentTask;
@@ -255,7 +233,7 @@
   /// Call this before returning to the eventloop.
   void startAsyncWallClock() {
     if (currentAsyncTask != null) {
-      currentAsyncTask.watch.start();
+      currentAsyncTask._watch.start();
     } else {
       asyncWallClock.start();
     }
@@ -264,7 +242,7 @@
   /// Call this when the eventloop returns control to us.
   void stopAsyncWallClock() {
     if (currentAsyncTask != null) {
-      currentAsyncTask.watch.stop();
+      currentAsyncTask._watch.stop();
     }
     asyncWallClock.stop();
   }
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 82cc6de..9bab3a5 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -6,7 +6,7 @@
 
 import 'common.dart';
 import 'common/resolution.dart' show Resolution;
-import 'common/tasks.dart' show CompilerTask;
+import 'common/tasks.dart' show CompilerTask, Measurer;
 import 'compiler.dart' show Compiler;
 import 'constant_system_dart.dart';
 import 'constants/constant_system.dart';
@@ -16,7 +16,8 @@
 import 'core_types.dart' show CoreTypes;
 import 'dart_types.dart';
 import 'elements/elements.dart';
-import 'elements/modelx.dart' show FieldElementX, FunctionElementX;
+import 'elements/modelx.dart'
+    show FieldElementX, FunctionElementX, ConstantVariableMixin;
 import 'resolution/tree_elements.dart' show TreeElements;
 import 'resolution/operators.dart';
 import 'tree/tree.dart';
@@ -109,7 +110,7 @@
 /// frontend and backend interpretation of compile-time constants.
 abstract class ConstantCompilerTask extends CompilerTask
     implements ConstantCompiler {
-  ConstantCompilerTask(Compiler compiler) : super(compiler);
+  ConstantCompilerTask(Measurer measurer) : super(measurer);
 
   /// Copy all cached constant values from [task].
   ///
@@ -187,8 +188,19 @@
       ConstantExpression result = initialVariableValues[element.declaration];
       return result;
     }
+    if (element.hasConstant) {
+      if (element.constant != null) {
+        if (compiler.serialization.supportsDeserialization) {
+          evaluate(element.constant);
+        }
+        assert(invariant(element, hasConstantValue(element.constant),
+            message: "Constant expression has not been evaluated: "
+                "${element.constant.toStructuredText()}."));
+      }
+      return element.constant;
+    }
     AstElement currentElement = element.analyzableElement;
-    return reporter.withCurrentElement(currentElement, () {
+    return reporter.withCurrentElement(element, () {
       // TODO(johnniwinther): Avoid this eager analysis.
       compiler.resolution.ensureResolved(currentElement.declaration);
 
@@ -206,7 +218,7 @@
    * error.
    */
   ConstantExpression compileVariableWithDefinitions(
-      VariableElement element, TreeElements definitions,
+      ConstantVariableMixin element, TreeElements definitions,
       {bool isConst: false, bool checkType: true}) {
     Node node = element.node;
     if (pendingVariables.contains(element)) {
@@ -238,9 +250,17 @@
         ConstantValue value = getConstantValue(expression);
         if (elementType.isMalformed && !value.isNull) {
           if (isConst) {
-            ErroneousElement element = elementType.element;
-            reporter.reportErrorMessage(
-                node, element.messageKind, element.messageArguments);
+            // TODO(johnniwinther): Check that it is possible to reach this
+            // point in a situation where `elementType is! MalformedType`.
+            if (elementType is MalformedType) {
+              ErroneousElement element = elementType.element;
+              reporter.reportErrorMessage(
+                  node, element.messageKind, element.messageArguments);
+            } else {
+              assert(elementType is MethodTypeVariableType);
+              reporter.reportErrorMessage(
+                  node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED);
+            }
           } else {
             // We need to throw an exception at runtime.
             expression = null;
@@ -262,6 +282,7 @@
       }
     }
     if (expression != null) {
+      element.constant = expression;
       initialVariableValues[element.declaration] = expression;
     } else {
       assert(invariant(element, !isConst,
@@ -583,7 +604,7 @@
     if (send.isPropertyAccess) {
       AstConstant result;
       if (Elements.isStaticOrTopLevelFunction(element)) {
-        FunctionElementX function = element;
+        FunctionElement function = element;
         function.computeType(resolution);
         result = new AstConstant(
             context,
@@ -1280,13 +1301,12 @@
     Map<FieldElement, AstConstant> fieldConstants =
         <FieldElement, AstConstant>{};
     classElement.implementation.forEachInstanceField(
-        (ClassElement enclosing, FieldElementX field) {
+        (ClassElement enclosing, FieldElement field) {
       AstConstant fieldValue = fieldValues[field];
       if (fieldValue == null) {
         // Use the default value.
         ConstantExpression fieldExpression =
             handler.internalCompileVariable(field, true, false);
-        field.constant = fieldExpression;
         fieldValue = new AstConstant.fromDefaultValue(
             field, fieldExpression, handler.getConstantValue(fieldExpression));
         // TODO(het): If the field value doesn't typecheck due to the type
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index de80e0b..7f7a37f 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -15,7 +15,12 @@
 import 'common/names.dart' show Identifiers, Uris;
 import 'common/registry.dart' show EagerRegistry, Registry;
 import 'common/resolution.dart'
-    show ParsingContext, Resolution, ResolutionWorkItem, ResolutionImpact;
+    show
+        ParsingContext,
+        Resolution,
+        ResolutionWorkItem,
+        ResolutionImpact,
+        Target;
 import 'common/tasks.dart' show CompilerTask, GenericTask, Measurer;
 import 'common/work.dart' show ItemCompilationContext, WorkItem;
 import 'common.dart';
@@ -85,11 +90,7 @@
     Compiler compiler, CompilerOptions options);
 
 abstract class Compiler implements LibraryLoaderListener {
-  /// Helper instance for measurements in [CompilerTask].
-  ///
-  /// Note: MUST be first field to ensure [Measurer.wallclock] is started
-  /// before other computations.
-  final Measurer measurer = new Measurer();
+  Measurer get measurer;
 
   final IdGenerator idGenerator = new IdGenerator();
   World world;
@@ -244,8 +245,6 @@
   ti.TypesTask typesTask;
   Backend backend;
 
-  GenericTask reuseLibraryTask;
-
   GenericTask selfTask;
 
   /// The constant environment for the frontend interpretation of compile-time
@@ -260,8 +259,6 @@
   /// A customizable filter that is applied to enqueued work items.
   QueueFilter enqueuerFilter = new QueueFilter();
 
-  static const String CREATE_INVOCATION_MIRROR = 'createInvocationMirror';
-
   bool enabledRuntimeType = false;
   bool enabledFunctionApply = false;
   bool enabledInvokeOn = false;
@@ -339,17 +336,18 @@
 
     tasks = [
       dietParser =
-          new DietParserTask(this, options, idGenerator, backend, reporter),
+          new DietParserTask(options, idGenerator, backend, reporter, measurer),
       scanner = createScannerTask(),
       serialization = new SerializationTask(this),
       libraryLoader = new LibraryLoaderTask(
-          this,
-          this.resolvedUriTranslator,
+          resolvedUriTranslator,
           new _ScriptLoader(this),
           new _ElementScanner(scanner),
-          this.serialization,
+          serialization,
           this,
-          environment),
+          environment,
+          reporter,
+          measurer),
       parser = new ParserTask(this, options),
       patchParser = new PatchParserTask(this, options),
       resolver = createResolverTask(),
@@ -361,8 +359,7 @@
       mirrorUsageAnalyzerTask = new MirrorUsageAnalyzerTask(this),
       enqueuer = backend.makeEnqueuer(),
       dumpInfoTask = new DumpInfoTask(this),
-      reuseLibraryTask = new GenericTask('Reuse library', this),
-      selfTask = new GenericTask('self', this),
+      selfTask = new GenericTask('self', measurer),
     ];
     if (options.resolveOnly) {
       serialization.supportSerialization = true;
@@ -377,8 +374,9 @@
   /// Creates the scanner task.
   ///
   /// Override this to mock the scanner for testing.
-  ScannerTask createScannerTask() => new ScannerTask(this, dietParser,
-      preserveComments: options.preserveComments, commentMap: commentMap);
+  ScannerTask createScannerTask() =>
+      new ScannerTask(dietParser, reporter, measurer,
+          preserveComments: options.preserveComments, commentMap: commentMap);
 
   /// Creates the resolver task.
   ///
@@ -1033,7 +1031,7 @@
       if (identical(e.kind, ElementKind.GENERATIVE_CONSTRUCTOR)) {
         resolved.remove(e);
       }
-      if (backend.isBackendLibrary(e.library)) {
+      if (backend.isTargetSpecificLibrary(e.library)) {
         resolved.remove(e);
       }
     }
@@ -1557,6 +1555,9 @@
     }
   }
 
+  @override
+  bool get hasReportedError => compiler.compilationFailed;
+
   /**
    * Perform an operation, [f], returning the return value from [f].  If an
    * error occurs then report it as having occurred during compilation of
@@ -1886,9 +1887,18 @@
   ParsingContext get parsingContext => compiler.parsingContext;
 
   @override
+  CoreClasses get coreClasses => compiler.coreClasses;
+
+  @override
   CoreTypes get coreTypes => compiler.coreTypes;
 
   @override
+  Types get types => compiler.types;
+
+  @override
+  Target get target => compiler.backend;
+
+  @override
   void registerClass(ClassElement cls) {
     compiler.world.registerClass(cls);
   }
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
index dd756c6..3e1f9bf 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder.dart
@@ -2734,10 +2734,18 @@
     type = program.unaliasType(type);
 
     if (type.isMalformed) {
-      ErroneousElement element = type.element;
-      ir.Primitive message = buildStringConstant(element.message);
+      String message;
+      if (type is MalformedType) {
+        ErroneousElement element = type.element;
+        message = element.message;
+      } else {
+        assert(type is MethodTypeVariableType);
+        message = "Method type variables are not reified, "
+            "so they cannot be tested dynamically";
+      }
+      ir.Primitive irMessage = buildStringConstant(message);
       return buildStaticFunctionInvocation(program.throwTypeErrorHelper,
-          <ir.Primitive>[message], sourceInformation);
+          <ir.Primitive>[irMessage], sourceInformation);
     }
 
     List<ir.Primitive> typeArguments = const <ir.Primitive>[];
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index 29b516d..18eeb52 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -56,6 +56,7 @@
 /// takes.
 class IrBuilderTask extends CompilerTask {
   final SourceInformationStrategy sourceInformationStrategy;
+  final Compiler compiler;
 
   String bailoutMessage = null;
 
@@ -65,7 +66,8 @@
 
   IrBuilderTask(Compiler compiler, this.sourceInformationStrategy,
       [this.builderCallback])
-      : super(compiler);
+      : compiler = compiler,
+        super(compiler.measurer);
 
   String get name => 'CPS builder';
 
@@ -76,7 +78,7 @@
 
       ResolvedAst resolvedAst = element.resolvedAst;
       element = element.implementation;
-      return reporter.withCurrentElement(element, () {
+      return compiler.reporter.withCurrentElement(element, () {
         SourceInformationBuilder sourceInformationBuilder =
             sourceInformationStrategy.createBuilderForContext(resolvedAst);
 
diff --git a/pkg/compiler/lib/src/dart2js.dart b/pkg/compiler/lib/src/dart2js.dart
index 5dffdf7de..64bb70a 100644
--- a/pkg/compiler/lib/src/dart2js.dart
+++ b/pkg/compiler/lib/src/dart2js.dart
@@ -108,7 +108,7 @@
   Uri libraryRoot = currentDirectory;
   Uri out = currentDirectory.resolve('out.js');
   Uri sourceMapOut = currentDirectory.resolve('out.js.map');
-  Uri resolutionInput;
+  List<Uri> resolutionInputs;
   Uri packageConfig = null;
   Uri packageRoot = null;
   List<String> options = new List<String>();
@@ -190,8 +190,11 @@
   }
 
   void setResolutionInput(String argument) {
-    resolutionInput =
-        currentDirectory.resolve(extractPath(argument, isDirectory: false));
+    resolutionInputs = <Uri>[];
+    String parts = extractParameter(argument);
+    for (String part in parts.split(',')) {
+      resolutionInputs.add(currentDirectory.resolve(nativeToUriPath(part)));
+    }
   }
 
   void setResolveOnly(String argument) {
@@ -525,7 +528,7 @@
       packageRoot: packageRoot,
       packageConfig: packageConfig,
       packagesDiscoveryProvider: findPackages,
-      resolutionInput: resolutionInput,
+      resolutionInputs: resolutionInputs,
       resolutionOutput: resolutionOutput,
       options: options,
       environment: environment);
@@ -834,6 +837,9 @@
 final bool USE_SERIALIZED_DART_CORE =
     Platform.environment['USE_SERIALIZED_DART_CORE'] == 'true';
 
+/// Mock URI used only in testing when [USE_SERIALIZED_DART_CORE] is enabled.
+final Uri _SERIALIZED_URI = Uri.parse('file:fake.data');
+
 void _useSerializedDataForDartCore(CompileFunc oldCompileFunc) {
   String serializedData;
 
@@ -844,7 +850,7 @@
       api.CompilerOutput compilerOutput) async {
     CompilerImpl compiler = new CompilerImpl(
         compilerInput, compilerOutput, compilerDiagnostics, compilerOptions);
-    compiler.serialization.deserializeFromText(serializedData);
+    compiler.serialization.deserializeFromText(_SERIALIZED_URI, serializedData);
     return compiler.run(compilerOptions.entryPoint).then((bool success) {
       return new api.CompilationResult(compiler, isSuccess: success);
     });
@@ -865,7 +871,7 @@
             packagesDiscoveryProvider:
                 compilerOptions.packagesDiscoveryProvider,
             environment: compilerOptions.environment,
-            resolutionOutput: Uri.parse('file:fake.data'),
+            resolutionOutput: _SERIALIZED_URI,
             options: [Flags.resolveOnly]),
         compilerInput,
         compilerDiagnostics,
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index 5f3eed9..9a1162e 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -457,7 +457,7 @@
 
   DartConstantTask(Compiler compiler)
       : this.constantCompiler = new DartConstantCompiler(compiler),
-        super(compiler);
+        super(compiler.measurer);
 
   String get name => 'ConstantHandler';
 
diff --git a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
index 03f0ba1..469858d 100644
--- a/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend_ast_to_frontend_ast.dart
@@ -495,7 +495,8 @@
           : makeFunctionBody(exp.body);
       result = new tree.FunctionExpression(
           constructorName(exp),
-          // TODO(eernst): retrieve and pass the actual type variables.
+          // GENERIC_METHODS: In order to support generic methods fully,
+          // we must retrieve and pass the actual type variables here.
           null, // typeVariables
           parameters,
           body,
@@ -516,7 +517,8 @@
       tree.Node body = makeFunctionBody(exp.body);
       result = new tree.FunctionExpression(
           functionName(exp),
-          // TODO(eernst): retrieve and pass the actual type variables.
+          // GENERIC_METHODS: In order to support generic methods fully,
+          // we must retrieve and pass the actual type variables here.
           null, // typeVariables
           parameters,
           body,
@@ -802,7 +804,8 @@
     } else if (stmt is FunctionDeclaration) {
       tree.FunctionExpression function = new tree.FunctionExpression(
           stmt.name != null ? makeIdentifier(stmt.name) : null,
-          // TODO(eernst): retrieve and pass the actual type variables.
+          // GENERIC_METHODS: In order to support generic methods fully,
+          // we must retrieve and pass the actual type variables here.
           null, // typeVariables
           makeParameters(stmt.parameters),
           makeFunctionBody(stmt.body),
@@ -971,7 +974,8 @@
     if (param.isFunction) {
       tree.Node definition = new tree.FunctionExpression(
           makeIdentifier(param.name),
-          // TODO(eernst): retrieve and pass the actual type variables.
+          // GENERIC_METHODS: In order to support generic methods fully,
+          // we must retrieve and pass the actual type variables here.
           null, // typeVariables
           makeParameters(param.parameters),
           null, // body
diff --git a/pkg/compiler/lib/src/dart_types.dart b/pkg/compiler/lib/src/dart_types.dart
index 685077d..fb0eac4 100644
--- a/pkg/compiler/lib/src/dart_types.dart
+++ b/pkg/compiler/lib/src/dart_types.dart
@@ -10,7 +10,7 @@
 import 'common.dart';
 import 'core_types.dart';
 import 'elements/elements.dart';
-import 'elements/modelx.dart' show TypeDeclarationElementX;
+import 'elements/modelx.dart' show TypeDeclarationElementX, ErroneousElementX;
 import 'ordered_typeset.dart' show OrderedTypeSet;
 import 'util/util.dart' show equalElements;
 
@@ -124,7 +124,7 @@
   bool get isTypeVariable => kind == TypeKind.TYPE_VARIABLE;
 
   /// Is [: true :] if this type is a malformed type.
-  bool get isMalformed => kind == TypeKind.MALFORMED_TYPE;
+  bool get isMalformed => false;
 
   /// Is `true` if this type is declared by an enum.
   bool get isEnumType => false;
@@ -164,6 +164,15 @@
       type.accept(visitor, argument);
     }
   }
+
+  /// Returns a [DartType] which corresponds to [this] except that each
+  /// contained [MethodTypeVariableType] is replaced by a [DynamicType].
+  /// GENERIC_METHODS: Temporary, only used with '--generic-method-syntax'.
+  DartType get dynamifyMethodTypeVariableType => this;
+
+  /// Returns true iff [this] is or contains a [MethodTypeVariableType].
+  /// GENERIC_METHODS: Temporary, only used with '--generic-method-syntax'
+  bool get containsMethodTypeVariableType => false;
 }
 
 /**
@@ -234,6 +243,25 @@
   String toString() => name;
 }
 
+/// Provides a thin model of method type variables: They are treated as if
+/// their value were `dynamic` when used in a type annotation, and as a
+/// malformed type when used in an `as` or `is` expression.
+class MethodTypeVariableType extends TypeVariableType {
+  MethodTypeVariableType(TypeVariableElement element) : super(element);
+
+  @override
+  bool get treatAsDynamic => true;
+
+  @override
+  bool get isMalformed => true;
+
+  @override
+  DartType get dynamifyMethodTypeVariableType => const DynamicType();
+
+  @override
+  get containsMethodTypeVariableType => true;
+}
+
 /// Internal type representing the result of analyzing a statement.
 class StatementType extends DartType {
   Element get element => null;
@@ -313,6 +341,9 @@
   // Malformed types are treated as dynamic.
   bool get treatAsDynamic => true;
 
+  @override
+  bool get isMalformed => true;
+
   accept(DartTypeVisitor visitor, var argument) {
     return visitor.visitMalformedType(this, argument);
   }
@@ -341,9 +372,12 @@
   final TypeDeclarationElement element;
   final List<DartType> typeArguments;
 
-  GenericType(TypeDeclarationElement element, this.typeArguments,
+  GenericType(TypeDeclarationElement element, List<DartType> typeArguments,
       {bool checkTypeArgumentCount: true})
-      : this.element = element {
+      : this.element = element,
+        this.typeArguments = typeArguments,
+        this.containsMethodTypeVariableType =
+            typeArguments.any(_typeContainsMethodTypeVariableType) {
     assert(invariant(CURRENT_ELEMENT_SPANNABLE, element != null,
         message: "Missing element for generic type."));
     assert(invariant(element, () {
@@ -405,6 +439,18 @@
     return sb.toString();
   }
 
+  @override
+  final bool containsMethodTypeVariableType;
+
+  @override
+  DartType get dynamifyMethodTypeVariableType {
+    if (!containsMethodTypeVariableType) return this;
+    List<DartType> newTypeArguments = typeArguments
+        .map((DartType type) => type.dynamifyMethodTypeVariableType)
+        .toList();
+    return createInstantiation(newTypeArguments);
+  }
+
   int get hashCode {
     int hash = element.hashCode;
     for (DartType argument in typeArguments) {
@@ -586,11 +632,21 @@
   }
 
   FunctionType.internal(FunctionTypedElement this.element,
-      [DartType this.returnType = const DynamicType(),
-      this.parameterTypes = const <DartType>[],
-      this.optionalParameterTypes = const <DartType>[],
-      this.namedParameters = const <String>[],
-      this.namedParameterTypes = const <DartType>[]]) {
+      [DartType returnType = const DynamicType(),
+      List<DartType> parameterTypes = const <DartType>[],
+      List<DartType> optionalParameterTypes = const <DartType>[],
+      List<String> namedParameters = const <String>[],
+      List<DartType> namedParameterTypes = const <DartType>[]])
+      : this.returnType = returnType,
+        this.parameterTypes = parameterTypes,
+        this.optionalParameterTypes = optionalParameterTypes,
+        this.namedParameters = namedParameters,
+        this.namedParameterTypes = namedParameterTypes,
+        this.containsMethodTypeVariableType = returnType
+                .containsMethodTypeVariableType ||
+            parameterTypes.any(_typeContainsMethodTypeVariableType) ||
+            optionalParameterTypes.any(_typeContainsMethodTypeVariableType) ||
+            namedParameterTypes.any(_typeContainsMethodTypeVariableType) {
     assert(invariant(
         CURRENT_ELEMENT_SPANNABLE, element == null || element.isDeclaration));
     // Assert that optional and named parameters are not used at the same time.
@@ -718,6 +774,23 @@
 
   int computeArity() => parameterTypes.length;
 
+  @override
+  DartType get dynamifyMethodTypeVariableType {
+    if (!containsMethodTypeVariableType) return this;
+    DartType eraseIt(DartType type) => type.dynamifyMethodTypeVariableType;
+    DartType newReturnType = returnType.dynamifyMethodTypeVariableType;
+    List<DartType> newParameterTypes = parameterTypes.map(eraseIt).toList();
+    List<DartType> newOptionalParameterTypes =
+        optionalParameterTypes.map(eraseIt).toList();
+    List<DartType> newNamedParameterTypes =
+        namedParameterTypes.map(eraseIt).toList();
+    return new FunctionType.internal(element, newReturnType, newParameterTypes,
+        newOptionalParameterTypes, namedParameters, newNamedParameterTypes);
+  }
+
+  @override
+  final bool containsMethodTypeVariableType;
+
   int get hashCode {
     int hash = 3 * returnType.hashCode;
     for (DartType parameter in parameterTypes) {
@@ -745,6 +818,9 @@
   }
 }
 
+bool _typeContainsMethodTypeVariableType(DartType type) =>
+    type.containsMethodTypeVariableType;
+
 class TypedefType extends GenericType {
   DartType _unaliased;
 
@@ -1347,6 +1423,15 @@
   static ClassElement getClassContext(DartType type) {
     TypeVariableType typeVariable = type.typeVariableOccurrence;
     if (typeVariable == null) return null;
+    // GENERIC_METHODS: When generic method support is complete enough to
+    // include a runtime value for method type variables this must be updated.
+    // For full support the global assumption that all type variables are
+    // declared by the same enclosing class will not hold: Both an enclosing
+    // method and an enclosing class may define type variables, so the return
+    // type cannot be [ClassElement] and the caller must be prepared to look in
+    // two locations, not one. Currently we ignore method type variables by
+    // returning in the next statement.
+    if (typeVariable.element.typeDeclaration is! ClassElement) return null;
     return typeVariable.element.typeDeclaration;
   }
 
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index c34c06e..18e85ad 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -152,11 +152,15 @@
 
   Set<Element> _mainElements = new Set<Element>();
 
-  DeferredLoadTask(Compiler compiler) : super(compiler) {
+  final Compiler compiler;
+  DeferredLoadTask(Compiler compiler)
+      : compiler = compiler,
+        super(compiler.measurer) {
     mainOutputUnit.imports.add(_fakeMainImport);
   }
 
   Backend get backend => compiler.backend;
+  DiagnosticReporter get reporter => compiler.reporter;
 
   /// Returns the [OutputUnit] where [element] belongs.
   OutputUnit outputUnitForElement(Element element) {
@@ -629,88 +633,97 @@
     _constantsDeferredBy = new Map<_DeferredImport, Set<ConstantValue>>();
     _importedDeferredBy[_fakeMainImport] = _mainElements;
 
-    measureElement(mainLibrary, () {
-      // Starting from main, traverse the program and find all dependencies.
-      _mapDependencies(element: compiler.mainFunction, import: _fakeMainImport);
+    reporter.withCurrentElement(
+        mainLibrary,
+        () => measure(() {
+              // Starting from main, traverse the program and find all
+              // dependencies.
+              _mapDependencies(
+                  element: compiler.mainFunction, import: _fakeMainImport);
 
-      // Also add "global" dependencies to the main OutputUnit.  These are
-      // things that the backend needs but cannot associate with a particular
-      // element, for example, startRootIsolate.  This set also contains
-      // elements for which we lack precise information.
-      for (Element element in compiler.globalDependencies.otherDependencies) {
-        _mapDependencies(element: element, import: _fakeMainImport);
-      }
+              // Also add "global" dependencies to the main OutputUnit.  These
+              // are things that the backend needs but cannot associate with a
+              // particular element, for example, startRootIsolate.  This set
+              // also contains elements for which we lack precise information.
+              for (Element element
+                  in compiler.globalDependencies.otherDependencies) {
+                _mapDependencies(element: element, import: _fakeMainImport);
+              }
 
-      // Now check to see if we have to add more elements due to mirrors.
-      if (compiler.mirrorsLibrary != null) {
-        _addMirrorElements();
-      }
+              // Now check to see if we have to add more elements due to
+              // mirrors.
+              if (compiler.mirrorsLibrary != null) {
+                _addMirrorElements();
+              }
 
-      // Build the OutputUnits using these two maps.
-      Map<Element, OutputUnit> elementToOutputUnitBuilder =
-          new Map<Element, OutputUnit>();
-      Map<ConstantValue, OutputUnit> constantToOutputUnitBuilder =
-          new Map<ConstantValue, OutputUnit>();
+              // Build the OutputUnits using these two maps.
+              Map<Element, OutputUnit> elementToOutputUnitBuilder =
+                  new Map<Element, OutputUnit>();
+              Map<ConstantValue, OutputUnit> constantToOutputUnitBuilder =
+                  new Map<ConstantValue, OutputUnit>();
 
-      // Reverse the mappings. For each element record an OutputUnit collecting
-      // all deferred imports mapped to this element. Same for constants.
-      for (_DeferredImport import in _importedDeferredBy.keys) {
-        for (Element element in _importedDeferredBy[import]) {
-          // Only one file should be loaded when the program starts, so make
-          // sure that only one OutputUnit is created for [fakeMainImport].
-          if (import == _fakeMainImport) {
-            elementToOutputUnitBuilder[element] = mainOutputUnit;
-          } else {
-            elementToOutputUnitBuilder
-                .putIfAbsent(element, () => new OutputUnit())
-                .imports
-                .add(import);
-          }
-        }
-      }
-      for (_DeferredImport import in _constantsDeferredBy.keys) {
-        for (ConstantValue constant in _constantsDeferredBy[import]) {
-          // Only one file should be loaded when the program starts, so make
-          // sure that only one OutputUnit is created for [fakeMainImport].
-          if (import == _fakeMainImport) {
-            constantToOutputUnitBuilder[constant] = mainOutputUnit;
-          } else {
-            constantToOutputUnitBuilder
-                .putIfAbsent(constant, () => new OutputUnit())
-                .imports
-                .add(import);
-          }
-        }
-      }
+              // Reverse the mappings. For each element record an OutputUnit
+              // collecting all deferred imports mapped to this element. Same
+              // for constants.
+              for (_DeferredImport import in _importedDeferredBy.keys) {
+                for (Element element in _importedDeferredBy[import]) {
+                  // Only one file should be loaded when the program starts, so
+                  // make sure that only one OutputUnit is created for
+                  // [fakeMainImport].
+                  if (import == _fakeMainImport) {
+                    elementToOutputUnitBuilder[element] = mainOutputUnit;
+                  } else {
+                    elementToOutputUnitBuilder
+                        .putIfAbsent(element, () => new OutputUnit())
+                        .imports
+                        .add(import);
+                  }
+                }
+              }
+              for (_DeferredImport import in _constantsDeferredBy.keys) {
+                for (ConstantValue constant in _constantsDeferredBy[import]) {
+                  // Only one file should be loaded when the program starts, so
+                  // make sure that only one OutputUnit is created for
+                  // [fakeMainImport].
+                  if (import == _fakeMainImport) {
+                    constantToOutputUnitBuilder[constant] = mainOutputUnit;
+                  } else {
+                    constantToOutputUnitBuilder
+                        .putIfAbsent(constant, () => new OutputUnit())
+                        .imports
+                        .add(import);
+                  }
+                }
+              }
 
-      // Release maps;
-      _importedDeferredBy = null;
-      _constantsDeferredBy = null;
+              // Release maps;
+              _importedDeferredBy = null;
+              _constantsDeferredBy = null;
 
-      // Find all the output units elements/constants have been mapped to, and
-      // canonicalize them.
-      elementToOutputUnitBuilder
-          .forEach((Element element, OutputUnit outputUnit) {
-        OutputUnit representative = allOutputUnits.lookup(outputUnit);
-        if (representative == null) {
-          representative = outputUnit;
-          allOutputUnits.add(representative);
-        }
-        _elementToOutputUnit[element] = representative;
-      });
-      constantToOutputUnitBuilder
-          .forEach((ConstantValue constant, OutputUnit outputUnit) {
-        OutputUnit representative = allOutputUnits.lookup(outputUnit);
-        if (representative == null) {
-          representative = outputUnit;
-          allOutputUnits.add(representative);
-        }
-        _constantToOutputUnit[constant] = representative;
-      });
+              // Find all the output units elements/constants have been mapped
+              // to, and canonicalize them.
+              elementToOutputUnitBuilder
+                  .forEach((Element element, OutputUnit outputUnit) {
+                OutputUnit representative = allOutputUnits.lookup(outputUnit);
+                if (representative == null) {
+                  representative = outputUnit;
+                  allOutputUnits.add(representative);
+                }
+                _elementToOutputUnit[element] = representative;
+              });
+              constantToOutputUnitBuilder
+                  .forEach((ConstantValue constant, OutputUnit outputUnit) {
+                OutputUnit representative = allOutputUnits.lookup(outputUnit);
+                if (representative == null) {
+                  representative = outputUnit;
+                  allOutputUnits.add(representative);
+                }
+                _constantToOutputUnit[constant] = representative;
+              });
 
-      // Generate a unique name for each OutputUnit.
-      _assignNamesToOutputUnits(allOutputUnits);
-    });
+              // Generate a unique name for each OutputUnit.
+              _assignNamesToOutputUnits(allOutputUnits);
+            }));
     // Notify the impact strategy impacts are no longer needed for deferred
     // load.
     compiler.impactStrategy.onImpactUsed(IMPACT_USE);
diff --git a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
index e31edde..0a9c5f5 100644
--- a/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
+++ b/pkg/compiler/lib/src/diagnostics/diagnostic_listener.dart
@@ -61,6 +61,9 @@
   DiagnosticMessage createMessage(Spannable spannable, MessageKind messageKind,
       [Map arguments = const {}]);
 
+  /// Returns `true` if a crash, an error or a fatal warning has been reported.
+  bool get hasReportedError;
+
   /// Called when an [exception] is thrown from user-provided code, like from
   /// the input provider or diagnostics handler.
   void onCrashInUserCode(String message, exception, stackTrace) {}
diff --git a/pkg/compiler/lib/src/diagnostics/messages.dart b/pkg/compiler/lib/src/diagnostics/messages.dart
index bbe777e..ad689fd 100644
--- a/pkg/compiler/lib/src/diagnostics/messages.dart
+++ b/pkg/compiler/lib/src/diagnostics/messages.dart
@@ -177,6 +177,7 @@
   DUPLICATE_IMPORT,
   DUPLICATE_INITIALIZER,
   DUPLICATE_LABEL,
+  DUPLICATE_SERIALIZED_LIBRARY,
   DUPLICATE_SUPER_INITIALIZER,
   DUPLICATE_TYPE_VARIABLE_NAME,
   DUPLICATED_LIBRARY_NAME,
@@ -430,6 +431,7 @@
   TYPE_ARGUMENT_COUNT_MISMATCH,
   TYPE_VARIABLE_IN_CONSTANT,
   TYPE_VARIABLE_WITHIN_STATIC_MEMBER,
+  TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED,
   TYPEDEF_FORMAL_WITH_DEFAULT,
   UNARY_OPERATOR_BAD_ARITY,
   UNBOUND_LABEL,
@@ -1152,6 +1154,33 @@
 """
           ]),
 
+      MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED: const MessageTemplate(
+          MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED,
+          "Method type variables do not have a runtime value.",
+          options: const ["--generic-method-syntax"],
+          howToFix: "Try using the upper bound of the type variable, "
+              "or refactor the code to avoid needing this runtime value.",
+          examples: const [
+            """
+// Method type variables are not reified, so they cannot be returned.
+Type f<T>() => T;
+
+main() => f<int>();
+""",
+            """
+// Method type variables are not reified, so they cannot be tested dynamically.
+bool f<T>(Object o) => o is T;
+
+main() => f<int>(42);
+""",
+            """
+// Method type variables are not reified, so they cannot be tested dynamically.
+bool f<T>(Object o) => o as T;
+
+main() => f<int>(42);
+"""
+          ]),
+
       MessageKind.INVALID_TYPE_VARIABLE_BOUND: const MessageTemplate(
           MessageKind.INVALID_TYPE_VARIABLE_BOUND,
           "'#{typeArgument}' is not a subtype of bound '#{bound}' for "
@@ -3643,6 +3672,11 @@
           MessageKind.UNRECOGNIZED_VERSION_OF_LOOKUP_MAP,
           "Unsupported version of package:lookup_map.",
           howToFix: DONT_KNOW_HOW_TO_FIX),
+
+      MessageKind.DUPLICATE_SERIALIZED_LIBRARY: const MessageTemplate(
+          MessageKind.DUPLICATE_SERIALIZED_LIBRARY,
+          "Library '#{libraryUri}' found in both '#{sourceUri1}' and "
+          "'#{sourceUri2}'."),
     }); // End of TEMPLATES.
 
   /// Padding used before and between import chains in the message for
diff --git a/pkg/compiler/lib/src/dump_info.dart b/pkg/compiler/lib/src/dump_info.dart
index 0ee0093..a8c39fa 100644
--- a/pkg/compiler/lib/src/dump_info.dart
+++ b/pkg/compiler/lib/src/dump_info.dart
@@ -368,8 +368,11 @@
 
 class DumpInfoTask extends CompilerTask implements InfoReporter {
   static const ImpactUseCase IMPACT_USE = const ImpactUseCase('Dump info');
+  final Compiler compiler;
 
-  DumpInfoTask(Compiler compiler) : super(compiler);
+  DumpInfoTask(Compiler compiler)
+      : compiler = compiler,
+        super(compiler.measurer);
 
   String get name => "Dump Info";
 
@@ -588,7 +591,7 @@
     ChunkedConversionSink<Object> sink = encoder.startChunkedConversion(
         new StringConversionSink.fromStringSink(buffer));
     sink.add(new AllInfoJsonCodec().encode(result));
-    reporter.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, {
+    compiler.reporter.reportInfo(NO_LOCATION_SPANNABLE, MessageKind.GENERIC, {
       'text': "View the dumped .info.json file at "
           "https://dart-lang.github.io/dump-info-visualizer"
     });
diff --git a/pkg/compiler/lib/src/elements/elements.dart b/pkg/compiler/lib/src/elements/elements.dart
index 2e6adb0..dc708d0 100644
--- a/pkg/compiler/lib/src/elements/elements.dart
+++ b/pkg/compiler/lib/src/elements/elements.dart
@@ -1005,6 +1005,8 @@
 
   Expression get initializer;
 
+  bool get hasConstant;
+
   /// The constant expression defining the (initial) value of the variable.
   ///
   /// If the variable is `const` the value is always non-null, possibly an
@@ -1236,6 +1238,10 @@
 /// A constructor.
 abstract class ConstructorElement extends FunctionElement
     implements MemberElement {
+  /// Returns `true` if [effectiveTarget] has been computed for this
+  /// constructor.
+  bool get hasEffectiveTarget;
+
   /// The effective target of this constructor, that is the non-redirecting
   /// constructor that is called on invocation of this constructor.
   ///
diff --git a/pkg/compiler/lib/src/elements/modelx.dart b/pkg/compiler/lib/src/elements/modelx.dart
index 3e14846..2381d64 100644
--- a/pkg/compiler/lib/src/elements/modelx.dart
+++ b/pkg/compiler/lib/src/elements/modelx.dart
@@ -256,6 +256,8 @@
 
   bool get hasFunctionSignature => false;
 
+  bool get hasEffectiveTarget => true;
+
   get effectiveTarget => this;
 
   computeEffectiveTargetType(InterfaceType newType) => unsupported();
@@ -1391,6 +1393,11 @@
 abstract class ConstantVariableMixin implements VariableElement {
   ConstantExpression constantCache;
 
+  // TODO(johnniwinther): Update the on `constant = ...` when evaluation of
+  // constant expression can handle references to unanalyzed constant variables.
+  @override
+  bool get hasConstant => false;
+
   ConstantExpression get constant {
     if (isPatch) {
       ConstantVariableMixin originVariable = origin;
@@ -2199,6 +2206,8 @@
   DartType _effectiveTargetType;
   bool _isEffectiveTargetMalformed;
 
+  bool get hasEffectiveTarget => effectiveTargetInternal != null;
+
   void setEffectiveTarget(ConstructorElement target, DartType type,
       {bool isMalformed: false}) {
     assert(invariant(this, target != null,
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index f619520..29ae8ea 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -10,7 +10,7 @@
 import 'common/names.dart' show Identifiers;
 import 'common/resolution.dart' show Resolution;
 import 'common/resolution.dart' show ResolutionWorkItem;
-import 'common/tasks.dart' show CompilerTask, DeferredAction, DeferredTask;
+import 'common/tasks.dart' show CompilerTask;
 import 'common/work.dart' show ItemCompilationContext, WorkItem;
 import 'common.dart';
 import 'compiler.dart' show Compiler;
@@ -46,11 +46,13 @@
 class EnqueueTask extends CompilerTask {
   final ResolutionEnqueuer resolution;
   final CodegenEnqueuer codegen;
+  final Compiler compiler;
 
   String get name => 'Enqueue';
 
   EnqueueTask(Compiler compiler)
-      : resolution = new ResolutionEnqueuer(
+      : compiler = compiler,
+        resolution = new ResolutionEnqueuer(
             compiler,
             compiler.backend.createItemCompilationContext,
             compiler.options.analyzeOnly && compiler.options.analyzeMain
@@ -60,7 +62,7 @@
             compiler,
             compiler.backend.createItemCompilationContext,
             const TreeShakingEnqueuerStrategy()),
-        super(compiler) {
+        super(compiler.measurer) {
     codegen.task = this;
     resolution.task = this;
 
@@ -714,11 +716,9 @@
 
   final Queue<ResolutionWorkItem> queue;
 
-  /**
-   * A deferred task queue for the resolution phase which is processed
-   * when the resolution queue has been emptied.
-   */
-  final Queue<DeferredTask> deferredTaskQueue;
+  /// Queue of deferred resolution actions to execute when the resolution queue
+  /// has been emptied.
+  final Queue<_DeferredAction> deferredQueue;
 
   static const ImpactUseCase IMPACT_USE =
       const ImpactUseCase('ResolutionEnqueuer');
@@ -733,7 +733,7 @@
             strategy),
         processedElements = new Set<AstElement>(),
         queue = new Queue<ResolutionWorkItem>(),
-        deferredTaskQueue = new Queue<DeferredTask>();
+        deferredQueue = new Queue<_DeferredAction>();
 
   bool get isResolutionQueue => true;
 
@@ -831,24 +831,26 @@
    *
    * The queue is processed in FIFO order.
    */
-  void addDeferredAction(Element element, DeferredAction action) {
+  void addDeferredAction(Element element, void action()) {
     if (queueIsClosed) {
       throw new SpannableAssertionFailure(
           element,
           "Resolution work list is closed. "
           "Trying to add deferred action for $element");
     }
-    deferredTaskQueue.add(new DeferredTask(element, action));
+    deferredQueue.add(new _DeferredAction(element, action));
   }
 
   bool onQueueEmpty(Iterable<ClassElement> recentClasses) {
-    emptyDeferredTaskQueue();
+    _emptyDeferredQueue();
     return super.onQueueEmpty(recentClasses);
   }
 
-  void emptyDeferredTaskQueue() {
-    while (!deferredTaskQueue.isEmpty) {
-      DeferredTask task = deferredTaskQueue.removeFirst();
+  void emptyDeferredQueueForTesting() => _emptyDeferredQueue();
+
+  void _emptyDeferredQueue() {
+    while (!deferredQueue.isEmpty) {
+      _DeferredAction task = deferredQueue.removeFirst();
       reporter.withCurrentElement(task.element, task.action);
     }
   }
@@ -1044,3 +1046,12 @@
     enqueuer.registerTypeUse(typeUse);
   }
 }
+
+typedef void _DeferredActionFunction();
+
+class _DeferredAction {
+  final Element element;
+  final _DeferredActionFunction action;
+
+  _DeferredAction(this.element, this.action);
+}
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index 5f334e3..e8f43ca 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -2703,7 +2703,12 @@
           if (type.isTypedef) {
             backend.compiler.world.allTypedefs.add(type.element);
           }
-          if (type.isTypeVariable) {
+          if (type.isTypeVariable && type is! MethodTypeVariableType) {
+            // GENERIC_METHODS: The `is!` test above filters away method type
+            // variables, because they have the value `dynamic` with the
+            // incomplete support for generic methods offered with
+            // '--generic-method-syntax'. This must be revised in order to
+            // support generic methods fully.
             ClassElement cls = type.element.enclosingClass;
             backend.rti.registerClassUsingTypeVariableExpression(cls);
             registerBackendImpact(transformed, impacts.typeVariableExpression);
diff --git a/pkg/compiler/lib/src/js_backend/backend_helpers.dart b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
index 5863104..7613305 100644
--- a/pkg/compiler/lib/src/js_backend/backend_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_helpers.dart
@@ -553,7 +553,7 @@
   }
 
   Element get createInvocationMirror {
-    return findHelper(Compiler.CREATE_INVOCATION_MIRROR);
+    return findHelper('createInvocationMirror');
   }
 
   Element get cyclicThrowHelper {
diff --git a/pkg/compiler/lib/src/js_backend/codegen/task.dart b/pkg/compiler/lib/src/js_backend/codegen/task.dart
index c293d5a..69b13f3 100644
--- a/pkg/compiler/lib/src/js_backend/codegen/task.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen/task.dart
@@ -68,9 +68,11 @@
         constantSystem = backend.constantSystem,
         compiler = compiler,
         glue = new Glue(compiler),
-        cpsOptimizationTask = new GenericTask('CPS optimization', compiler),
-        treeBuilderTask = new GenericTask('Tree builder', compiler),
-        treeOptimizationTask = new GenericTask('Tree optimization', compiler) {
+        cpsOptimizationTask =
+            new GenericTask('CPS optimization', compiler.measurer),
+        treeBuilderTask = new GenericTask('Tree builder', compiler.measurer),
+        treeOptimizationTask =
+            new GenericTask('Tree optimization', compiler.measurer) {
     inliner = new Inliner(this);
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index 5aefd39..da3efb5 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -18,7 +18,7 @@
   JavaScriptConstantTask(Compiler compiler)
       : this.dartConstantCompiler = new DartConstantCompiler(compiler),
         this.jsConstantCompiler = new JavaScriptConstantCompiler(compiler),
-        super(compiler);
+        super(compiler.measurer);
 
   String get name => 'ConstantHandler';
 
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
index 4bc5384..4cbc011 100644
--- a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -206,6 +206,13 @@
         expr = stmt.expression;
       }
     }
+    if (expr is Send && expr.isTypeCast) {
+      Send sendExpr = expr;
+      var typeName = sendExpr.typeAnnotationFromIsCheckOrCast.typeName;
+      if (typeName is Identifier && typeName.source == "dynamic") {
+        expr = sendExpr.receiver;
+      }
+    }
     if (expr is Send &&
         expr.isSuperCall &&
         expr.selector is Identifier &&
diff --git a/pkg/compiler/lib/src/js_backend/patch_resolver.dart b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
index 521dd2d..17a4a4e 100644
--- a/pkg/compiler/lib/src/js_backend/patch_resolver.dart
+++ b/pkg/compiler/lib/src/js_backend/patch_resolver.dart
@@ -14,7 +14,12 @@
 import '../tree/tree.dart';
 
 class PatchResolverTask extends CompilerTask {
-  PatchResolverTask(Compiler compiler) : super(compiler);
+  final Compiler compiler;
+  PatchResolverTask(Compiler compiler)
+      : compiler = compiler,
+        super(compiler.measurer);
+
+  DiagnosticReporter get reporter => compiler.reporter;
 
   Resolution get resolution => compiler.resolution;
 
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index 036e52a..369cec0 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -252,7 +252,12 @@
     compiler.resolverWorld.isChecks.forEach((DartType type) {
       if (type.isTypeVariable) {
         TypeVariableElement variable = type.element;
-        classesUsingTypeVariableTests.add(variable.typeDeclaration);
+        // GENERIC_METHODS: When generic method support is complete enough to
+        // include a runtime value for method type variables, this may need to
+        // be updated: It simply ignores method type arguments.
+        if (variable.typeDeclaration is ClassElement) {
+          classesUsingTypeVariableTests.add(variable.typeDeclaration);
+        }
       }
     });
     // Add is-checks that result from classes using type variables in checks.
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 28583fc..da0aff8 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -19,6 +19,7 @@
   NativeEmitter nativeEmitter;
   MetadataCollector metadataCollector;
   Emitter emitter;
+  final Compiler compiler;
 
   /// Records if a type variable is read dynamically for type tests.
   final Set<TypeVariableElement> readTypeVariables =
@@ -35,9 +36,10 @@
 
   CodeEmitterTask(Compiler compiler, Namer namer, bool generateSourceMap,
       bool useStartupEmitter)
-      : super(compiler),
+      : compiler = compiler,
         this.namer = namer,
-        this.typeTestRegistry = new TypeTestRegistry(compiler) {
+        this.typeTestRegistry = new TypeTestRegistry(compiler),
+        super(compiler.measurer) {
     nativeEmitter = new NativeEmitter(this);
     if (USE_LAZY_EMITTER) {
       emitter = new lazy_js_emitter.Emitter(compiler, namer, nativeEmitter);
diff --git a/pkg/compiler/lib/src/library_loader.dart b/pkg/compiler/lib/src/library_loader.dart
index d555a73..3a2e2a3 100644
--- a/pkg/compiler/lib/src/library_loader.dart
+++ b/pkg/compiler/lib/src/library_loader.dart
@@ -7,9 +7,8 @@
 import 'dart:async';
 
 import 'common/names.dart' show Uris;
-import 'common/tasks.dart' show CompilerTask;
+import 'common/tasks.dart' show CompilerTask, Measurer;
 import 'common.dart';
-import 'compiler.dart' show Compiler;
 import 'elements/elements.dart'
     show
         CompilationUnitElement,
@@ -115,8 +114,8 @@
  * A 'resource URI' is an absolute URI with a scheme supported by the input
  * provider. For the standard implementation this means a URI with the 'file'
  * scheme. Readable URIs are converted into resource URIs as part of the
- * [Compiler.readScript] method. In the standard implementation the package URIs
- * are converted to file URIs using the package root URI provided on the
+ * [ScriptLoader.readScript] method. In the standard implementation the package
+ * URIs are converted to file URIs using the package root URI provided on the
  * command line as base. If the package root URI is
  * 'file:///current/working/dir/' then the package URI 'package:foo/bar.dart'
  * will be resolved to the resource URI
@@ -134,13 +133,14 @@
  */
 abstract class LibraryLoaderTask implements CompilerTask {
   factory LibraryLoaderTask(
-      Compiler compiler,
       ResolvedUriTranslator uriTranslator,
       ScriptLoader scriptLoader,
       ElementScanner scriptScanner,
       LibraryDeserializer deserializer,
       LibraryLoaderListener listener,
-      Environment environment) = _LibraryLoaderTask;
+      Environment environment,
+      DiagnosticReporter reporter,
+      Measurer measurer) = _LibraryLoaderTask;
 
   /// Returns all libraries that have been loaded.
   Iterable<LibraryElement> get libraries;
@@ -297,10 +297,12 @@
   /// conditional imports.
   final Environment environment;
 
-  _LibraryLoaderTask(Compiler compiler, this.uriTranslator, this.scriptLoader,
-      this.scanner, this.deserializer, this.listener, this.environment)
-      // TODO(sigmund): make measurements separate from compiler
-      : super(compiler);
+  final DiagnosticReporter reporter;
+
+  _LibraryLoaderTask(this.uriTranslator, this.scriptLoader,
+      this.scanner, this.deserializer, this.listener, this.environment,
+      this.reporter, Measurer measurer)
+      : super(measurer);
 
   String get name => 'LibraryLoader';
 
@@ -325,8 +327,7 @@
 
       Iterable<LibraryElement> reusedLibraries = null;
       if (reuseLibrary != null) {
-        // TODO(sigmund): make measurements separate from compiler
-        reusedLibraries = compiler.reuseLibraryTask.measure(() {
+        reusedLibraries = measureSubtask(_reuseLibrarySubtaskName, () {
           // Call [toList] to force eager calls to [reuseLibrary].
           return libraryCanonicalUriMap.values.where(reuseLibrary).toList();
         });
@@ -363,10 +364,9 @@
         }
       }
 
-      List<Future<LibraryElement>> reusedLibrariesFuture =
-          // TODO(sigmund): make measurements separate from compiler
-          compiler.reuseLibraryTask.measure(
-              () => libraryCanonicalUriMap.values.map(wrapper).toList());
+      List<Future<LibraryElement>> reusedLibrariesFuture = measureSubtask(
+          _reuseLibrarySubtaskName,
+          () => libraryCanonicalUriMap.values.map(wrapper).toList());
 
       return Future
           .wait(reusedLibrariesFuture)
@@ -380,12 +380,12 @@
       Future<Iterable<LibraryElement>> reuseLibraries(
           Iterable<LibraryElement> libraries)) {
     assert(currentHandler == null);
-    return compiler.reuseLibraryTask.measure(() {
+    return measureSubtask(_reuseLibrarySubtaskName, () {
       return new Future<Iterable<LibraryElement>>(() {
         // Wrap in Future to shield against errors in user code.
         return reuseLibraries(libraryCanonicalUriMap.values);
       }).catchError((exception, StackTrace trace) {
-        compiler.reportCrashInUserCode(
+        reporter.onCrashInUserCode(
             'Uncaught exception in reuseLibraries', exception, trace);
         throw exception; // Async rethrow.
       }).then((Iterable<LibraryElement> reusedLibraries) {
@@ -1508,3 +1508,5 @@
   /// Called whenever a library is scanned from a script file.
   Future onLibraryScanned(LibraryElement library, LibraryLoader loader);
 }
+
+const _reuseLibrarySubtaskName = "Reuse library";
diff --git a/pkg/compiler/lib/src/mirrors/analyze.dart b/pkg/compiler/lib/src/mirrors/analyze.dart
deleted file mode 100644
index d6ab956..0000000
--- a/pkg/compiler/lib/src/mirrors/analyze.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.source_mirrors.analyze;
-
-import 'dart:async';
-
-import 'source_mirrors.dart';
-import 'dart2js_mirrors.dart' show Dart2JsMirrorSystem;
-import '../../compiler.dart' as api;
-import '../options.dart' show CompilerOptions;
-import '../apiimpl.dart' as apiimpl;
-import '../compiler.dart' show Compiler;
-import '../old_to_new_api.dart';
-
-//------------------------------------------------------------------------------
-// Analysis entry point.
-//------------------------------------------------------------------------------
-
-/**
- * Analyzes set of libraries and provides a mirror system which can be used for
- * static inspection of the source code.
- */
-// TODO(johnniwinther): Move this to [compiler/compiler.dart].
-Future<MirrorSystem> analyze(
-    List<Uri> libraries,
-    Uri libraryRoot,
-    Uri packageRoot,
-    api.CompilerInputProvider inputProvider,
-    api.DiagnosticHandler diagnosticHandler,
-    [List<String> options = const <String>[],
-    Uri packageConfig,
-    api.PackagesDiscoveryProvider findPackages]) {
-  if (!libraryRoot.path.endsWith("/")) {
-    throw new ArgumentError("libraryRoot must end with a /");
-  }
-  if (packageRoot != null && !packageRoot.path.endsWith("/")) {
-    throw new ArgumentError("packageRoot must end with a /");
-  }
-  options = new List<String>.from(options);
-  options.add('--analyze-only');
-  options.add('--analyze-signatures-only');
-  options.add('--analyze-all');
-  options.add('--categories=Client,Server');
-  options.add('--enable-async');
-  options.add('--allow-native-extensions');
-
-  bool compilationFailed = false;
-  void internalDiagnosticHandler(
-      Uri uri, int begin, int end, String message, api.Diagnostic kind) {
-    if (kind == api.Diagnostic.ERROR || kind == api.Diagnostic.CRASH) {
-      compilationFailed = true;
-    }
-    diagnosticHandler(uri, begin, end, message, kind);
-  }
-
-  Compiler compiler = new apiimpl.CompilerImpl(
-      new LegacyCompilerInput(inputProvider),
-      new LegacyCompilerOutput(),
-      new LegacyCompilerDiagnostics(internalDiagnosticHandler),
-      new CompilerOptions.parse(
-          libraryRoot: libraryRoot,
-          packageRoot: packageRoot,
-          options: options,
-          environment: const {},
-          packageConfig: packageConfig,
-          packagesDiscoveryProvider: findPackages));
-  compiler.librariesToAnalyzeWhenRun = libraries;
-  return compiler.run(null).then((bool success) {
-    if (success && !compilationFailed) {
-      return new Dart2JsMirrorSystem(compiler);
-    } else {
-      throw new StateError('Failed to create mirror system.');
-    }
-  });
-}
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart
deleted file mode 100644
index 0c90060..0000000
--- a/pkg/compiler/lib/src/mirrors/dart2js_instance_mirrors.dart
+++ /dev/null
@@ -1,286 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart2js.mirrors;
-
-abstract class ObjectMirrorMixin implements ObjectMirror {
-  InstanceMirror getField(Symbol fieldName) {
-    throw new UnsupportedError('ObjectMirror.getField unsupported.');
-  }
-
-  InstanceMirror setField(Symbol fieldName, Object value) {
-    throw new UnsupportedError('ObjectMirror.setField unsupported.');
-  }
-
-  InstanceMirror invoke(Symbol memberName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    throw new UnsupportedError('ObjectMirror.invoke unsupported.');
-  }
-
-  delegate(Invocation invocation) {
-    throw new UnsupportedError('ObjectMirror.delegate unsupported');
-  }
-}
-
-abstract class InstanceMirrorMixin implements InstanceMirror {
-  bool get hasReflectee => false;
-
-  get reflectee {
-    throw new UnsupportedError('InstanceMirror.reflectee unsupported.');
-  }
-}
-
-InstanceMirror _convertConstantToInstanceMirror(
-    Dart2JsMirrorSystem mirrorSystem,
-    ConstantExpression constant,
-    ConstantValue value) {
-  if (value.isBool) {
-    return new Dart2JsBoolConstantMirror(mirrorSystem, constant, value);
-  } else if (value.isNum) {
-    return new Dart2JsNumConstantMirror(mirrorSystem, constant, value);
-  } else if (value.isString) {
-    return new Dart2JsStringConstantMirror(mirrorSystem, constant, value);
-  } else if (value.isList) {
-    return new Dart2JsListConstantMirror(mirrorSystem, constant, value);
-  } else if (value.isMap) {
-    return new Dart2JsMapConstantMirror(mirrorSystem, constant, value);
-  } else if (value.isType) {
-    return new Dart2JsTypeConstantMirror(mirrorSystem, constant, value);
-  } else if (value.isFunction) {
-    return new Dart2JsConstantMirror(mirrorSystem, constant, value);
-  } else if (value.isNull) {
-    return new Dart2JsNullConstantMirror(mirrorSystem, constant, value);
-  } else if (value.isConstructedObject) {
-    return new Dart2JsConstructedConstantMirror(mirrorSystem, constant, value);
-  }
-  mirrorSystem.compiler.reporter
-      .internalError(NO_LOCATION_SPANNABLE, "Unexpected constant value $value");
-  return null;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// Mirrors on constant values used for metadata.
-////////////////////////////////////////////////////////////////////////////////
-
-class Dart2JsConstantMirror extends Object
-    with ObjectMirrorMixin, InstanceMirrorMixin {
-  final Dart2JsMirrorSystem mirrorSystem;
-  final ConstantExpression _constant;
-  final ConstantValue _value;
-
-  Dart2JsConstantMirror(this.mirrorSystem, this._constant, this._value);
-
-  String toString() {
-    if (_constant != null) {
-      return _constant.toDartText();
-    } else {
-      return _value.toDartText();
-    }
-  }
-
-  ClassMirror get type {
-    return mirrorSystem._getTypeDeclarationMirror(
-        _value.getType(mirrorSystem.compiler.coreTypes).element);
-  }
-
-  int get hashCode => 13 * _constant.hashCode;
-
-  bool operator ==(var other) {
-    if (other is! Dart2JsConstantMirror) return false;
-    return _value == other._value;
-  }
-}
-
-class Dart2JsNullConstantMirror extends Dart2JsConstantMirror {
-  Dart2JsNullConstantMirror(Dart2JsMirrorSystem mirrorSystem,
-      ConstantExpression constant, NullConstantValue value)
-      : super(mirrorSystem, constant, value);
-
-  NullConstantValue get _value => super._value;
-
-  bool get hasReflectee => true;
-
-  get reflectee => null;
-}
-
-class Dart2JsBoolConstantMirror extends Dart2JsConstantMirror {
-  Dart2JsBoolConstantMirror(Dart2JsMirrorSystem mirrorSystem,
-      ConstantExpression constant, BoolConstantValue value)
-      : super(mirrorSystem, constant, value);
-
-  Dart2JsBoolConstantMirror.fromBool(
-      Dart2JsMirrorSystem mirrorSystem, bool value)
-      : super(mirrorSystem, null,
-            value ? new TrueConstantValue() : new FalseConstantValue());
-
-  BoolConstantValue get _value => super._value;
-
-  bool get hasReflectee => true;
-
-  get reflectee => _value is TrueConstantValue;
-}
-
-class Dart2JsStringConstantMirror extends Dart2JsConstantMirror {
-  Dart2JsStringConstantMirror(Dart2JsMirrorSystem mirrorSystem,
-      ConstantExpression constant, StringConstantValue value)
-      : super(mirrorSystem, constant, value);
-
-  Dart2JsStringConstantMirror.fromString(
-      Dart2JsMirrorSystem mirrorSystem, String text)
-      : super(mirrorSystem, null,
-            new StringConstantValue(new DartString.literal(text)));
-
-  StringConstantValue get _value => super._value;
-
-  bool get hasReflectee => true;
-
-  get reflectee => _value.primitiveValue.slowToString();
-}
-
-class Dart2JsNumConstantMirror extends Dart2JsConstantMirror {
-  Dart2JsNumConstantMirror(Dart2JsMirrorSystem mirrorSystem,
-      ConstantExpression constant, NumConstantValue value)
-      : super(mirrorSystem, constant, value);
-
-  NumConstantValue get _value => super._value;
-
-  bool get hasReflectee => true;
-
-  get reflectee => _value.primitiveValue;
-}
-
-class Dart2JsListConstantMirror extends Dart2JsConstantMirror
-    implements ListInstanceMirror {
-  Dart2JsListConstantMirror(Dart2JsMirrorSystem mirrorSystem,
-      ConstantExpression constant, ListConstantValue value)
-      : super(mirrorSystem, constant, value);
-
-  ListConstantValue get _value => super._value;
-
-  int get length => _value.length;
-
-  InstanceMirror getElement(int index) {
-    if (index < 0) throw new RangeError('Negative index');
-    if (index >= _value.length) throw new RangeError('Index out of bounds');
-    return _convertConstantToInstanceMirror(
-        mirrorSystem, null, _value.entries[index]);
-  }
-}
-
-class Dart2JsMapConstantMirror extends Dart2JsConstantMirror
-    implements MapInstanceMirror {
-  List<String> _listCache;
-
-  Dart2JsMapConstantMirror(Dart2JsMirrorSystem mirrorSystem,
-      ConstantExpression constant, MapConstantValue value)
-      : super(mirrorSystem, constant, value);
-
-  MapConstantValue get _value => super._value;
-
-  List<String> get _list {
-    if (_listCache == null) {
-      _listCache = new List<String>(_value.length);
-      int index = 0;
-      for (StringConstantValue keyConstant in _value.keys) {
-        _listCache[index] = keyConstant.primitiveValue.slowToString();
-        index++;
-      }
-      _listCache = new UnmodifiableListView<String>(_listCache);
-    }
-    return _listCache;
-  }
-
-  int get length => _value.length;
-
-  Iterable<String> get keys {
-    return _list;
-  }
-
-  InstanceMirror getValue(String key) {
-    int index = _list.indexOf(key);
-    if (index == -1) return null;
-    return _convertConstantToInstanceMirror(
-        mirrorSystem, null, _value.values[index]);
-  }
-}
-
-class Dart2JsTypeConstantMirror extends Dart2JsConstantMirror
-    implements TypeInstanceMirror {
-  Dart2JsTypeConstantMirror(Dart2JsMirrorSystem mirrorSystem,
-      ConstantExpression constant, TypeConstantValue value)
-      : super(mirrorSystem, constant, value);
-
-  TypeConstantValue get _value => super._value;
-
-  TypeMirror get representedType =>
-      mirrorSystem._convertTypeToTypeMirror(_value.representedType);
-}
-
-class Dart2JsConstructedConstantMirror extends Dart2JsConstantMirror {
-  Map<String, ConstantValue> _fieldMapCache;
-
-  Dart2JsConstructedConstantMirror(Dart2JsMirrorSystem mirrorSystem,
-      ConstantExpression constant, ConstructedConstantValue value)
-      : super(mirrorSystem, constant, value);
-
-  ConstructedConstantValue get _value => super._value;
-
-  Map<String, ConstantValue> get _fieldMap {
-    if (_fieldMapCache == null) {
-      _fieldMapCache = new Map<String, ConstantValue>();
-      if (identical(_value.type.element.kind, ElementKind.CLASS)) {
-        _value.fields.forEach((FieldElement field, ConstantValue value) {
-          _fieldMapCache[field.name] = value;
-        });
-      }
-    }
-    return _fieldMapCache;
-  }
-
-  InstanceMirror getField(Symbol fieldName) {
-    String name = MirrorSystem.getName(fieldName);
-    ConstantValue fieldConstant = _fieldMap[name];
-    if (fieldConstant != null) {
-      return _convertConstantToInstanceMirror(
-          mirrorSystem, null, fieldConstant);
-    }
-    return super.getField(fieldName);
-  }
-}
-
-class Dart2JsCommentInstanceMirror extends Object
-    with ObjectMirrorMixin, InstanceMirrorMixin
-    implements CommentInstanceMirror {
-  final Dart2JsMirrorSystem mirrorSystem;
-  final String text;
-  String _trimmedText;
-
-  Dart2JsCommentInstanceMirror(this.mirrorSystem, this.text);
-
-  ClassMirror get type {
-    return mirrorSystem
-        ._getTypeDeclarationMirror(mirrorSystem.compiler.documentClass);
-  }
-
-  bool get isDocComment => text.startsWith('/**') || text.startsWith('///');
-
-  String get trimmedText {
-    if (_trimmedText == null) {
-      _trimmedText = stripComment(text);
-    }
-    return _trimmedText;
-  }
-
-  InstanceMirror getField(Symbol fieldName) {
-    if (fieldName == #isDocComment) {
-      return new Dart2JsBoolConstantMirror.fromBool(mirrorSystem, isDocComment);
-    } else if (fieldName == #text) {
-      return new Dart2JsStringConstantMirror.fromString(mirrorSystem, text);
-    } else if (fieldName == #trimmedText) {
-      return new Dart2JsStringConstantMirror.fromString(
-          mirrorSystem, trimmedText);
-    }
-    return super.getField(fieldName);
-  }
-}
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_library_mirror.dart b/pkg/compiler/lib/src/mirrors/dart2js_library_mirror.dart
deleted file mode 100644
index 39468d3..0000000
--- a/pkg/compiler/lib/src/mirrors/dart2js_library_mirror.dart
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart2js.mirrors;
-
-class Dart2JsLibraryMirror extends Dart2JsElementMirror
-    with ObjectMirrorMixin, ContainerMixin
-    implements LibrarySourceMirror {
-  List<LibraryDependencySourceMirror> _libraryDependencies;
-
-  Dart2JsLibraryMirror(Dart2JsMirrorSystem system, LibraryElement library)
-      : super(system, library);
-
-  Function operator [](Symbol name) {
-    throw new UnsupportedError('LibraryMirror.operator [] unsupported.');
-  }
-
-  // TODO(johnniwinther): Avoid the need for [LibraryElementX].
-  LibraryElementX get _element => super._element;
-
-  Uri get uri => _element.canonicalUri;
-
-  DeclarationMirror get owner => null;
-
-  bool get isPrivate => false;
-
-  LibraryMirror library() => this;
-
-  /**
-   * Returns the library name (for libraries with a library tag) or the script
-   * file name (for scripts without a library tag). The latter case is used to
-   * provide a 'library name' for scripts, to use for instance in dartdoc.
-   */
-  String get _simpleNameString => _element.libraryOrScriptName;
-
-  Symbol get qualifiedName => simpleName;
-
-  void _forEachElement(f(Element element)) => _element.forEachLocalMember(f);
-
-  Iterable<Dart2JsDeclarationMirror> _getDeclarationMirrors(Element element) {
-    if (element.isClass || element.isTypedef) {
-      return [mirrorSystem._getTypeDeclarationMirror(element)];
-    } else {
-      return super._getDeclarationMirrors(element);
-    }
-  }
-
-  Map<Symbol, MethodMirror> get topLevelMembers => null;
-
-  /**
-   * Computes the first token of this library using the first library tag as
-   * indicator.
-   */
-  Token getBeginToken() {
-    if (_element.libraryTag != null) {
-      return _element.libraryTag.getBeginToken();
-    } else if (!_element.tags.isEmpty) {
-      return _element.tags.first.getBeginToken();
-    }
-    return null;
-  }
-
-  /**
-   * Computes the first token of this library using the last library tag as
-   * indicator.
-   */
-  Token getEndToken() {
-    if (!_element.tags.isEmpty) {
-      return _element.tags.last.getEndToken();
-    }
-    return null;
-  }
-
-  void _ensureLibraryDependenciesAnalyzed() {
-    if (_libraryDependencies == null) {
-      // TODO(johnniwinther): Support order of declarations on [LibraryElement].
-      Map<LibraryDependency, Dart2JsLibraryDependencyMirror> mirrorMap =
-          <LibraryDependency, Dart2JsLibraryDependencyMirror>{};
-
-      void addLibraryDependency(LibraryDependency libraryDependency,
-          LibraryElement targetLibraryElement) {
-        assert(targetLibraryElement != null);
-        LibraryMirror targetLibrary =
-            mirrorSystem._getLibrary(targetLibraryElement);
-        mirrorMap[libraryDependency] = new Dart2JsLibraryDependencyMirror(
-            libraryDependency, this, targetLibrary);
-      }
-      for (ImportElement import in _element.imports) {
-        addLibraryDependency(import.node, import.importedLibrary);
-      }
-      for (ExportElement export in _element.exports) {
-        addLibraryDependency(export.node, export.exportedLibrary);
-      }
-
-      _libraryDependencies = <LibraryDependencySourceMirror>[];
-
-      for (LibraryTag node in _element.tags) {
-        LibraryDependency libraryDependency = node.asLibraryDependency();
-        if (libraryDependency != null) {
-          Dart2JsLibraryDependencyMirror mirror = mirrorMap[libraryDependency];
-          assert(mirror != null);
-          _libraryDependencies.add(mirror);
-        }
-      }
-    }
-  }
-
-  List<LibraryDependencyMirror> get libraryDependencies {
-    _ensureLibraryDependenciesAnalyzed();
-    return _libraryDependencies;
-  }
-}
-
-class Dart2JsLibraryDependencyMirror implements LibraryDependencySourceMirror {
-  final LibraryDependency _node;
-  final Dart2JsLibraryMirror _sourceLibrary;
-  final Dart2JsLibraryMirror _targetLibrary;
-  List<CombinatorMirror> _combinators;
-
-  Dart2JsLibraryDependencyMirror(
-      this._node, this._sourceLibrary, this._targetLibrary);
-
-  SourceLocation get location {
-    return new Dart2JsSourceLocation(
-        _sourceLibrary._element.entryCompilationUnit.script,
-        _sourceLibrary.mirrorSystem.compiler.reporter.spanFromSpannable(_node));
-  }
-
-  List<CombinatorMirror> get combinators {
-    if (_combinators == null) {
-      _combinators = <CombinatorMirror>[];
-      if (_node.combinators != null) {
-        for (Combinator combinator in _node.combinators.nodes) {
-          List<String> identifiers = <String>[];
-          for (Identifier identifier in combinator.identifiers.nodes) {
-            identifiers.add(identifier.source);
-          }
-          _combinators.add(new Dart2JsCombinatorMirror(identifiers,
-              isShow: combinator.isShow));
-        }
-      }
-    }
-    return _combinators;
-  }
-
-  LibraryMirror get sourceLibrary => _sourceLibrary;
-
-  LibraryMirror get targetLibrary => _targetLibrary;
-
-  /*String*/ get prefix {
-    Import import = _node.asImport();
-    if (import != null && import.prefix != null) {
-      return import.prefix.source;
-    }
-    return null;
-  }
-
-  bool get isImport => _node.asImport() != null;
-
-  bool get isExport => _node.asExport() != null;
-
-  bool get isDeferred {
-    if (_node is Import) {
-      Import import = _node;
-      return import.isDeferred;
-    }
-    return false;
-  }
-
-  List<InstanceMirror> get metadata => const <InstanceMirror>[];
-
-  /*Future<LibraryMirror>*/ loadLibrary() {
-    throw new UnsupportedError(
-        'LibraryDependencyMirror.loadLibrary unsupported.');
-  }
-}
-
-class Dart2JsCombinatorMirror implements CombinatorSourceMirror {
-  final List/*<String>*/ identifiers;
-  final bool isShow;
-
-  Dart2JsCombinatorMirror(this.identifiers, {bool isShow: true})
-      : this.isShow = isShow;
-
-  bool get isHide => !isShow;
-}
-
-class Dart2JsSourceLocation implements SourceLocation {
-  final Script _script;
-  final SourceSpan _span;
-  int _line;
-  int _column;
-
-  Dart2JsSourceLocation(this._script, this._span);
-
-  int _computeLine() {
-    var sourceFile = _script.file;
-    if (sourceFile != null) {
-      return sourceFile.getLine(offset) + 1;
-    }
-    var index = 0;
-    var lineNumber = 0;
-    while (index <= offset && index < sourceText.length) {
-      index = sourceText.indexOf('\n', index) + 1;
-      if (index <= 0) break;
-      lineNumber++;
-    }
-    return lineNumber;
-  }
-
-  int get line {
-    if (_line == null) {
-      _line = _computeLine();
-    }
-    return _line;
-  }
-
-  int _computeColumn() {
-    if (length == 0) return 0;
-
-    var sourceFile = _script.file;
-    if (sourceFile != null) {
-      return sourceFile.getColumn(sourceFile.getLine(offset), offset) + 1;
-    }
-    int index = offset - 1;
-    var columnNumber = 0;
-    while (0 <= index && index < sourceText.length) {
-      columnNumber++;
-      var codeUnit = sourceText.codeUnitAt(index);
-      if (codeUnit == $CR || codeUnit == $LF) {
-        break;
-      }
-      index--;
-    }
-    return columnNumber;
-  }
-
-  int get column {
-    if (_column == null) {
-      _column = _computeColumn();
-    }
-    return _column;
-  }
-
-  int get offset => _span.begin;
-
-  int get length => _span.end - _span.begin;
-
-  String get text => _script.text.substring(_span.begin, _span.end);
-
-  Uri get sourceUri => _script.resourceUri;
-
-  String get sourceText => _script.text;
-}
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_member_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_member_mirrors.dart
deleted file mode 100644
index 8278525..0000000
--- a/pkg/compiler/lib/src/mirrors/dart2js_member_mirrors.dart
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart2js.mirrors;
-
-//------------------------------------------------------------------------------
-// Member mirrors implementation.
-//------------------------------------------------------------------------------
-
-abstract class Dart2JsMemberMirror extends Dart2JsElementMirror {
-  Dart2JsMemberMirror(Dart2JsMirrorSystem system, AstElement element)
-      : super(system, element);
-
-  bool get isStatic => false;
-}
-
-class Dart2JsMethodKind {
-  static const Dart2JsMethodKind REGULAR = const Dart2JsMethodKind("regular");
-  static const Dart2JsMethodKind GENERATIVE =
-      const Dart2JsMethodKind("generative");
-  static const Dart2JsMethodKind REDIRECTING =
-      const Dart2JsMethodKind("redirecting");
-  static const Dart2JsMethodKind CONST = const Dart2JsMethodKind("const");
-  static const Dart2JsMethodKind FACTORY = const Dart2JsMethodKind("factory");
-  static const Dart2JsMethodKind GETTER = const Dart2JsMethodKind("getter");
-  static const Dart2JsMethodKind SETTER = const Dart2JsMethodKind("setter");
-  static const Dart2JsMethodKind OPERATOR = const Dart2JsMethodKind("operator");
-
-  final String text;
-
-  const Dart2JsMethodKind(this.text);
-
-  String toString() => text;
-}
-
-class Dart2JsMethodMirror extends Dart2JsMemberMirror implements MethodMirror {
-  final Dart2JsDeclarationMirror owner;
-  final String _simpleNameString;
-  final Dart2JsMethodKind _kind;
-
-  Dart2JsMethodMirror._internal(
-      Dart2JsDeclarationMirror owner,
-      FunctionElement function,
-      String this._simpleNameString,
-      Dart2JsMethodKind this._kind)
-      : this.owner = owner,
-        super(owner.mirrorSystem, function);
-
-  factory Dart2JsMethodMirror(
-      Dart2JsDeclarationMirror owner, FunctionElement function) {
-    String simpleName = function.name;
-    // TODO(ahe): This method should not be calling
-    // Elements.operatorNameToIdentifier.
-    Dart2JsMethodKind kind;
-    if (function.kind == ElementKind.GETTER) {
-      kind = Dart2JsMethodKind.GETTER;
-    } else if (function.kind == ElementKind.SETTER) {
-      kind = Dart2JsMethodKind.SETTER;
-      simpleName = '$simpleName=';
-    } else if (function.kind == ElementKind.GENERATIVE_CONSTRUCTOR) {
-      // TODO(johnniwinther): Support detection of redirecting constructors.
-      if (function.isConst) {
-        kind = Dart2JsMethodKind.CONST;
-      } else {
-        kind = Dart2JsMethodKind.GENERATIVE;
-      }
-    } else if (function.isFactoryConstructor) {
-      // TODO(johnniwinther): Support detection of redirecting constructors.
-      kind = Dart2JsMethodKind.FACTORY;
-    } else if (function.isOperator) {
-      kind = Dart2JsMethodKind.OPERATOR;
-    } else {
-      kind = Dart2JsMethodKind.REGULAR;
-    }
-    return new Dart2JsMethodMirror._internal(owner, function, simpleName, kind);
-  }
-
-  FunctionElement get _function => _element;
-
-  bool get isTopLevel => owner is LibraryMirror;
-
-  // TODO(johnniwinther): This seems stale and broken.
-  Symbol get constructorName => isConstructor ? simpleName : const Symbol('');
-
-  bool get isConstructor =>
-      isGenerativeConstructor ||
-      isConstConstructor ||
-      isFactoryConstructor ||
-      isRedirectingConstructor;
-
-  bool get isSynthetic => false;
-
-  bool get isStatic => _function.isStatic;
-
-  List<ParameterMirror> get parameters {
-    return _parametersFromFunctionSignature(this, _function.functionSignature);
-  }
-
-  TypeMirror get returnType =>
-      owner._getTypeMirror(_function.functionSignature.type.returnType);
-
-  bool get isAbstract => _function.isAbstract;
-
-  bool get isRegularMethod => !(isGetter || isSetter || isConstructor);
-
-  bool get isConstConstructor => _kind == Dart2JsMethodKind.CONST;
-
-  bool get isGenerativeConstructor => _kind == Dart2JsMethodKind.GENERATIVE;
-
-  bool get isRedirectingConstructor => _kind == Dart2JsMethodKind.REDIRECTING;
-
-  bool get isFactoryConstructor => _kind == Dart2JsMethodKind.FACTORY;
-
-  bool get isGetter => _kind == Dart2JsMethodKind.GETTER;
-
-  bool get isSetter => _kind == Dart2JsMethodKind.SETTER;
-
-  bool get isOperator => _kind == Dart2JsMethodKind.OPERATOR;
-
-  DeclarationMirror lookupInScope(String name) {
-    for (Dart2JsParameterMirror parameter in parameters) {
-      if (parameter._element.name == name) {
-        return parameter;
-      }
-    }
-    return super.lookupInScope(name);
-  }
-
-  // TODO(johnniwinther): Should this really be in the interface of
-  // [MethodMirror]?
-  String get source => location.sourceText;
-
-  String toString() => 'Mirror on method ${_element.name}';
-}
-
-class Dart2JsFieldMirror extends Dart2JsMemberMirror implements VariableMirror {
-  final Dart2JsDeclarationMirror owner;
-  VariableElement _variable;
-
-  Dart2JsFieldMirror(Dart2JsDeclarationMirror owner, VariableElement variable)
-      : this.owner = owner,
-        this._variable = variable,
-        super(owner.mirrorSystem, variable);
-
-  bool get isTopLevel => owner is LibraryMirror;
-
-  bool get isStatic => _variable.isStatic;
-
-  bool get isFinal => _variable.isFinal;
-
-  bool get isConst => _variable.isConst;
-
-  TypeMirror get type => owner._getTypeMirror(_variable.type);
-}
-
-class Dart2JsParameterMirror extends Dart2JsMemberMirror
-    implements ParameterMirror {
-  final Dart2JsDeclarationMirror owner;
-  final bool isOptional;
-  final bool isNamed;
-
-  factory Dart2JsParameterMirror(
-      Dart2JsDeclarationMirror owner, FormalElement element,
-      {bool isOptional: false, bool isNamed: false}) {
-    if (element is InitializingFormalElement) {
-      return new Dart2JsFieldParameterMirror(
-          owner, element, isOptional, isNamed);
-    } else {
-      return new Dart2JsParameterMirror._normal(
-          owner, element, isOptional, isNamed);
-    }
-  }
-
-  Dart2JsParameterMirror._normal(Dart2JsDeclarationMirror owner,
-      FormalElement element, this.isOptional, this.isNamed)
-      : this.owner = owner,
-        super(owner.mirrorSystem, element);
-
-  FormalElement get _element => super._element;
-
-  TypeMirror get type => owner._getTypeMirror(_element.type);
-
-  bool get isFinal => false;
-
-  bool get isConst => false;
-
-  InstanceMirror get defaultValue {
-    if (hasDefaultValue) {
-      // TODO(johnniwinther): Get the constant from the [TreeElements]
-      // associated with the enclosing method.
-      ParameterElement parameter = _element;
-      ConstantExpression constant = parameter.constant;
-      assert(invariant(parameter, constant != null,
-          message: "Missing constant for parameter "
-              "$parameter with default value."));
-      return _convertConstantToInstanceMirror(mirrorSystem, constant,
-          mirrorSystem.compiler.constants.getConstantValue(constant));
-    }
-    return null;
-  }
-
-  bool get hasDefaultValue {
-    if (_element is ParameterElement) {
-      ParameterElement parameter = _element;
-      return parameter.initializer != null;
-    }
-    return false;
-  }
-
-  bool get isInitializingFormal => false;
-
-  VariableMirror get initializedField => null;
-}
-
-class Dart2JsFieldParameterMirror extends Dart2JsParameterMirror {
-  Dart2JsFieldParameterMirror(Dart2JsDeclarationMirror method,
-      InitializingFormalElement element, bool isOptional, bool isNamed)
-      : super._normal(method, element, isOptional, isNamed);
-
-  InitializingFormalElement get _fieldParameterElement => _element;
-
-  bool get isInitializingFormal => true;
-
-  VariableMirror get initializedField =>
-      new Dart2JsFieldMirror(owner.owner, _fieldParameterElement.fieldElement);
-}
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
deleted file mode 100644
index 406502a..0000000
--- a/pkg/compiler/lib/src/mirrors/dart2js_mirrors.dart
+++ /dev/null
@@ -1,480 +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.
-
-library dart2js.mirrors;
-
-import 'dart:collection' show UnmodifiableListView, UnmodifiableMapView;
-
-import '../common.dart';
-import '../compiler.dart' show Compiler;
-import '../constants/expressions.dart';
-import '../constants/values.dart';
-import '../dart_types.dart';
-import '../elements/elements.dart';
-import '../elements/modelx.dart' show LibraryElementX;
-import '../resolution/scope.dart' show Scope;
-import '../script.dart';
-import '../tokens/token.dart';
-import '../tokens/token_constants.dart' as Tokens;
-import '../tree/tree.dart';
-import '../util/characters.dart' show $CR, $LF;
-import '../util/util.dart' show Link;
-import 'mirrors_util.dart';
-import 'source_mirrors.dart';
-
-part 'dart2js_instance_mirrors.dart';
-part 'dart2js_library_mirror.dart';
-part 'dart2js_member_mirrors.dart';
-part 'dart2js_type_mirrors.dart';
-
-//------------------------------------------------------------------------------
-// Utility types and functions for the dart2js mirror system
-//------------------------------------------------------------------------------
-
-bool _includeLibrary(Dart2JsLibraryMirror mirror) {
-  return const bool.fromEnvironment("list_all_libraries") ||
-      !mirror._element.isInternalLibrary;
-}
-
-bool _isPrivate(String name) {
-  return name.startsWith('_');
-}
-
-List<ParameterMirror> _parametersFromFunctionSignature(
-    Dart2JsDeclarationMirror owner, FunctionSignature signature) {
-  var parameters = <ParameterMirror>[];
-  signature.requiredParameters.forEach((FormalElement parameter) {
-    parameters.add(new Dart2JsParameterMirror(owner, parameter,
-        isOptional: false, isNamed: false));
-  });
-  bool isNamed = signature.optionalParametersAreNamed;
-  signature.optionalParameters.forEach((FormalElement parameter) {
-    parameters.add(new Dart2JsParameterMirror(owner, parameter,
-        isOptional: true, isNamed: isNamed));
-  });
-  return parameters;
-}
-
-MethodMirror _convertElementMethodToMethodMirror(
-    Dart2JsDeclarationMirror library, Element element) {
-  if (element is FunctionElement) {
-    return new Dart2JsMethodMirror(library, element);
-  } else {
-    return null;
-  }
-}
-
-//------------------------------------------------------------------------------
-// Dart2Js specific extensions of mirror interfaces
-//------------------------------------------------------------------------------
-
-abstract class Dart2JsMirror implements Mirror {
-  Dart2JsMirrorSystem get mirrorSystem;
-}
-
-abstract class Dart2JsDeclarationMirror extends Dart2JsMirror
-    implements DeclarationSourceMirror {
-  bool get isTopLevel => owner != null && owner is LibraryMirror;
-
-  bool get isPrivate => _isPrivate(_simpleNameString);
-
-  String get _simpleNameString;
-
-  String get _qualifiedNameString {
-    var parent = owner;
-    if (parent is Dart2JsDeclarationMirror) {
-      return '${parent._qualifiedNameString}.${_simpleNameString}';
-    }
-    assert(parent == null);
-    return _simpleNameString;
-  }
-
-  Symbol get simpleName => symbolOf(_simpleNameString, getLibrary(this));
-
-  Symbol get qualifiedName => symbolOf(_qualifiedNameString, getLibrary(this));
-
-  DeclarationMirror lookupInScope(String name) => null;
-
-  bool get isNameSynthetic => false;
-
-  /// Returns the type mirror for [type] in the context of this declaration.
-  TypeMirror _getTypeMirror(DartType type) {
-    return mirrorSystem._convertTypeToTypeMirror(type);
-  }
-
-  /// Returns a list of the declaration mirrorSystem for [element].
-  Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element) {
-    if (element.isSynthesized) {
-      return const <Dart2JsMemberMirror>[];
-    } else if (element is VariableElement) {
-      return <Dart2JsMemberMirror>[new Dart2JsFieldMirror(this, element)];
-    } else if (element is FunctionElement) {
-      return <Dart2JsMemberMirror>[new Dart2JsMethodMirror(this, element)];
-    } else if (element is AbstractFieldElement) {
-      var members = <Dart2JsMemberMirror>[];
-      AbstractFieldElement field = element;
-      if (field.getter != null) {
-        members.add(new Dart2JsMethodMirror(this, field.getter));
-      }
-      if (field.setter != null) {
-        members.add(new Dart2JsMethodMirror(this, field.setter));
-      }
-      return members;
-    }
-    mirrorSystem.compiler.reporter.internalError(
-        element, "Unexpected member type $element ${element.kind}.");
-    return null;
-  }
-}
-
-abstract class Dart2JsElementMirror extends Dart2JsDeclarationMirror {
-  final Dart2JsMirrorSystem mirrorSystem;
-  final Element _element;
-  List<InstanceMirror> _metadata;
-
-  Dart2JsElementMirror(this.mirrorSystem, this._element) {
-    assert(mirrorSystem != null);
-    assert(_element != null);
-  }
-
-  String get _simpleNameString => _element.name;
-
-  /**
-   * Computes the first token for this declaration using the begin token of the
-   * element node or element position as indicator.
-   */
-  Token getBeginToken() {
-    Element element = _element;
-    if (element is AstElement) {
-      Node node = element.node;
-      if (node != null) {
-        return node.getBeginToken();
-      }
-    }
-    return element.position;
-  }
-
-  /**
-   * Computes the last token for this declaration using the end token of the
-   * element node or element position as indicator.
-   */
-  Token getEndToken() {
-    Element element = _element;
-    if (element is AstElement) {
-      Node node = element.node;
-      if (node != null) {
-        return node.getEndToken();
-      }
-    }
-    return element.position;
-  }
-
-  /**
-   * Returns the first token for the source of this declaration, including
-   * metadata annotations.
-   */
-  Token getFirstToken() {
-    if (!_element.metadata.isEmpty) {
-      for (MetadataAnnotation metadata in _element.metadata) {
-        if (metadata.beginToken != null) {
-          return metadata.beginToken;
-        }
-      }
-    }
-    return getBeginToken();
-  }
-
-  Script getScript() => _element.compilationUnit.script;
-
-  SourceLocation get location {
-    Token beginToken = getFirstToken();
-    Script script = getScript();
-    SourceSpan span;
-    if (beginToken == null) {
-      span = new SourceSpan(script.resourceUri, 0, 0);
-    } else {
-      Token endToken = getEndToken();
-      span =
-          new SourceSpan.fromTokens(script.resourceUri, beginToken, endToken);
-    }
-    return new Dart2JsSourceLocation(script, span);
-  }
-
-  String toString() => _element.toString();
-
-  void _appendCommentTokens(Token commentToken) {
-    while (commentToken != null && commentToken.kind == Tokens.COMMENT_TOKEN) {
-      _metadata.add(
-          new Dart2JsCommentInstanceMirror(mirrorSystem, commentToken.value));
-      commentToken = commentToken.next;
-    }
-  }
-
-  List<InstanceMirror> get metadata {
-    if (_metadata == null) {
-      _metadata = <InstanceMirror>[];
-      for (MetadataAnnotation metadata in _element.metadata) {
-        _appendCommentTokens(
-            mirrorSystem.compiler.commentMap[metadata.beginToken]);
-        metadata.ensureResolved(mirrorSystem.compiler.resolution);
-        _metadata.add(_convertConstantToInstanceMirror(
-            mirrorSystem,
-            metadata.constant,
-            mirrorSystem.compiler.constants
-                .getConstantValue(metadata.constant)));
-      }
-      _appendCommentTokens(mirrorSystem.compiler.commentMap[getBeginToken()]);
-    }
-    // TODO(johnniwinther): Return an unmodifiable list instead.
-    return new List<InstanceMirror>.from(_metadata);
-  }
-
-  DeclarationMirror lookupInScope(String name) {
-    // TODO(11653): Support lookup of constructors.
-    Scope scope = _element.buildScope();
-    Element result;
-    int index = name.indexOf('.');
-    if (index != -1) {
-      // Lookup [: prefix.id :].
-      String prefix = name.substring(0, index);
-      String id = name.substring(index + 1);
-      result = scope.lookup(prefix);
-      if (result != null && result.isPrefix) {
-        PrefixElement prefix = result;
-        result = prefix.lookupLocalMember(id);
-      } else {
-        result = null;
-      }
-    } else {
-      // Lookup [: id :].
-      result = scope.lookup(name);
-    }
-    if (result == null || result.isPrefix) return null;
-    return _convertElementToDeclarationMirror(mirrorSystem, result);
-  }
-
-  bool operator ==(var other) {
-    if (identical(this, other)) return true;
-    if (other == null) return false;
-    if (other is! Dart2JsElementMirror) return false;
-    return _element == other._element && owner == other.owner;
-  }
-
-  int get hashCode {
-    return 13 * _element.hashCode + 17 * owner.hashCode;
-  }
-}
-
-//------------------------------------------------------------------------------
-// Mirror system implementation.
-//------------------------------------------------------------------------------
-
-class Dart2JsMirrorSystem extends MirrorSystem {
-  final Compiler compiler;
-  Map<LibraryElement, Dart2JsLibraryMirror> _libraryMap;
-  UnmodifiableMapView<Uri, LibraryMirror> _filteredLibraries;
-
-  Dart2JsMirrorSystem(this.compiler);
-
-  IsolateMirror get isolate => null;
-
-  void _ensureLibraries() {
-    if (_filteredLibraries == null) {
-      var filteredLibs = new Map<Uri, LibraryMirror>();
-      _libraryMap = new Map<LibraryElement, Dart2JsLibraryMirror>();
-      compiler.libraryLoader.libraries.forEach((LibraryElement v) {
-        var mirror = new Dart2JsLibraryMirror(mirrorSystem, v);
-        if (_includeLibrary(mirror)) {
-          filteredLibs[mirror.uri] = mirror;
-        }
-        _libraryMap[v] = mirror;
-      });
-
-      _filteredLibraries =
-          new UnmodifiableMapView<Uri, LibraryMirror>(filteredLibs);
-    }
-  }
-
-  Map<Uri, LibraryMirror> get libraries {
-    _ensureLibraries();
-    return _filteredLibraries;
-  }
-
-  Dart2JsLibraryMirror _getLibrary(LibraryElement element) =>
-      _libraryMap[element];
-
-  Dart2JsMirrorSystem get mirrorSystem => this;
-
-  TypeMirror get dynamicType => _convertTypeToTypeMirror(const DynamicType());
-
-  TypeMirror get voidType => _convertTypeToTypeMirror(const VoidType());
-
-  TypeMirror _convertTypeToTypeMirror(DartType type) {
-    assert(type != null);
-    if (type.treatAsDynamic) {
-      return new Dart2JsDynamicMirror(this, type);
-    } else if (type is InterfaceType) {
-      if (type.typeArguments.isEmpty) {
-        return _getTypeDeclarationMirror(type.element);
-      } else {
-        return new Dart2JsInterfaceTypeMirror(this, type);
-      }
-    } else if (type is TypeVariableType) {
-      return new Dart2JsTypeVariableMirror(this, type);
-    } else if (type is FunctionType) {
-      return new Dart2JsFunctionTypeMirror(this, type);
-    } else if (type is VoidType) {
-      return new Dart2JsVoidMirror(this, type);
-    } else if (type is TypedefType) {
-      if (type.typeArguments.isEmpty) {
-        return _getTypeDeclarationMirror(type.element);
-      } else {
-        return new Dart2JsTypedefMirror(this, type);
-      }
-    }
-    compiler.reporter.internalError(
-        type.element, "Unexpected type $type of kind ${type.kind}.");
-    return null;
-  }
-
-  DeclarationMirror _getTypeDeclarationMirror(TypeDeclarationElement element) {
-    if (element.isClass) {
-      return new Dart2JsClassDeclarationMirror(this, element.thisType);
-    } else if (element.isTypedef) {
-      return new Dart2JsTypedefDeclarationMirror(this, element.thisType);
-    }
-    compiler.reporter.internalError(element, "Unexpected element $element.");
-    return null;
-  }
-}
-
-abstract class ContainerMixin {
-  UnmodifiableMapView<Symbol, DeclarationMirror> _declarations;
-
-  void _ensureDeclarations() {
-    if (_declarations == null) {
-      var declarations = <Symbol, DeclarationMirror>{};
-      _forEachElement((Element element) {
-        for (DeclarationMirror mirror in _getDeclarationMirrors(element)) {
-          assert(
-              invariant(_element, !declarations.containsKey(mirror.simpleName),
-                  message: "Declaration name '${nameOf(mirror)}' "
-                      "is not unique in $_element."));
-          declarations[mirror.simpleName] = mirror;
-        }
-      });
-      _declarations =
-          new UnmodifiableMapView<Symbol, DeclarationMirror>(declarations);
-    }
-  }
-
-  Element get _element;
-
-  void _forEachElement(f(Element element));
-
-  Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element);
-
-  Map<Symbol, DeclarationMirror> get declarations {
-    _ensureDeclarations();
-    return _declarations;
-  }
-}
-
-/**
- * Converts [element] into its corresponding [DeclarationMirror], if any.
- *
- * If [element] is an [AbstractFieldElement] the mirror for its getter is
- * returned or, if not present, the mirror for its setter.
- */
-DeclarationMirror _convertElementToDeclarationMirror(
-    Dart2JsMirrorSystem system, Element element) {
-  if (element.isTypeVariable) {
-    TypeVariableElement typeVariable = element;
-    return new Dart2JsTypeVariableMirror(system, typeVariable.type);
-  }
-
-  Dart2JsLibraryMirror library = system._libraryMap[element.library];
-  if (element.isLibrary) return library;
-  if (element.isTypedef) {
-    TypedefElement typedefElement = element;
-    return new Dart2JsTypedefMirror.fromLibrary(
-        library, typedefElement.thisType);
-  }
-
-  Dart2JsDeclarationMirror container = library;
-  if (element.enclosingClass != null) {
-    container = system._getTypeDeclarationMirror(element.enclosingClass);
-  }
-  if (element.isClass) return container;
-  if (element.isParameter) {
-    Dart2JsMethodMirror method = _convertElementMethodToMethodMirror(
-        container, element.outermostEnclosingMemberOrTopLevel);
-    // TODO(johnniwinther): Find the right info for [isOptional] and [isNamed].
-    return new Dart2JsParameterMirror(method, element,
-        isOptional: false, isNamed: false);
-  }
-  Iterable<DeclarationMirror> members =
-      container._getDeclarationMirrors(element);
-  if (members.isEmpty) return null;
-  return members.first;
-}
-
-/**
- * Experimental API for accessing compilation units defined in a
- * library.
- */
-// TODO(ahe): Superclasses? Is this really a mirror?
-class Dart2JsCompilationUnitMirror extends Dart2JsMirror with ContainerMixin {
-  final Dart2JsLibraryMirror _library;
-  final CompilationUnitElement _element;
-
-  Dart2JsCompilationUnitMirror(this._element, this._library);
-
-  Dart2JsMirrorSystem get mirrorSystem => _library.mirrorSystem;
-
-  // TODO(johnniwinther): make sure that these are returned in declaration
-  // order.
-  void _forEachElement(f(Element element)) => _element.forEachLocalMember(f);
-
-  Iterable<DeclarationMirror> _getDeclarationMirrors(Element element) =>
-      _library._getDeclarationMirrors(element);
-
-  Uri get uri => _element.script.resourceUri;
-}
-
-/**
- * Transitional class that allows access to features that have not yet
- * made it to the mirror API.
- *
- * All API in this class is experimental.
- */
-class BackDoor {
-  /// Return the compilation units comprising [library].
-  static List<Mirror> compilationUnitsOf(Dart2JsLibraryMirror library) {
-    return library._element.compilationUnits
-        .mapToList((cu) => new Dart2JsCompilationUnitMirror(cu, library));
-  }
-
-  static Iterable<ConstantExpression> metadataSyntaxOf(
-      Dart2JsElementMirror declaration) {
-    return declaration._element.metadata.map((metadata) => metadata.constant);
-  }
-
-  static ConstantExpression initializerSyntaxOf(Dart2JsFieldMirror variable) {
-    Compiler compiler = variable.mirrorSystem.compiler;
-    return variable._variable.constant;
-  }
-
-  static ConstantExpression defaultValueSyntaxOf(
-      Dart2JsParameterMirror parameter) {
-    if (!parameter.hasDefaultValue) return null;
-    ParameterElement parameterElement = parameter._element;
-    Compiler compiler = parameter.mirrorSystem.compiler;
-    return parameterElement.constant;
-  }
-
-  static Mirror getMirrorFromElement(Dart2JsMirror mirror, Element element) {
-    return _convertElementToDeclarationMirror(mirror.mirrorSystem, element);
-  }
-}
diff --git a/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart b/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart
deleted file mode 100644
index 6bf227c..0000000
--- a/pkg/compiler/lib/src/mirrors/dart2js_type_mirrors.dart
+++ /dev/null
@@ -1,497 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of dart2js.mirrors;
-
-abstract class ClassMirrorMixin implements ClassSourceMirror {
-  bool get hasReflectedType => false;
-  Type get reflectedType {
-    throw new UnsupportedError("ClassMirror.reflectedType is not supported.");
-  }
-
-  InstanceMirror newInstance(Symbol constructorName, List positionalArguments,
-      [Map<Symbol, dynamic> namedArguments]) {
-    throw new UnsupportedError("ClassMirror.newInstance is not supported.");
-  }
-}
-
-abstract class Dart2JsTypeMirror
-    implements Dart2JsDeclarationMirror, TypeSourceMirror {
-  DartType get _type;
-
-  String get _simpleNameString => _type.name;
-
-  Dart2JsDeclarationMirror get owner => library;
-
-  Dart2JsLibraryMirror get library;
-
-  bool get hasReflectedType => throw new UnimplementedError();
-
-  Type get reflectedType => throw new UnimplementedError();
-
-  bool get isOriginalDeclaration => true;
-
-  TypeMirror get originalDeclaration => this;
-
-  List<TypeMirror> get typeArguments => const <TypeMirror>[];
-
-  List<TypeVariableMirror> get typeVariables => const <TypeVariableMirror>[];
-
-  TypeMirror createInstantiation(List<TypeMirror> typeArguments) {
-    if (typeArguments.isEmpty) return this;
-    throw new ArgumentError('Cannot create generic instantiation of $_type.');
-  }
-
-  bool get isVoid => false;
-
-  bool get isDynamic => false;
-
-  bool isSubtypeOf(TypeMirror other) {
-    if (other is Dart2JsTypeMirror) {
-      return mirrorSystem.compiler.types.isSubtype(this._type, other._type);
-    } else {
-      throw new ArgumentError(other);
-    }
-  }
-
-  bool isAssignableTo(TypeMirror other) {
-    if (other is Dart2JsTypeMirror) {
-      return mirrorSystem.compiler.types.isAssignable(this._type, other._type);
-    } else {
-      throw new ArgumentError(other);
-    }
-  }
-
-  String toString() => _type.toString();
-}
-
-/// Base implementations for mirrors on element based types.
-abstract class Dart2JsTypeElementMirror extends Dart2JsElementMirror
-    with Dart2JsTypeMirror
-    implements TypeSourceMirror {
-  final DartType _type;
-
-  Dart2JsTypeElementMirror(Dart2JsMirrorSystem system, DartType type)
-      : super(system, type.element),
-        this._type = type;
-
-  Dart2JsLibraryMirror get library {
-    return mirrorSystem._getLibrary(_type.element.library);
-  }
-}
-
-abstract class DeclarationMixin implements TypeMirror {
-  bool get isOriginalDeclaration => true;
-
-  TypeMirror get originalDeclaration => this;
-
-  List<TypeMirror> get typeArguments => const <TypeMirror>[];
-}
-
-abstract class Dart2JsGenericTypeMirror extends Dart2JsTypeElementMirror {
-  List<TypeMirror> _typeArguments;
-  List<TypeVariableMirror> _typeVariables;
-
-  Dart2JsGenericTypeMirror(Dart2JsMirrorSystem system, GenericType type)
-      : super(system, type);
-
-  TypeDeclarationElement get _element => super._element;
-
-  GenericType get _type => super._type;
-
-  bool get isOriginalDeclaration => false;
-
-  TypeMirror get originalDeclaration =>
-      mirrorSystem._getTypeDeclarationMirror(_element);
-
-  List<TypeMirror> get typeArguments {
-    if (_typeArguments == null) {
-      _typeArguments = <TypeMirror>[];
-      if (!_type.isRaw) {
-        for (DartType type in _type.typeArguments) {
-          _typeArguments.add(_getTypeMirror(type));
-        }
-      }
-    }
-    return _typeArguments;
-  }
-
-  List<TypeVariableMirror> get typeVariables {
-    if (_typeVariables == null) {
-      _typeVariables = <TypeVariableMirror>[];
-      for (TypeVariableType typeVariable in _element.typeVariables) {
-        _typeVariables
-            .add(new Dart2JsTypeVariableMirror(mirrorSystem, typeVariable));
-      }
-    }
-    return _typeVariables;
-  }
-
-  Iterable<Dart2JsMemberMirror> _getDeclarationMirrors(Element element) {
-    if (element.isTypeVariable) {
-      assert(invariant(_element, _element == element.enclosingElement,
-          message: 'Foreigned type variable element $element.'));
-      for (Dart2JsTypeVariableMirror mirror in typeVariables) {
-        if (mirror._element == element) return [mirror];
-      }
-    }
-    return super._getDeclarationMirrors(element);
-  }
-
-  TypeMirror _getTypeMirror(DartType type) {
-    return super._getTypeMirror(
-        type.subst(_type.typeArguments, _type.element.typeVariables));
-  }
-
-  TypeSourceMirror createInstantiation(
-      List<TypeSourceMirror> newTypeArguments) {
-    if (newTypeArguments.isEmpty) return owner._getTypeMirror(_type.asRaw());
-    if (newTypeArguments.length != typeVariables.length) {
-      throw new ArgumentError('Cannot create generic instantiation of $_type '
-          'with ${newTypeArguments.length} arguments, '
-          'expect ${typeVariables.length} arguments.');
-    }
-    List<DartType> builder = <DartType>[];
-    for (TypeSourceMirror newTypeArgument in newTypeArguments) {
-      if (newTypeArgument.isVoid) {
-        throw new ArgumentError('Cannot use void as type argument.');
-      }
-      if (newTypeArgument is Dart2JsTypeMirror) {
-        builder.add(newTypeArgument._type);
-      } else {
-        throw new UnsupportedError('Cannot create instantiation using a type '
-            'mirror from a different mirrorSystem implementation.');
-      }
-    }
-    return owner._getTypeMirror(_type.createInstantiation(builder));
-  }
-}
-
-class Dart2JsInterfaceTypeMirror extends Dart2JsGenericTypeMirror
-    with ObjectMirrorMixin, ClassMirrorMixin, ContainerMixin
-    implements ClassMirror {
-  Dart2JsInterfaceTypeMirror(
-      Dart2JsMirrorSystem system, InterfaceType interfaceType)
-      : super(system, interfaceType);
-
-  ClassElement get _element => super._element;
-
-  InterfaceType get _type => super._type;
-
-  bool get isNameSynthetic {
-    if (_element.isMixinApplication) {
-      MixinApplicationElement mixinApplication = _element;
-      return mixinApplication.isUnnamedMixinApplication;
-    }
-    return false;
-  }
-
-  void _forEachElement(f(Element element)) {
-    _element.forEachMember((_, element) => f(element));
-  }
-
-  ClassMirror get superclass {
-    if (_element.supertype != null) {
-      return _getTypeMirror(_element.supertype);
-    }
-    return null;
-  }
-
-  bool isSubclassOf(Mirror other) {
-    if (other is Dart2JsTypeMirror) {
-      return other._type.element != null &&
-          _element.isSubclassOf(other._type.element);
-    } else {
-      throw new ArgumentError(other);
-    }
-  }
-
-  ClassMirror get mixin {
-    if (_element.isMixinApplication) {
-      MixinApplicationElement mixinApplication = _element;
-      return _getTypeMirror(mixinApplication.mixinType);
-    }
-    return this;
-  }
-
-  List<ClassMirror> get superinterfaces {
-    var list = <ClassMirror>[];
-    Link<DartType> link = _element.interfaces;
-    while (!link.isEmpty) {
-      var type = _getTypeMirror(link.head);
-      list.add(type);
-      link = link.tail;
-    }
-    return list;
-  }
-
-  Map<Symbol, MethodMirror> get instanceMembers => null;
-  Map<Symbol, MethodMirror> get staticMembers => null;
-
-  bool get isAbstract => _element.isAbstract;
-
-  bool get isEnum => throw new UnimplementedError();
-
-  bool operator ==(other) {
-    if (identical(this, other)) {
-      return true;
-    }
-    if (other is! ClassMirror) {
-      return false;
-    }
-    return _type == other._type;
-  }
-
-  String toString() => 'Mirror on interface type $_type';
-}
-
-class Dart2JsClassDeclarationMirror extends Dart2JsInterfaceTypeMirror
-    with DeclarationMixin {
-  Dart2JsClassDeclarationMirror(Dart2JsMirrorSystem system, InterfaceType type)
-      : super(system, type);
-
-  bool isSubclassOf(ClassMirror other) {
-    if (other is Dart2JsClassDeclarationMirror) {
-      Dart2JsClassDeclarationMirror otherDeclaration =
-          other.originalDeclaration;
-      return _element.isSubclassOf(otherDeclaration._element);
-    } else if (other is FunctionTypeMirror) {
-      return false;
-    }
-    throw new ArgumentError(other);
-  }
-
-  String toString() => 'Mirror on class ${_type.name}';
-}
-
-class Dart2JsTypedefMirror extends Dart2JsGenericTypeMirror
-    implements TypedefMirror {
-  final Dart2JsLibraryMirror _library;
-  List<TypeVariableMirror> _typeVariables;
-  var _definition;
-
-  Dart2JsTypedefMirror(Dart2JsMirrorSystem system, TypedefType _typedef)
-      : this._library = system._getLibrary(_typedef.element.library),
-        super(system, _typedef);
-
-  Dart2JsTypedefMirror.fromLibrary(
-      Dart2JsLibraryMirror library, TypedefType _typedef)
-      : this._library = library,
-        super(library.mirrorSystem, _typedef);
-
-  TypedefType get _typedef => _type;
-
-  LibraryMirror get library => _library;
-
-  bool get isTypedef => true;
-
-  FunctionTypeMirror get referent {
-    if (_definition == null) {
-      _definition = _getTypeMirror(_typedef.element.alias);
-    }
-    return _definition;
-  }
-
-  bool get isClass => false;
-
-  bool get isAbstract => false;
-
-  bool get isEnum => throw new UnimplementedError();
-
-  String toString() => 'Mirror on typedef $_type';
-}
-
-class Dart2JsTypedefDeclarationMirror extends Dart2JsTypedefMirror
-    with DeclarationMixin {
-  Dart2JsTypedefDeclarationMirror(Dart2JsMirrorSystem system, TypedefType type)
-      : super(system, type);
-
-  String toString() => 'Mirror on typedef ${_type.name}';
-}
-
-class Dart2JsTypeVariableMirror extends Dart2JsTypeElementMirror
-    implements TypeVariableMirror {
-  Dart2JsDeclarationMirror _owner;
-
-  Dart2JsTypeVariableMirror(
-      Dart2JsMirrorSystem system, TypeVariableType typeVariableType)
-      : super(system, typeVariableType);
-
-  TypeVariableType get _type => super._type;
-
-  Dart2JsDeclarationMirror get owner {
-    if (_owner == null) {
-      _owner =
-          mirrorSystem._getTypeDeclarationMirror(_type.element.typeDeclaration);
-    }
-    return _owner;
-  }
-
-  bool get isStatic => false;
-
-  TypeMirror get upperBound => owner._getTypeMirror(_type.element.bound);
-
-  bool operator ==(var other) {
-    if (identical(this, other)) {
-      return true;
-    }
-    if (other is! TypeVariableMirror) {
-      return false;
-    }
-    if (owner != other.owner) {
-      return false;
-    }
-    return qualifiedName == other.qualifiedName;
-  }
-
-  String toString() => 'Mirror on type variable $_type';
-}
-
-class Dart2JsFunctionTypeMirror extends Dart2JsTypeElementMirror
-    with ObjectMirrorMixin, ClassMirrorMixin, DeclarationMixin
-    implements FunctionTypeMirror {
-  List<ParameterMirror> _parameters;
-
-  Dart2JsFunctionTypeMirror(
-      Dart2JsMirrorSystem system, FunctionType functionType)
-      : super(system, functionType) {
-    assert(functionType.element != null);
-  }
-
-  FunctionType get _type => super._type;
-
-  // TODO(johnniwinther): Is this the qualified name of a function type?
-  Symbol get qualifiedName => originalDeclaration.qualifiedName;
-
-  // TODO(johnniwinther): Substitute type arguments for type variables.
-  Map<Symbol, DeclarationMirror> get declarations {
-    var method = callMethod;
-    if (method != null) {
-      var map = new Map<Symbol, DeclarationMirror>.from(
-          originalDeclaration.declarations);
-      var name = method.qualifiedName;
-      assert(!map.containsKey(name));
-      map[name] = method;
-      return new UnmodifiableMapView<Symbol, DeclarationMirror>(map);
-    }
-    return originalDeclaration.declarations;
-  }
-
-  bool get isFunction => true;
-
-  MethodMirror get callMethod => _convertElementMethodToMethodMirror(
-      mirrorSystem._getLibrary(_type.element.library), _type.element);
-
-  ClassMirror get originalDeclaration => mirrorSystem._getTypeDeclarationMirror(
-      mirrorSystem.compiler.coreClasses.functionClass);
-
-  // TODO(johnniwinther): Substitute type arguments for type variables.
-  ClassMirror get superclass => originalDeclaration.superclass;
-
-  // TODO(johnniwinther): Substitute type arguments for type variables.
-  List<ClassMirror> get superinterfaces => originalDeclaration.superinterfaces;
-
-  Map<Symbol, MethodMirror> get instanceMembers => null;
-  Map<Symbol, MethodMirror> get staticMembers => null;
-
-  ClassMirror get mixin => this;
-
-  bool get isPrivate => false;
-
-  bool get isAbstract => false;
-
-  bool get isEnum => throw new UnimplementedError();
-
-  List<TypeVariableMirror> get typeVariables =>
-      originalDeclaration.typeVariables;
-
-  TypeMirror get returnType => owner._getTypeMirror(_type.returnType);
-
-  List<ParameterMirror> get parameters {
-    if (_parameters == null) {
-      _parameters = _parametersFromFunctionSignature(
-          owner, _type.element.functionSignature);
-    }
-    return _parameters;
-  }
-
-  String toString() => 'Mirror on function type $_type';
-
-  bool isSubclassOf(ClassMirror other) => false;
-}
-
-/// Common superclass for mirrors on `dynamic` and `void`.
-abstract class Dart2JsBuiltinTypeMirror extends Dart2JsDeclarationMirror
-    with Dart2JsTypeMirror
-    implements TypeSourceMirror {
-  final Dart2JsMirrorSystem mirrorSystem;
-  final DartType _type;
-
-  Dart2JsBuiltinTypeMirror(
-      Dart2JsMirrorSystem this.mirrorSystem, DartType this._type);
-
-  Symbol get qualifiedName => simpleName;
-
-  /**
-   * The builtin types have has no location.
-   */
-  SourceLocation get location => null;
-
-  /**
-   * The builtin types have has no owner.
-   */
-  Dart2JsDeclarationMirror get owner => null;
-
-  /**
-   * The builtin types have no library.
-   */
-  Dart2JsLibraryMirror get library => null;
-
-  /**
-   * The builtin types have no metadata.
-   */
-  List<InstanceMirror> get metadata => const <InstanceMirror>[];
-}
-
-class Dart2JsVoidMirror extends Dart2JsBuiltinTypeMirror {
-  Dart2JsVoidMirror(Dart2JsMirrorSystem mirrorSystem, VoidType type)
-      : super(mirrorSystem, type);
-
-  bool get isVoid => true;
-
-  bool operator ==(other) {
-    if (identical(this, other)) {
-      return true;
-    }
-    if (other is! TypeMirror) {
-      return false;
-    }
-    return other.isVoid;
-  }
-
-  int get hashCode => 13 * _type.hashCode;
-
-  String toString() => 'Mirror on void';
-}
-
-class Dart2JsDynamicMirror extends Dart2JsBuiltinTypeMirror {
-  Dart2JsDynamicMirror(Dart2JsMirrorSystem mirrorSystem, DynamicType type)
-      : super(mirrorSystem, type);
-
-  bool get isDynamic => true;
-
-  bool operator ==(other) {
-    if (identical(this, other)) {
-      return true;
-    }
-    if (other is! TypeMirror) {
-      return false;
-    }
-    return other.isDynamic;
-  }
-
-  int get hashCode => 13 * _type.hashCode;
-
-  String toString() => 'Mirror on dynamic';
-}
diff --git a/pkg/compiler/lib/src/mirrors/mirrors_util.dart b/pkg/compiler/lib/src/mirrors/mirrors_util.dart
deleted file mode 100644
index 52eb0a9..0000000
--- a/pkg/compiler/lib/src/mirrors/mirrors_util.dart
+++ /dev/null
@@ -1,425 +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.
-
-library mirrors_util;
-
-import 'dart:collection' show Queue, IterableBase;
-
-import 'source_mirrors.dart';
-
-//------------------------------------------------------------------------------
-// Utility functions for using the Mirror API
-//------------------------------------------------------------------------------
-
-String nameOf(DeclarationMirror mirror) =>
-    MirrorSystem.getName(mirror.simpleName);
-
-String qualifiedNameOf(DeclarationMirror mirror) =>
-    MirrorSystem.getName(mirror.qualifiedName);
-
-// TODO(johnniwinther): Handle private names.
-Symbol symbolOf(String name, [LibraryMirror library]) => new Symbol(name);
-
-/**
- * Return the display name for [mirror].
- *
- * The display name is the normal representation of the entity name. In most
- * cases the display name is the simple name, but for a setter 'foo=' the
- * display name is simply 'foo' and for the unary minus operator the display
- * name is 'operator -'. For 'dart:' libraries the display name is the URI and
- * not the library name, for instance 'dart:core' instead of 'dart.core'.
- *
- * The display name is not unique.
- */
-String displayName(DeclarationMirror mirror) {
-  if (mirror is LibraryMirror) {
-    LibraryMirror library = mirror;
-    if (library.uri.scheme == 'dart') {
-      return library.uri.toString();
-    }
-  } else if (mirror is MethodMirror) {
-    String simpleName = nameOf(mirror);
-    if (mirror.isSetter) {
-      // Remove trailing '='.
-      return simpleName.substring(0, simpleName.length - 1);
-    } else if (mirror.isOperator) {
-      return 'operator ${operatorName(mirror)}';
-    } else if (mirror.isConstructor) {
-      String className = displayName(mirror.owner);
-      if (simpleName == '') {
-        return className;
-      } else {
-        return '$className.$simpleName';
-      }
-    }
-  }
-  return MirrorSystem.getName(mirror.simpleName);
-}
-
-/**
- * Returns the operator name if [methodMirror] is an operator method,
- * for instance [:'<':] for [:operator <:] and [:'-':] for the unary minus
- * operator. Return [:null:] if [methodMirror] is not an operator method.
- */
-String operatorName(MethodMirror methodMirror) {
-  if (methodMirror.isOperator) {
-    if (methodMirror.simpleName == const Symbol('unary-')) {
-      return '-';
-    } else {
-      return nameOf(methodMirror);
-    }
-  }
-  return null;
-}
-
-/**
- * Returns an iterable over the type declarations directly inheriting from
- * the declaration of [type] within [mirrors].
- */
-Iterable<ClassMirror> computeSubdeclarations(
-    MirrorSystem mirrors, ClassMirror type) {
-  type = type.originalDeclaration;
-  var subtypes = <ClassMirror>[];
-  mirrors.libraries.forEach((_, library) {
-    library.declarations.values
-        .where((mirror) => mirror is ClassMirror)
-        .forEach((ClassMirror otherType) {
-      var superClass = otherType.superclass;
-      if (superClass != null) {
-        superClass = superClass.originalDeclaration;
-        if (superClass == type) {
-          subtypes.add(otherType);
-        }
-      }
-      final superInterfaces = otherType.superinterfaces;
-      for (ClassMirror superInterface in superInterfaces) {
-        superInterface = superInterface.originalDeclaration;
-        if (superInterface == type) {
-          subtypes.add(otherType);
-        }
-      }
-    });
-  });
-  return subtypes;
-}
-
-class HierarchyIterable extends IterableBase<ClassMirror> {
-  final bool includeType;
-  final ClassMirror type;
-
-  HierarchyIterable(this.type, {bool includeType})
-      : this.includeType = includeType;
-
-  Iterator<ClassMirror> get iterator =>
-      new HierarchyIterator(type, includeType: includeType);
-}
-
-/**
- * [HierarchyIterator] iterates through the class hierarchy of the provided
- * type.
- *
- * First the superclass relation is traversed, skipping [Object], next the
- * superinterface relation and finally is [Object] visited. The supertypes are
- * visited in breadth first order and a superinterface is visited more than once
- * if implemented through multiple supertypes.
- */
-class HierarchyIterator implements Iterator<ClassMirror> {
-  final Queue<ClassMirror> queue = new Queue<ClassMirror>();
-  ClassMirror object;
-  ClassMirror _current;
-
-  HierarchyIterator(ClassMirror type, {bool includeType}) {
-    if (includeType) {
-      queue.add(type);
-    } else {
-      push(type);
-    }
-  }
-
-  ClassMirror push(ClassMirror type) {
-    if (type.superclass != null) {
-      if (isObject(type.superclass)) {
-        object = type.superclass;
-      } else {
-        queue.addFirst(type.superclass);
-      }
-    }
-    queue.addAll(type.superinterfaces);
-    return type;
-  }
-
-  ClassMirror get current => _current;
-
-  bool moveNext() {
-    _current = null;
-    if (queue.isEmpty) {
-      if (object == null) return false;
-      _current = object;
-      object = null;
-      return true;
-    } else {
-      _current = push(queue.removeFirst());
-      return true;
-    }
-  }
-}
-
-LibraryMirror getLibrary(DeclarationMirror declaration) {
-  while (declaration != null && declaration is! LibraryMirror) {
-    declaration = declaration.owner;
-  }
-  return declaration;
-}
-
-Iterable<DeclarationMirror> membersOf(
-    Map<Symbol, DeclarationMirror> declarations) {
-  return declarations.values
-      .where((mirror) => mirror is MethodMirror || mirror is VariableMirror);
-}
-
-Iterable<TypeMirror> classesOf(Map<Symbol, DeclarationMirror> declarations) {
-  return new _TypeOfIterable<ClassMirror>(declarations.values);
-}
-
-Iterable<TypeMirror> typesOf(Map<Symbol, DeclarationMirror> declarations) {
-  return new _TypeOfIterable<TypeMirror>(declarations.values);
-}
-
-Iterable<MethodMirror> methodsOf(Map<Symbol, DeclarationMirror> declarations) {
-  return anyMethodOf(declarations).where((mirror) => mirror.isRegularMethod);
-}
-
-Iterable<MethodMirror> constructorsOf(
-    Map<Symbol, DeclarationMirror> declarations) {
-  return anyMethodOf(declarations).where((mirror) => mirror.isConstructor);
-}
-
-Iterable<MethodMirror> settersOf(Map<Symbol, DeclarationMirror> declarations) {
-  return anyMethodOf(declarations).where((mirror) => mirror.isSetter);
-}
-
-Iterable<MethodMirror> gettersOf(Map<Symbol, DeclarationMirror> declarations) {
-  return anyMethodOf(declarations).where((mirror) => mirror.isGetter);
-}
-
-Iterable<MethodMirror> anyMethodOf(
-    Map<Symbol, DeclarationMirror> declarations) {
-  return new _TypeOfIterable<MethodMirror>(declarations.values);
-}
-
-Iterable<VariableMirror> variablesOf(
-    Map<Symbol, DeclarationMirror> declarations) {
-  return new _TypeOfIterable<VariableMirror>(declarations.values);
-}
-
-class _TypeOfIterable<T> extends IterableBase<T> {
-  final Iterable _source;
-
-  _TypeOfIterable(this._source);
-
-  Iterator<T> get iterator => new _TypeOfIterator<T>(_source.iterator);
-}
-
-class _TypeOfIterator<T> implements Iterator<T> {
-  final Iterator _source;
-
-  T get current => _source.current;
-
-  _TypeOfIterator(this._source);
-
-  bool moveNext() {
-    while (_source.moveNext()) {
-      if (_source.current is T) {
-        return true;
-      }
-    }
-    return false;
-  }
-}
-
-bool isObject(TypeMirror mirror) =>
-    mirror is ClassMirror && mirror.superclass == null;
-
-/// Returns `true` if [cls] is declared in a private dart library.
-bool isFromPrivateDartLibrary(ClassMirror cls) {
-  if (isMixinApplication(cls)) cls = cls.mixin;
-  var uri = getLibrary(cls).uri;
-  return uri.scheme == 'dart' && uri.path.startsWith('_');
-}
-
-/// Returns `true` if [mirror] reflects a mixin application.
-bool isMixinApplication(Mirror mirror) {
-  return mirror is ClassMirror && mirror.mixin != mirror;
-}
-
-/**
- * Returns the superclass of [cls] skipping unnamed mixin applications.
- *
- * For instance, for all of the following definitions this method returns [:B:].
- *
- *     class A extends B {}
- *     class A extends B with C1, C2 {}
- *     class A extends B implements D1, D2 {}
- *     class A extends B with C1, C2 implements D1, D2 {}
- *     class A = B with C1, C2;
- *     abstract class A = B with C1, C2 implements D1, D2;
- */
-ClassSourceMirror getSuperclass(ClassSourceMirror cls) {
-  ClassSourceMirror superclass = cls.superclass;
-  while (isMixinApplication(superclass) && superclass.isNameSynthetic) {
-    superclass = superclass.superclass;
-  }
-  return superclass;
-}
-
-/**
- * Returns the mixins directly applied to [cls].
- *
- * For instance, for all of the following definitions this method returns
- * [:C1, C2:].
- *
- *     class A extends B with C1, C2 {}
- *     class A extends B with C1, C2 implements D1, D2 {}
- *     class A = B with C1, C2;
- *     abstract class A = B with C1, C2 implements D1, D2;
- */
-Iterable<ClassSourceMirror> getAppliedMixins(ClassSourceMirror cls) {
-  List<ClassSourceMirror> mixins = <ClassSourceMirror>[];
-  ClassSourceMirror superclass = cls.superclass;
-  while (isMixinApplication(superclass) && superclass.isNameSynthetic) {
-    mixins.add(superclass.mixin);
-    superclass = superclass.superclass;
-  }
-  if (mixins.length > 1) {
-    mixins = new List<ClassSourceMirror>.from(mixins.reversed);
-  }
-  if (isMixinApplication(cls)) {
-    mixins.add(cls.mixin);
-  }
-  return mixins;
-}
-
-/**
- * Returns the superinterfaces directly and explicitly implemented by [cls].
- *
- * For instance, for all of the following definitions this method returns
- * [:D1, D2:].
- *
- *     class A extends B implements D1, D2 {}
- *     class A extends B with C1, C2 implements D1, D2 {}
- *     abstract class A = B with C1, C2 implements D1, D2;
- */
-Iterable<ClassMirror> getExplicitInterfaces(ClassMirror cls) {
-  if (isMixinApplication(cls)) {
-    bool first = true;
-    ClassMirror mixin = cls.mixin;
-    bool filter(ClassMirror superinterface) {
-      if (first && superinterface == mixin) {
-        first = false;
-        return false;
-      }
-      return true;
-    }
-    return cls.superinterfaces.where(filter);
-  }
-  return cls.superinterfaces;
-}
-
-final RegExp _singleLineCommentStart = new RegExp(r'^///? ?(.*)');
-final RegExp _multiLineCommentStartEnd =
-    new RegExp(r'^/\*\*? ?([\s\S]*)\*/$', multiLine: true);
-final RegExp _multiLineCommentLineStart = new RegExp(r'^[ \t]*\* ?(.*)');
-
-/**
- * Pulls the raw text out of a comment (i.e. removes the comment
- * characters).
- */
-String stripComment(String comment) {
-  Match match = _singleLineCommentStart.firstMatch(comment);
-  if (match != null) {
-    return match[1];
-  }
-  match = _multiLineCommentStartEnd.firstMatch(comment);
-  if (match != null) {
-    comment = match[1];
-    var sb = new StringBuffer();
-    List<String> lines = comment.split('\n');
-    for (int index = 0; index < lines.length; index++) {
-      String line = lines[index];
-      if (index == 0) {
-        sb.write(line); // Add the first line unprocessed.
-        continue;
-      }
-      sb.write('\n');
-      match = _multiLineCommentLineStart.firstMatch(line);
-      if (match != null) {
-        sb.write(match[1]);
-      } else if (index < lines.length - 1 || !line.trim().isEmpty) {
-        // Do not add the last line if it only contains white space.
-        // This interprets cases like
-        //     /*
-        //      * Foo
-        //      */
-        // as "\nFoo\n" and not as "\nFoo\n     ".
-        sb.write(line);
-      }
-    }
-    return sb.toString();
-  }
-  throw new ArgumentError('Invalid comment $comment');
-}
-
-/**
- * Looks up [name] in the scope [declaration].
- *
- * If [name] is of the form 'a.b.c', 'a' is looked up in the scope of
- * [declaration] and if unresolved 'a.b' is looked in the scope of
- * [declaration]. Each identifier of the remaining suffix, 'c' or 'b.c', is
- * then looked up in the local scope of the previous result.
- *
- * For instance, assumming that [:Iterable:] is imported into the scope of
- * [declaration] via the prefix 'col', 'col.Iterable.E' finds the type
- * variable of [:Iterable:] and 'col.Iterable.contains.element' finds the
- * [:element:] parameter of the [:contains:] method on [:Iterable:].
- */
-DeclarationMirror lookupQualifiedInScope(
-    DeclarationSourceMirror declaration, String name) {
-  // TODO(11653): Support lookup of constructors using the [:new Foo:]
-  // syntax.
-  int offset = 1;
-  List<String> parts = name.split('.');
-  DeclarationMirror result = declaration.lookupInScope(parts[0]);
-  if (result == null && parts.length > 1) {
-    // Try lookup of `prefix.id`.
-    result = declaration.lookupInScope('${parts[0]}.${parts[1]}');
-    offset = 2;
-  }
-  if (result == null) return null;
-  LibraryMirror library = getLibrary(result);
-  while (result != null && offset < parts.length) {
-    result = _lookupLocal(result, symbolOf(parts[offset++], library));
-  }
-  return result;
-}
-
-DeclarationMirror _lookupLocal(Mirror mirror, Symbol id) {
-  DeclarationMirror result;
-  if (mirror is LibraryMirror) {
-    // Try member lookup.
-    result = mirror.declarations[id];
-  } else if (mirror is ClassMirror) {
-    // Try member lookup.
-    result = mirror.declarations[id];
-    if (result != null) return result;
-    // Try type variables.
-    result = mirror.typeVariables.firstWhere(
-        (TypeVariableMirror v) => v.simpleName == id,
-        orElse: () => null);
-  } else if (mirror is MethodMirror) {
-    result = mirror.parameters.firstWhere(
-        (ParameterMirror p) => p.simpleName == id,
-        orElse: () => null);
-  }
-  return result;
-}
diff --git a/pkg/compiler/lib/src/mirrors/source_mirrors.dart b/pkg/compiler/lib/src/mirrors/source_mirrors.dart
deleted file mode 100644
index 6bf555c..0000000
--- a/pkg/compiler/lib/src/mirrors/source_mirrors.dart
+++ /dev/null
@@ -1,255 +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.
-
-library mirrors;
-
-import 'dart:mirrors';
-import 'dart:mirrors' as api show SourceLocation;
-export 'dart:mirrors';
-
-abstract class DeclarationSourceMirror implements DeclarationMirror {
-  /// Returns `true` if the name of this declaration is generated by the
-  /// provider of the mirror system.
-  bool get isNameSynthetic;
-
-  /**
-   * Looks up [name] in the scope of this declaration.
-   *
-   * [name] may be either a single identifier, like 'foo', or of the
-   * a prefixed identifier, like 'foo.bar', where 'foo' must be a prefix.
-   * For methods and constructors, the scope includes the parameters. For
-   * classes and typedefs, the scope includes the type variables.
-   * For classes and class members, the scope includes inherited members.
-   *
-   * See also:
-   *
-   * * [Lexical Scope](https://www.dartlang.org/docs/dart-up-and-running/contents/ch02.html#ch02-lexical-scope)
-   *   in Dart Up and Running.
-   * * [Lexical Scoping](http://www.dartlang.org/docs/spec/latest/dart-language-specification.html#h.jb82efuudrc5)
-   *   in the Dart Specification.
-   */
-  DeclarationMirror lookupInScope(String name);
-}
-
-/**
- * Specialized [InstanceMirror] used for reflection on constant lists.
- */
-abstract class ListInstanceMirror implements InstanceMirror {
-  /**
-   * Returns an instance mirror of the value at [index] or throws a [RangeError]
-   * if the [index] is out of bounds.
-   */
-  InstanceMirror getElement(int index);
-
-  /**
-   * The number of elements in the list.
-   */
-  int get length;
-}
-
-/**
- * Specialized [InstanceMirror] used for reflection on constant maps.
- */
-abstract class MapInstanceMirror implements InstanceMirror {
-  /**
-   * Returns a collection containing all the keys in the map.
-   */
-  Iterable<String> get keys;
-
-  /**
-   * Returns an instance mirror of the value for the given key or
-   * null if key is not in the map.
-   */
-  InstanceMirror getValue(String key);
-
-  /**
-   * The number of {key, value} pairs in the map.
-   */
-  int get length;
-}
-
-/**
- * Specialized [InstanceMirror] used for reflection on type constants.
- */
-abstract class TypeInstanceMirror implements InstanceMirror {
-  /**
-   * Returns the type mirror for the type represented by the reflected type
-   * constant.
-   */
-  TypeMirror get representedType;
-}
-
-/**
- * Specialized [InstanceMirror] used for reflection on comments as metadata.
- */
-abstract class CommentInstanceMirror implements InstanceMirror {
-  /**
-   * The comment text as written in the source text.
-   */
-  String get text;
-
-  /**
-   * The comment text without the start, end, and padding text.
-   *
-   * For example, if [text] is [: /** Comment text. */ :] then the [trimmedText]
-   * is [: Comment text. :].
-   */
-  String get trimmedText;
-
-  /**
-   * Is [:true:] if this comment is a documentation comment.
-   *
-   * That is, that the comment is either enclosed in [: /** ... */ :] or starts
-   * with [: /// :].
-   */
-  bool get isDocComment;
-}
-
-/**
- * A library.
- */
-abstract class LibrarySourceMirror
-    implements DeclarationSourceMirror, LibraryMirror {
-  /**
-   * Returns a list of the imports and exports in this library;
-   */
-  List<LibraryDependencyMirror> get libraryDependencies;
-}
-
-/// A mirror on an import or export declaration.
-abstract class LibraryDependencySourceMirror extends Mirror
-    implements LibraryDependencyMirror {
-  /// Is `true` if this dependency is an import.
-  bool get isImport;
-
-  /// Is `true` if this dependency is an export.
-  bool get isExport;
-
-  /// Returns the library mirror of the library that imports or exports the
-  /// [targetLibrary].
-  LibraryMirror get sourceLibrary;
-
-  /// Returns the library mirror of the library that is imported or exported.
-  LibraryMirror get targetLibrary;
-
-  /// Returns the prefix if this is a prefixed import and `null` otherwise.
-  /*String*/ get prefix;
-
-  /// Returns the list of show/hide combinators on the import/export
-  /// declaration.
-  List<CombinatorMirror> get combinators;
-
-  /// Returns the source location for this import/export declaration.
-  SourceLocation get location;
-
-  /// Returns a future that completes when the library is loaded and initates a
-  /// load if one has not already happened.
-  /*Future<LibraryMirror>*/ loadLibrary();
-}
-
-/// A mirror on a show/hide combinator declared on a library dependency.
-abstract class CombinatorSourceMirror extends Mirror
-    implements CombinatorMirror {
-  /// The list of identifiers on the combinator.
-  List/*<String>*/ get identifiers;
-
-  /// Is `true` if this is a 'show' combinator.
-  bool get isShow;
-
-  /// Is `true` if this is a 'hide' combinator.
-  bool get isHide;
-}
-
-/**
- * Common interface for classes, interfaces, typedefs and type variables.
- */
-abstract class TypeSourceMirror implements DeclarationSourceMirror, TypeMirror {
-  /// Returns `true` is this is a mirror on the void type.
-  bool get isVoid;
-
-  /// Returns `true` is this is a mirror on the dynamic type.
-  bool get isDynamic;
-
-  /// Create a type mirror on the instantiation of the declaration of this type
-  /// with [typeArguments] as type arguments.
-  TypeMirror createInstantiation(List<TypeMirror> typeArguments);
-}
-
-/**
- * A class or interface type.
- */
-abstract class ClassSourceMirror implements TypeSourceMirror, ClassMirror {
-  /**
-   * Is [:true:] if this class is declared abstract.
-   */
-  bool get isAbstract;
-}
-
-/**
- * A formal parameter.
- */
-abstract class ParameterSourceMirror implements ParameterMirror {
-  /**
-   * Returns [:true:] iff this parameter is an initializing formal of a
-   * constructor. That is, if it is of the form [:this.x:] where [:x:] is a
-   * field.
-   */
-  bool get isInitializingFormal;
-
-  /**
-   * Returns the initialized field, if this parameter is an initializing formal.
-   */
-  VariableMirror get initializedField;
-}
-
-/**
- * A [SourceLocation] describes the span of an entity in Dart source code.
- * A [SourceLocation] with a non-zero [length] should be the minimum span that
- * encloses the declaration of the mirrored entity.
- */
-abstract class SourceLocation implements api.SourceLocation {
-  /**
-   * The 1-based line number for this source location.
-   *
-   * A value of 0 means that the line number is unknown.
-   */
-  int get line;
-
-  /**
-   * The 1-based column number for this source location.
-   *
-   * A value of 0 means that the column number is unknown.
-   */
-  int get column;
-
-  /**
-   * The 0-based character offset into the [sourceText] where this source
-   * location begins.
-   *
-   * A value of -1 means that the offset is unknown.
-   */
-  int get offset;
-
-  /**
-   * The number of characters in this source location.
-   *
-   * A value of 0 means that the [offset] is approximate.
-   */
-  int get length;
-
-  /**
-   * The text of the location span.
-   */
-  String get text;
-
-  /**
-   * Returns the URI where the source originated.
-   */
-  Uri get sourceUri;
-
-  /**
-   * Returns the text of this source.
-   */
-  String get sourceText;
-}
diff --git a/pkg/compiler/lib/src/mirrors_used.dart b/pkg/compiler/lib/src/mirrors_used.dart
index a13469e..c909c8a 100644
--- a/pkg/compiler/lib/src/mirrors_used.dart
+++ b/pkg/compiler/lib/src/mirrors_used.dart
@@ -80,8 +80,11 @@
 class MirrorUsageAnalyzerTask extends CompilerTask {
   Set<LibraryElement> librariesWithUsage;
   MirrorUsageAnalyzer analyzer;
+  final Compiler compiler;
 
-  MirrorUsageAnalyzerTask(Compiler compiler) : super(compiler) {
+  MirrorUsageAnalyzerTask(Compiler compiler)
+      : compiler = compiler,
+        super(compiler.measurer) {
     analyzer = new MirrorUsageAnalyzer(compiler, this);
   }
 
@@ -150,9 +153,8 @@
   final Map<ConstantValue, List<Element>> cachedElements;
   MirrorUsage mergedMirrorUsage;
 
-  MirrorUsageAnalyzer(Compiler compiler, this.task)
-      : compiler = compiler,
-        librariesWithUsage = new Set<LibraryElement>(),
+  MirrorUsageAnalyzer(this.compiler, this.task)
+      : librariesWithUsage = new Set<LibraryElement>(),
         cachedStrings = new Map<ConstantValue, List<String>>(),
         cachedElements = new Map<ConstantValue, List<Element>>();
 
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 93af700..e839a17 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -187,8 +187,8 @@
   /// Whether to emit URIs in the reflection metadata.
   final bool preserveUris;
 
-  /// The location of serialized data used for resolution.
-  final Uri resolutionInput;
+  /// The locations of serialized data used for resolution.
+  final List<Uri> resolutionInputs;
 
   /// The location of the serialized data from resolution.
   final Uri resolutionOutput;
@@ -256,7 +256,7 @@
       Uri libraryRoot,
       Uri packageRoot,
       Uri packageConfig,
-      Uri resolutionInput,
+      List<Uri> resolutionInputs,
       Uri resolutionOutput,
       PackagesDiscoveryProvider packagesDiscoveryProvider,
       Map<String, dynamic> environment: const <String, dynamic>{},
@@ -309,7 +309,7 @@
             _resolvePlatformConfigFromOptions(libraryRoot, options),
         preserveComments: _hasOption(options, Flags.preserveComments),
         preserveUris: _hasOption(options, Flags.preserveUris),
-        resolutionInput: resolutionInput,
+        resolutionInputs: resolutionInputs,
         resolutionOutput: resolutionOutput,
         resolveOnly: _hasOption(options, Flags.resolveOnly),
         sourceMapUri: _extractUriOption(options, '--source-map='),
@@ -373,7 +373,7 @@
       Uri platformConfigUri: null,
       bool preserveComments: false,
       bool preserveUris: false,
-      Uri resolutionInput: null,
+      List<Uri> resolutionInputs: null,
       Uri resolutionOutput: null,
       bool resolveOnly: false,
       Uri sourceMapUri: null,
@@ -448,7 +448,7 @@
                 libraryRoot, null, !emitJavaScript, const []),
         preserveComments: preserveComments,
         preserveUris: preserveUris,
-        resolutionInput: resolutionInput,
+        resolutionInputs: resolutionInputs,
         resolutionOutput: resolutionOutput,
         resolveOnly: resolveOnly,
         sourceMapUri: sourceMapUri,
@@ -499,7 +499,7 @@
       this.platformConfigUri: null,
       this.preserveComments: false,
       this.preserveUris: false,
-      this.resolutionInput: null,
+      this.resolutionInputs: null,
       this.resolutionOutput: null,
       this.resolveOnly: false,
       this.sourceMapUri: null,
diff --git a/pkg/compiler/lib/src/parser/diet_parser_task.dart b/pkg/compiler/lib/src/parser/diet_parser_task.dart
index 4192143..3c48a31 100644
--- a/pkg/compiler/lib/src/parser/diet_parser_task.dart
+++ b/pkg/compiler/lib/src/parser/diet_parser_task.dart
@@ -6,8 +6,7 @@
 
 import '../common.dart';
 import '../common/backend_api.dart' show Backend;
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
+import '../common/tasks.dart' show CompilerTask, Measurer;
 import '../elements/elements.dart' show CompilationUnitElement;
 import '../id_generator.dart';
 import '../tokens/token.dart' show Token;
@@ -23,9 +22,9 @@
   final Backend _backend;
   final DiagnosticReporter _reporter;
 
-  DietParserTask(Compiler compiler, this._parserOptions, this._idGenerator,
-      this._backend, this._reporter)
-      : super(compiler);
+  DietParserTask(this._parserOptions, this._idGenerator, this._backend,
+      this._reporter, Measurer measurer)
+      : super(measurer);
 
   final String name = 'Diet Parser';
 
diff --git a/pkg/compiler/lib/src/parser/parser_task.dart b/pkg/compiler/lib/src/parser/parser_task.dart
index 6470d1f..02c3719 100644
--- a/pkg/compiler/lib/src/parser/parser_task.dart
+++ b/pkg/compiler/lib/src/parser/parser_task.dart
@@ -19,8 +19,11 @@
 
 class ParserTask extends CompilerTask {
   final ParserOptions parserOptions;
+  final Compiler compiler;
 
-  ParserTask(Compiler compiler, this.parserOptions) : super(compiler);
+  ParserTask(Compiler compiler, this.parserOptions)
+      : compiler = compiler,
+        super(compiler.measurer);
 
   String get name => 'Parser';
 
@@ -31,7 +34,7 @@
   Node parseCompilationUnit(Token token) {
     return measure(() {
       NodeListener listener =
-          new NodeListener(const ScannerOptions(), reporter, null);
+          new NodeListener(const ScannerOptions(), compiler.reporter, null);
       Parser parser = new Parser(listener, parserOptions);
       try {
         parser.parseUnit(token);
diff --git a/pkg/compiler/lib/src/patch_parser.dart b/pkg/compiler/lib/src/patch_parser.dart
index 9baaeb3..a2246c4 100644
--- a/pkg/compiler/lib/src/patch_parser.dart
+++ b/pkg/compiler/lib/src/patch_parser.dart
@@ -146,8 +146,12 @@
 class PatchParserTask extends CompilerTask {
   final String name = "Patching Parser";
   final ParserOptions parserOptions;
+  final Compiler compiler;
+  DiagnosticReporter get reporter => compiler.reporter;
 
-  PatchParserTask(Compiler compiler, this.parserOptions) : super(compiler);
+  PatchParserTask(Compiler compiler, this.parserOptions)
+      : compiler = compiler,
+        super(compiler.measurer);
 
   /**
    * Scans a library patch file, applies the method patches and
diff --git a/pkg/compiler/lib/src/resolution/class_hierarchy.dart b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
index 1150c96..e136a14 100644
--- a/pkg/compiler/lib/src/resolution/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/resolution/class_hierarchy.dart
@@ -557,7 +557,7 @@
   isBlackListed(DartType type) {
     LibraryElement lib = element.library;
     return !identical(lib, compiler.coreLibrary) &&
-        !compiler.backend.isBackendLibrary(lib) &&
+        !resolution.target.isTargetSpecificLibrary(lib) &&
         (type.isDynamic ||
             type == coreTypes.boolType ||
             type == coreTypes.numType ||
diff --git a/pkg/compiler/lib/src/resolution/class_members.dart b/pkg/compiler/lib/src/resolution/class_members.dart
index 6a06749..6cbbf70 100644
--- a/pkg/compiler/lib/src/resolution/class_members.dart
+++ b/pkg/compiler/lib/src/resolution/class_members.dart
@@ -25,7 +25,7 @@
 
 abstract class MembersCreator {
   final ClassElement cls;
-  final Compiler compiler;
+  final Resolution resolution;
 
   final Iterable<String> computedMemberNames;
   final Map<Name, Member> classMembers;
@@ -34,17 +34,12 @@
       new Map<dynamic, Set<MessageKind>>();
 
   MembersCreator(
-      Compiler this.compiler,
-      ClassElement this.cls,
-      Iterable<String> this.computedMemberNames,
-      Map<Name, Member> this.classMembers) {
+      this.resolution, this.cls, this.computedMemberNames, this.classMembers) {
     assert(invariant(cls, cls.isDeclaration,
         message: "Members may only be computed on declarations."));
   }
 
-  DiagnosticReporter get reporter => compiler.reporter;
-
-  Resolution get resolution => compiler.resolution;
+  DiagnosticReporter get reporter => resolution.reporter;
 
   void reportMessage(var marker, MessageKind kind, report()) {
     Set<MessageKind> messages =
@@ -118,12 +113,12 @@
     }
 
     if (names != null) {
-      _computeClassMember(compiler, superclass, name, names);
+      _computeClassMember(resolution, superclass, name, names);
       for (Name memberName in names) {
         inheritClassMember(superclass.lookupClassMember(memberName));
       }
     } else {
-      computeAllClassMembers(compiler, superclass);
+      computeAllClassMembers(resolution, superclass);
       superclass.forEachClassMember(inheritClassMember);
     }
   }
@@ -155,13 +150,13 @@
 
         if (names != null) {
           _computeClassMember(
-              compiler, mixinApplication.mixin, nameText, names);
+              resolution, mixinApplication.mixin, nameText, names);
           for (Name memberName in names) {
             inheritMixinMember(
                 mixinApplication.mixin.lookupClassMember(memberName));
           }
         } else {
-          computeAllClassMembers(compiler, mixinApplication.mixin);
+          computeAllClassMembers(resolution, mixinApplication.mixin);
           mixinApplication.mixin.forEachClassMember(inheritMixinMember);
         }
       }
@@ -314,12 +309,12 @@
   void checkImplementsFunctionWithCall() {
     assert(!cls.isAbstract);
 
-    ClassElement functionClass = compiler.coreClasses.functionClass;
+    ClassElement functionClass = resolution.coreClasses.functionClass;
     if (cls.asInstanceOf(functionClass) == null) return;
     if (cls.lookupMember(Identifiers.call) != null) return;
     // TODO(johnniwinther): Make separate methods for backend exceptions.
     // Avoid warnings on backend implementation classes for closures.
-    if (compiler.backend.isBackendLibrary(cls.library)) return;
+    if (resolution.target.isTargetSpecificLibrary(cls.library)) return;
 
     reportMessage(functionClass, MessageKind.UNIMPLEMENTED_METHOD, () {
       reporter.reportWarningMessage(cls, MessageKind.UNIMPLEMENTED_METHOD_ONE, {
@@ -368,7 +363,8 @@
         for (Member inherited in superMember.declarations) {
           if (cls == inherited.declarer.element) {
             // An error should already have been reported.
-            assert(invariant(declared.element, compiler.compilationFailed));
+            assert(invariant(
+                declared.element, resolution.reporter.hasReportedError));
             continue;
           }
 
@@ -389,9 +385,10 @@
           // superMember.declarations. Investigate why.
         } else if (cls == inherited.declarer.element) {
           // An error should already have been reported.
-          assert(invariant(declared.element, compiler.compilationFailed,
-              message: "Member $inherited inherited from its "
-                  "declaring class: ${cls}."));
+          assert(
+              invariant(declared.element, resolution.reporter.hasReportedError,
+                  message: "Member $inherited inherited from its "
+                      "declaring class: ${cls}."));
           continue;
         }
 
@@ -427,7 +424,7 @@
               MessageKind.CANNOT_OVERRIDE_GETTER_WITH_METHOD_CONT);
         } else {
           DartType inheritedType = inherited.functionType;
-          if (!compiler.types.isSubtype(declaredType, inheritedType)) {
+          if (!resolution.types.isSubtype(declaredType, inheritedType)) {
             void reportWarning(
                 var marker, MessageKind warningKind, MessageKind infoKind) {
               reportMessage(marker, MessageKind.INVALID_OVERRIDE_METHOD, () {
@@ -511,11 +508,11 @@
 
   /// Compute all class and interface names by the [name] in [cls].
   static void computeClassMembersByName(
-      Compiler compiler, ClassMemberMixin cls, String name) {
+      Resolution resolution, ClassMemberMixin cls, String name) {
     if (cls.isMemberComputed(name)) return;
     LibraryElement library = cls.library;
     _computeClassMember(
-        compiler,
+        resolution,
         cls,
         name,
         new Setlet<Name>()
@@ -523,23 +520,24 @@
           ..add(new Name(name, library, isSetter: true)));
   }
 
-  static void _computeClassMember(Compiler compiler, ClassMemberMixin cls,
+  static void _computeClassMember(Resolution resolution, ClassMemberMixin cls,
       String name, Setlet<Name> names) {
-    cls.computeClassMember(compiler, name, names);
+    cls.computeClassMember(resolution, name, names);
   }
 
   /// Compute all class and interface names in [cls].
-  static void computeAllClassMembers(Compiler compiler, ClassMemberMixin cls) {
-    cls.computeAllClassMembers(compiler);
+  static void computeAllClassMembers(
+      Resolution resolution, ClassMemberMixin cls) {
+    cls.computeAllClassMembers(resolution);
   }
 }
 
 /// Class member creator for classes where the interface members are known to
 /// be a subset of the class members.
 class ClassMembersCreator extends MembersCreator {
-  ClassMembersCreator(Compiler compiler, ClassElement cls,
+  ClassMembersCreator(Resolution resolution, ClassElement cls,
       Iterable<String> computedMemberNames, Map<Name, Member> classMembers)
-      : super(compiler, cls, computedMemberNames, classMembers);
+      : super(resolution, cls, computedMemberNames, classMembers);
 
   Map<Name, Member> computeMembers(String name, Setlet<Name> names) {
     computeSuperMembers(name, names);
@@ -565,12 +563,12 @@
   final Map<Name, MemberSignature> interfaceMembers;
 
   InterfaceMembersCreator(
-      Compiler compiler,
+      Resolution resolution,
       ClassElement cls,
       Iterable<String> computedMemberNames,
       Map<Name, Member> classMembers,
       Map<Name, MemberSignature> this.interfaceMembers)
-      : super(compiler, cls, computedMemberNames, classMembers);
+      : super(resolution, cls, computedMemberNames, classMembers);
 
   Map<Name, Member> computeMembers(String name, Setlet<Name> names) {
     Map<Name, Setlet<Member>> inheritedInterfaceMembers =
@@ -634,13 +632,14 @@
       InterfaceType superinterface = link.head;
       if (names != null) {
         MembersCreator._computeClassMember(
-            compiler, superinterface.element, name, names);
+            resolution, superinterface.element, name, names);
         for (Name memberName in names) {
           inheritInterfaceMember(superinterface,
               superinterface.element.lookupInterfaceMember(memberName));
         }
       } else {
-        MembersCreator.computeAllClassMembers(compiler, superinterface.element);
+        MembersCreator.computeAllClassMembers(
+            resolution, superinterface.element);
         inheritInterfaceMembers(superinterface);
       }
     }
@@ -697,7 +696,7 @@
             if (someAreGetters) break outer;
           }
           for (MemberSignature other in inheritedMembers) {
-            if (!compiler.types
+            if (!resolution.types
                 .isSubtype(inherited.functionType, other.functionType)) {
               continue outer;
             }
@@ -833,9 +832,9 @@
 
   /// Creates the necessary maps and [MembersCreator] for compute members of
   /// this class.
-  MembersCreator _prepareCreator(Compiler compiler) {
+  MembersCreator _prepareCreator(Resolution resolution) {
     if (classMembers == null) {
-      ensureResolved(compiler.resolution);
+      ensureResolved(resolution);
       classMembers = new Map<Name, Member>();
 
       if (interfaceMembersAreClassMembers) {
@@ -853,8 +852,8 @@
     }
     return interfaceMembersAreClassMembers
         ? new ClassMembersCreator(
-            compiler, this, computedMemberNames, classMembers)
-        : new InterfaceMembersCreator(compiler, this, computedMemberNames,
+            resolution, this, computedMemberNames, classMembers)
+        : new InterfaceMembersCreator(resolution, this, computedMemberNames,
             classMembers, interfaceMembers);
   }
 
@@ -863,14 +862,15 @@
   /// Compute the members by the name [name] for this class. [names] collects
   /// the set of possible variations of [name], including getter, setter and
   /// and private names.
-  void computeClassMember(Compiler compiler, String name, Setlet<Name> names) {
+  void computeClassMember(
+      Resolution resolution, String name, Setlet<Name> names) {
     if (isMemberComputed(name)) return;
     if (Name.isPrivateName(name)) {
       names
         ..add(new Name(name, library))
         ..add(new Name(name, library, isSetter: true));
     }
-    MembersCreator creator = _prepareCreator(compiler);
+    MembersCreator creator = _prepareCreator(resolution);
     creator.computeMembersByName(name, names);
     if (computedMemberNames == null) {
       computedMemberNames = _EMPTY_MEMBERS_NAMES;
@@ -886,9 +886,9 @@
     }
   }
 
-  void computeAllClassMembers(Compiler compiler) {
+  void computeAllClassMembers(Resolution resolution) {
     if (areAllMembersComputed()) return;
-    MembersCreator creator = _prepareCreator(compiler);
+    MembersCreator creator = _prepareCreator(resolution);
     creator.computeAllMembers();
     computedMemberNames = null;
     assert(invariant(this, areAllMembersComputed()));
diff --git a/pkg/compiler/lib/src/resolution/constructors.dart b/pkg/compiler/lib/src/resolution/constructors.dart
index 17bd6e0..7a4dbc6 100644
--- a/pkg/compiler/lib/src/resolution/constructors.dart
+++ b/pkg/compiler/lib/src/resolution/constructors.dart
@@ -719,7 +719,17 @@
   ConstructorResult constructorResultForType(Node node, DartType type,
       {PrefixElement prefix}) {
     String name = type.name;
-    if (type.isMalformed) {
+    if (type.isTypeVariable) {
+      return reportAndCreateErroneousConstructorElement(
+          node,
+          ConstructorResultKind.INVALID_TYPE,
+          type,
+          resolver.enclosingElement,
+          name,
+          MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
+          {'typeVariableName': name});
+    } else if (type.isMalformed) {
+      // `type is MalformedType`: `MethodTypeVariableType` is handled above.
       return new ConstructorResult.forError(
           ConstructorResultKind.INVALID_TYPE, type.element, type);
     } else if (type.isInterfaceType) {
@@ -733,15 +743,6 @@
           name,
           MessageKind.CANNOT_INSTANTIATE_TYPEDEF,
           {'typedefName': name});
-    } else if (type.isTypeVariable) {
-      return reportAndCreateErroneousConstructorElement(
-          node,
-          ConstructorResultKind.INVALID_TYPE,
-          type,
-          resolver.enclosingElement,
-          name,
-          MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE,
-          {'typeVariableName': name});
     }
     return reporter.internalError(node, "Unexpected constructor type $type");
   }
diff --git a/pkg/compiler/lib/src/resolution/members.dart b/pkg/compiler/lib/src/resolution/members.dart
index 68f6f31..b69287a 100644
--- a/pkg/compiler/lib/src/resolution/members.dart
+++ b/pkg/compiler/lib/src/resolution/members.dart
@@ -24,7 +24,6 @@
         JumpTargetX,
         LocalFunctionElementX,
         LocalParameterElementX,
-        MethodElementX,
         ParameterElementX,
         VariableElementX,
         VariableList;
@@ -1122,6 +1121,14 @@
       type = resolveTypeAnnotation(typeNode);
       sendStructure = new IsStructure(type);
     }
+
+    // GENERIC_METHODS: Method type variables are not reified so we must warn
+    // about the error which will occur at runtime.
+    if (type is MethodTypeVariableType) {
+      reporter.reportWarningMessage(
+          node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED);
+    }
+
     registry.registerTypeUse(new TypeUse.isCheck(type));
     registry.registerSendStructure(node, sendStructure);
     return const NoneResult();
@@ -1134,6 +1141,14 @@
 
     Node typeNode = node.arguments.head;
     DartType type = resolveTypeAnnotation(typeNode);
+
+    // GENERIC_METHODS: Method type variables are not reified so we must warn
+    // about the error which will occur at runtime.
+    if (type is MethodTypeVariableType) {
+      reporter.reportWarningMessage(
+          node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED);
+    }
+
     registry.registerTypeUse(new TypeUse.asCast(type));
     registry.registerSendStructure(node, new AsStructure(type));
     return const NoneResult();
@@ -1546,7 +1561,7 @@
       bool isIncompatibleInvoke = false;
       switch (semantics.kind) {
         case AccessKind.SUPER_METHOD:
-          MethodElementX superMethod = semantics.element;
+          MethodElement superMethod = semantics.element;
           superMethod.computeType(resolution);
           if (!callStructure.signatureApplies(superMethod.functionSignature)) {
             registry.registerFeature(Feature.THROW_NO_SUCH_METHOD);
@@ -1824,7 +1839,7 @@
       return const NoneResult();
     }
     MembersCreator.computeClassMembersByName(
-        compiler, receiverClass.declaration, name);
+        resolution, receiverClass.declaration, name);
     Element member = receiverClass.lookupLocalMember(name);
     if (member == null) {
       return handleUnresolvedStaticMemberAccess(
@@ -1849,7 +1864,7 @@
     String name = memberName.text;
     receiverClass.ensureResolved(resolution);
     MembersCreator.computeClassMembersByName(
-        compiler, receiverClass.declaration, name);
+        resolution, receiverClass.declaration, name);
     Element member = receiverClass.lookupLocalMember(name);
     if (member == null) {
       return handleUnresolvedStaticMemberUpdate(
@@ -1889,6 +1904,12 @@
       // TODO(johnniwinther): Clean up registration of elements and selectors
       // for this case.
     } else {
+      // GENERIC_METHODS: Method type variables are not reified so we must warn
+      // about the error which will occur at runtime.
+      if (element.type is MethodTypeVariableType) {
+        reporter.reportWarningMessage(
+            node, MessageKind.TYPE_VARIABLE_FROM_METHOD_NOT_REIFIED);
+      }
       semantics = new StaticAccess.typeParameterTypeLiteral(element);
     }
 
@@ -3012,7 +3033,8 @@
     if (element is! ClassElement) return null;
     ClassElement cls = element;
     cls.ensureResolved(resolution);
-    return cls.computeType(resolution);
+    cls.computeType(resolution);
+    return cls.rawType;
   }
 
   /// Handle index operations like `a[b] = c`, `a[b] += c`, and `a[b]++`.
diff --git a/pkg/compiler/lib/src/resolution/resolution.dart b/pkg/compiler/lib/src/resolution/resolution.dart
index 0676ba6..4ea5aff 100644
--- a/pkg/compiler/lib/src/resolution/resolution.dart
+++ b/pkg/compiler/lib/src/resolution/resolution.dart
@@ -59,11 +59,16 @@
 
 class ResolverTask extends CompilerTask {
   final ConstantCompiler constantCompiler;
+  final Compiler compiler;
 
-  ResolverTask(Compiler compiler, this.constantCompiler) : super(compiler);
+  ResolverTask(Compiler compiler, this.constantCompiler)
+      : compiler = compiler,
+        super(compiler.measurer);
 
   String get name => 'Resolver';
 
+  DiagnosticReporter get reporter => compiler.reporter;
+
   Resolution get resolution => compiler.resolution;
 
   ParsingContext get parsingContext => compiler.parsingContext;
@@ -417,21 +422,23 @@
     return result;
   }
 
-  void resolveRedirectionChain(
-      ConstructorElementX constructor, Spannable node) {
-    ConstructorElementX target = constructor;
+  void resolveRedirectionChain(ConstructorElement constructor, Spannable node) {
+    ConstructorElement target = constructor;
     InterfaceType targetType;
     List<Element> seen = new List<Element>();
     bool isMalformed = false;
     // Follow the chain of redirections and check for cycles.
     while (target.isRedirectingFactory || target.isPatched) {
-      if (target.effectiveTargetInternal != null) {
+      if (target.hasEffectiveTarget) {
         // We found a constructor that already has been processed.
-        targetType = target.effectiveTargetType;
+        // TODO(johnniwinther): Should `effectiveTargetType` be part of the
+        // interface?
+        targetType =
+            target.computeEffectiveTargetType(target.enclosingClass.thisType);
         assert(invariant(target, targetType != null,
             message: 'Redirection target type has not been computed for '
                 '$target'));
-        target = target.effectiveTargetInternal;
+        target = target.effectiveTarget;
         break;
       }
 
@@ -665,11 +672,11 @@
   }
 
   void computeClassMembers(ClassElement element) {
-    MembersCreator.computeAllClassMembers(compiler, element);
+    MembersCreator.computeAllClassMembers(resolution, element);
   }
 
   void computeClassMember(ClassElement element, String name) {
-    MembersCreator.computeClassMembersByName(compiler, element, name);
+    MembersCreator.computeClassMembersByName(resolution, element, name);
   }
 
   void checkClass(ClassElement element) {
diff --git a/pkg/compiler/lib/src/resolution/resolution_common.dart b/pkg/compiler/lib/src/resolution/resolution_common.dart
index 3cf5dcb..819c292 100644
--- a/pkg/compiler/lib/src/resolution/resolution_common.dart
+++ b/pkg/compiler/lib/src/resolution/resolution_common.dart
@@ -6,7 +6,6 @@
 
 import '../common.dart';
 import '../common/resolution.dart' show Resolution;
-import '../common/tasks.dart' show DeferredAction;
 import '../compiler.dart' show Compiler;
 import '../elements/elements.dart';
 import '../tree/tree.dart';
@@ -34,7 +33,7 @@
   /** Convenience method for visiting nodes that may be null. */
   R visit(Node node) => (node == null) ? null : node.accept(this);
 
-  void addDeferredAction(Element element, DeferredAction action) {
+  void addDeferredAction(Element element, void action()) {
     compiler.enqueuer.resolution.addDeferredAction(element, action);
   }
 }
diff --git a/pkg/compiler/lib/src/resolution/signatures.dart b/pkg/compiler/lib/src/resolution/signatures.dart
index 33a8f2f..d3f3264 100644
--- a/pkg/compiler/lib/src/resolution/signatures.dart
+++ b/pkg/compiler/lib/src/resolution/signatures.dart
@@ -314,10 +314,12 @@
         nodes = nodes.tail;
         TypeVariableElementX variableElement =
             new TypeVariableElementX(variableName, element, index, node);
-        // TODO(eernst): When type variables are implemented fully we will need
-        // to resolve the actual bounds; currently we just claim [dynamic].
+        // GENERIC_METHODS: When method type variables are implemented fully we
+        // must resolve the actual bounds; currently we just claim that
+        // every method type variable has upper bound [dynamic].
         variableElement.boundCache = const DynamicType();
-        TypeVariableType variableType = new TypeVariableType(variableElement);
+        TypeVariableType variableType =
+            new MethodTypeVariableType(variableElement);
         variableElement.typeCache = variableType;
         return variableType;
       }, growable: false);
diff --git a/pkg/compiler/lib/src/resolution/type_resolver.dart b/pkg/compiler/lib/src/resolution/type_resolver.dart
index e1a076d..9837a09 100644
--- a/pkg/compiler/lib/src/resolution/type_resolver.dart
+++ b/pkg/compiler/lib/src/resolution/type_resolver.dart
@@ -206,10 +206,6 @@
           }
         }
       } else if (element.isTypeVariable) {
-        // FIXME: check enclosing, which may be not class, not typedef (so
-        // it's a generic method) then set the type to `const DynamicType()`.
-        // This should later be fixed such that we don't tell the user that they
-        // wrote `dynamic` anywhere.
         TypeVariableElement typeVariable = element;
         Element outer =
             visitor.enclosingElement.outermostEnclosingMemberOrTopLevel;
diff --git a/pkg/compiler/lib/src/scanner/scanner_task.dart b/pkg/compiler/lib/src/scanner/scanner_task.dart
index 3d694a3..6b25efd 100644
--- a/pkg/compiler/lib/src/scanner/scanner_task.dart
+++ b/pkg/compiler/lib/src/scanner/scanner_task.dart
@@ -4,8 +4,8 @@
 
 library dart2js.scanner.task;
 
-import '../common/tasks.dart' show CompilerTask;
-import '../compiler.dart' show Compiler;
+import '../common/tasks.dart' show CompilerTask, Measurer;
+import '../diagnostics/diagnostic_listener.dart' show DiagnosticReporter;
 import '../elements/elements.dart' show CompilationUnitElement, LibraryElement;
 import '../script.dart' show Script;
 import '../parser/diet_parser_task.dart' show DietParserTask;
@@ -20,12 +20,13 @@
   final DietParserTask _dietParser;
   final bool _preserveComments;
   final TokenMap _commentMap;
+  final DiagnosticReporter reporter;
 
-  ScannerTask(Compiler compiler, this._dietParser,
+  ScannerTask(this._dietParser, this.reporter, Measurer measurer,
       {bool preserveComments: false, TokenMap commentMap})
       : _preserveComments = preserveComments,
         _commentMap = commentMap,
-        super(compiler) {
+        super(measurer) {
     if (_preserveComments && _commentMap == null) {
       throw new ArgumentError(
           "commentMap must be provided if preserveComments is true");
diff --git a/pkg/compiler/lib/src/serialization/element_serialization.dart b/pkg/compiler/lib/src/serialization/element_serialization.dart
index ebb179a..ab10cc8 100644
--- a/pkg/compiler/lib/src/serialization/element_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/element_serialization.dart
@@ -51,7 +51,7 @@
   LOCAL_VARIABLE,
   EXTERNAL_LIBRARY,
   EXTERNAL_LIBRARY_MEMBER,
-  EXTERNAL_STATIC_MEMBER,
+  EXTERNAL_CLASS_MEMBER,
   EXTERNAL_CONSTRUCTOR,
 }
 
@@ -730,7 +730,7 @@
         return new LocalVariableElementZ(decoder);
       case SerializedElementKind.EXTERNAL_LIBRARY:
       case SerializedElementKind.EXTERNAL_LIBRARY_MEMBER:
-      case SerializedElementKind.EXTERNAL_STATIC_MEMBER:
+      case SerializedElementKind.EXTERNAL_CLASS_MEMBER:
       case SerializedElementKind.EXTERNAL_CONSTRUCTOR:
         break;
     }
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index 3c10292..0c06ea4 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -10,6 +10,7 @@
 library dart2js.serialization.modelz;
 
 import '../common.dart';
+import '../common/names.dart';
 import '../common/resolution.dart' show Resolution;
 import '../constants/constructors.dart';
 import '../constants/expressions.dart';
@@ -370,6 +371,9 @@
   String get name => entryCompilationUnit.name;
 
   @override
+  SourceSpan get sourcePosition => entryCompilationUnit.sourcePosition;
+
+  @override
   accept(ElementVisitor visitor, arg) {
     return visitor.visitLibraryElement(this, arg);
   }
@@ -556,6 +560,9 @@
   Element get enclosingElement => library;
 
   @override
+  SourceSpan get sourcePosition => new SourceSpan(script.resourceUri, 0, 0);
+
+  @override
   accept(ElementVisitor visitor, arg) {
     return visitor.visitCompilationUnitElement(this, arg);
   }
@@ -772,7 +779,10 @@
   List<DartType> get typeVariables => functionSignature.typeVariables;
 }
 
-abstract class ClassElementMixin implements ElementZ, ClassElement {
+abstract class ClassElementMixin
+    implements ElementZ, ClassElement, class_members.ClassMemberMixin {
+  bool _isResolved = false;
+
   InterfaceType _createType(List<DartType> typeArguments) {
     return new InterfaceType(this, typeArguments);
   }
@@ -806,7 +816,12 @@
 
   @override
   void ensureResolved(Resolution resolution) {
-    resolution.registerClass(this);
+    if (!_isResolved) {
+      _isResolved = true;
+      class_members.MembersCreator
+          .computeClassMembersByName(resolution, this, Identifiers.call);
+      resolution.registerClass(this);
+    }
   }
 }
 
@@ -903,6 +918,7 @@
   @override
   FunctionType get callType {
     _ensureSuperHierarchy();
+    // TODO(johnniwinther): Why can't this always be computed in ensureResolved?
     return _callType;
   }
 }
@@ -967,8 +983,11 @@
       for (ConstructorElement definingConstructor in superclass.constructors) {
         if (definingConstructor.isGenerativeConstructor &&
             definingConstructor.memberName.isAccessibleFrom(library)) {
-          builder.addLast(
-              new ForwardingConstructorElementZ(this, definingConstructor));
+          ForwardingConstructorElementZ constructor =
+              new ForwardingConstructorElementZ(this, definingConstructor);
+          constructor.resolvedAst = new SynthesizedResolvedAst(
+              constructor, ResolvedAstKind.FORWARDING_CONSTRUCTOR);
+          builder.addLast(constructor);
         }
       }
       _constructors = builder.toLink();
@@ -1108,6 +1127,9 @@
   ConstructorElement get definingConstructor => null;
 
   @override
+  bool get hasEffectiveTarget => true;
+
+  @override
   ConstructorElement get effectiveTarget {
     if (_effectiveTarget == null) {
       _effectiveTarget =
@@ -1256,7 +1278,7 @@
 
   @override
   InterfaceType computeEffectiveTargetType(InterfaceType newType) {
-    return enclosingClass.thisType;
+    return enclosingClass.thisType.substByContext(newType);
   }
 
   @override
@@ -1269,6 +1291,9 @@
   ConstantConstructor get constantConstructor => null;
 
   @override
+  bool get hasEffectiveTarget => true;
+
+  @override
   ConstructorElement get effectiveTarget => this;
 
   @override
@@ -1405,6 +1430,9 @@
   }
 
   @override
+  bool get hasConstant => true;
+
+  @override
   ConstantExpression get constant {
     _ensureConstant();
     return _constant;
@@ -1852,6 +1880,9 @@
   bool get isConst => false;
 
   @override
+  bool get hasConstant => true;
+
+  @override
   ConstantExpression get constant {
     if (isOptional) {
       if (_constant == null) {
@@ -1980,6 +2011,9 @@
   }
 
   @override
+  bool get hasConstant => true;
+
+  @override
   ConstantExpression get constant {
     if (isConst) {
       return _constant;
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index a16e558..74dd4a0 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -4,9 +4,10 @@
 
 library dart2js.serialization;
 
-import '../elements/elements.dart';
+import '../common.dart';
 import '../constants/expressions.dart';
 import '../dart_types.dart';
+import '../elements/elements.dart';
 import '../util/enumset.dart';
 
 import 'constant_serialization.dart';
@@ -686,6 +687,20 @@
     DataObject dataObject = _elementMap[element];
     if (dataObject == null) {
       if (!shouldInclude(element)) {
+        /// Helper used to check that external references are serialized by
+        /// the right kind.
+        bool verifyElement(var found, var expected) {
+          found = found.declaration;
+          if (found == expected) return true;
+          if (found.isAbstractField && expected.isGetter) {
+            return found.getter == expected;
+          }
+          if (found.isAbstractField && expected.isSetter) {
+            return found.setter == expected;
+          }
+          return false;
+        }
+
         if (element.isLibrary) {
           LibraryElement library = element;
           _elementMap[element] = dataObject = new DataObject(
@@ -693,15 +708,15 @@
               new EnumValue(SerializedElementKind.EXTERNAL_LIBRARY));
           ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
           encoder.setUri(Key.URI, library.canonicalUri, library.canonicalUri);
-        } else if (element.isStatic) {
-          Value classId = _getElementId(element.enclosingClass);
-          _elementMap[element] = dataObject = new DataObject(
-              new IntValue(_elementMap.length),
-              new EnumValue(SerializedElementKind.EXTERNAL_STATIC_MEMBER));
-          ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
-          encoder.setValue(Key.CLASS, classId);
-          encoder.setString(Key.NAME, element.name);
         } else if (element.isConstructor) {
+          assert(invariant(
+              element,
+              verifyElement(
+                  element.enclosingClass.implementation
+                      .lookupConstructor(element.name),
+                  element),
+              message: "Element $element is not found as a "
+                  "constructor of ${element.enclosingClass.implementation}."));
           Value classId = _getElementId(element.enclosingClass);
           _elementMap[element] = dataObject = new DataObject(
               new IntValue(_elementMap.length),
@@ -709,7 +724,31 @@
           ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
           encoder.setValue(Key.CLASS, classId);
           encoder.setString(Key.NAME, element.name);
+        } else if (element.isClassMember) {
+          assert(invariant(
+              element,
+              verifyElement(
+                  element.enclosingClass.lookupLocalMember(element.name),
+                  element),
+              message: "Element $element is not found as a "
+                  "class member of ${element.enclosingClass}."));
+          Value classId = _getElementId(element.enclosingClass);
+          _elementMap[element] = dataObject = new DataObject(
+              new IntValue(_elementMap.length),
+              new EnumValue(SerializedElementKind.EXTERNAL_CLASS_MEMBER));
+          ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
+          encoder.setValue(Key.CLASS, classId);
+          encoder.setString(Key.NAME, element.name);
+          if (element.isAccessor) {
+            encoder.setBool(Key.GETTER, element.isGetter);
+          }
         } else {
+          assert(invariant(
+              element,
+              verifyElement(
+                  element.library.implementation.find(element.name), element),
+              message: "Element $element is not found as a "
+                  "library member of ${element.library.implementation}."));
           Value libraryId = _getElementId(element.library);
           _elementMap[element] = dataObject = new DataObject(
               new IntValue(_elementMap.length),
@@ -717,6 +756,9 @@
           ObjectEncoder encoder = new ObjectEncoder(this, dataObject.map);
           encoder.setValue(Key.LIBRARY, libraryId);
           encoder.setString(Key.NAME, element.name);
+          if (element.isAccessor) {
+            encoder.setBool(Key.GETTER, element.isGetter);
+          }
         }
       } else {
         // Run through [ELEMENT_SERIALIZERS] sequentially to find the one that
@@ -878,18 +920,33 @@
 
 /// Context for parallel deserialization.
 class DeserializationContext {
+  final DiagnosticReporter reporter;
   Map<Uri, LibraryElement> _uriMap = <Uri, LibraryElement>{};
   List<Deserializer> deserializers = <Deserializer>[];
+  List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
+
+  DeserializationContext(this.reporter);
 
   LibraryElement lookupLibrary(Uri uri) {
     return _uriMap.putIfAbsent(uri, () {
+      Uri foundUri;
+      LibraryElement foundLibrary;
       for (Deserializer deserializer in deserializers) {
         LibraryElement library = deserializer.lookupLibrary(uri);
         if (library != null) {
-          return library;
+          if (foundLibrary != null) {
+            reporter.reportErrorMessage(NO_LOCATION_SPANNABLE,
+                MessageKind.DUPLICATE_SERIALIZED_LIBRARY, {
+              'libraryUri': uri,
+              'sourceUri1': foundUri,
+              'sourceUri2': deserializer.sourceUri
+            });
+          }
+          foundUri = deserializer.sourceUri;
+          foundLibrary = library;
         }
       }
-      return null;
+      return foundLibrary;
     });
   }
 }
@@ -900,7 +957,7 @@
 class Deserializer {
   final DeserializationContext context;
   final SerializationDecoder decoder;
-  List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
+  final Uri sourceUri;
   ObjectDecoder _headerObject;
   ListDecoder _elementList;
   ListDecoder _typeList;
@@ -909,9 +966,9 @@
   Map<int, DartType> _typeMap = {};
   Map<int, ConstantExpression> _constantMap = {};
 
-  Deserializer.fromText(this.context, String text, this.decoder) {
+  Deserializer.fromText(
+      this.context, this.sourceUri, String text, this.decoder) {
     _headerObject = new ObjectDecoder(this, decoder.decode(text));
-    context.deserializers.add(this);
   }
 
   /// Returns the [ListDecoder] for the [Element]s in this deserializer.
@@ -974,16 +1031,35 @@
       } else if (elementKind == SerializedElementKind.EXTERNAL_LIBRARY_MEMBER) {
         LibraryElement library = decoder.getElement(Key.LIBRARY);
         String name = decoder.getString(Key.NAME);
+        bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
         element = library.find(name);
         if (element == null) {
           throw new StateError("Missing library member for $name in $library.");
         }
-      } else if (elementKind == SerializedElementKind.EXTERNAL_STATIC_MEMBER) {
+        if (isGetter != null) {
+          AbstractFieldElement abstractField = element;
+          element = isGetter ? abstractField.getter : abstractField.setter;
+          if (element == null) {
+            throw new StateError(
+                "Missing ${isGetter ? 'getter' : 'setter'} for "
+                "$name in $library.");
+          }
+        }
+      } else if (elementKind == SerializedElementKind.EXTERNAL_CLASS_MEMBER) {
         ClassElement cls = decoder.getElement(Key.CLASS);
         String name = decoder.getString(Key.NAME);
+        bool isGetter = decoder.getBool(Key.GETTER, isOptional: true);
         element = cls.lookupLocalMember(name);
         if (element == null) {
-          throw new StateError("Missing static member for $name in $cls.");
+          throw new StateError("Missing class member for $name in $cls.");
+        }
+        if (isGetter != null) {
+          AbstractFieldElement abstractField = element;
+          element = isGetter ? abstractField.getter : abstractField.setter;
+          if (element == null) {
+            throw new StateError(
+                "Missing ${isGetter ? 'getter' : 'setter'} for $name in $cls.");
+          }
         }
       } else if (elementKind == SerializedElementKind.EXTERNAL_CONSTRUCTOR) {
         ClassElement cls = decoder.getElement(Key.CLASS);
@@ -1000,7 +1076,7 @@
       MapDecoder pluginData = decoder.getMap(Key.DATA, isOptional: true);
       // Call plugins even when there is no data, so they can take action in
       // this case.
-      for (DeserializerPlugin plugin in plugins) {
+      for (DeserializerPlugin plugin in context.plugins) {
         plugin.onElement(element,
             (String tag) => pluginData?.getObject(tag, isOptional: true));
       }
diff --git a/pkg/compiler/lib/src/serialization/system.dart b/pkg/compiler/lib/src/serialization/system.dart
index 8db5c4b..02a716b 100644
--- a/pkg/compiler/lib/src/serialization/system.dart
+++ b/pkg/compiler/lib/src/serialization/system.dart
@@ -28,43 +28,40 @@
 
 class DeserializerSystemImpl extends DeserializerSystem {
   final Compiler _compiler;
-  final Deserializer _deserializer;
+  final DeserializationContext deserializationContext;
   final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
   final ResolutionImpactDeserializer _resolutionImpactDeserializer;
   final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
   final ImpactTransformer _impactTransformer;
 
-  factory DeserializerSystemImpl(Compiler compiler, Deserializer deserializer,
-      ImpactTransformer impactTransformer) {
-    List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
+  factory DeserializerSystemImpl(
+      Compiler compiler, ImpactTransformer impactTransformer) {
+    DeserializationContext context =
+        new DeserializationContext(compiler.reporter);
     DeserializerPlugin backendDeserializer =
         compiler.backend.serialization.deserializer;
-    deserializer.plugins.add(backendDeserializer);
+    context.plugins.add(backendDeserializer);
     ResolutionImpactDeserializer resolutionImpactDeserializer =
         new ResolutionImpactDeserializer(backendDeserializer);
-    deserializer.plugins.add(resolutionImpactDeserializer);
+    context.plugins.add(resolutionImpactDeserializer);
     ResolvedAstDeserializerPlugin resolvedAstDeserializer =
         new ResolvedAstDeserializerPlugin(
             compiler.parsingContext, backendDeserializer);
-    deserializer.plugins.add(resolvedAstDeserializer);
-    return new DeserializerSystemImpl._(
-        compiler,
-        deserializer,
-        impactTransformer,
-        resolutionImpactDeserializer,
-        resolvedAstDeserializer);
+    context.plugins.add(resolvedAstDeserializer);
+    return new DeserializerSystemImpl._(compiler, context, impactTransformer,
+        resolutionImpactDeserializer, resolvedAstDeserializer);
   }
 
   DeserializerSystemImpl._(
       this._compiler,
-      this._deserializer,
+      this.deserializationContext,
       this._impactTransformer,
       this._resolutionImpactDeserializer,
       this._resolvedAstDeserializer);
 
   @override
   Future<LibraryElement> readLibrary(Uri resolvedUri) {
-    LibraryElement library = _deserializer.lookupLibrary(resolvedUri);
+    LibraryElement library = deserializationContext.lookupLibrary(resolvedUri);
     if (library != null) {
       deserializedLibraries.add(library);
       return Future.forEach(library.compilationUnits,
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index f0cd00e..80d98d6 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -5,6 +5,7 @@
 library dart2js.serialization.task;
 
 import 'dart:async' show EventSink, Future;
+import '../common.dart';
 import '../common/resolution.dart' show ResolutionImpact, ResolutionWorkItem;
 import '../common/tasks.dart' show CompilerTask;
 import '../common/work.dart' show ItemCompilationContext;
@@ -26,7 +27,10 @@
 
 /// Task that supports deserialization of elements.
 class SerializationTask extends CompilerTask implements LibraryDeserializer {
-  SerializationTask(Compiler compiler) : super(compiler);
+  final Compiler compiler;
+  SerializationTask(Compiler compiler)
+      : compiler = compiler,
+        super(compiler.measurer);
 
   DeserializerSystem deserializer;
 
@@ -83,7 +87,8 @@
     return measure(() {
       assert(supportSerialization);
 
-      Serializer serializer = new Serializer();
+      Serializer serializer =
+          new Serializer(shouldInclude: (e) => libraries.contains(e.library));
       SerializerPlugin backendSerializer =
           compiler.backend.serialization.serializer;
       serializer.plugins.add(backendSerializer);
@@ -109,15 +114,17 @@
     });
   }
 
-  void deserializeFromText(String serializedData) {
+  void deserializeFromText(Uri sourceUri, String serializedData) {
     measure(() {
+      if (deserializer == null) {
+        deserializer = new DeserializerSystemImpl(
+            compiler, compiler.backend.impactTransformer);
+      }
+      DeserializerSystemImpl deserializerImpl = deserializer;
+      DeserializationContext context = deserializerImpl.deserializationContext;
       Deserializer dataDeserializer = new Deserializer.fromText(
-          new DeserializationContext(),
-          serializedData,
-          const JsonSerializationDecoder());
-      dataDeserializer.plugins.add(compiler.backend.serialization.deserializer);
-      deserializer = new DeserializerSystemImpl(
-          compiler, dataDeserializer, compiler.backend.impactTransformer);
+          context, sourceUri, serializedData, const JsonSerializationDecoder());
+      context.deserializers.add(dataDeserializer);
     });
   }
 }
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index f8c3ad0..7607077 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -91,13 +91,15 @@
   final CodeEmitterTask emitter;
   final JavaScriptBackend backend;
   final SourceInformationStrategy sourceInformationFactory;
+  final Compiler compiler;
 
   String get name => 'SSA builder';
 
   SsaBuilderTask(JavaScriptBackend backend, this.sourceInformationFactory)
       : emitter = backend.emitter,
         backend = backend,
-        super(backend.compiler);
+        compiler = backend.compiler,
+        super(backend.compiler.measurer);
 
   DiagnosticReporter get reporter => compiler.reporter;
 
@@ -2578,13 +2580,17 @@
             "${localsHandler.contextClass}.");
   }
 
-  /// Build a [HTypeConversion] for convertion [original] to type [type].
+  /// Build a [HTypeConversion] for converting [original] to type [type].
   ///
   /// Invariant: [type] must be valid in the context.
   /// See [LocalsHandler.substInContext].
   HInstruction buildTypeConversion(
       HInstruction original, DartType type, int kind) {
     if (type == null) return original;
+    // GENERIC_METHODS: The following statement was added for parsing and
+    // ignoring method type variables; must be generalized for full support of
+    // generic methods.
+    type = type.dynamifyMethodTypeVariableType;
     type = type.unaliased;
     assert(assertTypeInContext(type, original));
     if (type.isInterfaceType && !type.treatAsRaw) {
@@ -3805,8 +3811,15 @@
   void visitAs(ast.Send node, ast.Node expression, DartType type, _) {
     HInstruction expressionInstruction = visitAndPop(expression);
     if (type.isMalformed) {
-      ErroneousElement element = type.element;
-      generateTypeError(node, element.message);
+      String message;
+      if (type is MalformedType) {
+        ErroneousElement element = type.element;
+        message = element.message;
+      } else {
+        assert(type is MethodTypeVariableType);
+        message = "Method type variables are not reified.";
+      }
+      generateTypeError(node, message);
     } else {
       HInstruction converted = buildTypeConversion(expressionInstruction,
           localsHandler.substInContext(type), HTypeConversion.CAST_TYPE_CHECK);
@@ -3832,7 +3845,20 @@
   HInstruction buildIsNode(
       ast.Node node, DartType type, HInstruction expression) {
     type = localsHandler.substInContext(type).unaliased;
-    if (type.isFunctionType) {
+    if (type.isMalformed) {
+      String message;
+      if (type is MethodTypeVariableType) {
+        message = "Method type variables are not reified, "
+            "so they cannot be tested with an `is` expression.";
+      } else {
+        assert(type is MalformedType);
+        ErroneousElement element = type.element;
+        message = element.message;
+      }
+      generateTypeError(node, message);
+      HInstruction call = pop();
+      return new HIs.compound(type, expression, call, backend.boolType);
+    } else if (type.isFunctionType) {
       List arguments = [buildFunctionType(type), expression];
       pushInvokeDynamic(
           node,
@@ -3867,11 +3893,6 @@
       pushInvokeStatic(node, helper, inputs, typeMask: backend.boolType);
       HInstruction call = pop();
       return new HIs.compound(type, expression, call, backend.boolType);
-    } else if (type.isMalformed) {
-      ErroneousElement element = type.element;
-      generateTypeError(node, element.message);
-      HInstruction call = pop();
-      return new HIs.compound(type, expression, call, backend.boolType);
     } else {
       if (backend.hasDirectCheckFor(type)) {
         return new HIs.direct(type, expression, backend.boolType);
@@ -5337,12 +5358,19 @@
   /// Generate the literal for [typeVariable] in the current context.
   void generateTypeVariableLiteral(
       ast.Send node, TypeVariableType typeVariable) {
-    DartType type = localsHandler.substInContext(typeVariable);
-    HInstruction value = analyzeTypeArgument(type,
-        sourceInformation: sourceInformationBuilder.buildGet(node));
-    pushInvokeStatic(node, helpers.runtimeTypeToString, [value],
-        typeMask: backend.stringType);
-    pushInvokeStatic(node, helpers.createRuntimeType, [pop()]);
+    // GENERIC_METHODS: This provides thin support for method type variables
+    // by treating them as malformed when evaluated as a literal. For full
+    // support of generic methods this must be revised.
+    if (typeVariable is MethodTypeVariableType) {
+      generateTypeError(node, "Method type variables are not reified");
+    } else {
+      DartType type = localsHandler.substInContext(typeVariable);
+      HInstruction value = analyzeTypeArgument(type,
+          sourceInformation: sourceInformationBuilder.buildGet(node));
+      pushInvokeStatic(node, helpers.runtimeTypeToString, [value],
+          typeMask: backend.stringType);
+      pushInvokeStatic(node, helpers.createRuntimeType, [pop()]);
+    }
   }
 
   /// Generate a call to a type literal.
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index 74cd875..0ff32f2 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -29,11 +29,13 @@
 
 class SsaCodeGeneratorTask extends CompilerTask {
   final JavaScriptBackend backend;
+  final Compiler compiler;
   final SourceInformationStrategy sourceInformationFactory;
 
   SsaCodeGeneratorTask(JavaScriptBackend backend, this.sourceInformationFactory)
       : this.backend = backend,
-        super(backend.compiler);
+        this.compiler = backend.compiler,
+        super(backend.compiler.measurer);
 
   String get name => 'SSA code generator';
   NativeEmitter get nativeEmitter => backend.emitter.nativeEmitter;
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index a4ee039..20aaf32 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -36,7 +36,7 @@
   final JavaScriptBackend backend;
   SsaOptimizerTask(JavaScriptBackend backend)
       : this.backend = backend,
-        super(backend.compiler);
+        super(backend.compiler.measurer);
   String get name => 'SSA optimizer';
   Compiler get compiler => backend.compiler;
   Map<HInstruction, Range> ranges = <HInstruction, Range>{};
@@ -780,6 +780,8 @@
     return inputType.isInMask(checkedType, classWorld) ? input : node;
   }
 
+  HInstruction removeCheck(HCheck node) => node.checkedInput;
+
   VariableElement findConcreteFieldForDynamicAccess(
       HInstruction receiver, Selector selector) {
     TypeMask receiverType = receiver.instructionType;
diff --git a/pkg/compiler/lib/src/typechecker.dart b/pkg/compiler/lib/src/typechecker.dart
index 5de81a6..750357e 100644
--- a/pkg/compiler/lib/src/typechecker.dart
+++ b/pkg/compiler/lib/src/typechecker.dart
@@ -46,8 +46,13 @@
 import 'util/util.dart' show Link, LinkBuilder;
 
 class TypeCheckerTask extends CompilerTask {
-  TypeCheckerTask(Compiler compiler) : super(compiler);
+  final Compiler compiler;
+  TypeCheckerTask(Compiler compiler)
+      : compiler = compiler,
+        super(compiler.measurer);
+
   String get name => "Type checker";
+  DiagnosticReporter get reporter => compiler.reporter;
 
   void check(AstElement element) {
     if (element.isClass) return;
@@ -716,7 +721,7 @@
     // Lookup the class or interface member [name] in [interface].
     MemberSignature lookupMemberSignature(Name name, InterfaceType interface) {
       MembersCreator.computeClassMembersByName(
-          compiler, interface.element, name.text);
+          resolution, interface.element, name.text);
       return lookupClassMember || analyzingInitializer
           ? interface.lookupClassMember(name)
           : interface.lookupInterfaceMember(name);
@@ -799,7 +804,7 @@
           }
         }
         // TODO(johnniwinther): Avoid computation of all class members.
-        MembersCreator.computeAllClassMembers(compiler, interface.element);
+        MembersCreator.computeAllClassMembers(resolution, interface.element);
         if (lookupClassMember) {
           interface.element.forEachClassMember(findPrivateMember);
         } else {
diff --git a/pkg/compiler/lib/src/types/types.dart b/pkg/compiler/lib/src/types/types.dart
index fcaf762..61dbabf 100644
--- a/pkg/compiler/lib/src/types/types.dart
+++ b/pkg/compiler/lib/src/types/types.dart
@@ -52,11 +52,13 @@
 class TypesTask extends CompilerTask {
   final String name = 'Type inference';
   final ClassWorld classWorld;
+  final Compiler compiler;
   TypesInferrer typesInferrer;
 
   TypesTask(Compiler compiler)
       : this.classWorld = compiler.world,
-        super(compiler) {
+        compiler = compiler,
+        super(compiler.measurer) {
     typesInferrer = new TypeGraphInferrer(compiler);
   }
 
@@ -102,7 +104,7 @@
   TypeMask get intType {
     if (intTypeCache == null) {
       intTypeCache = new TypeMask.nonNullSubclass(
-          compiler.backend.intImplementation, compiler.world);
+          compiler.backend.intImplementation, classWorld);
     }
     return intTypeCache;
   }
@@ -110,7 +112,7 @@
   TypeMask get uint32Type {
     if (uint32TypeCache == null) {
       uint32TypeCache = new TypeMask.nonNullSubclass(
-          compiler.backend.uint32Implementation, compiler.world);
+          compiler.backend.uint32Implementation, classWorld);
     }
     return uint32TypeCache;
   }
@@ -118,7 +120,7 @@
   TypeMask get uint31Type {
     if (uint31TypeCache == null) {
       uint31TypeCache = new TypeMask.nonNullExact(
-          compiler.backend.uint31Implementation, compiler.world);
+          compiler.backend.uint31Implementation, classWorld);
     }
     return uint31TypeCache;
   }
@@ -126,7 +128,7 @@
   TypeMask get positiveIntType {
     if (positiveIntTypeCache == null) {
       positiveIntTypeCache = new TypeMask.nonNullSubclass(
-          compiler.backend.positiveIntImplementation, compiler.world);
+          compiler.backend.positiveIntImplementation, classWorld);
     }
     return positiveIntTypeCache;
   }
@@ -134,7 +136,7 @@
   TypeMask get doubleType {
     if (doubleTypeCache == null) {
       doubleTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.doubleImplementation, compiler.world);
+          compiler.backend.doubleImplementation, classWorld);
     }
     return doubleTypeCache;
   }
@@ -142,7 +144,7 @@
   TypeMask get numType {
     if (numTypeCache == null) {
       numTypeCache = new TypeMask.nonNullSubclass(
-          compiler.backend.numImplementation, compiler.world);
+          compiler.backend.numImplementation, classWorld);
     }
     return numTypeCache;
   }
@@ -150,7 +152,7 @@
   TypeMask get boolType {
     if (boolTypeCache == null) {
       boolTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.boolImplementation, compiler.world);
+          compiler.backend.boolImplementation, classWorld);
     }
     return boolTypeCache;
   }
@@ -166,7 +168,7 @@
   TypeMask get listType {
     if (listTypeCache == null) {
       listTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.listImplementation, compiler.world);
+          compiler.backend.listImplementation, classWorld);
     }
     return listTypeCache;
   }
@@ -174,7 +176,7 @@
   TypeMask get constListType {
     if (constListTypeCache == null) {
       constListTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.constListImplementation, compiler.world);
+          compiler.backend.constListImplementation, classWorld);
     }
     return constListTypeCache;
   }
@@ -182,7 +184,7 @@
   TypeMask get fixedListType {
     if (fixedListTypeCache == null) {
       fixedListTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.fixedListImplementation, compiler.world);
+          compiler.backend.fixedListImplementation, classWorld);
     }
     return fixedListTypeCache;
   }
@@ -190,7 +192,7 @@
   TypeMask get growableListType {
     if (growableListTypeCache == null) {
       growableListTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.growableListImplementation, compiler.world);
+          compiler.backend.growableListImplementation, classWorld);
     }
     return growableListTypeCache;
   }
@@ -214,7 +216,7 @@
   TypeMask get stringType {
     if (stringTypeCache == null) {
       stringTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.stringImplementation, compiler.world);
+          compiler.backend.stringImplementation, classWorld);
     }
     return stringTypeCache;
   }
@@ -222,7 +224,7 @@
   TypeMask get typeType {
     if (typeTypeCache == null) {
       typeTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.typeImplementation, compiler.world);
+          compiler.backend.typeImplementation, classWorld);
     }
     return typeTypeCache;
   }
@@ -230,7 +232,7 @@
   TypeMask get syncStarIterableType {
     if (syncStarIterableTypeCache == null) {
       syncStarIterableTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.syncStarIterableImplementation, compiler.world);
+          compiler.backend.syncStarIterableImplementation, classWorld);
     }
     return syncStarIterableTypeCache;
   }
@@ -238,7 +240,7 @@
   TypeMask get asyncFutureType {
     if (asyncFutureTypeCache == null) {
       asyncFutureTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.asyncFutureImplementation, compiler.world);
+          compiler.backend.asyncFutureImplementation, classWorld);
     }
     return asyncFutureTypeCache;
   }
@@ -246,7 +248,7 @@
   TypeMask get asyncStarStreamType {
     if (asyncStarStreamTypeCache == null) {
       asyncStarStreamTypeCache = new TypeMask.nonNullExact(
-          compiler.backend.asyncStarStreamImplementation, compiler.world);
+          compiler.backend.asyncStarStreamImplementation, classWorld);
     }
     return asyncStarStreamTypeCache;
   }
diff --git a/pkg/compiler/samples/jsonify/jsonify.dart b/pkg/compiler/samples/jsonify/jsonify.dart
deleted file mode 100644
index a84cb04..0000000
--- a/pkg/compiler/samples/jsonify/jsonify.dart
+++ /dev/null
@@ -1,109 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'dart:mirrors';
-
-import 'package:sdk_library_metadata/libraries.dart' show libraries;
-
-import '../../lib/src/filenames.dart';
-import '../../lib/src/mirrors/analyze.dart' show analyze;
-import '../../lib/src/mirrors/dart2js_mirrors.dart' show BackDoor;
-import '../../lib/src/source_file_provider.dart';
-import '../../lib/src/util/uri_extras.dart';
-
-const DART2JS = '../../lib/src/dart2js.dart';
-const DART2JS_MIRROR = '../../lib/src/mirrors/dart2js_mirror.dart';
-const SDK_ROOT = '../../../../sdk/';
-
-bool isPublicDart2jsLibrary(String name) {
-  return !name.startsWith('_') && libraries[name].isDart2jsLibrary;
-}
-
-var handler;
-RandomAccessFile output;
-Uri outputUri;
-Uri sdkRoot;
-const bool outputJson =
-    const bool.fromEnvironment('outputJson', defaultValue: false);
-
-main(List<String> arguments) {
-  handler = new FormattingDiagnosticHandler()..throwOnError = true;
-
-  outputUri = handler.provider.cwd.resolve(nativeToUriPath(arguments.first));
-  output = new File(arguments.first).openSync(mode: FileMode.WRITE);
-
-  Uri myLocation = handler.provider.cwd.resolveUri(Platform.script);
-
-  Uri packageRoot = handler.provider.cwd.resolve(Platform.packageRoot);
-
-  Uri libraryRoot = myLocation.resolve(SDK_ROOT);
-
-  sdkRoot = libraryRoot.resolve('../');
-
-  // Get the names of public dart2js libraries.
-  Iterable<String> names = libraries.keys.where(isPublicDart2jsLibrary);
-
-  // Turn the names into uris by prepending dart: to them.
-  List<Uri> uris = names.map((String name) => Uri.parse('dart:$name')).toList();
-
-  analyze(uris, libraryRoot, packageRoot, handler.provider, handler)
-      .then(jsonify);
-}
-
-jsonify(MirrorSystem mirrors) {
-  var map = <String, String>{};
-  List<Future> futures = <Future>[];
-
-  Future mapUri(Uri uri) {
-    String filename = relativize(sdkRoot, uri, false);
-    return handler.provider.readStringFromUri(uri).then((contents) {
-      map['sdk:/$filename'] = contents;
-    });
-  }
-
-  mirrors.libraries.forEach((_, LibraryMirror library) {
-    BackDoor.compilationUnitsOf(library).forEach((compilationUnit) {
-      futures.add(mapUri(compilationUnit.uri));
-    });
-  });
-
-  libraries.forEach((name, info) {
-    var patch = info.dart2jsPatchPath;
-    if (patch != null) {
-      futures.add(mapUri(sdkRoot.resolve('sdk/lib/$patch')));
-    }
-  });
-
-  for (String filename in [
-    "dart_client.platform",
-    "dart_server.platform",
-    "dart_shared.platform"
-  ]) {
-    futures.add(mapUri(sdkRoot.resolve('sdk/lib/$filename')));
-  }
-
-  Future.wait(futures).then((_) {
-    if (outputJson) {
-      output.writeStringSync(JSON.encode(map));
-    } else {
-      output.writeStringSync('''
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// DO NOT EDIT.
-// This file is generated by jsonify.dart.
-
-library dart.sdk_sources;
-
-const Map<String, String> SDK_SOURCES = const <String, String>''');
-      output.writeStringSync(JSON.encode(map).replaceAll(r'$', r'\$'));
-      output.writeStringSync(';\n');
-    }
-    output.closeSync();
-  });
-}
diff --git a/pkg/dart2js_incremental/lib/caching_compiler.dart b/pkg/dart2js_incremental/lib/caching_compiler.dart
index f7f8f10..7401ba4 100644
--- a/pkg/dart2js_incremental/lib/caching_compiler.dart
+++ b/pkg/dart2js_incremental/lib/caching_compiler.dart
@@ -87,11 +87,7 @@
       });
     });
   } else {
-    for (final task in compiler.tasks) {
-      if (task.watch != null) {
-        task.watch.reset();
-      }
-    }
+    compiler.tasks.forEach((t) => t.clearMeasurements());
     compiler
         ..userOutputProvider = outputProvider
         ..provider = inputProvider
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index f0c0cdc..6b16d99 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -702,13 +702,7 @@
     _log('Resolving: $userString from $base');
   }
   var baseUri = Uri.parse(base);
-  var result;
-  if (userString.startsWith(_DART_EXT)) {
-    var uri = userString.substring(_DART_EXT.length);
-    result = '$_DART_EXT${baseUri.resolve(uri)}';
-  } else {
-    result = baseUri.resolve(userString).toString();
-  }
+  var result = baseUri.resolve(userString).toString();
   if (_traceLoading) {
     _log('Resolved $userString in $base to $result');
   }
@@ -831,10 +825,6 @@
 }
 
 
-// Handling of dart-ext loading.
-// Dart native extension scheme.
-const _DART_EXT = 'dart-ext:';
-
 // Returns either a file path or a URI starting with http[s]:, as a String.
 String _filePathFromUri(String userUri) {
   var uri = Uri.parse(userUri);
@@ -864,42 +854,19 @@
 }
 
 
-// Embedder Entrypoint:
-// When loading an extension the embedder calls this method to get the
-// different components.
-// Returns the directory part, the filename part, and the name
-// of a native extension URL as a list [directory, filename, name].
-// The directory part is either a file system path or an HTTP(S) URL.
-// The filename part is the extension name, with the platform-dependent
-// prefixes and extensions added.
-_extensionPathFromUri(String userUri) {
+// Embedder Entrypoint.
+_libraryFilePath(String libraryUri) {
   if (!_setupCompleted) {
     _setupHooks();
   }
-  if (!userUri.startsWith(_DART_EXT)) {
-    throw 'Unexpected internal error: Extension URI $userUri missing dart-ext:';
-  }
-  userUri = userUri.substring(_DART_EXT.length);
-
-  if (userUri.contains('\\')) {
-    throw 'Unexpected internal error: Extension URI $userUri contains \\';
-  }
-
-  String name;
-  String path;  // Will end in '/'.
-  int index = userUri.lastIndexOf('/');
+  int index = libraryUri.lastIndexOf('/');
+  var path;
   if (index == -1) {
-    name = userUri;
     path = './';
-  } else if (index == userUri.length - 1) {
-    throw 'Extension name missing in $extensionUri';
   } else {
-    name = userUri.substring(index + 1);
-    path = userUri.substring(0, index + 1);
+    path = libraryUri.substring(0, index + 1);
   }
-  path = _filePathFromUri(path);
-
-  return [path, name];
+  return _filePathFromUri(path);
 }
 
 
diff --git a/runtime/bin/dart_io_entries.txt b/runtime/bin/dart_io_entries.txt
new file mode 100644
index 0000000..4cfcd70
--- /dev/null
+++ b/runtime/bin/dart_io_entries.txt
@@ -0,0 +1,19 @@
+dart:io,::,_makeUint8ListView
+dart:io,::,_makeDatagram
+dart:io,::,_setupHooks
+dart:io,::,_getWatchSignalInternal
+dart:io,CertificateException,CertificateException.
+dart:io,Directory,Directory.
+dart:io,File,File.
+dart:io,FileSystemException,FileSystemException.
+dart:io,HandshakeException,HandshakeException.
+dart:io,Link,Link.
+dart:io,OSError,OSError.
+dart:io,TlsException,TlsException.
+dart:io,X509Certificate,X509Certificate._
+dart:io,_ExternalBuffer,set:data
+dart:io,_Platform,set:_nativeScript
+dart:io,_ProcessStartStatus,set:_errorCode
+dart:io,_ProcessStartStatus,set:_errorMessage
+dart:io,_SecureFilterImpl,get:ENCRYPTED_SIZE
+dart:io,_SecureFilterImpl,get:SIZE
diff --git a/runtime/bin/dart_product_entries.txt b/runtime/bin/dart_product_entries.txt
index d8825d2..fcfda57 100644
--- a/runtime/bin/dart_product_entries.txt
+++ b/runtime/bin/dart_product_entries.txt
@@ -6,22 +6,3 @@
 dart:_builtin,::,_setPackageRoot
 dart:_builtin,::,_loadPackagesMap
 dart:_builtin,::,_loadDataAsync
-dart:io,::,_makeUint8ListView
-dart:io,::,_makeDatagram
-dart:io,::,_setupHooks
-dart:io,::,_getWatchSignalInternal
-dart:io,CertificateException,CertificateException.
-dart:io,Directory,Directory.
-dart:io,File,File.
-dart:io,FileSystemException,FileSystemException.
-dart:io,HandshakeException,HandshakeException.
-dart:io,Link,Link.
-dart:io,OSError,OSError.
-dart:io,TlsException,TlsException.
-dart:io,X509Certificate,X509Certificate._
-dart:io,_ExternalBuffer,set:data
-dart:io,_Platform,set:_nativeScript
-dart:io,_ProcessStartStatus,set:_errorCode
-dart:io,_ProcessStartStatus,set:_errorMessage
-dart:io,_SecureFilterImpl,get:ENCRYPTED_SIZE
-dart:io,_SecureFilterImpl,get:SIZE
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index 02f6016..b7f418b 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -180,6 +180,16 @@
 }
 
 
+const char* DartUtils::RemoveScheme(const char* url) {
+  const char* colon = strchr(url, ':');
+  if (colon == NULL) {
+    return url;
+  } else {
+    return colon + 1;
+  }
+}
+
+
 void* DartUtils::MapExecutable(const char* name, intptr_t* len) {
   File* file = File::Open(name, File::kRead);
   if (file == NULL) {
@@ -346,12 +356,12 @@
 }
 
 
-Dart_Handle DartUtils::ExtensionPathFromUri(Dart_Handle extension_uri) {
+Dart_Handle DartUtils::LibraryFilePath(Dart_Handle library_uri) {
   const int kNumArgs = 1;
   Dart_Handle dart_args[kNumArgs];
-  dart_args[0] = extension_uri;
+  dart_args[0] = library_uri;
   return Dart_Invoke(DartUtils::BuiltinLib(),
-                     NewString("_extensionPathFromUri"),
+                     NewString("_libraryFilePath"),
                      kNumArgs,
                      dart_args);
 }
@@ -452,25 +462,18 @@
     if (tag != Dart_kImportTag) {
       return NewError("Dart extensions must use import: '%s'", url_string);
     }
-    Dart_Handle path_parts = DartUtils::ExtensionPathFromUri(url);
-    if (Dart_IsError(path_parts)) {
-      return path_parts;
+    Dart_Handle library_file_path = DartUtils::LibraryFilePath(library_url);
+    const char* lib_path_str = NULL;
+    Dart_StringToCString(library_file_path, &lib_path_str);
+    const char* extension_path = DartUtils::RemoveScheme(url_string);
+    if (strchr(extension_path, '/') != NULL ||
+        (IsWindowsHost() && strchr(extension_path, '\\') != NULL)) {
+      return NewError(
+          "Relative paths for dart extensions are not supported: '%s'",
+          extension_path);
     }
-#if defined(DEBUG)
-    intptr_t path_parts_length;
-    result = Dart_ListLength(path_parts, &path_parts_length);
-    if (Dart_IsError(result)) {
-      return result;
-    }
-    ASSERT(path_parts_length == 2);
-#endif
-    const char* extension_directory = NULL;
-    Dart_StringToCString(Dart_ListGetAt(path_parts, 0), &extension_directory);
-    const char* extension_name = NULL;
-    Dart_StringToCString(Dart_ListGetAt(path_parts, 1), &extension_name);
-
-    return Extensions::LoadExtension(extension_directory,
-                                     extension_name,
+    return Extensions::LoadExtension(lib_path_str,
+                                     extension_path,
                                      library);
   }
 
diff --git a/runtime/bin/dartutils.h b/runtime/bin/dartutils.h
index ed63c7c..b416a93 100644
--- a/runtime/bin/dartutils.h
+++ b/runtime/bin/dartutils.h
@@ -115,6 +115,7 @@
   static bool IsDartIOLibURL(const char* url_name);
   static bool IsDartBuiltinLibURL(const char* url_name);
   static bool IsHttpSchemeURL(const char* url_name);
+  static const char* RemoveScheme(const char* url);
   static void* MapExecutable(const char* name, intptr_t* file_len);
   static void* OpenFile(const char* name, bool write);
   static void ReadFile(const uint8_t** data, intptr_t* file_len, void* stream);
@@ -232,8 +233,7 @@
 
  private:
   static Dart_Handle SetWorkingDirectory();
-  static Dart_Handle ExtensionPathFromUri(Dart_Handle extension_uri);
-
+  static Dart_Handle LibraryFilePath(Dart_Handle library_uri);
   static Dart_Handle PrepareBuiltinLibrary(Dart_Handle builtin_lib,
                                            Dart_Handle internal_lib,
                                            bool is_service_isolate,
diff --git a/runtime/lib/array_patch.dart b/runtime/lib/array_patch.dart
index c0ddfee..94f29f1 100644
--- a/runtime/lib/array_patch.dart
+++ b/runtime/lib/array_patch.dart
@@ -36,8 +36,10 @@
     if (elements is EfficientLength) {
       int length = elements.length;
       var list = growable ? new _GrowableList<E>(length) : new _List<E>(length);
-      int i = 0;
-      for (var element in elements) { list[i++] = element; }
+      if (length > 0) {  // Avoid creating iterator unless necessary.
+        int i = 0;
+        for (var element in elements) { list[i++] = element; }
+      }
       return list;
     }
     List<E> list = new _GrowableList<E>(0);
@@ -47,7 +49,7 @@
     if (growable) return list;
     if (list.length == 0) {
       // Avoid getting an immutable list from makeListFixedLength.
-      return new List<E>(0);
+      return new _List<E>(0);
     }
     return makeListFixedLength(list);
   }
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index c4b532f..ad0d89a 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -735,6 +735,14 @@
   }
 
   Iterator<int> get iterator => new _TypedListIterator<int>(this);
+
+  List<int> toList({bool growable: true}) {
+    return new List<int>.from(this, growable: growable);
+  }
+
+  Set<int> toSet() {
+    return new Set<int>.from(this);
+  }
 }
 
 
@@ -762,6 +770,14 @@
   }
 
   Iterator<double> get iterator => new _TypedListIterator<double>(this);
+
+  List<double> toList({bool growable: true}) {
+    return new List<double>.from(this, growable: growable);
+  }
+
+  Set<double> toSet() {
+    return new Set<double>.from(this);
+  }
 }
 
 
@@ -790,6 +806,14 @@
   }
 
   Iterator<Float32x4> get iterator => new _TypedListIterator<Float32x4>(this);
+
+  List<Float32x4> toList({bool growable: true}) {
+    return new List<Float32x4>.from(this, growable: growable);
+  }
+
+  Set<Float32x4> toSet() {
+    return new Set<Float32x4>.from(this);
+  }
 }
 
 
@@ -817,6 +841,14 @@
   }
 
   Iterator<Int32x4> get iterator => new _TypedListIterator<Int32x4>(this);
+
+  List<Int32x4> toList({bool growable: true}) {
+    return new List<Int32x4>.from(this, growable: growable);
+  }
+
+  Set<Int32x4> toSet() {
+    return new Set<Int32x4>.from(this);
+  }
 }
 
 
@@ -845,6 +877,14 @@
   }
 
   Iterator<Float64x2> get iterator => new _TypedListIterator<Float64x2>(this);
+
+  List<Float64x2> toList({bool growable: true}) {
+    return new List<Float64x2>.from(this, growable: growable);
+  }
+
+  Set<Float64x2> toSet() {
+    return new Set<Float64x2>.from(this);
+  }
 }
 
 
@@ -1146,7 +1186,6 @@
     return Uint8List.BYTES_PER_ELEMENT;
   }
 
-
   // Internal utility methods.
 
   Uint8List _createList(int length) {
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index a3a2510..9c9baec 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -14,8 +14,8 @@
     'lib/object_graph.dart',
     'lib/service.dart',
     'lib/service_common.dart',
-    'lib/service_io.dart',
     'lib/service_html.dart',
+    'lib/service_io.dart',
     'lib/src/app/analytics.dart',
     'lib/src/app/application.dart',
     'lib/src/app/location_manager.dart',
@@ -45,6 +45,7 @@
     'lib/src/elements/context_view.html',
     'lib/src/elements/cpu_profile.dart',
     'lib/src/elements/cpu_profile.html',
+    'lib/src/elements/css/shared.css',
     'lib/src/elements/curly_block.dart',
     'lib/src/elements/curly_block.html',
     'lib/src/elements/debugger.dart',
@@ -77,6 +78,9 @@
     'lib/src/elements/heap_snapshot.html',
     'lib/src/elements/icdata_view.dart',
     'lib/src/elements/icdata_view.html',
+    'lib/src/elements/img/chromium_icon.png',
+    'lib/src/elements/img/dart_icon.png',
+    'lib/src/elements/img/isolate_icon.png',
     'lib/src/elements/inbound_reference.dart',
     'lib/src/elements/inbound_reference.html',
     'lib/src/elements/instance_ref.dart',
@@ -145,18 +149,15 @@
     'lib/src/elements/vm_ref.html',
     'lib/src/elements/vm_view.dart',
     'lib/src/elements/vm_view.html',
-    'lib/src/elements/css/shared.css',
-    'lib/src/elements/img/chromium_icon.png',
-    'lib/src/elements/img/dart_icon.png',
-    'lib/src/elements/img/isolate_icon.png',
     'lib/src/service/object.dart',
     'lib/tracer.dart',
     'lib/utils.dart',
+    'web/favicon.ico',
     'web/index.html',
     'web/main.dart',
-    'web/favicon.ico',
     'web/third_party/trace_viewer_full.html',
-    'web/timeline.js',
     'web/timeline.html',
+    'web/timeline.js',
+    'web/timeline_message_handler.js',
   ],
 }
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index bb742ac..3ec12e9 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -2,6 +2,12 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
+# Flaky failures
+vm_timeline_flags_test: Pass, RuntimeError # Issue 26483
+gc_test: Pass, RuntimeError # Issue 26490
+pause_on_start_and_exit_test: Pass, RuntimeError # Issue 26470
+pause_on_start_then_step_test: Pass, RuntimeError # Issue 26470
+
 [ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
 evaluate_activation_test/instance: RuntimeError # http://dartbug.com/20047
 evaluate_activation_test/scope: RuntimeError # http://dartbug.com/20047
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 0fa725f..8c08954 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -26,8 +26,8 @@
 cc/CorelibIsolateStartup: Skip
 # Negative tests of VerifiedMemory should crash iff in DEBUG mode.
 # TODO(koda): Improve support for negative tests.
-cc/VerifyImplicit_Crash: Crash, Timeout  # Timeout: Issue #24596
-cc/VerifyExplicit_Crash: Crash, Timeout  # Timeout: Issue #24596
+cc/VerifyImplicit_Crash: Crash
+cc/VerifyExplicit_Crash: Crash
 # It can take some time for all the isolates to shutdown in a Debug build.
 dart/spawn_shutdown_test: Pass, Slow  # VM Shutdown test
 
@@ -190,3 +190,29 @@
 cc/Debug_InspectStack_Optimized: Skip
 cc/Debug_InspectStackWithClosure_Optimized: Skip
 
+# Isolate reload code assumes that all static calls have ICData attached to
+# them. However this is not the case on DBC.
+cc/IsolateReload_LiveStack: Skip
+cc/IsolateReload_StaticValuePreserved: Skip
+cc/IsolateReload_TopLevelFieldAdded: Skip
+cc/IsolateReload_ConstructorChanged: Skip
+cc/IsolateReload_ImplicitConstructorChanged: Skip
+cc/IsolateReload_MixinChanged: Skip
+cc/IsolateReload_SuperClassChanged: Skip
+cc/IsolateReload_ComplexInheritanceChange: Skip
+cc/IsolateReload_LibraryImportAdded: Skip
+cc/IsolateReload_LibraryHide: Skip
+cc/IsolateReload_LibraryLookup: Skip
+cc/IsolateReload_LibraryShow: Skip
+cc/IsolateReload_LiveStack: Skip
+cc/IsolateReload_StaticValuePreserved: Skip
+cc/IsolateReload_TopLevelFieldAdded: Skip
+cc/IsolateReload_ConstructorChanged: Skip
+cc/IsolateReload_ImplicitConstructorChanged: Skip
+cc/IsolateReload_MixinChanged: Skip
+cc/IsolateReload_SuperClassChanged: Skip
+cc/IsolateReload_ComplexInheritanceChange: Skip
+cc/IsolateReload_LibraryImportAdded: Skip
+cc/IsolateReload_LibraryHide: Skip
+cc/IsolateReload_LibraryLookup: Skip
+cc/IsolateReload_LibraryShow: Skip
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index e81ddfc..8b66e49 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -2060,15 +2060,13 @@
 
   // Private classes cannot be subclassed by later loaded libs.
   if (!type_class.IsPrivate()) {
-    if (FLAG_use_cha_deopt || isolate()->all_classes_finalized()) {
+    if (isolate()->all_classes_finalized()) {
       if (FLAG_trace_cha) {
         THR_Print("  **(CHA) Typecheck as class equality since no "
             "subclasses: %s\n",
             type_class.ToCString());
       }
-      if (FLAG_use_cha_deopt) {
-        thread()->cha()->AddToLeafClasses(type_class);
-      }
+      ASSERT(!FLAG_use_cha_deopt);
     } else {
       return false;
     }
@@ -2456,8 +2454,10 @@
             instr->function_name(),
             args_desc));
     if (!function.IsNull()) {
+      intptr_t subclasses = 0;
       if (!thread()->cha()->HasOverride(receiver_class,
-                                        instr->function_name())) {
+                                        instr->function_name(),
+                                        &subclasses)) {
         if (FLAG_trace_cha) {
           THR_Print("  **(CHA) Instance call needs no check, "
               "no overrides of '%s' '%s'\n",
diff --git a/runtime/vm/cha.cc b/runtime/vm/cha.cc
index 57214bb..6a0a16d 100644
--- a/runtime/vm/cha.cc
+++ b/runtime/vm/cha.cc
@@ -12,13 +12,26 @@
 
 namespace dart {
 
-void CHA::AddToLeafClasses(const Class& cls) {
-  for (intptr_t i = 0; i < leaf_classes_.length(); i++) {
-    if (leaf_classes_[i]->raw() == cls.raw()) {
+void CHA::AddToGuardedClasses(const Class& cls, intptr_t subclass_count) {
+  for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
+    if (guarded_classes_[i].cls->raw() == cls.raw()) {
       return;
     }
   }
-  leaf_classes_.Add(&Class::ZoneHandle(thread_->zone(), cls.raw()));
+  GuardedClassInfo info = {
+    &Class::ZoneHandle(thread_->zone(), cls.raw()),
+    subclass_count
+  };
+  guarded_classes_.Add(info);
+  return;
+}
+
+
+bool CHA::IsGuardedClass(intptr_t cid) const {
+  for (intptr_t i = 0; i < guarded_classes_.length(); ++i) {
+    if (guarded_classes_[i].cls->id() == cid) return true;
+  }
+  return false;
 }
 
 
@@ -86,7 +99,41 @@
 }
 
 
-bool CHA::HasOverride(const Class& cls, const String& function_name) {
+static intptr_t CountFinalizedSubclasses(Thread* thread, const Class& cls) {
+  intptr_t count = 0;
+  const GrowableObjectArray& cls_direct_subclasses =
+      GrowableObjectArray::Handle(thread->zone(), cls.direct_subclasses());
+  if (cls_direct_subclasses.IsNull()) return count;
+  Class& direct_subclass = Class::Handle(thread->zone());
+  for (intptr_t i = 0; i < cls_direct_subclasses.Length(); i++) {
+    direct_subclass ^= cls_direct_subclasses.At(i);
+    // Unfinalized classes are treated as non-existent for CHA purposes,
+    // as that means that no instance of that class exists at runtime.
+    if (!direct_subclass.is_finalized()) {
+      continue;
+    }
+
+    count += 1 + CountFinalizedSubclasses(thread, direct_subclass);
+  }
+  return count;
+}
+
+
+bool CHA::IsConsistentWithCurrentHierarchy() const {
+  for (intptr_t i = 0; i < guarded_classes_.length(); i++) {
+    const intptr_t subclass_count =
+        CountFinalizedSubclasses(thread_, *guarded_classes_[i].cls);
+    if (guarded_classes_[i].subclass_count != subclass_count) {
+      return false;
+    }
+  }
+  return true;
+}
+
+
+bool CHA::HasOverride(const Class& cls,
+                      const String& function_name,
+                      intptr_t* subclasses_count) {
   // Can't track dependencies for classes on the VM heap since those are
   // read-only.
   // TODO(fschneider): Enable tracking of CHA dependent code for VM heap
@@ -109,16 +156,31 @@
     direct_subclass ^= cls_direct_subclasses.At(i);
     // Unfinalized classes are treated as non-existent for CHA purposes,
     // as that means that no instance of that class exists at runtime.
-    if (direct_subclass.is_finalized() &&
-        (direct_subclass.LookupDynamicFunction(function_name) !=
-         Function::null())) {
+    if (!direct_subclass.is_finalized()) {
+      continue;
+    }
+
+    if (direct_subclass.LookupDynamicFunction(function_name) !=
+            Function::null()) {
       return true;
     }
-    if (HasOverride(direct_subclass, function_name)) {
+
+    if (HasOverride(direct_subclass, function_name, subclasses_count)) {
       return true;
     }
+
+    (*subclasses_count)++;
   }
+
   return false;
 }
 
+
+void CHA::RegisterDependencies(const Code& code) const {
+  for (intptr_t i = 0; i < guarded_classes_.length(); ++i) {
+    guarded_classes_[i].cls->RegisterCHACode(code);
+  }
+}
+
+
 }  // namespace dart
diff --git a/runtime/vm/cha.h b/runtime/vm/cha.h
index a1ea229..7aa7774 100644
--- a/runtime/vm/cha.h
+++ b/runtime/vm/cha.h
@@ -21,7 +21,7 @@
   explicit CHA(Thread* thread)
       : StackResource(thread),
         thread_(thread),
-        leaf_classes_(thread->zone(), 1),
+        guarded_classes_(thread->zone(), 1),
         previous_(thread->cha()) {
     thread->set_cha(this);
   }
@@ -44,20 +44,42 @@
   static bool IsImplemented(const Class& cls);
 
   // Returns true if any subclass of 'cls' contains the function.
-  bool HasOverride(const Class& cls, const String& function_name);
+  // If no override was found subclass_count would contain total count of
+  // finalized subclasses that CHA looked at.
+  // This count will be used to validate CHA decision before installing
+  // optimized code compiled in background.
+  bool HasOverride(const Class& cls,
+                   const String& function_name,
+                   intptr_t* subclass_count);
 
-  const GrowableArray<Class*>& leaf_classes() const {
-    return leaf_classes_;
-  }
-
-  // Adds class 'cls' to the list of guarded leaf classes, deoptimization occurs
-  // if any of those leaf classes gets subclassed through later loaded/finalized
+  // Adds class 'cls' to the list of guarded classes, deoptimization occurs
+  // if any of those classes gets subclassed through later loaded/finalized
   // libraries. Only classes that were used for CHA optimizations are added.
-  void AddToLeafClasses(const Class& cls);
+  void AddToGuardedClasses(const Class& cls, intptr_t subclass_count);
+
+  // When compiling in background we need to check that no new finalized
+  // subclasses were added to guarded classes.
+  bool IsConsistentWithCurrentHierarchy() const;
+
+  void RegisterDependencies(const Code& code) const;
+
+  // Used for testing.
+  bool IsGuardedClass(intptr_t cid) const;
 
  private:
   Thread* thread_;
-  GrowableArray<Class*> leaf_classes_;
+
+  struct GuardedClassInfo {
+    Class* cls;
+
+    // Number of finalized subclasses that this class had at the moment
+    // when CHA made the first decision based on this class.
+    // Used to validate correctness of background compilation: if
+    // any subclasses were added we will discard compiled code.
+    intptr_t subclass_count;
+  };
+
+  GrowableArray<GuardedClassInfo> guarded_classes_;
   CHA* previous_;
 };
 
diff --git a/runtime/vm/cha_test.cc b/runtime/vm/cha_test.cc
index 7316da0..107c233 100644
--- a/runtime/vm/cha_test.cc
+++ b/runtime/vm/cha_test.cc
@@ -11,13 +11,6 @@
 
 namespace dart {
 
-static bool ContainsCid(const GrowableArray<Class*>& classes, intptr_t cid) {
-  for (intptr_t i = 0; i < classes.length(); ++i) {
-    if (classes[i]->id() == cid) return true;
-  }
-  return false;
-}
-
 
 TEST_CASE(ClassHierarchyAnalysis) {
   const char* kScriptChars =
@@ -89,14 +82,14 @@
   EXPECT(CHA::HasSubclasses(class_a));
   EXPECT(CHA::HasSubclasses(class_b));
   EXPECT(!CHA::HasSubclasses(class_c));
-  cha.AddToLeafClasses(class_c);
+  cha.AddToGuardedClasses(class_c, /*subclass_count=*/0);
   EXPECT(!CHA::HasSubclasses(class_d));
-  cha.AddToLeafClasses(class_d);
+  cha.AddToGuardedClasses(class_d, /*subclass_count=*/0);
 
-  EXPECT(!ContainsCid(cha.leaf_classes(), class_a.id()));
-  EXPECT(!ContainsCid(cha.leaf_classes(), class_b.id()));
-  EXPECT(ContainsCid(cha.leaf_classes(), class_c.id()));
-  EXPECT(ContainsCid(cha.leaf_classes(), class_d.id()));
+  EXPECT(!cha.IsGuardedClass(class_a.id()));
+  EXPECT(!cha.IsGuardedClass(class_b.id()));
+  EXPECT(cha.IsGuardedClass(class_c.id()));
+  EXPECT(cha.IsGuardedClass(class_d.id()));
 
   const Class& closure_class =
       Class::Handle(Isolate::Current()->object_store()->closure_class());
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 3a8cf41..5d4e3cb 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -1604,7 +1604,9 @@
   // Patch call site (lazy deoptimization is quite rare, patching it twice
   // is not a performance issue).
   uword lazy_deopt_jump = optimized_code.GetLazyDeoptPc();
+#if !defined(TARGET_ARCH_DBC)
   ASSERT(lazy_deopt_jump != 0);
+#endif
   const Instructions& instrs =
       Instructions::Handle(zone, optimized_code.instructions());
   {
@@ -1637,14 +1639,22 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
+#if !defined(TARGET_ARCH_DBC)
+static const intptr_t kNumberOfSavedCpuRegisters = kNumberOfCpuRegisters;
+static const intptr_t kNumberOfSavedFpuRegisters = kNumberOfFpuRegisters;
+#else
+static const intptr_t kNumberOfSavedCpuRegisters = 0;
+static const intptr_t kNumberOfSavedFpuRegisters = 0;
+#endif
+
 static void CopySavedRegisters(uword saved_registers_address,
                                fpu_register_t** fpu_registers,
                                intptr_t** cpu_registers) {
   ASSERT(sizeof(fpu_register_t) == kFpuRegisterSize);
   fpu_register_t* fpu_registers_copy =
-      new fpu_register_t[kNumberOfFpuRegisters];
+      new fpu_register_t[kNumberOfSavedFpuRegisters];
   ASSERT(fpu_registers_copy != NULL);
-  for (intptr_t i = 0; i < kNumberOfFpuRegisters; i++) {
+  for (intptr_t i = 0; i < kNumberOfSavedFpuRegisters; i++) {
     fpu_registers_copy[i] =
         *reinterpret_cast<fpu_register_t*>(saved_registers_address);
     saved_registers_address += kFpuRegisterSize;
@@ -1652,9 +1662,9 @@
   *fpu_registers = fpu_registers_copy;
 
   ASSERT(sizeof(intptr_t) == kWordSize);
-  intptr_t* cpu_registers_copy = new intptr_t[kNumberOfCpuRegisters];
+  intptr_t* cpu_registers_copy = new intptr_t[kNumberOfSavedCpuRegisters];
   ASSERT(cpu_registers_copy != NULL);
-  for (intptr_t i = 0; i < kNumberOfCpuRegisters; i++) {
+  for (intptr_t i = 0; i < kNumberOfSavedCpuRegisters; i++) {
     cpu_registers_copy[i] =
         *reinterpret_cast<intptr_t*>(saved_registers_address);
     saved_registers_address += kWordSize;
@@ -1681,12 +1691,13 @@
 
   // All registers have been saved below last-fp as if they were locals.
   const uword last_fp = saved_registers_address
-                        + (kNumberOfCpuRegisters * kWordSize)
-                        + (kNumberOfFpuRegisters * kFpuRegisterSize)
+                        + (kNumberOfSavedCpuRegisters * kWordSize)
+                        + (kNumberOfSavedFpuRegisters * kFpuRegisterSize)
                         - ((kFirstLocalSlotFromFp + 1) * kWordSize);
 
   // Get optimized code and frame that need to be deoptimized.
   DartFrameIterator iterator(last_fp);
+
   StackFrame* caller_frame = iterator.NextFrame();
   ASSERT(caller_frame != NULL);
   const Code& optimized_code = Code::Handle(caller_frame->LookupDartCode());
@@ -1760,11 +1771,7 @@
   }
 #endif
 
-  // TODO(turnidge): Compute the start of the dest frame in the
-  // DeoptContext instead of passing it in here.
-  intptr_t* start = reinterpret_cast<intptr_t*>(
-      caller_frame->sp() - (kDartFrameFixedSize * kWordSize));
-  deopt_context->set_dest_frame(start);
+  deopt_context->set_dest_frame(caller_frame);
   deopt_context->FillDestFrame();
 #else
   UNREACHABLE();
diff --git a/runtime/vm/code_patcher_dbc.cc b/runtime/vm/code_patcher_dbc.cc
index e0010ab..6a273ac 100644
--- a/runtime/vm/code_patcher_dbc.cc
+++ b/runtime/vm/code_patcher_dbc.cc
@@ -31,8 +31,7 @@
 
 
 void CodePatcher::InsertDeoptimizationCallAt(uword start, uword target) {
-  // The inserted call should not overlap the lazy deopt jump code.
-  ASSERT(start + CallPattern::DeoptCallPatternLengthInBytes() <= target);
+  ASSERT(target == 0);  // Always 0 on DBC.
   CallPattern::InsertDeoptCallAt(start, target);
 }
 
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 7685b3c..a15dca3 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -448,12 +448,8 @@
         optimized_(optimized),
         osr_id_(osr_id),
         thread_(Thread::Current()),
-        field_invalidation_gen_at_start_(isolate()->field_invalidation_gen()),
         loading_invalidation_gen_at_start_(
             isolate()->loading_invalidation_gen()) {
-    if (Compiler::IsBackgroundCompilation()) {
-      isolate()->ClearDisablingFieldList();
-    }
   }
 
   bool Compile(CompilationPipeline* pipeline);
@@ -464,9 +460,6 @@
   intptr_t osr_id() const { return osr_id_; }
   Thread* thread() const { return thread_; }
   Isolate* isolate() const { return thread_->isolate(); }
-  intptr_t field_invalidation_gen_at_start() const {
-    return field_invalidation_gen_at_start_;
-  }
   intptr_t loading_invalidation_gen_at_start() const {
     return loading_invalidation_gen_at_start_;
   }
@@ -479,35 +472,12 @@
   const bool optimized_;
   const intptr_t osr_id_;
   Thread* const thread_;
-  const intptr_t field_invalidation_gen_at_start_;
   const intptr_t loading_invalidation_gen_at_start_;
 
   DISALLOW_COPY_AND_ASSIGN(CompileParsedFunctionHelper);
 };
 
 
-// Returns true if any of disabling fields is inside the guarded_fields.
-// The number of guarded_fields and disabling-fields is expected to be small
-// (less than 5).
-static bool CheckDisablingFields(
-    Thread* thread,
-    const ZoneGrowableArray<const Field*>& guarded_fields) {
-  Isolate* isolate = thread->isolate();
-  Zone* zone = thread->zone();
-  Field& field = Field::Handle(zone, isolate->GetDisablingField());
-  while (!field.IsNull()) {
-    for (intptr_t i = 0; i < guarded_fields.length(); i++) {
-      if (guarded_fields.At(i)->raw() == field.raw()) {
-        return true;
-      }
-    }
-    // Get next field.
-    field = isolate->GetDisablingField();
-  }
-  return false;
-}
-
-
 void CompileParsedFunctionHelper::FinalizeCompilation(
     Assembler* assembler,
     FlowGraphCompiler* graph_compiler,
@@ -593,17 +563,21 @@
           FLAG_trace_compiler || FLAG_trace_optimizing_compiler;
       bool code_is_valid = true;
       if (!flow_graph->parsed_function().guarded_fields()->is_empty()) {
-        if (field_invalidation_gen_at_start() !=
-            isolate()->field_invalidation_gen()) {
-          const ZoneGrowableArray<const Field*>& guarded_fields =
-              *flow_graph->parsed_function().guarded_fields();
-          bool field_conflict = CheckDisablingFields(thread(), guarded_fields);
-          if (field_conflict) {
+        const ZoneGrowableArray<const Field*>& guarded_fields =
+            *flow_graph->parsed_function().guarded_fields();
+        Field& original = Field::Handle();
+        for (intptr_t i = 0; i < guarded_fields.length(); i++) {
+          const Field& field = *guarded_fields[i];
+          ASSERT(!field.IsOriginal());
+          original = field.Original();
+          if (!field.IsConsistentWith(original)) {
             code_is_valid = false;
             if (trace_compiler) {
-              THR_Print("--> FAIL: Field invalidation.");
+              THR_Print("--> FAIL: Field %s guarded state changed.",
+                        field.ToCString());
             }
-         }
+            break;
+          }
         }
       }
       if (loading_invalidation_gen_at_start() !=
@@ -613,6 +587,13 @@
           THR_Print("--> FAIL: Loading invalidation.");
         }
       }
+      if (!thread()->cha()->IsConsistentWithCurrentHierarchy()) {
+        code_is_valid = false;
+        if (trace_compiler) {
+          THR_Print("--> FAIL: Class hierarchy has new subclasses.");
+        }
+      }
+
       // Setting breakpoints at runtime could make a function non-optimizable.
       if (code_is_valid && Compiler::CanOptimizeFunction(thread(), function)) {
         const bool is_osr = osr_id() != Compiler::kNoOSRDeoptId;
@@ -632,19 +613,17 @@
     }
 
     if (code_was_installed) {
-      // Register code with the classes it depends on because of CHA and
-      // fields it depends on because of store guards, unless we cannot
-      // deopt.
-      for (intptr_t i = 0;
-           i < thread()->cha()->leaf_classes().length();
-           ++i) {
-        thread()->cha()->leaf_classes()[i]->RegisterCHACode(code);
-      }
+      // The generated code was compiled under certain assumptions about
+      // class hierarchy and field types. Register these dependencies
+      // to ensure that the code will be deoptimized if they are violated.
+      thread()->cha()->RegisterDependencies(code);
+
       const ZoneGrowableArray<const Field*>& guarded_fields =
           *flow_graph->parsed_function().guarded_fields();
+      Field& field = Field::Handle();
       for (intptr_t i = 0; i < guarded_fields.length(); i++) {
-        const Field* field = guarded_fields[i];
-        field->RegisterDependentCode(code);
+        field = guarded_fields[i]->Original();
+        field.RegisterDependentCode(code);
       }
     }
   } else {  // not optimized.
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 5639af5..f544a77 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -283,7 +283,7 @@
 const Register ARGS_DESC_REG = R4;
 const Register CODE_REG = R6;
 const Register THR = R10;  // Caches current thread in generated code.
-const Register CALLEE_SAVED_TEMP = R6;
+const Register CALLEE_SAVED_TEMP = R8;
 
 // R15 encodes APSR in the vmrs instruction.
 const Register APSR = R15;
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index 54fc66b..657ffb0 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -119,6 +119,12 @@
 //    Note: rX is signed so it can be used to address parameters which are
 //    at negative indices with respect to FP.
 //
+//  - Swap rA, rX
+//
+//    FP[rA], FP[rX] <- FP[rX], FP[rA]
+//    Note: rX is signed so it can be used to address parameters which are
+//    at negative indices with respect to FP.
+//
 //  - Push rX
 //
 //    Push FP[rX] to the stack.
@@ -137,10 +143,10 @@
 //    Invoke function in SP[0] with arguments SP[-(1+ArgC)], ..., SP[-1] and
 //    argument descriptor PP[D].
 //
-//  - InstanceCall ArgC, D; InstanceCall2 ArgC, D; InstanceCall3 ArgC, D
+//  - InstanceCall<N> ArgC, D; InstanceCall<N>Opt ArgC, D
 //
-//    Lookup and invoke method using ICData in PP[D] with arguments
-//    SP[-(1+ArgC)], ..., SP[-1].
+//    Lookup and invoke method with N checked arguments using ICData in PP[D]
+//    with arguments SP[-(1+ArgC)], ..., SP[-1].
 //
 //  - NativeCall, NativeBootstrapCall
 //
@@ -166,7 +172,10 @@
 //
 //    Takes static field from TOS and ensures that it is initialized.
 //
-//  - IfNeStrictTOS; IfEqStrictTOS; IfNeStrictNumTOS; IfEqStrictNumTOS
+//  - If<Cond>(Num)TOS
+//    If<Cond>(Num) rA, rD
+//
+//    Cond is either NeStrict or EqStrict
 //
 //    Skips the next instruction unless the given condition holds. 'Num'
 //    variants perform number check while non-Num variants just compare
@@ -194,6 +203,11 @@
 //    Store SP[0] into array SP[-2] at index SP[-1]. No typechecking is done.
 //    SP[-2] is assumed to be a RawArray, SP[-1] to be a smi.
 //
+//  - StoreIndexed rA, rB, rC
+//
+//    Store rC into array rA at index rB. No typechecking is done.
+//    rA is assumed to be a RawArray, rB to be a smi.
+//
 //  - StoreField rA, B, rC
 //
 //    Store value FP[rC] into object FP[rA] at offset (in words) B.
@@ -214,6 +228,10 @@
 //
 //    SP[0] = !SP[0]
 //
+//  - BooleanNegate rA, rD
+//
+//    FP[rA] = !FP[rD]
+//
 //  - Throw A
 //
 //    Throw (Rethrow if A != 0) exception. Exception object and stack object
@@ -226,7 +244,7 @@
 //        B - number of local slots to reserve;
 //        rC - specifies context register to initialize with empty context.
 //
-//  - EntryOpt A, B, C
+//  - EntryOptional A, B, C
 //
 //    Function prologue for the function with optional or named arguments:
 //        A - expected number of positional arguments;
@@ -235,19 +253,36 @@
 //
 //    Only one of B and C can be not 0.
 //
-//    If B is not 0 then EntryOpt bytecode is followed by B LoadConstant
+//    If B is not 0 then EntryOptional bytecode is followed by B LoadConstant
 //    bytecodes specifying default values for optional arguments.
 //
-//    If C is not 0 then EntryOpt is followed by 2 * B LoadConstant bytecodes.
+//    If C is not 0 then EntryOptional is followed by 2 * B LoadConstant
+//    bytecodes.
 //    Bytecode at 2 * i specifies name of the i-th named argument and at
 //    2 * i + 1 default value. rA part of the LoadConstant bytecode specifies
 //    the location of the parameter on the stack. Here named arguments are
 //    sorted alphabetically to enable linear matching similar to how function
 //    prologues are implemented on other architectures.
 //
-//    Note: Unlike Entry bytecode EntryOpt does not setup the frame for
+//    Note: Unlike Entry bytecode EntryOptional does not setup the frame for
 //    local variables this is done by a separate bytecode Frame.
 //
+//  - EntryOptimized A, D
+//
+//    Function prologue for optimized functions with no optional or named
+//    arguments.
+//        A - expected number of positional arguments;
+//        B - number of local slots to reserve for registers;
+//
+//    Note: reserved slots are not initialized because optimized code
+//    has stack maps attached to call sites.
+//
+//  - HotCheck A, D
+//
+//    Increment current function's usage counter by A and check if it
+//    exceeds D. If it does trigger (re)optimization of the current
+//    function.
+//
 //  - Frame D
 //
 //    Reserve and initialize with null space for D local variables.
@@ -302,14 +337,29 @@
 //    match patched call's argument count so that Return instructions continue
 //    to work.
 //
+// TODO(vegorov) the way we replace calls with DebugBreak does not work
+//               with our smi fast paths because DebugBreak is simply skipped.
+//
 //  - LoadClassIdTOS, LoadClassId rA, D
 //
 //    LoadClassIdTOS loads the class id from the object at SP[0] and stores it
 //    to SP[0]. LoadClassId loads the class id from FP[rA] and stores it to
 //    FP[D].
 //
-// TODO(vegorov) the way we replace calls with DebugBreak does not work
-//               with our smi fast paths because DebugBreak is simply skipped.
+//  - Deopt ArgC, D
+//
+//    If D != 0 then trigger eager deoptimization with deopt id (D - 1).
+//    If D == 0 then trigger lazy deoptimization.
+//
+//    The meaning of operand ArgC (encoded as A operand) matches that of an
+//    ArgC operand in call instructions. This is needed because we could
+//    potentially patch calls instructions with a lazy deopt and we need to
+//    ensure that any Return/ReturnTOS instructions
+//    returning from the patched calls will continue to function,
+//    e.g. in bytecode sequences like
+//
+//    InstanceCall ... <- lazy deopt inside first call
+//    InstanceCall ... <- patches seconds call with Deopt
 //
 // BYTECODE LIST FORMAT
 //
@@ -336,14 +386,16 @@
 #define BYTECODES_LIST(V)                              \
   V(Trap,                            0, ___, ___, ___) \
   V(Compile,                         0, ___, ___, ___) \
+  V(HotCheck,                      A_D, num, num, ___) \
   V(Intrinsic,                       A, num, ___, ___) \
   V(Drop1,                           0, ___, ___, ___) \
   V(DropR,                           A, num, ___, ___) \
   V(Drop,                            A, num, ___, ___) \
   V(Jump,                            T, tgt, ___, ___) \
-  V(Return,                          A, num, ___, ___) \
+  V(Return,                          A, reg, ___, ___) \
   V(ReturnTOS,                       0, ___, ___, ___) \
   V(Move,                          A_X, reg, xeg, ___) \
+  V(Swap,                          A_X, reg, xeg, ___) \
   V(Push,                            X, xeg, ___, ___) \
   V(LoadConstant,                  A_D, reg, lit, ___) \
   V(LoadClassId,                   A_D, reg, reg, ___) \
@@ -352,9 +404,10 @@
   V(StoreLocal,                      X, xeg, ___, ___) \
   V(PopLocal,                        X, xeg, ___, ___) \
   V(StaticCall,                    A_D, num, num, ___) \
-  V(InstanceCall,                  A_D, num, num, ___) \
+  V(InstanceCall1,                  A_D, num, num, ___) \
   V(InstanceCall2,                 A_D, num, num, ___) \
-  V(InstanceCall3,                 A_D, num, num, ___) \
+  V(InstanceCall1Opt,              A_D, num, num, ___) \
+  V(InstanceCall2Opt,              A_D, num, num, ___) \
   V(NativeCall,                      0, ___, ___, ___) \
   V(NativeBootstrapCall,             0, ___, ___, ___) \
   V(AddTOS,                          0, ___, ___, ___) \
@@ -372,18 +425,25 @@
   V(IfEqStrictTOS,                   0, ___, ___, ___) \
   V(IfNeStrictNumTOS,                0, ___, ___, ___) \
   V(IfEqStrictNumTOS,                0, ___, ___, ___) \
+  V(IfNeStrict,                    A_D, reg, reg, ___) \
+  V(IfEqStrict,                    A_D, reg, reg, ___) \
+  V(IfNeStrictNum,                 A_D, reg, reg, ___) \
+  V(IfEqStrictNum,                 A_D, reg, reg, ___) \
   V(CreateArrayTOS,                  0, ___, ___, ___) \
   V(Allocate,                        D, lit, ___, ___) \
   V(AllocateT,                       0, ___, ___, ___) \
   V(StoreIndexedTOS,                 0, ___, ___, ___) \
-  V(StoreField,                  A_B_C, reg, reg, reg) \
+  V(StoreIndexed,                A_B_C, reg, reg, reg) \
+  V(StoreField,                  A_B_C, reg, num, reg) \
   V(StoreFieldTOS,                   D, num, ___, ___) \
-  V(LoadField,                   A_B_C, reg, reg, reg) \
+  V(LoadField,                   A_B_C, reg, reg, num) \
   V(LoadFieldTOS,                    D, num, ___, ___) \
   V(BooleanNegateTOS,                0, ___, ___, ___) \
+  V(BooleanNegate,                 A_D, reg, reg, ___) \
   V(Throw,                           A, num, ___, ___) \
   V(Entry,                       A_B_C, num, num, num) \
-  V(EntryOpt,                    A_B_C, num, num, num) \
+  V(EntryOptional,               A_B_C, num, num, num) \
+  V(EntryOptimized,                A_D, num, num, ___) \
   V(Frame,                           D, num, ___, ___) \
   V(SetFrame,                        A, num, ___, num) \
   V(AllocateContext,                 D, num, ___, ___) \
@@ -396,6 +456,7 @@
   V(CheckStack,                      0, ___, ___, ___) \
   V(DebugStep,                       0, ___, ___, ___) \
   V(DebugBreak,                      A, num, ___, ___) \
+  V(Deopt,                         A_D, num, num, ___) \
 
 typedef uint32_t Instr;
 
@@ -457,15 +518,23 @@
     return static_cast<Opcode>(bc & 0xFF);
   }
 
+  DART_FORCE_INLINE static bool IsCallOpcode(Instr instr) {
+    switch (DecodeOpcode(instr)) {
+      case Bytecode::kStaticCall:
+      case Bytecode::kInstanceCall1:
+      case Bytecode::kInstanceCall2:
+      case Bytecode::kInstanceCall1Opt:
+      case Bytecode::kInstanceCall2Opt:
+      case Bytecode::kDebugBreak:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
   DART_FORCE_INLINE static uint8_t DecodeArgc(Instr call) {
-#if defined(DEBUG)
-    const Opcode op = DecodeOpcode(call);
-    ASSERT((op == Bytecode::kStaticCall) ||
-           (op == Bytecode::kInstanceCall) ||
-           (op == Bytecode::kInstanceCall2) ||
-           (op == Bytecode::kInstanceCall3) ||
-           (op == Bytecode::kDebugBreak));
-#endif
+    ASSERT(IsCallOpcode(call));
     return (call >> 8) & 0xFF;
   }
 
@@ -484,7 +553,7 @@
 const int16_t FPREG = 0;
 const int16_t SPREG = 1;
 const intptr_t kNumberOfCpuRegisters = 20;
-const intptr_t kDartAvailableCpuRegs = 0;
+const intptr_t kDartAvailableCpuRegs = -1;
 const intptr_t kNoRegister = -1;
 const intptr_t kReservedCpuRegisters = 0;
 const intptr_t ARGS_DESC_REG = 0;
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 0cfee29..72c4710 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -93,7 +93,7 @@
 const Register ARGS_DESC_REG = R10;  // Arguments descriptor register.
 const Register CODE_REG = R12;
 const Register THR = R14;  // Caches current thread in generated code.
-const Register CALLEE_SAVED_TEMP = R13;
+const Register CALLEE_SAVED_TEMP = RBX;
 
 // Exception object is passed in this register to the catch handlers when an
 // exception is thrown.
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index f6e8bb7..fcc4e79 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -8957,6 +8957,41 @@
 }
 
 
+TEST_CASE(ExternalStringLoadElimination) {
+  const bool saved_flag = FLAG_support_externalizable_strings;
+  FLAG_support_externalizable_strings = true;
+
+  const char* kScriptChars =
+      "class A {\n"
+      "  static change_str(String s) native 'A_change_str';\n"
+      "}\n"
+      "double_char0(str) {\n"
+      "  return str.codeUnitAt(0) + str.codeUnitAt(0);\n"
+      "}\n"
+      "main() {\n"
+      "  var externalA = 'AA' + 'AA';\n"
+      "  A.change_str(externalA);\n"
+      "  for (var i = 0; i < 10000; i++) double_char0(externalA);\n"
+      "  var result = double_char0(externalA);\n"
+      "  return result == 130;\n"
+      "}\n";
+  Dart_Handle lib =
+      TestCase::LoadTestScript(kScriptChars,
+                               &ExternalStringDeoptimize_native_lookup);
+  Dart_Handle result = Dart_Invoke(lib,
+                                   NewString("main"),
+                                   0,
+                                   NULL);
+  EXPECT_VALID(result);
+  bool value = false;
+  result = Dart_BooleanValue(result, &value);
+  EXPECT_VALID(result);
+  EXPECT(value);
+
+  FLAG_support_externalizable_strings = saved_flag;
+}
+
+
 TEST_CASE(ExternalStringGuardFieldDeoptimize) {
   const bool saved_flag = FLAG_support_externalizable_strings;
   FLAG_support_externalizable_strings = true;
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 1d89239..1839f7f 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -66,14 +66,19 @@
   // optimized function contains FP, PP (ARM and MIPS only), PC-marker and
   // return-address. This section is copied as well, so that its contained
   // values can be updated before returning to the deoptimized function.
+  // Note: on DBC stack grows upwards unlike on all other architectures.
   source_frame_size_ =
       + kDartFrameFixedSize  // For saved values below sp.
+#if !defined(TARGET_ARCH_DBC)
       + ((frame->fp() - frame->sp()) / kWordSize)  // For frame size incl. sp.
+#else
+      + ((frame->sp() - frame->fp()) / kWordSize)  // For frame size incl. sp.
+#endif  // !defined(TARGET_ARCH_DBC)
       + 1  // For fp.
       + kParamEndSlotFromFp  // For saved values above fp.
       + num_args_;  // For arguments.
-  source_frame_ = reinterpret_cast<intptr_t*>(
-      frame->sp() - (kDartFrameFixedSize * kWordSize));
+
+  source_frame_ = FrameBase(frame);
 
   if (dest_options == kDestIsOriginalFrame) {
     // Work from a copy of the source frame.
@@ -182,29 +187,46 @@
 
 
 intptr_t DeoptContext::DestStackAdjustment() const {
-  return (dest_frame_size_
-          - kDartFrameFixedSize
-          - num_args_
-          - kParamEndSlotFromFp
-          - 1);  // For fp.
+  return dest_frame_size_
+         - kDartFrameFixedSize
+         - num_args_
+#if !defined(TARGET_ARCH_DBC)
+         - 1  // For fp.
+#endif
+         - kParamEndSlotFromFp;
 }
 
 
 intptr_t DeoptContext::GetSourceFp() const {
+#if !defined(TARGET_ARCH_DBC)
   return source_frame_[source_frame_size_ - 1 - num_args_ -
                        kParamEndSlotFromFp];
+#else
+  return source_frame_[num_args_ + kDartFrameFixedSize +
+      kSavedCallerFpSlotFromFp];
+#endif
 }
 
 
 intptr_t DeoptContext::GetSourcePp() const {
+#if !defined(TARGET_ARCH_DBC)
   return source_frame_[source_frame_size_ - 1 - num_args_ -
                        kParamEndSlotFromFp +
                        StackFrame::SavedCallerPpSlotFromFp()];
+#else
+  UNREACHABLE();
+  return 0;
+#endif
 }
 
 
 intptr_t DeoptContext::GetSourcePc() const {
+#if !defined(TARGET_ARCH_DBC)
   return source_frame_[source_frame_size_ - num_args_ + kSavedPcSlotFromSp];
+#else
+  return source_frame_[num_args_ + kDartFrameFixedSize +
+      kSavedCallerPcSlotFromFp];
+#endif
 }
 
 
@@ -305,12 +327,12 @@
   }
 
   if (FLAG_trace_deoptimization_verbose) {
-    intptr_t* start = dest_frame_;
     for (intptr_t i = 0; i < frame_size; i++) {
-      OS::PrintErr("*%" Pd ". [0x%" Px "] 0x%" Px " [%s]\n",
+      intptr_t* to_addr = GetDestFrameAddressAt(i);
+      OS::PrintErr("*%" Pd ". [%p] 0x%" Px " [%s]\n",
                    i,
-                   reinterpret_cast<uword>(&start[i]),
-                   start[i],
+                   to_addr,
+                   *to_addr,
                    deopt_instructions[i + (len - frame_size)]->ToCString());
     }
   }
@@ -660,12 +682,9 @@
     Function& function = Function::Handle(deopt_context->zone());
     function ^= deopt_context->ObjectAt(object_table_index_);
     if (function.IsNull()) {
-      // There are no deoptimization stubs on DBC.
-#if !defined(TARGET_ARCH_DBC)
       *reinterpret_cast<RawObject**>(dest_addr) = deopt_context->is_lazy_deopt()
           ? StubCode::DeoptimizeLazy_entry()->code()
           : StubCode::Deoptimize_entry()->code();
-#endif
       return;
     }
 
@@ -729,7 +748,7 @@
   void Execute(DeoptContext* deopt_context, intptr_t* dest_addr) {
     *dest_addr = deopt_context->GetCallerFp();
     deopt_context->SetCallerFp(reinterpret_cast<intptr_t>(
-        dest_addr - (kSavedCallerFpSlotFromFp * kWordSize)));
+        dest_addr - kSavedCallerFpSlotFromFp));
   }
 
  private:
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index 229a0aa..5dfab38 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -9,9 +9,11 @@
 #include "vm/assembler.h"
 #include "vm/code_generator.h"
 #include "vm/deferred_objects.h"
+#include "vm/flow_graph_compiler.h"
 #include "vm/growable_array.h"
 #include "vm/locations.h"
 #include "vm/object.h"
+#include "vm/stack_frame.h"
 #include "vm/thread.h"
 
 namespace dart {
@@ -48,6 +50,10 @@
   intptr_t* GetSourceFrameAddressAt(intptr_t index) const {
     ASSERT(source_frame_ != NULL);
     ASSERT((0 <= index) && (index < source_frame_size_));
+#if !defined(TARGET_ARCH_DBC)
+    // Convert FP relative index to SP relative one.
+    index = source_frame_size_ - 1 - index;
+#endif  // !defined(TARGET_ARCH_DBC)
     return &source_frame_[index];
   }
 
@@ -64,13 +70,20 @@
   }
 
   intptr_t RegisterValue(Register reg) const {
-    ASSERT(cpu_registers_ != NULL);
     ASSERT(reg >= 0);
     ASSERT(reg < kNumberOfCpuRegisters);
+#if !defined(TARGET_ARCH_DBC)
+    ASSERT(cpu_registers_ != NULL);
     return cpu_registers_[reg];
+#else
+    // On DBC registers and stack slots are the same.
+    const intptr_t stack_index = num_args_ + kDartFrameFixedSize + reg;
+    return *GetSourceFrameAddressAt(stack_index);
+#endif  // !defined(TARGET_ARCH_DBC)
   }
 
   double FpuRegisterValue(FpuRegister reg) const {
+    ASSERT(FlowGraphCompiler::SupportsUnboxedDoubles());
     ASSERT(fpu_registers_ != NULL);
     ASSERT(reg >= 0);
     ASSERT(reg < kNumberOfFpuRegisters);
@@ -78,6 +91,7 @@
   }
 
   simd128_value_t FpuRegisterValueAsSimd128(FpuRegister reg) const {
+    ASSERT(FlowGraphCompiler::SupportsUnboxedSimd128());
     ASSERT(fpu_registers_ != NULL);
     ASSERT(reg >= 0);
     ASSERT(reg < kNumberOfFpuRegisters);
@@ -85,9 +99,29 @@
     return simd128_value_t().readFrom(address);
   }
 
-  void set_dest_frame(intptr_t* dest_frame) {
-    ASSERT(dest_frame != NULL && dest_frame_ == NULL);
-    dest_frame_ = dest_frame;
+  // Return base pointer for the given frame (either source or destination).
+  // Base pointer points to the slot with the lowest address in the frame
+  // including incoming arguments and artificial deoptimization frame
+  // on top of it.
+  // Note: artificial frame created by the deoptimization stub is considered
+  // part of the frame because it contains saved caller PC and FP that
+  // deoptimization will fill in.
+  intptr_t* FrameBase(const StackFrame* frame) {
+#if !defined(TARGET_ARCH_DBC)
+    // SP of the deoptimization frame is the lowest slot because
+    // stack is growing downwards.
+    return reinterpret_cast<intptr_t*>(
+      frame->sp() - (kDartFrameFixedSize * kWordSize));
+#else
+    // First argument is the lowest slot because stack is growing upwards.
+    return reinterpret_cast<intptr_t*>(
+      frame->fp() - (kDartFrameFixedSize + num_args_) * kWordSize);
+#endif  // !defined(TARGET_ARCH_DBC)
+  }
+
+  void set_dest_frame(const StackFrame* frame) {
+    ASSERT(frame != NULL && dest_frame_ == NULL);
+    dest_frame_ = FrameBase(frame);
   }
 
   Thread* thread() const { return thread_; }
@@ -188,10 +222,18 @@
     return deferred_objects_[idx];
   }
 
+  intptr_t num_args() const { return num_args_; }
+
  private:
   intptr_t* GetDestFrameAddressAt(intptr_t index) const {
     ASSERT(dest_frame_ != NULL);
     ASSERT((0 <= index) && (index < dest_frame_size_));
+#if defined(TARGET_ARCH_DBC)
+    // Stack on DBC is growing upwards but we record deopt commands
+    // in the same order we record them on other architectures as if
+    // the stack was growing downwards.
+    index = dest_frame_size_ - 1 - index;
+#endif  // defined(TARGET_ARCH_DBC)
     return &dest_frame_[index];
   }
 
@@ -383,7 +425,7 @@
         context, reg()));
     } else {
       return *reinterpret_cast<T*>(context->GetSourceFrameAddressAt(
-          context->source_frame_size() - raw_index() - 1));
+          raw_index()));
     }
   }
 
diff --git a/runtime/vm/disassembler_dbc.cc b/runtime/vm/disassembler_dbc.cc
index 85d734d..5c8b3a0 100644
--- a/runtime/vm/disassembler_dbc.cc
+++ b/runtime/vm/disassembler_dbc.cc
@@ -63,7 +63,11 @@
 
 
 static void Fmtxeg(char** buf, intptr_t* size, uword pc, int32_t value) {
-  FormatOperand(buf, size, "R(%d)", value);
+  if (value < 0) {
+    FormatOperand(buf, size, "FP[%d]", value);
+  } else {
+    Fmtreg(buf, size, pc, value);
+  }
 }
 
 
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index ee483ad..5818624 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -61,6 +61,8 @@
   "Disassemble dart code.")                                                    \
 R(disassemble_optimized, false, bool, false,                                   \
   "Disassemble optimized code.")                                               \
+R(dump_megamorphic_stats, false, bool, false,                                  \
+  "Dump megamorphic cache statistics")                                         \
 R(dump_symbol_stats, false, bool, false,                                       \
   "Dump symbol table statistics")                                              \
 R(enable_asserts, false, bool, false,                                          \
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index bac0c4b..0c8dbc0 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -444,13 +444,14 @@
         ? String::Handle(zone(), Field::NameFromGetter(call->function_name()))
         : call->function_name();
     const Class& cls = Class::Handle(zone(), function().Owner());
-    if (!thread()->cha()->HasOverride(cls, name)) {
+    intptr_t subclass_count = 0;
+    if (!thread()->cha()->HasOverride(cls, name, &subclass_count)) {
       if (FLAG_trace_cha) {
         THR_Print("  **(CHA) Instance call needs no check, "
             "no overrides of '%s' '%s'\n",
             name.ToCString(), cls.ToCString());
       }
-      thread()->cha()->AddToLeafClasses(cls);
+      thread()->cha()->AddToGuardedClasses(cls, subclass_count);
       return false;
     }
   }
diff --git a/runtime/vm/flow_graph_allocator.cc b/runtime/vm/flow_graph_allocator.cc
index 747094c..d4fd498 100644
--- a/runtime/vm/flow_graph_allocator.cc
+++ b/runtime/vm/flow_graph_allocator.cc
@@ -152,6 +152,15 @@
 
       // Initialize location summary for instruction.
       current->InitializeLocationSummary(zone(), true);  // opt
+#if defined(TARGET_ARCH_DBC)
+      // TODO(vegorov) remove this once we have ported all necessary
+      // instructions to DBC.
+      if (!current->HasLocs()) {
+        graph_entry_->parsed_function().Bailout("SSALivenessAnalysis",
+                                                current->ToCString());
+      }
+#endif
+
       LocationSummary* locs = current->locs();
 #if defined(DEBUG)
       locs->DiscoverWritableInputs();
@@ -598,6 +607,10 @@
     } else if (block->IsCatchBlockEntry()) {
       // Process initial definitions.
       CatchBlockEntryInstr* catch_entry = block->AsCatchBlockEntry();
+#if defined(TARGET_ARCH_DBC)
+      // TODO(vegorov) support try-catch/finally for DBC.
+      flow_graph_.parsed_function().Bailout("FlowGraphAllocator", "Catch");
+#endif
       for (intptr_t i = 0;
            i < catch_entry->initial_definitions()->length();
            i++) {
@@ -652,14 +665,35 @@
       slot_index -= flow_graph_.num_non_copied_params();
     }
 
+#if defined(TARGET_ARCH_DBC)
+    ASSERT(param->base_reg() == FPREG);
+    if (slot_index >= 0) {
+      AssignSafepoints(defn, range);
+      range->finger()->Initialize(range);
+      range->set_assigned_location(Location::RegisterLocation(slot_index));
+      if (range->End() > kNormalEntryPos) {
+        LiveRange* tail = range->SplitAt(kNormalEntryPos);
+        CompleteRange(tail, Location::kRegister);
+      }
+      ConvertAllUses(range);
+      return;
+    }
+#endif  // defined(TARGET_ARCH_DBC)
     range->set_assigned_location(Location::StackSlot(slot_index,
                                                      param->base_reg()));
     range->set_spill_slot(Location::StackSlot(slot_index,
                                               param->base_reg()));
+
   } else if (defn->IsCurrentContext()) {
+#if !defined(TARGET_ARCH_DBC)
+    const Register context_reg = CTX;
+#else
+    const intptr_t context_reg = flow_graph_.num_copied_params();
+#endif
+
     AssignSafepoints(defn, range);
     range->finger()->Initialize(range);
-    range->set_assigned_location(Location::RegisterLocation(CTX));
+    range->set_assigned_location(Location::RegisterLocation(context_reg));
     if (range->End() > kNormalEntryPos) {
       LiveRange* tail = range->SplitAt(kNormalEntryPos);
       CompleteRange(tail, Location::kRegister);
@@ -1323,7 +1357,10 @@
     }
   }
 
-  // Block all allocatable registers for calls and record the stack bitmap.
+  // Block all allocatable registers for calls.
+  // Note that on DBC registers are always essentially spilled so
+  // we don't need to block anything.
+#if !defined(TARGET_ARCH_DBC)
   if (locs->always_calls()) {
     // Expected shape of live range:
     //
@@ -1373,6 +1410,7 @@
     }
 #endif
   }
+#endif
 
   if (locs->can_call()) {
     safepoints_.Add(current);
@@ -1906,6 +1944,14 @@
 
 
 void FlowGraphAllocator::AllocateSpillSlotFor(LiveRange* range) {
+#if defined(TARGET_ARCH_DBC)
+  // There is no need to support spilling on DBC because we have a lot of
+  // registers and registers and spill-slots have the same performance
+  // characteristics.
+  flow_graph_.parsed_function().Bailout("FlowGraphAllocator", "SPILL");
+  UNREACHABLE();
+#endif
+
   ASSERT(range->spill_slot().IsInvalid());
 
   // Compute range start and end.
@@ -2242,6 +2288,9 @@
 
   registers_[candidate]->Add(unallocated);
   unallocated->set_assigned_location(MakeRegisterLocation(candidate));
+#if defined(TARGET_ARCH_DBC)
+  last_used_register_ = Utils::Maximum(last_used_register_, candidate);
+#endif
 
   return true;
 }
@@ -2441,6 +2490,9 @@
 
   registers_[reg]->Add(unallocated);
   unallocated->set_assigned_location(MakeRegisterLocation(reg));
+#if defined(TARGET_ARCH_DBC)
+  last_used_register_ = Utils::Maximum(last_used_register_, reg);
+#endif
 }
 
 
@@ -2530,10 +2582,16 @@
     for (SafepointPosition* safepoint = range->first_safepoint();
          safepoint != NULL;
          safepoint = safepoint->next()) {
+#if !defined(TARGET_ARCH_DBC)
       if (!safepoint->locs()->always_calls()) {
         ASSERT(safepoint->locs()->can_call());
         safepoint->locs()->live_registers()->Add(loc, range->representation());
       }
+#else
+      if (range->representation() == kTagged) {
+        safepoint->locs()->SetStackBit(loc.reg());
+      }
+#endif  // !defined(TARGET_ARCH_DBC)
     }
   }
 }
@@ -2683,6 +2741,10 @@
       registers_[reg]->Add(range);
     }
   }
+
+#if defined(TARGET_ARCH_DBC)
+  last_used_register_ = -1;
+#endif
 }
 
 
@@ -2949,10 +3011,6 @@
 
   BuildLiveRanges();
 
-  if (FLAG_print_ssa_liveness) {
-    liveness_.Dump();
-  }
-
   if (FLAG_print_ssa_liveranges) {
     const Function& function = flow_graph_.function();
     THR_Print("-- [before ssa allocator] ranges [%s] ---------\n",
@@ -2977,6 +3035,9 @@
                        cpu_regs_,
                        blocked_cpu_registers_);
   AllocateUnallocatedRanges();
+#if defined(TARGET_ARCH_DBC)
+  const intptr_t last_used_cpu_register = last_used_register_;
+#endif
 
   cpu_spill_slot_count_ = spill_slots_.length();
   spill_slots_.Clear();
@@ -2989,6 +3050,10 @@
                        fpu_regs_,
                        blocked_fpu_registers_);
   AllocateUnallocatedRanges();
+#if defined(TARGET_ARCH_DBC)
+  const intptr_t last_used_fpu_register = last_used_register_;
+  ASSERT(last_used_fpu_register == -1);  // Not supported right now.
+#endif
 
   ResolveControlFlow();
 
@@ -2997,6 +3062,21 @@
   intptr_t double_spill_slot_count = spill_slots_.length() * kDoubleSpillFactor;
   entry->set_spill_slot_count(cpu_spill_slot_count_ + double_spill_slot_count);
 
+#if defined(TARGET_ARCH_DBC)
+  // Spilling is unsupported on DBC.
+  if (entry->spill_slot_count() != 0) {
+    UNREACHABLE();
+  }
+
+  // We store number of used DBC registers in the spill slot count to avoid
+  // introducing a separate field. It has roughly the same meaning:
+  // number of used registers determines how big of a frame to reserve for
+  // this function on DBC stack.
+  entry->set_spill_slot_count(Utils::Maximum((last_used_cpu_register + 1) +
+                                             (last_used_fpu_register + 1),
+                                             flow_graph_.num_copied_params()));
+#endif
+
   if (FLAG_print_ssa_liveranges) {
     const Function& function = flow_graph_.function();
 
diff --git a/runtime/vm/flow_graph_allocator.h b/runtime/vm/flow_graph_allocator.h
index fe2c710..7df1a6a 100644
--- a/runtime/vm/flow_graph_allocator.h
+++ b/runtime/vm/flow_graph_allocator.h
@@ -298,6 +298,10 @@
 
   intptr_t number_of_registers_;
 
+#if defined(TARGET_ARCH_DBC)
+  intptr_t last_used_register_;
+#endif
+
   // Per register lists of allocated live ranges.  Contain only those
   // ranges that can be affected by future allocation decisions.
   // Those live ranges that end before the start of the current live range are
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index b968585..bd07667 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -860,7 +860,7 @@
                                                 Value* value,
                                                 TokenPosition token_pos) {
   if (local.is_captured()) {
-    LocalVariable* tmp_var = EnterTempLocalScope(value, token_pos);
+    LocalVariable* tmp_var = EnterTempLocalScope(value);
     intptr_t delta =
         owner()->context_level() - local.owner()->context_level();
     ASSERT(delta >= 0);
@@ -878,7 +878,7 @@
                                        kEmitStoreBarrier,
                                        token_pos);
     Do(store);
-    return ExitTempLocalScope(tmp_var, token_pos);
+    return ExitTempLocalScope(value);
   } else {
     return new(Z) StoreLocalInstr(local, value, token_pos);
   }
@@ -1318,20 +1318,17 @@
   ValueGraphVisitor for_value(owner());
   node->expr()->Visit(&for_value);
   Append(for_value);
-  Definition* checked_value;
   if (CanSkipTypeCheck(node->expr()->token_pos(),
                        for_value.value(),
                        node->type(),
                        node->dst_name())) {
-    // Drop the value and 0 additional temporaries.
-    checked_value = new(Z) DropTempsInstr(0, for_value.value());
+    ReturnValue(for_value.value());
   } else {
-    checked_value = BuildAssertAssignable(node->expr()->token_pos(),
-                                          for_value.value(),
-                                          node->type(),
-                                          node->dst_name());
+    ReturnDefinition(BuildAssertAssignable(node->expr()->token_pos(),
+                                           for_value.value(),
+                                           node->type(),
+                                           node->dst_name()));
   }
-  ReturnDefinition(checked_value);
 }
 
 
@@ -2245,8 +2242,7 @@
 }
 
 
-LocalVariable* EffectGraphVisitor::EnterTempLocalScope(
-    Value* value, TokenPosition token_pos) {
+LocalVariable* EffectGraphVisitor::EnterTempLocalScope(Value* value) {
   ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1));
   intptr_t index = GetCurrentTempLocalIndex();
   char name[64];
@@ -2260,12 +2256,8 @@
 }
 
 
-Definition* EffectGraphVisitor::ExitTempLocalScope(
-    LocalVariable* var, TokenPosition token_pos) {
-  Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos));
-  owner()->DeallocateTemps(1);
-  ASSERT(GetCurrentTempLocalIndex() == var->index());
-  return new(Z) DropTempsInstr(1, tmp);
+Definition* EffectGraphVisitor::ExitTempLocalScope(Value* value) {
+  return new(Z) DropTempsInstr(0, value);
 }
 
 
@@ -2337,7 +2329,7 @@
                                                      num_elements);
   Value* array_val = Bind(create);
 
-  { LocalVariable* tmp_var = EnterTempLocalScope(array_val, node->token_pos());
+  { LocalVariable* tmp_var = EnterTempLocalScope(array_val);
     const intptr_t class_id = kArrayCid;
     const intptr_t deopt_id = Thread::kNoDeoptId;
     for (int i = 0; i < node->length(); ++i) {
@@ -2359,7 +2351,7 @@
           index_scale, class_id, deopt_id, node->token_pos());
       Do(store);
     }
-    ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos()));
+    ReturnDefinition(ExitTempLocalScope(array_val));
   }
 }
 
@@ -2452,8 +2444,7 @@
   alloc->set_closure_function(function);
 
   Value* closure_val = Bind(alloc);
-  { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val,
-                                                         node->token_pos());
+  { LocalVariable* closure_tmp_var = EnterTempLocalScope(closure_val);
     // Store type arguments if scope class is generic.
     const Type& function_type = Type::ZoneHandle(Z, function.SignatureType());
     const Class& scope_cls = Class::ZoneHandle(Z, function_type.type_class());
@@ -2489,8 +2480,7 @@
       Value* allocated_context =
           Bind(new(Z) AllocateContextInstr(node->token_pos(),
                                            kNumContextVariables));
-      { LocalVariable* context_tmp_var =
-            EnterTempLocalScope(allocated_context, node->token_pos());
+      { LocalVariable* context_tmp_var = EnterTempLocalScope(allocated_context);
         // Store receiver in context.
         Value* context_tmp_val =
             Bind(new(Z) LoadLocalInstr(*context_tmp_var, node->token_pos()));
@@ -2513,7 +2503,7 @@
                                           context_tmp_val,
                                           kEmitStoreBarrier,
                                           node->token_pos()));
-        Do(ExitTempLocalScope(context_tmp_var, node->token_pos()));
+        Do(ExitTempLocalScope(allocated_context));
       }
     } else {
       // Store current context in closure.
@@ -2526,7 +2516,7 @@
                                         kEmitStoreBarrier,
                                         node->token_pos()));
     }
-    ReturnDefinition(ExitTempLocalScope(closure_tmp_var, node->token_pos()));
+    ReturnDefinition(ExitTempLocalScope(closure_val));
   }
 }
 
@@ -2687,8 +2677,8 @@
   node->closure()->Visit(&for_closure);
   Append(for_closure);
 
-  LocalVariable* tmp_var =
-      EnterTempLocalScope(for_closure.value(), node->token_pos());
+  Value* closure_value = for_closure.value();
+  LocalVariable* tmp_var = EnterTempLocalScope(closure_value);
 
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new(Z) ZoneGrowableArray<PushArgumentInstr*>(node->arguments()->length());
@@ -2714,7 +2704,7 @@
   } else {
     Do(closure_call);
   }
-  ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos()));
+  ReturnDefinition(ExitTempLocalScope(closure_value));
 }
 
 
@@ -2953,12 +2943,12 @@
   //   tn       <- LoadLocal(temp)
 
   Value* allocate = BuildObjectAllocation(node);
-  { LocalVariable* tmp_var = EnterTempLocalScope(allocate, node->token_pos());
+  { LocalVariable* tmp_var = EnterTempLocalScope(allocate);
     Value* allocated_tmp =
         Bind(new(Z) LoadLocalInstr(*tmp_var, node->token_pos()));
     PushArgumentInstr* push_allocated_value = PushArgument(allocated_tmp);
     BuildConstructorCall(node, push_allocated_value);
-    ReturnDefinition(ExitTempLocalScope(tmp_var, node->token_pos()));
+    ReturnDefinition(ExitTempLocalScope(allocate));
   }
 }
 
@@ -3974,8 +3964,7 @@
     Value* allocated_context =
         Bind(new(Z) AllocateContextInstr(node->token_pos(),
                                          num_context_variables));
-    { LocalVariable* tmp_var =
-          EnterTempLocalScope(allocated_context, node->token_pos());
+    { LocalVariable* tmp_var = EnterTempLocalScope(allocated_context);
       if (!is_top_level_sequence || HasContextScope()) {
         ASSERT(is_top_level_sequence ||
                (nested_block.ContextLevel() ==
@@ -3990,7 +3979,7 @@
                                           node->token_pos()));
       }
       Do(BuildStoreContext(
-          Bind(ExitTempLocalScope(tmp_var, node->token_pos())),
+          Bind(ExitTempLocalScope(allocated_context)),
           node->token_pos()));
     }
 
@@ -4605,15 +4594,7 @@
 
 
 void FlowGraphBuilder::Bailout(const char* reason) const {
-  const Function& function = parsed_function_.function();
-  Report::MessageF(Report::kBailout,
-                   Script::Handle(function.script()),
-                   function.token_pos(),
-                   Report::AtLocation,
-                   "FlowGraphBuilder Bailout: %s %s",
-                   String::Handle(function.name()).ToCString(),
-                   reason);
-  UNREACHABLE();
+  parsed_function_.Bailout("FlowGraphBuilder", reason);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 977df17..870773b 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -436,8 +436,8 @@
 
   // Helpers for allocating and deallocating temporary locals on top of the
   // expression stack.
-  LocalVariable* EnterTempLocalScope(Value* value, TokenPosition token_pos);
-  Definition* ExitTempLocalScope(LocalVariable* var, TokenPosition token_pos);
+  LocalVariable* EnterTempLocalScope(Value* value);
+  Definition* ExitTempLocalScope(Value* value);
 
   void BuildLetTempExpressions(LetNode* node);
 
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 93225db..b403bbf 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -644,15 +644,7 @@
 
 
 void FlowGraphCompiler::Bailout(const char* reason) {
-  const Function& function = parsed_function_.function();
-  Report::MessageF(Report::kBailout,
-                   Script::Handle(function.script()),
-                   function.token_pos(),
-                   Report::AtLocation,
-                   "FlowGraphCompiler Bailout: %s %s",
-                   String::Handle(function.name()).ToCString(),
-                   reason);
-  UNREACHABLE();
+  parsed_function_.Bailout("FlowGraphCompiler", reason);
 }
 
 
@@ -1188,7 +1180,7 @@
     return;
   }
   if (FLAG_always_megamorphic_calls) {
-    EmitMegamorphicInstanceCall(ic_data, argument_count,
+    EmitMegamorphicInstanceCall(ic_data_in, argument_count,
                                 deopt_id, token_pos, locs,
                                 CatchClauseNode::kInvalidTryIndex);
     return;
@@ -1216,7 +1208,7 @@
   }
 
   if (is_optimizing()) {
-    EmitMegamorphicInstanceCall(ic_data, argument_count,
+    EmitMegamorphicInstanceCall(ic_data_in, argument_count,
                                 deopt_id, token_pos, locs,
                                 CatchClauseNode::kInvalidTryIndex);
     return;
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index f7aa76e..a94eaa6 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -613,6 +613,10 @@
   void BeginCodeSourceRange();
   bool EndCodeSourceRange(TokenPosition token_pos);
 
+#if defined(TARGET_ARCH_DBC)
+  void RecordAfterCall(Instruction* instr);
+#endif
+
  private:
   friend class CheckStackOverflowSlowPath;  // For pending_deoptimization_env_.
 
diff --git a/runtime/vm/flow_graph_compiler_dbc.cc b/runtime/vm/flow_graph_compiler_dbc.cc
index 92ba799..86352cc 100644
--- a/runtime/vm/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/flow_graph_compiler_dbc.cc
@@ -90,8 +90,120 @@
 RawTypedData* CompilerDeoptInfo::CreateDeoptInfo(FlowGraphCompiler* compiler,
                                                  DeoptInfoBuilder* builder,
                                                  const Array& deopt_table) {
-  UNIMPLEMENTED();
-  return TypedData::null();
+  if (deopt_env_ == NULL) {
+    ++builder->current_info_number_;
+    return TypedData::null();
+  }
+
+  intptr_t stack_height = compiler->StackSize();
+  AllocateIncomingParametersRecursive(deopt_env_, &stack_height);
+
+  intptr_t slot_ix = 0;
+  Environment* current = deopt_env_;
+
+  // Emit all kMaterializeObject instructions describing objects to be
+  // materialized on the deoptimization as a prefix to the deoptimization info.
+  EmitMaterializations(deopt_env_, builder);
+
+  // The real frame starts here.
+  builder->MarkFrameStart();
+
+  Zone* zone = compiler->zone();
+
+  builder->AddCallerFp(slot_ix++);
+  builder->AddReturnAddress(current->function(), deopt_id(), slot_ix++);
+  builder->AddPcMarker(Function::ZoneHandle(zone), slot_ix++);
+  builder->AddConstant(Function::ZoneHandle(zone), slot_ix++);
+
+  // Emit all values that are needed for materialization as a part of the
+  // expression stack for the bottom-most frame. This guarantees that GC
+  // will be able to find them during materialization.
+  slot_ix = builder->EmitMaterializationArguments(slot_ix);
+
+  // For the innermost environment, set outgoing arguments and the locals.
+  for (intptr_t i = current->Length() - 1;
+       i >= current->fixed_parameter_count();
+       i--) {
+    builder->AddCopy(current->ValueAt(i), current->LocationAt(i), slot_ix++);
+  }
+
+  builder->AddCallerFp(slot_ix++);
+
+  Environment* previous = current;
+  current = current->outer();
+  while (current != NULL) {
+    // For any outer environment the deopt id is that of the call instruction
+    // which is recorded in the outer environment.
+    builder->AddReturnAddress(
+        current->function(),
+        Thread::ToDeoptAfter(current->deopt_id()),
+        slot_ix++);
+
+    builder->AddPcMarker(previous->function(), slot_ix++);
+    builder->AddConstant(previous->function(), slot_ix++);
+
+    // The values of outgoing arguments can be changed from the inlined call so
+    // we must read them from the previous environment.
+    for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
+      builder->AddCopy(previous->ValueAt(i),
+                       previous->LocationAt(i),
+                       slot_ix++);
+    }
+
+    // Set the locals, note that outgoing arguments are not in the environment.
+    for (intptr_t i = current->Length() - 1;
+         i >= current->fixed_parameter_count();
+         i--) {
+      builder->AddCopy(current->ValueAt(i),
+                       current->LocationAt(i),
+                       slot_ix++);
+    }
+
+    builder->AddCallerFp(slot_ix++);
+
+    // Iterate on the outer environment.
+    previous = current;
+    current = current->outer();
+  }
+  // The previous pointer is now the outermost environment.
+  ASSERT(previous != NULL);
+
+  // For the outermost environment, set caller PC.
+  builder->AddCallerPc(slot_ix++);
+
+  builder->AddPcMarker(previous->function(), slot_ix++);
+  builder->AddConstant(previous->function(), slot_ix++);
+
+
+  // For the outermost environment, set the incoming arguments.
+  for (intptr_t i = previous->fixed_parameter_count() - 1; i >= 0; i--) {
+    builder->AddCopy(previous->ValueAt(i), previous->LocationAt(i), slot_ix++);
+  }
+
+  return builder->CreateDeoptInfo(deopt_table);
+}
+
+
+void FlowGraphCompiler::RecordAfterCall(Instruction* instr) {
+  RecordSafepoint(instr->locs());
+  // Marks either the continuation point in unoptimized code or the
+  // deoptimization point in optimized code, after call.
+  const intptr_t deopt_id_after = Thread::ToDeoptAfter(instr->deopt_id());
+  if (is_optimizing()) {
+    // Return/ReturnTOS instruction drops incoming arguments so
+    // we have to drop outgoing arguments from the innermost environment.
+    // On all other architectures caller drops outgoing arguments itself
+    // hence the difference.
+    pending_deoptimization_env_->DropArguments(instr->ArgumentCount());
+    AddDeoptIndexAtCall(deopt_id_after, instr->token_pos());
+  } else {
+    // Add deoptimization continuation point after the call and before the
+    // arguments are removed.
+    // In optimized code this descriptor is needed for exception handling.
+    AddCurrentDescriptor(RawPcDescriptors::kDeopt,
+                         deopt_id_after,
+                         instr->token_pos());
+  }
 }
 
 
@@ -109,16 +221,28 @@
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(!is_optimizing());
   SubtypeTestCache& test_cache = SubtypeTestCache::Handle();
   if (!dst_type.IsVoidType() && dst_type.IsInstantiated()) {
     test_cache = SubtypeTestCache::New();
   }
 
+  if (is_optimizing()) {
+    __ Push(locs->in(0).reg());
+    __ Push(locs->in(1).reg());
+  }
   __ PushConstant(dst_type);
   __ PushConstant(dst_name);
   __ AssertAssignable(__ AddConstant(test_cache));
+  RecordSafepoint(locs);
   AddCurrentDescriptor(RawPcDescriptors::kOther, deopt_id, token_pos);
+  if (is_optimizing()) {
+    // Assert assignable keeps the instance on the stack as the result,
+    // all other arguments are popped.
+    // In optimized code we need to drop it because optimized code
+    // expects the result in the register and it is already there
+    // because locs()->in(0).reg() == locs()->out(0).reg().
+    __ Drop1();
+  }
 }
 
 
@@ -168,10 +292,21 @@
   const intptr_t context_index =
       -parsed_function().current_context_var()->index() - 1;
 
+  if (CanOptimizeFunction() &&
+      function.IsOptimizable() &&
+      (!is_optimizing() || may_reoptimize())) {
+    __ HotCheck(!is_optimizing(), GetOptimizationThreshold());
+  }
+
   if (has_optional_params) {
-    __ EntryOpt(num_fixed_params, num_opt_pos_params, num_opt_named_params);
-  } else {
+    __ EntryOptional(num_fixed_params,
+                     num_opt_pos_params,
+                     num_opt_named_params);
+  } else if (!is_optimizing()) {
     __ Entry(num_fixed_params, num_locals, context_index);
+  } else {
+    __ EntryOptimized(num_fixed_params,
+                      flow_graph_.graph_entry()->spill_slot_count());
   }
 
   if (num_opt_named_params != 0) {
@@ -212,14 +347,20 @@
   }
 
 
-  ASSERT(num_locals > 0);  // There is always at least context_var.
   if (has_optional_params) {
-    ASSERT(!is_optimizing());
-    __ Frame(num_locals);  // Reserve space for locals.
+    if (!is_optimizing()) {
+      ASSERT(num_locals > 0);  // There is always at least context_var.
+      __ Frame(num_locals);  // Reserve space for locals.
+    } else if (flow_graph_.graph_entry()->spill_slot_count() >
+                   flow_graph_.num_copied_params()) {
+      __ Frame(flow_graph_.graph_entry()->spill_slot_count() -
+          flow_graph_.num_copied_params());
+    }
   }
 
   if (function.IsClosureFunction()) {
-    Register reg = context_index;
+    Register reg = is_optimizing() ? flow_graph_.num_copied_params()
+                                   : context_index;
     Register closure_reg = reg;
     LocalScope* scope = parsed_function().node_sequence()->scope();
     LocalVariable* local = scope->VariableAt(0);
@@ -229,7 +370,7 @@
       closure_reg = -local->index() - 1;
     }
     __ LoadField(reg, closure_reg, Closure::context_offset() / kWordSize);
-  } else if (has_optional_params) {
+  } else if (has_optional_params && !is_optimizing()) {
     __ LoadConstant(context_index,
         Object::Handle(isolate()->object_store()->empty_context()));
   }
@@ -254,12 +395,48 @@
 
 
 void ParallelMoveResolver::EmitMove(int index) {
-  UNIMPLEMENTED();
+  MoveOperands* move = moves_[index];
+  const Location source = move->src();
+  const Location destination = move->dest();
+  if (source.IsStackSlot() && destination.IsRegister()) {
+    // Only allow access to the arguments.
+    ASSERT(source.base_reg() == FPREG);
+    ASSERT(source.stack_index() < 0);
+    __ Move(destination.reg(), -kParamEndSlotFromFp + source.stack_index());
+  } else if (source.IsRegister() && destination.IsRegister()) {
+    __ Move(destination.reg(), source.reg());
+  } else if (source.IsConstant() && destination.IsRegister()) {
+    __ LoadConstant(destination.reg(), source.constant());
+  } else {
+    compiler_->Bailout("Unsupported move");
+  }
+
+  move->Eliminate();
 }
 
 
 void ParallelMoveResolver::EmitSwap(int index) {
-  UNIMPLEMENTED();
+  MoveOperands* move = moves_[index];
+  const Location source = move->src();
+  const Location destination = move->dest();
+  ASSERT(source.IsRegister() && destination.IsRegister());
+  __ Swap(destination.reg(), source.reg());
+
+  // The swap of source and destination has executed a move from source to
+  // destination.
+  move->Eliminate();
+
+  // Any unperformed (including pending) move with a source of either
+  // this move's source or destination needs to have their source
+  // changed to reflect the state of affairs after the swap.
+  for (int i = 0; i < moves_.length(); ++i) {
+    const MoveOperands& other_move = *moves_[i];
+    if (other_move.Blocks(source)) {
+      moves_[i]->set_src(destination);
+    } else if (other_move.Blocks(destination)) {
+      moves_[i]->set_src(source);
+    }
+  }
 }
 
 
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index af0a03fc..d0ffe77 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -356,6 +356,8 @@
         new CheckSmiInstr(assert->value()->Copy(zone()),
                           assert->env()->deopt_id(),
                           check->token_pos());
+    check_clone->AsCheckSmi()->set_licm_hoisted(
+        check->AsCheckSmi()->licm_hoisted());
   } else {
     ASSERT(check->IsCheckClass());
     check_clone =
@@ -363,6 +365,8 @@
                             assert->env()->deopt_id(),
                             check->AsCheckClass()->unary_checks(),
                             check->token_pos());
+    check_clone->AsCheckClass()->set_licm_hoisted(
+        check->AsCheckClass()->licm_hoisted());
   }
   ASSERT(check_clone != NULL);
   ASSERT(assert->deopt_id() == assert->env()->deopt_id());
@@ -504,7 +508,7 @@
                 type_class.ToCString());
           }
           if (FLAG_use_cha_deopt) {
-            cha->AddToLeafClasses(type_class);
+            cha->AddToGuardedClasses(type_class, /*subclass_count=*/0);
           }
           cid_ = type_class.id();
         } else {
@@ -752,7 +756,8 @@
                   type_class.ToCString());
             }
             if (FLAG_use_cha_deopt) {
-              thread->cha()->AddToLeafClasses(type_class);
+              thread->cha()->AddToGuardedClasses(
+                  type_class, /*subclass_count=*/0);
             }
             cid = type_class.id();
           }
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index 2c2643e..069f341 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -4,10 +4,6 @@
 
 #include "vm/gc_marker.h"
 
-#include <map>
-#include <utility>
-#include <vector>
-
 #include "vm/allocation.h"
 #include "vm/dart_api_state.h"
 #include "vm/isolate.h"
@@ -25,64 +21,6 @@
 
 namespace dart {
 
-class DelaySet {
- private:
-  typedef std::multimap<RawObject*, RawWeakProperty*> Map;
-  typedef std::pair<RawObject*, RawWeakProperty*> MapEntry;
-
- public:
-  DelaySet() : mutex_(new Mutex()) {}
-  ~DelaySet() { delete mutex_; }
-
-  // After atomically setting the watched bit on a white key (see
-  // EnsureWatchedIfWhitewhich; this means the mark bit cannot be set
-  // without observing the watched bit), this method atomically
-  // inserts raw_weak if its key is *still* white, so that any future
-  // call to VisitValuesForKey is guaranteed to include its
-  // value. Returns true on success, and false if the key is no longer white.
-  bool InsertIfWhite(RawWeakProperty* raw_weak) {
-    MutexLocker ml(mutex_);
-    RawObject* raw_key = raw_weak->ptr()->key_;
-    if (raw_key->IsMarked()) return false;
-    // The key was white *after* acquiring the lock. Thus any future call to
-    // VisitValuesForKey is guaranteed to include the entry inserted below.
-    delay_set_.insert(std::make_pair(raw_key, raw_weak));
-    return true;
-  }
-
-  void ClearReferences() {
-    MutexLocker ml(mutex_);
-    for (Map::iterator it = delay_set_.begin(); it != delay_set_.end(); ++it) {
-      ASSERT(!it->first->IsMarked());
-      WeakProperty::Clear(it->second);
-    }
-  }
-
-  // Visit all values with a key equal to raw_obj, which must already be marked.
-  void VisitValuesForKey(RawObject* raw_obj, ObjectPointerVisitor* visitor) {
-    ASSERT(raw_obj->IsMarked());
-    // Extract the range into a temporary vector to iterate over it
-    // while delay_set_ may be modified.
-    std::vector<MapEntry> temp_copy;
-    {
-      MutexLocker ml(mutex_);
-      std::pair<Map::iterator, Map::iterator> ret =
-          delay_set_.equal_range(raw_obj);
-      temp_copy.insert(temp_copy.end(), ret.first, ret.second);
-      delay_set_.erase(ret.first, ret.second);
-    }
-    for (std::vector<MapEntry>::iterator it = temp_copy.begin();
-         it != temp_copy.end(); ++it) {
-      it->second->VisitPointers(visitor);
-    }
-  }
-
- private:
-  Map delay_set_;
-  Mutex* mutex_;
-};
-
-
 class SkippedCodeFunctions : public ZoneAllocated {
  public:
   SkippedCodeFunctions() {}
@@ -206,7 +144,6 @@
                  Heap* heap,
                  PageSpace* page_space,
                  MarkingStack* marking_stack,
-                 DelaySet* delay_set,
                  SkippedCodeFunctions* skipped_code_functions)
       : ObjectPointerVisitor(isolate),
         thread_(Thread::Current()),
@@ -216,7 +153,7 @@
         class_stats_size_(isolate->class_table()->NumCids()),
         page_space_(page_space),
         work_list_(marking_stack),
-        delay_set_(delay_set),
+        delayed_weak_properties_(NULL),
         visiting_old_object_(NULL),
         skipped_code_functions_(skipped_code_functions),
         marked_bytes_(0) {
@@ -248,15 +185,44 @@
       return false;
     }
     do {
-      VisitingOldObject(raw_obj);
-      const intptr_t class_id = raw_obj->GetClassId();
-      if (class_id != kWeakPropertyCid) {
-        marked_bytes_ += raw_obj->VisitPointers(this);
-      } else {
-        RawWeakProperty* raw_weak = reinterpret_cast<RawWeakProperty*>(raw_obj);
-        marked_bytes_ += raw_weak->Size();
-        ProcessWeakProperty(raw_weak);
+      do {
+        // First drain the marking stacks.
+        VisitingOldObject(raw_obj);
+        const intptr_t class_id = raw_obj->GetClassId();
+        if (class_id != kWeakPropertyCid) {
+          marked_bytes_ += raw_obj->VisitPointers(this);
+        } else {
+          RawWeakProperty* raw_weak =
+              reinterpret_cast<RawWeakProperty*>(raw_obj);
+          marked_bytes_ += ProcessWeakProperty(raw_weak);
+        }
+        raw_obj = work_list_.Pop();
+      } while (raw_obj != NULL);
+
+      // Marking stack is empty.
+      // Process all the pending weak properties in this visitor.
+      RawWeakProperty* cur_weak = delayed_weak_properties_;
+      delayed_weak_properties_ = NULL;
+      while (cur_weak != NULL) {
+        uword next_weak = cur_weak->ptr()->next_;
+        RawObject* raw_key = cur_weak->ptr()->key_;
+        // Reset the next pointer in the weak property.
+        cur_weak->ptr()->next_ = 0;
+        if (raw_key->IsMarked()) {
+          // The key is marked so we make sure to properly visit all pointers
+          // originating from this weak property.
+          VisitingOldObject(cur_weak);
+          cur_weak->VisitPointers(this);
+        } else {
+          // Requeue this weak property to be handled later.
+          EnqueueWeakProperty(cur_weak);
+        }
+        // Advance to next weak property in the queue.
+        cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
       }
+
+      // Check whether any further work was pushed either by other markers or
+      // by the handling of weak properties.
       raw_obj = work_list_.Pop();
     } while (raw_obj != NULL);
     VisitingOldObject(NULL);
@@ -278,47 +244,49 @@
     skipped_code_functions_->Add(func);
   }
 
-  // If unmarked, sets the watch bit and returns true.
-  // If marked, does nothing and returns false.
-  static bool EnsureWatchedIfWhite(RawObject* obj) {
-    if (!sync) {
-      if (obj->IsMarked()) return false;
-      if (!obj->IsWatched()) obj->SetWatchedBitUnsynchronized();
-      return true;
-    }
-    uword tags = obj->ptr()->tags_;
-    uword old_tags;
-    do {
-      old_tags = tags;
-      if (RawObject::MarkBit::decode(tags)) return false;
-      if (RawObject::WatchedBit::decode(tags)) return true;
-      uword new_tags = RawObject::WatchedBit::update(true, old_tags);
-      tags = AtomicOperations::CompareAndSwapWord(
-          &obj->ptr()->tags_, old_tags, new_tags);
-    } while (tags != old_tags);
-    return true;
+  void EnqueueWeakProperty(RawWeakProperty* raw_weak) {
+    ASSERT(raw_weak->IsHeapObject());
+    ASSERT(raw_weak->IsOldObject());
+    ASSERT(raw_weak->IsWeakProperty());
+    ASSERT(raw_weak->IsMarked());
+    ASSERT(raw_weak->ptr()->next_ == 0);
+    raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
+    delayed_weak_properties_ = raw_weak;
   }
 
-  void ProcessWeakProperty(RawWeakProperty* raw_weak) {
+  intptr_t ProcessWeakProperty(RawWeakProperty* raw_weak) {
     // The fate of the weak property is determined by its key.
     RawObject* raw_key = raw_weak->ptr()->key_;
     if (raw_key->IsHeapObject() &&
         raw_key->IsOldObject() &&
-        EnsureWatchedIfWhite(raw_key) &&
-        delay_set_->InsertIfWhite(raw_weak)) {
-      // Key was white.  Delayed the weak property.
-    } else {
-      // Key is gray or black.  Make the weak property black.
-      raw_weak->VisitPointers(this);
+        !raw_key->IsMarked()) {
+      // Key was white. Enqueue the weak property.
+      EnqueueWeakProperty(raw_weak);
+      return raw_weak->Size();
     }
+    // Key is gray or black. Make the weak property black.
+    return raw_weak->VisitPointers(this);
   }
 
   // Called when all marking is complete.
   void Finalize() {
     work_list_.Finalize();
+    // Detach code from functions.
     if (skipped_code_functions_ != NULL) {
       skipped_code_functions_->DetachCode();
     }
+    // Clear pending weak properties.
+    RawWeakProperty* cur_weak = delayed_weak_properties_;
+    delayed_weak_properties_ = NULL;
+    intptr_t weak_properties_cleared = 0;
+    while (cur_weak != NULL) {
+      uword next_weak = cur_weak->ptr()->next_;
+      cur_weak->ptr()->next_ = 0;
+      WeakProperty::Clear(cur_weak);
+      weak_properties_cleared++;
+      // Advance to next weak property in the queue.
+      cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+    }
   }
 
   void VisitingOldObject(RawObject* obj) {
@@ -335,15 +303,10 @@
 
     // Push the marked object on the marking stack.
     ASSERT(raw_obj->IsMarked());
-    const bool is_watched = raw_obj->IsWatched();
     // We acquired the mark bit => no other task is modifying the header.
     // TODO(koda): For concurrent mutator, this needs synchronization. Consider
     // clearing these bits already in the CAS for the mark bit.
     raw_obj->ClearRememberedBitUnsynchronized();
-    raw_obj->ClearWatchedBitUnsynchronized();
-    if (is_watched) {
-      delay_set_->VisitValuesForKey(raw_obj, this);
-    }
     work_list_.Push(raw_obj);
   }
 
@@ -430,7 +393,7 @@
   GrowableArray<intptr_t> class_stats_size_;
   PageSpace* page_space_;
   MarkerWorkList work_list_;
-  DelaySet* delay_set_;
+  RawWeakProperty* delayed_weak_properties_;
   RawObject* visiting_old_object_;
   SkippedCodeFunctions* skipped_code_functions_;
   uintptr_t marked_bytes_;
@@ -574,7 +537,6 @@
            Heap* heap,
            PageSpace* page_space,
            MarkingStack* marking_stack,
-           DelaySet* delay_set,
            ThreadBarrier* barrier,
            bool collect_code,
            intptr_t task_index,
@@ -585,7 +547,6 @@
         heap_(heap),
         page_space_(page_space),
         marking_stack_(marking_stack),
-        delay_set_(delay_set),
         barrier_(barrier),
         collect_code_(collect_code),
         task_index_(task_index),
@@ -605,7 +566,7 @@
       SkippedCodeFunctions* skipped_code_functions =
           collect_code_ ? new(zone) SkippedCodeFunctions() : NULL;
       SyncMarkingVisitor visitor(isolate_, heap_, page_space_, marking_stack_,
-                                 delay_set_, skipped_code_functions);
+                                 skipped_code_functions);
       // Phase 1: Iterate over roots and drain marking stack in tasks.
       marker_->IterateRoots(isolate_, &visitor, task_index_, num_tasks_);
       do {
@@ -653,7 +614,6 @@
   Heap* heap_;
   PageSpace* page_space_;
   MarkingStack* marking_stack_;
-  DelaySet* delay_set_;
   ThreadBarrier* barrier_;
   bool collect_code_;
   const intptr_t task_index_;
@@ -692,10 +652,10 @@
   // The API prologue/epilogue may create/destroy zones, so we must not
   // depend on zone allocations surviving beyond the epilogue callback.
   {
-    StackZone stack_zone(Thread::Current());
+    Thread* thread = Thread::Current();
+    StackZone stack_zone(thread);
     Zone* zone = stack_zone.GetZone();
     MarkingStack marking_stack;
-    DelaySet delay_set;
     marked_bytes_ = 0;
     const int num_tasks = FLAG_marker_tasks;
     if (num_tasks == 0) {
@@ -703,11 +663,14 @@
       SkippedCodeFunctions* skipped_code_functions =
           collect_code ? new(zone) SkippedCodeFunctions() : NULL;
       UnsyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
-                                &delay_set, skipped_code_functions);
+                                skipped_code_functions);
       IterateRoots(isolate, &mark, 0, 1);
       mark.DrainMarkingStack();
-      MarkingWeakVisitor mark_weak;
-      IterateWeakRoots(isolate, &mark_weak);
+      {
+        TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing");
+        MarkingWeakVisitor mark_weak;
+        IterateWeakRoots(isolate, &mark_weak);
+      }
       // All marking done; detach code, etc.
       FinalizeResultsFrom(&mark);
     } else {
@@ -720,31 +683,24 @@
       for (intptr_t i = 0; i < num_tasks; ++i) {
         MarkTask* mark_task =
             new MarkTask(this, isolate, heap_, page_space, &marking_stack,
-                         &delay_set, &barrier, collect_code,
+                         &barrier, collect_code,
                          i, num_tasks, &num_busy);
         ThreadPool* pool = Dart::thread_pool();
         pool->Run(mark_task);
       }
       barrier.Sync();
 
-      // Phase 2: Weak processing and follow-up marking on main thread.
-      SkippedCodeFunctions* skipped_code_functions =
-          collect_code ? new(zone) SkippedCodeFunctions() : NULL;
-      SyncMarkingVisitor mark(isolate, heap_, page_space, &marking_stack,
-                              &delay_set, skipped_code_functions);
-      MarkingWeakVisitor mark_weak;
-      IterateWeakRoots(isolate, &mark_weak);
+      // Phase 2: Weak processing on main thread.
+      {
+        TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing");
+        MarkingWeakVisitor mark_weak;
+        IterateWeakRoots(isolate, &mark_weak);
+      }
       barrier.Sync();
 
       // Phase 3: Finalize results from all markers (detach code, etc.).
-      if (FLAG_log_marker_tasks) {
-        THR_Print("Main thread marked %" Pd " bytes.\n",
-                  mark.marked_bytes());
-      }
-      FinalizeResultsFrom(&mark);
       barrier.Exit();
     }
-    delay_set.ClearReferences();
     ProcessWeakTables(page_space);
     ProcessObjectIdTable(isolate);
   }
diff --git a/runtime/vm/instructions_dbc.cc b/runtime/vm/instructions_dbc.cc
index ec7945f..3656722 100644
--- a/runtime/vm/instructions_dbc.cc
+++ b/runtime/vm/instructions_dbc.cc
@@ -114,9 +114,10 @@
     case Bytecode::kLoadConstant:
     case Bytecode::kPushConstant:
     case Bytecode::kStaticCall:
-    case Bytecode::kInstanceCall:
+    case Bytecode::kInstanceCall1:
     case Bytecode::kInstanceCall2:
-    case Bytecode::kInstanceCall3:
+    case Bytecode::kInstanceCall1Opt:
+    case Bytecode::kInstanceCall2Opt:
     case Bytecode::kStoreStaticTOS:
     case Bytecode::kPushStatic:
     case Bytecode::kAllocate:
@@ -165,7 +166,9 @@
 
 
 void CallPattern::InsertDeoptCallAt(uword pc, uword target_address) {
-  UNIMPLEMENTED();
+  const uint8_t argc = Bytecode::IsCallOpcode(Bytecode::At(pc)) ?
+      Bytecode::DecodeArgc(Bytecode::At(pc)) : 0;
+  *reinterpret_cast<Instr*>(pc) = Bytecode::Encode(Bytecode::kDeopt, argc, 0);
 }
 
 
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 66abf75..4704219 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -3110,6 +3110,8 @@
     }
   }
 #else
+  call_ic_data = &ICData::ZoneHandle(call_ic_data->Original());
+
   // Emit smi fast path instruction. If fast-path succeeds it skips the next
   // instruction otherwise it falls through.
   if (function_name().raw() == Symbols::Plus().raw()) {
@@ -3131,13 +3133,18 @@
   const intptr_t call_ic_data_kidx = __ AddConstant(*call_ic_data);
   switch (call_ic_data->NumArgsTested()) {
     case 1:
-      __ InstanceCall(ArgumentCount(), call_ic_data_kidx);
+      if (compiler->is_optimizing()) {
+        __ InstanceCall1Opt(ArgumentCount(), call_ic_data_kidx);
+      } else {
+        __ InstanceCall1(ArgumentCount(), call_ic_data_kidx);
+      }
       break;
     case 2:
-      __ InstanceCall2(ArgumentCount(), call_ic_data_kidx);
-      break;
-    case 3:
-      __ InstanceCall3(ArgumentCount(), call_ic_data_kidx);
+      if (compiler->is_optimizing()) {
+        __ InstanceCall2Opt(ArgumentCount(), call_ic_data_kidx);
+      } else {
+        __ InstanceCall2(ArgumentCount(), call_ic_data_kidx);
+      }
       break;
     default:
       UNIMPLEMENTED();
@@ -3146,6 +3153,11 @@
   compiler->AddCurrentDescriptor(RawPcDescriptors::kIcCall,
                                  deopt_id(),
                                  token_pos());
+  compiler->RecordAfterCall(this);
+
+  if (compiler->is_optimizing()) {
+    __ PopLocal(locs()->out(0).reg());
+  }
 #endif  // !defined(TARGET_ARCH_DBC)
 }
 
@@ -3252,6 +3264,12 @@
   compiler->AddCurrentDescriptor(RawPcDescriptors::kUnoptStaticCall,
                                  deopt_id(),
                                  token_pos());
+
+  compiler->RecordAfterCall(this);
+
+  if (compiler->is_optimizing()) {
+    __ PopLocal(locs()->out(0).reg());
+  }
 #endif  // !defined(TARGET_ARCH_DBC)
 }
 
@@ -3266,7 +3284,10 @@
   // DBC does not use LocationSummaries in the same way as other architectures.
 #if !defined(TARGET_ARCH_DBC)
   ASSERT(locs()->in(0).reg() == locs()->out(0).reg());
-#endif
+#else
+  ASSERT(!compiler->is_optimizing() ||
+         (locs()->in(0).reg() == locs()->out(0).reg()));
+#endif  // !defined(TARGET_ARCH_DBC)
 }
 
 
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index a7f3d7f..be04e5e 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -3032,7 +3032,8 @@
                 const ZoneGrowableArray<intptr_t>& cid_results,
                 intptr_t deopt_id)
       : ComparisonInstr(token_pos, kind, value, NULL, deopt_id),
-        cid_results_(cid_results) {
+        cid_results_(cid_results),
+        licm_hoisted_(false) {
     ASSERT((kind == Token::kIS) || (kind == Token::kISNOT));
     set_operation_cid(kObjectCid);
   }
@@ -3067,10 +3068,13 @@
   virtual Condition EmitComparisonCode(FlowGraphCompiler* compiler,
                                        BranchLabels labels);
 
+  void set_licm_hoisted(bool value) { licm_hoisted_ = value; }
+
   PRINT_OPERANDS_TO_SUPPORT
 
  private:
   const ZoneGrowableArray<intptr_t>& cid_results_;
+  bool licm_hoisted_;
   DISALLOW_COPY_AND_ASSIGN(TestCidsInstr);
 };
 
@@ -7788,6 +7792,7 @@
   virtual EffectSet Effects() const { return EffectSet::None(); }
   virtual bool AttributesEqual(Instruction* other) const;
 
+  bool licm_hoisted() const { return licm_hoisted_; }
   void set_licm_hoisted(bool value) { licm_hoisted_ = value; }
 
   PRINT_OPERANDS_TO_SUPPORT
@@ -7823,6 +7828,7 @@
 
   virtual bool AttributesEqual(Instruction* other) const { return true; }
 
+  bool licm_hoisted() const { return licm_hoisted_; }
   void set_licm_hoisted(bool value) { licm_hoisted_ = value; }
 
  private:
@@ -8188,6 +8194,17 @@
   // from the copy.
   Environment* DeepCopy(Zone* zone, intptr_t length) const;
 
+#if defined(TARGET_ARCH_DBC)
+  // Return/ReturnTOS instruction drops incoming arguments so
+  // we have to drop outgoing arguments from the innermost environment.
+  // On all other architectures caller drops outgoing arguments itself
+  // hence the difference.
+  // Note: this method can only be used at the code generation stage because
+  // it mutates environment in unsafe way (e.g. does not update def-use
+  // chains).
+  void DropArguments(intptr_t argc);
+#endif
+
  private:
   friend class ShallowIterator;
 
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 4123a2a..a0fa8cc 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -763,8 +763,11 @@
   const Register val_reg = locs()->in(0).reg();
   const Register cid_reg = locs()->temp(0).reg();
 
-  Label* deopt = CanDeoptimize() ?
-      compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL;
+  Label* deopt = CanDeoptimize()
+      ? compiler->AddDeoptStub(deopt_id(),
+                               ICData::kDeoptTestCids,
+                               licm_hoisted_ ? ICData::kHoisted : 0)
+      : NULL;
 
   const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
   const ZoneGrowableArray<intptr_t>& data = cid_results();
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 29eae7d..9d167dc 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -639,8 +639,11 @@
   const Register val_reg = locs()->in(0).reg();
   const Register cid_reg = locs()->temp(0).reg();
 
-  Label* deopt = CanDeoptimize() ?
-      compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL;
+  Label* deopt = CanDeoptimize()
+      ? compiler->AddDeoptStub(deopt_id(),
+                               ICData::kDeoptTestCids,
+                               licm_hoisted_ ? ICData::kHoisted : 0)
+      : NULL;
 
   const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
   const ZoneGrowableArray<intptr_t>& data = cid_results();
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index c4399e0..16a2baf 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -119,36 +119,40 @@
 
 // Location summaries actually are not used by the unoptimizing DBC compiler
 // because we don't allocate any registers.
-static LocationSummary* CreateLocationSummary(Zone* zone,
-                                              intptr_t num_inputs,
-                                              bool has_result) {
+static LocationSummary* CreateLocationSummary(
+    Zone* zone,
+    intptr_t num_inputs,
+    Location output = Location::NoLocation(),
+    LocationSummary::ContainsCall contains_call = LocationSummary::kNoCall) {
   const intptr_t kNumTemps = 0;
   LocationSummary* locs = new(zone) LocationSummary(
-      zone, num_inputs, kNumTemps, LocationSummary::kNoCall);
+      zone, num_inputs, kNumTemps, contains_call);
   for (intptr_t i = 0; i < num_inputs; i++) {
-    locs->set_in(i, Location::RequiresRegister());
+    locs->set_in(i, (contains_call == LocationSummary::kNoCall) ?
+        Location::RequiresRegister() : Location::RegisterLocation(i));
   }
-  if (has_result) {
-    locs->set_out(0, Location::RequiresRegister());
+  if (!output.IsInvalid()) {
+    // For instructions that call we default to returning result in R0.
+    locs->set_out(0, output);
   }
   return locs;
 }
 
 
-#define DEFINE_MAKE_LOCATION_SUMMARY(Name, In, Out)                            \
+#define DEFINE_MAKE_LOCATION_SUMMARY(Name, ...)                                \
   LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt)      \
       const {                                                                  \
-    return CreateLocationSummary(zone, In, Out);                               \
+    return CreateLocationSummary(zone, __VA_ARGS__);                           \
   }                                                                            \
 
-#define EMIT_NATIVE_CODE(Name, In, Out)                                        \
-  DEFINE_MAKE_LOCATION_SUMMARY(Name, In, Out);                                 \
+#define EMIT_NATIVE_CODE(Name, ...)                                            \
+  DEFINE_MAKE_LOCATION_SUMMARY(Name, __VA_ARGS__);                             \
   void Name##Instr::EmitNativeCode(FlowGraphCompiler* compiler)                \
 
 #define DEFINE_UNIMPLEMENTED_MAKE_LOCATION_SUMMARY(Name)                       \
   LocationSummary* Name##Instr::MakeLocationSummary(Zone* zone, bool opt)      \
       const {                                                                  \
-    UNIMPLEMENTED();                                                           \
+    if (!opt) UNIMPLEMENTED();                                                 \
     return NULL;                                                               \
   }                                                                            \
 
@@ -181,51 +185,63 @@
 DEFINE_UNIMPLEMENTED_EMIT_BRANCH_CODE(EqualityCompare)
 
 
-DEFINE_MAKE_LOCATION_SUMMARY(AssertAssignable, 2, true);
+DEFINE_MAKE_LOCATION_SUMMARY(AssertAssignable, 2, Location::SameAsFirstInput());
 
 
-EMIT_NATIVE_CODE(AssertBoolean, 1, true) {
+EMIT_NATIVE_CODE(AssertBoolean,
+                 1, Location::SameAsFirstInput(),
+                 LocationSummary::kCall) {
+  if (compiler->is_optimizing()) {
+    __ Push(locs()->in(0).reg());
+  }
   __ AssertBoolean(Isolate::Current()->type_checks() ? 1 : 0);
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  deopt_id(),
                                  token_pos());
+  if (compiler->is_optimizing()) {
+    __ Drop1();
+  }
 }
 
 
-LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(Zone* zone,
-                                                        bool optimizing) const {
+LocationSummary* PolymorphicInstanceCallInstr::MakeLocationSummary(
+    Zone* zone, bool optimizing) const {
   return MakeCallSummary(zone);
 }
 
 
 void PolymorphicInstanceCallInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  UNIMPLEMENTED();
+  compiler->Bailout(ToCString());
 }
 
 
-EMIT_NATIVE_CODE(CheckStackOverflow, 0, false) {
+EMIT_NATIVE_CODE(CheckStackOverflow,
+                 0, Location::NoLocation(),
+                 LocationSummary::kCall) {
   __ CheckStack();
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                                  Thread::kNoDeoptId,
                                  token_pos());
 }
 
 
-EMIT_NATIVE_CODE(PushArgument, 1, false) {
+EMIT_NATIVE_CODE(PushArgument, 1) {
   if (compiler->is_optimizing()) {
     __ Push(locs()->in(0).reg());
   }
 }
 
 
-EMIT_NATIVE_CODE(LoadLocal, 0, false) {
+EMIT_NATIVE_CODE(LoadLocal, 0) {
   ASSERT(!compiler->is_optimizing());
   ASSERT(local().index() != 0);
   __ Push((local().index() > 0) ? (-local().index()) : (-local().index() - 1));
 }
 
 
-EMIT_NATIVE_CODE(StoreLocal, 0, false) {
+EMIT_NATIVE_CODE(StoreLocal, 0) {
   ASSERT(!compiler->is_optimizing());
   ASSERT(local().index() != 0);
   if (HasTemp()) {
@@ -238,7 +254,7 @@
 }
 
 
-EMIT_NATIVE_CODE(LoadClassId, 1, true) {
+EMIT_NATIVE_CODE(LoadClassId, 1, Location::RequiresRegister()) {
   if (compiler->is_optimizing()) {
     __ LoadClassId(locs()->out(0).reg(), locs()->in(0).reg());
   } else {
@@ -247,40 +263,80 @@
 }
 
 
-EMIT_NATIVE_CODE(Constant, 0, true) {
-  const intptr_t kidx = __ AddConstant(value());
+EMIT_NATIVE_CODE(Constant, 0, Location::RequiresRegister()) {
   if (compiler->is_optimizing()) {
-    __ LoadConstant(locs()->out(0).reg(), kidx);
+    __ LoadConstant(locs()->out(0).reg(), value());
   } else {
-    __ PushConstant(kidx);
+    __ PushConstant(value());
   }
 }
 
 
-EMIT_NATIVE_CODE(Return, 1, false) {
-  __ ReturnTOS();
+EMIT_NATIVE_CODE(Return, 1) {
+  if (compiler->is_optimizing()) {
+    __ Return(locs()->in(0).reg());
+  } else {
+    __ ReturnTOS();
+  }
 }
 
 
-EMIT_NATIVE_CODE(StoreStaticField, 1, false) {
-  const intptr_t kidx = __ AddConstant(field());
-  __ StoreStaticTOS(kidx);
+LocationSummary* StoreStaticFieldInstr::MakeLocationSummary(
+    Zone* zone, bool opt) const {
+  const intptr_t kNumInputs = 1;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* locs = new(zone) LocationSummary(
+      zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  for (intptr_t i = 0; i < kNumInputs; i++) {
+    locs->set_in(i, Location::RequiresRegister());
+  }
+  for (intptr_t i = 0; i < kNumTemps; i++) {
+    locs->set_temp(i, Location::RequiresRegister());
+  }
+  return locs;
 }
 
 
-EMIT_NATIVE_CODE(LoadStaticField, 1, true) {
-  const intptr_t kidx = __ AddConstant(StaticField());
-  __ PushStatic(kidx);
+void StoreStaticFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (compiler->is_optimizing()) {
+    __ LoadConstant(locs()->temp(0).reg(),
+                    Field::ZoneHandle(field().Original()));
+    __ StoreField(locs()->temp(0).reg(),
+                  Field::static_value_offset() / kWordSize,
+                  locs()->in(0).reg());
+  } else {
+    const intptr_t kidx = __ AddConstant(field());
+    __ StoreStaticTOS(kidx);
+  }
 }
 
 
-EMIT_NATIVE_CODE(InitStaticField, 0, false) {
+EMIT_NATIVE_CODE(LoadStaticField, 1, Location::RequiresRegister()) {
+  if (compiler->is_optimizing()) {
+    __ LoadField(locs()->out(0).reg(),
+                 locs()->in(0).reg(),
+                 Field::static_value_offset() / kWordSize);
+  } else {
+    const intptr_t kidx = __ AddConstant(StaticField());
+    __ PushStatic(kidx);
+  }
+}
+
+
+EMIT_NATIVE_CODE(InitStaticField, 0) {
   ASSERT(!compiler->is_optimizing());
   __ InitStaticTOS();
 }
 
 
-EMIT_NATIVE_CODE(ClosureCall, 0, false) {
+EMIT_NATIVE_CODE(ClosureCall,
+                 1,
+                 Location::RegisterLocation(0),
+                 LocationSummary::kCall) {
+  if (compiler->is_optimizing()) {
+    __ Push(locs()->in(0).reg());
+  }
+
   intptr_t argument_count = ArgumentCount();
   const Array& arguments_descriptor =
       Array::ZoneHandle(ArgumentsDescriptor::New(argument_count,
@@ -288,20 +344,11 @@
   const intptr_t argdesc_kidx =
       compiler->assembler()->AddConstant(arguments_descriptor);
   __ StaticCall(argument_count, argdesc_kidx);
+  compiler->RecordAfterCall(this);
 
-  compiler->RecordSafepoint(locs());
-  // Marks either the continuation point in unoptimized code or the
-  // deoptimization point in optimized code, after call.
-  const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id());
   if (compiler->is_optimizing()) {
-    compiler->AddDeoptIndexAtCall(deopt_id_after, token_pos());
+    __ PopLocal(locs()->out(0).reg());
   }
-  // Add deoptimization continuation point after the call and before the
-  // arguments are removed.
-  // In optimized code this descriptor is needed for exception handling.
-  compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
-                                 deopt_id_after,
-                                 token_pos());
 }
 
 
@@ -327,18 +374,39 @@
                                                  BranchLabels labels) {
   ASSERT((kind() == Token::kNE_STRICT) ||
          (kind() == Token::kEQ_STRICT));
-  const Bytecode::Opcode eq_op = needs_number_check() ?
-      Bytecode::kIfEqStrictNumTOS : Bytecode::kIfEqStrictTOS;
-  const Bytecode::Opcode ne_op = needs_number_check() ?
-      Bytecode::kIfNeStrictNumTOS : Bytecode::kIfNeStrictTOS;
 
-  if (kind() == Token::kEQ_STRICT) {
-    __ Emit((labels.fall_through == labels.false_label) ? eq_op : ne_op);
+  if (!compiler->is_optimizing()) {
+    const Bytecode::Opcode eq_op = needs_number_check() ?
+        Bytecode::kIfEqStrictNumTOS : Bytecode::kIfEqStrictTOS;
+    const Bytecode::Opcode ne_op = needs_number_check() ?
+        Bytecode::kIfNeStrictNumTOS : Bytecode::kIfNeStrictTOS;
+
+    if (kind() == Token::kEQ_STRICT) {
+      __ Emit((labels.fall_through == labels.false_label) ? eq_op : ne_op);
+    } else {
+      __ Emit((labels.fall_through == labels.false_label) ? ne_op : eq_op);
+    }
   } else {
-    __ Emit((labels.fall_through == labels.false_label) ? ne_op : eq_op);
+    const Bytecode::Opcode eq_op = needs_number_check() ?
+        Bytecode::kIfEqStrictNum : Bytecode::kIfEqStrict;
+    const Bytecode::Opcode ne_op = needs_number_check() ?
+        Bytecode::kIfNeStrictNum : Bytecode::kIfNeStrict;
+
+    if (kind() == Token::kEQ_STRICT) {
+      __ Emit(Bytecode::Encode(
+          (labels.fall_through == labels.false_label) ? eq_op : ne_op,
+          locs()->in(0).reg(),
+          locs()->in(1).reg()));
+    } else {
+      __ Emit(Bytecode::Encode(
+          (labels.fall_through == labels.false_label) ? ne_op : eq_op,
+          locs()->in(0).reg(),
+          locs()->in(1).reg()));
+    }
   }
 
   if (needs_number_check() && token_pos().IsReal()) {
+    compiler->RecordSafepoint(locs());
     compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                                    Thread::kNoDeoptId,
                                    token_pos());
@@ -358,7 +426,11 @@
 }
 
 
-EMIT_NATIVE_CODE(StrictCompare, 2, true) {
+EMIT_NATIVE_CODE(StrictCompare,
+                 2,
+                 Location::RequiresRegister(),
+                 needs_number_check() ? LocationSummary::kCall
+                                      : LocationSummary::kNoCall) {
   ASSERT((kind() == Token::kEQ_STRICT) ||
          (kind() == Token::kNE_STRICT));
 
@@ -367,18 +439,31 @@
   Condition true_condition = EmitComparisonCode(compiler, labels);
   EmitBranchOnCondition(compiler, true_condition, labels);
   Label done;
-  __ Bind(&is_false);
-  __ PushConstant(Bool::False());
-  __ Jump(&done);
-  __ Bind(&is_true);
-  __ PushConstant(Bool::True());
-  __ Bind(&done);
+  if (compiler->is_optimizing()) {
+    const Register result = locs()->out(0).reg();
+    __ Bind(&is_false);
+    __ LoadConstant(result, Bool::False());
+    __ Jump(&done);
+    __ Bind(&is_true);
+    __ LoadConstant(result, Bool::True());
+    __ Bind(&done);
+  } else {
+    __ Bind(&is_false);
+    __ PushConstant(Bool::False());
+    __ Jump(&done);
+    __ Bind(&is_true);
+    __ PushConstant(Bool::True());
+    __ Bind(&done);
+  }
 }
 
 
 LocationSummary* BranchInstr::MakeLocationSummary(Zone* zone,
                                                   bool opt) const {
   comparison()->InitializeLocationSummary(zone, opt);
+  if (!comparison()->HasLocs()) {
+    return NULL;
+  }
   // Branches don't produce a result.
   comparison()->locs()->set_out(0, Location::NoLocation());
   return comparison()->locs();
@@ -390,7 +475,7 @@
 }
 
 
-EMIT_NATIVE_CODE(Goto, 0, false) {
+EMIT_NATIVE_CODE(Goto, 0) {
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
   }
@@ -402,28 +487,60 @@
 }
 
 
-EMIT_NATIVE_CODE(CreateArray, 2, true) {
+EMIT_NATIVE_CODE(CreateArray,
+                 2, Location::RequiresRegister(),
+                 LocationSummary::kCall) {
+  if (compiler->is_optimizing()) {
+    __ Push(locs()->in(0).reg());
+    __ Push(locs()->in(1).reg());
+  }
   __ CreateArrayTOS();
+  compiler->RecordSafepoint(locs());
+  if (compiler->is_optimizing()) {
+    __ PopLocal(locs()->out(0).reg());
+  }
 }
 
 
-EMIT_NATIVE_CODE(StoreIndexed, 3, false) {
-  ASSERT(class_id() == kArrayCid);
-  __ StoreIndexedTOS();
+EMIT_NATIVE_CODE(StoreIndexed, 3) {
+  if (compiler->is_optimizing()) {
+    if (class_id() != kArrayCid) {
+      compiler->Bailout(ToCString());
+    }
+
+    __ StoreIndexed(locs()->in(kArrayPos).reg(),
+                    locs()->in(kIndexPos).reg(),
+                    locs()->in(kValuePos).reg());
+  } else {
+    ASSERT(class_id() == kArrayCid);
+    __ StoreIndexedTOS();
+  }
 }
 
 
-EMIT_NATIVE_CODE(StringInterpolate, 0, false) {
+EMIT_NATIVE_CODE(StringInterpolate,
+                 1, Location::RegisterLocation(0),
+                 LocationSummary::kCall) {
+  if (compiler->is_optimizing()) {
+    __ Push(locs()->in(0).reg());
+  }
   const intptr_t kArgumentCount = 1;
   const Array& arguments_descriptor = Array::Handle(
       ArgumentsDescriptor::New(kArgumentCount, Object::null_array()));
   __ PushConstant(CallFunction());
   const intptr_t argdesc_kidx = __ AddConstant(arguments_descriptor);
   __ StaticCall(kArgumentCount, argdesc_kidx);
+  compiler->RecordAfterCall(this);
+
+  if (compiler->is_optimizing()) {
+    __ PopLocal(locs()->out(0).reg());
+  }
 }
 
 
-EMIT_NATIVE_CODE(NativeCall, 0, false) {
+EMIT_NATIVE_CODE(NativeCall,
+                 0, Location::NoLocation(),
+                 LocationSummary::kCall) {
   SetupNative();
 
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
@@ -441,13 +558,16 @@
   } else {
     __ NativeCall();
   }
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  Thread::kNoDeoptId,
                                  token_pos());
 }
 
 
-EMIT_NATIVE_CODE(AllocateObject, 0, true) {
+EMIT_NATIVE_CODE(AllocateObject,
+                 0, Location::RequiresRegister(),
+                 LocationSummary::kCall) {
   if (ArgumentCount() == 1) {
     __ PushConstant(cls());
     __ AllocateT();
@@ -461,10 +581,14 @@
                                    Thread::kNoDeoptId,
                                    token_pos());
   }
+  compiler->RecordSafepoint(locs());
+  if (compiler->is_optimizing()) {
+    __ PopLocal(locs()->out(0).reg());
+  }
 }
 
 
-EMIT_NATIVE_CODE(StoreInstanceField, 2, false) {
+EMIT_NATIVE_CODE(StoreInstanceField, 2) {
   ASSERT(!HasTemp());
   ASSERT(offset_in_bytes() % kWordSize == 0);
   if (compiler->is_optimizing()) {
@@ -477,34 +601,52 @@
 }
 
 
-EMIT_NATIVE_CODE(LoadField, 1, true) {
+EMIT_NATIVE_CODE(LoadField, 1, Location::RequiresRegister()) {
   ASSERT(offset_in_bytes() % kWordSize == 0);
-  __ LoadFieldTOS(offset_in_bytes() / kWordSize);
+  if (compiler->is_optimizing()) {
+    const Register result = locs()->out(0).reg();
+    const Register instance = locs()->in(0).reg();
+    __ LoadField(result, instance, offset_in_bytes() / kWordSize);
+  } else {
+    __ LoadFieldTOS(offset_in_bytes() / kWordSize);
+  }
 }
 
 
-EMIT_NATIVE_CODE(BooleanNegate, 1, true) {
-  __ BooleanNegateTOS();
+EMIT_NATIVE_CODE(BooleanNegate, 1, Location::RequiresRegister()) {
+  if (compiler->is_optimizing()) {
+    __ BooleanNegate(locs()->out(0).reg(), locs()->in(0).reg());
+  } else {
+    __ BooleanNegateTOS();
+  }
 }
 
 
-EMIT_NATIVE_CODE(AllocateContext, 0, false) {
+EMIT_NATIVE_CODE(AllocateContext,
+                 0, Location::RequiresRegister(),
+                 LocationSummary::kCall) {
+  ASSERT(!compiler->is_optimizing());
   __ AllocateContext(num_context_variables());
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  Thread::kNoDeoptId,
                                  token_pos());
 }
 
 
-EMIT_NATIVE_CODE(CloneContext, 0, false) {
+EMIT_NATIVE_CODE(CloneContext,
+                 1, Location::RequiresRegister(),
+                 LocationSummary::kCall) {
+  ASSERT(!compiler->is_optimizing());
   __ CloneContext();
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  Thread::kNoDeoptId,
                                  token_pos());
 }
 
 
-EMIT_NATIVE_CODE(CatchBlockEntry, 0, false) {
+EMIT_NATIVE_CODE(CatchBlockEntry, 0) {
   __ Bind(compiler->GetJumpLabel(this));
   compiler->AddExceptionHandler(catch_try_index(),
                                 try_index(),
@@ -519,8 +661,9 @@
 }
 
 
-EMIT_NATIVE_CODE(Throw, 0, false) {
+EMIT_NATIVE_CODE(Throw, 0, Location::NoLocation(), LocationSummary::kCall) {
   __ Throw(0);
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  deopt_id(),
                                  token_pos());
@@ -528,29 +671,48 @@
 }
 
 
-EMIT_NATIVE_CODE(ReThrow, 0, false) {
+EMIT_NATIVE_CODE(ReThrow, 0, Location::NoLocation(), LocationSummary::kCall) {
   compiler->SetNeedsStacktrace(catch_try_index());
   __ Throw(1);
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  deopt_id(),
                                  token_pos());
   __ Trap();
 }
 
-EMIT_NATIVE_CODE(InstantiateType, 1, true) {
+EMIT_NATIVE_CODE(InstantiateType,
+                 1, Location::RequiresRegister(),
+                 LocationSummary::kCall) {
+  if (compiler->is_optimizing()) {
+    __ Push(locs()->in(0).reg());
+  }
   __ InstantiateType(__ AddConstant(type()));
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  deopt_id(),
                                  token_pos());
+  if (compiler->is_optimizing()) {
+    __ PopLocal(locs()->out(0).reg());
+  }
 }
 
-EMIT_NATIVE_CODE(InstantiateTypeArguments, 1, true) {
+EMIT_NATIVE_CODE(InstantiateTypeArguments,
+                 1, Location::RequiresRegister(),
+                 LocationSummary::kCall) {
+  if (compiler->is_optimizing()) {
+    __ Push(locs()->in(0).reg());
+  }
   __ InstantiateTypeArgumentsTOS(
       type_arguments().IsRawInstantiatedRaw(type_arguments().Length()),
       __ AddConstant(type_arguments()));
+  compiler->RecordSafepoint(locs());
   compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
                                  deopt_id(),
                                  token_pos());
+  if (compiler->is_optimizing()) {
+    __ PopLocal(locs()->out(0).reg());
+  }
 }
 
 
@@ -570,7 +732,9 @@
 LocationSummary* Instruction::MakeCallSummary(Zone* zone) {
   LocationSummary* result = new(zone) LocationSummary(
       zone, 0, 0, LocationSummary::kCall);
-  result->set_out(0, Location::RequiresRegister());
+  // TODO(vegorov) support allocating out registers for calls.
+  // Currently we require them to be fixed.
+  result->set_out(0, Location::RegisterLocation(0));
   return result;
 }
 
@@ -624,6 +788,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return CompileType::FromCid(kSmiCid);
 
     case kTypedDataInt32ArrayCid:
@@ -650,6 +816,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return kTagged;
     case kTypedDataInt32ArrayCid:
       return kUnboxedInt32;
@@ -680,6 +848,9 @@
   switch (class_id_) {
     case kArrayCid:
     case kOneByteStringCid:
+    case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
     case kTypedDataInt8ArrayCid:
     case kTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ArrayCid:
@@ -707,6 +878,23 @@
   }
 }
 
+
+void Environment::DropArguments(intptr_t argc) {
+#if defined(DEBUG)
+    // Check that we are in the backend - register allocation has been run.
+    ASSERT(locations_ != NULL);
+
+    // Check that we are only dropping PushArgument instructions from the
+    // environment.
+    ASSERT(argc <= values_.length());
+    for (intptr_t i = 0; i < argc; i++) {
+      ASSERT(values_[values_.length() - i - 1]->definition()->IsPushArgument());
+    }
+#endif
+    values_.TruncateTo(values_.length() - argc);
+}
+
+
 }  // namespace dart
 
 #endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 5a7d5ce..aa3c355 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -658,8 +658,11 @@
   Register val_reg = locs()->in(0).reg();
   Register cid_reg = locs()->temp(0).reg();
 
-  Label* deopt = CanDeoptimize() ?
-      compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL;
+  Label* deopt = CanDeoptimize()
+      ? compiler->AddDeoptStub(deopt_id(),
+                               ICData::kDeoptTestCids,
+                               licm_hoisted_ ? ICData::kHoisted : 0)
+      : NULL;
 
   const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
   const ZoneGrowableArray<intptr_t>& data = cid_results();
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index b1b078f..6b9100b 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -832,8 +832,11 @@
   Register val_reg = locs()->in(0).reg();
   Register cid_reg = locs()->temp(0).reg();
 
-  Label* deopt = CanDeoptimize() ?
-      compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL;
+  Label* deopt = CanDeoptimize()
+      ? compiler->AddDeoptStub(deopt_id(),
+                               ICData::kDeoptTestCids,
+                               licm_hoisted_ ? ICData::kHoisted : 0)
+      : NULL;
 
   const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
   const ZoneGrowableArray<intptr_t>& data = cid_results();
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 28159ed..2b71a16 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -637,8 +637,11 @@
   Register val_reg = locs()->in(0).reg();
   Register cid_reg = locs()->temp(0).reg();
 
-  Label* deopt = CanDeoptimize() ?
-      compiler->AddDeoptStub(deopt_id(), ICData::kDeoptTestCids) : NULL;
+  Label* deopt = CanDeoptimize()
+      ? compiler->AddDeoptStub(deopt_id(),
+                               ICData::kDeoptTestCids,
+                               licm_hoisted_ ? ICData::kHoisted : 0)
+      : NULL;
 
   const intptr_t true_result = (kind() == Token::kIS) ? 1 : 0;
   const ZoneGrowableArray<intptr_t>& data = cid_results();
@@ -5183,6 +5186,8 @@
       (recognized_kind() == MethodRecognizer::kMathDoublePow) ? 3 : 1;
   LocationSummary* result = new(zone) LocationSummary(
       zone, InputCount(), kNumTemps, LocationSummary::kCall);
+  ASSERT(R13 != CALLEE_SAVED_TEMP);
+  ASSERT(((1 << R13) & CallingConventions::kCalleeSaveCpuRegisters) != 0);
   result->set_temp(0, Location::RegisterLocation(R13));
   result->set_in(0, Location::FpuRegisterLocation(XMM2));
   if (InputCount() == 2) {
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 119fd7a..e17abcb 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -33,7 +33,16 @@
 intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
 
 
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
+}
+
+
 void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+
   // Save LR by moving it to a callee saved temporary register.
   assembler->Comment("IntrinsicCallPrologue");
   assembler->mov(CALLEE_SAVED_TEMP, Operand(LR));
diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc
index 0ca8c25..fbaa1677 100644
--- a/runtime/vm/intrinsifier_arm64.cc
+++ b/runtime/vm/intrinsifier_arm64.cc
@@ -32,17 +32,31 @@
 intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
 
 
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
+}
+
+
 void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP2));
+  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+  ASSERT(CALLEE_SAVED_TEMP2 != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP2 != ARGS_DESC_REG);
+
   assembler->Comment("IntrinsicCallPrologue");
   assembler->mov(CALLEE_SAVED_TEMP, LR);
-  assembler->mov(CALLEE_SAVED_TEMP2, R4);
+  assembler->mov(CALLEE_SAVED_TEMP2, ARGS_DESC_REG);
 }
 
 
 void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
   assembler->Comment("IntrinsicCallEpilogue");
   assembler->mov(LR, CALLEE_SAVED_TEMP);
-  assembler->mov(R4, CALLEE_SAVED_TEMP2);
+  assembler->mov(ARGS_DESC_REG, CALLEE_SAVED_TEMP2);
 }
 
 
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index 576c6a0..130b5d6 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -41,16 +41,16 @@
 
 
 void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  COMPILE_ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+
   assembler->Comment("IntrinsicCallPrologue");
-  assembler->movl(CALLEE_SAVED_TEMP, ICREG);
-  assembler->movl(CALLEE_SAVED_TEMP2, ARGS_DESC_REG);
+  assembler->movl(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
 }
 
 
 void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
   assembler->Comment("IntrinsicCallEpilogue");
-  assembler->movl(ICREG, CALLEE_SAVED_TEMP);
-  assembler->movl(ARGS_DESC_REG, CALLEE_SAVED_TEMP2);
+  assembler->movl(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
 }
 
 
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index ea2183c..d8da470 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -32,15 +32,25 @@
 intptr_t Intrinsifier::ParameterSlotFromSp() { return -1; }
 
 
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & kAbiPreservedCpuRegs) != 0;
+}
+
 void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+
   assembler->Comment("IntrinsicCallPrologue");
-  assembler->mov(CALLEE_SAVED_TEMP, RA);
+  assembler->mov(CALLEE_SAVED_TEMP, LRREG);
 }
 
 
 void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
   assembler->Comment("IntrinsicCallEpilogue");
-  assembler->mov(RA, CALLEE_SAVED_TEMP);
+  assembler->mov(LRREG, CALLEE_SAVED_TEMP);
 }
 
 
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index 58f096d..5ac5d39 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -32,15 +32,26 @@
 intptr_t Intrinsifier::ParameterSlotFromSp() { return 0; }
 
 
+static bool IsABIPreservedRegister(Register reg) {
+  return ((1 << reg) & CallingConventions::kCalleeSaveCpuRegisters) != 0;
+}
+
+
 void Intrinsifier::IntrinsicCallPrologue(Assembler* assembler) {
+  ASSERT(IsABIPreservedRegister(CODE_REG));
+  ASSERT(!IsABIPreservedRegister(ARGS_DESC_REG));
+  ASSERT(IsABIPreservedRegister(CALLEE_SAVED_TEMP));
+  ASSERT(CALLEE_SAVED_TEMP != CODE_REG);
+  ASSERT(CALLEE_SAVED_TEMP != ARGS_DESC_REG);
+
   assembler->Comment("IntrinsicCallPrologue");
-  assembler->movq(CALLEE_SAVED_TEMP, R10);
+  assembler->movq(CALLEE_SAVED_TEMP, ARGS_DESC_REG);
 }
 
 
 void Intrinsifier::IntrinsicCallEpilogue(Assembler* assembler) {
   assembler->Comment("IntrinsicCallEpilogue");
-  assembler->movq(R10, CALLEE_SAVED_TEMP);
+  assembler->movq(ARGS_DESC_REG, CALLEE_SAVED_TEMP);
 }
 
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 11f5536..b184f6c 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -822,12 +822,10 @@
       all_classes_finalized_(false),
       next_(NULL),
       pause_loop_monitor_(NULL),
-      field_invalidation_gen_(kInvalidGen),
       loading_invalidation_gen_(kInvalidGen),
       top_level_parsing_count_(0),
       field_list_mutex_(new Mutex()),
       boxed_field_list_(GrowableObjectArray::null()),
-      disabling_field_list_(GrowableObjectArray::null()),
       spawn_count_monitor_(new Monitor()),
       spawn_count_(0),
       has_attempted_reload_(false),
@@ -1610,9 +1608,11 @@
   FinalizeWeakPersistentHandlesVisitor visitor;
   api_state()->weak_persistent_handles().VisitHandles(&visitor);
 
+  if (FLAG_dump_megamorphic_stats) {
+    MegamorphicCacheTable::PrintSizes(this);
+  }
   if (FLAG_trace_isolates) {
     heap()->PrintSizes();
-    MegamorphicCacheTable::PrintSizes(this);
     Symbols::DumpStats();
     OS::Print("[-] Stopping isolate:\n"
               "\tisolate:    %s\n", name());
@@ -1766,12 +1766,6 @@
   // when at safepoint or the field_list_mutex_ lock has been taken.
   visitor->VisitPointer(reinterpret_cast<RawObject**>(&boxed_field_list_));
 
-  // Visit the disabling_field_list.
-  // 'disabling_field_list_' access via mutator and background compilation
-  // threads is guarded with a monitor. This means that we can visit it only
-  // when at safepoint or the field_list_mutex_ lock has been taken.
-  visitor->VisitPointer(reinterpret_cast<RawObject**>(&disabling_field_list_));
-
   // Visit objects in the debugger.
   if (FLAG_support_debugger) {
     debugger()->VisitObjectPointers(visitor);
@@ -2020,50 +2014,6 @@
 }
 
 
-// Used by mutator thread to notify background compiler which fields
-// triggered code invalidation.
-void Isolate::AddDisablingField(const Field& field) {
-  ASSERT(Thread::Current()->IsMutatorThread());
-  SafepointMutexLocker ml(field_list_mutex_);
-  if (disabling_field_list_ == GrowableObjectArray::null()) {
-    disabling_field_list_ = GrowableObjectArray::New(Heap::kOld);
-  }
-  const GrowableObjectArray& array =
-      GrowableObjectArray::Handle(disabling_field_list_);
-  array.Add(field, Heap::kOld);
-}
-
-
-RawField* Isolate::GetDisablingField() {
-  ASSERT(Compiler::IsBackgroundCompilation() &&
-         (!Isolate::Current()->HasMutatorThread() ||
-         Isolate::Current()->mutator_thread()->IsAtSafepoint()));
-  ASSERT(Thread::Current()->IsAtSafepoint());
-  if (disabling_field_list_ == GrowableObjectArray::null()) {
-    return Field::null();
-  }
-  const GrowableObjectArray& array =
-      GrowableObjectArray::Handle(disabling_field_list_);
-  if (array.Length() == 0) {
-    return Field::null();
-  }
-  return Field::RawCast(array.RemoveLast());
-}
-
-
-void Isolate::ClearDisablingFieldList() {
-  MutexLocker ml(field_list_mutex_);
-  if (disabling_field_list_ == GrowableObjectArray::null()) {
-    return;
-  }
-  const GrowableObjectArray& array =
-      GrowableObjectArray::Handle(disabling_field_list_);
-  if (array.Length() > 0) {
-    array.SetLength(0);
-  }
-}
-
-
 void Isolate::AddDeoptimizingBoxedField(const Field& field) {
   ASSERT(Compiler::IsBackgroundCompilation());
   ASSERT(field.IsOriginal());
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index b418fd6..5c219cc 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -560,14 +560,6 @@
 
   static const intptr_t kInvalidGen = 0;
 
-  void IncrFieldInvalidationGen() {
-    AtomicOperations::IncrementBy(&field_invalidation_gen_, 1);
-    if (field_invalidation_gen_ == kInvalidGen) {
-      AtomicOperations::IncrementBy(&field_invalidation_gen_, 1);
-    }
-  }
-  intptr_t field_invalidation_gen() const { return field_invalidation_gen_; }
-
   void IncrLoadingInvalidationGen() {
     AtomicOperations::IncrementBy(&loading_invalidation_gen_, 1);
     if (loading_invalidation_gen_ == kInvalidGen) {
@@ -578,14 +570,6 @@
     return AtomicOperations::LoadRelaxedIntPtr(&loading_invalidation_gen_);
   }
 
-  // Used by mutator thread to notify background compiler which fields
-  // triggered code invalidation.
-  void AddDisablingField(const Field& field);
-  // Returns Field::null() if none available in the list. Can be called
-  // only from background compiler and while mutator thread is at safepoint.
-  RawField* GetDisablingField();
-  void ClearDisablingFieldList();
-
   // Used by background compiler which field became boxed and must trigger
   // deoptimization in the mutator thread.
   void AddDeoptimizingBoxedField(const Field& field);
@@ -805,17 +789,13 @@
   // Invalidation generations; used to track events occuring in parallel
   // to background compilation. The counters may overflow, which is OK
   // since we check for equality to detect if an event occured.
-  intptr_t field_invalidation_gen_;
   intptr_t loading_invalidation_gen_;
   intptr_t top_level_parsing_count_;
 
-  // Protect access to boxed_field_list_ and disabling_field_list_.
+  // Protect access to boxed_field_list_.
   Mutex* field_list_mutex_;
   // List of fields that became boxed and that trigger deoptimization.
   RawGrowableObjectArray* boxed_field_list_;
-  // List of fields that were disabling code while background compiler
-  // was running.
-  RawGrowableObjectArray* disabling_field_list_;
 
   // This guards spawn_count_. An isolate cannot complete shutdown and be
   // destroyed while there are child isolates in the midst of a spawn.
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index f4d8757..f05813d 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -2391,7 +2391,7 @@
             type_class.ToCString());
       }
       if (FLAG_use_cha_deopt) {
-        thread()->cha()->AddToLeafClasses(type_class);
+        thread()->cha()->AddToGuardedClasses(type_class, /*subclass_count=*/0);
       }
     } else {
       return false;
@@ -2917,9 +2917,10 @@
     // usage count of at least 1/kGetterSetterRatio of the getter usage count.
     // This is to avoid unboxing fields where the setter is never or rarely
     // executed.
-    const Field& field = Field::ZoneHandle(Z, instr->field().Original());
+    const Field& field = instr->field();
     const String& field_name = String::Handle(Z, field.name());
-    const Class& owner = Class::Handle(Z, field.Owner());
+    const Class& owner =
+        Class::Handle(Z, Field::Handle(Z, field.Original()).Owner());
     const Function& getter =
         Function::Handle(Z, owner.LookupGetterFunction(field_name));
     const Function& setter =
@@ -2954,6 +2955,7 @@
           OS::Print("  getter usage count: %" Pd "\n", getter.usage_counter());
         }
       }
+      ASSERT(field.IsOriginal());
       field.set_is_unboxing_candidate(false);
       field.DeoptimizeDependentCode();
     } else {
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 3a55d5a..9b80f80 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -91,14 +91,64 @@
   const GrowableObjectArray& table = GrowableObjectArray::Handle(
       isolate->object_store()->megamorphic_cache_table());
   if (table.IsNull()) return;
+  intptr_t max_size = 0;
   for (intptr_t i = 0; i < table.Length(); i++) {
     cache ^= table.At(i);
     buckets = cache.buckets();
     size += MegamorphicCache::InstanceSize();
     size += Array::InstanceSize(buckets.Length());
+    if (buckets.Length() > max_size) {
+      max_size = buckets.Length();
+    }
   }
   OS::Print("%" Pd " megamorphic caches using %" Pd "KB.\n",
             table.Length(), size / 1024);
+
+  intptr_t* probe_counts = new intptr_t[max_size];
+  intptr_t entry_count = 0;
+  intptr_t max_probe_count = 0;
+  for (intptr_t i = 0; i < max_size; i++) {
+    probe_counts[i] = 0;
+  }
+  for (intptr_t i = 0; i < table.Length(); i++) {
+    cache ^= table.At(i);
+    buckets = cache.buckets();
+    intptr_t mask = cache.mask();
+    intptr_t capacity = mask + 1;
+    for (intptr_t j = 0; j < capacity; j++) {
+      intptr_t class_id =
+          Smi::Value(Smi::RawCast(cache.GetClassId(buckets, j)));
+      if (class_id != kIllegalCid) {
+        intptr_t probe_count = 0;
+        intptr_t probe_index =
+            (class_id * MegamorphicCache::kSpreadFactor) & mask;
+        intptr_t probe_cid;
+        while (true) {
+          probe_count++;
+          probe_cid =
+              Smi::Value(Smi::RawCast(cache.GetClassId(buckets, probe_index)));
+          if (probe_cid == class_id) {
+            break;
+          }
+          probe_index = (probe_index + 1) & mask;
+        }
+        probe_counts[probe_count]++;
+        if (probe_count > max_probe_count) {
+          max_probe_count = probe_count;
+        }
+        entry_count++;
+      }
+    }
+  }
+  intptr_t cumulative_entries = 0;
+  for (intptr_t i = 0; i <= max_probe_count; i++) {
+    cumulative_entries += probe_counts[i];
+    OS::Print("Megamorphic probe %" Pd ": %" Pd " (%lf)\n",
+              i, probe_counts[i],
+              static_cast<double>(cumulative_entries) /
+              static_cast<double>(entry_count));
+  }
+  delete probe_counts;
 }
 
 }  // namespace dart
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index a8ccce5..2230804 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -165,7 +165,7 @@
 RawClass* Object::unwind_error_class_ = reinterpret_cast<RawClass*>(RAW_NULL);
 
 
-const double MegamorphicCache::kLoadFactor = 0.75;
+const double MegamorphicCache::kLoadFactor = 0.50;
 
 
 static void AppendSubString(Zone* zone,
@@ -2753,8 +2753,6 @@
     }
   }
 
-  virtual void IncrementInvalidationGen() {}
-
  private:
   const Class& cls_;
   DISALLOW_COPY_AND_ASSIGN(CHACodeArray);
@@ -7684,10 +7682,6 @@
     }
   }
 
-  virtual void IncrementInvalidationGen() {
-    Isolate::Current()->IncrFieldInvalidationGen();
-  }
-
  private:
   const Field& field_;
   DISALLOW_COPY_AND_ASSIGN(FieldDependentArray);
@@ -7706,14 +7700,19 @@
 void Field::DeoptimizeDependentCode() const {
   ASSERT(Thread::Current()->IsMutatorThread());
   ASSERT(IsOriginal());
-  if (FLAG_background_compilation) {
-    Isolate::Current()->AddDisablingField(*this);
-  }
   FieldDependentArray a(*this);
   a.DisableCode();
 }
 
 
+bool Field::IsConsistentWith(const Field& other) const {
+  return (raw_ptr()->guarded_cid_ == other.raw_ptr()->guarded_cid_) &&
+         (raw_ptr()->is_nullable_ == other.raw_ptr()->is_nullable_) &&
+         (raw_ptr()->guarded_list_length_ ==
+             other.raw_ptr()->guarded_list_length_);
+}
+
+
 bool Field::IsUninitialized() const {
   const Instance& value = Instance::Handle(raw_ptr()->value_.static_value_);
   ASSERT(value.raw() != Object::transition_sentinel().raw());
@@ -10974,8 +10973,6 @@
     }
   }
 
-  virtual void IncrementInvalidationGen() {}
-
  private:
   const LibraryPrefix& prefix_;
   DISALLOW_COPY_AND_ASSIGN(PrefixDependentArray);
@@ -14735,7 +14732,7 @@
          (kLoadFactor * static_cast<double>(mask() + 1)));
   const Array& backing_array = Array::Handle(buckets());
   intptr_t id_mask = mask();
-  intptr_t index = class_id.Value() & id_mask;
+  intptr_t index = (class_id.Value() * kSpreadFactor) & id_mask;
   intptr_t i = index;
   do {
     if (Smi::Value(Smi::RawCast(GetClassId(backing_array, i))) == kIllegalCid) {
@@ -15249,16 +15246,17 @@
     // other instances to be canonical otherwise report error (return false).
     Zone* zone = thread->zone();
     Object& obj = Object::Handle(zone);
-    intptr_t end_field_offset = SizeFromClass() - kWordSize;
-    for (intptr_t field_offset = 0;
-         field_offset <= end_field_offset;
-         field_offset += kWordSize) {
-      obj = *this->FieldAddrAtOffset(field_offset);
+    const intptr_t instance_size = SizeFromClass();
+    ASSERT(instance_size != 0);
+    for (intptr_t offset = Instance::NextFieldOffset();
+         offset < instance_size;
+         offset += kWordSize) {
+      obj = *this->FieldAddrAtOffset(offset);
       if (obj.IsInstance() && !obj.IsSmi() && !obj.IsCanonical()) {
         if (obj.IsNumber() || obj.IsString()) {
           obj = Instance::Cast(obj).CheckAndCanonicalize(thread, NULL);
           ASSERT(!obj.IsNull());
-          this->SetFieldAtOffset(field_offset, obj);
+          this->SetFieldAtOffset(offset, obj);
         } else {
           ASSERT(error_str != NULL);
           char* chars = OS::SCreate(zone, "field: %s\n", obj.ToCString());
@@ -22414,7 +22412,9 @@
   RawObject* raw = Object::Allocate(WeakProperty::kClassId,
                                     WeakProperty::InstanceSize(),
                                     space);
-  return reinterpret_cast<RawWeakProperty*>(raw);
+  RawWeakProperty* result = reinterpret_cast<RawWeakProperty*>(raw);
+  result->ptr()->next_ = 0;  // Init the list to NULL.
+  return result;
 }
 
 
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index c517514..30cc72d 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3125,10 +3125,19 @@
   // Return class id that any non-null value read from this field is guaranteed
   // to have or kDynamicCid if such class id is not known.
   // Stores to this field must update this information hence the name.
-  intptr_t guarded_cid() const { return raw_ptr()->guarded_cid_; }
+  intptr_t guarded_cid() const {
+#if defined(DEGUG)
+    Thread* thread = Thread::Current();
+    ASSERT(!IsOriginal() || thread->IsMutator() || thread->IsAtSafepoint());
+#endif
+    return raw_ptr()->guarded_cid_;
+  }
 
   void set_guarded_cid(intptr_t cid) const {
-    ASSERT(Thread::Current()->IsMutatorThread());
+#if defined(DEGUG)
+    Thread* thread = Thread::Current();
+    ASSERT(!IsOriginal() || thread->IsMutator() || thread->IsAtSafepoint());
+#endif
     StoreNonPointer(&raw_ptr()->guarded_cid_, cid);
   }
   static intptr_t guarded_cid_offset() {
@@ -3213,6 +3222,10 @@
   // Deoptimize all dependent code objects.
   void DeoptimizeDependentCode() const;
 
+  // Used by background compiler to check consistency of field copy with its
+  // original.
+  bool IsConsistentWith(const Field& field) const;
+
   bool IsUninitialized() const;
 
   void EvaluateInitializer() const;
@@ -4975,7 +4988,8 @@
 
 class MegamorphicCache : public Object {
  public:
-  static const int kInitialCapacity = 16;
+  static const intptr_t kInitialCapacity = 16;
+  static const intptr_t kSpreadFactor = 7;
   static const double kLoadFactor;
 
   RawArray* buckets() const;
@@ -5018,6 +5032,7 @@
 
  private:
   friend class Class;
+  friend class MegamorphicCacheTable;
 
   static RawMegamorphicCache* New();
 
@@ -8398,6 +8413,7 @@
   }
 
   static void Clear(RawWeakProperty* raw_weak) {
+    ASSERT(raw_weak->ptr()->next_ == 0);
     raw_weak->StorePointer(&(raw_weak->ptr()->key_), Object::null());
     raw_weak->StorePointer(&(raw_weak->ptr()->value_), Object::null());
   }
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index 0ed04ec..3806ed5 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -90,7 +90,9 @@
 }
 
 
+#if !TARGET_OS_IOS
 static mach_timebase_info_data_t timebase_info;
+#endif
 
 
 int64_t OS::GetCurrentMonotonicTicks() {
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 7819cd7..a07921f 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -161,12 +161,42 @@
       (field->guarded_cid() == kIllegalCid)) {
     return;
   }
+
   for (intptr_t j = 0; j < guarded_fields_->length(); j++) {
-    if ((*guarded_fields_)[j]->raw() == field->raw()) {
+    const Field* other = (*guarded_fields_)[j];
+    if (field->Original() == other->Original()) {
+      // Abort background compilation early if the guarded state of this field
+      // has changed during compilation. We will not be able to commit
+      // the resulting code anyway.
+      if (Compiler::IsBackgroundCompilation()) {
+        if (!other->IsConsistentWith(*field)) {
+          Compiler::AbortBackgroundCompilation(Thread::kNoDeoptId,
+              "Field's guarded state changed during compilation");
+        }
+      }
       return;
     }
   }
-  guarded_fields_->Add(&Field::ZoneHandle(Z, field->Original()));
+
+  // Note: the list of guarded fields must contain copies during background
+  // compilation because we will look at their guarded_cid when copying
+  // the array of guarded fields from callee into the caller during
+  // inlining.
+  ASSERT(!field->IsOriginal() || Thread::Current()->IsMutatorThread());
+  guarded_fields_->Add(&Field::ZoneHandle(Z, field->raw()));
+}
+
+
+void ParsedFunction::Bailout(const char* origin, const char* reason) const {
+  Report::MessageF(Report::kBailout,
+                   Script::Handle(function_.script()),
+                   function_.token_pos(),
+                   Report::AtLocation,
+                   "%s Bailout in %s: %s",
+                   origin,
+                   String::Handle(function_.name()).ToCString(),
+                   reason);
+  UNREACHABLE();
 }
 
 
@@ -9269,8 +9299,10 @@
     return;
   }
   ASSERT(node->IsReturnNode() || node->IsJumpNode());
+  const intptr_t func_level = current_block_->scope->function_level();
   TryStack* iterator = try_stack_;
-  while (iterator != NULL) {
+  while ((iterator != NULL) &&
+      (iterator->try_block()->scope->function_level() == func_level)) {
     // For continue and break node check if the target label is in scope.
     if (node->IsJumpNode()) {
       SourceLabel* label = node->AsJumpNode()->label();
@@ -14453,6 +14485,11 @@
 }
 
 
+void ParsedFunction::Bailout(const char* origin, const char* reason) const {
+  UNREACHABLE();
+}
+
+
 void Parser::ParseCompilationUnit(const Library& library,
                                   const Script& script) {
   UNREACHABLE();
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index ba284a5..84301f2 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -230,6 +230,8 @@
   // relevant.
   void AddToGuardedFields(const Field* field) const;
 
+  void Bailout(const char* origin, const char* reason) const;
+
  private:
   Thread* thread_;
   const Function& function_;
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index b366396..52c6e88 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -192,57 +192,63 @@
     StackZone stack_zone(T);
     zone_ = stack_zone.GetZone();
 
-    // Make sure class hierarchy is stable before compilation so that CHA
-    // can be used. Also ensures lookup of entry points won't miss functions
-    // because their class hasn't been finalized yet.
-    FinalizeAllClasses();
+    { HANDLESCOPE(T);
+      // Make sure class hierarchy is stable before compilation so that CHA
+      // can be used. Also ensures lookup of entry points won't miss functions
+      // because their class hasn't been finalized yet.
+      FinalizeAllClasses();
 
-    // Precompile static initializers to compute result type information.
-    PrecompileStaticInitializers();
+      // Precompile static initializers to compute result type information.
+      PrecompileStaticInitializers();
 
-    for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) {
-      if (FLAG_trace_precompiler) {
-        THR_Print("Precompiler round %" Pd "\n", round);
+      for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) {
+        if (FLAG_trace_precompiler) {
+          THR_Print("Precompiler round %" Pd "\n", round);
+        }
+
+        if (round > 0) {
+          ResetPrecompilerState();
+        }
+
+        // TODO(rmacnak): We should be able to do a more thorough job and drop
+        // some
+        //  - implicit static closures
+        //  - field initializers
+        //  - invoke-field-dispatchers
+        //  - method-extractors
+        // that are needed in early iterations but optimized away in later
+        // iterations.
+        ClearAllCode();
+
+        CollectDynamicFunctionNames();
+
+        // Start with the allocations and invocations that happen from C++.
+        AddRoots(embedder_entry_points);
+
+        // Compile newly found targets and add their callees until we reach a
+        // fixed point.
+        Iterate();
       }
 
-      if (round > 0) {
-        ResetPrecompilerState();
-      }
+      I->set_compilation_allowed(false);
 
-      // TODO(rmacnak): We should be able to do a more thorough job and drop
-      // some
-      //  - implicit static closures
-      //  - field initializers
-      //  - invoke-field-dispatchers
-      //  - method-extractors
-      // that are needed in early iterations but optimized away in later
-      // iterations.
-      ClearAllCode();
+      TraceForRetainedFunctions();
+      DropFunctions();
+      DropFields();
+      TraceTypesFromRetainedClasses();
+      DropTypes();
+      DropTypeArguments();
 
-      CollectDynamicFunctionNames();
-
-      // Start with the allocations and invocations that happen from C++.
-      AddRoots(embedder_entry_points);
-
-      // Compile newly found targets and add their callees until we reach a
-      // fixed point.
-      Iterate();
+      // Clear these before dropping classes as they may hold onto otherwise
+      // dead instances of classes we will remove.
+      I->object_store()->set_compile_time_constants(Array::null_array());
+      I->object_store()->set_unique_dynamic_targets(Array::null_array());
+      Class& null_class = Class::Handle(Z);
+      I->object_store()->set_future_class(null_class);
+      I->object_store()->set_completer_class(null_class);
+      I->object_store()->set_stream_iterator_class(null_class);
+      I->object_store()->set_symbol_class(null_class);
     }
-
-    I->set_compilation_allowed(false);
-
-    TraceForRetainedFunctions();
-    DropFunctions();
-    DropFields();
-    TraceTypesFromRetainedClasses();
-    DropTypes();
-    DropTypeArguments();
-
-    // Clear these before dropping classes as they may hold onto otherwise
-    // dead instances of classes we will remove.
-    I->object_store()->set_compile_time_constants(Array::null_array());
-    I->object_store()->set_unique_dynamic_targets(Array::null_array());
-
     DropClasses();
     DropLibraries();
 
@@ -324,6 +330,8 @@
     Field& field_;
     Function& function_;
   };
+
+  HANDLESCOPE(T);
   StaticInitializerVisitor visitor(Z);
   VisitClasses(&visitor);
 }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ef5924e..f81f02d 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -256,21 +256,19 @@
   // The tags field which is a part of the object header uses the following
   // bit fields for storing tags.
   enum TagBits {
-    kWatchedBit = 0,
-    kMarkBit = 1,
-    kCanonicalBit = 2,
-    kVMHeapObjectBit = 3,
-    kRememberedBit = 4,
+    kMarkBit = 0,
+    kCanonicalBit = 1,
+    kVMHeapObjectBit = 2,
+    kRememberedBit = 3,
+    kReservedTagPos = 4,  // kReservedBit{100K,1M,10M}
 #if defined(ARCH_IS_32_BIT)
-    kReservedTagPos = 5,  // kReservedBit{100K,1M,10M}
-    kReservedTagSize = 3,
+    kReservedTagSize = 4,
     kSizeTagPos = kReservedTagPos + kReservedTagSize,  // = 8
     kSizeTagSize = 8,
     kClassIdTagPos = kSizeTagPos + kSizeTagSize,  // = 16
     kClassIdTagSize = 16,
 #elif defined(ARCH_IS_64_BIT)
-    kReservedTagPos = 5,  // kReservedBit{100K,1M,10M}
-    kReservedTagSize = 11,
+    kReservedTagSize = 12,
     kSizeTagPos = kReservedTagPos + kReservedTagSize,  // = 16
     kSizeTagSize = 16,
     kClassIdTagPos = kSizeTagPos + kSizeTagSize,  // = 32
@@ -374,21 +372,6 @@
     return TryAcquireTagBit<MarkBit>();
   }
 
-  // Support for GC watched bit.
-  // TODO(iposva): Get rid of this.
-  bool IsWatched() const {
-    return WatchedBit::decode(ptr()->tags_);
-  }
-  void SetWatchedBitUnsynchronized() {
-    ASSERT(!IsWatched());
-    uword tags = ptr()->tags_;
-    ptr()->tags_ = WatchedBit::update(true, tags);
-  }
-  void ClearWatchedBitUnsynchronized() {
-    uword tags = ptr()->tags_;
-    ptr()->tags_ = WatchedBit::update(false, tags);
-  }
-
   // Support for object tags.
   bool IsCanonical() const {
     return CanonicalObjectTag::decode(ptr()->tags_);
@@ -521,8 +504,6 @@
  private:
   uword tags_;  // Various object tags (bits).
 
-  class WatchedBit : public BitField<uword, bool, kWatchedBit, 1> {};
-
   class MarkBit : public BitField<uword, bool, kMarkBit, 1> {};
 
   class RememberedBit : public BitField<uword, bool, kRememberedBit, 1> {};
@@ -1135,15 +1116,12 @@
   RawObject* owner_;  // Function, Null, or a Class.
   RawExceptionHandlers* exception_handlers_;
   RawPcDescriptors* pc_descriptors_;
-  RawCodeSourceMap* code_source_map_;
   RawArray* stackmaps_;
-  RawObject** to_snapshot() {
-    return reinterpret_cast<RawObject**>(&ptr()->stackmaps_);
-  }
   RawArray* deopt_info_array_;
   RawArray* static_calls_target_table_;  // (code-offset, function, code).
   RawLocalVarDescriptors* var_descriptors_;
   RawArray* inlined_metadata_;
+  RawCodeSourceMap* code_source_map_;
   RawArray* comments_;
   // If return_address_metadata_ is a Smi, it is the offset to the prologue.
   // Else, return_address_metadata_ is null.
@@ -2183,7 +2161,10 @@
     return reinterpret_cast<RawObject**>(&ptr()->value_);
   }
 
-  friend class DelaySet;
+  // Linked list is chaining all pending weak properties.
+  // Untyped to make it clear that it is not to be visited by GC.
+  uword next_;
+
   friend class GCMarker;
   template<bool> friend class MarkingVisitorBase;
   friend class Scavenger;
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 5f5a15c..1543db6 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -1443,11 +1443,6 @@
 
   (*reader->PassiveObjectHandle()) ^= reader->ReadObjectImpl(kAsReference);
   result.StorePointer(reinterpret_cast<RawObject*const*>(
-                          &result.raw_ptr()->code_source_map_),
-                      reader->PassiveObjectHandle()->raw());
-
-  (*reader->PassiveObjectHandle()) ^= reader->ReadObjectImpl(kAsReference);
-  result.StorePointer(reinterpret_cast<RawObject*const*>(
                           &result.raw_ptr()->stackmaps_),
                       reader->PassiveObjectHandle()->raw());
 
@@ -1459,6 +1454,8 @@
                       LocalVarDescriptors::null());
   result.StorePointer(&result.raw_ptr()->inlined_metadata_,
                       Array::null());
+  result.StorePointer(&result.raw_ptr()->code_source_map_,
+                      CodeSourceMap::null());
   result.StorePointer(&result.raw_ptr()->comments_,
                       Array::null());
   result.StorePointer(&result.raw_ptr()->return_address_metadata_,
@@ -1520,7 +1517,6 @@
   writer->WriteObjectImpl(ptr()->owner_, kAsReference);
   writer->WriteObjectImpl(ptr()->exception_handlers_, kAsReference);
   writer->WriteObjectImpl(ptr()->pc_descriptors_, kAsReference);
-  writer->WriteObjectImpl(ptr()->code_source_map_, kAsReference);
   writer->WriteObjectImpl(ptr()->stackmaps_, kAsReference);
 }
 
diff --git a/runtime/vm/redundancy_elimination.cc b/runtime/vm/redundancy_elimination.cc
index adc1319..93b3951 100644
--- a/runtime/vm/redundancy_elimination.cc
+++ b/runtime/vm/redundancy_elimination.cc
@@ -550,6 +550,8 @@
       case kImmutableArrayCid:
       case kOneByteStringCid:
       case kTwoByteStringCid:
+      case kExternalOneByteStringCid:
+      case kExternalTwoByteStringCid:
         // Object arrays and strings do not allow accessing them through
         // different types. No need to attach scale.
         return kNoSize;
@@ -1353,6 +1355,8 @@
     current->AsCheckEitherNonSmi()->set_licm_hoisted(true);
   } else if (current->IsCheckArrayBound()) {
     current->AsCheckArrayBound()->set_licm_hoisted(true);
+  } else if (current->IsTestCids()) {
+    current->AsTestCids()->set_licm_hoisted(true);
   }
   if (FLAG_trace_optimization) {
     THR_Print("Hoisting instruction %s:%" Pd " from B%" Pd " to B%" Pd "\n",
diff --git a/runtime/vm/runtime_entry_arm64.cc b/runtime/vm/runtime_entry_arm64.cc
index f9cd8c2..f3e98bc 100644
--- a/runtime/vm/runtime_entry_arm64.cc
+++ b/runtime/vm/runtime_entry_arm64.cc
@@ -52,14 +52,20 @@
     // We cache the Dart stack pointer and the stack limit in callee-saved
     // registers, then align and call, restoring CSP and SP on return from the
     // call.
-    __ mov(R24, CSP);
+    // This sequence may occur in an intrinsic, so don't use registers an
+    // intrinsic must preserve.
+    COMPILE_ASSERT(R23 != CODE_REG);
+    COMPILE_ASSERT(R25 != CODE_REG);
+    COMPILE_ASSERT(R23 != ARGS_DESC_REG);
+    COMPILE_ASSERT(R25 != ARGS_DESC_REG);
+    __ mov(R23, CSP);
     __ mov(R25, SP);
     __ ReserveAlignedFrameSpace(0);
     __ mov(CSP, SP);
     __ ldr(TMP, Address(THR, Thread::OffsetFromThread(this)));
     __ blr(TMP);
     __ mov(SP, R25);
-    __ mov(CSP, R24);
+    __ mov(CSP, R23);
   } else {
     // Argument count is not checked here, but in the runtime entry for a more
     // informative error message.
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 2ca7b09..03f0912 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -4,10 +4,6 @@
 
 #include "vm/scavenger.h"
 
-#include <algorithm>
-#include <map>
-#include <utility>
-
 #include "vm/dart.h"
 #include "vm/dart_api_state.h"
 #include "vm/isolate.h"
@@ -18,6 +14,7 @@
 #include "vm/stack_frame.h"
 #include "vm/store_buffer.h"
 #include "vm/thread_registry.h"
+#include "vm/timeline.h"
 #include "vm/verified_memory.h"
 #include "vm/verifier.h"
 #include "vm/visitor.h"
@@ -62,21 +59,6 @@
 }
 
 
-class BoolScope : public ValueObject {
- public:
-  BoolScope(bool* addr, bool value) : _addr(addr), _value(*addr) {
-    *_addr = value;
-  }
-  ~BoolScope() {
-    *_addr = _value;
-  }
-
- private:
-  bool* _addr;
-  bool _value;
-};
-
-
 class ScavengerVisitor : public ObjectPointerVisitor {
  public:
   explicit ScavengerVisitor(Isolate* isolate,
@@ -89,45 +71,23 @@
         heap_(scavenger->heap_),
         vm_heap_(Dart::vm_isolate()->heap()),
         page_space_(scavenger->heap_->old_space()),
-        delayed_weak_stack_(),
         bytes_promoted_(0),
-        visiting_old_object_(NULL),
-        in_scavenge_pointer_(false) { }
+        visiting_old_object_(NULL) { }
 
   void VisitPointers(RawObject** first, RawObject** last) {
+    ASSERT((visiting_old_object_ != NULL) ||
+           scavenger_->Contains(reinterpret_cast<uword>(first)) ||
+           !heap_->Contains(reinterpret_cast<uword>(first)));
     for (RawObject** current = first; current <= last; current++) {
       ScavengePointer(current);
     }
   }
 
-  GrowableArray<RawObject*>* DelayedWeakStack() {
-    return &delayed_weak_stack_;
-  }
-
   void VisitingOldObject(RawObject* obj) {
     ASSERT((obj == NULL) || obj->IsOldObject());
     visiting_old_object_ = obj;
   }
 
-  void DelayWeakProperty(RawWeakProperty* raw_weak) {
-    RawObject* raw_key = raw_weak->ptr()->key_;
-    DelaySet::iterator it = delay_set_.find(raw_key);
-    if (it != delay_set_.end()) {
-      ASSERT(raw_key->IsWatched());
-    } else {
-      ASSERT(!raw_key->IsWatched());
-      raw_key->SetWatchedBitUnsynchronized();
-    }
-    delay_set_.insert(std::make_pair(raw_key, raw_weak));
-  }
-
-  void Finalize() {
-    DelaySet::iterator it = delay_set_.begin();
-    for (; it != delay_set_.end(); ++it) {
-      WeakProperty::Clear(it->second);
-    }
-  }
-
   intptr_t bytes_promoted() const { return bytes_promoted_; }
 
  private:
@@ -147,11 +107,6 @@
 
   void ScavengePointer(RawObject** p) {
     // ScavengePointer cannot be called recursively.
-#ifdef DEBUG
-    ASSERT(!in_scavenge_pointer_);
-    BoolScope bs(&in_scavenge_pointer_, true);
-#endif
-
     RawObject* raw_obj = *p;
 
     if (raw_obj->IsSmiOrOldObject()) {
@@ -169,20 +124,6 @@
       // Get the new location of the object.
       new_addr = ForwardedAddr(header);
     } else {
-      if (raw_obj->IsWatched()) {
-        raw_obj->ClearWatchedBitUnsynchronized();
-        std::pair<DelaySet::iterator, DelaySet::iterator> ret;
-        // Visit all elements with a key equal to this raw_obj.
-        ret = delay_set_.equal_range(raw_obj);
-        for (DelaySet::iterator it = ret.first; it != ret.second; ++it) {
-          // Remember the delayed WeakProperty. These objects have been
-          // forwarded, but have not been scavenged because their key was not
-          // known to be reachable. Now that the key object is known to be
-          // reachable, we need to visit its key and value pointers.
-          delayed_weak_stack_.Add(it->second);
-        }
-        delay_set_.erase(ret.first, ret.second);
-      }
       intptr_t size = raw_obj->Size();
       intptr_t cid = raw_obj->GetClassId();
       ClassTable* class_table = isolate()->class_table();
@@ -240,14 +181,11 @@
   Heap* heap_;
   Heap* vm_heap_;
   PageSpace* page_space_;
-  typedef std::multimap<RawObject*, RawWeakProperty*> DelaySet;
-  DelaySet delay_set_;
-  GrowableArray<RawObject*> delayed_weak_stack_;
-  // TODO(cshapiro): use this value to compute survival statistics for
-  // new space growth policy.
+  RawWeakProperty* delayed_weak_properties_;
   intptr_t bytes_promoted_;
   RawObject* visiting_old_object_;
-  bool in_scavenge_pointer_;
+
+  friend class Scavenger;
 
   DISALLOW_COPY_AND_ASSIGN(ScavengerVisitor);
 };
@@ -396,6 +334,7 @@
       max_semi_capacity_in_words_(max_semi_capacity_in_words),
       object_alignment_(object_alignment),
       scavenging_(false),
+      delayed_weak_properties_(NULL),
       gc_time_micros_(0),
       collections_(0),
       external_size_(0) {
@@ -607,12 +546,9 @@
 
 
 void Scavenger::ProcessToSpace(ScavengerVisitor* visitor) {
-  GrowableArray<RawObject*>* delayed_weak_stack = visitor->DelayedWeakStack();
-
   // Iterate until all work has been drained.
   while ((resolved_top_ < top_) ||
-         PromotedStackHasMore() ||
-         !delayed_weak_stack->is_empty()) {
+         PromotedStackHasMore()) {
     while (resolved_top_ < top_) {
       RawObject* raw_obj = RawObject::FromAddr(resolved_top_);
       intptr_t class_id = raw_obj->GetClassId();
@@ -624,6 +560,8 @@
       }
     }
     {
+      // Visit all the promoted objects and update/scavenge their internal
+      // pointers. Potentially this adds more objects to the to space.
       while (PromotedStackHasMore()) {
         RawObject* raw_object = RawObject::FromAddr(PopFromPromotedStack());
         // Resolve or copy all objects referred to by the current object. This
@@ -635,10 +573,36 @@
       }
       visitor->VisitingOldObject(NULL);
     }
-    while (!delayed_weak_stack->is_empty()) {
-      // Pop the delayed weak object from the stack and visit its pointers.
-      RawObject* weak_property = delayed_weak_stack->RemoveLast();
-      weak_property->VisitPointers(visitor);
+    {
+      // Finished this round of scavenging. Process the pending weak properties
+      // for which the keys have become reachable. Potentially this adds more
+      // objects to the to space.
+      RawWeakProperty* cur_weak = delayed_weak_properties_;
+      delayed_weak_properties_ = NULL;
+      while (cur_weak != NULL) {
+        uword next_weak = cur_weak->ptr()->next_;
+        // Promoted weak properties are not enqueued. So we can guarantee that
+        // we do not need to think about store barriers here.
+        ASSERT(cur_weak->IsNewObject());
+        RawObject* raw_key = cur_weak->ptr()->key_;
+        ASSERT(raw_key->IsHeapObject());
+        // Key still points into from space even if the object has been
+        // promoted to old space by now. The key will be updated accordingly
+        // below when VisitPointers is run.
+        ASSERT(raw_key->IsNewObject());
+        uword raw_addr = RawObject::ToAddr(raw_key);
+        ASSERT(visitor->from_->Contains(raw_addr));
+        uword header = *reinterpret_cast<uword*>(raw_addr);
+        // Reset the next pointer in the weak property.
+        cur_weak->ptr()->next_ = 0;
+        if (IsForwarding(header)) {
+          cur_weak->VisitPointers(visitor);
+        } else {
+          EnqueueWeakProperty(cur_weak);
+        }
+        // Advance to next weak property in the queue.
+        cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+      }
     }
   }
 }
@@ -671,6 +635,21 @@
 }
 
 
+void Scavenger::EnqueueWeakProperty(RawWeakProperty* raw_weak) {
+  ASSERT(raw_weak->IsHeapObject());
+  ASSERT(raw_weak->IsNewObject());
+  ASSERT(raw_weak->IsWeakProperty());
+  DEBUG_ONLY(
+      uword raw_addr = RawObject::ToAddr(raw_weak);
+      uword header = *reinterpret_cast<uword*>(raw_addr);
+      ASSERT(!IsForwarding(header));
+  )
+  ASSERT(raw_weak->ptr()->next_ == 0);
+  raw_weak->ptr()->next_ = reinterpret_cast<uword>(delayed_weak_properties_);
+  delayed_weak_properties_ = raw_weak;
+}
+
+
 uword Scavenger::ProcessWeakProperty(RawWeakProperty* raw_weak,
                                      ScavengerVisitor* visitor) {
   // The fate of the weak property is determined by its key.
@@ -679,8 +658,8 @@
     uword raw_addr = RawObject::ToAddr(raw_key);
     uword header = *reinterpret_cast<uword*>(raw_addr);
     if (!IsForwarding(header)) {
-      // Key is white.  Delay the weak property.
-      visitor->DelayWeakProperty(raw_weak);
+      // Key is white.  Enqueue the weak property.
+      EnqueueWeakProperty(raw_weak);
       return raw_weak->Size();
     }
   }
@@ -689,7 +668,8 @@
 }
 
 
-void Scavenger::ProcessWeakTables() {
+void Scavenger::ProcessWeakReferences() {
+  // Rehash the weak tables now that we know which objects survive this cycle.
   for (int sel = 0;
        sel < Heap::kNumWeakSelectors;
        sel++) {
@@ -719,6 +699,32 @@
     // table above.
     delete table;
   }
+
+  // The queued weak properties at this point do not refer to reachable keys,
+  // so we clear their key and value fields.
+  {
+    RawWeakProperty* cur_weak = delayed_weak_properties_;
+    delayed_weak_properties_ = NULL;
+    while (cur_weak != NULL) {
+      uword next_weak = cur_weak->ptr()->next_;
+      // Reset the next pointer in the weak property.
+      cur_weak->ptr()->next_ = 0;
+
+      DEBUG_ONLY(
+          RawObject* raw_key = cur_weak->ptr()->key_;
+          uword raw_addr = RawObject::ToAddr(raw_key);
+          uword header = *reinterpret_cast<uword*>(raw_addr);
+          ASSERT(!IsForwarding(header));
+          ASSERT(raw_key->IsHeapObject());
+          ASSERT(raw_key->IsNewObject());  // Key still points into from space.
+      )
+
+      WeakProperty::Clear(cur_weak);
+
+      // Advance to next weak property in the queue.
+      cur_weak = reinterpret_cast<RawWeakProperty*>(next_weak);
+    }
+  }
 }
 
 
@@ -773,7 +779,8 @@
   // will continue with its scavenge after waiting for the winner to complete.
   // TODO(koda): Consider moving SafepointThreads into allocation failure/retry
   // logic to avoid needless collections.
-  SafepointOperationScope safepoint_scope(Thread::Current());
+  Thread* thread = Thread::Current();
+  SafepointOperationScope safepoint_scope(thread);
 
   // Scavenging is not reentrant. Make sure that is the case.
   ASSERT(!scavenging_);
@@ -797,7 +804,7 @@
   // The API prologue/epilogue may create/destroy zones, so we must not
   // depend on zone allocations surviving beyond the epilogue callback.
   {
-    StackZone zone(Thread::Current());
+    StackZone zone(thread);
     // Setup the visitor and run the scavenge.
     ScavengerVisitor visitor(isolate, this, from);
     page_space->AcquireDataLock();
@@ -805,10 +812,12 @@
     int64_t start = OS::GetCurrentTimeMicros();
     ProcessToSpace(&visitor);
     int64_t middle = OS::GetCurrentTimeMicros();
-    ScavengerWeakVisitor weak_visitor(this);
-    IterateWeakRoots(isolate, &weak_visitor);
-    visitor.Finalize();
-    ProcessWeakTables();
+    {
+      TIMELINE_FUNCTION_GC_DURATION(thread, "WeakHandleProcessing");
+      ScavengerWeakVisitor weak_visitor(this);
+      IterateWeakRoots(isolate, &weak_visitor);
+    }
+    ProcessWeakReferences();
     page_space->ReleaseDataLock();
 
     // Scavenge finished. Run accounting.
diff --git a/runtime/vm/scavenger.h b/runtime/vm/scavenger.h
index c5f2b81..5e7dcb1 100644
--- a/runtime/vm/scavenger.h
+++ b/runtime/vm/scavenger.h
@@ -233,6 +233,7 @@
   void IterateWeakReferences(Isolate* isolate, ScavengerVisitor* visitor);
   void IterateWeakRoots(Isolate* isolate, HandleVisitor* visitor);
   void ProcessToSpace(ScavengerVisitor* visitor);
+  void EnqueueWeakProperty(RawWeakProperty* raw_weak);
   uword ProcessWeakProperty(RawWeakProperty* raw_weak,
                             ScavengerVisitor* visitor);
   void Epilogue(Isolate* isolate, SemiSpace* from, bool invoke_api_callbacks);
@@ -264,7 +265,7 @@
   void UpdateMaxHeapCapacity();
   void UpdateMaxHeapUsage();
 
-  void ProcessWeakTables();
+  void ProcessWeakReferences();
 
   intptr_t NewSizeInWords(intptr_t old_size_in_words) const;
 
@@ -292,6 +293,9 @@
   // Keep track whether a scavenge is currently running.
   bool scavenging_;
 
+  // Keep track of pending weak properties discovered while scagenging.
+  RawWeakProperty* delayed_weak_properties_;
+
   int64_t gc_time_micros_;
   intptr_t collections_;
   static const int kStatsHistoryCapacity = 2;
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index e732409..ffe4e92 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -87,24 +87,26 @@
 }
 
 
-DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) {
-  return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]);
-}
-
-
-DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) {
-  FP[kPcMarkerSlotFromFp] = code;
-}
-
-
 DART_FORCE_INLINE static RawObject** FrameArguments(RawObject** FP,
                                                     intptr_t argc) {
   return FP - (kDartFrameFixedSize + argc);
 }
 
 
+#define RAW_CAST(Type, val)  (SimulatorHelpers::CastTo##Type(val))
+
+
 class SimulatorHelpers {
  public:
+#define DEFINE_CASTS(Type)                                              \
+    DART_FORCE_INLINE static Raw##Type* CastTo##Type(RawObject* obj) {  \
+      ASSERT((k##Type##Cid == kSmiCid) ? !obj->IsHeapObject()           \
+                                       : obj->Is##Type());              \
+      return reinterpret_cast<Raw##Type*>(obj);                         \
+    }
+  CLASS_LIST(DEFINE_CASTS)
+#undef DEFINE_CASTS
+
   DART_FORCE_INLINE static RawSmi* GetClassIdAsSmi(RawObject* obj) {
     return Smi::New(obj->IsHeapObject() ? obj->GetClassId()
                                         : static_cast<intptr_t>(kSmiCid));
@@ -115,10 +117,8 @@
                                : static_cast<intptr_t>(kSmiCid);
   }
 
-  DART_FORCE_INLINE static void IncrementUsageCounter(RawICData* icdata) {
-    reinterpret_cast<RawFunction*>(icdata->ptr()->owner_)
-        ->ptr()
-        ->usage_counter_++;
+  DART_FORCE_INLINE static void IncrementUsageCounter(RawFunction* f) {
+    f->ptr()->usage_counter_++;
   }
 
   DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs,
@@ -226,6 +226,17 @@
     }
     return false;
   }
+
+  DART_FORCE_INLINE static RawCode* FrameCode(RawObject** FP) {
+    ASSERT(GetClassId(FP[kPcMarkerSlotFromFp]) == kCodeCid);
+    return static_cast<RawCode*>(FP[kPcMarkerSlotFromFp]);
+  }
+
+
+  DART_FORCE_INLINE static void SetFrameCode(RawObject** FP, RawCode* code) {
+    ASSERT(GetClassId(code) == kCodeCid);
+    FP[kPcMarkerSlotFromFp] = code;
+  }
 };
 
 
@@ -482,6 +493,26 @@
 }
 
 
+DART_FORCE_INLINE static void EnterSyntheticFrame(RawObject*** FP,
+                                                  RawObject*** SP,
+                                                  uint32_t* pc) {
+  RawObject** fp = *SP + kDartFrameFixedSize;
+  fp[kPcMarkerSlotFromFp] = 0;
+  fp[kSavedCallerPcSlotFromFp] = reinterpret_cast<RawObject*>(pc);
+  fp[kSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
+  *FP = fp;
+  *SP = fp - 1;
+}
+
+
+DART_FORCE_INLINE static void LeaveSyntheticFrame(RawObject*** FP,
+                                                  RawObject*** SP) {
+  RawObject** fp = *FP;
+  *FP = reinterpret_cast<RawObject**>(fp[kSavedCallerFpSlotFromFp]);
+  *SP = fp - kDartFrameFixedSize;
+}
+
+
 DART_FORCE_INLINE void Simulator::Invoke(Thread* thread,
                                          RawObject** call_base,
                                          RawObject** call_top,
@@ -557,7 +588,6 @@
                                                 RawObject*** FP,
                                                 RawObject*** SP) {
   ASSERT(icdata->GetClassId() == kICDataCid);
-  SimulatorHelpers::IncrementUsageCounter(icdata);
 
   const intptr_t kCheckedArgs = 1;
   RawObject** args = call_base;
@@ -596,7 +626,6 @@
                                                 RawObject*** FP,
                                                 RawObject*** SP) {
   ASSERT(icdata->GetClassId() == kICDataCid);
-  SimulatorHelpers::IncrementUsageCounter(icdata);
 
   const intptr_t kCheckedArgs = 2;
   RawObject** args = call_base;
@@ -627,49 +656,6 @@
 }
 
 
-DART_FORCE_INLINE void Simulator::InstanceCall3(Thread* thread,
-                                                RawICData* icdata,
-                                                RawObject** call_base,
-                                                RawObject** top,
-                                                RawArray** argdesc,
-                                                RawObjectPool** pp,
-                                                uint32_t** pc,
-                                                RawObject*** FP,
-                                                RawObject*** SP) {
-  ASSERT(icdata->GetClassId() == kICDataCid);
-  SimulatorHelpers::IncrementUsageCounter(icdata);
-
-  const intptr_t kCheckedArgs = 3;
-  RawObject** args = call_base;
-  RawArray* cache = icdata->ptr()->ic_data_->ptr();
-
-  RawSmi* receiver_cid = SimulatorHelpers::GetClassIdAsSmi(args[0]);
-  RawSmi* arg0_cid = SimulatorHelpers::GetClassIdAsSmi(args[1]);
-  RawSmi* arg1_cid = SimulatorHelpers::GetClassIdAsSmi(args[2]);
-
-  bool found = false;
-  const intptr_t length = Smi::Value(cache->length_);
-  for (intptr_t i = 0;
-       i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
-    if ((cache->data()[i + 0] == receiver_cid) &&
-        (cache->data()[i + 1] == arg0_cid) &&
-        (cache->data()[i + 2] == arg1_cid)) {
-      top[0] = cache->data()[i + kCheckedArgs];
-      found = true;
-      break;
-    }
-  }
-
-  if (!found) {
-    InlineCacheMiss(
-        kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP);
-  }
-
-  *argdesc = icdata->ptr()->args_descriptor_;
-  Invoke(thread, call_base, top, pp, pc, FP, SP);
-}
-
-
 // Note: functions below are marked DART_NOINLINE to recover performance on
 // ARM where inlining these functions into the interpreter loop seemed to cause
 // some code quality issues.
@@ -801,7 +787,7 @@
       thread->set_vm_tag(vm_tag);                                              \
       return special_[kExceptionSpecialIndex];                                 \
     }                                                                          \
-    pp = FrameCode(FP)->ptr()->object_pool_->ptr();                            \
+    pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();          \
     goto DispatchAfterException;                                               \
   } while (0)                                                                  \
 
@@ -950,7 +936,29 @@
   }
 
   {
-    BYTECODE(EntryOpt, A_B_C);
+    BYTECODE(EntryOptimized, A_D);
+    const uint8_t num_fixed_params = rA;
+    const uint16_t num_registers = rD;
+
+    // Decode arguments descriptor.
+    const intptr_t pos_count = Smi::Value(*reinterpret_cast<RawSmi**>(
+        reinterpret_cast<uword>(argdesc->ptr()) +
+        Array::element_offset(ArgumentsDescriptor::kPositionalCountIndex)));
+
+    // Check that we got the right number of positional parameters.
+    if (pos_count != num_fixed_params) {
+      // Mismatch can only occur if current function is a closure.
+      goto ClosureNoSuchMethod;
+    }
+
+    // Reserve space for registers used by the optimized code.
+    SP = FP + num_registers - 1;
+
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(EntryOptional, A_B_C);
     const uint16_t num_fixed_params = rA;
     const uint16_t num_opt_pos_params = rB;
     const uint16_t num_opt_named_params = rC;
@@ -1098,7 +1106,7 @@
     {
       // Function should be compiled now, dispatch to its entry point.
       RawCode* code = FrameFunction(FP)->ptr()->code_;
-      SetFrameCode(FP, code);
+      SimulatorHelpers::SetFrameCode(FP, code);
       pp = code->ptr()->object_pool_->ptr();
       pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_);
     }
@@ -1106,6 +1114,36 @@
   }
 
   {
+    BYTECODE(HotCheck, A_D);
+    const uint8_t increment = rA;
+    const uint16_t threshold = rD;
+    RawFunction* f =  FrameFunction(FP);
+    int32_t counter = f->ptr()->usage_counter_;
+    // Note: we don't increment usage counter in the prologue of optimized
+    // functions.
+    if (increment) {
+      counter += increment;
+      f->ptr()->usage_counter_ = counter;
+    }
+    if (counter >= threshold) {
+      FP[0] = f;
+      FP[1] = 0;
+      Exit(thread, FP, FP + 2, pc);
+      NativeArguments args(thread, 1, FP, FP + 1);
+      INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, args);
+      {
+        // DRT_OptimizeInvokedFunction returns the code object to execute.
+        ASSERT(FP[1]->GetClassId() == kCodeCid);
+        RawCode* code = static_cast<RawCode*>(FP[1]);
+        SimulatorHelpers::SetFrameCode(FP, code);
+        pp = code->ptr()->object_pool_->ptr();
+        pc = reinterpret_cast<uint32_t*>(code->ptr()->entry_point_);
+      }
+    }
+    DISPATCH();
+  }
+
+  {
     BYTECODE(CheckStack, A);
     {
       if (reinterpret_cast<uword>(SP) >= thread->stack_limit()) {
@@ -1259,6 +1297,14 @@
   }
 
   {
+    BYTECODE(Swap, A_X);
+    RawObject* tmp = FP[rD];
+    FP[rD] = FP[rA];
+    FP[rA] = tmp;
+    DISPATCH();
+  }
+
+  {
     BYTECODE(StoreLocal, A_X);
     FP[rD] = *SP;
     DISPATCH();
@@ -1283,6 +1329,12 @@
   }
 
   {
+    BYTECODE(BooleanNegate, A_D);
+    FP[rA] = (FP[rD] == true_value) ? false_value : true_value;
+    DISPATCH();
+  }
+
+  {
     BYTECODE(StaticCall, A_D);
 
     // Check if single stepping.
@@ -1305,7 +1357,7 @@
   }
 
   {
-    BYTECODE(InstanceCall, A_D);
+    BYTECODE(InstanceCall1, A_D);
 
     // Check if single stepping.
     if (thread->isolate()->single_step()) {
@@ -1320,9 +1372,12 @@
 
       RawObject** call_base = SP - argc + 1;
       RawObject** call_top = SP + 1;
-      InstanceCall1(thread,
-                    static_cast<RawICData*>(LOAD_CONSTANT(kidx)),
-                    call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+
+      RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
+      SimulatorHelpers::IncrementUsageCounter(
+          RAW_CAST(Function, icdata->ptr()->owner_));
+      InstanceCall1(
+          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
     }
 
     DISPATCH();
@@ -1342,21 +1397,19 @@
 
       RawObject** call_base = SP - argc + 1;
       RawObject** call_top = SP + 1;
-      InstanceCall2(thread,
-                    static_cast<RawICData*>(LOAD_CONSTANT(kidx)),
-                    call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+
+      RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
+      SimulatorHelpers::IncrementUsageCounter(
+          RAW_CAST(Function, icdata->ptr()->owner_));
+      InstanceCall2(
+          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
     }
 
     DISPATCH();
   }
 
   {
-    BYTECODE(InstanceCall3, A_D);
-    if (thread->isolate()->single_step()) {
-      Exit(thread, FP, SP + 1, pc);
-      NativeArguments args(thread, 0, NULL, NULL);
-      INVOKE_RUNTIME(DRT_SingleStepHandler, args);
-    }
+    BYTECODE(InstanceCall1Opt, A_D);
 
     {
       const uint16_t argc = rA;
@@ -1364,9 +1417,30 @@
 
       RawObject** call_base = SP - argc + 1;
       RawObject** call_top = SP + 1;
-      InstanceCall3(thread,
-                    static_cast<RawICData*>(LOAD_CONSTANT(kidx)),
-                    call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+
+      RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
+      SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP));
+      InstanceCall1(
+          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+    }
+
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(InstanceCall2Opt, A_D);
+
+    {
+      const uint16_t argc = rA;
+      const uint16_t kidx = rD;
+
+      RawObject** call_base = SP - argc + 1;
+      RawObject** call_top = SP + 1;
+
+      RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
+      SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP));
+      InstanceCall2(
+          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
     }
 
     DISPATCH();
@@ -1495,7 +1569,7 @@
     // Restore SP, FP and PP. Push result and dispatch.
     SP = FrameArguments(FP, argc);
     FP = SavedCallerFP(FP);
-    pp = FrameCode(FP)->ptr()->object_pool_->ptr();
+    pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
     *SP = result;
     DISPATCH();
   }
@@ -1740,7 +1814,7 @@
   }
 
   {
-    BYTECODE(IfEqStrictTOS, A_D);
+    BYTECODE(IfEqStrictTOS, 0);
     SP -= 2;
     if (SP[1] != SP[2]) {
       pc++;
@@ -1749,7 +1823,7 @@
   }
 
   {
-    BYTECODE(IfNeStrictTOS, A_D);
+    BYTECODE(IfNeStrictTOS, 0);
     SP -= 2;
     if (SP[1] == SP[2]) {
       pc++;
@@ -1758,7 +1832,7 @@
   }
 
   {
-    BYTECODE(IfEqStrictNumTOS, A_D);
+    BYTECODE(IfEqStrictNumTOS, 0);
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
@@ -1773,7 +1847,7 @@
   }
 
   {
-    BYTECODE(IfNeStrictNumTOS, A_D);
+    BYTECODE(IfNeStrictNumTOS, 0);
     if (thread->isolate()->single_step()) {
       Exit(thread, FP, SP + 1, pc);
       NativeArguments args(thread, 0, NULL, NULL);
@@ -1788,6 +1862,46 @@
   }
 
   {
+    BYTECODE(IfEqStrict, A_D);
+    RawObject* lhs = FP[rA];
+    RawObject* rhs = FP[rD];
+    if (lhs != rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfNeStrict, A_D);
+    RawObject* lhs = FP[rA];
+    RawObject* rhs = FP[rD];
+    if (lhs == rhs) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfEqStrictNum, A_D);
+    RawObject* lhs = FP[rA];
+    RawObject* rhs = FP[rD];
+    if (!SimulatorHelpers::IsStrictEqualWithNumberCheck(lhs, rhs)) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(IfNeStrictNum, A_D);
+    RawObject* lhs = FP[rA];
+    RawObject* rhs = FP[rD];
+    if (SimulatorHelpers::IsStrictEqualWithNumberCheck(lhs, rhs)) {
+      pc++;
+    }
+    DISPATCH();
+  }
+
+  {
     BYTECODE(Jump, 0);
     const int32_t target = static_cast<int32_t>(op) >> 8;
     pc += (target - 1);
@@ -1817,11 +1931,79 @@
     RawObject* value = SP[3];
     ASSERT(array->GetClassId() == kArrayCid);
     ASSERT(!index->IsHeapObject());
+    ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
     array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
     DISPATCH();
   }
 
   {
+    BYTECODE(StoreIndexed, A_B_C);
+    RawArray* array = static_cast<RawArray*>(FP[rA]);
+    RawSmi* index = static_cast<RawSmi*>(FP[rB]);
+    RawObject* value = FP[rC];
+    ASSERT(array->GetClassId() == kArrayCid);
+    ASSERT(!index->IsHeapObject());
+    ASSERT(SimulatorHelpers::CheckIndex(index, array->ptr()->length_));
+    array->StorePointer(array->ptr()->data() + Smi::Value(index), value);
+    DISPATCH();
+  }
+
+  {
+    BYTECODE(Deopt, A_D);
+    const uint16_t deopt_id = rD;
+    if (deopt_id == 0) {  // Lazy deoptimization.
+      // Preserve result of the previous call.
+      // TODO(vegorov) we could have actually included result into the
+      // deoptimization environment because it is passed through the stack.
+      // If we do then we could remove special result handling from this code.
+      RawObject* result = SP[0];
+
+      // Leaf runtime function DeoptimizeCopyFrame expects a Dart frame.
+      // The code in this frame may not cause GC.
+      // DeoptimizeCopyFrame and DeoptimizeFillFrame are leaf runtime calls.
+      EnterSyntheticFrame(&FP, &SP, pc - 1);
+      const intptr_t frame_size_in_bytes =
+          DLRT_DeoptimizeCopyFrame(reinterpret_cast<uword>(FP),
+                                   /*is_lazy_deopt=*/1);
+      LeaveSyntheticFrame(&FP, &SP);
+
+      SP = FP + (frame_size_in_bytes / kWordSize);
+      EnterSyntheticFrame(&FP, &SP, pc - 1);
+      DLRT_DeoptimizeFillFrame(reinterpret_cast<uword>(FP));
+
+      // We are now inside a valid frame.
+      {
+        *++SP = result;  // Preserve result (call below can cause GC).
+        *++SP = 0;  // Space for the result: number of materialization args.
+        Exit(thread, FP, SP + 1, /*pc=*/0);
+        NativeArguments native_args(thread, 0, SP, SP);
+        INVOKE_RUNTIME(DRT_DeoptimizeMaterialize, native_args);
+      }
+      const intptr_t materialization_arg_count =
+          Smi::Value(RAW_CAST(Smi, *SP--));
+      result = *SP--;  // Reload the result. It might have been relocated by GC.
+
+      // Restore caller PC.
+      pc = SavedCallerPC(FP);
+
+      // Check if it is a fake PC marking the entry frame.
+      ASSERT((reinterpret_cast<uword>(pc) & 2) == 0);
+
+      // Restore SP, FP and PP. Push result and dispatch.
+      // Note: unlike in a normal return sequence we don't need to drop
+      // arguments - those are not part of the innermost deoptimization
+      // environment they were dropped by FlowGraphCompiler::RecordAfterCall.
+      SP = FrameArguments(FP, materialization_arg_count);
+      FP = SavedCallerFP(FP);
+      pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
+      *SP = result;
+    } else {
+      UNIMPLEMENTED();
+    }
+    DISPATCH();
+  }
+
+  {
     BYTECODE(Trap, 0);
     UNIMPLEMENTED();
     DISPATCH();
@@ -1847,7 +2029,7 @@
     RawObject** args = SP - argc;
     FP = SavedCallerFP(FP);
     if (has_dart_caller) {
-      pp = FrameCode(FP)->ptr()->object_pool_->ptr();
+      pp = SimulatorHelpers::FrameCode(FP)->ptr()->object_pool_->ptr();
     }
 
     *++SP = null_value;
diff --git a/runtime/vm/simulator_dbc.h b/runtime/vm/simulator_dbc.h
index c1d3ff9a..9865ca9 100644
--- a/runtime/vm/simulator_dbc.h
+++ b/runtime/vm/simulator_dbc.h
@@ -156,15 +156,6 @@
                      uint32_t** pc,
                      RawObject*** B, RawObject*** SP);
 
-  void InstanceCall3(Thread* thread,
-                     RawICData* icdata,
-                     RawObject** call_base,
-                     RawObject** call_top,
-                     RawArray** argdesc,
-                     RawObjectPool** pp,
-                     uint32_t** pc,
-                     RawObject*** B, RawObject*** SP);
-
   // Longjmp support for exceptions.
   SimulatorSetjmpBuffer* last_setjmp_buffer() {
     return last_setjmp_buffer_;
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index b1b2f4a..e5c5b0b 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -143,11 +143,6 @@
   ASSERT(kLengthIndex == length_offset());
   ASSERT((kSnapshotFlagIndex * sizeof(int64_t)) == kind_offset());
   ASSERT((kHeapObjectTag & kInlined));
-  // The kWatchedBit and kMarkBit are only set during GC operations. This
-  // allows the two low bits in the header to be used for snapshotting.
-  ASSERT(kObjectId ==
-         ((1 << RawObject::kWatchedBit) | (1 << RawObject::kMarkBit)));
-  ASSERT((kObjectAlignmentMask & kObjectId) == kObjectId);
   const Snapshot* snapshot = reinterpret_cast<const Snapshot*>(raw_memory);
   // If the raw length is negative or greater than what the local machine can
   // handle, then signal an error.
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index da26ca1..601eba5 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -297,7 +297,6 @@
 
   intptr_t ReadTags() {
     const intptr_t tags = static_cast<intptr_t>(Read<int8_t>()) & 0xff;
-    ASSERT(SerializedHeaderTag::decode(tags) != kObjectId);
     return tags;
   }
 
@@ -757,7 +756,6 @@
   }
 
   void WriteTags(intptr_t tags) {
-    ASSERT(SerializedHeaderTag::decode(tags) != kObjectId);
     const intptr_t flags = tags & 0xff;
     Write<int8_t>(static_cast<int8_t>(flags));
   }
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 28636b8..827407d 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -89,7 +89,6 @@
 void StackFrame::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(thread() == Thread::Current());
   ASSERT(visitor != NULL);
-#if !defined(TARGET_ARCH_DBC)
   // NOTE: This code runs while GC is in progress and runs within
   // a NoHandleScope block. Hence it is not ok to use regular Zone or
   // Scope handles. We use direct stack handles, the raw pointers in
@@ -113,6 +112,7 @@
                         Instructions::HeaderSize();
     map = code.GetStackmap(pc() - entry, &maps, &map);
     if (!map.IsNull()) {
+#if !defined(TARGET_ARCH_DBC)
       RawObject** first = reinterpret_cast<RawObject**>(sp());
       RawObject** last = reinterpret_cast<RawObject**>(
           fp() + (kFirstLocalSlotFromFp * kWordSize));
@@ -157,24 +157,59 @@
       last = reinterpret_cast<RawObject**>(
           fp() + (kFirstObjectSlotFromFp * kWordSize));
       visitor->VisitPointers(first, last);
+#else
+      RawObject** first = reinterpret_cast<RawObject**>(fp());
+      RawObject** last = reinterpret_cast<RawObject**>(sp());
+
+      // Visit fixed prefix of the frame.
+      ASSERT((first + kFirstObjectSlotFromFp) < first);
+      visitor->VisitPointers(first + kFirstObjectSlotFromFp, first - 1);
+
+      // A stack map is present in the code object, use the stack map to
+      // visit frame slots which are marked as having objects.
+      //
+      // The layout of the frame is (lower addresses to the left):
+      // | registers | outgoing arguments |
+      // |XXXXXXXXXXX|--------------------|
+      //
+      // The DBC registers are described in the stack map.
+      // The outgoing arguments are assumed to be tagged; the number
+      // of outgoing arguments is not explicitly tracked.
+      ASSERT(map.SlowPathBitCount() == 0);
+
+      // Visit DBC registers that contain tagged values.
+      intptr_t length = map.Length();
+      for (intptr_t bit = 0; bit < length; ++bit) {
+        if (map.IsObject(bit)) {
+          visitor->VisitPointer(first + bit);
+        }
+      }
+
+      // Visit outgoing arguments.
+      if ((first + length) <= last) {
+        visitor->VisitPointers(first + length, last);
+      }
+#endif  // !defined(TARGET_ARCH_DBC)
       return;
     }
 
     // No stack map, fall through.
   }
+
+#if !defined(TARGET_ARCH_DBC)
   // For normal unoptimized Dart frames and Stub frames each slot
   // between the first and last included are tagged objects.
   RawObject** first = reinterpret_cast<RawObject**>(sp());
   RawObject** last = reinterpret_cast<RawObject**>(
       fp() + (kFirstObjectSlotFromFp * kWordSize));
-  visitor->VisitPointers(first, last);
 #else
   // On DBC stack grows upwards: fp() <= sp().
   RawObject** first = reinterpret_cast<RawObject**>(
       fp() + (kFirstObjectSlotFromFp * kWordSize));
   RawObject** last = reinterpret_cast<RawObject**>(sp());
-  visitor->VisitPointers(first, last);
 #endif  // !defined(TARGET_ARCH_DBC)
+
+  visitor->VisitPointers(first, last);
 }
 
 
diff --git a/runtime/vm/stub_code.h b/runtime/vm/stub_code.h
index aa20321..8232a4b 100644
--- a/runtime/vm/stub_code.h
+++ b/runtime/vm/stub_code.h
@@ -69,6 +69,8 @@
 #define VM_STUB_CODE_LIST(V)                                                   \
   V(LazyCompile)                                                               \
   V(FixCallersTarget)                                                          \
+  V(Deoptimize)                                                                \
+  V(DeoptimizeLazy)                                                            \
 
 #endif  // !defined(TARGET_ARCH_DBC)
 
diff --git a/runtime/vm/stub_code_arm.cc b/runtime/vm/stub_code_arm.cc
index e4e32ce..538cd33 100644
--- a/runtime/vm/stub_code_arm.cc
+++ b/runtime/vm/stub_code_arm.cc
@@ -2055,7 +2055,8 @@
   __ ldr(R1, FieldAddress(R9, MegamorphicCache::mask_offset()));
   // R2: cache buckets array.
   // R1: mask.
-  __ mov(R3, Operand(R0));
+  __ LoadImmediate(IP, MegamorphicCache::kSpreadFactor);
+  __ mul(R3, R0, IP);
   // R3: probe.
 
   Label loop, update, load_target_function;
diff --git a/runtime/vm/stub_code_arm64.cc b/runtime/vm/stub_code_arm64.cc
index cb31d8e..15b7e0f 100644
--- a/runtime/vm/stub_code_arm64.cc
+++ b/runtime/vm/stub_code_arm64.cc
@@ -2106,7 +2106,8 @@
   __ ldr(R1, FieldAddress(R5, MegamorphicCache::mask_offset()));
   // R2: cache buckets array.
   // R1: mask.
-  __ mov(R3, R0);
+  __ LoadImmediate(TMP, MegamorphicCache::kSpreadFactor);
+  __ mul(R3, R0, TMP);
   // R3: probe.
 
   Label loop, update, load_target_function;
diff --git a/runtime/vm/stub_code_dbc.cc b/runtime/vm/stub_code_dbc.cc
index 0f66414..36e44b3c 100644
--- a/runtime/vm/stub_code_dbc.cc
+++ b/runtime/vm/stub_code_dbc.cc
@@ -51,6 +51,19 @@
 }
 
 
+// These deoptimization stubs are only used to populate stack frames
+// with something meaningful to make sure GC can scan the stack during
+// the last phase of deoptimization which materializes objects.
+void StubCode::GenerateDeoptimizeLazyStub(Assembler* assembler) {
+  __ Trap();
+}
+
+
+void StubCode::GenerateDeoptimizeStub(Assembler* assembler) {
+  __ Trap();
+}
+
+
 // Print the stop message.
 DEFINE_LEAF_RUNTIME_ENTRY(void, PrintStopMessage, 1, const char* message) {
   OS::Print("Stop message: %s\n", message);
diff --git a/runtime/vm/stub_code_ia32.cc b/runtime/vm/stub_code_ia32.cc
index 772e39b..836e4b5 100644
--- a/runtime/vm/stub_code_ia32.cc
+++ b/runtime/vm/stub_code_ia32.cc
@@ -2029,6 +2029,7 @@
   // EBX: mask.
   __ pushl(ECX);  // Spill MegamorphicCache.
   __ movl(ECX, EAX);
+  __ imull(ECX, Immediate(MegamorphicCache::kSpreadFactor));
   // ECX: probe.
 
   Label loop, update, load_target_function;
diff --git a/runtime/vm/stub_code_mips.cc b/runtime/vm/stub_code_mips.cc
index ce5db80..27aa782 100644
--- a/runtime/vm/stub_code_mips.cc
+++ b/runtime/vm/stub_code_mips.cc
@@ -2220,7 +2220,9 @@
   __ lw(T1, FieldAddress(S5, MegamorphicCache::mask_offset()));
   // T2: cache buckets array.
   // T1: mask.
-  __ mov(T3, T0);
+  __ LoadImmediate(TMP, MegamorphicCache::kSpreadFactor);
+  __ mult(TMP, T0);
+  __ mflo(T3);
   // T3: probe.
 
   Label loop, update, call_target_function;
diff --git a/runtime/vm/stub_code_x64.cc b/runtime/vm/stub_code_x64.cc
index 4e8f0e0..d66c125 100644
--- a/runtime/vm/stub_code_x64.cc
+++ b/runtime/vm/stub_code_x64.cc
@@ -2092,6 +2092,7 @@
   // RDI: cache buckets array.
   // RBX: mask.
   __ movq(RCX, RAX);
+  __ imulq(RCX, Immediate(MegamorphicCache::kSpreadFactor));
 
   Label loop, update, load_target_function;
   __ jmp(&loop);
diff --git a/runtime/vm/weak_code.cc b/runtime/vm/weak_code.cc
index 1305443..6dedc88 100644
--- a/runtime/vm/weak_code.cc
+++ b/runtime/vm/weak_code.cc
@@ -61,7 +61,6 @@
 
 
 void WeakCodeReferences::DisableCode() {
-  IncrementInvalidationGen();
   const Array& code_objects = Array::Handle(array_.raw());
   if (code_objects.IsNull()) {
     return;
diff --git a/runtime/vm/weak_code.h b/runtime/vm/weak_code.h
index ea2d9c1..9fd11c1 100644
--- a/runtime/vm/weak_code.h
+++ b/runtime/vm/weak_code.h
@@ -25,7 +25,6 @@
   virtual void UpdateArrayTo(const Array& array) = 0;
   virtual void ReportDeoptimization(const Code& code) = 0;
   virtual void ReportSwitchingCode(const Code& code) = 0;
-  virtual void IncrementInvalidationGen() = 0;
 
   static bool IsOptimizedCode(const Array& dependent_code, const Code& code);
 
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 5e4d69a..6cfcda8 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -1039,7 +1039,7 @@
     return JS('String', "#.charCodeAt(0) == 0 ? # : #", str, str, str);
   }
 
-  static String getTimeZoneName(receiver) {
+  static String getTimeZoneName(DateTime receiver) {
     // Firefox and Chrome emit the timezone in parenthesis.
     // Example: "Wed May 16 2012 21:13:00 GMT+0200 (CEST)".
     // We extract this name using a regexp.
@@ -1073,7 +1073,7 @@
     return "";
   }
 
-  static int getTimeZoneOffsetInMinutes(receiver) {
+  static int getTimeZoneOffsetInMinutes(DateTime receiver) {
     // Note that JS and Dart disagree on the sign of the offset.
     return -JS('int', r'#.getTimezoneOffset()', lazyAsJsDate(receiver));
   }
@@ -1118,7 +1118,7 @@
   }
 
   // Lazily keep a JS Date stored in the JS object.
-  static lazyAsJsDate(receiver) {
+  static lazyAsJsDate(DateTime receiver) {
     if (JS('bool', r'#.date === (void 0)', receiver)) {
       JS('void', r'#.date = new Date(#)', receiver,
          receiver.millisecondsSinceEpoch);
@@ -1130,49 +1130,49 @@
   // that the result is really an integer, because the JavaScript implementation
   // may return -0.0 instead of 0.
 
-  static getYear(receiver) {
+  static getYear(DateTime receiver) {
     return (receiver.isUtc)
       ? JS('int', r'(#.getUTCFullYear() + 0)', lazyAsJsDate(receiver))
       : JS('int', r'(#.getFullYear() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getMonth(receiver) {
+  static getMonth(DateTime receiver) {
     return (receiver.isUtc)
       ? JS('JSUInt31', r'#.getUTCMonth() + 1', lazyAsJsDate(receiver))
       : JS('JSUInt31', r'#.getMonth() + 1', lazyAsJsDate(receiver));
   }
 
-  static getDay(receiver) {
+  static getDay(DateTime receiver) {
     return (receiver.isUtc)
       ? JS('JSUInt31', r'(#.getUTCDate() + 0)', lazyAsJsDate(receiver))
       : JS('JSUInt31', r'(#.getDate() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getHours(receiver) {
+  static getHours(DateTime receiver) {
     return (receiver.isUtc)
       ? JS('JSUInt31', r'(#.getUTCHours() + 0)', lazyAsJsDate(receiver))
       : JS('JSUInt31', r'(#.getHours() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getMinutes(receiver) {
+  static getMinutes(DateTime receiver) {
     return (receiver.isUtc)
       ? JS('JSUInt31', r'(#.getUTCMinutes() + 0)', lazyAsJsDate(receiver))
       : JS('JSUInt31', r'(#.getMinutes() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getSeconds(receiver) {
+  static getSeconds(DateTime receiver) {
     return (receiver.isUtc)
       ? JS('JSUInt31', r'(#.getUTCSeconds() + 0)', lazyAsJsDate(receiver))
       : JS('JSUInt31', r'(#.getSeconds() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getMilliseconds(receiver) {
+  static getMilliseconds(DateTime receiver) {
     return (receiver.isUtc)
       ? JS('JSUInt31', r'(#.getUTCMilliseconds() + 0)', lazyAsJsDate(receiver))
       : JS('JSUInt31', r'(#.getMilliseconds() + 0)', lazyAsJsDate(receiver));
   }
 
-  static getWeekday(receiver) {
+  static getWeekday(DateTime receiver) {
     int weekday = (receiver.isUtc)
       ? JS('int', r'#.getUTCDay() + 0', lazyAsJsDate(receiver))
       : JS('int', r'#.getDay() + 0', lazyAsJsDate(receiver));
diff --git a/sdk/lib/collection/hash_map.dart b/sdk/lib/collection/hash_map.dart
index c8c31c5..d934e8c 100644
--- a/sdk/lib/collection/hash_map.dart
+++ b/sdk/lib/collection/hash_map.dart
@@ -92,8 +92,8 @@
    *
    * Effectively a shorthand for:
    *
-   *     new HashMap(equals: identical,
-   *                 hashCode: identityHashCode)
+   *     new HashMap<K, V>(equals: identical,
+   *                       hashCode: identityHashCode)
    */
   external factory HashMap.identity();
 
diff --git a/sdk/lib/collection/linked_hash_map.dart b/sdk/lib/collection/linked_hash_map.dart
index 91814ed..d4ce4ca 100644
--- a/sdk/lib/collection/linked_hash_map.dart
+++ b/sdk/lib/collection/linked_hash_map.dart
@@ -79,8 +79,8 @@
    *
    * Effectively a shorthand for:
    *
-   *     new LinkedHashMap(equals: identical,
-   *                       hashCode: identityHashCode)
+   *     new LinkedHashMap<K, V>(equals: identical,
+   *                             hashCode: identityHashCode)
    */
   external factory LinkedHashMap.identity();
 
diff --git a/sdk/lib/collection/linked_hash_set.dart b/sdk/lib/collection/linked_hash_set.dart
index 3bc170f..5addba5 100644
--- a/sdk/lib/collection/linked_hash_set.dart
+++ b/sdk/lib/collection/linked_hash_set.dart
@@ -83,8 +83,8 @@
    *
    * Effectively a shorthand for:
    *
-   *     new LinkedHashSet(equals: identical,
-   *                       hashCode: identityHashCode)
+   *     new LinkedHashSet<E>(equals: identical,
+   *                          hashCode: identityHashCode)
    */
   external factory LinkedHashSet.identity();
 
@@ -92,7 +92,7 @@
    * Create a linked hash set containing all [elements].
    *
    * Creates a linked hash set as by `new LinkedHashSet<E>()` and adds each
-   * element of`elements` to this set in the order they are iterated.
+   * element of `elements` to this set in the order they are iterated.
    *
    * All the [elements] should be assignable to [E].
    * The `elements` iterable itself may have any element type,
diff --git a/sdk/lib/collection/queue.dart b/sdk/lib/collection/queue.dart
index 816f62e..386cf50 100644
--- a/sdk/lib/collection/queue.dart
+++ b/sdk/lib/collection/queue.dart
@@ -444,7 +444,7 @@
  *
  * The structure is efficient for any queue or stack usage.
  */
-class ListQueue<E> extends Iterable<E> implements Queue<E> {
+class ListQueue<E> extends ListIterable<E> implements Queue<E> {
   static const int _INITIAL_CAPACITY = 8;
   List<E> _table;
   int _head;
@@ -478,7 +478,7 @@
   factory ListQueue.from(Iterable elements) {
     if (elements is List) {
       int length = elements.length;
-      ListQueue<E> queue = new ListQueue(length + 1);
+      ListQueue<E> queue = new ListQueue<E>(length + 1);
       assert(queue._table.length > length);
       for (int i = 0; i < length; i++) {
         queue._table[i] = elements[i] as Object/*=E*/;
diff --git a/sdk/lib/core/iterable.dart b/sdk/lib/core/iterable.dart
index 300b2ef..3e7c1cb 100644
--- a/sdk/lib/core/iterable.dart
+++ b/sdk/lib/core/iterable.dart
@@ -336,8 +336,9 @@
    * The elements are in iteration order.
    * The list is fixed-length if [growable] is false.
    */
-  List<E> toList({ bool growable: true }) =>
-      new List<E>.from(this, growable: growable);
+  List<E> toList({bool growable: true}) {
+    return new List<E>.from(this, growable: growable);
+  }
 
   /**
    * Creates a [Set] containing the same elements as this iterable.
diff --git a/sdk/lib/core/uri.dart b/sdk/lib/core/uri.dart
index 1d35106..5718ca8 100644
--- a/sdk/lib/core/uri.dart
+++ b/sdk/lib/core/uri.dart
@@ -500,6 +500,12 @@
         if (i == start) _fail(uri, start, "Invalid empty scheme");
         scheme = _makeScheme(uri, start, i);
         i++;
+        if (scheme == "data") {
+          // This generates a URI that is (potentially) not path normalized.
+          // Applying part normalization to a non-hierarchial URI isn't
+          // meaningful.
+          return UriData._parse(uri, i, null).uri;
+        }
         pathStart = i;
         if (i == end) {
           char = EOI;
@@ -3040,9 +3046,10 @@
       end = queryIndex;
     }
     path = _text.substring(colonIndex + 1, end);
-    // TODO(lrn): This is probably too simple. We should ensure URI
-    // normalization before passing in the raw strings, maybe using
-    // Uri._makePath, Uri._makeQuery.
+    // TODO(lrn): This can generate a URI that isn't path normalized.
+    // That's perfectly reasonable - data URIs are not hierarchical,
+    // but it may make some consumers stumble.
+    // Should we at least do escape normalization?
     _uriCache = new Uri._internal("data", "", null, null, path, query, null);
     return _uriCache;
   }
diff --git a/sdk/lib/internal/sort.dart b/sdk/lib/internal/sort.dart
index 562d8b8..63037ea 100644
--- a/sdk/lib/internal/sort.dart
+++ b/sdk/lib/internal/sort.dart
@@ -29,7 +29,7 @@
    * The function's behavior must be consistent. It must not return different
    * results for the same values.
    */
-  static void sort(List a, int compare(a, b)) {
+  static void sort/*<E>*/(List/*<E>*/ a, int compare(dynamic /*=E*/ a, dynamic /*=E*/ b)) {
     _doSort(a, 0, a.length - 1, compare);
   }
 
@@ -42,7 +42,7 @@
    *
    * See [:sort:] for requirements of the [:compare:] function.
    */
-  static void sortRange(List a, int from, int to, int compare(a, b)) {
+  static void sortRange/*<E>*/(List/*<E>*/ a, int from, int to, int compare(dynamic /*=E*/ a, dynamic /*=E*/ b)) {
     if ((from < 0) || (to > a.length) || (to < from)) {
       throw "OutOfRange";
     }
@@ -52,7 +52,7 @@
   /**
    * Sorts the list in the interval [:left:] to [:right:] (both inclusive).
    */
-  static void _doSort(List a, int left, int right, int compare(a, b)) {
+  static void _doSort/*<E>*/(List/*<E>*/ a, int left, int right, int compare(dynamic /*=E*/ a, dynamic /*=E*/ b)) {
     if ((right - left) <= _INSERTION_SORT_THRESHOLD) {
       _insertionSort(a, left, right, compare);
     } else {
@@ -60,7 +60,7 @@
     }
   }
 
-  static void _insertionSort(List a, int left, int right, int compare(a, b)) {
+  static void _insertionSort/*<E>*/(List/*<E>*/ a, int left, int right, int compare(dynamic /*=E*/ a, dynamic /*=E*/ b)) {
     for (int i = left + 1; i <= right; i++) {
       var el = a[i];
       int j = i;
@@ -72,9 +72,9 @@
     }
   }
 
-  static void _dualPivotQuicksort(List a,
+  static void _dualPivotQuicksort/*<E>*/(List/*<E>*/ a,
                                   int left, int right,
-                                  int compare(a, b)) {
+                                  int compare(dynamic /*=E*/ a, dynamic /*=E*/ b)) {
     assert(right - left > _INSERTION_SORT_THRESHOLD);
 
     // Compute the two pivots by looking at 5 elements.
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 07257ea..4e1d8e3 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -975,7 +975,7 @@
    * To reconstruct the scheme, first 'X-Forwarded-Proto' is checked, and then
    * falling back to server type.
    *
-   * To reconstruct the host, fisrt 'X-Forwarded-Host' is checked, then 'Host'
+   * To reconstruct the host, first 'X-Forwarded-Host' is checked, then 'Host'
    * and finally calling back to server.
    */
   Uri get requestedUri;
diff --git a/sdk/lib/js/dartium/js_dartium.dart b/sdk/lib/js/dartium/js_dartium.dart
index 97e927e..8d0b248 100644
--- a/sdk/lib/js/dartium/js_dartium.dart
+++ b/sdk/lib/js/dartium/js_dartium.dart
@@ -311,7 +311,16 @@
   return false;
 }
 
-bool _hasJsName(mirrors.DeclarationMirror mirror) => _getJsName(mirror) != null;
+bool _hasJsName(mirrors.DeclarationMirror mirror) {
+  if (_atJsType != null) {
+    for (var annotation in mirror.metadata) {
+      if (annotation.type.reflectedType == _atJsType) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
 
 var _domNameType;
 
@@ -634,15 +643,7 @@
 // Remember the @JS type to compare annotation type.
 var _atJsType = -1;
 
-/**
- * Generates part files defining source code for JSObjectImpl, all DOM classes
- * classes. This codegen  is needed so that type checks for all registered
- * JavaScript interop classes pass.
- * If genCachedPatches is true then the patch files don't exist this is a special
- * signal to generate and emit the patches to stdout to be captured and put into
- * the file sdk/lib/js/dartium/cached_patches.dart
- */
-List<String> _generateInteropPatchFiles(List<String> libraryPaths, genCachedPatches) {
+void setupJsTypeCache() {
   // Cache the @JS Type.
   if (_atJsType == -1) {
     var uri = new Uri(scheme: "package", path: "js/js.dart");
@@ -656,6 +657,19 @@
       _atJsType = null;
     }
   }
+}
+
+/**
+ * Generates part files defining source code for JSObjectImpl, all DOM classes
+ * classes. This codegen  is needed so that type checks for all registered
+ * JavaScript interop classes pass.
+ * If genCachedPatches is true then the patch files don't exist this is a special
+ * signal to generate and emit the patches to stdout to be captured and put into
+ * the file sdk/lib/js/dartium/cached_patches.dart
+ */
+List<String> _generateInteropPatchFiles(List<String> libraryPaths, genCachedPatches) {
+  // Cache the @JS Type.
+  if (_atJsType == -1) setupJsTypeCache();
 
   var ret = _generateExternalMethods(libraryPaths, genCachedPatches ? false : true);
   var libraryPrefixes = new Map<mirrors.LibraryMirror, String>();
diff --git a/site/try/build_sdk_json.dart b/site/try/build_sdk_json.dart
new file mode 100644
index 0000000..ec5b56b
--- /dev/null
+++ b/site/try/build_sdk_json.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'dart:io';
+import 'dart:convert';
+import 'package:compiler/src/util/uri_extras.dart' show relativize;
+
+main(List<String> arguments) async {
+  if (arguments.length == 0) {
+    print('usage: build_sdk_json.dart <out-path>');
+    exit(1);
+  }
+
+  var out = arguments[0];
+  List<Uri> sdkFiles = await collectSdkFiles();
+  new File(out).writeAsStringSync(emitSdkAsJson(sdkFiles));
+}
+
+Uri sdkRoot = Uri.base.resolveUri(Platform.script).resolve('../../');
+
+/// Collects a list of files that are part of the SDK.
+List<Uri> collectSdkFiles() {
+  var files = <Uri>[];
+  var sdkDir = new Directory.fromUri(sdkRoot.resolve('sdk/lib/'));
+  for (var entity in sdkDir.listSync(recursive: true)) {
+    if (entity is File &&
+        (entity.path.endsWith('.dart') || entity.path.endsWith('.platform'))) {
+      files.add(entity.uri);
+    }
+  }
+  return files;
+}
+
+/// Creates a string that encodes the contents of the sdk libraries in json.
+///
+/// The keys of the json file are sdk-relative paths to source files, and the
+/// values are the contents of the file.
+String emitSdkAsJson(List<Uri> paths) {
+  var map = <String, String>{};
+  for (var uri in paths) {
+    String filename = relativize(sdkRoot, uri, false);
+    var contents = new File.fromUri(uri).readAsStringSync();
+    map['sdk:/$filename'] = contents;
+  }
+  return JSON.encode(map);
+}
diff --git a/site/try/build_try.gyp b/site/try/build_try.gyp
index c421c85..07717a3 100644
--- a/site/try/build_try.gyp
+++ b/site/try/build_try.gyp
@@ -69,8 +69,7 @@
 
             # This dependency is redundant for now, as this directory is
             # implicitly part of the dependencies for dart-sdk/README.
-            '<!@(["python", "../../tools/list_files.py", "\\.dart$", '
-                 '"../../pkg/compiler/samples/jsonify"])',
+            'build_sdk_json.dart',
           ],
           'outputs': [
             '<(SHARED_INTERMEDIATE_DIR)/sdk.json',
@@ -80,10 +79,8 @@
             '<(PRODUCT_DIR)/dart-sdk/bin/'
             '<(EXECUTABLE_PREFIX)dart<(EXECUTABLE_SUFFIX)',
 
-            '-Dlist_all_libraries=true',
-            '-DoutputJson=true',
             '--package-root=<(PRODUCT_DIR)/packages/',
-            '../../pkg/compiler/samples/jsonify/jsonify.dart',
+            'build_sdk_json.dart',
             '<(SHARED_INTERMEDIATE_DIR)/sdk.json',
           ],
         },
diff --git a/site/try/poi/poi.dart b/site/try/poi/poi.dart
index be98153..f73e4e7 100644
--- a/site/try/poi/poi.dart
+++ b/site/try/poi/poi.dart
@@ -565,7 +565,7 @@
 }
 
 class PoiTask extends CompilerTask {
-  PoiTask(Compiler compiler) : super(compiler);
+  PoiTask(Compiler compiler) : super(compiler.measurer);
 
   String get name => 'POI';
 }
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 69afd94..fb4c02e 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -86,7 +86,7 @@
 [ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $mode == debug && $builder_tag == asan ]
 Language/Types/Interface_Types/subtype_t27: Skip  # Issue 21174.
 
-[ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) && $arch == arm ]
+[ ($runtime == vm || $runtime == dart_product) && $arch == arm ]
 LibTest/typed_data/Float32x4/operator_multiplication_A01_t01: Fail # Dart issue 24416
 
 [ ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
diff --git a/tests/compiler/dart2js/analyze_test_test.dart b/tests/compiler/dart2js/analyze_test_test.dart
index af3eb25..ea2524d 100644
--- a/tests/compiler/dart2js/analyze_test_test.dart
+++ b/tests/compiler/dart2js/analyze_test_test.dart
@@ -30,10 +30,6 @@
       "Library 'package:async/async.dart' doesn't export a "
       "'ForkableStream' declaration.",
   ],
-  "mirrors_test.dart": const [
-      MessageKind.INVALID_SYMBOL,
-      MessageKind.PRIVATE_IDENTIFIER,
-  ],
 };
 
 const List<String> SKIP_LIST = const <String>[
@@ -51,11 +47,6 @@
   "packages/",
 ];
 
-const List<MessageKind> MESSAGE_SKIP_LIST = const <MessageKind>[
-  // TODO(johnniwinther): Support checking of this warning. (Issue 26132)
-  MessageKind.IMPORT_EXPERIMENTAL_MIRRORS,
-];
-
 main(List<String> arguments) {
   List<String> options = <String>[];
   List<Uri> uriList = <Uri>[];
@@ -108,7 +99,6 @@
         uriList,
         WHITE_LIST,
         mode: AnalysisMode.URI,
-        options: options,
-        skipList: MESSAGE_SKIP_LIST);
+        options: options);
   });
 }
diff --git a/tests/compiler/dart2js/dart2js.status b/tests/compiler/dart2js/dart2js.status
index e6c7b74..d4ef503 100644
--- a/tests/compiler/dart2js/dart2js.status
+++ b/tests/compiler/dart2js/dart2js.status
@@ -56,6 +56,8 @@
 
 check_elements_invariants_test: Slow, Pass, Timeout # Slow due to inlining in the CPS backend
 
+uri_retention_test: Fail # Issue 26504
+
 [ $unchecked ]
 exit_code_test: Skip # This tests requires checked mode.
 
diff --git a/tests/compiler/dart2js/diagnostic_reporter_helper.dart b/tests/compiler/dart2js/diagnostic_reporter_helper.dart
index afc199d..16ff636 100644
--- a/tests/compiler/dart2js/diagnostic_reporter_helper.dart
+++ b/tests/compiler/dart2js/diagnostic_reporter_helper.dart
@@ -73,4 +73,7 @@
   withCurrentElement(Element element, f()) {
     return reporter.withCurrentElement(element, f);
   }
+
+  @override
+  bool get hasReportedError => reporter.hasReportedError;
 }
diff --git a/tests/compiler/dart2js/exit_code_test.dart b/tests/compiler/dart2js/exit_code_test.dart
index 3c7b2d9..ff419c7 100644
--- a/tests/compiler/dart2js/exit_code_test.dart
+++ b/tests/compiler/dart2js/exit_code_test.dart
@@ -137,10 +137,11 @@
 }
 
 class TestScanner extends ScannerTask {
-  TestScanner(TestCompiler compiler)
-      : super(compiler, compiler.dietParser);
+  final TestCompiler compiler;
 
-  TestCompiler get compiler => super.compiler;
+  TestScanner(TestCompiler compiler)
+      : compiler = compiler,
+        super(compiler.dietParser, compiler.reporter, compiler.measurer);
 
   void scanElements(CompilationUnitElement compilationUnit) {
     compiler.test('ScannerTask.scanElements');
diff --git a/tests/compiler/dart2js/members_test.dart b/tests/compiler/dart2js/members_test.dart
index 0856b32..10e8859 100644
--- a/tests/compiler/dart2js/members_test.dart
+++ b/tests/compiler/dart2js/members_test.dart
@@ -219,7 +219,7 @@
                 functionType: env.functionType(String_, []));
 
     InterfaceType A = env['A'];
-    MembersCreator.computeAllClassMembers(env.compiler, A.element);
+    MembersCreator.computeAllClassMembers(env.resolution, A.element);
 
     checkMemberCount(A, 5 /*inherited*/ + 9 /*non-static declared*/,
                      interfaceMembers: true);
@@ -264,7 +264,7 @@
                 isStatic: true, functionType: env.functionType(dynamic_, []));
 
     ClassElement B = env.getElement('B');
-    MembersCreator.computeAllClassMembers(env.compiler, B);
+    MembersCreator.computeAllClassMembers(env.resolution, B);
     InterfaceType B_this = B.thisType;
     TypeVariableType B_T = B_this.typeArguments.first;
     checkMemberCount(B_this, 4 /*inherited*/ + 4 /*non-static declared*/,
@@ -290,7 +290,7 @@
                                                optionalParameters: [B_T]));
 
     ClassElement C = env.getElement('C');
-    MembersCreator.computeAllClassMembers(env.compiler, C);
+    MembersCreator.computeAllClassMembers(env.resolution, C);
     InterfaceType C_this = C.thisType;
     TypeVariableType C_S = C_this.typeArguments.first;
     checkMemberCount(C_this, 8 /*inherited*/, interfaceMembers: true);
@@ -317,7 +317,7 @@
                                                optionalParameters: [C_S]));
 
     InterfaceType D = env['D'];
-    MembersCreator.computeAllClassMembers(env.compiler, D.element);
+    MembersCreator.computeAllClassMembers(env.resolution, D.element);
     checkMemberCount(D, 8 /*inherited*/, interfaceMembers: true);
     checkMemberCount(D, 8 /*inherited*/, interfaceMembers: false);
     InterfaceType B_int = instantiate(B, [int_]);
@@ -342,7 +342,7 @@
                                                optionalParameters: [int_]));
 
     InterfaceType E = env['E'];
-    MembersCreator.computeAllClassMembers(env.compiler, E.element);
+    MembersCreator.computeAllClassMembers(env.resolution, E.element);
     checkMemberCount(E, 8 /*inherited*/, interfaceMembers: true);
     checkMemberCount(E, 8 /*inherited*/, interfaceMembers: false);
 
@@ -425,7 +425,7 @@
     InterfaceType D = env['D'];
 
     // Ensure that members have been computed on all classes.
-    MembersCreator.computeAllClassMembers(env.compiler, D.element);
+    MembersCreator.computeAllClassMembers(env.resolution, D.element);
 
     // A: num method1()
     // B: int method1()
@@ -593,7 +593,7 @@
     InterfaceType C = env['C'];
 
     // Ensure that members have been computed on all classes.
-    MembersCreator.computeAllClassMembers(env.compiler, C.element);
+    MembersCreator.computeAllClassMembers(env.resolution, C.element);
 
     // A: method1()
     // B: method1()
@@ -654,7 +654,7 @@
     InterfaceType B_V = instantiate(B, [C_V]);
 
     // Ensure that members have been computed on all classes.
-    MembersCreator.computeAllClassMembers(env.compiler, C);
+    MembersCreator.computeAllClassMembers(env.resolution, C);
 
     // A: method1()
     // B: method1()
@@ -725,7 +725,7 @@
     InterfaceType C = env['C'];
 
     // Ensure that members have been computed on all classes.
-    MembersCreator.computeAllClassMembers(env.compiler, C.element);
+    MembersCreator.computeAllClassMembers(env.resolution, C.element);
 
     checkMember(C, 'm', checkType: NO_CLASS_MEMBER,
                 inheritedFrom: A,
diff --git a/tests/compiler/dart2js/memory_compiler.dart b/tests/compiler/dart2js/memory_compiler.dart
index 47c1a43..411257b 100644
--- a/tests/compiler/dart2js/memory_compiler.dart
+++ b/tests/compiler/dart2js/memory_compiler.dart
@@ -16,8 +16,6 @@
     PackagesDiscoveryProvider;
 import 'package:compiler/src/diagnostics/messages.dart' show
     Message;
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-import 'package:compiler/src/mirrors/analyze.dart';
 import 'package:compiler/src/null_compiler_output.dart' show
     NullCompilerOutput;
 import 'package:compiler/src/library_loader.dart' show
@@ -73,6 +71,7 @@
     {Map<String, String> memorySourceFiles: const <String, String>{},
      Uri entryPoint,
      List<Uri> entryPoints,
+     List<Uri> resolutionInputs,
      CompilerDiagnostics diagnosticHandler,
      CompilerOutput outputProvider,
      List<String> options: const <String>[],
@@ -87,6 +86,7 @@
   }
   CompilerImpl compiler = compilerFor(
       entryPoint: entryPoint,
+      resolutionInputs: resolutionInputs,
       memorySourceFiles: memorySourceFiles,
       diagnosticHandler: diagnosticHandler,
       outputProvider: outputProvider,
@@ -106,6 +106,7 @@
 
 CompilerImpl compilerFor(
     {Uri entryPoint,
+     List<Uri> resolutionInputs,
      Map<String, String> memorySourceFiles: const <String, String>{},
      CompilerDiagnostics diagnosticHandler,
      CompilerOutput outputProvider,
@@ -149,6 +150,7 @@
       diagnosticHandler,
       new CompilerOptions.parse(
           entryPoint: entryPoint,
+          resolutionInputs: resolutionInputs,
           libraryRoot: libraryRoot,
           packageRoot: packageRoot,
           options: options,
@@ -259,23 +261,3 @@
   }
   return handler;
 }
-
-Future<MirrorSystem> mirrorSystemFor(Map<String,String> memorySourceFiles,
-                                     {DiagnosticHandler diagnosticHandler,
-                                      List<String> options: const [],
-                                      bool showDiagnostics: true}) {
-  Uri libraryRoot = Uri.base.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
-
-  var provider = new MemorySourceFileProvider(memorySourceFiles);
-  var handler =
-      createDiagnosticHandler(diagnosticHandler, provider, showDiagnostics);
-
-  List<Uri> libraries = <Uri>[];
-  memorySourceFiles.forEach((String path, _) {
-    libraries.add(new Uri(scheme: 'memory', path: path));
-  });
-
-  return analyze(libraries, libraryRoot, packageRoot,
-                 provider, handler, options);
-}
diff --git a/tests/compiler/dart2js/mirror_system_helper.dart b/tests/compiler/dart2js/mirror_system_helper.dart
deleted file mode 100644
index 323ff8e..0000000
--- a/tests/compiler/dart2js/mirror_system_helper.dart
+++ /dev/null
@@ -1,139 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library mirror_system_helper;
-
-import 'dart:async';
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-import 'package:compiler/src/mirrors/dart2js_mirrors.dart';
-import 'mock_compiler.dart';
-
-export 'package:compiler/src/mirrors/source_mirrors.dart';
-export 'package:compiler/src/mirrors/mirrors_util.dart';
-
-const String SOURCE = 'source';
-final Uri SOURCE_URI = new Uri(scheme: SOURCE, path: SOURCE);
-
-// TODO(johnniwinther): Move this to a mirrors helper library.
-Future<MirrorSystem> createMirrorSystem(String source) {
-  MockCompiler compiler = new MockCompiler.internal(
-      analyzeOnly: true,
-      analyzeAll: true,
-      preserveComments: true);
-    compiler.registerSource(SOURCE_URI, source);
-    compiler.librariesToAnalyzeWhenRun = <Uri>[SOURCE_URI];
-  return compiler.run(null).then((_) {
-    return new Dart2JsMirrorSystem(compiler);
-  });
-}
-
-/**
- * Returns [:true:] if [type] is an instance of [:decl:] with type arguments
- * equal to [typeArgument].
- */
-bool isInstance(ClassMirror decl, List<TypeMirror> typeArguments,
-            ClassMirror type) {
-  if (type.isOriginalDeclaration) return false;
-  if (!isSameDeclaration(decl, type)) return false;
-  return areEqualsTypes(typeArguments, type.typeArguments);
-}
-
-/**
- * Returns [:true:] if [type] is the same type as [expected]. This method
- * equates a non-generic declaration with its instantiation.
- */
-bool isEqualType(TypeMirror expected, TypeMirror type) {
-  if (expected == type) return true;
-  if (expected is ClassMirror && type is ClassMirror) {
-    if (!isSameDeclaration(expected, type)) return false;
-    if (expected.isOriginalDeclaration || expected.typeArguments.isEmpty) {
-      return type.isOriginalDeclaration || type.typeArguments.isEmpty;
-    }
-    return areEqualsTypes(expected.typeArguments, type.typeArguments);
-  }
-  return true;
-}
-
-/**
- * Returns [:true:] if [types] are equals to [expected] using the equalitry
- * defined by [isEqualType].
- */
-bool areEqualsTypes(List<TypeMirror> expected, List<TypeMirror> types) {
-  return checkSameList(expected, types, isEqualType);
-}
-
-/**
- * Returns [:true:] if an instance of [type] with type arguments equal to
- * [typeArguments] is found in [types].
- */
-bool containsType(ClassMirror decl, List<TypeMirror> typeArguments,
-                  Iterable<TypeMirror> types) {
-  return types.any((type) => isInstance(decl, typeArguments, type));
-}
-
-/**
- * Returns the declaration of [type].
- */
-TypeMirror toDeclaration(TypeMirror type) {
-  return type is ClassMirror ? type.originalDeclaration : type;
-}
-
-/**
- * Returns [:true:] if [type] is of the same declaration as [expected].
- */
-bool isSameDeclaration(TypeMirror expected, TypeMirror type) {
-  return toDeclaration(expected) == toDeclaration(type);
-}
-
-/**
- * Returns [:true:] if a type of the declaration of [expected] is in [types].
- */
-bool containsDeclaration(TypeMirror expected, Iterable<TypeMirror> types) {
-  for (var type in types) {
-    if (isSameDeclaration(expected, type)) {
-      return true;
-    }
-  }
-  return false;
-}
-
-/**
- * Returns [:true:] if declarations of [expected] are the same as those of
- * [types], taking order into account.
- */
-bool isSameDeclarationList(Iterable<TypeMirror> expected,
-                           Iterable<TypeMirror> types) {
-  return checkSameList(expected, types, isSameDeclaration);
-}
-
-/**
- * Returns [:true:] if declarations of [expected] are the same as those of
- * [iterable], not taking order into account.
- */
-bool isSameDeclarationSet(Iterable<TypeMirror> expected,
-                          Iterable<TypeMirror> types) {
-   Set<TypeMirror> expectedSet = expected.map(toDeclaration).toSet();
-   Set<TypeMirror> typesSet = types.map(toDeclaration).toSet();
-   return expectedSet.length == typesSet.length &&
-          expectedSet.containsAll(typesSet);
-}
-
-/**
- * Utility method for checking whether [expected] and [iterable] contains the
- * same elements with respect to the checking function [check], takin order
- * into account.
- */
-bool checkSameList(Iterable<TypeMirror> expected,
-                   Iterable<TypeMirror> types,
-                   bool check(TypeMirror a, TypeMirror b)) {
-  if (expected.length != types.length) return false;
-  Iterator<TypeMirror> expectedIterator = expected.iterator;
-  Iterator<TypeMirror> typesIterator = types.iterator;
-  while (expectedIterator.moveNext() && typesIterator.moveNext()) {
-    if (!check(expectedIterator.current, typesIterator.current)) {
-      return false;
-    }
-  }
-  return true;
-}
diff --git a/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart b/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart
deleted file mode 100644
index b8b2e56f..0000000
--- a/tests/compiler/dart2js/mirrors/class_mirror_type_variables_test.dart
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/class_mirror_type_variables_expect.dart";
-
-class CompileTimeEnv implements Env {
-  final MirrorSystem mirrors;
-
-  CompileTimeEnv(this.mirrors);
-
-  LibraryMirror get core => mirrors.libraries[Uri.parse('dart:core')];
-
-  LibraryMirror get test =>
-      mirrors.findLibrary(#class_mirror_type_variables_data);
-
-
-  ClassMirror getA() => test.declarations[#A];
-  ClassMirror getB() => test.declarations[#B];
-  ClassMirror getC() => test.declarations[#C];
-  ClassMirror getD() => test.declarations[#D];
-  ClassMirror getE() => test.declarations[#E];
-  ClassMirror getF() => test.declarations[#F];
-  ClassMirror getNoTypeParams() => test.declarations[#NoTypeParams];
-  ClassMirror getObject() => core.declarations[#Object];
-  ClassMirror getString() => core.declarations[#String];
-  ClassMirror getHelperOfString() =>
-      createInstantiation(test.declarations[#Helper], [getString()]);
-}
-
-main() {
-  asyncTest(() => analyze("class_mirror_type_variables_data.dart").
-      then((MirrorSystem mirrors) {
-    test(new CompileTimeEnv(mirrors));
-  }));
-
-}
diff --git a/tests/compiler/dart2js/mirrors/default_value_test.dart b/tests/compiler/dart2js/mirrors/default_value_test.dart
deleted file mode 100644
index b4ea3dc..0000000
--- a/tests/compiler/dart2js/mirrors/default_value_test.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-import "package:expect/expect.dart";
-import "../memory_compiler.dart";
-
-const SOURCE = const {
-  'main.dart': """
-library main;
-
-class Class {
-  var a, b, c, d, e, f, g, h;
-  Class.optional(this.a, int b, void this.c(), 
-                 [this.d, int this.e, void this.f(), 
-                  this.g = 0, int this.h = 0]);
-  Class.named(this.a, int b, void this.c(), 
-                 {this.d, int this.e, void this.f(), 
-                  this.g: 0, int this.h: 0});
-  methodOptional(a, int b, void c(), 
-                 [d, int e, void f(), 
-                  g = 0, int h = 0]) {}
-  methodNamed(a, int b, void c(), 
-              {d, int e, void f(), 
-               g: 0, int h: 0}) {}
-} 
-""",
-};
-
-main() {
-  asyncTest(() => mirrorSystemFor(SOURCE).then((MirrorSystem mirrors) {
-    LibraryMirror dartCore = mirrors.libraries[Uri.parse('memory:main.dart')];
-    ClassMirror classMirror = dartCore.declarations[#Class];
-    testMethod(classMirror.declarations[#optional]);
-    testMethod(classMirror.declarations[#named]);
-    testMethod(classMirror.declarations[#methodOptional]);
-    testMethod(classMirror.declarations[#methodNamed]);
-  }));
-}
-
-testMethod(MethodMirror mirror) {
-  Expect.equals(8, mirror.parameters.length);
-  for (int i = 0 ; i < 6 ; i++) {
-    testParameter(mirror.parameters[i], false);
-  }
-  for (int i = 6 ; i < 8 ; i++) {
-    testParameter(mirror.parameters[i], true);
-  }
-}
-
-testParameter(ParameterMirror mirror, bool expectDefaultValue) {
-  if (expectDefaultValue) {
-    Expect.isTrue(mirror.hasDefaultValue);
-    Expect.isNotNull(mirror.defaultValue);
-  } else {
-    Expect.isFalse(mirror.hasDefaultValue);
-    Expect.isNull(mirror.defaultValue);
-  }
-}
diff --git a/tests/compiler/dart2js/mirrors/field_parameter_type_test.dart b/tests/compiler/dart2js/mirrors/field_parameter_type_test.dart
deleted file mode 100644
index 3dbabd1..0000000
--- a/tests/compiler/dart2js/mirrors/field_parameter_type_test.dart
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-import "package:expect/expect.dart";
-import "../memory_compiler.dart";
-
-const SOURCE = const {
-  'main.dart': """
-library main;
-
-class Class {
-  var a, b, c, d, e, f, g, h;
-  Class.optional(this.a, int b, void this.c(),
-                 [this.d, int this.e, void this.f(),
-                  this.g = 0, int this.h = 0]);
-  Class.named(this.a, int b, void this.c(),
-                 {this.d, int this.e, void this.f(),
-                  this.g: 0, int this.h: 0});
-  methodOptional(a, int b, void c(),
-                 [d, int e, void f(),
-                  g = 0, int h = 0]) {}
-  methodNamed(a, int b, void c(),
-              {d, int e, void f(),
-               g: 0, int h: 0}) {}
-}
-""",
-};
-
-main() {
-  asyncTest(() => mirrorSystemFor(SOURCE).then((MirrorSystem mirrors) {
-    LibraryMirror dartCore = mirrors.libraries[Uri.parse('memory:main.dart')];
-    ClassMirror classMirror = dartCore.declarations[#Class];
-    testMethod(classMirror.declarations[#optional]);
-    testMethod(classMirror.declarations[#named]);
-    testMethod(classMirror.declarations[#methodOptional]);
-    testMethod(classMirror.declarations[#methodNamed]);
-  }));
-}
-
-testMethod(MethodMirror mirror) {
-  Expect.equals(8, mirror.parameters.length);
-  for (int i = 0 ; i < 6 ; i++) {
-    testParameter(mirror.parameters[i], false);
-  }
-  for (int i = 6 ; i < 8 ; i++) {
-    testParameter(mirror.parameters[i], true);
-  }
-}
-
-testParameter(ParameterMirror mirror, bool expectDefaultValue) {
-  if (expectDefaultValue) {
-    Expect.isTrue(mirror.hasDefaultValue);
-    Expect.isNotNull(mirror.defaultValue);
-  } else {
-    Expect.isFalse(mirror.hasDefaultValue);
-    Expect.isNull(mirror.defaultValue);
-  }
-}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart b/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart
deleted file mode 100644
index ec22898..0000000
--- a/tests/compiler/dart2js/mirrors/library_exports_hidden_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_exports_hidden_test.dart";
-
-main() {
-  asyncTest(() => analyze("library_exports_hidden_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart b/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart
deleted file mode 100644
index 0234524..0000000
--- a/tests/compiler/dart2js/mirrors/library_exports_shown_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_exports_shown_test.dart";
-
-main() {
-  asyncTest(() => analyze("library_exports_shown_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart b/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart
deleted file mode 100644
index d72132d..0000000
--- a/tests/compiler/dart2js/mirrors/library_imports_hidden_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_imports_hidden_test.dart";
-
-main() {
-  asyncTest(() => analyze("library_imports_hidden_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart b/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart
deleted file mode 100644
index 45b7dd5..0000000
--- a/tests/compiler/dart2js/mirrors/library_imports_prefixed_show_hide_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_imports_prefixed_show_hide_test.dart";
-
-main() {
-  asyncTest(() => analyze("library_imports_prefixed_show_hide_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart b/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart
deleted file mode 100644
index 528247d..0000000
--- a/tests/compiler/dart2js/mirrors/library_imports_prefixed_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_imports_prefixed_test.dart";
-
-main() {
-  asyncTest(() => analyze("library_imports_prefixed_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart b/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart
deleted file mode 100644
index 83a77b0..0000000
--- a/tests/compiler/dart2js/mirrors/library_imports_shown_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/library_imports_shown_test.dart";
-
-main() {
-  asyncTest(() => analyze("library_imports_shown_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart b/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
deleted file mode 100644
index ed8d8fd..0000000
--- a/tests/compiler/dart2js/mirrors/mirrors_reader_test.dart
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-// Test that everything reachable from a [MirrorSystem] can be accessed.
-
-library test.mirrors.reader;
-
-import "dart:mirrors" hide SourceLocation;
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/mirrors_reader.dart";
-import "package:compiler/src/diagnostics/spannable.dart";
-import "package:compiler/src/mirrors/dart2js_mirrors.dart";
-import "package:compiler/src/mirrors/source_mirrors.dart";
-
-class SourceMirrorsReader extends MirrorsReader {
-  final Dart2JsMirrorSystem mirrorSystem;
-
-  SourceMirrorsReader(this.mirrorSystem,
-                      {bool verbose: false, bool includeStackTrace: false})
-      : super(verbose: verbose, includeStackTrace: includeStackTrace);
-
-  evaluate(f()) {
-    try {
-      return f();
-    } on SpannableAssertionFailure catch (e) {
-      var reporter = mirrorSystem.compiler.reporter;
-      reporter.reportAssertionFailure(e);
-      rethrow;
-    }
-  }
-
-  visitMirror(Mirror mirror) {
-    if (mirror is CombinatorMirror) {
-      visitCombinatorMirror(mirror);
-    } else if (mirror is LibraryDependencyMirror) {
-      visitLibraryDependencyMirror(mirror);
-    } else if (mirror is CommentInstanceMirror) {
-      visitCommentInstanceMirror(mirror);
-    } else if (mirror is ListInstanceMirror) {
-      visitListInstanceMirror(mirror);
-    } else if (mirror is MapInstanceMirror) {
-      visitMapInstanceMirror(mirror);
-    } else if (mirror is TypeInstanceMirror) {
-      visitTypeInstanceMirror(mirror);
-    } else {
-      super.visitMirror(mirror);
-    }
-  }
-
-  visitDeclarationMirror(DeclarationSourceMirror mirror) {
-    super.visitDeclarationMirror(mirror);
-    visit(mirror, 'isNameSynthetic', () => mirror.isNameSynthetic);
-  }
-
-  visitClassMirror(ClassSourceMirror mirror) {
-    super.visitClassMirror(mirror);
-    visit(mirror, 'isAbstract', () => mirror.isAbstract);
-  }
-
-  visitLibraryMirror(LibrarySourceMirror mirror) {
-    super.visitLibraryMirror(mirror);
-    visit(mirror, 'libraryDependencies', () => mirror.libraryDependencies);
-  }
-
-  visitParameterMirror(ParameterMirror mirror) {
-    super.visitParameterMirror(mirror);
-    if (mirror is ParameterSourceMirror) {
-      visit(mirror, 'isInitializingFormal', () => mirror.isInitializingFormal);
-      visit(mirror, 'initializedField', () => mirror.initializedField);
-    }
-  }
-
-  visitTypeMirror(TypeSourceMirror mirror) {
-    super.visitTypeMirror(mirror);
-    visit(mirror, 'isVoid', () => mirror.isVoid);
-    visit(mirror, 'isDynamic', () => mirror.isDynamic);
-  }
-
-  visitSourceLocation(SourceLocation location) {
-    super.visitSourceLocation(location);
-    visit(location, 'line', () => location.line);
-    visit(location, 'column', () => location.column);
-    visit(location, 'offset', () => location.offset);
-    visit(location, 'length', () => location.length);
-    visit(location, 'text', () => location.text);
-    visit(location, 'sourceUri', () => location.sourceUri);
-    visit(location, 'sourceText', () => location.sourceText);
-  }
-
-  visitCombinatorMirror(CombinatorMirror mirror) {
-    visit(mirror, 'identifiers', () => mirror.identifiers);
-    visit(mirror, 'isShow', () => mirror.isShow);
-    visit(mirror, 'isHide', () => mirror.isHide);
-  }
-
-  visitLibraryDependencyMirror(LibraryDependencyMirror mirror) {
-    visit(mirror, 'isImport', () => mirror.isImport);
-    visit(mirror, 'isExport', () => mirror.isExport);
-    visit(mirror, 'sourceLibrary', () => mirror.sourceLibrary);
-    visit(mirror, 'targetLibrary', () => mirror.targetLibrary);
-    visit(mirror, 'prefix', () => mirror.prefix);
-    visit(mirror, 'combinators', () => mirror.combinators);
-    visit(mirror, 'location', () => mirror.location);
-  }
-
-  visitCommentInstanceMirror(CommentInstanceMirror mirror) {
-    visitInstanceMirror(mirror);
-    visit(mirror, 'text', () => mirror.text);
-    visit(mirror, 'trimmedText', () => mirror.trimmedText);
-    visit(mirror, 'isDocComment', () => mirror.isDocComment);
-  }
-
-  visitListInstanceMirror(ListInstanceMirror mirror) {
-    visitInstanceMirror(mirror);
-    visit(mirror, 'length', () => mirror.length);
-  }
-
-  visitMapInstanceMirror(MapInstanceMirror mirror) {
-    visitInstanceMirror(mirror);
-    visit(mirror, 'keys', () => mirror.keys);
-    visit(mirror, 'length', () => mirror.length);
-  }
-
-  visitTypeInstanceMirror(TypeInstanceMirror mirror) {
-    visitInstanceMirror(mirror);
-    visit(mirror, 'representedType', () => mirror.representedType);
-  }
-}
-
-main(List<String> arguments) {
-  asyncTest(() => analyzeUri(Uri.parse('dart:core')).
-      then((MirrorSystem mirrors) {
-    MirrorsReader reader = new SourceMirrorsReader(mirrors,
-        verbose: arguments.contains('-v'),
-        includeStackTrace: arguments.contains('-s'));
-    reader.checkMirrorSystem(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart b/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
deleted file mode 100644
index c308dae..0000000
--- a/tests/compiler/dart2js/mirrors/mirrors_test_helper.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:io';
-import 'dart:async';
-
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-import 'package:compiler/src/mirrors/analyze.dart' as source_mirrors;
-import 'package:compiler/src/source_file_provider.dart';
-
-TypeMirror createInstantiation(TypeSourceMirror type,
-                               List<TypeMirror> typeArguments) {
-  return type.createInstantiation(typeArguments);
-}
-
-Future<MirrorSystem> analyze(String test) {
-  Uri repository = Platform.script.resolve('../../../../');
-  Uri testUri = repository.resolve('tests/lib/mirrors/$test');
-  return analyzeUri(testUri);
-}
-
-
-Future<MirrorSystem> analyzeUri(Uri testUri) {
-  Uri repository = Platform.script.resolve('../../../../');
-  Uri libraryRoot = repository.resolve('sdk/');
-  Uri packageRoot = Uri.base.resolve(Platform.packageRoot);
-  var provider = new CompilerSourceFileProvider();
-  var handler = new FormattingDiagnosticHandler(provider);
-  return source_mirrors.analyze(
-      [testUri],
-      libraryRoot,
-      packageRoot,
-      provider,
-      handler);
-}
diff --git a/tests/compiler/dart2js/mirrors/relation_assignable_test.dart b/tests/compiler/dart2js/mirrors/relation_assignable_test.dart
deleted file mode 100644
index eeb6190..0000000
--- a/tests/compiler/dart2js/mirrors/relation_assignable_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/relation_assignable_test.dart";
-
-main() {
-  asyncTest(() => analyze("relation_assignable_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/relation_subclass_test.dart b/tests/compiler/dart2js/mirrors/relation_subclass_test.dart
deleted file mode 100644
index 86503eb..0000000
--- a/tests/compiler/dart2js/mirrors/relation_subclass_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/relation_subclass_test.dart";
-
-main() {
-  asyncTest(() => analyze("relation_subclass_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors/relation_subtype_test.dart b/tests/compiler/dart2js/mirrors/relation_subtype_test.dart
deleted file mode 100644
index 2fca90c..0000000
--- a/tests/compiler/dart2js/mirrors/relation_subtype_test.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import "dart:mirrors";
-
-import "package:async_helper/async_helper.dart";
-
-import "mirrors_test_helper.dart";
-import "../../../lib/mirrors/relation_subtype_test.dart";
-
-main() {
-  asyncTest(() => analyze("relation_subtype_test.dart").
-      then((MirrorSystem mirrors) {
-    test(mirrors);
-  }));
-}
diff --git a/tests/compiler/dart2js/mirrors_exports_test.dart b/tests/compiler/dart2js/mirrors_exports_test.dart
deleted file mode 100644
index 302dd31..0000000
--- a/tests/compiler/dart2js/mirrors_exports_test.dart
+++ /dev/null
@@ -1,183 +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.
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-
-import 'memory_compiler.dart';
-
-const SOURCE_FILES = const {
-'main.dart': '''
-import 'a.dart' show A1, A2;
-import 'b.dart' as b hide B1;
-export 'a.dart' show A2 hide A3, A1;
-export 'b.dart' hide B1, B2 show B3;
-import 'dart:core' as core;
-import 'c.dart' deferred as c;
-
-main() {}
-''',
-'a.dart': '''
-class A1 {}
-class A2 {}
-class A3 {}
-''',
-'b.dart': '''
-class B1 {}
-class B2 {}
-class B3 {}
-''',
-'c.dart': '''
-foo() => 499;
-'''
-};
-
-void main() {
-  asyncTest(() => mirrorSystemFor(SOURCE_FILES).then((MirrorSystem mirrors) {
-    LibrarySourceMirror mainLibrary =
-        mirrors.libraries[Uri.parse('memory:main.dart')];
-    Expect.isNotNull(mainLibrary);
-
-    LibrarySourceMirror aLibrary =
-        mirrors.libraries[Uri.parse('memory:a.dart')];
-    Expect.isNotNull(aLibrary);
-
-    LibrarySourceMirror bLibrary =
-        mirrors.libraries[Uri.parse('memory:b.dart')];
-    Expect.isNotNull(bLibrary);
-
-    LibrarySourceMirror cLibrary =
-        mirrors.libraries[Uri.parse('memory:c.dart')];
-    Expect.isNotNull(cLibrary);
-
-    LibrarySourceMirror coreLibrary =
-        mirrors.libraries[Uri.parse('dart:core')];
-    Expect.isNotNull(coreLibrary);
-
-    var dependencies = mainLibrary.libraryDependencies;
-    Expect.isNotNull(dependencies);
-    Expect.equals(6, dependencies.length);
-
-    // import 'a.dart' show A1, A2;
-    var dependency = dependencies[0];
-    Expect.isNotNull(dependency);
-    Expect.isTrue(dependency.isImport);
-    Expect.isFalse(dependency.isExport);
-    Expect.equals(mainLibrary, dependency.sourceLibrary);
-    Expect.equals(aLibrary, dependency.targetLibrary);
-    Expect.isNull(dependency.prefix);
-    Expect.isFalse(dependency.isDeferred);
-
-    var combinators = dependency.combinators;
-    Expect.isNotNull(combinators);
-    Expect.equals(1, combinators.length);
-
-    var combinator = combinators[0];
-    Expect.isNotNull(combinator);
-    Expect.isTrue(combinator.isShow);
-    Expect.isFalse(combinator.isHide);
-    Expect.listEquals(['A1', 'A2'], combinator.identifiers);
-
-    // import 'b.dart' as b hide B1;
-    dependency = dependencies[1];
-    Expect.isNotNull(dependency);
-    Expect.isTrue(dependency.isImport);
-    Expect.isFalse(dependency.isExport);
-    Expect.equals(mainLibrary, dependency.sourceLibrary);
-    Expect.equals(bLibrary, dependency.targetLibrary);
-    Expect.equals('b', dependency.prefix);
-    Expect.isFalse(dependency.isDeferred);
-
-    combinators = dependency.combinators;
-    Expect.isNotNull(combinators);
-    Expect.equals(1, combinators.length);
-
-    combinator = combinators[0];
-    Expect.isNotNull(combinator);
-    Expect.isFalse(combinator.isShow);
-    Expect.isTrue(combinator.isHide);
-    Expect.listEquals(['B1'], combinator.identifiers);
-
-    // export 'a.dart' show A2 hide A3, A1;
-    dependency = dependencies[2];
-    Expect.isNotNull(dependency);
-    Expect.isFalse(dependency.isImport);
-    Expect.isTrue(dependency.isExport);
-    Expect.equals(mainLibrary, dependency.sourceLibrary);
-    Expect.equals(aLibrary, dependency.targetLibrary);
-    Expect.isNull(dependency.prefix);
-    Expect.isFalse(dependency.isDeferred);
-
-    combinators = dependency.combinators;
-    Expect.isNotNull(combinators);
-    Expect.equals(2, combinators.length);
-
-    combinator = combinators[0];
-    Expect.isNotNull(combinator);
-    Expect.isTrue(combinator.isShow);
-    Expect.isFalse(combinator.isHide);
-    Expect.listEquals(['A2'], combinator.identifiers);
-
-    combinator = combinators[1];
-    Expect.isNotNull(combinator);
-    Expect.isFalse(combinator.isShow);
-    Expect.isTrue(combinator.isHide);
-    Expect.listEquals(['A3', 'A1'], combinator.identifiers);
-
-    // export 'b.dart' hide B1, B2 show B3;
-    dependency = dependencies[3];
-    Expect.isNotNull(dependency);
-    Expect.isFalse(dependency.isImport);
-    Expect.isTrue(dependency.isExport);
-    Expect.equals(mainLibrary, dependency.sourceLibrary);
-    Expect.equals(bLibrary, dependency.targetLibrary);
-    Expect.isNull(dependency.prefix);
-    Expect.isFalse(dependency.isDeferred);
-
-    combinators = dependency.combinators;
-    Expect.isNotNull(combinators);
-    Expect.equals(2, combinators.length);
-
-    combinator = combinators[0];
-    Expect.isNotNull(combinator);
-    Expect.isFalse(combinator.isShow);
-    Expect.isTrue(combinator.isHide);
-    Expect.listEquals(['B1', 'B2'], combinator.identifiers);
-
-    combinator = combinators[1];
-    Expect.isNotNull(combinator);
-    Expect.isTrue(combinator.isShow);
-    Expect.isFalse(combinator.isHide);
-    Expect.listEquals(['B3'], combinator.identifiers);
-
-    // import 'dart:core' as core;
-    dependency = dependencies[4];
-    Expect.isNotNull(dependency);
-    Expect.isTrue(dependency.isImport);
-    Expect.isFalse(dependency.isExport);
-    Expect.equals(mainLibrary, dependency.sourceLibrary);
-    Expect.equals(coreLibrary, dependency.targetLibrary);
-    Expect.equals('core', dependency.prefix);
-    Expect.isFalse(dependency.isDeferred);
-
-    combinators = dependency.combinators;
-    Expect.isNotNull(combinators);
-    Expect.equals(0, combinators.length);
-
-    // import 'c.dart' deferred as c;
-    dependency = dependencies[5];
-    Expect.isNotNull(dependency);
-    Expect.isTrue(dependency.isImport);
-    Expect.isFalse(dependency.isExport);
-    Expect.equals(mainLibrary, dependency.sourceLibrary);
-    Expect.equals(cLibrary, dependency.targetLibrary);
-    Expect.equals('c', dependency.prefix);
-    Expect.isTrue(dependency.isDeferred);
-
-    combinators = dependency.combinators;
-    Expect.isNotNull(combinators);
-    Expect.equals(0, combinators.length);
-  }));
-}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors_lookup_test.dart b/tests/compiler/dart2js/mirrors_lookup_test.dart
deleted file mode 100644
index 32e04e1..0000000
--- a/tests/compiler/dart2js/mirrors_lookup_test.dart
+++ /dev/null
@@ -1,263 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library dart2js.test.mirrors_lookup;
-
-import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
-import 'memory_compiler.dart';
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-import 'package:compiler/src/mirrors/mirrors_util.dart';
-
-const Map MEMORY_SOURCE_FILES = const {
-  'main.dart': r"""
-
-library main;
-
-import 'dart:async' as async show Future;
-
-var variable;
-
-method(a, [b]) {}
-
-class Class<A> {
-  var field;
-  var variable;
-  method(c, {d}) {}
-}
-
-class Subclass<B> extends Class<B> {
-  var subfield;
-}
-""",
-};
-
-void main() {
-  asyncTest(() => mirrorSystemFor(MEMORY_SOURCE_FILES).then(
-      (MirrorSystem mirrors) => test(mirrors),
-      onError: (e) => Expect.fail('$e')));
-}
-
-void test(MirrorSystem mirrors) {
-  LibrarySourceMirror dartCore = mirrors.libraries[Uri.parse('dart:core')];
-  Expect.isNotNull(dartCore);
-
-  LibrarySourceMirror dartAsync = mirrors.libraries[Uri.parse('dart:async')];
-  Expect.isNotNull(dartAsync);
-
-  LibrarySourceMirror library = mirrors.libraries[Uri.parse('memory:main.dart')];
-  Expect.isNotNull(library);
-
-  // Check top-level scope.
-
-  DeclarationSourceMirror String_ = library.lookupInScope('String');
-  Expect.isTrue(String_ is ClassMirror);
-  Expect.equals(#String, String_.simpleName);
-  Expect.equals(dartCore, String_.owner);
-
-  Expect.isNull(library.lookupInScope('async'));
-  Expect.isNull(library.lookupInScope('Future'));
-  DeclarationSourceMirror Future_ = library.lookupInScope('async.Future');
-  Expect.isTrue(Future_ is ClassMirror);
-  Expect.equals(#Future, Future_.simpleName);
-  Expect.equals(dartAsync, Future_.owner);
-  // Timer is not in scope.
-  Expect.isNull(library.lookupInScope('Timer'));
-  // async.Timer is hidden.
-  Expect.isNull(library.lookupInScope('async.Timer'));
-
-  DeclarationSourceMirror variable = library.lookupInScope('variable');
-  Expect.isTrue(variable is VariableMirror);
-  Expect.equals(#variable, variable.simpleName);
-  Expect.equals(#main.variable, variable.qualifiedName);
-  Expect.equals(library, variable.owner);
-  // Parameter `a` is not in scope.
-  Expect.isNull(library.lookupInScope('a'));
-  // Parameter `b` is not in scope.
-  Expect.isNull(library.lookupInScope('b'));
-
-  DeclarationSourceMirror method = library.lookupInScope('method');
-  Expect.isTrue(method is MethodMirror);
-  Expect.equals(#method, method.simpleName);
-  Expect.equals(#main.method, method.qualifiedName);
-  Expect.equals(library, method.owner);
-
-  DeclarationSourceMirror Class = library.lookupInScope('Class');
-  Expect.isTrue(Class is ClassMirror);
-  Expect.equals(#Class, Class.simpleName);
-  Expect.equals(#main.Class, Class.qualifiedName);
-  Expect.equals(library, Class.owner);
-  // Type variable `A` is not in scope.
-  Expect.isNull(library.lookupInScope('A'));
-
-  DeclarationSourceMirror Subclass = library.lookupInScope('Subclass');
-  Expect.isTrue(Subclass is ClassMirror);
-  Expect.equals(#Subclass, Subclass.simpleName);
-  Expect.equals(#main.Subclass, Subclass.qualifiedName);
-  Expect.equals(library, Subclass.owner);
-  // Type variable `B` is not in scope.
-  Expect.isNull(library.lookupInScope('B'));
-
-  // Check top-level declaration scope.
-  checkTopScope(DeclarationSourceMirror declaration) {
-    Expect.equals(String_, declaration.lookupInScope('String'));
-    Expect.equals(Future_, declaration.lookupInScope('async.Future'));
-    Expect.isNull(method.lookupInScope('Timer'));
-    Expect.isNull(declaration.lookupInScope('async.Timer'));
-    Expect.equals(variable, declaration.lookupInScope('variable'));
-    Expect.equals(method, declaration.lookupInScope('method'));
-    Expect.equals(Class, declaration.lookupInScope('Class'));
-    // Type variable `A` is not in scope.
-    Expect.isNull(declaration.lookupInScope('A'));
-    // Field `field` is not in scope.
-    Expect.isNull(declaration.lookupInScope('field'));
-    Expect.equals(Subclass, declaration.lookupInScope('Subclass'));
-    // Type variable `B` is not in scope.
-    Expect.isNull(declaration.lookupInScope('B'));
-    // Field `subfield` is not in scope.
-    Expect.isNull(declaration.lookupInScope('subfield'));
-  }
-
-  checkTopScope(variable);
-  // Parameter `a` is not in scope of `variable`.
-  Expect.isNull(variable.lookupInScope('a'));
-  // Parameter `b` is not in scope of `variable`.
-  Expect.isNull(variable.lookupInScope('b'));
-
-  checkTopScope(method);
-  // Parameter `a` is in scope of `method`.
-  print(method.lookupInScope('a'));
-  Expect.isTrue(method.lookupInScope('a') is ParameterMirror);
-  // Parameter `b` is in scope of `method`.
-  Expect.isTrue(method.lookupInScope('b') is ParameterMirror);
-
-  // Check class scope.
-  DeclarationSourceMirror Class_field = Class.lookupInScope('field');
-  Expect.isTrue(Class_field is VariableMirror);
-  Expect.notEquals(variable, Class_field);
-  Expect.equals(Class, Class_field.owner);
-
-  DeclarationSourceMirror Class_variable = Class.lookupInScope('variable');
-  Expect.isTrue(Class_variable is VariableMirror);
-  Expect.notEquals(variable, Class_variable);
-  Expect.equals(Class, Class_variable.owner);
-
-  DeclarationSourceMirror Class_method = Class.lookupInScope('method');
-  Expect.isTrue(Class_method is MethodMirror);
-  Expect.notEquals(method, Class_method);
-  Expect.equals(Class, Class_method.owner);
-
-  checkClassScope(DeclarationSourceMirror declaration, {bool parametersInScope}) {
-    Expect.equals(String_, declaration.lookupInScope('String'));
-    Expect.equals(Future_, declaration.lookupInScope('async.Future'));
-    Expect.isNull(declaration.lookupInScope('Timer'));
-    Expect.isNull(declaration.lookupInScope('async.Timer'));
-
-    Expect.equals(Class_field, declaration.lookupInScope('field'));
-    Expect.equals(Class_variable, declaration.lookupInScope('variable'));
-    Expect.equals(Class_method, declaration.lookupInScope('method'));
-
-    // Parameter `a` is not in scope.
-    Expect.isNull(declaration.lookupInScope('a'));
-    // Parameter `b` is not in scope.
-    Expect.isNull(declaration.lookupInScope('b'));
-
-    if (parametersInScope) {
-      // Parameter `c` is in scope.
-      Expect.isTrue(declaration.lookupInScope('c') is ParameterMirror);
-      // Parameter `d` is in scope.
-      Expect.isTrue(declaration.lookupInScope('d') is ParameterMirror);
-    } else {
-      // Parameter `c` is not in scope.
-      Expect.isNull(declaration.lookupInScope('c'));
-      // Parameter `d` is not in scope.
-      Expect.isNull(declaration.lookupInScope('d'));
-    }
-
-    Expect.equals(Class, declaration.lookupInScope('Class'));
-    // Type variable `A` is in scope.
-    Expect.isTrue(declaration.lookupInScope('A') is TypeVariableMirror);
-    Expect.equals(Subclass, declaration.lookupInScope('Subclass'));
-    // Type variable `B` is not in scope.
-    Expect.isNull(declaration.lookupInScope('B'));
-    // Field `subfield` is not in scope.
-    Expect.isNull(declaration.lookupInScope('subfield'));
-  }
-  checkClassScope(Class, parametersInScope: false);
-  checkClassScope(Class_field, parametersInScope: false);
-  checkClassScope(Class_variable, parametersInScope: false);
-  checkClassScope(Class_method, parametersInScope: true);
-
-  // Check class scope.
-  DeclarationSourceMirror Subclass_subfield = Subclass.lookupInScope('subfield');
-  Expect.isTrue(Subclass_subfield is VariableMirror);
-  Expect.notEquals(variable, Subclass_subfield);
-  Expect.equals(Subclass, Subclass_subfield.owner);
-
-  checkSubclassScope(DeclarationSourceMirror declaration) {
-    Expect.equals(String_, declaration.lookupInScope('String'));
-    Expect.equals(Future_, declaration.lookupInScope('async.Future'));
-    Expect.isNull(declaration.lookupInScope('Timer'));
-    Expect.isNull(declaration.lookupInScope('async.Timer'));
-
-    // Top level `variable` is in scope.
-    Expect.equals(variable, declaration.lookupInScope('variable'));
-    // Top level `method` is in scope.
-    Expect.equals(method, declaration.lookupInScope('method'));
-
-    // Parameter `a` is not in scope
-    Expect.isNull(declaration.lookupInScope('a'));
-    // Parameter `b` is not in scope
-    Expect.isNull(declaration.lookupInScope('b'));
-
-    // Parameter `c` is not in scope.
-    Expect.isNull(declaration.lookupInScope('c'));
-    // Parameter `d` is not in scope.
-    Expect.isNull(declaration.lookupInScope('d'));
-
-    Expect.equals(Class, declaration.lookupInScope('Class'));
-    // Type variable `A` is not in scope
-    Expect.isNull(declaration.lookupInScope('A'));
-    // Field `field` is in scope
-    Expect.equals(Class_field, declaration.lookupInScope('field'));
-    Expect.equals(Subclass, declaration.lookupInScope('Subclass'));
-    // Type variable `B` is in scope
-    Expect.isTrue(declaration.lookupInScope('B') is TypeVariableMirror);
-    // Field `subfield` is in scope
-    Expect.equals(Subclass_subfield, declaration.lookupInScope('subfield'));
-  }
-  checkSubclassScope(Subclass);
-  checkSubclassScope(Subclass_subfield);
-
-  // `Timer` is in scope of `Future`.
-  Expect.isTrue(Future_.lookupInScope('Timer') is ClassMirror);
-
-  // Check qualified lookup.
-  Expect.equals(variable, lookupQualifiedInScope(library, 'variable'));
-  Expect.equals(method, lookupQualifiedInScope(library, 'method'));
-  Expect.isTrue(lookupQualifiedInScope(library, 'method.a') is ParameterMirror);
-
-  Expect.equals(Class, lookupQualifiedInScope(library, 'Class'));
-  Expect.isTrue(
-      lookupQualifiedInScope(library, 'Class.A') is TypeVariableMirror);
-
-  Expect.isNull(library.lookupInScope('Class.field'));
-  Expect.equals(Class_field, lookupQualifiedInScope(library, 'Class.field'));
-
-  Expect.equals(Class_method, lookupQualifiedInScope(library, 'Class.method'));
-  Expect.isTrue(
-      lookupQualifiedInScope(library, 'Class.method.c') is ParameterMirror);
-
-  // `field` should not be found through the prefix `Subclass`.
-  Expect.isNull(lookupQualifiedInScope(library, 'Subclass.field'));
-  Expect.equals(Subclass_subfield,
-                lookupQualifiedInScope(library, 'Subclass.subfield'));
-
-  Expect.equals(Future_, lookupQualifiedInScope(library, 'async.Future'));
-  Expect.isTrue(
-      lookupQualifiedInScope(library, 'async.Future.then') is MethodMirror);
-  // `Timer` should not be found through the prefix `async.Future`.
-  Expect.isNull(
-      lookupQualifiedInScope(library, 'async.Future.Timer'));
-}
diff --git a/tests/compiler/dart2js/mirrors_metadata_test.dart b/tests/compiler/dart2js/mirrors_metadata_test.dart
deleted file mode 100644
index 4097da7..0000000
--- a/tests/compiler/dart2js/mirrors_metadata_test.dart
+++ /dev/null
@@ -1,86 +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.
-
-import 'package:expect/expect.dart';
-import "package:async_helper/async_helper.dart";
-import 'dart:async';
-import 'mirror_system_helper.dart';
-
-Future validateDeclarationComment(String code,
-                                String text,
-                                String trimmedText,
-                                bool isDocComment,
-                                List<Symbol> declarationNames) {
-  return createMirrorSystem(code).then((mirrors) {
-    LibraryMirror library = mirrors.libraries[SOURCE_URI];
-    Expect.isNotNull(library);
-    for (Symbol declarationName in declarationNames) {
-      DeclarationMirror declaration = library.declarations[declarationName];
-      Expect.isNotNull(declaration);
-      List<InstanceMirror> metadata = declaration.metadata;
-      Expect.isNotNull(metadata);
-      Expect.equals(1, metadata.length);
-      Expect.isTrue(metadata[0] is CommentInstanceMirror);
-      CommentInstanceMirror commentMetadata = metadata[0];
-      Expect.equals(text, commentMetadata.text);
-      Expect.equals(trimmedText, commentMetadata.trimmedText);
-      Expect.equals(isDocComment, commentMetadata.isDocComment);
-    }
-  });
-}
-
-Future testDeclarationComment(String declaration,
-                              List<Symbol> declarationNames) {
-  return Future.forEach([
-    () {
-      String text = 'Single line comment';
-      String comment = '// $text';
-      String code = '$comment\n$declaration';
-      return validateDeclarationComment(
-          code, comment, text, false, declarationNames);
-    },
-    () {
-      String text = 'Single line comment';
-      String comment = '/// $text';
-      String code = '$comment\n$declaration';
-      return validateDeclarationComment(
-          code, comment, text, true, declarationNames);
-    },
-    () {
-      String text = 'Multiline comment';
-      String comment = '/* $text*/';
-      String code = '$comment$declaration';
-      return validateDeclarationComment(
-          code, comment, text, false, declarationNames);
-    },
-    () {
-      String text = 'Multiline comment';
-      String comment = '/** $text*/';
-      String code = '$comment$declaration';
-      return validateDeclarationComment(
-          code, comment, text, true, declarationNames);
-    },
-  ], (f) => f());
-}
-
-void main() {
-  asyncTest(() => Future.forEach([
-    () => testDeclarationComment('var field;', [#field]),
-    () => testDeclarationComment('int field;', [#field]),
-    () => testDeclarationComment('int field = 0;', [#field]),
-    () => testDeclarationComment('int field1, field2;', [#field1, #field2]),
-    () => testDeclarationComment('final field = 0;', [#field]),
-    () => testDeclarationComment('final int field = 0;', [#field]),
-    () => testDeclarationComment('final field1 = 0, field2 = 0;',
-                                 [#field1, #field2]),
-    () => testDeclarationComment('final int field1 = 0, field2 = 0;',
-                                 [#field1, #field2]),
-    () => testDeclarationComment('const field = 0;', [#field]),
-    () => testDeclarationComment('const int field = 0;', [#field]),
-    () => testDeclarationComment('const field1 = 0, field2 = 0;',
-                                 [#field1, #field2]),
-    () => testDeclarationComment('const int field1 = 0, field2 = 0;',
-                                 [#field1, #field2]),
-  ], (f) => f()));
-}
diff --git a/tests/compiler/dart2js/mirrors_mixin_test.dart b/tests/compiler/dart2js/mirrors_mixin_test.dart
deleted file mode 100644
index d5ab821..0000000
--- a/tests/compiler/dart2js/mirrors_mixin_test.dart
+++ /dev/null
@@ -1,240 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library mirrors_mixin_test;
-
-import 'package:expect/expect.dart';
-import 'package:async_helper/async_helper.dart';
-import 'mirror_system_helper.dart';
-
-const String CLASS_SOURCE = '''
-class A {}
-
-class S {}
-class M1<T> {}
-class M2 {}
-
-class C extends S with M1<A> {}
-class D extends S with M1, M2 {}
-class E extends S with M2, M1 implements A, M1 {}
-class E2 extends E {}
-
-class F = S with M1<A>;
-abstract class G = S with M1, M2;
-class H = S with M2, M1 implements A, M1;
-class H2 extends H {}
-''';
-
-void main() {
-  asyncTest(() => createMirrorSystem(CLASS_SOURCE).then((MirrorSystem mirrors) {
-    LibraryMirror library = mirrors.libraries[SOURCE_URI];
-
-    checkSimpleClass(var cls) {
-      Expect.isNotNull(cls);
-      Expect.isTrue(cls is ClassMirror);
-      Expect.isFalse(isMixinApplication(cls));
-      Expect.isFalse(cls.isNameSynthetic);
-      Expect.isFalse(isObject(cls));
-      Expect.isTrue(isObject(cls.superclass));
-      Expect.equals(0, cls.superinterfaces.length);
-
-      Expect.isTrue(isObject(getSuperclass(cls)));
-      Expect.isTrue(getAppliedMixins(cls).isEmpty);
-      Expect.isTrue(getExplicitInterfaces(cls).isEmpty);
-    }
-
-    // class A {}
-    var A = library.declarations[#A];
-    checkSimpleClass(A);
-
-    // class S {}
-    var S = library.declarations[#S];
-    checkSimpleClass(S);
-
-    // class M1 {}
-    var M1 = library.declarations[#M1];
-    checkSimpleClass(M1);
-
-    // class M2 {}
-    var M2 = library.declarations[#M2];
-    checkSimpleClass(M2);
-
-    // class C extends S with M1<A> {}
-    var C = library.declarations[#C];
-    Expect.isNotNull(C);
-    Expect.isTrue(C is ClassMirror);
-    Expect.isFalse(isMixinApplication(C));
-    Expect.isFalse(isObject(C));
-    Expect.equals(0, C.superinterfaces.length);
-    var C_super = C.superclass;
-    Expect.isNotNull(C_super);
-    Expect.isTrue(C_super is ClassMirror);
-    Expect.isTrue(isMixinApplication(C_super));
-    Expect.isTrue(C_super.isNameSynthetic);
-    Expect.equals(1, C_super.superinterfaces.length);
-    Expect.isTrue(containsType(M1, [A], C_super.superinterfaces));
-    Expect.isTrue(isInstance(M1, [A], C_super.mixin));
-    Expect.isFalse(isObject(C_super));
-    Expect.isTrue(isSameDeclaration(S, C_super.superclass));
-
-    Expect.isTrue(isSameDeclaration(S, getSuperclass(C)));
-    Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(C)));
-    Expect.isTrue(getExplicitInterfaces(C).isEmpty);
-
-    // D extends S with M1, M2 {}
-    var D = library.declarations[#D];
-    Expect.isNotNull(D);
-    Expect.isTrue(D is ClassMirror);
-    Expect.isFalse(isMixinApplication(D));
-    Expect.isFalse(isObject(D));
-    Expect.equals(0, D.superinterfaces.length);
-    var D_super = D.superclass;
-    Expect.isNotNull(D_super);
-    Expect.isTrue(D_super is ClassMirror);
-    Expect.isTrue(isMixinApplication(D_super));
-    Expect.isTrue(D_super.isNameSynthetic);
-    Expect.equals(1, D_super.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(M2, D_super.superinterfaces));
-    Expect.isTrue(isSameDeclaration(M2, D_super.mixin));
-    Expect.isFalse(isObject(D_super));
-    Expect.isFalse(isSameDeclaration(S, D_super.superclass));
-    var D_super_super = D_super.superclass;
-    Expect.isNotNull(D_super_super);
-    Expect.isTrue(D_super_super is ClassMirror);
-    Expect.isTrue(isMixinApplication(D_super_super));
-    Expect.isTrue(D_super_super.isNameSynthetic);
-    Expect.equals(1, D_super_super.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(M1, D_super_super.superinterfaces));
-    Expect.isTrue(isSameDeclaration(M1, D_super_super.mixin));
-    Expect.isFalse(isObject(D_super_super));
-    Expect.isTrue(isSameDeclaration(S, D_super_super.superclass));
-
-    Expect.isTrue(isSameDeclaration(S, getSuperclass(D)));
-    Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(D)));
-    Expect.isTrue(getExplicitInterfaces(D).isEmpty);
-
-    // class E extends S with M2, M1 implements A, M1 {}
-    var E = library.declarations[#E];
-    Expect.isNotNull(E);
-    Expect.isTrue(E is ClassMirror);
-    Expect.isFalse(isMixinApplication(E));
-    Expect.isFalse(isObject(E));
-    Expect.equals(2, E.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(A, E.superinterfaces));
-    Expect.isTrue(containsDeclaration(M1, E.superinterfaces));
-    var E_super = E.superclass;
-    Expect.isNotNull(E_super);
-    Expect.isTrue(E_super is ClassMirror);
-    Expect.isTrue(isMixinApplication(E_super));
-    Expect.isTrue(E_super.isNameSynthetic);
-    Expect.equals(1, E_super.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(M1, E_super.superinterfaces));
-    Expect.isTrue(isSameDeclaration(M1, E_super.mixin));
-    Expect.isFalse(isObject(E_super));
-    Expect.isFalse(isSameDeclaration(S, E_super.superclass));
-    var E_super_super = E_super.superclass;
-    Expect.isNotNull(E_super_super);
-    Expect.isTrue(E_super_super is ClassMirror);
-    Expect.isTrue(isMixinApplication(E_super_super));
-    Expect.isTrue(E_super_super.isNameSynthetic);
-    Expect.equals(1, E_super_super.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(M2, E_super_super.superinterfaces));
-    Expect.isTrue(isSameDeclaration(M2, E_super_super.mixin));
-    Expect.isFalse(isObject(E_super_super));
-    Expect.isTrue(isSameDeclaration(S, E_super_super.superclass));
-
-    Expect.isTrue(isSameDeclaration(S, getSuperclass(E)));
-    Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(E)));
-    Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(E)));
-
-    // class E2 extends E {}
-    var E2 = library.declarations[#E2];
-    Expect.isTrue(isSameDeclaration(E, getSuperclass(E2)));
-    Expect.isTrue(getAppliedMixins(E2).isEmpty);
-    Expect.isTrue(getExplicitInterfaces(E2).isEmpty);
-
-    // class F = S with M1<A>;
-    var F = library.declarations[#F];
-    Expect.isNotNull(F);
-    Expect.isTrue(F is ClassMirror);
-    Expect.isFalse(F.isAbstract);
-    Expect.isTrue(isMixinApplication(F));
-    Expect.isFalse(F.isNameSynthetic);
-    Expect.equals(#F, F.simpleName);
-    Expect.isFalse(isObject(F));
-    Expect.equals(1, F.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(M1, F.superinterfaces));
-    Expect.isTrue(isInstance(M1, [A], F.mixin));
-    var F_super = F.superclass;
-    Expect.isNotNull(F_super);
-    Expect.isTrue(F_super is ClassMirror);
-    Expect.isFalse(isMixinApplication(F_super));
-    Expect.isFalse(isObject(F_super));
-    Expect.isTrue(isSameDeclaration(S, F_super));
-
-    Expect.isTrue(isSameDeclaration(S, getSuperclass(F)));
-    Expect.isTrue(isSameDeclarationList([M1], getAppliedMixins(F)));
-    Expect.isTrue(getExplicitInterfaces(F).isEmpty);
-
-    // typedef G = abstract S with M1, M2;
-    var G = library.declarations[#G];
-    Expect.isNotNull(G);
-    Expect.isTrue(G is ClassMirror);
-    Expect.isTrue(G.isAbstract);
-    Expect.isTrue(isMixinApplication(G));
-    Expect.isFalse(G.isNameSynthetic);
-    Expect.equals(#G, G.simpleName);
-    Expect.isFalse(isObject(G));
-    Expect.equals(1, G.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(M2, G.superinterfaces));
-    Expect.isTrue(isSameDeclaration(M2, G.mixin));
-    var G_super = G.superclass;
-    Expect.isNotNull(G_super);
-    Expect.isTrue(G_super is ClassMirror);
-    Expect.isTrue(isMixinApplication(G_super));
-    Expect.equals(1, G_super.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(M1, G_super.superinterfaces));
-    Expect.isTrue(isSameDeclaration(M1, G_super.mixin));
-    Expect.isFalse(isObject(G_super));
-    Expect.isTrue(isSameDeclaration(S, G_super.superclass));
-
-    Expect.isTrue(isSameDeclaration(S, getSuperclass(G)));
-    Expect.isTrue(isSameDeclarationList([M1, M2], getAppliedMixins(G)));
-    Expect.isTrue(getExplicitInterfaces(G).isEmpty);
-
-    // typedef H = S with M2, M1 implements A, M1;
-    var H = library.declarations[#H];
-    Expect.isNotNull(H);
-    Expect.isTrue(H is ClassMirror);
-    Expect.isFalse(H.isAbstract);
-    Expect.isTrue(isMixinApplication(H));
-    Expect.isFalse(H.isNameSynthetic);
-    Expect.equals(#H, H.simpleName);
-    Expect.isFalse(isObject(H));
-    Expect.equals(3, H.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(A, H.superinterfaces));
-    Expect.isTrue(containsDeclaration(M1, H.superinterfaces));
-    Expect.isFalse(containsDeclaration(M2, H.superinterfaces));
-    Expect.isTrue(isSameDeclaration(M1, H.mixin));
-    var H_super = H.superclass;
-    Expect.isNotNull(H_super);
-    Expect.isTrue(H_super is ClassMirror);
-    Expect.isTrue(isMixinApplication(H_super));
-    Expect.equals(1, H_super.superinterfaces.length);
-    Expect.isTrue(containsDeclaration(M2, H_super.superinterfaces));
-    Expect.isTrue(isSameDeclaration(M2, H_super.mixin));
-    Expect.isFalse(isObject(H_super));
-    Expect.isTrue(isSameDeclaration(S, H_super.superclass));
-
-    Expect.isTrue(isSameDeclaration(S, getSuperclass(H)));
-    Expect.isTrue(isSameDeclarationList([M2, M1], getAppliedMixins(H)));
-    Expect.isTrue(isSameDeclarationSet([A, M1], getExplicitInterfaces(H)));
-
-    // class H2 extends H {}
-    var H2 = library.declarations[#H2];
-    Expect.isTrue(isSameDeclaration(H, getSuperclass(H2)));
-    Expect.isTrue(getAppliedMixins(H2).isEmpty);
-    Expect.isTrue(getExplicitInterfaces(H2).isEmpty);
-  }));
-}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/mirrors_used_test.dart b/tests/compiler/dart2js/mirrors_used_test.dart
index a96cf2a..71d92ae 100644
--- a/tests/compiler/dart2js/mirrors_used_test.dart
+++ b/tests/compiler/dart2js/mirrors_used_test.dart
@@ -69,7 +69,7 @@
     // 2. Some code was refactored, and there are more methods.
     // Either situation could be problematic, but in situation 2, it is often
     // acceptable to increase [expectedMethodCount] a little.
-    int expectedMethodCount = 431;
+    int expectedMethodCount = 449;
     Expect.isTrue(
         generatedCode.length <= expectedMethodCount,
         'Too many compiled methods: '
diff --git a/tests/compiler/dart2js/mock_compiler.dart b/tests/compiler/dart2js/mock_compiler.dart
index 59dc3da..9c5b770 100644
--- a/tests/compiler/dart2js/mock_compiler.dart
+++ b/tests/compiler/dart2js/mock_compiler.dart
@@ -41,6 +41,7 @@
     FunctionElementX;
 
 import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/common/tasks.dart' show Measurer;
 
 import 'package:compiler/src/deferred_load.dart' show
     DeferredLoadTask,
@@ -69,6 +70,7 @@
   final DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
   final ResolvedUriTranslator resolvedUriTranslator =
       new MockResolvedUriTranslator();
+  final Measurer measurer = new Measurer();
 
   MockCompiler.internal(
       {Map<String, String> coreSource,
diff --git a/tests/compiler/dart2js/no_such_method_enabled_test.dart b/tests/compiler/dart2js/no_such_method_enabled_test.dart
index ac8e480..c9e651a 100644
--- a/tests/compiler/dart2js/no_such_method_enabled_test.dart
+++ b/tests/compiler/dart2js/no_such_method_enabled_test.dart
@@ -271,6 +271,25 @@
           clsA.lookupMember('noSuchMethod')));
 }
 
+Future dummyImplTest13() async {
+  String source = """
+class A {
+  noSuchMethod(x) => super.noSuchMethod(x) as dynamic;
+}
+main() {
+  print(new A().foo());
+}
+""";
+  Uri uri = new Uri(scheme: 'source');
+  var compiler = compilerFor(source, uri);
+  await compiler.run(uri);
+  Expect.isFalse(compiler.backend.enabledNoSuchMethod);
+  ClassElement clsA = findElement(compiler, 'A');
+  Expect.isTrue(
+      compiler.backend.noSuchMethodRegistry.defaultImpls.contains(
+          clsA.lookupMember('noSuchMethod')));
+}
+
 main() {
   asyncTest(() async {
     await dummyImplTest();
@@ -285,5 +304,6 @@
     await dummyImplTest10();
     await dummyImplTest11();
     await dummyImplTest12();
+    await dummyImplTest13();
   });
 }
diff --git a/tests/compiler/dart2js/override_inheritance_test.dart b/tests/compiler/dart2js/override_inheritance_test.dart
index ef4387f..f44b871 100644
--- a/tests/compiler/dart2js/override_inheritance_test.dart
+++ b/tests/compiler/dart2js/override_inheritance_test.dart
@@ -30,7 +30,7 @@
     compiler.parseScript(source);
     var cls = compiler.mainApp.find('Class');
     cls.ensureResolved(compiler.resolution);
-    MembersCreator.computeAllClassMembers(compiler, cls);
+    MembersCreator.computeAllClassMembers(compiler.resolution, cls);
 
     toList(o) => o == null ? [] : o is List ? o : [o];
 
diff --git a/tests/compiler/dart2js/parser_helper.dart b/tests/compiler/dart2js/parser_helper.dart
index 13556b7..a86aebe 100644
--- a/tests/compiler/dart2js/parser_helper.dart
+++ b/tests/compiler/dart2js/parser_helper.dart
@@ -92,6 +92,9 @@
         null, spannable,
         new Message(MessageTemplate.TEMPLATES[messageKind], arguments, false));
   }
+
+  @override
+  bool get hasReportedError => false;
 }
 
 Token scan(String text) =>
diff --git a/tests/compiler/dart2js/parser_test.dart b/tests/compiler/dart2js/parser_test.dart
index 2ee3d9e..762d074 100644
--- a/tests/compiler/dart2js/parser_test.dart
+++ b/tests/compiler/dart2js/parser_test.dart
@@ -319,7 +319,8 @@
   }
 
   @override
-  DiagnosticMessage createMessage(spannable, messageKind, [arguments]) {
+  DiagnosticMessage createMessage(
+      spannable, messageKind, [arguments = const {}]) {
     return new DiagnosticMessage(null, spannable, null);
   }
 }
diff --git a/tests/compiler/dart2js/patch_test.dart b/tests/compiler/dart2js/patch_test.dart
index 00ef722..2130f06 100644
--- a/tests/compiler/dart2js/patch_test.dart
+++ b/tests/compiler/dart2js/patch_test.dart
@@ -206,7 +206,7 @@
         }
 
         compiler.analyzeElement(origin);
-        compiler.enqueuer.resolution.emptyDeferredTaskQueue();
+        compiler.enqueuer.resolution.emptyDeferredQueueForTesting();
 
         DiagnosticCollector collector = compiler.diagnosticCollector;
         Expect.isTrue(collector.warnings.isEmpty,
diff --git a/tests/compiler/dart2js/quarantined/mirrors_test.dart b/tests/compiler/dart2js/quarantined/mirrors_test.dart
deleted file mode 100644
index 428442f..0000000
--- a/tests/compiler/dart2js/quarantined/mirrors_test.dart
+++ /dev/null
@@ -1,974 +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.
-
-import "package:expect/expect.dart";
-import "package:async_helper/async_helper.dart";
-import 'package:compiler/src/mirrors/source_mirrors.dart';
-import 'package:compiler/src/mirrors/mirrors_util.dart';
-import 'package:compiler/src/mirrors/analyze.dart';
-import 'package:compiler/src/filenames.dart'
-       show currentDirectory;
-import 'package:compiler/src/source_file_provider.dart';
-
-import 'dart:io';
-
-final Uri DART_MIRRORS_URI = new Uri(scheme: 'dart', path: 'mirrors');
-
-int count(Iterable iterable) {
-  var count = 0;
-  for (var element in iterable) {
-    count++;
-  }
-  return count;
-}
-
-bool containsType(TypeMirror expected, Iterable<TypeMirror> iterable) {
-  for (var element in iterable) {
-    if (element.originalDeclaration == expected.originalDeclaration) {
-      return true;
-    }
-  }
-  return false;
-}
-
-DeclarationMirror findMirror(Iterable<DeclarationMirror> list, Symbol name) {
-  for (DeclarationMirror mirror in list) {
-    if (mirror.simpleName == name) {
-      return mirror;
-    }
-  }
-  return null;
-}
-
-main() {
-  Uri scriptUri = currentDirectory.resolveUri(Platform.script);
-  Uri packageRoot = scriptUri.resolve('../packages/');
-  Uri libUri = scriptUri.resolve('../../../../sdk/');
-  Uri inputUri = scriptUri.resolve('../data/mirrors_helper.dart');
-  var provider = new CompilerSourceFileProvider();
-  var diagnosticHandler = new FormattingDiagnosticHandler(provider);
-  asyncStart();
-  var result = analyze([inputUri], libUri, packageRoot,
-                       provider.readStringFromUri, diagnosticHandler,
-                       <String>['--preserve-comments']);
-  result.then((MirrorSystem mirrors) {
-    test(mirrors);
-  }).then(asyncSuccess);
-}
-
-void test(MirrorSystem mirrors) {
-  Expect.isNotNull(mirrors, "No mirror system returned from compilation");
-
-  var libraries = mirrors.libraries;
-  Expect.isNotNull(libraries, "No libraries map returned");
-  Expect.isFalse(libraries.isEmpty, "Empty libraries map returned");
-
-  var helperLibrary = findMirror(libraries.values, #mirrors_helper);
-  Expect.isNotNull(helperLibrary, "Library 'mirrors_helper' not found");
-  Expect.equals(#mirrors_helper, helperLibrary.simpleName,
-    "Unexpected library simple name");
-  Expect.equals(#mirrors_helper, helperLibrary.qualifiedName,
-    "Unexpected library qualified name");
-  Expect.equals(helperLibrary, mirrors.findLibrary(#mirrors_helper));
-
-  var helperLibraryLocation = helperLibrary.location;
-  Expect.isNotNull(helperLibraryLocation);
-  Expect.equals(271, helperLibraryLocation.offset, "Unexpected offset");
-  Expect.equals(23, helperLibraryLocation.length, "Unexpected length");
-  Expect.equals(9, helperLibraryLocation.line, "Unexpected line");
-  Expect.equals(1, helperLibraryLocation.column, "Unexpected column");
-
-
-  var declarations = helperLibrary.declarations;
-  Expect.isNotNull(declarations, "No declarations map returned");
-  Expect.isFalse(declarations.isEmpty, "Empty declarations map returned");
-
-  testFoo(mirrors, helperLibrary, declarations);
-  testBar(mirrors, helperLibrary, declarations);
-  testBaz(mirrors, helperLibrary, declarations);
-  // TODO(johnniwinther): Add test of class [Boz] and typedef [Func].
-  // TODO(johnniwinther): Add tests of type argument substitution, which
-  // is not currently implemented in dart2js.
-  // TODO(johnniwinther): Add tests of Location and Source.
-  testPrivate(mirrors, helperLibrary, declarations);
-}
-
-// Testing class Foo:
-//
-// class Foo {
-//
-// }
-void testFoo(MirrorSystem system, LibraryMirror helperLibrary,
-             Map<Symbol, DeclarationMirror> declarations) {
-  var fooClass = declarations[#Foo];
-  Expect.isNotNull(fooClass, "Type 'Foo' not found");
-  Expect.isTrue(fooClass is ClassMirror,
-                "Unexpected mirror type returned");
-  Expect.equals(#Foo, fooClass.simpleName,
-                      "Unexpected type simple name");
-  Expect.equals(#mirrors_helper.Foo, fooClass.qualifiedName,
-                      "Unexpected type qualified name");
-
-  Expect.equals(helperLibrary, getLibrary(fooClass),
-                "Unexpected library returned from type");
-
-  Expect.isFalse(isObject(fooClass), "Class is Object");
-  Expect.isFalse(fooClass.isDynamic, "Class is dynamic");
-  Expect.isFalse(fooClass.isVoid, "Class is void");
-  Expect.isFalse(fooClass is TypeVariableMirror, "Class is a type variable");
-  Expect.isFalse(fooClass is TypedefMirror, "Class is a typedef");
-  Expect.isFalse(fooClass is FunctionTypeMirror, "Class is a function");
-
-  Expect.isTrue(fooClass.isOriginalDeclaration);
-  Expect.equals(fooClass, fooClass.originalDeclaration);
-
-  Expect.isTrue(fooClass is ClassMirror, "Class is not class");
-  Expect.isFalse(fooClass.isAbstract);
-  Expect.isFalse(fooClass.isPrivate, "Class is private");
-
-  var objectType = fooClass.superclass;
-  Expect.isNotNull(objectType, "Superclass is null");
-  Expect.isTrue(isObject(objectType), "Object is not Object");
-  Expect.isTrue(objectType.isOriginalDeclaration);
-  Expect.isTrue(containsType(fooClass,
-                             computeSubdeclarations(system, objectType)),
-                "Class is not subclass of superclass");
-
-  var fooInterfaces = fooClass.superinterfaces;
-  Expect.isNotNull(fooInterfaces, "Interfaces map is null");
-  Expect.isTrue(fooInterfaces.isEmpty, "Interfaces map is not empty");
-
-  var fooSubdeclarations = computeSubdeclarations(system, fooClass);
-  Expect.equals(1, count(fooSubdeclarations), "Unexpected subtype count");
-  for (var fooSubdeclaration in fooSubdeclarations) {
-    Expect.equals(fooClass, fooSubdeclaration.superclass.originalDeclaration);
-  }
-
-  Expect.isTrue(fooClass.typeArguments.isEmpty);
-  var fooClassTypeVariables = fooClass.typeVariables;
-  Expect.isNotNull(fooClassTypeVariables, "Type variable list is null");
-  Expect.isTrue(fooClassTypeVariables.isEmpty,
-                "Type variable list is not empty");
-
-  var fooClassMembers = fooClass.declarations;
-  Expect.isNotNull(fooClassMembers, "Declared members map is null");
-  Expect.equals(1, fooClassMembers.length);
-
-  var fooM = fooClassMembers[#m];
-  Expect.isNotNull(fooM);
-  Expect.isTrue(fooM is MethodMirror);
-  Expect.equals(1, fooM.parameters.length);
-  var fooMa = fooM.parameters[0];
-  Expect.isNotNull(fooMa);
-  Expect.isTrue(fooMa is ParameterMirror);
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Metadata tests
-  //////////////////////////////////////////////////////////////////////////////
-
-  var metadataList = fooClass.metadata;
-  Expect.isNotNull(metadataList);
-  Expect.equals(14, metadataList.length);
-  var metadataListIndex = 0;
-  var metadata;
-
-  var dartMirrorsLibrary = system.libraries[DART_MIRRORS_URI];
-  Expect.isNotNull(dartMirrorsLibrary);
-  var commentType = dartMirrorsLibrary.declarations[#Comment];
-  Expect.isNotNull(commentType);
-
-  // /// Singleline doc comment.
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is CommentInstanceMirror,
-      "Unexpected metadata: $metadata");
-  Expect.equals(commentType.originalDeclaration, metadata.type);
-  Expect.isTrue(metadata.isDocComment);
-  Expect.stringEquals(
-      "/// Singleline doc comment.", metadata.text);
-  Expect.stringEquals(
-      "Singleline doc comment.", metadata.trimmedText);
-
-  // @Metadata(null)
-  metadata = metadataList[metadataListIndex++];
-  var metadataType = metadata.type;
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadataType.isOriginalDeclaration);
-  InstanceMirror data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.isNull(data.reflectee);
-
-  // Singleline comment 1.
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is CommentInstanceMirror);
-  Expect.equals(commentType.originalDeclaration, metadata.type);
-  Expect.isFalse(metadata.isDocComment);
-  Expect.stringEquals(
-      "// Singleline comment 1.", metadata.text);
-  Expect.stringEquals(
-      "Singleline comment 1.", metadata.trimmedText);
-
-  // Singleline comment 2.
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is CommentInstanceMirror);
-  Expect.equals(commentType.originalDeclaration, metadata.type);
-  Expect.isFalse(metadata.isDocComment);
-  Expect.stringEquals(
-      "// Singleline comment 2.", metadata.text);
-  Expect.stringEquals(
-      "Singleline comment 2.", metadata.trimmedText);
-
-  // @Metadata(true)
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.isTrue(data.reflectee);
-
-  // @Metadata(false)
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.isFalse(data.reflectee);
-
-  // @Metadata(0)
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.equals(0, data.reflectee);
-
-  // @Metadata(1.5)
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.equals(1.5, data.reflectee);
-
-  // @Metadata("Foo")
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.stringEquals("Foo", data.reflectee);
-
-  // @Metadata(const ["Foo"])
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  data = metadata.getField(#data);
-  Expect.isTrue(data is ListInstanceMirror);
-  Expect.isFalse(data.hasReflectee);
-  Expect.throws(() => data.reflectee, (_) => true);
-  ListInstanceMirror listData = data;
-  Expect.equals(1, listData.length);
-  InstanceMirror element = listData.getElement(0);
-  Expect.isNotNull(element);
-  Expect.isTrue(element.hasReflectee);
-  Expect.stringEquals("Foo", element.reflectee);
-
-  // @Metadata(/* Inline comment */ const {'foo':"Foo"})
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  data = metadata.getField(#data);
-  Expect.isTrue(data is MapInstanceMirror);
-  Expect.isFalse(data.hasReflectee);
-  Expect.throws(() => data.reflectee, (_) => true);
-  MapInstanceMirror mapData = data;
-  Expect.equals(1, mapData.length);
-  var it = mapData.keys.iterator;
-  Expect.isTrue(it.moveNext());
-  Expect.stringEquals('foo', it.current);
-  element = mapData.getValue('foo');
-  Expect.isNotNull(element);
-  Expect.isTrue(element.hasReflectee);
-  Expect.stringEquals("Foo", element.reflectee);
-  Expect.isNull(mapData.getValue('bar'));
-
-  // @metadata
-  var metadataRef = metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.equals(metadataType.originalDeclaration, metadata.type);
-  data = metadata.getField(#data);
-  Expect.isNotNull(data);
-  Expect.isTrue(data.hasReflectee);
-  Expect.isNull(data.reflectee);
-
-  // /** Multiline doc comment. */
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is CommentInstanceMirror);
-  Expect.equals(commentType.originalDeclaration, metadata.type);
-  Expect.isTrue(metadata.isDocComment);
-  Expect.stringEquals(
-      "/** Multiline doc comment. */", metadata.text);
-  Expect.stringEquals(
-      "Multiline doc comment. ", metadata.trimmedText);
-
-  // /* Multiline comment. */
-  metadata = metadataList[metadataListIndex++];
-  Expect.isTrue(metadata is InstanceMirror);
-  Expect.isFalse(metadata.hasReflectee);
-  Expect.throws(() => metadata.reflectee, (_) => true);
-  Expect.isTrue(metadata is CommentInstanceMirror);
-  Expect.equals(commentType.originalDeclaration, metadata.type);
-  Expect.isFalse(metadata.isDocComment);
-  Expect.stringEquals(
-      "/* Multiline comment. */", metadata.text);
-  Expect.stringEquals(
-      "Multiline comment. ", metadata.trimmedText);
-
-  Expect.equals(metadataList.length, metadataListIndex);
-
-  Expect.isNotNull(fooMa.metadata);
-  Expect.equals(1, fooMa.metadata.length);
-  Expect.equals(metadataRef, fooMa.metadata[0]);
-
-  //////////////////////////////////////////////////////////////////////////////
-  // Location test
-  //////////////////////////////////////////////////////////////////////////////
-
-  var fooClassLocation = fooClass.location;
-  Expect.isNotNull(fooClassLocation);
-  // Expect the location to start with the first metadata, not including the
-  // leading comment.
-  Expect.equals(376, fooClassLocation.offset, "Unexpected offset");
-  // Expect the location to end with the class body.
-  Expect.equals(298, fooClassLocation.length, "Unexpected length");
-  Expect.equals(18, fooClassLocation.line, "Unexpected line");
-  Expect.equals(1, fooClassLocation.column, "Unexpected column");
-
-}
-
-// Testing abstract class Bar:
-//
-// abstract class Bar<E> {
-//
-// }
-void testBar(MirrorSystem system, LibraryMirror helperLibrary,
-             Map<Symbol, DeclarationMirror> classes) {
-  var barClass = classes[#Bar];
-  Expect.isNotNull(barClass, "Type 'Bar' not found");
-  Expect.isTrue(barClass is ClassMirror,
-               "Unexpected mirror type returned");
-  Expect.equals(#Bar, barClass.simpleName,
-                      "Unexpected type simple name");
-  Expect.equals(#mirrors_helper.Bar, barClass.qualifiedName,
-                "Unexpected type qualified name");
-
-  Expect.equals(helperLibrary, getLibrary(barClass),
-                "Unexpected library returned from type");
-
-  Expect.isFalse(isObject(barClass), "Interface is Object");
-  Expect.isFalse(barClass.isDynamic, "Interface is dynamic");
-  Expect.isFalse(barClass.isVoid, "Interface is void");
-  Expect.isFalse(barClass is TypeVariableMirror, "Interface is a type variable");
-  Expect.isFalse(barClass is TypedefMirror, "Interface is a typedef");
-  Expect.isFalse(barClass is FunctionTypeMirror, "Interface is a function");
-
-  Expect.isTrue(barClass.isOriginalDeclaration);
-  Expect.equals(barClass, barClass.originalDeclaration);
-
-  Expect.isTrue(barClass is ClassMirror);
-  Expect.isTrue(barClass.isAbstract);
-  Expect.isFalse(barClass.isPrivate, "Interface is private");
-
-  var objectType = barClass.superclass;
-  Expect.isNotNull(objectType, "Superclass is null");
-  Expect.isTrue(isObject(objectType), "Object is not Object");
-  Expect.isTrue(objectType.isOriginalDeclaration);
-  Expect.isTrue(containsType(barClass,
-                             computeSubdeclarations(system, objectType)),
-                "Class is not subclass of superclass");
-
-  var barInterfaces = barClass.superinterfaces;
-  Expect.isNotNull(barInterfaces, "Interfaces map is null");
-  Expect.isTrue(barInterfaces.isEmpty, "Interfaces map is not empty");
-
-  var barSubdeclarations = computeSubdeclarations(system, barClass);
-  Expect.equals(1, count(barSubdeclarations), "Unexpected subtype count");
-  for (var barSubdeclaration in barSubdeclarations) {
-    Expect.isTrue(containsType(barClass,
-                               barSubdeclaration.superinterfaces),
-                  "Interface is not superinterface of subclass");
-  }
-
-  Expect.isTrue(barClass.typeArguments.isEmpty);
-  var barInterfaceTypeVariables = barClass.typeVariables;
-  Expect.isNotNull(barInterfaceTypeVariables, "Type variable list is null");
-  Expect.isFalse(barInterfaceTypeVariables.isEmpty,
-                 "Type variable list is empty");
-  Expect.equals(barInterfaceTypeVariables.length, 1,
-                "Unexpected number of type variables");
-
-  var barE = barInterfaceTypeVariables[0];
-  Expect.isNotNull(barE, "Type variable is null");
-  Expect.isTrue(barE is TypeVariableMirror);
-
-  var barInterfaceMembers = barClass.declarations;
-  Expect.isNotNull(barInterfaceMembers, "Declared members map is null");
-  Expect.isTrue(barInterfaceMembers.isEmpty,
-                "Declarations map is unempty");
-
-  var metadata = barClass.metadata;
-  Expect.isNotNull(metadata);
-  Expect.equals(0, metadata.length);
-}
-
-// Testing class Baz:
-//
-// class Baz<E,F extends Foo> implements Bar<E> {
-//   Baz();
-//   const Baz.named();
-//   factory Baz.factory() => new Baz<E,F>();
-//
-//   static method1(e) {}
-//   void method2(E e, [F f = null]) {}
-//   Baz<E,F> method3(E func1(F f), Func<E,F> func2) => null;
-//
-//   bool operator==(Object other) => false;
-//   int operator -() => 0;
-//   operator$foo() {}
-// }
-void testBaz(MirrorSystem system, LibraryMirror helperLibrary,
-             Map<Symbol, DeclarationMirror> declarations) {
-  var bazClass = declarations[#Baz];
-  Expect.isNotNull(bazClass, "Type 'Baz' not found");
-  Expect.isTrue(bazClass is ClassMirror,
-                "Unexpected mirror type returned");
-  Expect.equals(#Baz, bazClass.simpleName,
-                "Unexpected type simple name");
-  Expect.equals(#mirrors_helper.Baz, bazClass.qualifiedName,
-                "Unexpected type qualified name");
-
-  Expect.equals(helperLibrary, getLibrary(bazClass),
-                "Unexpected library returned from type");
-
-  Expect.isFalse(isObject(bazClass), "Class is Object");
-  Expect.isFalse(bazClass.isDynamic, "Class is dynamic");
-  Expect.isFalse(bazClass.isVoid, "Class is void");
-  Expect.isFalse(bazClass is TypeVariableMirror, "Class is a type variable");
-  Expect.isFalse(bazClass is TypedefMirror, "Class is a typedef");
-  Expect.isFalse(bazClass is FunctionTypeMirror, "Class is a function");
-
-  Expect.isTrue(bazClass.isOriginalDeclaration);
-  Expect.equals(bazClass, bazClass.originalDeclaration);
-
-  Expect.isTrue(bazClass is ClassMirror, "Class is not class");
-  Expect.isFalse(bazClass.isAbstract);
-  Expect.isFalse(bazClass.isPrivate, "Class is private");
-
-  var objectType = bazClass.superclass;
-  Expect.isNotNull(objectType, "Superclass is null");
-  Expect.isTrue(isObject(objectType), "Object is not Object");
-  Expect.isTrue(objectType.isOriginalDeclaration);
-  Expect.isTrue(containsType(bazClass,
-                             computeSubdeclarations(system, objectType)),
-                "Class is not subclass of superclass");
-
-  var bazInterfaces = bazClass.superinterfaces;
-  Expect.isNotNull(bazInterfaces, "Interfaces map is null");
-  Expect.isTrue(!bazInterfaces.isEmpty, "Interfaces map is empty");
-  for (var bazInterface in bazInterfaces) {
-    Expect.isTrue(containsType(bazClass,
-                               computeSubdeclarations(system, objectType)),
-                  "Class is not subclass of superinterface");
-  }
-
-  var bazSubdeclarations = computeSubdeclarations(system, bazClass);
-  Expect.equals(0, count(bazSubdeclarations), "Unexpected subtype count");
-
-  var barInterface = findMirror(bazInterfaces, #Bar);
-  Expect.isNotNull(barInterface, "Interface bar is missing");
-  Expect.isFalse(barInterface.isOriginalDeclaration);
-  var barInterfaceTypeArguments = barInterface.typeArguments;
-  Expect.isNotNull(barInterfaceTypeArguments, "Type arguments are missing");
-  Expect.equals(1, barInterfaceTypeArguments.length,
-                "Type arguments is empty");
-
-  Expect.isTrue(bazClass.typeArguments.isEmpty, "Class has type arguments");
-  var bazClassTypeVariables = bazClass.typeVariables;
-  Expect.isNotNull(bazClassTypeVariables, "Type variable list is null");
-  Expect.equals(2, bazClassTypeVariables.length,
-                "Type variable list is not empty");
-
-  var bazE = bazClassTypeVariables[0];
-  Expect.isNotNull(bazE, "Type variable is null");
-  Expect.equals(#E, bazE.simpleName, "Unexpected simpleName");
-  Expect.equals(#mirrors_helper.Baz.E, bazE.qualifiedName,
-                "Unexpected qualifiedName");
-  Expect.equals(bazClass, bazE.owner,
-                "Unexpected type variable declarer");
-  var bazEbound = bazE.upperBound;
-  Expect.isNotNull(bazEbound);
-  Expect.isTrue(bazEbound.isOriginalDeclaration);
-  Expect.isTrue(isObject(bazEbound), "Bound is not object");
-
-  var bazF = bazClassTypeVariables[1];
-  Expect.isNotNull(bazF, "Type variable is null");
-  Expect.equals(#F, bazF.simpleName, "Unexpected simpleName");
-  Expect.equals(#mirrors_helper.Baz.F, bazF.qualifiedName,
-                "Unexpected qualifiedName");
-  Expect.equals(bazClass, bazF.owner);
-  var bazFbound = bazF.upperBound;
-  Expect.isNotNull(bazFbound);
-  Expect.isTrue(bazFbound.isOriginalDeclaration);
-  Expect.equals(#mirrors_helper.Foo, bazFbound.qualifiedName,
-                "Bound is not Foo");
-
-  var bazClassMembers = bazClass.declarations;
-  Expect.isNotNull(bazClassMembers, "Declared members map is null");
-  Expect.equals(9, bazClassMembers.length,
-                "Unexpected number of declared members");
-
-  ////////////////////////////////////////////////////////////////////////////
-  // static method1(e) {}
-  ////////////////////////////////////////////////////////////////////////////
-  var method1 = bazClassMembers[#method1];
-  Expect.isNotNull(method1, "method1 not found");
-  Expect.equals(#method1, method1.simpleName);
-  Expect.equals(#mirrors_helper.Baz.method1, method1.qualifiedName);
-  Expect.equals(method1.owner, bazClass);
-  Expect.isFalse(method1.isTopLevel);
-  Expect.isTrue(method1 is MethodMirror);
-  Expect.isFalse(method1.isConstructor);
-  Expect.isFalse(method1.isPrivate);
-  Expect.isTrue(method1.isStatic);
-  Expect.isTrue(method1.isRegularMethod);
-  Expect.isFalse(method1.isConstConstructor);
-  Expect.isFalse(method1.isGenerativeConstructor);
-  Expect.isFalse(method1.isRedirectingConstructor);
-  Expect.isFalse(method1.isFactoryConstructor);
-  Expect.isFalse(method1.isGetter);
-  Expect.isFalse(method1.isSetter);
-  Expect.isFalse(method1.isOperator);
-
-  var dynamicType = method1.returnType;
-  Expect.isNotNull(dynamicType, "Return type was null");
-  Expect.isFalse(isObject(dynamicType), "dynamic is Object");
-  Expect.isTrue(dynamicType.isDynamic, "dynamic is not dynamic");
-  Expect.isFalse(dynamicType.isVoid, "dynamic is void");
-  Expect.isFalse(dynamicType is TypeVariableMirror, "dynamic is a type variable");
-  Expect.isFalse(dynamicType is TypedefMirror, "dynamic is a typedef");
-  Expect.isFalse(dynamicType is FunctionTypeMirror, "dynamic is a function");
-
-  var method1Parameters = method1.parameters;
-  Expect.isNotNull(method1Parameters, "Method parameters is null");
-  Expect.equals(1, method1Parameters.length, "Unexpected parameter count");
-  var method1Parameter1 = method1Parameters[0];
-  Expect.isNotNull(method1Parameter1, "Parameter is null");
-  Expect.equals(dynamicType, method1Parameter1.type);
-  Expect.equals(#e, method1Parameter1.simpleName);
-  Expect.equals(#mirrors_helper.Baz.method1.e, method1Parameter1.qualifiedName);
-  Expect.isFalse(method1Parameter1.hasDefaultValue,
-    "Parameter has default value");
-  Expect.isNull(method1Parameter1.defaultValue,
-    "Parameter default value is non-null");
-  Expect.isFalse(method1Parameter1.isOptional, "Parameter is optional");
-
-  ////////////////////////////////////////////////////////////////////////////
-  // static void method2(E e, [F f = null]) {}
-  ////////////////////////////////////////////////////////////////////////////
-  var method2 = bazClassMembers[#method2];
-  Expect.isNotNull(method2, "method2 not found");
-  Expect.equals(#method2, method2.simpleName);
-  Expect.equals(#mirrors_helper.Baz.method2, method2.qualifiedName);
-  Expect.equals(method2.owner, bazClass);
-  Expect.isFalse(method2.isTopLevel);
-  Expect.isTrue(method2 is MethodMirror);
-  Expect.isFalse(method2.isConstructor);
-  Expect.isFalse(method2.isPrivate);
-  Expect.isFalse(method2.isStatic);
-  Expect.isTrue(method2.isRegularMethod);
-  Expect.isFalse(method2.isConstConstructor);
-  Expect.isFalse(method2.isGenerativeConstructor);
-  Expect.isFalse(method2.isRedirectingConstructor);
-  Expect.isFalse(method2.isFactoryConstructor);
-  Expect.isFalse(method2.isGetter);
-  Expect.isFalse(method2.isSetter);
-  Expect.isFalse(method2.isOperator);
-
-  var voidType = method2.returnType;
-  Expect.isNotNull(voidType, "Return type was null");
-  Expect.isFalse(isObject(voidType), "void is Object");
-  Expect.isFalse(voidType.isDynamic, "void is dynamic");
-  Expect.isTrue(voidType.isVoid, "void is not void");
-  Expect.isFalse(voidType is TypeVariableMirror, "void is a type variable");
-  Expect.isFalse(voidType is TypedefMirror, "void is a typedef");
-  Expect.isFalse(voidType is FunctionTypeMirror, "void is a function");
-
-  var method2Parameters = method2.parameters;
-  Expect.isNotNull(method2Parameters, "Method parameters is null");
-  Expect.equals(2, method2Parameters.length, "Unexpected parameter count");
-  var method2Parameter1 = method2Parameters[0];
-  Expect.isNotNull(method2Parameter1, "Parameter is null");
-  Expect.equals(bazE, method2Parameter1.type);
-  Expect.equals(#e, method2Parameter1.simpleName);
-  Expect.equals(#mirrors_helper.Baz.method2.e, method2Parameter1.qualifiedName);
-  Expect.isFalse(method2Parameter1.hasDefaultValue,
-                      "Parameter has default value");
-  Expect.isNull(method2Parameter1.defaultValue,
-                "Parameter default value is non-null");
-  Expect.isFalse(method2Parameter1.isOptional, "Parameter is optional");
-  var method2Parameter2 = method2Parameters[1];
-  Expect.isNotNull(method2Parameter2, "Parameter is null");
-  Expect.equals(bazF, method2Parameter2.type);
-  Expect.equals(#f, method2Parameter2.simpleName);
-  Expect.equals(#mirrors_helper.Baz.method2.f,
-                method2Parameter2.qualifiedName);
-  Expect.isTrue(method2Parameter2.hasDefaultValue,
-                 "Parameter has default value");
-  Expect.isNotNull(method2Parameter2.defaultValue,
-                   "Parameter default value is null");
-  Expect.isTrue(method2Parameter2.isOptional, "Parameter is not optional");
-
-  ////////////////////////////////////////////////////////////////////////////
-  // Baz<E,F> method3(E func1(F f), Func<E,F> func2) => null;
-  ////////////////////////////////////////////////////////////////////////////
-  var method3 = bazClassMembers[#method3];
-  Expect.isNotNull(method3, "method3 not found");
-  Expect.equals(#method3, method3.simpleName);
-  Expect.equals(#mirrors_helper.Baz.method3, method3.qualifiedName);
-  Expect.equals(method3.owner, bazClass);
-  Expect.isFalse(method3.isTopLevel);
-  Expect.isTrue(method3 is MethodMirror);
-  Expect.isFalse(method3.isConstructor);
-  Expect.isFalse(method3.isPrivate);
-  Expect.isFalse(method3.isStatic);
-  Expect.isTrue(method3.isRegularMethod);
-  Expect.isFalse(method3.isConstConstructor);
-  Expect.isFalse(method3.isGenerativeConstructor);
-  Expect.isFalse(method3.isRedirectingConstructor);
-  Expect.isFalse(method3.isFactoryConstructor);
-  Expect.isFalse(method3.isGetter);
-  Expect.isFalse(method3.isSetter);
-  Expect.isFalse(method3.isOperator);
-
-  var method3ReturnType = method3.returnType;
-  Expect.isNotNull(method3ReturnType, "Return type is null");
-  Expect.isTrue(method3ReturnType is ClassMirror,
-                "Return type is not interface");
-  Expect.equals(bazClass, method3ReturnType.originalDeclaration);
-  // TODO(johnniwinther): Test type arguments of [method3ReturnType].
-
-  var method3Parameters = method3.parameters;
-  Expect.isNotNull(method3Parameters, "Method parameters is null");
-  Expect.equals(2, method3Parameters.length, "Unexpected parameter count");
-  var method3Parameter1 = method3Parameters[0];
-  Expect.isNotNull(method3Parameter1, "Parameter is null");
-  var method3Parameter1type = method3Parameter1.type;
-  Expect.isNotNull(method3Parameter1type, "Parameter type of 'func1' is null");
-  Expect.isTrue(method3Parameter1type is FunctionTypeMirror,
-                "Parameter type of 'func1' is not a function");
-  Expect.equals(bazE, method3Parameter1type.returnType,
-                "Return type of 'func1' is not a E");
-  Expect.isNotNull(method3Parameter1type.parameters,
-                   "Parameters of 'func1' is null");
-  Expect.equals(1, method3Parameter1type.parameters.length,
-                "Unexpected parameter count of 'func1'");
-  Expect.equals(bazE, method3Parameter1type.returnType,
-                "Return type of 'func1' is not a E");
-  Expect.isNotNull(method3Parameter1type.parameters[0],
-                "Parameter 1 of 'func1' is null");
-  Expect.equals(#f, method3Parameter1type.parameters[0].simpleName);
-  Expect.equals(bazF, method3Parameter1type.parameters[0].type,
-                "Argument type of 'func1' is not a F");
-  Expect.equals(#func1, method3Parameter1.simpleName);
-  Expect.equals(#mirrors_helper.Baz.method3.func1,
-                method3Parameter1.qualifiedName);
-  Expect.isFalse(method3Parameter1.hasDefaultValue,
-                 "Parameter has default value");
-  Expect.isNull(method3Parameter1.defaultValue,
-                "Parameter default value is non-null");
-  Expect.isFalse(method3Parameter1.isOptional, "Parameter is optional");
-
-  var method3Parameter2 = method3Parameters[1];
-  Expect.isNotNull(method3Parameter2, "Parameter is null");
-  var funcTypedef = method3Parameter2.type;
-  Expect.isNotNull(funcTypedef, "Parameter type is null");
-  Expect.equals(#Func, funcTypedef.simpleName);
-  Expect.equals(#mirrors_helper.Func, funcTypedef.qualifiedName);
-  Expect.isFalse(isObject(funcTypedef), "Typedef is Object");
-  Expect.isFalse(funcTypedef.isDynamic, "Typedef is dynamic");
-  Expect.isFalse(funcTypedef.isVoid, "Typedef is void");
-  Expect.isFalse(funcTypedef is TypeVariableMirror, "Typedef is a type variable");
-  Expect.isTrue(funcTypedef is TypedefMirror, "Typedef is not a typedef");
-  Expect.isFalse(funcTypedef is FunctionTypeMirror, "Typedef is a function");
-
-  Expect.equals(helperLibrary, getLibrary(funcTypedef),
-                "Unexpected typedef library");
-
-  Expect.isFalse(funcTypedef.isOriginalDeclaration);
-  Expect.isFalse(funcTypedef is ClassMirror, "Typedef is class");
-  Expect.isFalse(funcTypedef.isPrivate, "Typedef is private");
-  Expect.equals(2, funcTypedef.typeArguments.length);
-  var funcTypedefTypeVariables = funcTypedef.typeVariables;
-  Expect.isNotNull(funcTypedefTypeVariables);
-  Expect.equals(2, funcTypedefTypeVariables.length);
-
-  var funcTypedefDefinition = funcTypedef.referent;
-  Expect.isNotNull(funcTypedefDefinition);
-  Expect.isTrue(funcTypedefDefinition is FunctionTypeMirror);
-
-  Expect.equals(#func2, method3Parameter2.simpleName);
-  Expect.equals(#mirrors_helper.Baz.method3.func2,
-                method3Parameter2.qualifiedName);
-  Expect.isFalse(method3Parameter2.hasDefaultValue,
-                 "Parameter 'func2' has default value: "
-                 "${method3Parameter2.defaultValue}");
-  Expect.isNull(method3Parameter2.defaultValue,
-                "Parameter default value is non-null");
-  Expect.isFalse(method3Parameter2.isOptional, "Parameter is optional");
-
-  ////////////////////////////////////////////////////////////////////////////
-  // bool operator==(Object other) => false;
-  ////////////////////////////////////////////////////////////////////////////
-  var operator_eq = bazClassMembers[const Symbol('==')];
-  Expect.isNotNull(operator_eq, "operator == not found");
-  Expect.equals(const Symbol('=='), operator_eq.simpleName,
-                "Unexpected method simpleName");
-  Expect.stringEquals('operator ==', displayName(operator_eq));
-  Expect.equals(const Symbol('mirrors_helper.Baz.=='),
-                operator_eq.qualifiedName,
-                "Unexpected method qualifiedName");
-  Expect.equals(operator_eq.owner, bazClass);
-  Expect.isFalse(operator_eq.isTopLevel);
-  Expect.isTrue(operator_eq is MethodMirror);
-  Expect.isFalse(operator_eq.isConstructor);
-  Expect.isFalse(operator_eq.isPrivate);
-  Expect.isFalse(operator_eq.isStatic);
-  Expect.isTrue(operator_eq.isRegularMethod);
-  Expect.isFalse(operator_eq.isConstConstructor);
-  Expect.isFalse(operator_eq.isGenerativeConstructor);
-  Expect.isFalse(operator_eq.isRedirectingConstructor);
-  Expect.isFalse(operator_eq.isFactoryConstructor);
-  Expect.isFalse(operator_eq.isGetter);
-  Expect.isFalse(operator_eq.isSetter);
-  Expect.isTrue(operator_eq.isOperator);
-  Expect.stringEquals('==', operatorName(operator_eq));
-
-  ////////////////////////////////////////////////////////////////////////////
-  // int operator -() => 0;
-  ////////////////////////////////////////////////////////////////////////////
-  var operator_negate = bazClassMembers[const Symbol('unary-')];
-  Expect.isNotNull(operator_negate, "operator < not found");
-  Expect.equals(const Symbol('unary-'), operator_negate.simpleName,
-                      "Unexpected method simpleName");
-  Expect.stringEquals('operator -', displayName(operator_negate));
-  Expect.equals(const Symbol('mirrors_helper.Baz.unary-'),
-                      operator_negate.qualifiedName,
-                      "Unexpected method qualifiedName");
-  Expect.equals(operator_negate.owner, bazClass);
-  Expect.isFalse(operator_negate.isTopLevel);
-  Expect.isTrue(operator_negate is MethodMirror);
-  Expect.isFalse(operator_negate.isConstructor);
-  Expect.isFalse(operator_negate.isPrivate);
-  Expect.isFalse(operator_negate.isStatic);
-  Expect.isTrue(operator_negate.isRegularMethod);
-  Expect.isFalse(operator_negate.isConstConstructor);
-  Expect.isFalse(operator_negate.isGenerativeConstructor);
-  Expect.isFalse(operator_negate.isRedirectingConstructor);
-  Expect.isFalse(operator_negate.isFactoryConstructor);
-  Expect.isFalse(operator_negate.isGetter);
-  Expect.isFalse(operator_negate.isSetter);
-  Expect.isTrue(operator_negate.isOperator);
-  Expect.stringEquals('-', operatorName(operator_negate));
-
-
-  ////////////////////////////////////////////////////////////////////////////
-  // operator$foo() {}
-  ////////////////////////////////////////////////////////////////////////////
-  var operator$foo = bazClassMembers[#operator$foo];
-  Expect.isNotNull(operator$foo, "operator\$foo not found");
-  Expect.equals(#operator$foo, operator$foo.simpleName);
-  Expect.equals(#mirrors_helper.Baz.operator$foo, operator$foo.qualifiedName);
-  Expect.equals(operator$foo.owner, bazClass);
-  Expect.isFalse(operator$foo.isTopLevel);
-  Expect.isTrue(operator$foo is MethodMirror);
-  Expect.isFalse(operator$foo.isConstructor);
-  Expect.isFalse(operator$foo.isPrivate);
-  Expect.isFalse(operator$foo.isStatic);
-  Expect.isTrue(operator$foo.isRegularMethod);
-  Expect.isFalse(operator$foo.isConstConstructor);
-  Expect.isFalse(operator$foo.isGenerativeConstructor);
-  Expect.isFalse(operator$foo.isRedirectingConstructor);
-  Expect.isFalse(operator$foo.isFactoryConstructor);
-  Expect.isFalse(operator$foo.isGetter);
-  Expect.isFalse(operator$foo.isSetter);
-  Expect.isFalse(operator$foo.isOperator);
-
-  Expect.equals(dynamicType, operator$foo.returnType);
-
-  var operator$fooParameters = operator$foo.parameters;
-  Expect.isNotNull(operator$fooParameters, "Method parameters is null");
-  Expect.equals(0, operator$fooParameters.length, "Unexpected parameter count");
-
-  ////////////////////////////////////////////////////////////////////////////
-  //   Baz();
-  ////////////////////////////////////////////////////////////////////////////
-  var bazClassNonameConstructor = bazClassMembers[const Symbol('')];
-  Expect.isNotNull(bazClassNonameConstructor);
-  Expect.isTrue(bazClassNonameConstructor is MethodMirror);
-  Expect.isTrue(bazClassNonameConstructor.isConstructor);
-  Expect.isFalse(bazClassNonameConstructor.isRegularMethod);
-  Expect.isFalse(bazClassNonameConstructor.isConstConstructor);
-  Expect.isTrue(bazClassNonameConstructor.isGenerativeConstructor);
-  Expect.isFalse(bazClassNonameConstructor.isRedirectingConstructor);
-  Expect.isFalse(bazClassNonameConstructor.isFactoryConstructor);
-  Expect.equals(const Symbol(''), bazClassNonameConstructor.simpleName);
-  Expect.stringEquals('Baz', displayName(bazClassNonameConstructor));
-  Expect.equals(const Symbol('mirrors_helper.Baz.'),
-      bazClassNonameConstructor.qualifiedName);
-
-  ////////////////////////////////////////////////////////////////////////////
-  //   const Baz.named();
-  ////////////////////////////////////////////////////////////////////////////
-  var bazClassNamedConstructor = bazClassMembers[#named];
-  Expect.isNotNull(bazClassNamedConstructor);
-  Expect.isTrue(bazClassNamedConstructor is MethodMirror);
-  Expect.isTrue(bazClassNamedConstructor.isConstructor);
-  Expect.isFalse(bazClassNamedConstructor.isRegularMethod);
-  Expect.isTrue(bazClassNamedConstructor.isConstConstructor);
-  Expect.isFalse(bazClassNamedConstructor.isGenerativeConstructor);
-  Expect.isFalse(bazClassNamedConstructor.isRedirectingConstructor);
-  Expect.isFalse(bazClassNamedConstructor.isFactoryConstructor);
-  Expect.equals(#named, bazClassNamedConstructor.simpleName);
-  Expect.stringEquals('Baz.named', displayName(bazClassNamedConstructor));
-  Expect.equals(#mirrors_helper.Baz.named,
-      bazClassNamedConstructor.qualifiedName);
-
-  ////////////////////////////////////////////////////////////////////////////
-  //   factory Baz.factory() => new Baz<E,F>();
-  ////////////////////////////////////////////////////////////////////////////
-  var bazClassFactoryConstructor = bazClassMembers[#factory];
-  Expect.isNotNull(bazClassFactoryConstructor);
-  Expect.isTrue(bazClassFactoryConstructor is MethodMirror);
-  Expect.isTrue(bazClassFactoryConstructor.isConstructor);
-  Expect.isFalse(bazClassFactoryConstructor.isRegularMethod);
-  Expect.isFalse(bazClassFactoryConstructor.isConstConstructor);
-  Expect.isFalse(bazClassFactoryConstructor.isGenerativeConstructor);
-  Expect.isFalse(bazClassFactoryConstructor.isRedirectingConstructor);
-  Expect.isTrue(bazClassFactoryConstructor.isFactoryConstructor);
-  Expect.equals(#factory, bazClassFactoryConstructor.simpleName);
-  Expect.stringEquals('Baz.factory', displayName(bazClassFactoryConstructor));
-  Expect.equals(#mirrors_helper.Baz.factory,
-      bazClassFactoryConstructor.qualifiedName);
-
-  // TODO(johnniwinther): Add more tests of constructors.
-  // TODO(johnniwinther): Add a test for unnamed factory methods.
-
-  var metadata = bazClass.metadata;
-  Expect.isNotNull(metadata);
-  Expect.equals(0, metadata.length);
-}
-
-// class _PrivateClass {
-//   var _privateField;
-//   get _privateGetter => _privateField;
-//   void set _privateSetter(value) => _privateField = value;
-//   void _privateMethod() {}
-//   _PrivateClass._privateConstructor();
-//   factory _PrivateClass._privateFactoryConstructor() => new _PrivateClass();
-// }
-void testPrivate(MirrorSystem system, LibraryMirror helperLibrary,
-                 Map<Symbol, DeclarationMirror> declarations) {
-  var privateClass = declarations[const Symbol('_PrivateClass')];
-  Expect.isNotNull(privateClass);
-  Expect.isTrue(privateClass is ClassMirror);
-  Expect.isFalse(privateClass.isAbstract);
-  Expect.isTrue(privateClass.isPrivate);
-
-  var privateField = privateClass.declarations[const Symbol('_privateField')];
-  Expect.isNotNull(privateField);
-  Expect.isTrue(privateField is VariableMirror);
-  Expect.isTrue(privateField.isPrivate);
-
-  var privateGetter = privateClass.declarations[const Symbol('_privateGetter')];
-  Expect.isNotNull(privateGetter);
-  Expect.isTrue(privateGetter is MethodMirror);
-  Expect.isTrue(privateGetter.isGetter);
-  Expect.isTrue(privateGetter.isPrivate);
-  Expect.isFalse(privateGetter.isRegularMethod);
-
-  var privateSetter =
-      privateClass.declarations[const Symbol('_privateSetter=')];
-  Expect.isNotNull(privateSetter);
-  Expect.isTrue(privateSetter is MethodMirror);
-  Expect.isTrue(privateSetter.isSetter);
-  Expect.isTrue(privateSetter.isPrivate);
-  Expect.isFalse(privateSetter.isRegularMethod);
-
-  var privateMethod = privateClass.declarations[const Symbol('_privateMethod')];
-  Expect.isNotNull(privateMethod);
-  Expect.isTrue(privateMethod is MethodMirror);
-  Expect.isTrue(privateMethod.isPrivate);
-  Expect.isTrue(privateMethod.isRegularMethod);
-
-  var privateConstructor =
-      privateClass.declarations[const Symbol('_privateConstructor')];
-  Expect.isNotNull(privateConstructor);
-  Expect.isTrue(privateConstructor is MethodMirror);
-  Expect.isTrue(privateConstructor.isConstructor);
-  Expect.isTrue(privateConstructor.isPrivate);
-  Expect.isFalse(privateConstructor.isConstConstructor);
-  Expect.isFalse(privateConstructor.isRedirectingConstructor);
-  Expect.isTrue(privateConstructor.isGenerativeConstructor);
-  Expect.isFalse(privateConstructor.isFactoryConstructor);
-
-  var privateFactoryConstructor =
-      privateClass.declarations[const Symbol('_privateFactoryConstructor')];
-  Expect.isNotNull(privateFactoryConstructor);
-  Expect.isTrue(privateFactoryConstructor is MethodMirror);
-  Expect.isTrue(privateFactoryConstructor.isConstructor);
-  Expect.isTrue(privateFactoryConstructor.isPrivate);
-  Expect.isFalse(privateFactoryConstructor.isConstConstructor);
-  Expect.isFalse(privateFactoryConstructor.isRedirectingConstructor);
-  Expect.isFalse(privateFactoryConstructor.isGenerativeConstructor);
-  Expect.isTrue(privateFactoryConstructor.isFactoryConstructor);
-
-  var metadata = privateClass.metadata;
-  Expect.isNotNull(metadata);
-  Expect.equals(0, metadata.length);
-}
diff --git a/tests/compiler/dart2js/serialization/analysis_test.dart b/tests/compiler/dart2js/serialization/analysis_test.dart
index 1630660..42c1f5f 100644
--- a/tests/compiler/dart2js/serialization/analysis_test.dart
+++ b/tests/compiler/dart2js/serialization/analysis_test.dart
@@ -14,32 +14,38 @@
 import 'helper.dart';
 import 'test_data.dart';
 
-main(List<String> arguments) {
+main(List<String> args) {
   asyncTest(() async {
-    String serializedData = await serializeDartCore();
-
-    if (arguments.isNotEmpty) {
-      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.last));
+    Arguments arguments = new Arguments.from(args);
+    SerializedData serializedData =
+        await serializeDartCore(arguments: arguments);
+    if (arguments.filename != null) {
+      Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
       await analyze(serializedData, entryPoint, null);
     } else {
       Uri entryPoint = Uri.parse('memory:main.dart');
-      for (Test test in TESTS) {
+      await arguments.forEachTest(TESTS, (int index, Test test) async {
         await analyze(serializedData, entryPoint, test);
-      }
+      });
     }
   });
 }
 
-Future analyze(String serializedData, Uri entryPoint, Test test) async {
+Future analyze(SerializedData serializedData, Uri entryPoint, Test test,
+               {int index}) async {
+  String testDescription =
+  test != null ? test.sourceFiles[entryPoint.path] : '${entryPoint}';
+  print('------------------------------------------------------------------');
+  print('analyze ${index != null ? '$index:' :''}${testDescription}');
+  print('------------------------------------------------------------------');
   DiagnosticCollector diagnosticCollector = new DiagnosticCollector();
   await runCompiler(
       entryPoint: entryPoint,
-      memorySourceFiles: test != null ? test.sourceFiles : const {},
+      resolutionInputs: serializedData.toUris(),
+      memorySourceFiles: serializedData.toMemorySourceFiles(
+          test != null ? test.sourceFiles : null),
       options: [Flags.analyzeOnly],
-      diagnosticHandler: diagnosticCollector,
-      beforeRun: (Compiler compiler) {
-        compiler.serialization.deserializeFromText(serializedData);
-      });
+      diagnosticHandler: diagnosticCollector);
   if (test != null) {
     Expect.equals(test.expectedErrorCount, diagnosticCollector.errors.length,
         "Unexpected error count.");
diff --git a/tests/compiler/dart2js/serialization/compilation_test.dart b/tests/compiler/dart2js/serialization/compilation_test.dart
index 7346b86..595803a 100644
--- a/tests/compiler/dart2js/serialization/compilation_test.dart
+++ b/tests/compiler/dart2js/serialization/compilation_test.dart
@@ -16,13 +16,14 @@
 main(List<String> args) {
   asyncTest(() async {
     Arguments arguments = new Arguments.from(args);
-    String serializedData = await serializeDartCore(arguments: arguments);
+    SerializedData serializedData =
+        await serializeDartCore(arguments: arguments);
     if (arguments.filename != null) {
       Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
       await compile(serializedData, entryPoint, null);
     } else {
       Uri entryPoint = Uri.parse('memory:main.dart');
-      arguments.forEachTest(TESTS, (int index, Test test) async {
+      await arguments.forEachTest(TESTS, (int index, Test test) async {
         await compile(serializedData, entryPoint, test,
                       index: index,
                       verbose: arguments.verbose);
@@ -31,7 +32,7 @@
   });
 }
 
-Future compile(String serializedData, Uri entryPoint, Test test,
+Future compile(SerializedData serializedData, Uri entryPoint, Test test,
                {int index, bool verbose: false}) async {
   String testDescription =
       test != null ? test.sourceFiles[entryPoint.path] : '${entryPoint}';
@@ -41,12 +42,11 @@
   OutputCollector outputCollector = new OutputCollector();
   await runCompiler(
       entryPoint: entryPoint,
-      memorySourceFiles: test != null ? test.sourceFiles : const {},
+      resolutionInputs: serializedData.toUris(),
+      memorySourceFiles: serializedData.toMemorySourceFiles(
+          test != null ? test.sourceFiles : null),
       options: [],
-      outputProvider: outputCollector,
-      beforeRun: (Compiler compiler) {
-        compiler.serialization.deserializeFromText(serializedData);
-      });
+      outputProvider: outputCollector);
   if (verbose) {
     print(outputCollector.getOutput('', 'js'));
   }
diff --git a/tests/compiler/dart2js/serialization/duplicate_library_test.dart b/tests/compiler/dart2js/serialization/duplicate_library_test.dart
new file mode 100644
index 0000000..3380c66
--- /dev/null
+++ b/tests/compiler/dart2js/serialization/duplicate_library_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library dart2js.serialization.duplicate_libraryc_test;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common/names.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/filenames.dart';
+import '../memory_compiler.dart';
+import 'helper.dart';
+import 'test_data.dart';
+
+void main(List<String> args) {
+  asyncTest(() async {
+    SerializedData data = await serializeDartCore(
+        arguments: new Arguments.from(args));
+    Map<String, String> sourceFiles = data.toMemorySourceFiles();
+    List<Uri> resolutionInputs = data.toUris();
+    Uri extraUri = Uri.parse('memory:extraUri');
+    sourceFiles[extraUri.path] = data.data;
+    resolutionInputs.add(extraUri);
+
+    DiagnosticCollector collector = new DiagnosticCollector();
+    await runCompiler(
+        entryPoint: Uris.dart_core,
+        memorySourceFiles: sourceFiles,
+        resolutionInputs: resolutionInputs,
+        diagnosticHandler: collector,
+        options: [Flags.analyzeAll]);
+    Expect.isTrue(collector.errors.isNotEmpty,
+        "Expected duplicate serialized library errors.");
+  });
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/serialization/equivalence_test.dart b/tests/compiler/dart2js/serialization/equivalence_test.dart
index fb1ace8..7caae28 100644
--- a/tests/compiler/dart2js/serialization/equivalence_test.dart
+++ b/tests/compiler/dart2js/serialization/equivalence_test.dart
@@ -8,6 +8,7 @@
 import '../memory_compiler.dart';
 import 'package:async_helper/async_helper.dart';
 import 'package:compiler/src/commandline_options.dart';
+import 'package:compiler/src/common.dart';
 import 'package:compiler/src/constants/constructors.dart';
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/diagnostics/invariant.dart';
@@ -18,6 +19,7 @@
 import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/serialization/json_serializer.dart';
 import 'package:compiler/src/serialization/serialization.dart';
+import 'package:expect/expect.dart';
 import 'test_helper.dart';
 
 main(List<String> arguments) {
@@ -51,14 +53,19 @@
         entryPoint: entryPoint, options: [Flags.analyzeAll]);
     Compiler compiler = result.compiler;
     testSerialization(compiler.libraryLoader.libraries,
+                      compiler.reporter,
                       outPath: outPath,
                       prettyPrint: prettyPrint);
+    Expect.isFalse(compiler.reporter.hasReportedError,
+        "Unexpected errors occured.");
   });
 }
 
-void testSerialization(Iterable<LibraryElement> libraries1,
-                       {String outPath,
-                        bool prettyPrint}) {
+void testSerialization(
+    Iterable<LibraryElement> libraries1,
+    DiagnosticReporter reporter,
+    {String outPath,
+     bool prettyPrint}) {
   Serializer serializer = new Serializer();
   for (LibraryElement library1 in libraries1) {
     serializer.serialize(library1);
@@ -75,7 +82,7 @@
   }
 
   Deserializer deserializer = new Deserializer.fromText(
-      new DeserializationContext(),
+      new DeserializationContext(reporter), Uri.parse('out1.data'),
       text, const JsonSerializationDecoder());
   List<LibraryElement> libraries2 = <LibraryElement>[];
   for (LibraryElement library1 in libraries1) {
@@ -95,7 +102,7 @@
   String text2 = serializer2.toText(const JsonSerializationEncoder());
 
   Deserializer deserializer3 = new Deserializer.fromText(
-      new DeserializationContext(),
+      new DeserializationContext(reporter), Uri.parse('out2.data'),
       text2, const JsonSerializationDecoder());
   for (LibraryElement library1 in libraries1) {
     LibraryElement library2 =
@@ -572,6 +579,11 @@
         element1.computeEffectiveTargetType(element1.enclosingClass.thisType),
         element2.computeEffectiveTargetType(element2.enclosingClass.thisType),
         areTypesEquivalent);
+    check(
+        element1, element2, 'effectiveTargetType.raw',
+        element1.computeEffectiveTargetType(element1.enclosingClass.rawType),
+        element2.computeEffectiveTargetType(element2.enclosingClass.rawType),
+        areTypesEquivalent);
     checkElementIdentities(element1, element2, 'immediateRedirectionTarget',
         element1.immediateRedirectionTarget,
         element2.immediateRedirectionTarget);
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
index 1ce8c2b..0471658 100644
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ b/tests/compiler/dart2js/serialization/helper.dart
@@ -14,6 +14,8 @@
 import '../memory_compiler.dart';
 import 'test_data.dart';
 
+const String DEFAULT_DATA_FILE_NAME = 'out.data';
+
 class Arguments {
   final String filename;
   final int start;
@@ -29,7 +31,7 @@
     this.end,
     this.loadSerializedData: false,
     this.saveSerializedData: false,
-    this.serializedDataFileName: 'out.data',
+    this.serializedDataFileName: DEFAULT_DATA_FILE_NAME,
     this.verbose: false});
 
   factory Arguments.from(List<String> arguments) {
@@ -38,7 +40,7 @@
     int end;
     for (String arg in arguments) {
       if (!arg.startsWith('-')) {
-        int index = int.parse(arg);
+        int index = int.parse(arg, onError: (_) => null);
         if (index == null) {
           filename = arg;
         } else if (start == null) {
@@ -51,6 +53,14 @@
     bool verbose = arguments.contains('-v');
     bool loadSerializedData = arguments.contains('-l');
     bool saveSerializedData = arguments.contains('-s');
+    if (arguments.contains('--auto')) {
+      File file = new File(DEFAULT_DATA_FILE_NAME);
+      if (file.existsSync()) {
+        loadSerializedData = true;
+      } else {
+        saveSerializedData = true;
+      }
+    }
     return new Arguments(
         filename: filename,
         start: start,
@@ -71,17 +81,18 @@
 }
 
 
-Future<String> serializeDartCore(
+Future<SerializedData> serializeDartCore(
     {Arguments arguments: const Arguments()}) async {
+  Uri uri = Uri.parse('memory:${arguments.serializedDataFileName}');
   print('------------------------------------------------------------------');
   print('serialize dart:core');
   print('------------------------------------------------------------------');
-  String serializedData;
+  SerializedData serializedData;
   if (arguments.loadSerializedData) {
     File file = new File(arguments.serializedDataFileName);
     if (file.existsSync()) {
       print('Loading data from $file');
-      serializedData = file.readAsStringSync();
+      serializedData = new SerializedData(uri, file.readAsStringSync());
     }
   }
   if (serializedData == null) {
@@ -92,12 +103,47 @@
     BufferedEventSink sink = new BufferedEventSink();
     compiler.serialization.serializeToSink(
         sink, compiler.libraryLoader.libraries);
-    serializedData = sink.text;
+    serializedData = new SerializedData(uri, sink.text);
     if (arguments.saveSerializedData) {
       File file = new File(arguments.serializedDataFileName);
       print('Saving data to $file');
-      file.writeAsStringSync(serializedData);
+      file.writeAsStringSync(serializedData.data);
     }
   }
   return serializedData;
 }
+
+class SerializedData {
+  final Uri uri;
+  final String data;
+
+  SerializedData(this.uri, this.data);
+
+  Map<String, String> toMemorySourceFiles([Map<String, String> input]) {
+    Map<String, String> sourceFiles = <String, String>{};
+    if (input != null) {
+      sourceFiles.addAll(input);
+    }
+    expandMemorySourceFiles(sourceFiles);
+    return sourceFiles;
+  }
+
+  void expandMemorySourceFiles(Map<String, String> sourceFiles) {
+    if (uri.scheme == 'memory') {
+      sourceFiles[uri.path] = data;
+    }
+  }
+
+  List<Uri> toUris([List<Uri> input]) {
+    List<Uri> uris = <Uri>[];
+    if (input != null) {
+      uris.addAll(input);
+    }
+    expandUris(uris);
+    return uris;
+  }
+
+  void expandUris(List<Uri> uris) {
+    uris.add(uri);
+  }
+}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/serialization/impact_test.dart b/tests/compiler/dart2js/serialization/impact_test.dart
index 5b062fe..3858f70 100644
--- a/tests/compiler/dart2js/serialization/impact_test.dart
+++ b/tests/compiler/dart2js/serialization/impact_test.dart
@@ -16,7 +16,8 @@
 main(List<String> args) {
   Arguments arguments = new Arguments.from(args);
   asyncTest(() async {
-    String serializedData = await serializeDartCore(arguments: arguments);
+    SerializedData serializedData =
+        await serializeDartCore(arguments: arguments);
     if (arguments.filename != null) {
       Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
       await check(serializedData, entryPoint);
@@ -30,7 +31,7 @@
 }
 
 Future check(
-  String serializedData,
+  SerializedData serializedData,
   Uri entryPoint,
   {Map<String, String> sourceFiles: const <String, String>{},
    bool verbose: false}) async {
@@ -42,10 +43,10 @@
   await compilerNormal.run(entryPoint);
 
   Compiler compilerDeserialized = compilerFor(
-      memorySourceFiles: sourceFiles,
+      memorySourceFiles: serializedData.toMemorySourceFiles(sourceFiles),
+      resolutionInputs: serializedData.toUris(),
       options: [Flags.analyzeAll]);
   compilerDeserialized.resolution.retainCachesForTesting = true;
-  compilerDeserialized.serialization.deserializeFromText(serializedData);
   await compilerDeserialized.run(entryPoint);
 
   checkAllImpacts(compilerNormal, compilerDeserialized, verbose: verbose);
diff --git a/tests/compiler/dart2js/serialization/library_test.dart b/tests/compiler/dart2js/serialization/library_test.dart
index c8cfd4c..840cd78 100644
--- a/tests/compiler/dart2js/serialization/library_test.dart
+++ b/tests/compiler/dart2js/serialization/library_test.dart
@@ -4,9 +4,11 @@
 
 library dart2js.serialization_library_test;
 
+import 'dart:async';
 import 'dart:io';
 import '../memory_compiler.dart';
 import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/common/names.dart';
 import 'package:compiler/src/compiler.dart';
@@ -14,8 +16,12 @@
 import 'package:compiler/src/elements/elements.dart';
 import 'package:compiler/src/serialization/json_serializer.dart';
 import 'package:compiler/src/serialization/serialization.dart';
+import 'package:expect/expect.dart';
 
 import 'equivalence_test.dart';
+import 'test_helper.dart';
+import 'resolved_ast_test.dart';
+import 'helper.dart';
 
 main(List<String> arguments) {
   // Ensure that we can print out constant expressions.
@@ -47,20 +53,25 @@
     entryPoint = Uris.dart_core;
   }
   asyncTest(() async {
-    CompilationResult result = await runCompiler(
+    Compiler compiler = await compilerFor(
         entryPoint: entryPoint, options: [Flags.analyzeAll]);
-    Compiler compiler = result.compiler;
-    testSerialization(compiler.libraryLoader.libraries,
-                      outPath: outPath,
-                      prettyPrint: prettyPrint,
-                      shardCount: shardCount);
+    compiler.serialization.supportSerialization = true;
+    await compiler.run(entryPoint);
+    List<SerializedData> data =
+        createData(compiler,
+                   outPath: outPath,
+                   prettyPrint: prettyPrint,
+                   shardCount: shardCount);
+    await testAnalysis(compiler, data, entryPoint);
   });
 }
 
-void testSerialization(Iterable<LibraryElement> libraries1,
-                       {String outPath,
-                        bool prettyPrint,
-                        int shardCount: 3}) {
+List<SerializedData> createData(
+    Compiler compiler,
+    {String outPath,
+     bool prettyPrint,
+     int shardCount: 3}) {
+  Iterable<LibraryElement> libraries1 = compiler.libraryLoader.libraries;
   if (shardCount < 1 || shardCount > libraries1.length) {
     shardCount = libraries1.length;
   }
@@ -78,14 +89,11 @@
     offset += shardSize;
   }
   print(librarySplits.join('\n'));
-  List<String> texts = <String>[];
+  List<SerializedData> data = <SerializedData>[];
   for (int shard = 0; shard < shardCount; shard++) {
     List<LibraryElement> libraries = librarySplits[shard];
-    Serializer serializer = new Serializer(
-        shouldInclude: (e) => libraries.contains(e.library));
-    for (LibraryElement library in libraries) {
-      serializer.serialize(library);
-    }
+    Serializer serializer =
+        compiler.serialization.createSerializer(libraries);
     String text = serializer.toText(const JsonSerializationEncoder());
     String outText = text;
     if (prettyPrint) {
@@ -103,22 +111,37 @@
     } else if (prettyPrint) {
       print(outText);
     }
-    texts.add(text);
+    data.add(new SerializedData(Uri.parse('memory:out$shard.data'), text));
   }
-  DeserializationContext deserializationContext =
-      new DeserializationContext();
-  for (int shard = 0; shard < shardCount; shard++) {
-    new Deserializer.fromText(
-        deserializationContext, texts[shard], const JsonSerializationDecoder());
+  return data;
+}
+
+Future testAnalysis(
+    Compiler compiler1,
+    List<SerializedData> data,
+    Uri entryPoint) async {
+  Map<String, String> memorySourceFiles = <String, String>{};
+  List<Uri> resolutionInputs = <Uri>[];
+  for (int index = 0; index < data.length; index++) {
+    SerializedData serializedData = data[index];
+    serializedData.expandMemorySourceFiles(memorySourceFiles);
+    serializedData.expandUris(resolutionInputs);
   }
-  List<LibraryElement> libraries2 = <LibraryElement>[];
-  for (LibraryElement library1 in libraries1) {
+  CompilationResult result = await runCompiler(
+      entryPoint: entryPoint,
+      memorySourceFiles: memorySourceFiles,
+      resolutionInputs: resolutionInputs,
+      options: [Flags.analyzeAll]);
+  Compiler compiler2 = result.compiler;
+  for (LibraryElement library1 in compiler1.libraryLoader.libraries) {
     LibraryElement library2 =
-        deserializationContext.lookupLibrary(library1.canonicalUri);
+        compiler2.libraryLoader.lookupLibrary(library1.canonicalUri);
     if (library2 == null) {
       throw new ArgumentError('No library ${library1.canonicalUri} found.');
     }
     checkLibraryContent('library1', 'library2', 'library', library1, library2);
-    libraries2.add(library2);
+    checkAllResolvedAsts(compiler1, compiler2);
+    checkAllImpacts(compiler1, compiler2);
   }
+  Expect.isFalse(compiler2.reporter.hasReportedError, "Unexpected errors");
 }
\ No newline at end of file
diff --git a/tests/compiler/dart2js/serialization/model_test.dart b/tests/compiler/dart2js/serialization/model_test.dart
index a8704ae..2ab28e9 100644
--- a/tests/compiler/dart2js/serialization/model_test.dart
+++ b/tests/compiler/dart2js/serialization/model_test.dart
@@ -24,7 +24,8 @@
 main(List<String> args) {
   asyncTest(() async {
     Arguments arguments = new Arguments.from(args);
-    String serializedData = await serializeDartCore(arguments: arguments);
+    SerializedData serializedData =
+        await serializeDartCore(arguments: arguments);
     if (arguments.filename != null) {
       Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
       await checkModels(serializedData, entryPoint);
@@ -36,7 +37,7 @@
         await checkModels(
           serializedData,
           entryPoint,
-          sourceFiles: test.sourceFiles,
+          memorySourceFiles: test.sourceFiles,
           verbose: arguments.verbose);
       });
     }
@@ -44,16 +45,16 @@
 }
 
 Future checkModels(
-  String serializedData,
-  Uri entryPoint,
-  {Map<String, String> sourceFiles: const <String, String>{},
+    SerializedData serializedData,
+    Uri entryPoint,
+  {Map<String, String> memorySourceFiles: const <String, String>{},
    bool verbose: false}) async {
 
   print('------------------------------------------------------------------');
   print('compile normal');
   print('------------------------------------------------------------------');
   Compiler compilerNormal = compilerFor(
-      memorySourceFiles: sourceFiles,
+      memorySourceFiles: memorySourceFiles,
       options: [Flags.analyzeOnly]);
   compilerNormal.resolution.retainCachesForTesting = true;
   await compilerNormal.run(entryPoint);
@@ -65,10 +66,10 @@
   print('compile deserialized');
   print('------------------------------------------------------------------');
   Compiler compilerDeserialized = compilerFor(
-      memorySourceFiles: sourceFiles,
+      memorySourceFiles: serializedData.toMemorySourceFiles(memorySourceFiles),
+      resolutionInputs: serializedData.toUris(),
       options: [Flags.analyzeOnly]);
   compilerDeserialized.resolution.retainCachesForTesting = true;
-  compilerDeserialized.serialization.deserializeFromText(serializedData);
   await compilerDeserialized.run(entryPoint);
   compilerDeserialized.phase = Compiler.PHASE_DONE_RESOLVING;
   compilerDeserialized.world.populate();
diff --git a/tests/compiler/dart2js/serialization/resolved_ast_test.dart b/tests/compiler/dart2js/serialization/resolved_ast_test.dart
index b9bae80..9cba5af 100644
--- a/tests/compiler/dart2js/serialization/resolved_ast_test.dart
+++ b/tests/compiler/dart2js/serialization/resolved_ast_test.dart
@@ -20,7 +20,8 @@
 main(List<String> args) {
   Arguments arguments = new Arguments.from(args);
   asyncTest(() async {
-    String serializedData = await serializeDartCore(arguments: arguments);
+    SerializedData serializedData =
+        await serializeDartCore(arguments: arguments);
     if (arguments.filename != null) {
       Uri entryPoint = Uri.base.resolve(nativeToUriPath(arguments.filename));
       await check(serializedData, entryPoint);
@@ -35,7 +36,7 @@
 }
 
 Future check(
-  String serializedData,
+  SerializedData serializedData,
   Uri entryPoint,
   [Map<String, String> sourceFiles = const <String, String>{}]) async {
 
@@ -46,10 +47,10 @@
   await compilerNormal.run(entryPoint);
 
   Compiler compilerDeserialized = compilerFor(
-      memorySourceFiles: sourceFiles,
+      memorySourceFiles: serializedData.toMemorySourceFiles(sourceFiles),
+      resolutionInputs: serializedData.toUris(),
       options: [Flags.analyzeAll]);
   compilerDeserialized.resolution.retainCachesForTesting = true;
-  compilerDeserialized.serialization.deserializeFromText(serializedData);
   await compilerDeserialized.run(entryPoint);
 
   checkAllResolvedAsts(compilerNormal, compilerDeserialized, verbose: true);
diff --git a/tests/compiler/dart2js/serialization/test_data.dart b/tests/compiler/dart2js/serialization/test_data.dart
index 0606a48..62126fd 100644
--- a/tests/compiler/dart2js/serialization/test_data.dart
+++ b/tests/compiler/dart2js/serialization/test_data.dart
@@ -217,6 +217,53 @@
 }
 main() => const C();'''
   }),
+
+  const Test(const {
+    'main.dart': '''
+class C {
+  factory C() = Object;
+}
+main() => new C();'''
+  }),
+
+  const Test(const {
+    'main.dart': '''
+abstract class C implements List {
+  factory C([_]) = List;
+}
+main() => new C();'''
+  }),
+
+  const Test(const {
+    'main.dart': '''
+main() => const Duration();
+''',
+  }),
+
+  const Test(const {
+    'main.dart': '''
+import 'dart:collection';
+main() => new UnmodifiableListView(null);
+''',
+  }),
+
+  const Test(const {
+    'main.dart': '''
+var myIdentical = identical;
+main() => myIdentical;
+''',
+  }),
+
+  const Test(const {
+    'main.dart': '''
+class Foo {
+  String toString() => super.toString();
+}
+main() {
+  print(new Foo());
+}
+''',
+  }),
 ];
 
 class Test {
diff --git a/tests/compiler/dart2js/strip_comment_test.dart b/tests/compiler/dart2js/strip_comment_test.dart
deleted file mode 100644
index 40921a9..0000000
--- a/tests/compiler/dart2js/strip_comment_test.dart
+++ /dev/null
@@ -1,80 +0,0 @@
-// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-library strip_comment_test;
-
-import "package:expect/expect.dart";
-import 'package:compiler/src/mirrors/mirrors_util.dart';
-
-testComment(String strippedText, String commentText) {
-  Expect.stringEquals(strippedText, stripComment(commentText));
-}
-
-void main() {
-  testComment('', '//');
-  testComment('', '// ');
-  testComment(' ', '//  ');
-  testComment('foo bar baz', '//foo bar baz');
-  testComment('foo bar baz', '// foo bar baz');
-  testComment('foo bar baz ', '// foo bar baz ');
-  testComment(' foo bar baz  ', '//  foo bar baz  ');
-
-  testComment('', '///');
-  testComment('', '/// ');
-  testComment(' ', '///  ');
-  testComment('foo bar baz', '///foo bar baz');
-  testComment('foo bar baz', '/// foo bar baz');
-  testComment('foo bar baz ', '/// foo bar baz ');
-  testComment(' foo bar baz  ', '///  foo bar baz  ');
-
-  testComment('', '/**/');
-  testComment('', '/* */');
-  testComment(' ', '/*  */');
-  testComment('foo bar baz', '/*foo bar baz*/');
-  testComment('foo bar baz', '/* foo bar baz*/');
-  testComment('foo bar baz ', '/* foo bar baz */');
-  testComment(' foo bar baz  ', '/*  foo bar baz  */');
-  testComment('foo\nbar\nbaz', '/*foo\nbar\nbaz*/');
-  testComment('foo\nbar\nbaz', '/* foo\nbar\nbaz*/');
-  testComment('foo \n bar \n baz ', '/* foo \n bar \n baz */');
-  testComment('foo\nbar\nbaz', '/* foo\n *bar\n *baz*/');
-  testComment('foo\nbar\nbaz', '/* foo\n * bar\n * baz*/');
-  testComment('foo \nbar \nbaz ', '/* foo \n * bar \n * baz */');
-  testComment('\nfoo\nbar\nbaz',
-      '''/*
-          * foo
-          * bar
-          * baz*/''');
-  testComment('\nfoo\nbar\nbaz\n',
-      '''/*
-          * foo
-          * bar
-          * baz
-          */''');
-
-  testComment('', '/***/');
-  testComment('', '/** */');
-  testComment(' ', '/**  */');
-  testComment('foo bar baz', '/**foo bar baz*/');
-  testComment('foo bar baz', '/** foo bar baz*/');
-  testComment('foo bar baz ', '/** foo bar baz */');
-  testComment(' foo bar baz  ', '/**  foo bar baz  */');
-  testComment('foo\nbar\nbaz', '/**foo\nbar\nbaz*/');
-  testComment('foo\nbar\nbaz', '/** foo\nbar\nbaz*/');
-  testComment('foo \n bar \n baz ', '/** foo \n bar \n baz */');
-  testComment('foo\nbar\nbaz', '/** foo\n *bar\n *baz*/');
-  testComment('foo\nbar\nbaz', '/** foo\n * bar\n * baz*/');
-  testComment('foo \nbar \nbaz ', '/** foo \n * bar \n * baz */');
-  testComment('\nfoo\nbar\nbaz',
-      '''/**
-          * foo
-          * bar
-          * baz*/''');
-  testComment('\nfoo\nbar\nbaz\n',
-      '''/**
-          * foo
-          * bar
-          * baz
-          */''');
-}
\ No newline at end of file
diff --git a/tests/compiler/dart2js/type_checker_test.dart b/tests/compiler/dart2js/type_checker_test.dart
index 0b3fb87..d471cf1 100644
--- a/tests/compiler/dart2js/type_checker_test.dart
+++ b/tests/compiler/dart2js/type_checker_test.dart
@@ -2563,14 +2563,14 @@
     new CompilationUnitElementX(new Script(null, null, null), compiler.mainApp);
   Element function = new MockElement(compilationUnit);
   TreeElements elements = compiler.resolveNodeStatement(node, function);
-  compiler.enqueuer.resolution.emptyDeferredTaskQueue();
+  compiler.enqueuer.resolution.emptyDeferredQueueForTesting();
   TypeCheckerVisitor checker = new TypeCheckerVisitor(
       compiler, elements, compiler.types);
   DiagnosticCollector collector = compiler.diagnosticCollector;
   collector.clear();
   checker.analyze(node);
   if (flushDeferred) {
-    compiler.enqueuer.resolution.emptyDeferredTaskQueue();
+    compiler.enqueuer.resolution.emptyDeferredQueueForTesting();
   }
   compareWarningKinds(text, warnings, collector.warnings);
   compareWarningKinds(text, errors, collector.errors);
diff --git a/tests/compiler/dart2js/type_test_helper.dart b/tests/compiler/dart2js/type_test_helper.dart
index 1e20ba7..5e91f77 100644
--- a/tests/compiler/dart2js/type_test_helper.dart
+++ b/tests/compiler/dart2js/type_test_helper.dart
@@ -8,6 +8,7 @@
 import 'package:expect/expect.dart';
 import 'compiler_helper.dart' as mock;
 import 'memory_compiler.dart' as memory;
+import 'package:compiler/src/common/resolution.dart';
 import 'package:compiler/src/commandline_options.dart';
 import 'package:compiler/src/dart_types.dart';
 import 'package:compiler/src/compiler.dart'
@@ -31,6 +32,8 @@
 class TypeEnvironment {
   final Compiler compiler;
 
+  Resolution get resolution => compiler.resolution;
+
   static Future<TypeEnvironment> create(
       String source, {bool useMockCompiler: true,
                       bool expectNoErrors: false,
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 62f45da..9757816 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -29,9 +29,6 @@
 symbol_operator_test/03: Fail # bug 11669
 string_case_test/01: Fail # Bug 18061
 
-iterable_return_type_test/01: RuntimeError # Issue 13646
-iterable_return_type_test/02: RuntimeError # Issue 13646
-
 # #void should be a valid symbol.
 [ $compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2js ]
 symbol_reserved_word_test/02: CompileTimeError # bug 20191
@@ -92,6 +89,7 @@
 integer_to_string_test/01: RuntimeError # Issue 1533
 iterable_return_type_test/01: RuntimeError # Issue 20085
 iterable_return_type_test/02: RuntimeError # Dart2js does not support Uint64*.
+iterable_to_list_test/01: RuntimeError # Issue 26501
 
 big_integer_*: Skip # VM specific test.
 bit_twiddling_bigint_test: RuntimeError # Requires bigint support.
diff --git a/tests/corelib/iterable_to_list_test.dart b/tests/corelib/iterable_to_list_test.dart
index 3ee443a..2257d8f 100644
--- a/tests/corelib/iterable_to_list_test.dart
+++ b/tests/corelib/iterable_to_list_test.dart
@@ -2,70 +2,70 @@
 // 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:collection" show Queue;
+import "dart:typed_data" show Uint8List, Float32List;
 import "package:expect/expect.dart";
 
-dynamicCheck(input, {isInt, isString}) {
-  var copy = input.toList();
-  Expect.isTrue(isInt == copy is List<int>);
-  Expect.isTrue(isString == copy is List<String>);
+main() {
+  // testIterable takes an iterable and a list expected to be equal to
+  // the iterable's toList result, including the type parameter of the list.
+  testIterable([], []);
+  testIterable(<int>[], <int>[]);
+  testIterable(<String>[], <String>[]);
+  testIterable([1, 2, 3], [1, 2, 3]);
+  testIterable(<int>[1, 2, 3], <int>[1, 2, 3]);
+  testIterable(const [1, 2], [1, 2]);
+  testIterable(const <int>[1, 2], <int>[1, 2]);
+  testIterable({"x": 1, "y": 1}.keys, ["x", "y"]);
+  testIterable(<String, int>{"x": 1, "y": 1}.keys, <String>["x", "y"]);
+  testIterable({"x": 2, "y": 3}.values, [2, 3]);
+  testIterable(<String, int>{"x": 2, "y": 3}.values, <int>[2, 3]);
+  testIterable(new Iterable.generate(3), [0, 1, 2]);
+  testIterable(new Iterable<int>.generate(3), <int>[0, 1, 2]);
+  testIterable(new Iterable<String>.generate(3, (x)=>"$x"),
+               <String>["0", "1", "2"]);
+  testIterable(new Set.from([1, 2, 3]), [1, 2, 3]);
+  testIterable(new Set<int>.from([1, 2, 3]), <int>[1, 2, 3]);
+  testIterable(new Queue.from([1, 2, 3]), [1, 2, 3]);
+  testIterable(new Queue<int>.from(<int>[1, 2, 3]), <int>[1, 2, 3]);
+  testIterable(new Uint8List.fromList(<int>[1, 2, 3]),     /// 01: ok
+               <int>[1, 2, 3]);                            /// 01: continued
+  testIterable(new Float32List.fromList([1.0, 2.0, 3.0]),  /// 01: continued
+               <double>[1.0, 2.0, 3.0]);                   /// 01: continued
+  testIterable("abc".codeUnits, <int>[97, 98, 99]);        /// 01: continued
+  testIterable("abc".runes, <int>[97, 98, 99]);
 }
 
-main() {
-  List<int> list1 = <int>[1, 2, 3];
-  List<int> list2 = const <int>[4, 5];
-  List<String> list3 = <String>[];
-  Set<int> set1 = new Set<int>();
-  set1..add(11)
-      ..add(12)
-      ..add(13);
-  Set<String> set2 = new Set<String>();
-  set2..add("foo")
-      ..add("bar")
-      ..add("toto");
-  Set set3 = new Set();
+testIterable(Iterable iterable, List expected, [int depth = 0]) {
+  print(" " * depth + "${iterable.runtimeType} vs ${expected.runtimeType}");
+  test(iterable, expected);
+  test(iterable, expected, growable: true);
+  test(iterable, expected, growable: false);
+  if (depth < 2) {
+    depth++;
+    testIterable(iterable.map((x) => x), new List.from(expected), depth);
+    testIterable(iterable.where((x) => true), expected, depth);
+    testIterable(iterable.expand((x) => [x]), new List.from(expected), depth);
+    testIterable(iterable.map((x) => x), new List.from(expected), depth);
+    testIterable(iterable.skipWhile((x) => false), expected, depth);
+    testIterable(iterable.takeWhile((x) => true), expected, depth);
+    testIterable(iterable.skip(0), expected, depth);
+    testIterable(iterable.take(expected.length * 2), expected, depth);
+    testIterable(iterable.toSet(), expected, depth);
+  }
+}
 
-  var listCopy = list1.toList();
-  Expect.listEquals(list1, listCopy);
-  Expect.isTrue(listCopy is List<int>);
-  Expect.isFalse(listCopy is List<String>);
-  Expect.isFalse(identical(list1, listCopy));
-  dynamicCheck(list1, isInt: true, isString: false);
-
-  listCopy = list2.toList();
-  Expect.listEquals(list2, listCopy);
-  Expect.isTrue(listCopy is List<int>);
-  Expect.isFalse(listCopy is List<String>);
-  Expect.isFalse(identical(list2, listCopy));
-  dynamicCheck(list2, isInt: true, isString: false);
-
-  listCopy = list3.toList();
-  Expect.listEquals(list3, listCopy);
-  Expect.isTrue(listCopy is List<String>);
-  Expect.isFalse(listCopy is List<int>);
-  Expect.isFalse(identical(list3, listCopy));
-  dynamicCheck(list3, isInt: false, isString: true);
-
-  listCopy = set1.toList();
-  Expect.equals(3, listCopy.length);
-  Expect.isTrue(listCopy.contains(11));
-  Expect.isTrue(listCopy.contains(12));
-  Expect.isTrue(listCopy.contains(13));
-  Expect.isTrue(listCopy is List<int>);
-  Expect.isFalse(listCopy is List<String>);
-  dynamicCheck(set1, isInt: true, isString: false);
-
-  listCopy = set2.toList();
-  Expect.equals(3, listCopy.length);
-  Expect.isTrue(listCopy.contains("foo"));
-  Expect.isTrue(listCopy.contains("bar"));
-  Expect.isTrue(listCopy.contains("toto"));
-  Expect.isTrue(listCopy is List<String>);
-  Expect.isFalse(listCopy is List<int>);
-  dynamicCheck(set2, isInt: false, isString: true);
-
-  listCopy = set3.toList();
-  Expect.isTrue(listCopy.isEmpty);
-  Expect.isTrue(listCopy is List<int>);
-  Expect.isTrue(listCopy is List<String>);
-  dynamicCheck(set3, isInt: true, isString: true);
+test(Iterable iterable, List expected, { bool growable: true}) {
+  var list = iterable.toList(growable: growable);
+  Expect.listEquals(expected, list);
+  Expect.equals(expected is List<int>, list is List<int>, "int");
+  Expect.equals(expected is List<double>, list is List<double>, "double");
+  Expect.equals(expected is List<String>, list is List<String>, "str");
+  if (growable) {
+    int length = list.length;
+    list.add(null);
+    Expect.equals(length + 1, list.length);
+  } else {
+    Expect.throws(() { list.add(null); });
+  }
 }
diff --git a/tests/language/generic_local_functions_test.dart b/tests/language/generic_local_functions_test.dart
index 21bd7a7..1ec1227 100644
--- a/tests/language/generic_local_functions_test.dart
+++ b/tests/language/generic_local_functions_test.dart
@@ -7,7 +7,7 @@
 /// Dart test verifying that the parser can handle type parameterization of
 /// local function declarations, and declarations of function parameters.
 
-library generic_functions_test;
+library generic_local_functions_test;
 
 import "package:expect/expect.dart";
 
diff --git a/tests/language/generic_methods_function_type_test.dart b/tests/language/generic_methods_function_type_test.dart
new file mode 100644
index 0000000..17a4c1a
--- /dev/null
+++ b/tests/language/generic_methods_function_type_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// DartOptions=--generic-method-syntax
+
+/// Dart test on the usage of method type arguments in a function typed
+/// parameter declaration.
+
+library generic_methods_function_type_test;
+
+import "package:expect/expect.dart";
+
+class C<V> {
+  U m1<U>(U f(V v), V v) => f(v);
+  V m2<U>(V f(U v), U u) => f(u);
+}
+
+main() {
+  Expect.equals(new C<int>().m1<int>((x) => x, 10), 10);
+  Expect.equals(new C<int>().m2<int>((x) => x, 20), 20);
+}
+
diff --git a/tests/language/generic_methods_function_type_test.options b/tests/language/generic_methods_function_type_test.options
new file mode 100644
index 0000000..86e2aac
--- /dev/null
+++ b/tests/language/generic_methods_function_type_test.options
@@ -0,0 +1,3 @@
+analyzer:
+  language:
+    enableGenericMethods: true
diff --git a/tests/language/generic_methods_new_test.dart b/tests/language/generic_methods_new_test.dart
new file mode 100644
index 0000000..ea23b94
--- /dev/null
+++ b/tests/language/generic_methods_new_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// DartOptions=--generic-method-syntax
+
+/// Dart test on the usage of method type arguments in object creation. With
+/// '--generic-method-syntax', the type argument is available at runtime,
+/// but erased to `dynamic`.
+
+library generic_methods_new_test;
+
+import "package:expect/expect.dart";
+
+class C<E> {
+  E e;
+  C(this.e);
+}
+
+C<T> f1<T>(T t) => new C<T>(t);
+
+List<T> f2<T>(T t) => <T>[t];
+
+main() {
+  C c = f1<int>(42);
+  List i = f2<String>("Hello!");
+  Expect.isTrue(c is C<int> && c is C<String>); // C<dynamic>.
+  Expect.isTrue(i is List<String> && i is List<int>); // List<dynamic>.
+  Expect.equals(c.e, 42);
+  Expect.equals(i[0], "Hello!");
+}
diff --git a/tests/language/generic_methods_new_test.options b/tests/language/generic_methods_new_test.options
new file mode 100644
index 0000000..86e2aac
--- /dev/null
+++ b/tests/language/generic_methods_new_test.options
@@ -0,0 +1,3 @@
+analyzer:
+  language:
+    enableGenericMethods: true
diff --git a/tests/language/generic_methods_type_expression_test.dart b/tests/language/generic_methods_type_expression_test.dart
new file mode 100644
index 0000000..cbe0802
--- /dev/null
+++ b/tests/language/generic_methods_type_expression_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+//
+// DartOptions=--generic-method-syntax
+
+/// Dart test on the usage of method type arguments in type expressions. With
+/// '--generic-method-syntax', the type argument is available at runtime,
+/// but erased to `dynamic`.
+
+library generic_methods_type_expression_test;
+
+import "package:expect/expect.dart";
+
+bool f1<T>(Object o) => o is T;
+
+bool f2<T>(Object o) => o is List<T>;
+
+bool f3<T>(Object o) => o is! T;
+
+bool f4<T>(Object o) => o is! List<T>;
+
+T f5<T>(Object o) => o as T;
+
+List<T> f6<T>(Object o) => o as List<T>;
+
+Type f7<T>() => T;
+
+class TypeValue<X> {
+  Type get value => X;
+}
+
+Type f8<T>() => new TypeValue<List<T>>().value;
+
+main() {
+  String s = "Hello!";
+  List<String> ss = <String>[s];
+  Expect.throws(() => f1<int>(42), (e) => e is TypeError);
+  Expect.throws(() => f1<String>(42), (e) => e is TypeError);
+  Expect.equals(f2<int>(<int>[42]), true);
+  Expect.equals(f2<String>(<int>[42]), true); // `is List<dynamic>` is true.
+  Expect.throws(() => f3<int>(42), (e) => e is TypeError);
+  Expect.throws(() => f3<String>(42), (e) => e is TypeError);
+  Expect.equals(f4<int>(<int>[42]), false);
+  Expect.equals(f4<String>(<int>[42]), false); // `is! List<dynamic>` is false.
+  Expect.throws(() => f5<String>(s), (e) => e is TypeError);
+  Expect.throws(() => f5<int>(s), (e) => e is TypeError);
+  Expect.equals(f6<String>(ss), ss);
+  Expect.equals(f6<int>(ss), ss); // `as List<dynamic>` succeeds.
+  Expect.throws(() => f7<int>(), (e) => e is TypeError);
+  Expect.equals(f8<int>(), List); // Returns `List<dynamic>`.
+}
diff --git a/tests/language/generic_methods_type_expression_test.options b/tests/language/generic_methods_type_expression_test.options
new file mode 100644
index 0000000..86e2aac
--- /dev/null
+++ b/tests/language/generic_methods_type_expression_test.options
@@ -0,0 +1,3 @@
+analyzer:
+  language:
+    enableGenericMethods: true
diff --git a/tests/language/language.status b/tests/language/language.status
index 4b75506..b64df81 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -49,6 +49,9 @@
 generic_functions_test: CompiletimeError # Issue 25869
 generic_local_functions_test: CompiletimeError # Issue 25869
 generic_sends_test: CompiletimeError # Issue 25869
+generic_methods_new_test: CompiletimeError # Issue 25869
+generic_methods_function_type_test: CompiletimeError # Issue 25869
+generic_methods_type_expression_test: CompiletimeError # Issue 25869
 
 [ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 
@@ -94,6 +97,9 @@
 generic_functions_test: RuntimeError # Issue 25869
 generic_local_functions_test: RuntimeError # Issue 25869
 generic_sends_test: RuntimeError # Issue 25869
+generic_methods_new_test: RuntimeError # Issue 25869
+generic_methods_function_type_test: RuntimeError # Issue 25869
+generic_methods_type_expression_test: RuntimeError # Issue 25869
 config_import_test: Skip  # Issue 26250
 
 [ $compiler == none && $runtime == dartium && $system == linux && $arch != x64 ]
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index 2035434..a0e3ee5 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -506,3 +506,6 @@
 generic_local_functions_test: CompileTimeError # Issue 25868
 generic_methods_test: CompileTimeError # Issue 25868
 generic_sends_test: CompileTimeError # Issue 25868
+generic_methods_new_test: CompiletimeError # Issue 25868
+generic_methods_function_type_test: CompiletimeError # Issue 25868
+generic_methods_type_expression_test: CompiletimeError # Issue 25868
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 25902c1..b61dd39 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -50,6 +50,9 @@
 generic_local_functions_test: CompileTimeError # DartOptions not passed to compiler.
 generic_methods_test: CompileTimeError # DartOptions not passed to compiler.
 generic_sends_test: CompileTimeError # DartOptions not passed to compiler.
+generic_methods_new_test: CompiletimeError # DartOptions not passed to compiler.
+generic_methods_function_type_test: CompiletimeError # DartOptions not passed to compiler.
+generic_methods_type_expression_test: CompiletimeError # DartOptions not passed to compiler.
 
 [ $compiler == dart2js ]
 invocation_mirror_empty_arguments_test: Fail # Issue 24331
@@ -132,9 +135,6 @@
 malbounded_type_test_test/04: Fail # Issue 14121
 malbounded_type_test2_test: Fail # Issue 14121
 default_factory2_test/01: Fail # Issue 14121
-generic_functions_test: Crash # Issue 26436
-generic_local_functions_test: Crash # Issue 26436
-generic_methods_test: Crash # Issue 26436
 
 [ $compiler == dart2js && $unchecked ]
 type_checks_in_factory_method_test: RuntimeError # Issue 12746
diff --git a/tests/lib/math/call_cmath_box_failure_path_test.dart b/tests/lib/math/call_cmath_box_failure_path_test.dart
new file mode 100644
index 0000000..9718489
--- /dev/null
+++ b/tests/lib/math/call_cmath_box_failure_path_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--optimization-counter-threshold=-1 --new_gen_semi_max_size=2
+
+import 'dart:math';
+
+main() {
+  // 2MB / 16 bytes = 125000 allocations
+
+  for (var i = 0; i < 500000; i++) {
+    sin(i);
+  }
+
+  for (var i = 0; i < 500000; i++) {
+    cos(i);
+  }
+
+  for (var i = 0; i < 500000; i++) {
+    i.toDouble().truncateToDouble();
+  }
+}
diff --git a/tests/lib/typed_data/typed_list_iterable_test.dart b/tests/lib/typed_data/typed_list_iterable_test.dart
index acdfa4b..787bfec 100644
--- a/tests/lib/typed_data/typed_list_iterable_test.dart
+++ b/tests/lib/typed_data/typed_list_iterable_test.dart
@@ -153,10 +153,11 @@
   Expect.isTrue(list.takeWhile((x) => true).isEmpty);
   Expect.isTrue(list.toList().isEmpty);
   var l2 = list.toList();
-  l2.add(0);
-  Expect.equals(0, l2.last);
+  var sampleValue = list is List<int> ? 0 : 0.0;
+  l2.add(sampleValue);
+  Expect.equals(sampleValue, l2.last);
   var l3 = list.toList(growable: false);
-  Expect.throws(() => l3.add(0), (e) => e is UnsupportedError);
+  Expect.throws(() => l3.add(sampleValue), (e) => e is UnsupportedError);
 }
 
 main() {
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index b163964..975dad7 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -181,7 +181,6 @@
 io/skipping_dart2js_compilations_test: Fail # Issue 19551.
 verbose_gc_to_bmu_test: Skip
 io/platform_resolved_executable_test/06: RuntimeError  # Issue 23641
-io/process_sync_test: Pass, Timeout  # Issue 24596
 io/sleep_test: Pass, Fail # Issue 25757
 
 [ $arch != ia32 && $arch != x64 && $arch != simarm && $arch != simarmv5te && $mode == debug ]
diff --git a/tests/utils/source_mirrors_test.dart b/tests/utils/source_mirrors_test.dart
deleted file mode 100644
index 8a748c7..0000000
--- a/tests/utils/source_mirrors_test.dart
+++ /dev/null
@@ -1,36 +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.
-// VMOptions=
-// VMOptions=--print-object-histogram
-
-// Smoke test of the dart2js compiler API.
-library source_mirrors_test;
-
-import 'dart:async';
-import "package:async_helper/async_helper.dart";
-
-import 'package:compiler/src/mirrors/analyze.dart';
-import 'dummy_compiler_test.dart';
-
-main() {
-  asyncStart();
-  Future result =
-      analyze([new Uri(scheme: 'main')],
-              new Uri(scheme: 'lib', path: '/'),
-              new Uri(scheme: 'package', path: '/'),
-              provider, handler);
-  result.then((mirrorSystem) {
-    if (mirrorSystem == null) {
-      throw 'Analysis failed';
-    }
-    mirrorSystem.libraries.forEach((uri, library) {
-      print(library);
-      library.declarations.forEach((name, declaration) {
-        print(' $name:$declaration');
-      });
-    });
-  }, onError: (e, s) {
-      throw 'Analysis failed: $e\n$s';
-  }).then(asyncSuccess);
-}
diff --git a/tests/utils/utils.status b/tests/utils/utils.status
index bec008c..b1dc829 100644
--- a/tests/utils/utils.status
+++ b/tests/utils/utils.status
@@ -7,7 +7,6 @@
 
 [ $compiler == dart2js ]
 recursive_import_test: Slow, Pass
-source_mirrors_test: Slow, Pass
 
 [ $compiler == dart2js && $browser ]
 *: Skip
@@ -18,10 +17,6 @@
 [ $compiler == dart2js && $mode == debug ]
 dummy_compiler_test: Slow, Pass
 
-[ $noopt || $compiler == precompiler || $mode == product ]
-source_mirrors_test: SkipByDesign # Imports dart:mirrors
-
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 dummy_compiler_test: Crash # Issue 24485
 recursive_import_test: Crash # Issue 24485
-source_mirrors_test: Crash # Issue 24485
diff --git a/tools/VERSION b/tools/VERSION
index 2739e60..7b28ec1 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 17
 PATCH 0
-PRERELEASE 4
-PRERELEASE_PATCH 1
+PRERELEASE 5
+PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 960cf72..f1fa97c 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -8,8 +8,8 @@
 # Now we need to override some settings and add some new ones.
 
 vars.update({
-  "dartium_chromium_commit": "81ac1404ddd8fde55b9eb28a97c8a6d8b75e264f",
-  "dartium_webkit_commit": "ef30dc04127c86283c1f5c5c6b0094d73b1e29df",
+  "dartium_chromium_commit": "b6b6b76417ce80120ee48b662a7c7ef257723494",
+  "dartium_webkit_commit": "ca3b07f5929e6adb390901b31db634f4dfe0d2bf",
   "chromium_base_revision": "338390",
 
   # We use mirrors of all github repos to guarantee reproducibility and
diff --git a/tools/dom/scripts/generator.py b/tools/dom/scripts/generator.py
index 125d64a..db47521 100644
--- a/tools/dom/scripts/generator.py
+++ b/tools/dom/scripts/generator.py
@@ -14,6 +14,46 @@
 from htmlrenamer import custom_html_constructors, html_interface_renames, \
     typed_array_renames
 
+_pure_interfaces = monitored.Set('generator._pure_interfaces', [
+    'AbstractWorker',
+    'CanvasPathMethods',
+    'ChildNode',
+    'DocumentAnimation',
+    'DocumentFontFaceSet',
+    'DocumentFullscreen',
+    'DocumentXPathEvaluator',
+    'ElementAnimation',
+    'ElementFullscreen',
+    'EventListener',
+    'GlobalEventHandlers',
+    'ImageBitmapFactories',
+    'MediaQueryListListener',
+    'MouseEventHitRegion',
+    'MutationCallback',
+    'NavigatorCPU',
+    'NavigatorEvents',
+    'NavigatorID',
+    'NavigatorLanguage',
+    'NavigatorOnLine',
+    'ParentNode',
+    'SVGDocument',
+    'SVGExternalResourcesRequired',
+    'SVGFilterPrimitiveStandardAttributes',
+    'SVGFitToViewBox',
+    'SVGTests',
+    'SVGURIReference',
+    'SVGZoomAndPan',
+    'TimeoutHandler',
+    'URLUtils',
+    'URLUtilsReadOnly',
+    'WebGLRenderingContextBase',
+    'WindowBase64',
+    'WindowEventHandlers',
+    'WindowImageBitmapFactories',
+    'WindowPagePopup',
+    'WindowTimers',
+    ])
+
 _safe_interfaces = monitored.Set('generator._safe_interfaces', [
     'double',
     'Float32Array',
@@ -149,6 +189,8 @@
 # SpeechGrammarList and friends
 
 def IsPureInterface(interface_name, database):
+  if (interface_name in _pure_interfaces):
+    return True
   if (interface_name in _safe_interfaces or
       interface_name in _safe_interfaces_legacy or
       database.HasInterface(interface_name)):