Version 1.20.0-dev.1.0

Merge 7b29f2b79c9d8bc36aab1e9418a9377ac5662382 into dev
diff --git a/DEPS b/DEPS
index 2d7bfbf..e231f85 100644
--- a/DEPS
+++ b/DEPS
@@ -55,8 +55,8 @@
   "dart2js_info_rev" : "@0a221eaf16aec3879c45719de656680ccb80d8a1",
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.9+1",
-  "dartdoc_tag" : "@v0.9.6+2",
-  "dev_compiler_rev": "@fa084164b620ea75cd2008c9dc317655a045ad6d",
+  "dartdoc_tag" : "@v0.9.7+2",
+  "dev_compiler_rev": "@d6371ee44e8f119b847c1f4cc29957bff471057b",
   "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 866f58a..12b6378 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -32,7 +32,6 @@
 import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
@@ -46,7 +45,6 @@
 import 'package:analyzer/src/util/glob.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:plugin/plugin.dart';
-import 'package:yaml/yaml.dart';
 
 typedef void OptionUpdater(AnalysisOptionsImpl options);
 
@@ -1596,14 +1594,10 @@
   @override
   AnalysisContext addContext(
       Folder folder, AnalysisOptions options, FolderDisposition disposition) {
-    InternalAnalysisContext context =
-        AnalysisEngine.instance.createAnalysisContext();
-    context.contentCache = analysisServer.overlayState;
-    analysisServer.folderMap[folder] = context;
-    context.fileResolverProvider = analysisServer.fileResolverProvider;
-    context.sourceFactory =
-        _createSourceFactory(context, options, disposition, folder);
-    context.analysisOptions = options;
+    ContextBuilder builder = createContextBuilder(folder, options);
+    AnalysisContext context = builder.buildContext(folder.path);
+
+    // TODO(brianwilkerson) Move bundle discovery into ContextBuilder
     if (analysisServer.options.enablePubSummaryManager) {
       List<LinkedPubPackage> linkedBundles =
           analysisServer.pubSummaryManager.getLinkedBundles(context);
@@ -1613,11 +1607,12 @@
           store.addBundle(null, package.unlinked);
           store.addBundle(null, package.linked);
         }
-        context.resultProvider =
+        (context as InternalAnalysisContext).resultProvider =
             new InputPackagesResultProvider(context, store);
       }
     }
 
+    analysisServer.folderMap[folder] = context;
     analysisServer._onContextsChangedController
         .add(new ContextsChangedEvent(added: [context]));
     analysisServer.schedulePerformAnalysisOperation(context);
@@ -1646,6 +1641,32 @@
       analysisServer._computingPackageMap(computing);
 
   @override
+  ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) {
+    String defaultPackageFilePath = null;
+    String defaultPackagesDirectoryPath = null;
+    String path = (analysisServer.contextManager as ContextManagerImpl)
+        .normalizedPackageRoots[folder.path];
+    if (path != null) {
+      Resource resource = resourceProvider.getResource(path);
+      if (resource.exists) {
+        if (resource is File) {
+          defaultPackageFilePath = path;
+        } else {
+          defaultPackagesDirectoryPath = path;
+        }
+      }
+    }
+
+    ContextBuilder builder = new ContextBuilder(resourceProvider,
+        analysisServer.sdkManager, analysisServer.overlayState);
+    builder.defaultOptions = options;
+    builder.fileResolverProvider = analysisServer.fileResolverProvider;
+    builder.defaultPackageFilePath = defaultPackageFilePath;
+    builder.defaultPackagesDirectoryPath = defaultPackagesDirectoryPath;
+    return builder;
+  }
+
+  @override
   void moveContext(Folder from, Folder to) {
     // There is nothing to do.
     // This method is mostly for tests.
@@ -1671,61 +1692,6 @@
         .add(new ContextsChangedEvent(changed: [context]));
     analysisServer.schedulePerformAnalysisOperation(context);
   }
-
-  /**
-   * Set up a [SourceFactory] that resolves packages as appropriate for the
-   * given [disposition].
-   */
-  SourceFactory _createSourceFactory(InternalAnalysisContext context,
-      AnalysisOptions options, FolderDisposition disposition, Folder folder) {
-    List<UriResolver> resolvers = [];
-    List<UriResolver> packageUriResolvers =
-        disposition.createPackageUriResolvers(resourceProvider);
-
-    // If no embedded URI resolver was provided, defer to a locator-backed one.
-    SdkExtensionFinder extFinder =
-        disposition.getSdkExtensionFinder(resourceProvider);
-    List<String> extFilePaths = extFinder.extensionFilePaths;
-    EmbedderYamlLocator locator =
-        disposition.getEmbedderLocator(resourceProvider);
-    Map<Folder, YamlMap> embedderYamls = locator.embedderYamls;
-    EmbedderSdk embedderSdk = new EmbedderSdk(resourceProvider, embedderYamls);
-    if (embedderSdk.libraryMap.size() == 0) {
-      // There was no embedder file, or the file was empty, so used the default
-      // SDK.
-      resolvers.add(new DartUriResolver(
-          analysisServer.sdkManager.getSdkForOptions(options)));
-    } else {
-      // The embedder file defines an alternate SDK, so use it.
-      List<String> paths = <String>[];
-      for (Folder folder in embedderYamls.keys) {
-        paths.add(folder
-            .getChildAssumingFile(EmbedderYamlLocator.EMBEDDER_FILE_NAME)
-            .path);
-      }
-      paths.addAll(extFilePaths);
-      DartSdk dartSdk = analysisServer.sdkManager
-          .getSdk(new SdkDescription(paths, options), () {
-        if (extFilePaths.isNotEmpty) {
-          embedderSdk.addExtensions(extFinder.urlMappings);
-        }
-        embedderSdk.analysisOptions = options;
-        // TODO(brianwilkerson) Enable summary use after we have decided where
-        // summary files for embedder files will live.
-        embedderSdk.useSummary = false;
-        return embedderSdk;
-      });
-      resolvers.add(new DartUriResolver(dartSdk));
-    }
-
-    resolvers.addAll(packageUriResolvers);
-    UriResolver fileResolver;
-    if (context.fileResolverProvider != null) {
-      fileResolver = context.fileResolverProvider(folder);
-    }
-    resolvers.add(fileResolver ?? new ResourceUriResolver(resourceProvider));
-    return new SourceFactory(resolvers, disposition.packages);
-  }
 }
 
 /**
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index fd35213..5c47909 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -23,7 +23,6 @@
 import 'package:analyzer/source/sdk_ext.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/context.dart' as context;
-import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
@@ -343,6 +342,12 @@
   void computingPackageMap(bool computing);
 
   /**
+   * Create and return a context builder that can be used to create a context
+   * for the files in the given [folder] when analyzed using the given [options].
+   */
+  ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options);
+
+  /**
    * Called when the context manager changes the folder with which a context is
    * associated. Currently this is mostly FYI, and used only in tests.
    */
@@ -899,55 +904,14 @@
     // Check to see if this is the .packages file for this context and if so,
     // update the context's source factory.
     if (absolutePathContext.basename(path) == PACKAGE_SPEC_NAME) {
-      File packagespec = resourceProvider.getFile(path);
-      if (packagespec.exists) {
-        // Locate embedder yamls for this .packages file.
-        // If any embedder libs are contributed and this context does not
-        // have an embedded URI resolver, we need to create a new context.
-
-        List<int> bytes = packagespec.readAsStringSync().codeUnits;
-        Map<String, Uri> packages =
-            pkgfile.parse(bytes, new Uri.file(packagespec.path));
-
-        Map<String, List<Folder>> packageMap =
-            new PackagesFileDisposition(new MapPackages(packages))
-                .buildPackageMap(resourceProvider);
-        Map<Folder, YamlMap> embedderYamls =
-            new EmbedderYamlLocator(packageMap).embedderYamls;
-
-        SourceFactory sourceFactory = info.context.sourceFactory;
-
-        // Check for library embedders.
-        if (embedderYamls.values.any(definesEmbeddedLibs)) {
-          // If there is no embedded URI resolver, a new source factory needs to
-          // be recreated.
-          if (sourceFactory is SourceFactoryImpl) {
-            // Get all but the dart: Uri resolver.
-            List<UriResolver> resolvers = sourceFactory.resolvers
-                .where((r) => r is! DartUriResolver)
-                .toList();
-            // Add an embedded URI resolver in its place.
-            resolvers.add(new DartUriResolver(
-                new EmbedderSdk(resourceProvider, embedderYamls)));
-
-            // Set a new source factory.
-            SourceFactoryImpl newFactory = sourceFactory.clone();
-            newFactory.resolvers.clear();
-            newFactory.resolvers.addAll(resolvers);
-            info.context.sourceFactory = newFactory;
-            return;
-          }
-        }
-
-        // Next check for package URI updates.
-        if (info.isPathToPackageDescription(path)) {
-          Packages packages = _readPackagespec(packagespec);
-          if (packages != null) {
-            _updateContextPackageUriResolver(
-                folder, new PackagesFileDisposition(packages));
-          }
-        }
-      }
+      String contextRoot = info.folder.path;
+      ContextBuilder builder =
+          callbacks.createContextBuilder(info.folder, defaultContextOptions);
+      AnalysisOptions options =
+          builder.getAnalysisOptions(info.context, contextRoot);
+      SourceFactory factory = builder.createSourceFactory(contextRoot, options);
+      info.context.analysisOptions = options;
+      info.context.sourceFactory = factory;
     }
   }
 
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index b64f428..12b27fa 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -697,8 +697,8 @@
       }
     }
     // prepare location for a new constructor
-    _ClassMemberLocation targetLocation =
-        _prepareNewConstructorLocation(classDeclaration);
+    ClassMemberLocation targetLocation =
+        utils.prepareNewConstructorLocation(classDeclaration);
     // build constructor source
     SourceBuilder sb = new SourceBuilder(file, targetLocation.offset);
     {
@@ -741,8 +741,8 @@
     if (targetTypeNode is! ClassDeclaration) {
       return;
     }
-    _ClassMemberLocation targetLocation =
-        _prepareNewConstructorLocation(targetTypeNode);
+    ClassMemberLocation targetLocation =
+        utils.prepareNewConstructorLocation(targetTypeNode);
     String targetFile = targetElement.source.fullName;
     // build method source
     SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -797,8 +797,8 @@
     if (targetTypeNode is! ClassDeclaration) {
       return;
     }
-    _ClassMemberLocation targetLocation =
-        _prepareNewConstructorLocation(targetTypeNode);
+    ClassMemberLocation targetLocation =
+        utils.prepareNewConstructorLocation(targetTypeNode);
     String targetFile = targetElement.source.fullName;
     // build method source
     SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -935,8 +935,8 @@
         argumentsBuffer.append(parameterName);
       }
       // add proposal
-      _ClassMemberLocation targetLocation =
-          _prepareNewConstructorLocation(targetClassNode);
+      ClassMemberLocation targetLocation =
+          utils.prepareNewConstructorLocation(targetClassNode);
       SourceBuilder sb = new SourceBuilder(file, targetLocation.offset);
       {
         sb.append(targetLocation.prefix);
@@ -1017,8 +1017,8 @@
     }
     ClassDeclaration targetClassNode = targetTypeNode;
     // prepare location
-    _ClassMemberLocation targetLocation =
-        _prepareNewFieldLocation(targetClassNode);
+    ClassMemberLocation targetLocation =
+        utils.prepareNewFieldLocation(targetClassNode);
     // build method source
     String targetFile = targetClassElement.source.fullName;
     SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -1150,8 +1150,8 @@
     }
     ClassDeclaration targetClassNode = targetTypeNode;
     // prepare location
-    _ClassMemberLocation targetLocation =
-        _prepareNewGetterLocation(targetClassNode);
+    ClassMemberLocation targetLocation =
+        utils.prepareNewGetterLocation(targetClassNode);
     // build method source
     String targetFile = targetClassElement.source.fullName;
     SourceBuilder sb = new SourceBuilder(targetFile, targetLocation.offset);
@@ -1278,7 +1278,7 @@
     // EOL management
     bool isFirst = true;
     void addEolIfNotFirst() {
-      if (!isFirst || _isClassWithEmptyBody(targetClass)) {
+      if (!isFirst || utils.isClassWithEmptyBody(targetClass)) {
         sb.append(eol);
       }
       isFirst = false;
@@ -2734,64 +2734,6 @@
   }
 
   /**
-   * Return `true` if the given [classDeclaration] has open '{' and close '}'
-   * at the same line, e.g. `class X {}`.
-   */
-  bool _isClassWithEmptyBody(ClassDeclaration classDeclaration) {
-    return utils.getLineThis(classDeclaration.leftBracket.offset) ==
-        utils.getLineThis(classDeclaration.rightBracket.offset);
-  }
-
-  _ClassMemberLocation _prepareNewClassMemberLocation(
-      ClassDeclaration classDeclaration,
-      bool shouldSkip(ClassMember existingMember)) {
-    String indent = utils.getIndent(1);
-    // Find the last target member.
-    ClassMember targetMember = null;
-    List<ClassMember> members = classDeclaration.members;
-    for (ClassMember member in members) {
-      if (shouldSkip(member)) {
-        targetMember = member;
-      } else {
-        break;
-      }
-    }
-    // After the last target member.
-    if (targetMember != null) {
-      return new _ClassMemberLocation(eol + eol + indent, targetMember.end, '');
-    }
-    // At the beginning of the class.
-    String suffix = members.isNotEmpty ||
-        _isClassWithEmptyBody(classDeclaration) ? eol : '';
-    return new _ClassMemberLocation(
-        eol + indent, classDeclaration.leftBracket.end, suffix);
-  }
-
-  _ClassMemberLocation _prepareNewConstructorLocation(
-      ClassDeclaration classDeclaration) {
-    return _prepareNewClassMemberLocation(
-        classDeclaration,
-        (member) =>
-            member is FieldDeclaration || member is ConstructorDeclaration);
-  }
-
-  _ClassMemberLocation _prepareNewFieldLocation(
-      ClassDeclaration classDeclaration) {
-    return _prepareNewClassMemberLocation(
-        classDeclaration, (member) => member is FieldDeclaration);
-  }
-
-  _ClassMemberLocation _prepareNewGetterLocation(
-      ClassDeclaration classDeclaration) {
-    return _prepareNewClassMemberLocation(
-        classDeclaration,
-        (member) =>
-            member is FieldDeclaration ||
-            member is ConstructorDeclaration ||
-            member is MethodDeclaration && member.isGetter);
-  }
-
-  /**
    * Removes any [ParenthesizedExpression] enclosing [expr].
    *
    * [exprPrecedence] - the effective precedence of [expr].
@@ -2910,17 +2852,6 @@
 }
 
 /**
- * Describes the location for a newly created [ClassMember].
- */
-class _ClassMemberLocation {
-  final String prefix;
-  final int offset;
-  final String suffix;
-
-  _ClassMemberLocation(this.prefix, this.offset, this.suffix);
-}
-
-/**
  * Helper for finding [Element] with name closest to the given.
  */
 class _ClosestElementFinder {
diff --git a/pkg/analysis_server/lib/src/services/correction/util.dart b/pkg/analysis_server/lib/src/services/correction/util.dart
index 445aab2..8a357d6 100644
--- a/pkg/analysis_server/lib/src/services/correction/util.dart
+++ b/pkg/analysis_server/lib/src/services/correction/util.dart
@@ -663,6 +663,17 @@
   return expression;
 }
 
+/**
+ * Describes the location for a newly created [ClassMember].
+ */
+class ClassMemberLocation {
+  final String prefix;
+  final int offset;
+  final String suffix;
+
+  ClassMemberLocation(this.prefix, this.offset, this.suffix);
+}
+
 class CorrectionUtils {
   final CompilationUnit unit;
 
@@ -1214,6 +1225,15 @@
       _invertCondition0(expression)._source;
 
   /**
+   * Return `true` if the given [classDeclaration] has open '{' and close '}'
+   * at the same line, e.g. `class X {}`.
+   */
+  bool isClassWithEmptyBody(ClassDeclaration classDeclaration) {
+    return getLineThis(classDeclaration.leftBracket.offset) ==
+        getLineThis(classDeclaration.rightBracket.offset);
+  }
+
+  /**
    * @return <code>true</code> if selection range contains only whitespace or comments
    */
   bool isJustWhitespaceOrComment(SourceRange range) {
@@ -1226,6 +1246,57 @@
     return TokenUtils.getTokens(trimmedText).isEmpty;
   }
 
+  ClassMemberLocation prepareNewClassMemberLocation(
+      ClassDeclaration classDeclaration,
+      bool shouldSkip(ClassMember existingMember)) {
+    String indent = getIndent(1);
+    // Find the last target member.
+    ClassMember targetMember = null;
+    List<ClassMember> members = classDeclaration.members;
+    for (ClassMember member in members) {
+      if (shouldSkip(member)) {
+        targetMember = member;
+      } else {
+        break;
+      }
+    }
+    // After the last target member.
+    if (targetMember != null) {
+      return new ClassMemberLocation(
+          endOfLine + endOfLine + indent, targetMember.end, '');
+    }
+    // At the beginning of the class.
+    String suffix = members.isNotEmpty || isClassWithEmptyBody(classDeclaration)
+        ? endOfLine
+        : '';
+    return new ClassMemberLocation(
+        endOfLine + indent, classDeclaration.leftBracket.end, suffix);
+  }
+
+  ClassMemberLocation prepareNewConstructorLocation(
+      ClassDeclaration classDeclaration) {
+    return prepareNewClassMemberLocation(
+        classDeclaration,
+        (member) =>
+            member is FieldDeclaration || member is ConstructorDeclaration);
+  }
+
+  ClassMemberLocation prepareNewFieldLocation(
+      ClassDeclaration classDeclaration) {
+    return prepareNewClassMemberLocation(
+        classDeclaration, (member) => member is FieldDeclaration);
+  }
+
+  ClassMemberLocation prepareNewGetterLocation(
+      ClassDeclaration classDeclaration) {
+    return prepareNewClassMemberLocation(
+        classDeclaration,
+        (member) =>
+            member is FieldDeclaration ||
+            member is ConstructorDeclaration ||
+            member is MethodDeclaration && member.isGetter);
+  }
+
   /**
    * Returns the source with indentation changed from [oldIndent] to
    * [newIndent], keeping indentation of lines relative to each other.
diff --git a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
index 23e0342..72a29ce 100644
--- a/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
+++ b/pkg/analysis_server/lib/src/services/refactoring/rename_constructor.dart
@@ -16,6 +16,7 @@
 import 'package:analysis_server/src/services/refactoring/rename.dart';
 import 'package:analysis_server/src/services/search/hierarchy.dart';
 import 'package:analysis_server/src/services/search/search_engine.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -52,17 +53,19 @@
 
   @override
   Future fillChange() async {
-    if (!element.isSynthetic) {
-      // prepare references
-      List<SearchMatch> matches = await searchEngine.searchReferences(element);
-      List<SourceReference> references = getSourceReferences(matches);
-      // append declaration
+    // prepare references
+    List<SearchMatch> matches = await searchEngine.searchReferences(element);
+    List<SourceReference> references = getSourceReferences(matches);
+    // append declaration
+    if (element.isSynthetic) {
+      _replaceSynthetic();
+    } else {
       references.add(_createDeclarationReference());
-      // update references
-      String replacement = newName.isEmpty ? '' : '.$newName';
-      for (SourceReference reference in references) {
-        reference.addEdit(change, replacement);
-      }
+    }
+    // update references
+    String replacement = newName.isEmpty ? '' : '.$newName';
+    for (SourceReference reference in references) {
+      reference.addEdit(change, replacement);
     }
   }
 
@@ -95,4 +98,21 @@
         true,
         true));
   }
+
+  void _replaceSynthetic() {
+    ClassElement classElement = element.enclosingElement;
+    ClassDeclaration classNode = classElement.computeNode();
+    CorrectionUtils utils = new CorrectionUtils(classNode.parent);
+    ClassMemberLocation location =
+        utils.prepareNewConstructorLocation(classNode);
+    doSourceChange_addElementEdit(
+        change,
+        classElement,
+        new SourceEdit(
+            location.offset,
+            0,
+            location.prefix +
+                '${classElement.name}.$newName();' +
+                location.suffix));
+  }
 }
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index d3a8cdf..157225f 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -486,10 +486,6 @@
     if (unit != null) {
       return unit;
     }
-    unit = entry.getValue(RESOLVED_UNIT13);
-    if (unit != null) {
-      return unit;
-    }
     return entry.getValue(RESOLVED_UNIT);
   }
 
@@ -562,7 +558,6 @@
       results.add(RESOLVED_UNIT10);
       results.add(RESOLVED_UNIT11);
       results.add(RESOLVED_UNIT12);
-      results.add(RESOLVED_UNIT13);
       results.add(RESOLVED_UNIT);
       results.add(STRONG_MODE_ERRORS);
       results.add(USED_IMPORTED_ELEMENTS);
diff --git a/pkg/analysis_server/test/analysis_abstract.dart b/pkg/analysis_server/test/analysis_abstract.dart
index b76102d..0db5841 100644
--- a/pkg/analysis_server/test/analysis_abstract.dart
+++ b/pkg/analysis_server/test/analysis_abstract.dart
@@ -125,6 +125,7 @@
     //
     // Create server
     //
+    MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
     return new AnalysisServer(
         serverChannel,
         resourceProvider,
@@ -132,7 +133,7 @@
         index,
         serverPlugin,
         new AnalysisServerOptions(),
-        new DartSdkManager('', false, (_) => new MockSdk()),
+        new DartSdkManager('/', false, (_) => sdk),
         InstrumentationService.NULL_SERVICE);
   }
 
@@ -143,10 +144,10 @@
   /**
    * Creates a project `/project`.
    */
-  void createProject() {
+  void createProject({Map<String, String> packageRoots}) {
     resourceProvider.newFolder(projectPath);
     Request request =
-        new AnalysisSetAnalysisRootsParams([projectPath], []).toRequest('0');
+        new AnalysisSetAnalysisRootsParams([projectPath], [], packageRoots: packageRoots).toRequest('0');
     handleSuccessfulRequest(request, handler: analysisHandler);
   }
 
diff --git a/pkg/analysis_server/test/analysis_server_test.dart b/pkg/analysis_server/test/analysis_server_test.dart
index 1c2e212..af36f04 100644
--- a/pkg/analysis_server/test/analysis_server_test.dart
+++ b/pkg/analysis_server/test/analysis_server_test.dart
@@ -137,6 +137,7 @@
     manager.processPlugins([plugin]);
     channel = new MockServerChannel();
     resourceProvider = new MemoryResourceProvider();
+    MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
     packageMapProvider = new MockPackageMapProvider();
     server = new AnalysisServer(
         channel,
@@ -145,7 +146,7 @@
         null,
         plugin,
         new AnalysisServerOptions(),
-        new DartSdkManager('', false, (_) => new MockSdk()),
+        new DartSdkManager('/', false, (_) => sdk),
         InstrumentationService.NULL_SERVICE,
         rethrowExceptions: true);
     processRequiredPlugins();
@@ -286,26 +287,6 @@
     expect(pair.source, isNull);
   }
 
-  test_getContextSourcePair_package_inRoot() {
-    String rootPath = '/my_package';
-    String filePath = rootPath + '/lib/file.dart';
-    Folder rootFolder = resourceProvider.newFolder(rootPath);
-    resourceProvider.newFile(filePath, 'library lib;');
-
-    packageMapProvider.packageMap = <String, List<Folder>>{
-      'my_package': <Folder>[rootFolder]
-    };
-    // create contexts
-    server.setAnalysisRoots('0', [rootPath], [], {});
-    // get pair
-    ContextSourcePair pair = server.getContextSourcePair(filePath);
-    _assertContextOfFolder(pair.context, rootPath);
-    Source source = pair.source;
-    expect(source, isNotNull);
-    expect(source.uri.scheme, 'package');
-    expect(source.fullName, filePath);
-  }
-
   test_getContextSourcePair_simple() {
     String dirPath = '/dir';
     String filePath = dirPath + '/file.dart';
@@ -321,6 +302,23 @@
     expect(source.fullName, filePath);
   }
 
+  test_getContextSourcePair_withPackagesFile() {
+    String dirPath = '/dir';
+    String packagesFilePath = dirPath + '/.packages';
+    resourceProvider.newFile(packagesFilePath, 'dir:lib/');
+    String filePath = dirPath + '/lib/file.dart';
+    resourceProvider.newFile(filePath, 'library lib;');
+    // create contexts
+    server.setAnalysisRoots('0', [dirPath], [], {});
+    // get pair
+    ContextSourcePair pair = server.getContextSourcePair(filePath);
+    _assertContextOfFolder(pair.context, dirPath);
+    Source source = pair.source;
+    expect(source, isNotNull);
+    expect(source.uri.scheme, 'package');
+    expect(source.fullName, filePath);
+  }
+
   /**
    * Test that having multiple analysis contexts analyze the same file doesn't
    * cause that file to receive duplicate notifications when it's modified.
diff --git a/pkg/analysis_server/test/completion_test.dart b/pkg/analysis_server/test/completion_test.dart
index 2a453eb..70ac854 100644
--- a/pkg/analysis_server/test/completion_test.dart
+++ b/pkg/analysis_server/test/completion_test.dart
@@ -2664,7 +2664,7 @@
           "8-null"
         ],
         failingTests: '234567'); //TODO(jwren) 234 failing as correct selection
-        // offset assertions can't be passed into buildTests(..)
+    // offset assertions can't be passed into buildTests(..)
 
     // keywords
     buildTests('test018', '''!1part !2of foo;''', <String>["1+part", "2+of"],
@@ -2850,7 +2850,7 @@
 
     // test analysis of untyped fields and top-level vars
     buildTests('test035', '''class Y {final x='hi';mth() {x.!1length;}}''',
-        <String>["1+length"]);
+        <String>["1+length"], failingTests: '1');
 
     // TODO(scheglov) decide what to do with Type for untyped field (not
     // supported by the new store)
@@ -2905,8 +2905,8 @@
         failingTests: '2');
 
     // test analysis of untyped fields and top-level vars
-    buildTests('test039', '''class X{}var x = null as !1X;''',
-        <String>["1-void"]);
+    buildTests(
+        'test039', '''class X{}var x = null as !1X;''', <String>["1-void"]);
 
     // test arg lists with named params
     buildTests('test040', '''m(){f(a, b, {x1, x2, y}) {};f(1, 2, !1)!2;}''',
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 41b0983..1aa02fe 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -1820,8 +1820,8 @@
     processRequiredPlugins();
     resourceProvider = new MemoryResourceProvider();
     packageMapProvider = new MockPackageMapProvider();
-    DartSdkManager sdkManager =
-        new DartSdkManager('', false, (_) => new MockSdk());
+    DartSdk sdk = new MockSdk(resourceProvider: resourceProvider);
+    DartSdkManager sdkManager = new DartSdkManager('/', false, (_) => sdk);
     manager = new ContextManagerImpl(
         resourceProvider,
         sdkManager,
@@ -2705,6 +2705,15 @@
   }
 
   @override
+  ContextBuilder createContextBuilder(Folder folder, AnalysisOptions options) {
+    DartSdkManager sdkManager = new DartSdkManager('/', false, null);
+    ContextBuilder builder =
+        new ContextBuilder(resourceProvider, sdkManager, new ContentCache());
+    builder.defaultOptions = options;
+    return builder;
+  }
+
+  @override
   void moveContext(Folder from, Folder to) {
     String path = from.path;
     String path2 = to.path;
diff --git a/pkg/analysis_server/test/domain_analysis_test.dart b/pkg/analysis_server/test/domain_analysis_test.dart
index 45ca634..1a7671e 100644
--- a/pkg/analysis_server/test/domain_analysis_test.dart
+++ b/pkg/analysis_server/test/domain_analysis_test.dart
@@ -41,6 +41,7 @@
     ExtensionManager manager = new ExtensionManager();
     ServerPlugin serverPlugin = new ServerPlugin();
     manager.processPlugins([serverPlugin]);
+    MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
     server = new AnalysisServer(
         serverChannel,
         resourceProvider,
@@ -48,7 +49,7 @@
         null,
         serverPlugin,
         new AnalysisServerOptions(),
-        new DartSdkManager('', false, (_) => new MockSdk()),
+        new DartSdkManager('/', false, (_) => sdk),
         InstrumentationService.NULL_SERVICE);
     handler = new AnalysisDomainHandler(server);
   });
@@ -250,7 +251,9 @@
     return helper.onAnalysisComplete.then((_) {
       Request request = new Request('0', ANALYSIS_UPDATE_CONTENT, {
         'files': {
-          helper.testFile: {TYPE: 'foo',}
+          helper.testFile: {
+            TYPE: 'foo',
+          }
         }
       });
       Response response = helper.handler.handleRequest(request);
@@ -425,9 +428,8 @@
 library lib_a;
 class A {}
 ''');
-    packageMapProvider.packageMap['pkgA'] = [
-      resourceProvider.getResource('/packages/pkgA')
-    ];
+    resourceProvider.newFile(
+        '/project/.packages', 'pkgA:file:///packages/pkgA');
     addTestFile('''
 import 'package:pkgA/libA.dart';
 main(A a) {
@@ -468,6 +470,7 @@
     ExtensionManager manager = new ExtensionManager();
     ServerPlugin serverPlugin = new ServerPlugin();
     manager.processPlugins([serverPlugin]);
+    MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
     server = new AnalysisServer(
         serverChannel,
         resourceProvider,
@@ -475,7 +478,7 @@
         null,
         serverPlugin,
         new AnalysisServerOptions(),
-        new DartSdkManager('', false, (_) => new MockSdk()),
+        new DartSdkManager('/', false, (_) => sdk),
         InstrumentationService.NULL_SERVICE);
     handler = new AnalysisDomainHandler(server);
     // listen for notifications
@@ -704,9 +707,8 @@
 library lib_a;
 class A {}
 ''');
-    packageMapProvider.packageMap = {
-      'pkgA': [(resourceProvider.newFolder('/packages/pkgA/lib'))]
-    };
+    resourceProvider.newFile(
+        '/project/.packages', 'pkgA:file:///packages/pkgA/lib');
     //
     addTestFile('''
 import 'package:pkgA/libA.dart';
@@ -774,9 +776,7 @@
 library lib_a;
 class A {}
 ''');
-    packageMapProvider.packageMap = {
-      'pkgA': [(resourceProvider.newFolder('/packages/pkgA/lib'))]
-    };
+    resourceProvider.newFile('/project/.packages', 'pkgA:/packages/pkgA/lib');
     //
     addTestFile('// no "pkgA" reference');
     createProject();
diff --git a/pkg/analysis_server/test/domain_diagnostic_test.dart b/pkg/analysis_server/test/domain_diagnostic_test.dart
index 3a6f3cb..1c4ba4a 100644
--- a/pkg/analysis_server/test/domain_diagnostic_test.dart
+++ b/pkg/analysis_server/test/domain_diagnostic_test.dart
@@ -47,6 +47,7 @@
     //
     var serverChannel = new MockServerChannel();
     resourceProvider = new MemoryResourceProvider();
+    MockSdk sdk = new MockSdk(resourceProvider: resourceProvider);
     server = new AnalysisServer(
         serverChannel,
         resourceProvider,
@@ -54,7 +55,7 @@
         null,
         serverPlugin,
         new AnalysisServerOptions(),
-        new DartSdkManager('', false, (_) => new MockSdk()),
+        new DartSdkManager('/', false, (_) => sdk),
         InstrumentationService.NULL_SERVICE);
     handler = new DiagnosticDomainHandler(server);
   });
diff --git a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart b/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart
index 2fee03a..70bd7aa 100644
--- a/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart
+++ b/pkg/analysis_server/test/integration/analysis/get_errors_nonStandard_sdk.dart
@@ -8,8 +8,6 @@
 import 'dart:io';
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:path/path.dart' as path;
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -75,10 +73,14 @@
   }
 
   @override
-  Future startServer({int servicesPort, bool checked: true}) {
+  Future startServer(
+      {bool checked: true, int diagnosticPort, int servicesPort}) {
     String sdkPath = createNonStandardSdk();
     return server.start(
-        servicesPort: servicesPort, checked: checked, sdkPath: sdkPath);
+        checked: checked,
+        diagnosticPort: diagnosticPort,
+        sdkPath: sdkPath,
+        servicesPort: servicesPort);
   }
 
   Future test_getErrors() async {
diff --git a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
index bd07449..c8d75ee 100644
--- a/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
+++ b/pkg/analysis_server/test/integration/analysis/highlights_test2.dart
@@ -20,10 +20,12 @@
 
 @reflectiveTest
 class AnalysisHighlightsTest extends AbstractAnalysisServerIntegrationTest {
-  Future startServer({int servicesPort, bool checked: true}) {
+  Future startServer(
+      {bool checked: true, int diagnosticPort, int servicesPort}) {
     return server.start(
-        servicesPort: servicesPort,
         checked: checked,
+        diagnosticPort: diagnosticPort,
+        servicesPort: servicesPort,
         useAnalysisHighlight2: true);
   }
 
@@ -109,6 +111,7 @@
         expect(highlights[type], equals(expected.toSet()));
         highlights.remove(type);
       }
+
       check(HighlightRegionType.ANNOTATION, ['@override']);
       check(HighlightRegionType.BUILT_IN,
           ['as', 'get', 'import', 'set', 'static', 'typedef']);
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 5ae41f9..1893c18 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -205,8 +205,12 @@
   /**
    * Start [server].
    */
-  Future startServer({int servicesPort, bool checked: true}) =>
-      server.start(servicesPort: servicesPort, checked: checked);
+  Future startServer(
+          {bool checked: true, int diagnosticPort, int servicesPort}) =>
+      server.start(
+          checked: checked,
+          diagnosticPort: diagnosticPort,
+          servicesPort: servicesPort);
 
   /**
    * After every test, the server is stopped and [sourceDirectory] is deleted.
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 5681817..0d39a19 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -242,18 +242,32 @@
     LIB_INTERNAL,
   ];
 
-  final resource.MemoryResourceProvider provider =
-      new resource.MemoryResourceProvider();
+  static const String librariesContent = r'''
+const Map<String, LibraryInfo> libraries = const {
+  "async": const LibraryInfo("async/async.dart"),
+  "collection": const LibraryInfo("collection/collection.dart"),
+  "convert": const LibraryInfo("convert/convert.dart"),
+  "core": const LibraryInfo("core/core.dart"),
+  "html": const LibraryInfo("html/dartium/html_dartium.dart"),
+  "math": const LibraryInfo("math/math.dart"),
+  "_internal": const LibraryInfo("internal/internal.dart"),
+};
+''';
+
+  final resource.MemoryResourceProvider provider;
 
   /**
    * The [AnalysisContext] which is used for all of the sources.
    */
   InternalAnalysisContext _analysisContext;
 
-  MockSdk() {
+  MockSdk({resource.ResourceProvider resourceProvider})
+      : provider = resourceProvider ?? new resource.MemoryResourceProvider() {
     LIBRARIES.forEach((SdkLibrary library) {
       provider.newFile(library.path, (library as MockSdkLibrary).content);
     });
+    provider.newFile('/lib/_internal/sdk_library_metadata/lib/libraries.dart',
+        librariesContent);
   }
 
   @override
diff --git a/pkg/analysis_server/test/search/type_hierarchy_test.dart b/pkg/analysis_server/test/search/type_hierarchy_test.dart
index 0dfc892..c3efbbf 100644
--- a/pkg/analysis_server/test/search/type_hierarchy_test.dart
+++ b/pkg/analysis_server/test/search/type_hierarchy_test.dart
@@ -33,7 +33,9 @@
   void setUp() {
     super.setUp();
     createProject();
-    server.handlers = [new SearchDomainHandler(server),];
+    server.handlers = [
+      new SearchDomainHandler(server),
+    ];
   }
 
   test_bad_function() async {
@@ -168,7 +170,7 @@
 
   test_class_extends_fileAndPackageUris() async {
     // prepare packages
-    String pkgFile = '/packages/pkgA/libA.dart';
+    String pkgFile = '/packages/pkgA/lib/libA.dart';
     resourceProvider.newFile(
         pkgFile,
         '''
@@ -176,14 +178,16 @@
 class A {}
 class B extends A {}
 ''');
-    packageMapProvider.packageMap['pkgA'] = [
-      resourceProvider.getResource('/packages/pkgA')
-    ];
+    resourceProvider.newFile(
+        '/packages/pkgA/.packages', 'pkgA:file:///packages/pkgA/lib');
     // reference the package from a project
+    resourceProvider.newFile(
+        '$projectPath/.packages', 'pkgA:file:///packages/pkgA/lib');
     addTestFile('''
 import 'package:pkgA/libA.dart';
 class C extends A {}
 ''');
+    await waitForTasksFinished();
     // configure roots
     Request request =
         new AnalysisSetAnalysisRootsParams([projectPath, '/packages/pkgA'], [])
diff --git a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
index bb4318b..f10a11d 100644
--- a/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
+++ b/pkg/analysis_server/test/services/refactoring/rename_constructor_test.dart
@@ -132,6 +132,39 @@
 ''');
   }
 
+  test_createChange_add_toSynthetic() {
+    indexTestUnit('''
+class A {
+}
+class B extends A {
+  B() : super() {}
+  factory B._() = A;
+}
+main() {
+  new A();
+}
+''');
+    // configure refactoring
+    _createConstructorInvocationRefactoring('new A();');
+    expect(refactoring.refactoringName, 'Rename Constructor');
+    expect(refactoring.elementKindName, 'constructor');
+    expect(refactoring.oldName, '');
+    // validate change
+    refactoring.newName = 'newName';
+    return assertSuccessfulRefactoring('''
+class A {
+  A.newName();
+}
+class B extends A {
+  B() : super.newName() {}
+  factory B._() = A.newName;
+}
+main() {
+  new A.newName();
+}
+''');
+  }
+
   test_createChange_change() {
     indexTestUnit('''
 class A {
@@ -210,4 +243,10 @@
         search, (node) => node is ConstructorDeclaration);
     createRenameRefactoringForElement(element);
   }
+
+  void _createConstructorInvocationRefactoring(String search) {
+    ConstructorElement element = findNodeElementAtString(
+        search, (node) => node is InstanceCreationExpression);
+    createRenameRefactoringForElement(element);
+  }
 }
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index 7aa782a..93ddb20 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -422,7 +422,7 @@
           <field name="sources">
             <map>
               <key><ref>String</ref></key>
-              <value><list>><ref>String</ref></list></value>
+              <value><list><ref>String</ref></list></value>
             </map>
             <p>
               A mapping from source URIs to directly reachable source URIs. For example,
diff --git a/pkg/analyzer/doc/tasks.html b/pkg/analyzer/doc/tasks.html
index 3129e1a..df31e7a 100644
--- a/pkg/analyzer/doc/tasks.html
+++ b/pkg/analyzer/doc/tasks.html
@@ -53,24 +53,23 @@
   CREATED_RESOLVED_UNIT [shape=box]
   CREATED_RESOLVED_UNIT1 [shape=box]
   CREATED_RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+  CREATED_RESOLVED_UNIT10 -> InferStaticVariableTypeTask
+  CREATED_RESOLVED_UNIT10 -> PartiallyResolveUnitReferencesTask
+  CREATED_RESOLVED_UNIT10 -> ResolveInstanceFieldsInUnitTask
+  CREATED_RESOLVED_UNIT10 -> ResolveUnitTask
   CREATED_RESOLVED_UNIT10 [shape=box]
-  CREATED_RESOLVED_UNIT11 -> InferInstanceMembersInUnitTask
-  CREATED_RESOLVED_UNIT11 -> InferStaticVariableTypeTask
-  CREATED_RESOLVED_UNIT11 -> PartiallyResolveUnitReferencesTask
-  CREATED_RESOLVED_UNIT11 -> ResolveInstanceFieldsInUnitTask
-  CREATED_RESOLVED_UNIT11 -> ResolveUnitTask
+  CREATED_RESOLVED_UNIT11 -> ResolveConstantExpressionTask
   CREATED_RESOLVED_UNIT11 [shape=box]
-  CREATED_RESOLVED_UNIT12 -> ResolveConstantExpressionTask
   CREATED_RESOLVED_UNIT12 [shape=box]
-  CREATED_RESOLVED_UNIT13 [shape=box]
   CREATED_RESOLVED_UNIT2 [shape=box]
   CREATED_RESOLVED_UNIT3 [shape=box]
   CREATED_RESOLVED_UNIT4 [shape=box]
   CREATED_RESOLVED_UNIT5 [shape=box]
   CREATED_RESOLVED_UNIT6 [shape=box]
   CREATED_RESOLVED_UNIT7 [shape=box]
+  CREATED_RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
   CREATED_RESOLVED_UNIT8 [shape=box]
-  CREATED_RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+  CREATED_RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
   CREATED_RESOLVED_UNIT9 [shape=box]
   ComputeConstantDependenciesTask -> CONSTANT_DEPENDENCIES
   ComputeConstantValueTask -> CONSTANT_VALUE
@@ -78,7 +77,6 @@
   ComputeLibraryCycleTask -> LIBRARY_CYCLE
   ComputeLibraryCycleTask -> LIBRARY_CYCLE_DEPENDENCIES
   ComputeLibraryCycleTask -> LIBRARY_CYCLE_UNITS
-  ComputePropagableVariableDependenciesTask -> PROPAGABLE_VARIABLE_DEPENDENCIES
   ComputeRequiredConstantsTask -> PENDING_ERRORS
   ComputeRequiredConstantsTask -> REQUIRED_CONSTANTS
   ContainingLibrariesTask -> CONTAINING_LIBRARIES
@@ -91,14 +89,14 @@
   EXPORTED_LIBRARIES -> BuildDirectiveElementsTask
   EXPORTED_LIBRARIES -> ReadyLibraryElement2Task
   EXPORTED_LIBRARIES -> ReadyLibraryElement5Task
-  EXPORTED_LIBRARIES -> ReadyLibraryElement6Task
+  EXPORTED_LIBRARIES -> ReadyLibraryElement7Task
   EXPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
   EXPORTED_LIBRARIES [shape=box]
   EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
   EXPORT_SOURCE_CLOSURE -> ResolveTopLevelUnitTypeBoundsTask
   EXPORT_SOURCE_CLOSURE [shape=box]
-  EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT13
-  EvaluateUnitConstantsTask -> RESOLVED_UNIT13
+  EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT12
+  EvaluateUnitConstantsTask -> RESOLVED_UNIT12
   GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
   GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
   GenerateHintsTask -> HINTS
@@ -110,7 +108,7 @@
   IMPORTED_LIBRARIES -> BuildDirectiveElementsTask
   IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
   IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
-  IMPORTED_LIBRARIES -> ReadyLibraryElement6Task
+  IMPORTED_LIBRARIES -> ReadyLibraryElement7Task
   IMPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
   IMPORTED_LIBRARIES -> ResolveTopLevelUnitTypeBoundsTask
   IMPORTED_LIBRARIES [shape=box]
@@ -124,12 +122,12 @@
   INFERRED_STATIC_VARIABLE -> InferStaticVariableTypesInUnitTask
   INFERRED_STATIC_VARIABLE [shape=box]
   IS_LAUNCHABLE [shape=box]
-  InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT11
-  InferInstanceMembersInUnitTask -> RESOLVED_UNIT11
+  InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT10
+  InferInstanceMembersInUnitTask -> RESOLVED_UNIT10
   InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
   InferStaticVariableTypeTask -> STATIC_VARIABLE_RESOLUTION_ERRORS
-  InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT9
-  InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT9
+  InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
+  InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT8
   InferStaticVariableTypesInUnitTask -> STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
   LIBRARY_CYCLE [shape=box]
   LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
@@ -163,12 +161,12 @@
   LIBRARY_ELEMENT5 -> ResolveUnitTypeNamesTask
   LIBRARY_ELEMENT5 [shape=box]
   LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
-  LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryTask
   LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
   LIBRARY_ELEMENT6 -> ResolveInstanceFieldsInUnitTask
+  LIBRARY_ELEMENT6 -> ResolvedUnit7InLibraryTask
   LIBRARY_ELEMENT6 [shape=box]
-  LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
-  LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+  LIBRARY_ELEMENT7 -> ReadyLibraryElement7Task
+  LIBRARY_ELEMENT7 -> ResolvedUnit7InLibraryClosureTask
   LIBRARY_ELEMENT7 [shape=box]
   LIBRARY_ELEMENT8 -> ResolveLibraryReferencesTask
   LIBRARY_ELEMENT8 -> ResolveUnitTask
@@ -178,11 +176,11 @@
   LIBRARY_ELEMENT9 [shape=box]
   LIBRARY_ERRORS_READY [shape=box]
   LIBRARY_SPECIFIC_UNITS -> GenerateHintsTask
-  LIBRARY_SPECIFIC_UNITS -> PropagateVariableTypesInLibraryTask
   LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnitTask
   LIBRARY_SPECIFIC_UNITS -> ResolveLibraryReferencesTask
   LIBRARY_SPECIFIC_UNITS -> ResolveLibraryTypeNamesTask
   LIBRARY_SPECIFIC_UNITS -> ResolveTopLevelLibraryTypeBoundsTask
+  LIBRARY_SPECIFIC_UNITS -> ResolvedUnit7InLibraryTask
   LIBRARY_SPECIFIC_UNITS [shape=box]
   LIBRARY_UNIT_ERRORS -> dartErrorsForUnit
   LIBRARY_UNIT_ERRORS [shape=box]
@@ -205,13 +203,6 @@
   PARSE_ERRORS [shape=box]
   PENDING_ERRORS -> VerifyUnitTask
   PENDING_ERRORS [shape=box]
-  PROPAGABLE_VARIABLES_IN_UNIT -> PropagateVariableTypesInUnitTask
-  PROPAGABLE_VARIABLES_IN_UNIT [shape=box]
-  PROPAGABLE_VARIABLE_DEPENDENCIES -> PropagateVariableTypeTask
-  PROPAGABLE_VARIABLE_DEPENDENCIES [shape=box]
-  PROPAGATED_VARIABLE -> PropagateVariableTypeTask
-  PROPAGATED_VARIABLE -> PropagateVariableTypesInUnitTask
-  PROPAGATED_VARIABLE [shape=box]
   ParseDartTask -> EXPLICITLY_IMPORTED_LIBRARIES
   ParseDartTask -> EXPORTED_LIBRARIES
   ParseDartTask -> IMPORTED_LIBRARIES
@@ -225,21 +216,15 @@
   ParseDartTask -> UNITS
   PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT7
   PartiallyResolveUnitReferencesTask -> INFERABLE_STATIC_VARIABLES_IN_UNIT
-  PartiallyResolveUnitReferencesTask -> PROPAGABLE_VARIABLES_IN_UNIT
   PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT7
-  PropagateVariableTypeTask -> PROPAGATED_VARIABLE
-  PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT8
-  PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT7
-  PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
-  PropagateVariableTypesInUnitTask -> RESOLVED_UNIT8
   READY_LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
   READY_LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
   READY_LIBRARY_ELEMENT2 [shape=box]
   READY_LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
   READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
   READY_LIBRARY_ELEMENT6 [shape=box]
-  READY_LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
-  READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+  READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement7Task
+  READY_LIBRARY_ELEMENT7 -> ResolvedUnit7InLibraryClosureTask
   READY_LIBRARY_ELEMENT7 [shape=box]
   READY_RESOLVED_UNIT -> ResolveLibraryTask
   READY_RESOLVED_UNIT -> VerifyUnitTask
@@ -260,17 +245,15 @@
   RESOLVED_UNIT1 -> BuildLibraryElementTask
   RESOLVED_UNIT1 -> ResolveDirectiveElementsTask
   RESOLVED_UNIT1 [shape=box]
-  RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+  RESOLVED_UNIT10 -> ResolveUnitTask
   RESOLVED_UNIT10 [shape=box]
-  RESOLVED_UNIT11 -> ResolveUnitTask
+  RESOLVED_UNIT11 -> EvaluateUnitConstantsTask
+  RESOLVED_UNIT11 -> GatherUsedImportedElementsTask
+  RESOLVED_UNIT11 -> GatherUsedLocalElementsTask
+  RESOLVED_UNIT11 -> ResolveLibraryReferencesTask
   RESOLVED_UNIT11 [shape=box]
-  RESOLVED_UNIT12 -> EvaluateUnitConstantsTask
-  RESOLVED_UNIT12 -> GatherUsedImportedElementsTask
-  RESOLVED_UNIT12 -> GatherUsedLocalElementsTask
-  RESOLVED_UNIT12 -> ResolveLibraryReferencesTask
+  RESOLVED_UNIT12 -> StrongModeVerifyUnitTask
   RESOLVED_UNIT12 [shape=box]
-  RESOLVED_UNIT13 -> StrongModeVerifyUnitTask
-  RESOLVED_UNIT13 [shape=box]
   RESOLVED_UNIT2 -> BuildEnumMemberElementsTask
   RESOLVED_UNIT2 [shape=box]
   RESOLVED_UNIT3 -> ResolveTopLevelUnitTypeBoundsTask
@@ -284,15 +267,13 @@
   RESOLVED_UNIT6 -> PartiallyResolveUnitReferencesTask
   RESOLVED_UNIT6 [shape=box]
   RESOLVED_UNIT7 -> ComputeInferableStaticVariableDependenciesTask
-  RESOLVED_UNIT7 -> ComputePropagableVariableDependenciesTask
-  RESOLVED_UNIT7 -> PropagateVariableTypeTask
-  RESOLVED_UNIT7 -> PropagateVariableTypesInUnitTask
+  RESOLVED_UNIT7 -> InferStaticVariableTypeTask
+  RESOLVED_UNIT7 -> InferStaticVariableTypesInUnitTask
+  RESOLVED_UNIT7 -> ResolvedUnit7InLibraryTask
   RESOLVED_UNIT7 [shape=box]
-  RESOLVED_UNIT8 -> InferStaticVariableTypeTask
-  RESOLVED_UNIT8 -> InferStaticVariableTypesInUnitTask
-  RESOLVED_UNIT8 -> PropagateVariableTypesInLibraryTask
+  RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
   RESOLVED_UNIT8 [shape=box]
-  RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+  RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
   RESOLVED_UNIT9 [shape=box]
   RESOLVE_TYPE_BOUNDS_ERRORS -> LibraryUnitErrorsTask
   RESOLVE_TYPE_BOUNDS_ERRORS [shape=box]
@@ -302,13 +283,13 @@
   RESOLVE_UNIT_ERRORS [shape=box]
   ReadyLibraryElement2Task -> READY_LIBRARY_ELEMENT2
   ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT6
-  ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT7
+  ReadyLibraryElement7Task -> READY_LIBRARY_ELEMENT7
   ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
   ResolveConstantExpressionTask -> CONSTANT_EXPRESSION_RESOLVED
   ResolveDirectiveElementsTask -> CREATED_RESOLVED_UNIT2
   ResolveDirectiveElementsTask -> RESOLVED_UNIT2
-  ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT10
-  ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT10
+  ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT9
+  ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT9
   ResolveLibraryReferencesTask -> LIBRARY_ELEMENT9
   ResolveLibraryTask -> LIBRARY_ELEMENT
   ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT6
@@ -317,8 +298,8 @@
   ResolveTopLevelUnitTypeBoundsTask -> RESOLVED_UNIT4
   ResolveTopLevelUnitTypeBoundsTask -> RESOLVE_TYPE_BOUNDS_ERRORS
   ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
-  ResolveUnitTask -> CREATED_RESOLVED_UNIT12
-  ResolveUnitTask -> RESOLVED_UNIT12
+  ResolveUnitTask -> CREATED_RESOLVED_UNIT11
+  ResolveUnitTask -> RESOLVED_UNIT11
   ResolveUnitTask -> RESOLVE_UNIT_ERRORS
   ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT5
   ResolveUnitTypeNamesTask -> RESOLVED_UNIT5
@@ -326,6 +307,8 @@
   ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT6
   ResolveVariableReferencesTask -> RESOLVED_UNIT6
   ResolveVariableReferencesTask -> VARIABLE_REFERENCE_ERRORS
+  ResolvedUnit7InLibraryClosureTask -> LIBRARY_ELEMENT8
+  ResolvedUnit7InLibraryTask -> LIBRARY_ELEMENT7
   SCAN_ERRORS -> dartErrorsForSource
   SCAN_ERRORS [shape=box]
   SOURCE_KIND -> BuildDirectiveElementsTask
@@ -352,7 +335,6 @@
   TYPE_PROVIDER -> InferInstanceMembersInUnitTask
   TYPE_PROVIDER -> InferStaticVariableTypeTask
   TYPE_PROVIDER -> PartiallyResolveUnitReferencesTask
-  TYPE_PROVIDER -> PropagateVariableTypeTask
   TYPE_PROVIDER -> ResolveInstanceFieldsInUnitTask
   TYPE_PROVIDER -> ResolveLibraryTypeNamesTask
   TYPE_PROVIDER -> ResolveTopLevelUnitTypeBoundsTask
diff --git a/pkg/analyzer/lib/file_system/file_system.dart b/pkg/analyzer/lib/file_system/file_system.dart
index 8fb6025..f005eef 100644
--- a/pkg/analyzer/lib/file_system/file_system.dart
+++ b/pkg/analyzer/lib/file_system/file_system.dart
@@ -54,12 +54,6 @@
   File renameSync(String newPath);
 
   /**
-   * Return a file that refers to the same file as this file, but whose path
-   * does not contain any symbolic links.
-   */
-  File resolveSymbolicLinksSync();
-
-  /**
    * Synchronously write the given [bytes] to the file. The new content will
    * replace any existing content.
    *
@@ -183,6 +177,12 @@
   bool isOrContains(String path);
 
   /**
+   * Return a resource that refers to the same resource as this resource, but
+   * whose path does not contain any symbolic links.
+   */
+  Resource resolveSymbolicLinksSync();
+
+  /**
    * Return a Uri representing this resource.
    */
   Uri toUri();
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index d179d7f..0ba9b94 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -201,6 +201,15 @@
     return file;
   }
 
+  /**
+   * Write a representation of the file system on the given [sink].
+   */
+  void writeOn(StringSink sink) {
+    List<String> paths = _pathToResource.keys.toList();
+    paths.sort();
+    paths.forEach(sink.writeln);
+  }
+
   void _checkFileAtPath(String path) {
     _MemoryResource resource = _pathToResource[path];
     if (resource is! _MemoryFile) {
@@ -484,6 +493,9 @@
   }
 
   @override
+  Folder resolveSymbolicLinksSync() => this;
+
+  @override
   Uri toUri() =>
       new Uri.directory(path, windows: _provider.pathContext == windows);
 }
diff --git a/pkg/analyzer/lib/file_system/physical_file_system.dart b/pkg/analyzer/lib/file_system/physical_file_system.dart
index b771149..38fc38a 100644
--- a/pkg/analyzer/lib/file_system/physical_file_system.dart
+++ b/pkg/analyzer/lib/file_system/physical_file_system.dart
@@ -217,6 +217,11 @@
   @override
   Stream<WatchEvent> get changes => new DirectoryWatcher(_entry.path).events;
 
+  /**
+   * Return the underlying file being represented by this wrapper.
+   */
+  io.Directory get _directory => _entry as io.Directory;
+
   @override
   String canonicalizePath(String relPath) {
     return normalize(join(path, relPath));
@@ -277,6 +282,16 @@
   }
 
   @override
+  Folder resolveSymbolicLinksSync() {
+    try {
+      return new _PhysicalFolder(
+          new io.Directory(_directory.resolveSymbolicLinksSync()));
+    } on io.FileSystemException catch (exception) {
+      throw new FileSystemException(exception.path, exception.message);
+    }
+  }
+
+  @override
   Uri toUri() => new Uri.directory(path);
 }
 
diff --git a/pkg/analyzer/lib/src/context/builder.dart b/pkg/analyzer/lib/src/context/builder.dart
index 51c0a21..65928bf 100644
--- a/pkg/analyzer/lib/src/context/builder.dart
+++ b/pkg/analyzer/lib/src/context/builder.dart
@@ -9,6 +9,7 @@
 
 import 'package:analyzer/context/declared_variables.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
@@ -20,6 +21,7 @@
 import 'package:package_config/packages.dart';
 import 'package:package_config/packages_file.dart';
 import 'package:package_config/src/packages_impl.dart';
+import 'package:path/src/context.dart';
 import 'package:yaml/yaml.dart';
 
 /**
@@ -121,11 +123,9 @@
    * *Note:* This method is not yet fully implemented and should not be used.
    */
   AnalysisContext buildContext(String path) {
-    // TODO(brianwilkerson) Split getAnalysisOptions so we can capture the
-    // option map and use it to run the options processors.
-    AnalysisOptions options = getAnalysisOptions(path);
     InternalAnalysisContext context =
         AnalysisEngine.instance.createAnalysisContext();
+    AnalysisOptions options = getAnalysisOptions(context, path);
     context.contentCache = contentCache;
     context.sourceFactory = createSourceFactory(path, options);
     context.analysisOptions = options;
@@ -184,6 +184,7 @@
       File configFile = resourceProvider.getFile(defaultPackageFilePath);
       List<int> bytes = configFile.readAsBytesSync();
       Map<String, Uri> map = parse(bytes, configFile.toUri());
+      resolveSymbolicLinks(map);
       return new MapPackages(map);
     } else if (defaultPackagesDirectoryPath != null) {
       Folder folder = resourceProvider.getFolder(defaultPackagesDirectoryPath);
@@ -215,7 +216,7 @@
           packageResolver,
           fileResolver
         ];
-        return new SourceFactory(resolvers);
+        return new SourceFactory(resolvers, null, resourceProvider);
       }
     }
     Packages packages = createPackageMap(rootDirectoryPath);
@@ -225,10 +226,12 @@
     if (packageMap != null) {
       // TODO(brianwilkerson) I think that we don't need a PackageUriResolver
       // when we can pass the packages object to the source factory directly.
+      // Actually, I think we're using it to restoreUri, which could lead to
+      // inconsistencies.
       resolvers.add(new PackageMapUriResolver(resourceProvider, packageMap));
     }
     resolvers.add(fileResolver);
-    return new SourceFactory(resolvers);
+    return new SourceFactory(resolvers, packages, resourceProvider);
   }
 
   /**
@@ -260,6 +263,7 @@
       List<int> fileBytes = location.readAsBytesSync();
       Map<String, Uri> map =
           parse(fileBytes, resourceProvider.pathContext.toUri(location.path));
+      resolveSymbolicLinks(map);
       return new MapPackages(map);
     } else if (location is Folder) {
       return getPackagesFromFolder(location);
@@ -334,16 +338,24 @@
   }
 
   /**
-   * Return the analysis options that should be used when analyzing code in the
-   * directory with the given [path].
+   * Return the analysis options that should be used when the given [context] is
+   * used to analyze code in the directory with the given [path].
    */
-  AnalysisOptions getAnalysisOptions(String path) {
+  AnalysisOptions getAnalysisOptions(AnalysisContext context, String path) {
     AnalysisOptionsImpl options = createDefaultOptions();
     File optionsFile = getOptionsFile(path);
     if (optionsFile != null) {
-      Map<String, YamlNode> fileOptions =
-          new AnalysisOptionsProvider().getOptionsFromFile(optionsFile);
-      applyToAnalysisOptions(options, fileOptions);
+      List<OptionsProcessor> optionsProcessors =
+          AnalysisEngine.instance.optionsPlugin.optionsProcessors;
+      try {
+        Map<String, YamlNode> optionMap =
+            new AnalysisOptionsProvider().getOptionsFromFile(optionsFile);
+        optionsProcessors.forEach(
+            (OptionsProcessor p) => p.optionsProcessed(context, optionMap));
+        applyToAnalysisOptions(options, optionMap);
+      } on Exception catch (exception) {
+        optionsProcessors.forEach((OptionsProcessor p) => p.onError(exception));
+      }
     }
     return options;
   }
@@ -379,23 +391,49 @@
    * directory.
    */
   Packages getPackagesFromFolder(Folder folder) {
+    Context pathContext = resourceProvider.pathContext;
     Map<String, Uri> map = new HashMap<String, Uri>();
     for (Resource child in folder.getChildren()) {
       if (child is Folder) {
-        String packageName = resourceProvider.pathContext.basename(child.path);
-        // Create a file URI (rather than a directory URI) and add a '.' so that
-        // the URI is suitable for resolving relative URI's against it.
-        //
-        // TODO(brianwilkerson) Decide whether we need to pass in a 'windows:'
-        // argument for testing purposes.
-        map[packageName] = resourceProvider.pathContext.toUri(
-            resourceProvider.pathContext.join(folder.path, packageName, '.'));
+        // Inline resolveSymbolicLinks for performance reasons.
+        String packageName = pathContext.basename(child.path);
+        String folderPath = resolveSymbolicLink(child);
+        String uriPath = pathContext.join(folderPath, '.');
+        map[packageName] = pathContext.toUri(uriPath);
       }
     }
     return new MapPackages(map);
   }
 
   /**
+   * Resolve any symbolic links encoded in the path to the given [folder].
+   */
+  String resolveSymbolicLink(Folder folder) {
+    try {
+      return folder.resolveSymbolicLinksSync().path;
+    } on FileSystemException {
+      return folder.path;
+    }
+  }
+
+  /**
+   * Resolve any symbolic links encoded in the URI's in the given [map] by
+   * replacing the values in the map.
+   */
+  void resolveSymbolicLinks(Map<String, Uri> map) {
+    Context pathContext = resourceProvider.pathContext;
+    for (String packageName in map.keys) {
+      Folder folder =
+          resourceProvider.getFolder(pathContext.fromUri(map[packageName]));
+      String folderPath = resolveSymbolicLink(folder);
+      // Add a '.' so that the URI is suitable for resolving relative URI's
+      // against it.
+      String uriPath = pathContext.join(folderPath, '.');
+      map[packageName] = pathContext.toUri(uriPath);
+    }
+  }
+
+  /**
    * Find the location of the package resolution file/directory for the
    * directory at the given absolute [path].
    *
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 55cd2c8..6b15c8e 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -284,6 +284,8 @@
         (this._options.lint && !options.lint) ||
         this._options.preserveComments != options.preserveComments ||
         this._options.strongMode != options.strongMode ||
+        this._options.enableAssertInitializer !=
+            options.enableAssertInitializer ||
         this._options.enableAssertMessage != options.enableAssertMessage ||
         ((options is AnalysisOptionsImpl)
             ? this._options.strongModeHints != options.strongModeHints
@@ -312,6 +314,7 @@
     this._options.generateSdkErrors = options.generateSdkErrors;
     this._options.dart2jsHint = options.dart2jsHint;
     this._options.enableGenericMethods = options.enableGenericMethods;
+    this._options.enableAssertInitializer = options.enableAssertInitializer;
     this._options.enableAssertMessage = options.enableAssertMessage;
     this._options.enableStrictCallChecks = options.enableStrictCallChecks;
     this._options.enableAsync = options.enableAsync;
@@ -1306,7 +1309,6 @@
       entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
       entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
       entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
-      entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
       // USED_IMPORTED_ELEMENTS
       // USED_LOCAL_ELEMENTS
       setValue(STRONG_MODE_ERRORS, AnalysisError.NO_ERRORS);
@@ -1386,7 +1388,6 @@
     entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
   }
 
@@ -1571,7 +1572,6 @@
         new LibrarySpecificUnit(librarySource, unitSource);
     for (ResultDescriptor result in [
       RESOLVED_UNIT,
-      RESOLVED_UNIT13,
       RESOLVED_UNIT12,
       RESOLVED_UNIT11,
       RESOLVED_UNIT10,
diff --git a/pkg/analyzer/lib/src/dart/sdk/sdk.dart b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
index ec64039..07e30c8 100644
--- a/pkg/analyzer/lib/src/dart/sdk/sdk.dart
+++ b/pkg/analyzer/lib/src/dart/sdk/sdk.dart
@@ -10,6 +10,7 @@
 
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
@@ -614,9 +615,13 @@
         lastStackTrace = stackTrace;
       }
     }
+    StringBuffer buffer = new StringBuffer();
+    buffer.writeln('Could not initialize the library map from $searchedPaths');
+    if (resourceProvider is MemoryResourceProvider) {
+      (resourceProvider as MemoryResourceProvider).writeOn(buffer);
+    }
     AnalysisEngine.instance.logger.logError(
-        "Could not initialize the library map from $searchedPaths",
-        new CaughtException(lastException, lastStackTrace));
+        buffer.toString(), new CaughtException(lastException, lastStackTrace));
     return new LibraryMap();
   }
 
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index b229169..aa9a74b 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1049,6 +1049,12 @@
   bool get dart2jsHint;
 
   /**
+   * Return `true` if the parser is to parse asserts in the initializer list of
+   * a constructor.
+   */
+  bool get enableAssertInitializer;
+
+  /**
    * Return `true` to enable custom assert messages (DEP 37).
    */
   bool get enableAssertMessage;
@@ -1202,100 +1208,61 @@
   AnalyzeFunctionBodiesPredicate _analyzeFunctionBodiesPredicate =
       _analyzeAllFunctionBodies;
 
-  /**
-   * The maximum number of sources for which AST structures should be kept in
-   * the cache.
-   */
+  @override
   int cacheSize = DEFAULT_CACHE_SIZE;
 
-  /**
-   * A flag indicating whether analysis is to generate dart2js related hint
-   * results.
-   */
+  @override
   bool dart2jsHint = false;
 
-  /**
-   * A flag indicating whether custom assert messages are to be supported (DEP
-   * 37).
-   */
+  @override
+  bool enableAssertInitializer = false;
+
+  @override
   bool enableAssertMessage = false;
 
-  /**
-   * A flag indicating whether analysis is to enable async support.
-   */
+  @override
   bool enableAsync = true;
 
-  /**
-   * A flag indicating whether generic methods are to be supported (DEP 22).
-   */
+  @override
   bool enableGenericMethods = false;
 
   @override
   bool enableLazyAssignmentOperators = false;
 
-  /**
-   * A flag indicating whether analysis is to strictly follow the specification
-   * when generating warnings on "call" methods (fixes dartbug.com/21938).
-   */
+  @override
   bool enableStrictCallChecks = false;
 
-  /**
-   * A flag indicating whether mixins are allowed to inherit from types other
-   * than Object, and are allowed to reference `super`.
-   */
+  @override
   bool enableSuperMixins = false;
 
   @override
   bool enableTiming = false;
 
-  /**
-   * A flag indicating whether errors, warnings and hints should be generated
-   * for sources that are implicitly being analyzed.
-   */
+  @override
   bool generateImplicitErrors = true;
 
-  /**
-   * A flag indicating whether errors, warnings and hints should be generated
-   * for sources in the SDK.
-   */
+  @override
   bool generateSdkErrors = false;
 
-  /**
-   * A flag indicating whether analysis is to generate hint results (e.g. type
-   * inference based information and pub best practices).
-   */
+  @override
   bool hint = true;
 
-  /**
-   * A flag indicating whether incremental analysis should be used.
-   */
+  @override
   bool incremental = false;
 
-  /**
-   * A flag indicating whether incremental analysis should be used for API
-   * changes.
-   */
+  @override
   bool incrementalApi = false;
 
-  /**
-   * A flag indicating whether validation should be performed after incremental
-   * analysis.
-   */
+  @override
   bool incrementalValidation = false;
 
-  /**
-   * A flag indicating whether analysis is to generate lint warnings.
-   */
+  @override
   bool lint = false;
 
-  /**
-   * A flag indicating whether analysis is to parse comments.
-   */
+  @override
   bool preserveComments = true;
 
-  /**
-   * A flag indicating whether strong-mode analysis should be used.
-   */
+  @override
   bool strongMode = false;
 
   /**
@@ -1352,6 +1319,7 @@
     analyzeFunctionBodiesPredicate = options.analyzeFunctionBodiesPredicate;
     cacheSize = options.cacheSize;
     dart2jsHint = options.dart2jsHint;
+    enableAssertInitializer = options.enableAssertInitializer;
     enableAssertMessage = options.enableAssertMessage;
     enableAsync = options.enableAsync;
     enableStrictCallChecks = options.enableStrictCallChecks;
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index c1bc461..9c6cbf8 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -98,11 +98,10 @@
         isByTask(ComputeConstantValueTask.DESCRIPTOR) ||
         isByTask(ComputeInferableStaticVariableDependenciesTask.DESCRIPTOR) ||
         isByTask(ComputeLibraryCycleTask.DESCRIPTOR) ||
-        isByTask(ComputePropagableVariableDependenciesTask.DESCRIPTOR) ||
         isByTask(DartErrorsTask.DESCRIPTOR) ||
         isByTask(ReadyLibraryElement2Task.DESCRIPTOR) ||
         isByTask(ReadyLibraryElement5Task.DESCRIPTOR) ||
-        isByTask(ReadyLibraryElement6Task.DESCRIPTOR) ||
+        isByTask(ReadyLibraryElement7Task.DESCRIPTOR) ||
         isByTask(ReadyResolvedUnitTask.DESCRIPTOR) ||
         isByTask(EvaluateUnitConstantsTask.DESCRIPTOR) ||
         isByTask(GenerateHintsTask.DESCRIPTOR) ||
@@ -113,13 +112,11 @@
         isByTask(LibraryUnitErrorsTask.DESCRIPTOR) ||
         isByTask(ParseDartTask.DESCRIPTOR) ||
         isByTask(PartiallyResolveUnitReferencesTask.DESCRIPTOR) ||
-        isByTask(PropagateVariableTypesInLibraryClosureTask.DESCRIPTOR) ||
-        isByTask(PropagateVariableTypesInLibraryTask.DESCRIPTOR) ||
-        isByTask(PropagateVariableTypesInUnitTask.DESCRIPTOR) ||
-        isByTask(PropagateVariableTypeTask.DESCRIPTOR) ||
         isByTask(ScanDartTask.DESCRIPTOR) ||
         isByTask(ResolveConstantExpressionTask.DESCRIPTOR) ||
         isByTask(ResolveDirectiveElementsTask.DESCRIPTOR) ||
+        isByTask(ResolvedUnit7InLibraryClosureTask.DESCRIPTOR) ||
+        isByTask(ResolvedUnit7InLibraryTask.DESCRIPTOR) ||
         isByTask(ResolveInstanceFieldsInUnitTask.DESCRIPTOR) ||
         isByTask(ResolveLibraryReferencesTask.DESCRIPTOR) ||
         isByTask(ResolveLibraryTask.DESCRIPTOR) ||
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index fcf9b01..d3f7475 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2135,6 +2135,12 @@
   int _errorListenerLock = 0;
 
   /**
+   * A flag indicating whether the parser is to parse asserts in the initializer
+   * list of a constructor.
+   */
+  bool _enableAssertInitializer = false;
+
+  /**
    * A flag indicating whether the parser is to parse the async support.
    */
   bool _parseAsync = true;
@@ -2202,6 +2208,20 @@
   }
 
   /**
+   * Return `true` if the parser is to parse asserts in the initializer list of
+   * a constructor.
+   */
+  bool get enableAssertInitializer => _enableAssertInitializer;
+
+  /**
+   * Set whether the parser is to parse asserts in the initializer list of a
+   * constructor to match the given [enable] flag.
+   */
+  void set enableAssertInitializer(bool enable) {
+    _enableAssertInitializer = enable;
+  }
+
+  /**
    * Return `true` if the current token is the first token of a return type that
    * is followed by an identifier, possibly followed by a list of type
    * parameters, followed by a left-parenthesis. This is used by
@@ -2862,6 +2882,7 @@
                 "parseDirective invoked in an invalid state (currentToken = $_currentToken)");
           }
         }
+
         Directive directive = parseDirective();
         if (declarations.length > 0 && !directiveFoundAfterDeclaration) {
           _reportErrorForToken(ParserErrorCode.DIRECTIVE_AFTER_DECLARATION,
@@ -4346,6 +4367,31 @@
   }
 
   /**
+   * Parse an assert within a constructor's initializer list. Return the assert.
+   *
+   * This method assumes that the current token matches `Keyword.ASSERT`.
+   *
+   *     assertInitializer ::=
+   *         'assert' '(' expression [',' expression] ')'
+   */
+  void _parseAssertInitializer() {
+    // TODO(brianwilkerson) Capture the syntax in the AST using a new class,
+    // such as AssertInitializer
+    Token keyword = getAndAdvance();
+    Token leftParen = _expect(TokenType.OPEN_PAREN);
+    Expression expression = parseExpression2();
+    Token comma;
+    Expression message;
+    if (_matches(TokenType.COMMA)) {
+      comma = getAndAdvance();
+      message = parseExpression2();
+    }
+    Token rightParen = _expect(TokenType.CLOSE_PAREN);
+//    return new AssertInitializer(
+//        keyword, leftParen, expression, comma, message, rightParen);
+  }
+
+  /**
    * Parse an assert statement. Return the assert statement.
    *
    * This method assumes that the current token matches `Keyword.ASSERT`.
@@ -5502,6 +5548,9 @@
         } else if (_matches(TokenType.OPEN_CURLY_BRACKET) ||
             _matches(TokenType.FUNCTION)) {
           _reportErrorForCurrentToken(ParserErrorCode.MISSING_INITIALIZER);
+        } else if (_enableAssertInitializer &&
+            _matchesKeyword(Keyword.ASSERT)) {
+          _parseAssertInitializer();
         } else {
           initializers.add(_parseConstructorFieldInitializer(false));
         }
@@ -8282,6 +8331,7 @@
             Keyword keyword = _currentToken.keyword;
             return keyword == Keyword.CASE || keyword == Keyword.DEFAULT;
           }
+
           while (!atEndOrNextMember()) {
             _advance();
           }
@@ -8625,6 +8675,7 @@
             type == TokenType.INT ||
             type == TokenType.DOUBLE;
       }
+
       while ((_tokenMatchesIdentifier(token) && !isKeywordAfterUri(token)) ||
           isValidInUri(token)) {
         token = token.next;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 9d04dff..e11afca 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -4963,7 +4963,11 @@
    * inference.
    */
   static void setType(AstNode node, DartType type) {
-    node?.setProperty(_typeProperty, type);
+    if (type == null || type.isDynamic) {
+      clearType(node);
+    } else {
+      node?.setProperty(_typeProperty, type);
+    }
   }
 
   /**
@@ -5202,12 +5206,6 @@
   final List<VariableElement> staticVariables = <VariableElement>[];
 
   /**
-   * The static and instance variables and fields that have an initializer.
-   * These are the variables whose types might be propagated.
-   */
-  final List<VariableElement> propagableVariables = <VariableElement>[];
-
-  /**
    * Initialize a newly created visitor to resolve the nodes in an AST node.
    *
    * The [definingLibrary] is the element for the library containing the node
@@ -5248,7 +5246,6 @@
 
   @override
   Object visitFieldDeclaration(FieldDeclaration node) {
-    _addPropagableVariables(node.fields.variables);
     if (node.isStatic) {
       _addStaticVariables(node.fields.variables);
     }
@@ -5262,28 +5259,11 @@
 
   @override
   Object visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-    _addPropagableVariables(node.variables.variables);
     _addStaticVariables(node.variables.variables);
     return super.visitTopLevelVariableDeclaration(node);
   }
 
   /**
-   * Add all of the [variables] with initializers to [propagableVariables].
-   */
-  void _addPropagableVariables(List<VariableDeclaration> variables) {
-    int length = variables.length;
-    for (int i = 0; i < length; i++) {
-      VariableDeclaration variable = variables[i];
-      if (variable.name.name.isNotEmpty && variable.initializer != null) {
-        VariableElement element = variable.element;
-        if (element.isConst || element.isFinal) {
-          propagableVariables.add(element);
-        }
-      }
-    }
-  }
-
-  /**
    * Add all of the [variables] with initializers to the list of variables whose
    * type can be inferred. Technically, we only infer the types of variables
    * that do not have a static type, but all variables with initializers
@@ -6625,8 +6605,10 @@
               //
               // We can't represent this in Dart so we populate it here during
               // inference.
-              returnType = FutureUnionType.from(
-                  futureThenType.returnType, typeProvider, typeSystem);
+              var typeParamS =
+                  futureThenType.returnType.flattenFutures(typeSystem);
+              returnType =
+                    FutureUnionType.from(typeParamS, typeProvider, typeSystem);
             } else {
               returnType = _computeReturnOrYieldType(functionType.returnType);
             }
@@ -7185,7 +7167,8 @@
         return (typeArgs?.length == 1) ? typeArgs[0] : null;
       }
       // async functions expect `Future<T> | T`
-      return new FutureUnionType(declaredType, typeProvider, typeSystem);
+      var futureTypeParam = declaredType.flattenFutures(typeSystem);
+      return FutureUnionType.from(futureTypeParam, typeProvider, typeSystem);
     }
     return declaredType;
   }
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 1abf232..e7d747e 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -1426,17 +1426,9 @@
       inferredTypes[i] =
           variance.passedIn || bound.lower.isBottom ? bound.upper : bound.lower;
 
-      // See if the constraints on the type variable are satisfied.
-      //
-      // If not, bail out of the analysis, unless a partial solution was
-      // requested. If we are willing to accept a partial solution, fall back to
-      // the known upper bound (if any) or `dynamic` for this unsolvable type
-      // variable.
-      if (inferredTypes[i].isBottom ||
-          !isSubtypeOf(inferredTypes[i],
-              bound.upper.substitute2(inferredTypes, fnTypeParams)) ||
-          !isSubtypeOf(bound.lower.substitute2(inferredTypes, fnTypeParams),
-              inferredTypes[i])) {
+      // See if the bounds can be satisfied.
+      if (bound.upper.isBottom ||
+          !_typeSystem.isSubtypeOf(bound.lower, bound.upper)) {
         // Inference failed. Bail.
         return null;
       }
@@ -1607,21 +1599,14 @@
   final List<DartType> _types;
 
   /**
-   * Creates a union of `Future< flatten(T) > | flatten(T)`.
+   * Creates a union of `Future<T> | T`.
    */
-  factory FutureUnionType(
-      DartType type, TypeProvider provider, TypeSystem system) {
-    type = type.flattenFutures(system);
-
-    // The order of these types is important: T could be a type variable, so
-    // we want to try and match `Future<T>` before we try and match `T`.
-    return new FutureUnionType._([
-      provider.futureType.instantiate([type]),
-      type
-    ]);
-  }
-
-  FutureUnionType._(this._types) : super(null, null);
+  FutureUnionType._(DartType type, TypeProvider provider, TypeSystem system)
+      : _types = [
+          provider.futureType.instantiate([type]),
+          type
+        ],
+        super(null, null);
 
   DartType get futureOfType => _types[0];
 
@@ -1676,15 +1661,39 @@
       throw new UnsupportedError('Future unions are not used in typedefs');
 
   /**
-   * Creates a union of `flatten(T) | Future<flatten(T)>`, unless `T` is
-   * already a future-union, in which case it simply returns `T`
+   * Creates a union of `T | Future<T>`, unless `T` is already a future or a
+   * future-union, in which case it simply returns `T`.
+   *
+   * Conceptually this is used as the inverse of the `flatten(T)` operation,
+   * defined as:
+   *
+   * - `flatten(Future<T>) -> T`
+   * - `flatten(T) -> T`
+   *
+   * Thus the inverse will give us `T | Future<T>`.
+   *
+   * If [type] is top (dynamic or Object) then the resulting union type is
+   * equivalent to top, so we simply return it.
+   *
+   * For a similar reason `Future<T> | Future<Future<T>>` is equivalent to just
+   * `Future<T>`, so we return it. Note that it is not possible to get a
+   * `Future<T>` as a result of `flatten`, so a this case likely indicates a
+   * type error in the code, but it will be reported elsewhere.
    */
   static DartType from(
       DartType type, TypeProvider provider, TypeSystem system) {
+    if (_isTop(type)) {
+      return type;
+    }
+    if (!identical(type, type.flattenFutures(system))) {
+      // As noted above, this most likely represents erroneous input.
+      return type;
+    }
+
     if (type is FutureUnionType) {
       return type;
     }
-    return new FutureUnionType(type, provider, system);
+    return new FutureUnionType._(type, provider, system);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/plugin/engine_plugin.dart b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
index 8e47707..ecf2e36 100644
--- a/pkg/analyzer/lib/src/plugin/engine_plugin.dart
+++ b/pkg/analyzer/lib/src/plugin/engine_plugin.dart
@@ -205,8 +205,6 @@
         taskId, ComputeInferableStaticVariableDependenciesTask.DESCRIPTOR);
     registerExtension(taskId, ComputeLibraryCycleTask.DESCRIPTOR);
     registerExtension(taskId, ComputeRequiredConstantsTask.DESCRIPTOR);
-    registerExtension(
-        taskId, ComputePropagableVariableDependenciesTask.DESCRIPTOR);
     registerExtension(taskId, ContainingLibrariesTask.DESCRIPTOR);
     registerExtension(taskId, DartErrorsTask.DESCRIPTOR);
     registerExtension(taskId, EvaluateUnitConstantsTask.DESCRIPTOR);
@@ -221,17 +219,14 @@
     registerExtension(taskId, LibraryUnitErrorsTask.DESCRIPTOR);
     registerExtension(taskId, ParseDartTask.DESCRIPTOR);
     registerExtension(taskId, PartiallyResolveUnitReferencesTask.DESCRIPTOR);
-    registerExtension(
-        taskId, PropagateVariableTypesInLibraryClosureTask.DESCRIPTOR);
-    registerExtension(taskId, PropagateVariableTypesInLibraryTask.DESCRIPTOR);
-    registerExtension(taskId, PropagateVariableTypesInUnitTask.DESCRIPTOR);
-    registerExtension(taskId, PropagateVariableTypeTask.DESCRIPTOR);
     registerExtension(taskId, ReadyLibraryElement2Task.DESCRIPTOR);
     registerExtension(taskId, ReadyLibraryElement5Task.DESCRIPTOR);
-    registerExtension(taskId, ReadyLibraryElement6Task.DESCRIPTOR);
+    registerExtension(taskId, ReadyLibraryElement7Task.DESCRIPTOR);
     registerExtension(taskId, ReadyResolvedUnitTask.DESCRIPTOR);
     registerExtension(taskId, ResolveConstantExpressionTask.DESCRIPTOR);
     registerExtension(taskId, ResolveDirectiveElementsTask.DESCRIPTOR);
+    registerExtension(taskId, ResolvedUnit7InLibraryClosureTask.DESCRIPTOR);
+    registerExtension(taskId, ResolvedUnit7InLibraryTask.DESCRIPTOR);
     registerExtension(taskId, ResolveInstanceFieldsInUnitTask.DESCRIPTOR);
     registerExtension(taskId, ResolveLibraryReferencesTask.DESCRIPTOR);
     registerExtension(taskId, ResolveLibraryTask.DESCRIPTOR);
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index dc9685f..caa98d2 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -253,8 +253,7 @@
           result == CREATED_RESOLVED_UNIT8 ||
           result == CREATED_RESOLVED_UNIT9 ||
           result == CREATED_RESOLVED_UNIT10 ||
-          result == CREATED_RESOLVED_UNIT11 ||
-          result == CREATED_RESOLVED_UNIT12) {
+          result == CREATED_RESOLVED_UNIT11) {
         entry.setValue(result, true, TargetedResult.EMPTY_LIST);
         return true;
       }
@@ -269,7 +268,7 @@
         }
       }
     } else if (target is VariableElement) {
-      if (result == PROPAGATED_VARIABLE || result == INFERRED_STATIC_VARIABLE) {
+      if (result == INFERRED_STATIC_VARIABLE) {
         entry.setValue(result, target, TargetedResult.EMPTY_LIST);
         return true;
       }
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 04c4ec4..cb5791c 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -246,15 +246,6 @@
     new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT12', false);
 
 /**
- * The flag specifying that [RESOLVED_UNIT13] has been been computed for this
- * compilation unit (without requiring that the AST for it still be in cache).
- *
- * The result is only available for [LibrarySpecificUnit]s.
- */
-final ResultDescriptor<bool> CREATED_RESOLVED_UNIT13 =
-    new ResultDescriptor<bool>('CREATED_RESOLVED_UNIT13', false);
-
-/**
  * The flag specifying that [RESOLVED_UNIT2] has been been computed for this
  * compilation unit (without requiring that the AST for it still be in cache).
  *
@@ -526,7 +517,7 @@
 /**
  * The partial [LibraryElement] associated with a library.
  *
- * [LIBRARY_ELEMENT6] plus propagated types for propagable variables.
+ * [LIBRARY_ELEMENT6] plus [RESOLVED_UNIT7] for all library units.
  *
  * The result is only available for [Source]s representing a library.
  */
@@ -635,36 +626,6 @@
         'PENDING_ERRORS', const <PendingError>[]);
 
 /**
- * A list of the [VariableElement]s whose type should be known to propagate
- * the type of another variable (the target).
- *
- * The result is only available for [VariableElement]s.
- */
-final ListResultDescriptor<VariableElement> PROPAGABLE_VARIABLE_DEPENDENCIES =
-    new ListResultDescriptor<VariableElement>(
-        'PROPAGABLE_VARIABLE_DEPENDENCIES', null);
-
-/**
- * A list of the [VariableElement]s defined in a unit whose type might be
- * propagated. This includes variables defined at the library level as well as
- * static and instance members inside classes.
- *
- * The result is only available for [LibrarySpecificUnit]s.
- */
-final ListResultDescriptor<VariableElement> PROPAGABLE_VARIABLES_IN_UNIT =
-    new ListResultDescriptor<VariableElement>(
-        'PROPAGABLE_VARIABLES_IN_UNIT', null);
-
-/**
- * An propagable variable ([VariableElement]) whose type has been propagated.
- *
- * The result is only available for [VariableElement]s.
- */
-final ResultDescriptor<VariableElement> PROPAGATED_VARIABLE =
-    new ResultDescriptor<VariableElement>('PROPAGATED_VARIABLE', null,
-        cachingPolicy: ELEMENT_CACHING_POLICY);
-
-/**
  * The flag specifying that [LIBRARY_ELEMENT2] is ready for a library and its
  * import/export closure.
  *
@@ -776,11 +737,9 @@
         cachingPolicy: AST_REUSABLE_CACHING_POLICY);
 
 /**
- * The partially resolved [CompilationUnit] associated with a compilation unit.
- *
- * In addition to what is true of a [RESOLVED_UNIT9], tasks that use this value
- * as an input can assume that the initializers of instance variables have been
- * re-resolved.
+ * The resolved [CompilationUnit] associated with a compilation unit in which
+ * the types of class members have been inferred in addition to everything that
+ * is true of a [RESOLVED_UNIT9].
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -789,9 +748,8 @@
         cachingPolicy: AST_CACHING_POLICY);
 
 /**
- * The resolved [CompilationUnit] associated with a compilation unit in which
- * the types of class members have been inferred in addition to everything that
- * is true of a [RESOLVED_UNIT10].
+ * The resolved [CompilationUnit] associated with a compilation unit, with
+ * constants not yet resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -801,7 +759,7 @@
 
 /**
  * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants not yet resolved.
+ * constants resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -810,16 +768,6 @@
         cachingPolicy: AST_CACHING_POLICY);
 
 /**
- * The resolved [CompilationUnit] associated with a compilation unit, with
- * constants resolved.
- *
- * The result is only available for [LibrarySpecificUnit]s.
- */
-final ResultDescriptor<CompilationUnit> RESOLVED_UNIT13 =
-    new ResultDescriptor<CompilationUnit>('RESOLVED_UNIT13', null,
-        cachingPolicy: AST_CACHING_POLICY);
-
-/**
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT1], tasks that use this value
@@ -902,8 +850,7 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT7], tasks that use this value
- * as an input can assume that the types of final variables have been
- * propagated.
+ * as an input can assume that the types of static variables have been inferred.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -915,7 +862,8 @@
  * The partially resolved [CompilationUnit] associated with a compilation unit.
  *
  * In addition to what is true of a [RESOLVED_UNIT8], tasks that use this value
- * as an input can assume that the types of static variables have been inferred.
+ * as an input can assume that the initializers of instance variables have been
+ * re-resolved.
  *
  * The result is only available for [LibrarySpecificUnit]s.
  */
@@ -940,7 +888,6 @@
   RESOLVED_UNIT10,
   RESOLVED_UNIT11,
   RESOLVED_UNIT12,
-  RESOLVED_UNIT13,
   RESOLVED_UNIT
 ];
 
@@ -2303,85 +2250,6 @@
 }
 
 /**
- * A task that computes the [PROPAGABLE_VARIABLE_DEPENDENCIES] for a variable.
- */
-class ComputePropagableVariableDependenciesTask
-    extends InferStaticVariableTask {
-  /**
-   * The name of the [RESOLVED_UNIT7] input.
-   */
-  static const String UNIT_INPUT = 'UNIT_INPUT';
-
-  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'ComputePropagableVariableDependenciesTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[PROPAGABLE_VARIABLE_DEPENDENCIES]);
-
-  ComputePropagableVariableDependenciesTask(
-      InternalAnalysisContext context, VariableElement variable)
-      : super(context, variable);
-
-  @override
-  TaskDescriptor get descriptor => DESCRIPTOR;
-
-  @override
-  void internalPerform() {
-    //
-    // Prepare inputs.
-    //
-    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
-    //
-    // Compute dependencies.
-    //
-    VariableDeclaration declaration = getDeclaration(unit);
-    VariableGatherer gatherer = new VariableGatherer(_isPropagable);
-    declaration.initializer.accept(gatherer);
-    //
-    // Record outputs.
-    //
-    outputs[PROPAGABLE_VARIABLE_DEPENDENCIES] = gatherer.results.toList();
-  }
-
-  /**
-   * Return `true` if the given [variable] is a variable whose type can be
-   * propagated.
-   */
-  bool _isPropagable(VariableElement variable) =>
-      variable is PropertyInducingElement &&
-      (variable.isConst || variable.isFinal) &&
-      variable.hasImplicitType &&
-      variable.initializer != null;
-
-  /**
-   * Return a map from the names of the inputs of this kind of task to the task
-   * input descriptors describing those inputs for a task with the
-   * given [target].
-   */
-  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
-    if (target is VariableElement) {
-      CompilationUnitElementImpl unit = target
-          .getAncestor((Element element) => element is CompilationUnitElement);
-      return <String, TaskInput>{
-        UNIT_INPUT: RESOLVED_UNIT7
-            .of(new LibrarySpecificUnit(unit.librarySource, unit.source))
-      };
-    }
-    throw new AnalysisException(
-        'Cannot build inputs for a ${target.runtimeType}');
-  }
-
-  /**
-   * Create a [ComputePropagableVariableDependenciesTask] based on the
-   * given [target] in the given [context].
-   */
-  static ComputePropagableVariableDependenciesTask createTask(
-      AnalysisContext context, AnalysisTarget target) {
-    return new ComputePropagableVariableDependenciesTask(context, target);
-  }
-}
-
-/**
  * A task that builds [REQUIRED_CONSTANTS] for a unit.
  */
 class ComputeRequiredConstantsTask extends SourceBasedAnalysisTask {
@@ -3006,11 +2874,11 @@
 }
 
 /**
- * A task that builds [RESOLVED_UNIT13] for a unit.
+ * A task that builds [RESOLVED_UNIT12] for a unit.
  */
 class EvaluateUnitConstantsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT12] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -3026,7 +2894,7 @@
       'EvaluateUnitConstantsTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT13, RESOLVED_UNIT13]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT12, RESOLVED_UNIT12]);
 
   EvaluateUnitConstantsTask(AnalysisContext context, LibrarySpecificUnit target)
       : super(context, target);
@@ -3039,8 +2907,8 @@
     // No actual work needs to be performed; the task manager will ensure that
     // all constants are evaluated before this method is called.
     CompilationUnit unit = getRequiredInput(UNIT_INPUT);
-    outputs[RESOLVED_UNIT13] = unit;
-    outputs[CREATED_RESOLVED_UNIT13] = true;
+    outputs[RESOLVED_UNIT12] = unit;
+    outputs[CREATED_RESOLVED_UNIT12] = true;
   }
 
   /**
@@ -3052,7 +2920,7 @@
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
       'libraryElement': LIBRARY_ELEMENT9.of(unit.library),
-      UNIT_INPUT: RESOLVED_UNIT12.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT11.of(unit),
       CONSTANT_VALUES:
           COMPILATION_UNIT_CONSTANTS.of(unit).toListOf(CONSTANT_VALUE),
       'constantExpressionsDependencies':
@@ -3075,7 +2943,7 @@
  */
 class GatherUsedImportedElementsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT12] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -3119,7 +2987,7 @@
    */
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
-    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT12.of(unit)};
+    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT11.of(unit)};
   }
 
   /**
@@ -3137,7 +3005,7 @@
  */
 class GatherUsedLocalElementsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT12] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -3181,7 +3049,7 @@
    */
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
-    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT12.of(unit)};
+    return <String, TaskInput>{UNIT_INPUT: RESOLVED_UNIT11.of(unit)};
   }
 
   /**
@@ -3199,7 +3067,7 @@
  */
 class GenerateHintsTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT12] input.
+   * The name of the [RESOLVED_UNIT11] input.
    */
   static const String RESOLVED_UNIT_INPUT = 'RESOLVED_UNIT';
 
@@ -3497,7 +3365,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT9] for the
+   * The name of the input whose value is the [RESOLVED_UNIT8] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -3509,7 +3377,7 @@
       'InferInstanceMembersInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT11, RESOLVED_UNIT11]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT10, RESOLVED_UNIT10]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -3541,8 +3409,8 @@
     //
     // Record outputs.
     //
-    outputs[RESOLVED_UNIT11] = unit;
-    outputs[CREATED_RESOLVED_UNIT11] = true;
+    outputs[RESOLVED_UNIT10] = unit;
+    outputs[CREATED_RESOLVED_UNIT10] = true;
   }
 
   /**
@@ -3553,7 +3421,7 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT10.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT9.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
@@ -3561,14 +3429,14 @@
       // Require that field re-resolution be complete for all units in the
       // current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
-          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT9.of(
               new LibrarySpecificUnit(
                   (unit as CompilationUnitElementImpl).librarySource,
                   unit.source))),
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
-          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
               new LibrarySpecificUnit(
                   (unit as CompilationUnitElementImpl).librarySource,
                   unit.source)))
@@ -3672,8 +3540,8 @@
       'InferStaticVariableTypesInUnitTask',
       createTask,
       buildInputs, <ResultDescriptor>[
-    CREATED_RESOLVED_UNIT9,
-    RESOLVED_UNIT9,
+    CREATED_RESOLVED_UNIT8,
+    RESOLVED_UNIT8,
     STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
   ]);
 
@@ -3700,8 +3568,8 @@
     // because the work has implicitly been done by virtue of the task model
     // preparing all of the inputs.
     //
-    outputs[RESOLVED_UNIT9] = unit;
-    outputs[CREATED_RESOLVED_UNIT9] = true;
+    outputs[RESOLVED_UNIT8] = unit;
+    outputs[CREATED_RESOLVED_UNIT8] = true;
     outputs[STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT] =
         AnalysisError.mergeLists(errorLists);
   }
@@ -3720,7 +3588,7 @@
       ERRORS_LIST_INPUT: INFERABLE_STATIC_VARIABLES_IN_UNIT
           .of(unit)
           .toListOf(STATIC_VARIABLE_RESOLUTION_ERRORS),
-      UNIT_INPUT: RESOLVED_UNIT8.of(unit)
+      UNIT_INPUT: RESOLVED_UNIT7.of(unit)
     };
   }
 
@@ -3848,14 +3716,14 @@
           .of(variable)
           .toListOf(INFERRED_STATIC_VARIABLE),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT8.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT7.of(unit),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
 
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
-          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
               new LibrarySpecificUnit(
                   (unit as CompilationUnitElementImpl).librarySource,
                   unit.source)))
@@ -4126,6 +3994,7 @@
     RecordingErrorListener errorListener = new RecordingErrorListener();
     Parser parser = new Parser(source, errorListener);
     AnalysisOptions options = context.analysisOptions;
+    parser.enableAssertInitializer = options.enableAssertInitializer;
     parser.parseAsync = options.enableAsync;
     parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
     parser.parseGenericMethods = options.enableGenericMethods;
@@ -4314,7 +4183,6 @@
       createTask,
       buildInputs, <ResultDescriptor>[
     INFERABLE_STATIC_VARIABLES_IN_UNIT,
-    PROPAGABLE_VARIABLES_IN_UNIT,
     CREATED_RESOLVED_UNIT7,
     RESOLVED_UNIT7
   ]);
@@ -4349,7 +4217,6 @@
     } else {
       outputs[INFERABLE_STATIC_VARIABLES_IN_UNIT] = VariableElement.EMPTY_LIST;
     }
-    outputs[PROPAGABLE_VARIABLES_IN_UNIT] = visitor.propagableVariables;
     outputs[RESOLVED_UNIT7] = unit;
     outputs[CREATED_RESOLVED_UNIT7] = true;
   }
@@ -4372,7 +4239,7 @@
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
-          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
               new LibrarySpecificUnit(
                   (unit as CompilationUnitElementImpl).librarySource,
                   unit.source)))
@@ -4390,295 +4257,6 @@
 }
 
 /**
- * An artificial task that does nothing except to force propagated types for
- * all propagable variables in the import/export closure a library.
- */
-class PropagateVariableTypesInLibraryClosureTask
-    extends SourceBasedAnalysisTask {
-  /**
-   * The name of the [LIBRARY_ELEMENT7] input.
-   */
-  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
-
-  /**
-   * The task descriptor describing this kind of task.
-   */
-  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'PropagateVariableTypesInLibraryClosureTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[LIBRARY_ELEMENT8]);
-
-  PropagateVariableTypesInLibraryClosureTask(
-      InternalAnalysisContext context, AnalysisTarget target)
-      : super(context, target);
-
-  @override
-  TaskDescriptor get descriptor => DESCRIPTOR;
-
-  @override
-  void internalPerform() {
-    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
-    outputs[LIBRARY_ELEMENT8] = library;
-  }
-
-  /**
-   * Return a map from the names of the inputs of this kind of task to the task
-   * input descriptors describing those inputs for a task with the
-   * given [target].
-   */
-  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
-    Source source = target;
-    return <String, TaskInput>{
-      'readyForClosure': READY_LIBRARY_ELEMENT7.of(source),
-      LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
-    };
-  }
-
-  /**
-   * Create a [PropagateVariableTypesInLibraryClosureTask] based on the given
-   * [target] in the given [context].
-   */
-  static PropagateVariableTypesInLibraryClosureTask createTask(
-      AnalysisContext context, AnalysisTarget target) {
-    return new PropagateVariableTypesInLibraryClosureTask(context, target);
-  }
-}
-
-/**
- * An artificial task that does nothing except to force propagated types for
- * all propagable variables in the defining and part units of a library.
- */
-class PropagateVariableTypesInLibraryTask extends SourceBasedAnalysisTask {
-  /**
-   * The name of the [LIBRARY_ELEMENT6] input.
-   */
-  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
-
-  /**
-   * The task descriptor describing this kind of task.
-   */
-  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'PropagateVariableTypesInLibraryTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[LIBRARY_ELEMENT7]);
-
-  PropagateVariableTypesInLibraryTask(
-      InternalAnalysisContext context, AnalysisTarget target)
-      : super(context, target);
-
-  @override
-  TaskDescriptor get descriptor => DESCRIPTOR;
-
-  @override
-  void internalPerform() {
-    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
-    outputs[LIBRARY_ELEMENT7] = library;
-  }
-
-  /**
-   * Return a map from the names of the inputs of this kind of task to the task
-   * input descriptors describing those inputs for a task with the
-   * given [target].
-   */
-  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
-    Source source = target;
-    return <String, TaskInput>{
-      'propagatedVariableTypesInUnits':
-          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT8),
-      LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
-    };
-  }
-
-  /**
-   * Create a [PropagateVariableTypesInLibraryTask] based on the given [target]
-   * in the given [context].
-   */
-  static PropagateVariableTypesInLibraryTask createTask(
-      AnalysisContext context, AnalysisTarget target) {
-    return new PropagateVariableTypesInLibraryTask(context, target);
-  }
-}
-
-/**
- * A task that ensures that all of the propagable variables in a compilation
- * unit have had their type propagated.
- */
-class PropagateVariableTypesInUnitTask extends SourceBasedAnalysisTask {
-  /**
-   * The name of the input whose value is the [RESOLVED_UNIT7] for the
-   * compilation unit.
-   */
-  static const String UNIT_INPUT = 'UNIT_INPUT';
-
-  /**
-   * The task descriptor describing this kind of task.
-   */
-  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'PropagateVariableTypesInUnitTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT8, RESOLVED_UNIT8]);
-
-  PropagateVariableTypesInUnitTask(
-      InternalAnalysisContext context, LibrarySpecificUnit unit)
-      : super(context, unit);
-
-  @override
-  TaskDescriptor get descriptor => DESCRIPTOR;
-
-  @override
-  void internalPerform() {
-    //
-    // Prepare inputs.
-    //
-    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
-    //
-    // Record outputs. There is no additional work to be done at this time
-    // because the work has implicitly been done by virtue of the task model
-    // preparing all of the inputs.
-    //
-    outputs[RESOLVED_UNIT8] = unit;
-    outputs[CREATED_RESOLVED_UNIT8] = true;
-  }
-
-  /**
-   * Return a map from the names of the inputs of this kind of task to the task
-   * input descriptors describing those inputs for a task with the given
-   * [target].
-   */
-  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
-    LibrarySpecificUnit unit = target;
-    return <String, TaskInput>{
-      'variables':
-          PROPAGABLE_VARIABLES_IN_UNIT.of(unit).toListOf(PROPAGATED_VARIABLE),
-      UNIT_INPUT: RESOLVED_UNIT7.of(unit)
-    };
-  }
-
-  /**
-   * Create a [PropagateVariableTypesInUnitTask] based on the given [target]
-   * in the given [context].
-   */
-  static PropagateVariableTypesInUnitTask createTask(
-      AnalysisContext context, AnalysisTarget target) {
-    return new PropagateVariableTypesInUnitTask(context, target);
-  }
-}
-
-/**
- * A task that computes the propagated type of an propagable variable and
- * stores it in the element model.
- */
-class PropagateVariableTypeTask extends InferStaticVariableTask {
-  /**
-   * The name of the [TYPE_PROVIDER] input.
-   */
-  static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
-
-  /**
-   * The name of the [RESOLVED_UNIT7] input.
-   */
-  static const String UNIT_INPUT = 'UNIT_INPUT';
-
-  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'PropagateVariableTypeTask',
-      createTask,
-      buildInputs,
-      <ResultDescriptor>[PROPAGATED_VARIABLE]);
-
-  PropagateVariableTypeTask(
-      InternalAnalysisContext context, VariableElement variable)
-      : super(context, variable);
-
-  @override
-  TaskDescriptor get descriptor => DESCRIPTOR;
-
-  @override
-  bool get handlesDependencyCycles => true;
-
-  @override
-  void internalPerform() {
-    //
-    // Prepare inputs.
-    //
-    PropertyInducingElementImpl variable = target;
-    TypeProvider typeProvider = getRequiredInput(TYPE_PROVIDER_INPUT);
-    CompilationUnit unit = getRequiredInput(UNIT_INPUT);
-
-    // If we're not in a dependency cycle, and we have no type annotation,
-    // re-resolve the right hand side and do propagation.
-    if (dependencyCycle == null && variable.hasImplicitType) {
-      VariableDeclaration declaration = getDeclaration(unit);
-      //
-      // Re-resolve the variable's initializer with the propagated types of
-      // other variables.
-      //
-      Expression initializer = declaration.initializer;
-      ResolutionContext resolutionContext = ResolutionContextBuilder.contextFor(
-          initializer, AnalysisErrorListener.NULL_LISTENER);
-      ResolverVisitor visitor = new ResolverVisitor(variable.library,
-          variable.source, typeProvider, AnalysisErrorListener.NULL_LISTENER,
-          nameScope: resolutionContext.scope);
-      if (resolutionContext.enclosingClassDeclaration != null) {
-        visitor.prepareToResolveMembersInClass(
-            resolutionContext.enclosingClassDeclaration);
-      }
-      visitor.initForIncrementalResolution();
-      initializer.accept(visitor);
-      //
-      // Record the type of the variable.
-      //
-      DartType newType = initializer.bestType;
-      if (newType != null && !newType.isBottom && !newType.isDynamic) {
-        variable.propagatedType = newType;
-      }
-    }
-    //
-    // Record outputs.
-    //
-    outputs[PROPAGATED_VARIABLE] = variable;
-  }
-
-  /**
-   * Return a map from the names of the inputs of this kind of task to the task
-   * input descriptors describing those inputs for a task with the given
-   * [target].
-   */
-  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
-    VariableElement variable = target;
-    if (variable.library == null) {
-      StringBuffer buffer = new StringBuffer();
-      buffer.write(
-          'PropagateVariableTypeTask building inputs for a variable with no library. Variable name = "');
-      buffer.write(variable.name);
-      buffer.write('". Path = ');
-      (variable as ElementImpl).appendPathTo(buffer);
-      throw new AnalysisException(buffer.toString());
-    }
-    LibrarySpecificUnit unit =
-        new LibrarySpecificUnit(variable.library.source, variable.source);
-    return <String, TaskInput>{
-      'dependencies': PROPAGABLE_VARIABLE_DEPENDENCIES
-          .of(variable)
-          .toListOf(PROPAGATED_VARIABLE),
-      TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT7.of(unit),
-    };
-  }
-
-  /**
-   * Create a [PropagateVariableTypeTask] based on the given [target] in the
-   * given [context].
-   */
-  static PropagateVariableTypeTask createTask(
-      AnalysisContext context, AnalysisTarget target) {
-    return new PropagateVariableTypeTask(context, target);
-  }
-}
-
-/**
  * A task that ensures that [LIBRARY_ELEMENT2] is ready for the target library
  * source and its import/export closure.
  */
@@ -4768,14 +4346,14 @@
  * A task that ensures that [LIBRARY_ELEMENT7] is ready for the target library
  * source and its import/export closure.
  */
-class ReadyLibraryElement6Task extends SourceBasedAnalysisTask {
+class ReadyLibraryElement7Task extends SourceBasedAnalysisTask {
   static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
-      'ReadyLibraryElement6Task',
+      'ReadyLibraryElement7Task',
       createTask,
       buildInputs,
       <ResultDescriptor>[READY_LIBRARY_ELEMENT7]);
 
-  ReadyLibraryElement6Task(
+  ReadyLibraryElement7Task(
       InternalAnalysisContext context, AnalysisTarget target)
       : super(context, target);
 
@@ -4801,9 +4379,9 @@
     };
   }
 
-  static ReadyLibraryElement6Task createTask(
+  static ReadyLibraryElement7Task createTask(
       AnalysisContext context, AnalysisTarget target) {
-    return new ReadyLibraryElement6Task(context, target);
+    return new ReadyLibraryElement7Task(context, target);
   }
 }
 
@@ -5292,7 +4870,7 @@
           'Cannot build inputs for a ${target.runtimeType}');
     }
     return <String, TaskInput>{
-      'createdResolvedUnit': CREATED_RESOLVED_UNIT12
+      'createdResolvedUnit': CREATED_RESOLVED_UNIT11
           .of(new LibrarySpecificUnit(librarySource, target.source))
     };
   }
@@ -5382,6 +4960,117 @@
 }
 
 /**
+ * An artificial task that does nothing except to force [LIBRARY_ELEMENT7] for
+ * the target library and its import/export closure.
+ */
+class ResolvedUnit7InLibraryClosureTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [LIBRARY_ELEMENT7] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ResolvedUnit7InLibraryClosureTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT8]);
+
+  ResolvedUnit7InLibraryClosureTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    outputs[LIBRARY_ELEMENT8] = library;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    Source source = target;
+    return <String, TaskInput>{
+      'readyForClosure': READY_LIBRARY_ELEMENT7.of(source),
+      LIBRARY_INPUT: LIBRARY_ELEMENT7.of(source),
+    };
+  }
+
+  /**
+   * Create a [ResolvedUnit7InLibraryClosureTask] based on the given
+   * [target] in the given [context].
+   */
+  static ResolvedUnit7InLibraryClosureTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ResolvedUnit7InLibraryClosureTask(context, target);
+  }
+}
+
+/**
+ * An artificial task that does nothing except to force [LIBRARY_ELEMENT6] and
+ * [RESOLVED_UNIT7] in the defining and part units of a library.
+ */
+class ResolvedUnit7InLibraryTask extends SourceBasedAnalysisTask {
+  /**
+   * The name of the [LIBRARY_ELEMENT6] input.
+   */
+  static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
+
+  /**
+   * The task descriptor describing this kind of task.
+   */
+  static final TaskDescriptor DESCRIPTOR = new TaskDescriptor(
+      'ResolvedUnit7InLibraryTask',
+      createTask,
+      buildInputs,
+      <ResultDescriptor>[LIBRARY_ELEMENT7]);
+
+  ResolvedUnit7InLibraryTask(
+      InternalAnalysisContext context, AnalysisTarget target)
+      : super(context, target);
+
+  @override
+  TaskDescriptor get descriptor => DESCRIPTOR;
+
+  @override
+  void internalPerform() {
+    LibraryElement library = getRequiredInput(LIBRARY_INPUT);
+    outputs[LIBRARY_ELEMENT7] = library;
+  }
+
+  /**
+   * Return a map from the names of the inputs of this kind of task to the task
+   * input descriptors describing those inputs for a task with the
+   * given [target].
+   */
+  static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
+    Source source = target;
+    return <String, TaskInput>{
+      'resolvedUnits':
+          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT7),
+      LIBRARY_INPUT: LIBRARY_ELEMENT6.of(source),
+    };
+  }
+
+  /**
+   * Create a [ResolvedUnit7InLibraryTask] based on the given [target]
+   * in the given [context].
+   */
+  static ResolvedUnit7InLibraryTask createTask(
+      AnalysisContext context, AnalysisTarget target) {
+    return new ResolvedUnit7InLibraryTask(context, target);
+  }
+}
+
+/**
  * A task that ensures that all of the inferable instance members in a
  * compilation unit have had their right hand sides re-resolved
  */
@@ -5397,7 +5086,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the input whose value is the [RESOLVED_UNIT9] for the
+   * The name of the input whose value is the [RESOLVED_UNIT8] for the
    * compilation unit.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
@@ -5409,7 +5098,7 @@
       'ResolveInstanceFieldsInUnitTask',
       createTask,
       buildInputs,
-      <ResultDescriptor>[CREATED_RESOLVED_UNIT10, RESOLVED_UNIT10]);
+      <ResultDescriptor>[CREATED_RESOLVED_UNIT9, RESOLVED_UNIT9]);
 
   /**
    * Initialize a newly created task to build a library element for the given
@@ -5446,8 +5135,8 @@
     //
     // Record outputs.
     //
-    outputs[RESOLVED_UNIT10] = unit;
-    outputs[CREATED_RESOLVED_UNIT10] = true;
+    outputs[RESOLVED_UNIT9] = unit;
+    outputs[CREATED_RESOLVED_UNIT9] = true;
   }
 
   /**
@@ -5458,7 +5147,7 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT9.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT8.of(unit),
       LIBRARY_INPUT: LIBRARY_ELEMENT6.of(unit.library),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
       // In strong mode, add additional dependencies to enforce inference
@@ -5467,14 +5156,14 @@
       // Require that static variable inference  be complete for all units in
       // the current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
-          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT9.of(
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT8.of(
               new LibrarySpecificUnit(
                   (unit as CompilationUnitElementImpl).librarySource,
                   unit.source))),
       // Require that full inference be complete for all dependencies of the
       // current library cycle.
       'orderLibraryCycles': LIBRARY_CYCLE_DEPENDENCIES.of(unit.library).toList(
-          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
               new LibrarySpecificUnit(
                   (unit as CompilationUnitElementImpl).librarySource,
                   unit.source)))
@@ -5492,7 +5181,7 @@
 }
 
 /**
- * A task that finishes resolution by requesting [RESOLVED_UNIT12] for every
+ * A task that finishes resolution by requesting [RESOLVED_UNIT11] for every
  * unit in the libraries closure and produces [LIBRARY_ELEMENT9].
  */
 class ResolveLibraryReferencesTask extends SourceBasedAnalysisTask {
@@ -5533,7 +5222,7 @@
     return <String, TaskInput>{
       LIBRARY_INPUT: LIBRARY_ELEMENT8.of(source),
       'resolvedUnits':
-          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT12),
+          LIBRARY_SPECIFIC_UNITS.of(source).toListOf(RESOLVED_UNIT11),
     };
   }
 
@@ -5548,7 +5237,7 @@
 }
 
 /**
- * A task that finishes resolution by requesting [RESOLVED_UNIT13] for every
+ * A task that finishes resolution by requesting [RESOLVED_UNIT12] for every
  * unit in the libraries closure and produces [LIBRARY_ELEMENT].
  */
 class ResolveLibraryTask extends SourceBasedAnalysisTask {
@@ -5558,7 +5247,7 @@
   static const String LIBRARY_INPUT = 'LIBRARY_INPUT';
 
   /**
-   * The name of the list of [RESOLVED_UNIT13] input.
+   * The name of the list of [RESOLVED_UNIT12] input.
    */
   static const String UNITS_INPUT = 'UNITS_INPUT';
 
@@ -5858,7 +5547,7 @@
   static const String TYPE_PROVIDER_INPUT = 'TYPE_PROVIDER_INPUT';
 
   /**
-   * The name of the [RESOLVED_UNIT11] input.
+   * The name of the [RESOLVED_UNIT10] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -5866,8 +5555,8 @@
       'ResolveUnitTask', createTask, buildInputs, <ResultDescriptor>[
     CONSTANT_EXPRESSIONS_DEPENDENCIES,
     RESOLVE_UNIT_ERRORS,
-    CREATED_RESOLVED_UNIT12,
-    RESOLVED_UNIT12
+    CREATED_RESOLVED_UNIT11,
+    RESOLVED_UNIT11
   ]);
 
   ResolveUnitTask(
@@ -5913,8 +5602,8 @@
     //
     outputs[CONSTANT_EXPRESSIONS_DEPENDENCIES] = constExprDependencies;
     outputs[RESOLVE_UNIT_ERRORS] = getTargetSourceErrors(errorListener, target);
-    outputs[RESOLVED_UNIT12] = unit;
-    outputs[CREATED_RESOLVED_UNIT12] = true;
+    outputs[RESOLVED_UNIT11] = unit;
+    outputs[CREATED_RESOLVED_UNIT11] = true;
   }
 
   /**
@@ -5927,14 +5616,14 @@
     return <String, TaskInput>{
       LIBRARY_INPUT: LIBRARY_ELEMENT8.of(unit.library),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
-      UNIT_INPUT: RESOLVED_UNIT11.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT10.of(unit),
       // In strong mode, add additional dependencies to enforce inference
       // ordering.
 
       // Require that inference be complete for all units in the
       // current library cycle.
       'orderLibraryCycleTasks': LIBRARY_CYCLE_UNITS.of(unit.library).toList(
-          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT11.of(
+          (CompilationUnitElement unit) => CREATED_RESOLVED_UNIT10.of(
               new LibrarySpecificUnit(
                   (unit as CompilationUnitElementImpl).librarySource,
                   unit.source)))
@@ -6289,7 +5978,7 @@
  */
 class StrongModeVerifyUnitTask extends SourceBasedAnalysisTask {
   /**
-   * The name of the [RESOLVED_UNIT13] input.
+   * The name of the [RESOLVED_UNIT12] input.
    */
   static const String UNIT_INPUT = 'UNIT_INPUT';
 
@@ -6350,7 +6039,7 @@
   static Map<String, TaskInput> buildInputs(AnalysisTarget target) {
     LibrarySpecificUnit unit = target;
     return <String, TaskInput>{
-      UNIT_INPUT: RESOLVED_UNIT13.of(unit),
+      UNIT_INPUT: RESOLVED_UNIT12.of(unit),
       TYPE_PROVIDER_INPUT: TYPE_PROVIDER.of(AnalysisContextTarget.request),
     };
   }
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 6cf5585..dd544ca 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -45,6 +45,7 @@
 /// `analyzer` analysis options constants.
 class AnalyzerOptions {
   static const String analyzer = 'analyzer';
+  static const String enableAssertInitializer = 'enableAssertInitializer';
   static const String enableAsync = 'enableAsync';
   static const String enableGenericMethods = 'enableGenericMethods';
   static const String enableStrictCallChecks = 'enableStrictCallChecks';
@@ -84,6 +85,7 @@
 
   /// Supported `analyzer` language configuration options.
   static const List<String> languageOptions = const [
+    enableAssertInitializer,
     enableAsync,
     enableGenericMethods,
     enableStrictCallChecks,
@@ -478,6 +480,14 @@
 
   void setLanguageOption(
       AnalysisContext context, Object feature, Object value) {
+    if (feature == AnalyzerOptions.enableAssertInitializer) {
+      if (isTrue(value)) {
+        AnalysisOptionsImpl options =
+            new AnalysisOptionsImpl.from(context.analysisOptions);
+        options.enableAssertInitializer = true;
+        context.analysisOptions = options;
+      }
+    }
     if (feature == AnalyzerOptions.enableAsync) {
       if (isFalse(value)) {
         AnalysisOptionsImpl options =
@@ -552,13 +562,13 @@
       AnalysisOptionsImpl options, Object feature, Object value) {
     bool boolValue = toBool(value);
     if (boolValue != null) {
-      if (feature == AnalyzerOptions.enableAsync) {
+      if (feature == AnalyzerOptions.enableAssertInitializer) {
+        options.enableAssertInitializer = boolValue;
+      } else if (feature == AnalyzerOptions.enableAsync) {
         options.enableAsync = boolValue;
-      }
-      if (feature == AnalyzerOptions.enableSuperMixins) {
+      } else if (feature == AnalyzerOptions.enableSuperMixins) {
         options.enableSuperMixins = boolValue;
-      }
-      if (feature == AnalyzerOptions.enableGenericMethods) {
+      } else if (feature == AnalyzerOptions.enableGenericMethods) {
         options.enableGenericMethods = boolValue;
       }
     }
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index a623b1c..d0b55fe 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -186,7 +186,9 @@
         // so no need to insert an error for this here.
         continue;
       }
-      checkArgument(arg, _elementType(element));
+      DartType expectedType = _elementType(element);
+      if (expectedType == null) expectedType = DynamicTypeImpl.instance;
+      checkArgument(arg, expectedType);
     }
   }
 
@@ -699,28 +701,34 @@
       assert(functionType.namedParameterTypes.isEmpty);
       assert(functionType.optionalParameterTypes.isEmpty);
 
-      // Refine the return type.
+      // Check the LHS type.
       var rhsType = _getDefiniteType(expr.rightHandSide);
       var lhsType = _getDefiniteType(expr.leftHandSide);
       var returnType = rules.refineBinaryExpressionType(
           typeProvider, lhsType, op, rhsType, functionType.returnType);
 
-      // Check the argument for an implicit cast.
-      _checkDowncast(expr.rightHandSide, paramTypes[0], from: rhsType);
-
-      // Check the return type for an implicit cast.
-      //
-      // If needed, mark the left side to indicate a down cast when we assign
-      // back to it. So these two implicit casts are equivalent:
-      //
-      //     y = /*implicit cast*/(y + 42);
-      //     y/*implicit cast*/ += 42;
-      //
-      // TODO(jmesserly): this is an unambiguous way to represent it, but it's
-      // a bit sneaky. We can't use the rightHandSide because that could be a
-      // downcast on its own, and we can't use the entire expression because its
-      // result value could used and then implicitly downcast.
-      _checkDowncast(expr.leftHandSide, lhsType, from: returnType);
+      if (!rules.isSubtypeOf(returnType, lhsType)) {
+        final numType = typeProvider.numType;
+        // TODO(jmesserly): this seems to duplicate logic in StaticTypeAnalyzer.
+        // Try to fix up the numerical case if possible.
+        if (rules.isSubtypeOf(lhsType, numType) &&
+            rules.isSubtypeOf(lhsType, rhsType)) {
+          // This is also slightly different from spec, but allows us to keep
+          // compound operators in the int += num and num += dynamic cases.
+          _recordImplicitCast(expr.rightHandSide, rhsType, lhsType);
+        } else {
+          // TODO(jmesserly): this results in a duplicate error, because
+          // ErrorVerifier also reports it.
+          _recordMessage(expr, StrongModeCode.STATIC_TYPE_ERROR,
+              [expr, returnType, lhsType]);
+        }
+      } else {
+        // Check the RHS type.
+        //
+        // This is only needed if we didn't already need a cast, and avoids
+        // emitting two messages for the same expression.
+        _checkDowncast(expr.rightHandSide, paramTypes.first);
+      }
     }
   }
 
diff --git a/pkg/analyzer/test/generated/analysis_context_factory.dart b/pkg/analyzer/test/generated/analysis_context_factory.dart
index 1e48058..48234e1 100644
--- a/pkg/analyzer/test/generated/analysis_context_factory.dart
+++ b/pkg/analyzer/test/generated/analysis_context_factory.dart
@@ -18,7 +18,6 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/sdk/sdk.dart';
 import 'package:analyzer/src/generated/engine.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source_io.dart';
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 10c227e..d8a3c72 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -1938,9 +1938,8 @@
     _assertCacheUnitResult(RESOLVED_UNIT9);
     _assertCacheUnitResult(RESOLVED_UNIT10);
     _assertCacheUnitResult(RESOLVED_UNIT11);
-    _assertCacheUnitResult(RESOLVED_UNIT12);
     if (expectCachePostConstantsValid) {
-      _assertCacheUnitResult(RESOLVED_UNIT13);
+      _assertCacheUnitResult(RESOLVED_UNIT12);
       _assertCacheUnitResult(RESOLVED_UNIT);
     }
   }
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index 1ac3a31..4d01088 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/src/dart/resolver/inheritance_manager.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/testing/ast_factory.dart';
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index e48c4dc..1224141 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -2772,6 +2772,12 @@
   static bool parseFunctionBodies = true;
 
   /**
+   * A flag indicating whether the parser is to parse asserts in the initializer
+   * list of a constructor.
+   */
+  bool enableAssertInitializer = false;
+
+  /**
    * A flag indicating whether parser is to parse async.
    */
   bool parseAsync = true;
@@ -2844,6 +2850,7 @@
     // Parse the source.
     //
     Parser parser = createParser(listener);
+    parser.enableAssertInitializer = enableAssertInitializer;
     parser.parseAsync = parseAsync;
     parser.parseGenericMethods = enableGenericMethods;
     parser.parseGenericMethodComments = enableGenericMethodComments;
@@ -2973,6 +2980,7 @@
     listener.setLineInfo(new TestSource(), scanner.lineStarts);
     Token token = scanner.tokenize();
     Parser parser = createParser(listener);
+    parser.enableAssertInitializer = enableAssertInitializer;
     parser.parseAsync = parseAsync;
     parser.parseFunctionBodies = parseFunctionBodies;
     parser.parseGenericMethods = enableGenericMethods;
@@ -7094,6 +7102,16 @@
 //        null, null, null, null, null, null}, "");
   }
 
+  void test_parseConstructor_assert() {
+    enableAssertInitializer = true;
+    ClassMember classMember = parse("parseClassMember", <Object>["C"],
+        "C(x, y) : _x = x, assert (x < y), _y = y;");
+    expect(classMember, new isInstanceOf<ConstructorDeclaration>());
+    ConstructorDeclaration constructor = classMember as ConstructorDeclaration;
+    NodeList<ConstructorInitializer> initializers = constructor.initializers;
+    expect(initializers, hasLength(2));
+  }
+
   void test_parseConstructor_with_pseudo_function_literal() {
     // "(b) {}" should not be misinterpreted as a function literal even though
     // it looks like one.
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 1135a52..cd87a6f 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -18,7 +18,6 @@
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
-import 'package:analyzer/src/generated/java_engine_io.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source_io.dart';
@@ -1482,109 +1481,6 @@
     expect(identifier.propagatedType.name, "CanvasRenderingContext2D");
   }
 
-  void test_finalPropertyInducingVariable_classMember_instance() {
-    addNamedSource(
-        "/lib.dart",
-        r'''
-class A {
-  final v = 0;
-}''');
-    String code = r'''
-import 'lib.dart';
-f(A a) {
-  return a.v; // marker
-}''';
-    assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void test_finalPropertyInducingVariable_classMember_instance_inherited() {
-    addNamedSource(
-        "/lib.dart",
-        r'''
-class A {
-  final v = 0;
-}''');
-    String code = r'''
-import 'lib.dart';
-class B extends A {
-  m() {
-    return v; // marker
-  }
-}''';
-    assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void
-      test_finalPropertyInducingVariable_classMember_instance_propagatedTarget() {
-    addNamedSource(
-        "/lib.dart",
-        r'''
-class A {
-  final v = 0;
-}''');
-    String code = r'''
-import 'lib.dart';
-f(p) {
-  if (p is A) {
-    return p.v; // marker
-  }
-}''';
-    assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void test_finalPropertyInducingVariable_classMember_instance_unprefixed() {
-    String code = r'''
-class A {
-  final v = 0;
-  m() {
-    v; // marker
-  }
-}''';
-    assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void test_finalPropertyInducingVariable_classMember_static() {
-    addNamedSource(
-        "/lib.dart",
-        r'''
-class A {
-  static final V = 0;
-}''');
-    String code = r'''
-import 'lib.dart';
-f() {
-  return A.V; // marker
-}''';
-    assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void test_finalPropertyInducingVariable_topLevelVariable_prefixed() {
-    addNamedSource("/lib.dart", "final V = 0;");
-    String code = r'''
-import 'lib.dart' as p;
-f() {
-  var v2 = p.V; // marker prefixed
-}''';
-    assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
-  void test_finalPropertyInducingVariable_topLevelVariable_simple() {
-    addNamedSource("/lib.dart", "final V = 0;");
-    String code = r'''
-import 'lib.dart';
-f() {
-  return V; // marker simple
-}''';
-    assertTypeOfMarkedExpression(
-        code, typeProvider.dynamicType, typeProvider.intType);
-  }
-
   void test_forEach() {
     String code = r'''
 main() {
diff --git a/pkg/analyzer/test/src/context/builder_test.dart b/pkg/analyzer/test/src/context/builder_test.dart
index e43d56f..5fde200 100644
--- a/pkg/analyzer/test/src/context/builder_test.dart
+++ b/pkg/analyzer/test/src/context/builder_test.dart
@@ -6,15 +6,18 @@
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
+import 'package:analyzer/plugin/options.dart';
 import 'package:analyzer/source/package_map_resolver.dart';
 import 'package:analyzer/src/context/builder.dart';
 import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/sdk.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/plugin/options_plugin.dart';
 import 'package:package_config/packages.dart';
 import 'package:package_config/src/packages_impl.dart';
 import 'package:path/path.dart' as path;
+import 'package:plugin/src/plugin_impl.dart';
 import 'package:unittest/unittest.dart';
 
 import '../../embedder_tests.dart';
@@ -485,7 +488,8 @@
     - empty_constructor_bodies
 ''');
 
-    AnalysisOptions options = builder.getAnalysisOptions(path);
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    AnalysisOptions options = builder.getAnalysisOptions(context, path);
     _expectEqualOptions(options, expected);
   }
 
@@ -505,8 +509,43 @@
   enableAsync : true
 ''');
 
-    AnalysisOptions options = builder.getAnalysisOptions(path);
-    _expectEqualOptions(options, expected);
+    AnalysisEngine engine = AnalysisEngine.instance;
+    OptionsPlugin plugin = engine.optionsPlugin;
+    plugin.registerExtensionPoints((_) {});
+    try {
+      _TestOptionsProcessor processor = new _TestOptionsProcessor();
+      processor.expectedOptions = <String, Object>{
+        'analyzer': {'enableAsync': true}
+      };
+      (plugin.optionsProcessorExtensionPoint as ExtensionPointImpl)
+          .add(processor);
+      AnalysisContext context = engine.createAnalysisContext();
+      AnalysisOptions options = builder.getAnalysisOptions(context, path);
+      _expectEqualOptions(options, expected);
+    } finally {
+      plugin.registerExtensionPoints((_) {});
+    }
+  }
+
+  void test_getAnalysisOptions_invalid() {
+    String path = '/some/directory/path';
+    String filePath = '$path/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}';
+    resourceProvider.newFile(filePath, ';');
+
+    AnalysisEngine engine = AnalysisEngine.instance;
+    OptionsPlugin plugin = engine.optionsPlugin;
+    plugin.registerExtensionPoints((_) {});
+    try {
+      _TestOptionsProcessor processor = new _TestOptionsProcessor();
+      (plugin.optionsProcessorExtensionPoint as ExtensionPointImpl)
+          .add(processor);
+      AnalysisContext context = engine.createAnalysisContext();
+      AnalysisOptions options = builder.getAnalysisOptions(context, path);
+      expect(options, isNotNull);
+      expect(processor.errorCount, 1);
+    } finally {
+      plugin.registerExtensionPoints((_) {});
+    }
   }
 
   void test_getAnalysisOptions_noDefault_noOverrides() {
@@ -520,7 +559,8 @@
     - empty_constructor_bodies
 ''');
 
-    AnalysisOptions options = builder.getAnalysisOptions(path);
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    AnalysisOptions options = builder.getAnalysisOptions(context, path);
     _expectEqualOptions(options, new AnalysisOptionsImpl());
   }
 
@@ -536,7 +576,8 @@
   enableAsync : true
 ''');
 
-    AnalysisOptions options = builder.getAnalysisOptions(path);
+    AnalysisContext context = AnalysisEngine.instance.createAnalysisContext();
+    AnalysisOptions options = builder.getAnalysisOptions(context, path);
     _expectEqualOptions(options, expected);
   }
 
@@ -651,3 +692,27 @@
     expect(locator.embedderYamls, hasLength(1));
   }
 }
+
+class _TestOptionsProcessor implements OptionsProcessor {
+  Map<String, Object> expectedOptions = null;
+
+  int errorCount = 0;
+
+  @override
+  void onError(Exception exception) {
+    errorCount++;
+  }
+
+  @override
+  void optionsProcessed(AnalysisContext context, Map<String, Object> options) {
+    if (expectedOptions == null) {
+      fail('Unexpected invocation of optionsProcessed');
+    }
+    expect(options, hasLength(expectedOptions.length));
+    for (String key in expectedOptions.keys) {
+      expect(options.containsKey(key), isTrue, reason: 'missing key $key');
+      expect(options[key], expectedOptions[key],
+          reason: 'values for key $key do not match');
+    }
+  }
+}
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 42b91f8..456d3ed 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2476,7 +2476,6 @@
     entry.setState(RESOLVED_UNIT10, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT11, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT12, CacheState.FLUSHED);
-    entry.setState(RESOLVED_UNIT13, CacheState.FLUSHED);
     entry.setState(RESOLVED_UNIT, CacheState.FLUSHED);
 
     context.resolveCompilationUnit2(source, source);
@@ -3797,10 +3796,10 @@
     {
       Expression argument = find42();
       expect(argument.staticParameterElement, isNull);
-      expect(argument.propagatedParameterElement, isNotNull);
     }
+
     // Update a.dart: add type annotation for 'a'.
-    // '42' has 'staticParameterElement', but not 'propagatedParameterElement'.
+    // '42' has 'staticParameterElement'.
     context.setContents(
         a,
         r'''
@@ -3816,10 +3815,10 @@
     {
       Expression argument = find42();
       expect(argument.staticParameterElement, isNotNull);
-      expect(argument.propagatedParameterElement, isNull);
     }
+
     // Update a.dart: remove type annotation for 'a'.
-    // '42' has 'propagatedParameterElement', but not 'staticParameterElement'.
+    // '42' doesn't have 'staticParameterElement'.
     context.setContents(
         a,
         r'''
@@ -3835,7 +3834,6 @@
     {
       Expression argument = find42();
       expect(argument.staticParameterElement, isNull);
-      expect(argument.propagatedParameterElement, isNotNull);
     }
   }
 
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index b034228..4b6f6d5 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -48,18 +48,6 @@
 
   @override
   @failingTest
-  test_field_propagated_type_final_immediate() {
-    super.test_field_propagated_type_final_immediate();
-  }
-
-  @override
-  @failingTest
-  test_fully_linked_references_follow_other_references() {
-    super.test_fully_linked_references_follow_other_references();
-  }
-
-  @override
-  @failingTest
   test_implicit_dependencies_follow_other_dependencies() {
     super.test_implicit_dependencies_follow_other_dependencies();
   }
@@ -120,18 +108,6 @@
 
   @override
   @failingTest
-  test_linked_reference_reuse() {
-    super.test_linked_reference_reuse();
-  }
-
-  @override
-  @failingTest
-  test_linked_type_dependency_reuse() {
-    super.test_linked_type_dependency_reuse();
-  }
-
-  @override
-  @failingTest
   test_syntheticFunctionType_genericClosure() {
     super.test_syntheticFunctionType_genericClosure();
   }
@@ -156,37 +132,7 @@
 
   @override
   @failingTest
-  test_syntheticFunctionType_noArguments() {
-    super.test_syntheticFunctionType_noArguments();
-  }
-
-  @override
-  @failingTest
-  test_syntheticFunctionType_withArguments() {
-    super.test_syntheticFunctionType_withArguments();
-  }
-
-  @override
-  @failingTest
   test_unused_type_parameter() {
     super.test_unused_type_parameter();
   }
-
-  @override
-  @failingTest
-  test_variable_propagated_type_final_immediate() {
-    super.test_variable_propagated_type_final_immediate();
-  }
-
-  @override
-  @failingTest
-  test_variable_propagated_type_new_reference() {
-    super.test_variable_propagated_type_new_reference();
-  }
-
-  @override
-  @failingTest
-  test_variable_propagated_type_omit_dynamic() {
-    super.test_variable_propagated_type_omit_dynamic();
-  }
 }
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
index b24daf9..03c638e 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_test.dart
@@ -65,18 +65,6 @@
 
   @override
   @failingTest
-  test_field_propagated_type_final_immediate() {
-    super.test_field_propagated_type_final_immediate();
-  }
-
-  @override
-  @failingTest
-  test_fully_linked_references_follow_other_references() {
-    super.test_fully_linked_references_follow_other_references();
-  }
-
-  @override
-  @failingTest
   test_implicit_dependencies_follow_other_dependencies() {
     super.test_implicit_dependencies_follow_other_dependencies();
   }
@@ -119,18 +107,6 @@
 
   @override
   @failingTest
-  test_linked_reference_reuse() {
-    super.test_linked_reference_reuse();
-  }
-
-  @override
-  @failingTest
-  test_linked_type_dependency_reuse() {
-    super.test_linked_type_dependency_reuse();
-  }
-
-  @override
-  @failingTest
   test_syntheticFunctionType_inGenericClass() {
     super.test_syntheticFunctionType_inGenericClass();
   }
@@ -143,39 +119,9 @@
 
   @override
   @failingTest
-  test_syntheticFunctionType_noArguments() {
-    super.test_syntheticFunctionType_noArguments();
-  }
-
-  @override
-  @failingTest
-  test_syntheticFunctionType_withArguments() {
-    super.test_syntheticFunctionType_withArguments();
-  }
-
-  @override
-  @failingTest
   test_unused_type_parameter() {
     super.test_unused_type_parameter();
   }
-
-  @override
-  @failingTest
-  test_variable_propagated_type_final_immediate() {
-    super.test_variable_propagated_type_final_immediate();
-  }
-
-  @override
-  @failingTest
-  test_variable_propagated_type_new_reference() {
-    super.test_variable_propagated_type_new_reference();
-  }
-
-  @override
-  @failingTest
-  test_variable_propagated_type_omit_dynamic() {
-    super.test_variable_propagated_type_omit_dynamic();
-  }
 }
 
 /**
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 287b482..5d9d9a7 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -7733,12 +7733,6 @@
     expect(v.inferredTypeSlot, 0);
   }
 
-  test_field_propagated_type_final_immediate() {
-    UnlinkedVariable v =
-        serializeClassText('class C { final v = 0; }').fields[0];
-    checkLinkedTypeSlot(v.propagatedTypeSlot, 'dart:core', 'dart:core', 'int');
-  }
-
   test_field_static() {
     UnlinkedVariable variable =
         serializeClassText('class C { static int i; }').fields[0];
@@ -7788,11 +7782,11 @@
   }
 
   test_fully_linked_references_follow_other_references() {
-    if (skipFullyLinkedData) {
+    if (!strongMode || skipFullyLinkedData) {
       return;
     }
     serializeLibraryText('final x = 0; String y;');
-    checkLinkedTypeSlot(unlinkedUnits[0].variables[0].propagatedTypeSlot,
+    checkLinkedTypeSlot(unlinkedUnits[0].variables[0].inferredTypeSlot,
         'dart:core', 'dart:core', 'int');
     checkTypeRef(
         unlinkedUnits[0].variables[1].type, 'dart:core', 'dart:core', 'String');
@@ -7800,7 +7794,7 @@
     // type reference for x should use a higher numbered reference than the
     // unlinked type reference for y.
     EntityRef propagatedType =
-        getTypeRefForSlot(unlinkedUnits[0].variables[0].propagatedTypeSlot);
+        getTypeRefForSlot(unlinkedUnits[0].variables[0].inferredTypeSlot);
     expect(unlinkedUnits[0].variables[1].type.reference,
         lessThan(propagatedType.reference));
   }
@@ -8712,7 +8706,7 @@
   }
 
   test_linked_reference_reuse() {
-    if (skipFullyLinkedData) {
+    if (!strongMode || skipFullyLinkedData) {
       return;
     }
     // When the reference for a linked type is the same as an explicitly
@@ -8722,12 +8716,12 @@
     serializeLibraryText(
         'import "a.dart"; import "b.dart"; C c1; final c2 = f();');
     int explicitReference = findVariable('c1').type.reference;
-    expect(getTypeRefForSlot(findVariable('c2').propagatedTypeSlot).reference,
+    expect(getTypeRefForSlot(findVariable('c2').inferredTypeSlot).reference,
         explicitReference);
   }
 
   test_linked_type_dependency_reuse() {
-    if (skipFullyLinkedData) {
+    if (!strongMode || skipFullyLinkedData) {
       return;
     }
     // When the dependency for a linked type is the same as an explicit
@@ -8739,7 +8733,7 @@
     int cReference = findVariable('c').type.reference;
     int explicitDependency = linked.units[0].references[cReference].dependency;
     int dReference =
-        getTypeRefForSlot(findVariable('d').propagatedTypeSlot).reference;
+        getTypeRefForSlot(findVariable('d').inferredTypeSlot).reference;
     expect(
         linked.units[0].references[dReference].dependency, explicitDependency);
   }
@@ -9500,8 +9494,8 @@
     // ids should be reused.
     addNamedSource('/a.dart', 'part of foo; final v = 0;');
     serializeLibraryText('library foo; part "a.dart"; final w = 0;');
-    expect(unlinkedUnits[1].variables[0].propagatedTypeSlot,
-        unlinkedUnits[0].variables[0].propagatedTypeSlot);
+    expect(unlinkedUnits[1].variables[0].inferredTypeSlot,
+        unlinkedUnits[0].variables[0].inferredTypeSlot);
   }
 
   test_syntheticFunctionType_genericClosure() {
@@ -9592,38 +9586,6 @@
     checkParamTypeRef(inferredType.syntheticParams[1].type, 1);
   }
 
-  test_syntheticFunctionType_noArguments() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable variable = serializeVariableText('''
-final v = f() ? () => 0 : () => 1;
-bool f() => true;
-''');
-    EntityRef propagatedType = getTypeRefForSlot(variable.propagatedTypeSlot);
-    checkLinkedTypeRef(
-        propagatedType.syntheticReturnType, 'dart:core', 'dart:core', 'int');
-    expect(propagatedType.syntheticParams, isEmpty);
-  }
-
-  test_syntheticFunctionType_withArguments() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable variable = serializeVariableText('''
-final v = f() ? (int x, String y) => 0 : (int x, String y) => 1;
-bool f() => true;
-''');
-    EntityRef propagatedType = getTypeRefForSlot(variable.propagatedTypeSlot);
-    checkTypeRef(
-        propagatedType.syntheticReturnType, 'dart:core', 'dart:core', 'int');
-    expect(propagatedType.syntheticParams, hasLength(2));
-    checkTypeRef(propagatedType.syntheticParams[0].type, 'dart:core',
-        'dart:core', 'int');
-    checkTypeRef(propagatedType.syntheticParams[1].type, 'dart:core',
-        'dart:core', 'String');
-  }
-
   test_type_arguments_explicit() {
     EntityRef typeRef = serializeTypeText('List<int>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
@@ -10335,59 +10297,6 @@
     expect(unlinkedUnits[0].publicNamespace.names, isEmpty);
   }
 
-  test_variable_propagated_type_final_immediate() {
-    UnlinkedVariable v = serializeVariableText('final v = 0;');
-    checkLinkedTypeSlot(v.propagatedTypeSlot, 'dart:core', 'dart:core', 'int');
-  }
-
-  test_variable_propagated_type_new_reference() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable v = serializeVariableText('final v = 0;');
-    // Since the propagated type of `v` is `int`, and there are no references
-    // to `int` elsewhere in the source file, a new linked reference should
-    // have been created for it, with no associated unlinked reference.
-    expect(v.propagatedTypeSlot, isNot(0));
-    EntityRef type = getTypeRefForSlot(v.propagatedTypeSlot);
-    expect(type, isNotNull);
-    expect(type.reference,
-        greaterThanOrEqualTo(unlinkedUnits[0].references.length));
-  }
-
-  test_variable_propagated_type_omit_dynamic() {
-    if (skipFullyLinkedData) {
-      return;
-    }
-    UnlinkedVariable v = serializeVariableText('final v = <int, dynamic>{};');
-    EntityRef type = getTypeRefForSlot(v.propagatedTypeSlot);
-    checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
-        numTypeParameters: 2, numTypeArguments: 2);
-    checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
-    checkLinkedDynamicTypeRef(type.typeArguments[1]);
-  }
-
-  test_variable_propagatedTypeSlot_const() {
-    // Const variables are propagable so they have a nonzero
-    // propagatedTypeSlot.
-    UnlinkedVariable variable = serializeVariableText('const v = 0;');
-    expect(variable.propagatedTypeSlot, isNot(0));
-  }
-
-  test_variable_propagatedTypeSlot_final() {
-    // Final variables are propagable so they have a nonzero
-    // propagatedTypeSlot.
-    UnlinkedVariable variable = serializeVariableText('final v = 0;');
-    expect(variable.propagatedTypeSlot, isNot(0));
-  }
-
-  test_variable_propagatedTypeSlot_non_propagable() {
-    // Non-final non-const variables aren't propagable so they don't have a
-    // propagatedTypeSlot.
-    UnlinkedVariable variable = serializeVariableText('var v;');
-    expect(variable.propagatedTypeSlot, 0);
-  }
-
   test_variable_static() {
     UnlinkedVariable variable =
         serializeClassText('class C { static int i; }').fields[0];
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index c01223c..06b94cd 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -49,7 +49,6 @@
   runReflectiveTests(ComputeConstantValueTaskTest);
   runReflectiveTests(ComputeInferableStaticVariableDependenciesTaskTest);
   runReflectiveTests(ComputeLibraryCycleTaskTest);
-  runReflectiveTests(ComputePropagableVariableDependenciesTaskTest);
   runReflectiveTests(ContainingLibrariesTaskTest);
   runReflectiveTests(DartErrorsTaskTest);
   runReflectiveTests(EvaluateUnitConstantsTaskTest);
@@ -64,8 +63,6 @@
   runReflectiveTests(LibraryUnitErrorsTaskTest);
   runReflectiveTests(ParseDartTaskTest);
   runReflectiveTests(PartiallyResolveUnitReferencesTaskTest);
-  runReflectiveTests(PropagateVariableTypesInUnitTaskTest);
-  runReflectiveTests(PropagateVariableTypeTaskTest);
   runReflectiveTests(ReferencedNamesBuilderTest);
   runReflectiveTests(ResolveDirectiveElementsTaskTest);
   runReflectiveTests(ResolveInstanceFieldsInUnitTaskTest);
@@ -103,8 +100,6 @@
     new isInstanceOf<ComputeConstantValueTask>();
 isInstanceOf isComputeInferableStaticVariableDependenciesTask =
     new isInstanceOf<ComputeInferableStaticVariableDependenciesTask>();
-isInstanceOf isComputePropagableVariableDependenciesTask =
-    new isInstanceOf<ComputePropagableVariableDependenciesTask>();
 isInstanceOf isContainingLibrariesTask =
     new isInstanceOf<ContainingLibrariesTask>();
 isInstanceOf isDartErrorsTask = new isInstanceOf<DartErrorsTask>();
@@ -129,10 +124,6 @@
 isInstanceOf isParseDartTask = new isInstanceOf<ParseDartTask>();
 isInstanceOf isPartiallyResolveUnitReferencesTask =
     new isInstanceOf<PartiallyResolveUnitReferencesTask>();
-isInstanceOf isPropagateVariableTypesInUnitTask =
-    new isInstanceOf<PropagateVariableTypesInUnitTask>();
-isInstanceOf isPropagateVariableTypeTask =
-    new isInstanceOf<PropagateVariableTypeTask>();
 isInstanceOf isResolveDirectiveElementsTask =
     new isInstanceOf<ResolveDirectiveElementsTask>();
 isInstanceOf isResolveLibraryReferencesTask =
@@ -2017,139 +2008,6 @@
 }
 
 @reflectiveTest
-class ComputePropagableVariableDependenciesTaskTest
-    extends _AbstractDartTaskTest {
-  List<VariableElement> getPropagableVariableDependencies(
-      Map<ResultDescriptor, dynamic> outputs) {
-    return outputs[PROPAGABLE_VARIABLE_DEPENDENCIES] as List<VariableElement>;
-  }
-
-  test_perform_instanceField() {
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-class A {
-  final a = a1 + a2 + a3 + a4 + B.b1 + B.b2 + B.b3 + B.b4;
-  static const a1 = 1;
-  final a2 = 2;
-  final a3;
-  var   a4 = 4;
-}
-class B {
-  static const b1 = 1;
-  static final b2 = 2;
-  static final b3;
-  static var   b4 = 4;
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    FieldElement elementA = AstFinder.getFieldInClassElement(unit, 'A', 'a');
-    // compute
-    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
-        matcher: isComputePropagableVariableDependenciesTask);
-    // verify
-    expect(outputs, hasLength(1));
-    List<VariableElement> dependencies =
-        getPropagableVariableDependencies(outputs);
-    expect(
-        dependencies,
-        unorderedEquals([
-          AstFinder.getFieldInClassElement(unit, 'A', 'a1'),
-          AstFinder.getFieldInClassElement(unit, 'A', 'a2'),
-          AstFinder.getFieldInClassElement(unit, 'B', 'b1'),
-          AstFinder.getFieldInClassElement(unit, 'B', 'b2')
-        ]));
-  }
-
-  test_perform_topLevel() {
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-const a = d1 + d2 + d3 + d4;
-const d1 = 1;
-final d2 = 2;
-final d3;
-var   d4 = 4;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    TopLevelVariableElement elementA =
-        AstFinder.getTopLevelVariableElement(unit, 'a');
-    // compute
-    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
-        matcher: isComputePropagableVariableDependenciesTask);
-    // verify
-    expect(outputs, hasLength(1));
-    List<VariableElement> dependencies =
-        getPropagableVariableDependencies(outputs);
-    expect(
-        dependencies,
-        unorderedEquals([
-          AstFinder.getTopLevelVariableElement(unit, 'd1'),
-          AstFinder.getTopLevelVariableElement(unit, 'd2')
-        ]));
-  }
-
-  test_perform_topLevel_ignoreLocal() {
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-final a = () {
-  const b = 2;
-  const c = 3;
-  return b + c;
-}() + d;
-final d = 4;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    TopLevelVariableElement elementA =
-        AstFinder.getTopLevelVariableElement(unit, 'a');
-    // compute
-    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
-        matcher: isComputePropagableVariableDependenciesTask);
-    // verify
-    expect(outputs, hasLength(1));
-    List<VariableElement> dependencies =
-        getPropagableVariableDependencies(outputs);
-    expect(dependencies,
-        unorderedEquals([AstFinder.getTopLevelVariableElement(unit, 'd')]));
-  }
-
-  test_perform_topLevel_withoutSpaceAfterType() {
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-const List<int>a=[b, c];
-const b = 1;
-const c = 2;
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    TopLevelVariableElement elementA =
-        AstFinder.getTopLevelVariableElement(unit, 'a');
-    // compute
-    computeResult(elementA, PROPAGABLE_VARIABLE_DEPENDENCIES,
-        matcher: isComputePropagableVariableDependenciesTask);
-    // verify
-    expect(outputs, hasLength(1));
-    List<VariableElement> dependencies =
-        getPropagableVariableDependencies(outputs);
-    expect(
-        dependencies,
-        unorderedEquals([
-          AstFinder.getTopLevelVariableElement(unit, 'b'),
-          AstFinder.getTopLevelVariableElement(unit, 'c')
-        ]));
-  }
-}
-
-@reflectiveTest
 class ContainingLibrariesTaskTest extends _AbstractDartTaskTest {
   List<Source> getContainingLibraries(Map<ResultDescriptor, dynamic> outputs) {
     return outputs[CONTAINING_LIBRARIES] as List<Source>;
@@ -2237,9 +2095,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT13);
-    expect(outputs[RESOLVED_UNIT13], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT13], isTrue);
+    computeResult(target, RESOLVED_UNIT12);
+    expect(outputs[RESOLVED_UNIT12], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
   }
 
   test_perform() {
@@ -2256,9 +2114,9 @@
 const x = const C();
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT13,
+    computeResult(target, RESOLVED_UNIT12,
         matcher: isEvaluateUnitConstantsTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT13];
+    CompilationUnit unit = outputs[RESOLVED_UNIT12];
     CompilationUnitElement unitElement = unit.element;
     expect(
         (unitElement.types[0].constructors[0] as ConstructorElementImpl)
@@ -2765,9 +2623,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT11);
-    expect(outputs[RESOLVED_UNIT11], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
+    computeResult(target, RESOLVED_UNIT10);
+    expect(outputs[RESOLVED_UNIT10], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
   }
 
   void test_perform() {
@@ -2787,9 +2645,9 @@
 class Y {}
 class Z {}
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10,
         matcher: isInferInstanceMembersInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
     VariableDeclaration field = AstFinder.getFieldInClass(unit, 'B', 'f');
     MethodDeclaration method = AstFinder.getMethodInClass(unit, 'B', 'm');
     DartType typeX = AstFinder.getClass(unit, 'X').element.type;
@@ -2821,12 +2679,12 @@
 }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11,
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT10,
         matcher: isInferInstanceMembersInUnitTask);
-    CompilationUnit firstUnit = outputs[RESOLVED_UNIT11];
+    CompilationUnit firstUnit = outputs[RESOLVED_UNIT10];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
-    CompilationUnit secondUnit = outputs[RESOLVED_UNIT11];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT10);
+    CompilationUnit secondUnit = outputs[RESOLVED_UNIT10];
 
     VariableDeclaration variableA =
         AstFinder.getTopLevelVariable(firstUnit, 'a');
@@ -2853,8 +2711,8 @@
   String field = topLevel;
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
-    CompilationUnit unit = outputs[RESOLVED_UNIT11];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT10);
+    CompilationUnit unit = outputs[RESOLVED_UNIT10];
     VariableDeclaration topLevelDecl =
         AstFinder.getTopLevelVariable(unit, 'topLevel');
     VariableDeclaration fieldDecl =
@@ -2885,9 +2743,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT9);
-    expect(outputs[RESOLVED_UNIT9], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+    computeResult(target, RESOLVED_UNIT8);
+    expect(outputs[RESOLVED_UNIT8], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
   }
 
   void test_perform_const_field() {
@@ -2899,9 +2757,9 @@
   static const X = "";
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    CompilationUnit unit = outputs[RESOLVED_UNIT8];
     VariableDeclaration declaration = AstFinder.getFieldInClass(unit, 'M', 'X');
     InterfaceType stringType = context.typeProvider.stringType;
     expect(declaration.element.type, stringType);
@@ -2914,9 +2772,9 @@
 @(i $=
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT9);
-    expect(outputs[RESOLVED_UNIT9], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+    computeResult(target, RESOLVED_UNIT8);
+    expect(outputs[RESOLVED_UNIT8], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
   }
 
   void test_perform_nestedDeclarations() {
@@ -2930,7 +2788,7 @@
   return xSquared;
 };
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
         matcher: isInferStaticVariableTypesInUnitTask);
   }
 
@@ -2953,12 +2811,12 @@
 class M {}
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT9,
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT8,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit firstUnit = outputs[RESOLVED_UNIT9];
+    CompilationUnit firstUnit = outputs[RESOLVED_UNIT8];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT9);
-    CompilationUnit secondUnit = outputs[RESOLVED_UNIT9];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT8);
+    CompilationUnit secondUnit = outputs[RESOLVED_UNIT8];
 
     VariableDeclaration variableA =
         AstFinder.getTopLevelVariable(firstUnit, 'a');
@@ -2987,9 +2845,9 @@
   return 1 + X;
 };
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT9,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
         matcher: isInferStaticVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT9];
+    CompilationUnit unit = outputs[RESOLVED_UNIT8];
     TopLevelVariableDeclaration declaration = unit.declarations[1];
     FunctionExpression function =
         declaration.variables.variables[0].initializer;
@@ -3010,9 +2868,9 @@
 var V = [42];
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT9);
-    expect(outputs[RESOLVED_UNIT9], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
+    computeResult(target, RESOLVED_UNIT8);
+    expect(outputs[RESOLVED_UNIT8], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
     // An INFERRED_TYPE_LITERAL error should be generated.
     List<AnalysisError> errors = outputs[
         STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT] as List<AnalysisError>;
@@ -3425,36 +3283,6 @@
 
 @reflectiveTest
 class PartiallyResolveUnitReferencesTaskTest extends _AbstractDartTaskTest {
-  test_perform_propagable() {
-    enableStrongMode();
-    Source source = newSource(
-        '/test.dart',
-        '''
-const t1 = 1;
-final t2 = 2;
-var   t3 = 3;
-final t4;
-class C {
-  static const fs1 = 1;
-  static final fs2 = 2;
-  static var   fs3 = 3;
-  static final fs4;
-  const fi1 = 1;
-  final fi2 = 2;
-  var   fi3 = 3;
-  final fi4;
-}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, PROPAGABLE_VARIABLES_IN_UNIT,
-        matcher: isPartiallyResolveUnitReferencesTask);
-    // PROPAGABLE_VARIABLES_IN_UNIT
-    List<VariableElement> variables =
-        outputs[PROPAGABLE_VARIABLES_IN_UNIT] as List<VariableElement>;
-    expect(variables.map((v) => v.displayName),
-        unorderedEquals(['t1', 't2', 'fs1', 'fs2', 'fi1', 'fi2']));
-  }
-
   test_perform_strong_importExport() {
     newSource(
         '/a.dart',
@@ -3597,138 +3425,6 @@
 }
 
 @reflectiveTest
-class PropagateVariableTypesInUnitTaskTest extends _AbstractDartTaskTest {
-  test_created_resolved_unit() {
-    Source source = newSource(
-        '/test.dart',
-        r'''
-library lib;
-class A {}
-''');
-    LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT8);
-    expect(outputs[RESOLVED_UNIT8], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT8], isTrue);
-  }
-
-  void test_perform_cycle() {
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-final piFirst = true;
-final pi = piFirst ? 3.14 : tau / 2;
-final tau = piFirst ? pi * 2 : 6.28;
-''');
-    // compute
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
-        matcher: isPropagateVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT8];
-    // verify
-    TopLevelVariableElement piFirst =
-        AstFinder.getTopLevelVariableElement(unit, 'piFirst');
-    TopLevelVariableElement pi =
-        AstFinder.getTopLevelVariableElement(unit, 'pi');
-    TopLevelVariableElement tau =
-        AstFinder.getTopLevelVariableElement(unit, 'tau');
-    expect(piFirst.propagatedType, context.typeProvider.boolType);
-    expect(pi.propagatedType, isNull);
-    expect(tau.propagatedType, isNull);
-  }
-
-  void test_perform_topLevel() {
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-//final a = b + c.length;
-final a = b;
-final b = 1;
-final c = '2';
-''');
-    // compute
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT8,
-        matcher: isPropagateVariableTypesInUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT8];
-    // verify
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-    expect(AstFinder.getTopLevelVariableElement(unit, 'a').propagatedType,
-        intType);
-    expect(AstFinder.getTopLevelVariableElement(unit, 'b').propagatedType,
-        intType);
-    expect(AstFinder.getTopLevelVariableElement(unit, 'c').propagatedType,
-        stringType);
-  }
-}
-
-@reflectiveTest
-class PropagateVariableTypeTaskTest extends _AbstractDartTaskTest {
-  void test_perform_cycle() {
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-final piFirst = true;
-final pi = piFirst ? 3.14 : tau / 2;
-final tau = piFirst ? pi * 2 : 6.28;
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    TopLevelVariableElement piFirst =
-        AstFinder.getTopLevelVariableElement(unit, 'piFirst');
-    TopLevelVariableElement pi =
-        AstFinder.getTopLevelVariableElement(unit, 'pi');
-    TopLevelVariableElement tau =
-        AstFinder.getTopLevelVariableElement(unit, 'tau');
-    // compute
-    computeResult(piFirst, PROPAGATED_VARIABLE,
-        matcher: isPropagateVariableTypeTask);
-    expect(piFirst.propagatedType, context.typeProvider.boolType);
-    expect(pi.propagatedType, isNull);
-    expect(tau.propagatedType, isNull);
-  }
-
-  void test_perform_null() {
-    enableStrongMode();
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-var a = null;
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    TopLevelVariableElement a = AstFinder.getTopLevelVariableElement(unit, 'a');
-    // compute
-    computeResult(a, PROPAGATED_VARIABLE, matcher: isPropagateVariableTypeTask);
-    expect(a.propagatedType, isNull);
-  }
-
-  void test_perform_topLevel() {
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-final a = b + c.length;
-final b = 1;
-final c = '2';
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT7);
-    CompilationUnit unit = outputs[RESOLVED_UNIT7];
-    TopLevelVariableElement elementA =
-        AstFinder.getTopLevelVariableElement(unit, 'a');
-    TopLevelVariableElement elementB =
-        AstFinder.getTopLevelVariableElement(unit, 'b');
-    TopLevelVariableElement elementC =
-        AstFinder.getTopLevelVariableElement(unit, 'c');
-    // compute
-    computeResult(elementA, PROPAGATED_VARIABLE,
-        matcher: isPropagateVariableTypeTask);
-    InterfaceType intType = context.typeProvider.intType;
-    InterfaceType stringType = context.typeProvider.stringType;
-    expect(elementA.propagatedType, intType);
-    expect(elementB.propagatedType, intType);
-    expect(elementC.propagatedType, stringType);
-  }
-}
-
-@reflectiveTest
 class ReferencedNamesBuilderTest extends _AbstractDartTaskTest {
   void setUp() {
     super.setUp();
@@ -4257,9 +3953,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT10);
-    expect(outputs[RESOLVED_UNIT10], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT10], isTrue);
+    computeResult(target, RESOLVED_UNIT9);
+    expect(outputs[RESOLVED_UNIT9], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT9], isTrue);
   }
 
   // Test inference of instance fields across units
@@ -4289,16 +3985,16 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
 
     // B.b2 shoud be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
 
     // B.b2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
@@ -4309,7 +4005,7 @@
         AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
 
     // A.a2 should now be fully resolved and inferred.
     assertVariableDeclarationTypes(
@@ -4346,15 +4042,15 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
 
     // A.a2 should now be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit0, "A", "a2"), dynamicType, dynamicType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
 
     // A.a2 should now be fully resolved and inferred (but not re-resolved).
     assertVariableDeclarationTypes(
@@ -4392,8 +4088,8 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT9];
 
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit1, "B", "b1"), intType, intType);
@@ -4401,8 +4097,8 @@
         AstFinder.getFieldInClass(unit1, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
 
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -4415,7 +4111,7 @@
         AstFinder.getFieldInClass(unit1, "B", "b2"), intType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT10);
+        new LibrarySpecificUnit(sources[2], sources[2]), RESOLVED_UNIT9);
 
     assertVariableDeclarationTypes(
         AstFinder.getFieldInClass(unit0, "A", "a1"), intType, intType);
@@ -4454,8 +4150,8 @@
     DartType dynamicType = context.typeProvider.dynamicType;
 
     computeResult(
-        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT10);
-    CompilationUnit unit0 = outputs[RESOLVED_UNIT10];
+        new LibrarySpecificUnit(sources[0], sources[0]), RESOLVED_UNIT9);
+    CompilationUnit unit0 = outputs[RESOLVED_UNIT9];
 
     // A.a2 should now be resolved on the rhs, but not yet inferred.
     assertVariableDeclarationTypes(
@@ -4466,7 +4162,7 @@
         AstFinder.getFieldInClass(unit0, "B", "b2"), dynamicType, intType);
 
     computeResult(
-        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT10);
+        new LibrarySpecificUnit(sources[1], sources[1]), RESOLVED_UNIT9);
 
     // A.a2 should now be fully resolved and inferred (but not re-resolved).
     assertVariableDeclarationTypes(
@@ -4703,9 +4399,9 @@
 class A {}
 ''');
     LibrarySpecificUnit target = new LibrarySpecificUnit(source, source);
-    computeResult(target, RESOLVED_UNIT12);
-    expect(outputs[RESOLVED_UNIT12], isNotNull);
-    expect(outputs[CREATED_RESOLVED_UNIT12], isTrue);
+    computeResult(target, RESOLVED_UNIT11);
+    expect(outputs[RESOLVED_UNIT11], isNotNull);
+    expect(outputs[CREATED_RESOLVED_UNIT11], isTrue);
   }
 
   void test_perform() {
@@ -4722,9 +4418,9 @@
   }
 }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12,
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11,
         matcher: isResolveUnitTask);
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     FunctionDeclaration f = unit.declarations[0];
     _assertResolved(f.functionExpression.body);
@@ -4735,33 +4431,6 @@
     expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
   }
 
-  void test_perform_ensurePropagatedVariableTypes() {
-    newSource(
-        '/lib.dart',
-        '''
-class A {
-  final v = 1;
-}
-''');
-    AnalysisTarget source = newSource(
-        '/test.dart',
-        '''
-import 'lib.dart';
-main(A a) {
-  a.v.isEven;
-}
-''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12,
-        matcher: isResolveUnitTask);
-    expect(outputs[RESOLVE_UNIT_ERRORS], hasLength(0));
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
-    FunctionDeclaration main = unit.declarations[0];
-    BlockFunctionBody body = main.functionExpression.body;
-    ExpressionStatement statement = body.block.statements.single;
-    Expression expression = statement.expression;
-    expect(expression.bestType, context.typeProvider.boolType);
-  }
-
   void _assertResolved(FunctionBody body) {
     ResolutionVerifier verifier = new ResolutionVerifier();
     body.accept(verifier);
@@ -5056,8 +4725,8 @@
 var pi = piFirst ? 3.14 : tau / 2;
 var tau = piFirst ? pi * 2 : 6.28;
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
     VariableElement piFirst =
         AstFinder.getTopLevelVariable(unit, 'piFirst').name.staticElement;
     VariableElement pi =
@@ -5099,11 +4768,11 @@
           }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT12);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT12];
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT12);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT12];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
+    CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
 
@@ -5150,7 +4819,7 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT12).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
     CompilationUnit unit0 = units[0];
     CompilationUnit unit1 = units[1];
     CompilationUnit unit2 = units[2];
@@ -5197,7 +4866,7 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT12).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
     CompilationUnit unit0 = units[0];
     CompilationUnit unit2 = units[2];
 
@@ -5238,11 +4907,11 @@
           }
 ''');
     computeResult(
-        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT12);
-    CompilationUnit unit1 = outputs[RESOLVED_UNIT12];
+        new LibrarySpecificUnit(firstSource, firstSource), RESOLVED_UNIT11);
+    CompilationUnit unit1 = outputs[RESOLVED_UNIT11];
     computeResult(
-        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT12);
-    CompilationUnit unit2 = outputs[RESOLVED_UNIT12];
+        new LibrarySpecificUnit(secondSource, secondSource), RESOLVED_UNIT11);
+    CompilationUnit unit2 = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -5292,7 +4961,7 @@
     '''
     });
     List<dynamic> units =
-        computeLibraryResults(sources, RESOLVED_UNIT12).toList();
+        computeLibraryResults(sources, RESOLVED_UNIT11).toList();
     CompilationUnit unit0 = units[0];
     CompilationUnit unit1 = units[1];
     CompilationUnit unit2 = units[2];
@@ -5328,8 +4997,8 @@
         y = "hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -5367,8 +5036,8 @@
         final z = 42; // should infer `int`
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -5416,8 +5085,8 @@
       int y = 0; // field def after use
       final z = 42; // should infer `int`
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -5469,8 +5138,8 @@
         new A().y2 = /*severe:StaticTypeError*/"hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
@@ -5511,8 +5180,8 @@
         x = "hi";
       }
 ''');
-    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT12);
-    CompilationUnit unit = outputs[RESOLVED_UNIT12];
+    computeResult(new LibrarySpecificUnit(source, source), RESOLVED_UNIT11);
+    CompilationUnit unit = outputs[RESOLVED_UNIT11];
 
     InterfaceType intType = context.typeProvider.intType;
     InterfaceType stringType = context.typeProvider.stringType;
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index a00747e..4c2d8af 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -269,7 +269,7 @@
 test() {
   int x = 0;
   x += 5;
-  x += /*error:INVALID_ASSIGNMENT*/3.14;
+  /*error:STATIC_TYPE_ERROR*/x += /*error:INVALID_ASSIGNMENT*/3.14;
 
   double y = 0.0;
   y += 5;
@@ -280,12 +280,12 @@
   z += 3.14;
 
   x = /*info:DOWN_CAST_IMPLICIT*/x + z;
-  /*info:DOWN_CAST_IMPLICIT*/x += z;
+  x += /*info:DOWN_CAST_IMPLICIT*/z;
   y = y + z;
   y += z;
 
   dynamic w = 42;
-  /*info:DOWN_CAST_IMPLICIT*/x += /*info:DYNAMIC_CAST*/w;
+  x += /*info:DYNAMIC_CAST*/w;
   y += /*info:DYNAMIC_CAST*/w;
   z += /*info:DYNAMIC_CAST*/w;
 
@@ -301,7 +301,7 @@
   a += b;
   a += /*error:ARGUMENT_TYPE_NOT_ASSIGNABLE*/a;
   a -= b;
-  b -= /*error:INVALID_ASSIGNMENT*/b;
+  /*error:STATIC_TYPE_ERROR*/b -= /*error:INVALID_ASSIGNMENT*/b;
   a <<= b;
   a >>= b;
   a &= b;
@@ -320,20 +320,6 @@
 ''');
   }
 
-  void test_compoundAssignment_returnsDynamic() {
-    checkFile(r'''
-class Foo {
-  operator +(other) => null;
-}
-
-main() {
-  var foo = new Foo();
-  foo = /*info:DYNAMIC_CAST*/foo + 1;
-  /*info:DYNAMIC_CAST*/foo += 1;
-}
-    ''');
-  }
-
   void test_constructorInvalid() {
     // Regression test for https://github.com/dart-lang/sdk/issues/26695
     checkFile('''
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 8b00a44..0087b3d 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1609,6 +1609,17 @@
     ''');
   }
 
+  void test_futureThen_explicitFuture() {
+    checkFile(r'''
+import "dart:async";
+main() {
+  Future<int> f;
+  var x = f.then/*<Future<List<int>>>*/(/*info:INFERRED_TYPE_CLOSURE*/(x) => /*info:INFERRED_TYPE_LITERAL*/[]);
+  Future<List<int>> y = x;
+}
+    ''');
+  }
+
   void test_futureThen_upwards() {
     // Regression test for https://github.com/dart-lang/sdk/issues/27088.
     String build({String declared, String downwards, String upwards}) => '''
@@ -1676,24 +1687,6 @@
     checkFile(build(downwards: "Future", upwards: "MyFuture"));
   }
 
-  void test_futureUnion_downwardsGenericMethods() {
-    // Regression test for https://github.com/dart-lang/sdk/issues/27134
-    //
-    // We need to take a future union into account for both directions of
-    // generic method inference.
-    checkFile(r'''
-import 'dart:async';
-
-foo() async {
-  Future<List<A>> f1 = null;
-  Future<List<A>> f2 = null;
-  List<List<A>> merged = await Future.wait(/*info:INFERRED_TYPE_LITERAL*/[f1, f2]);
-}
-
-class A {}
-    ''');
-  }
-
   void test_futureUnion_downwards() {
     String build({String declared, String downwards, String upwards}) {
       // TODO(leafp): The use of matchTypes in visitInstanceCreationExpression
@@ -1736,6 +1729,24 @@
         build(declared: "Future", downwards: "Future", upwards: "MyFuture"));
   }
 
+  void test_futureUnion_downwardsGenericMethods() {
+    // Regression test for https://github.com/dart-lang/sdk/issues/27134
+    //
+    // We need to take a future union into account for both directions of
+    // generic method inference.
+    checkFile(r'''
+import 'dart:async';
+
+foo() async {
+  Future<List<A>> f1 = null;
+  Future<List<A>> f2 = null;
+  List<List<A>> merged = await Future.wait(/*info:INFERRED_TYPE_LITERAL*/[f1, f2]);
+}
+
+class A {}
+    ''');
+  }
+
   void test_genericMethods_basicDownwardInference() {
     checkFile(r'''
 /*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
diff --git a/pkg/analyzer/tool/task_dependency_graph/tasks.dot b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
index 7cf3d9d..e6af229 100644
--- a/pkg/analyzer/tool/task_dependency_graph/tasks.dot
+++ b/pkg/analyzer/tool/task_dependency_graph/tasks.dot
@@ -48,24 +48,23 @@
   CREATED_RESOLVED_UNIT [shape=box]
   CREATED_RESOLVED_UNIT1 [shape=box]
   CREATED_RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+  CREATED_RESOLVED_UNIT10 -> InferStaticVariableTypeTask
+  CREATED_RESOLVED_UNIT10 -> PartiallyResolveUnitReferencesTask
+  CREATED_RESOLVED_UNIT10 -> ResolveInstanceFieldsInUnitTask
+  CREATED_RESOLVED_UNIT10 -> ResolveUnitTask
   CREATED_RESOLVED_UNIT10 [shape=box]
-  CREATED_RESOLVED_UNIT11 -> InferInstanceMembersInUnitTask
-  CREATED_RESOLVED_UNIT11 -> InferStaticVariableTypeTask
-  CREATED_RESOLVED_UNIT11 -> PartiallyResolveUnitReferencesTask
-  CREATED_RESOLVED_UNIT11 -> ResolveInstanceFieldsInUnitTask
-  CREATED_RESOLVED_UNIT11 -> ResolveUnitTask
+  CREATED_RESOLVED_UNIT11 -> ResolveConstantExpressionTask
   CREATED_RESOLVED_UNIT11 [shape=box]
-  CREATED_RESOLVED_UNIT12 -> ResolveConstantExpressionTask
   CREATED_RESOLVED_UNIT12 [shape=box]
-  CREATED_RESOLVED_UNIT13 [shape=box]
   CREATED_RESOLVED_UNIT2 [shape=box]
   CREATED_RESOLVED_UNIT3 [shape=box]
   CREATED_RESOLVED_UNIT4 [shape=box]
   CREATED_RESOLVED_UNIT5 [shape=box]
   CREATED_RESOLVED_UNIT6 [shape=box]
   CREATED_RESOLVED_UNIT7 [shape=box]
+  CREATED_RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
   CREATED_RESOLVED_UNIT8 [shape=box]
-  CREATED_RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+  CREATED_RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
   CREATED_RESOLVED_UNIT9 [shape=box]
   ComputeConstantDependenciesTask -> CONSTANT_DEPENDENCIES
   ComputeConstantValueTask -> CONSTANT_VALUE
@@ -73,7 +72,6 @@
   ComputeLibraryCycleTask -> LIBRARY_CYCLE
   ComputeLibraryCycleTask -> LIBRARY_CYCLE_DEPENDENCIES
   ComputeLibraryCycleTask -> LIBRARY_CYCLE_UNITS
-  ComputePropagableVariableDependenciesTask -> PROPAGABLE_VARIABLE_DEPENDENCIES
   ComputeRequiredConstantsTask -> PENDING_ERRORS
   ComputeRequiredConstantsTask -> REQUIRED_CONSTANTS
   ContainingLibrariesTask -> CONTAINING_LIBRARIES
@@ -86,14 +84,14 @@
   EXPORTED_LIBRARIES -> BuildDirectiveElementsTask
   EXPORTED_LIBRARIES -> ReadyLibraryElement2Task
   EXPORTED_LIBRARIES -> ReadyLibraryElement5Task
-  EXPORTED_LIBRARIES -> ReadyLibraryElement6Task
+  EXPORTED_LIBRARIES -> ReadyLibraryElement7Task
   EXPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
   EXPORTED_LIBRARIES [shape=box]
   EXPORT_SOURCE_CLOSURE -> BuildExportNamespaceTask
   EXPORT_SOURCE_CLOSURE -> ResolveTopLevelUnitTypeBoundsTask
   EXPORT_SOURCE_CLOSURE [shape=box]
-  EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT13
-  EvaluateUnitConstantsTask -> RESOLVED_UNIT13
+  EvaluateUnitConstantsTask -> CREATED_RESOLVED_UNIT12
+  EvaluateUnitConstantsTask -> RESOLVED_UNIT12
   GatherUsedImportedElementsTask -> USED_IMPORTED_ELEMENTS
   GatherUsedLocalElementsTask -> USED_LOCAL_ELEMENTS
   GenerateHintsTask -> HINTS
@@ -105,7 +103,7 @@
   IMPORTED_LIBRARIES -> BuildDirectiveElementsTask
   IMPORTED_LIBRARIES -> ReadyLibraryElement2Task
   IMPORTED_LIBRARIES -> ReadyLibraryElement5Task
-  IMPORTED_LIBRARIES -> ReadyLibraryElement6Task
+  IMPORTED_LIBRARIES -> ReadyLibraryElement7Task
   IMPORTED_LIBRARIES -> ResolveTopLevelLibraryTypeBoundsTask
   IMPORTED_LIBRARIES -> ResolveTopLevelUnitTypeBoundsTask
   IMPORTED_LIBRARIES [shape=box]
@@ -119,12 +117,12 @@
   INFERRED_STATIC_VARIABLE -> InferStaticVariableTypesInUnitTask
   INFERRED_STATIC_VARIABLE [shape=box]
   IS_LAUNCHABLE [shape=box]
-  InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT11
-  InferInstanceMembersInUnitTask -> RESOLVED_UNIT11
+  InferInstanceMembersInUnitTask -> CREATED_RESOLVED_UNIT10
+  InferInstanceMembersInUnitTask -> RESOLVED_UNIT10
   InferStaticVariableTypeTask -> INFERRED_STATIC_VARIABLE
   InferStaticVariableTypeTask -> STATIC_VARIABLE_RESOLUTION_ERRORS
-  InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT9
-  InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT9
+  InferStaticVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
+  InferStaticVariableTypesInUnitTask -> RESOLVED_UNIT8
   InferStaticVariableTypesInUnitTask -> STATIC_VARIABLE_RESOLUTION_ERRORS_IN_UNIT
   LIBRARY_CYCLE [shape=box]
   LIBRARY_CYCLE_DEPENDENCIES -> InferInstanceMembersInUnitTask
@@ -158,12 +156,12 @@
   LIBRARY_ELEMENT5 -> ResolveUnitTypeNamesTask
   LIBRARY_ELEMENT5 [shape=box]
   LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
-  LIBRARY_ELEMENT6 -> PropagateVariableTypesInLibraryTask
   LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
   LIBRARY_ELEMENT6 -> ResolveInstanceFieldsInUnitTask
+  LIBRARY_ELEMENT6 -> ResolvedUnit7InLibraryTask
   LIBRARY_ELEMENT6 [shape=box]
-  LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
-  LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+  LIBRARY_ELEMENT7 -> ReadyLibraryElement7Task
+  LIBRARY_ELEMENT7 -> ResolvedUnit7InLibraryClosureTask
   LIBRARY_ELEMENT7 [shape=box]
   LIBRARY_ELEMENT8 -> ResolveLibraryReferencesTask
   LIBRARY_ELEMENT8 -> ResolveUnitTask
@@ -173,11 +171,11 @@
   LIBRARY_ELEMENT9 [shape=box]
   LIBRARY_ERRORS_READY [shape=box]
   LIBRARY_SPECIFIC_UNITS -> GenerateHintsTask
-  LIBRARY_SPECIFIC_UNITS -> PropagateVariableTypesInLibraryTask
   LIBRARY_SPECIFIC_UNITS -> ReadyResolvedUnitTask
   LIBRARY_SPECIFIC_UNITS -> ResolveLibraryReferencesTask
   LIBRARY_SPECIFIC_UNITS -> ResolveLibraryTypeNamesTask
   LIBRARY_SPECIFIC_UNITS -> ResolveTopLevelLibraryTypeBoundsTask
+  LIBRARY_SPECIFIC_UNITS -> ResolvedUnit7InLibraryTask
   LIBRARY_SPECIFIC_UNITS [shape=box]
   LIBRARY_UNIT_ERRORS -> dartErrorsForUnit
   LIBRARY_UNIT_ERRORS [shape=box]
@@ -200,13 +198,6 @@
   PARSE_ERRORS [shape=box]
   PENDING_ERRORS -> VerifyUnitTask
   PENDING_ERRORS [shape=box]
-  PROPAGABLE_VARIABLES_IN_UNIT -> PropagateVariableTypesInUnitTask
-  PROPAGABLE_VARIABLES_IN_UNIT [shape=box]
-  PROPAGABLE_VARIABLE_DEPENDENCIES -> PropagateVariableTypeTask
-  PROPAGABLE_VARIABLE_DEPENDENCIES [shape=box]
-  PROPAGATED_VARIABLE -> PropagateVariableTypeTask
-  PROPAGATED_VARIABLE -> PropagateVariableTypesInUnitTask
-  PROPAGATED_VARIABLE [shape=box]
   ParseDartTask -> EXPLICITLY_IMPORTED_LIBRARIES
   ParseDartTask -> EXPORTED_LIBRARIES
   ParseDartTask -> IMPORTED_LIBRARIES
@@ -220,21 +211,15 @@
   ParseDartTask -> UNITS
   PartiallyResolveUnitReferencesTask -> CREATED_RESOLVED_UNIT7
   PartiallyResolveUnitReferencesTask -> INFERABLE_STATIC_VARIABLES_IN_UNIT
-  PartiallyResolveUnitReferencesTask -> PROPAGABLE_VARIABLES_IN_UNIT
   PartiallyResolveUnitReferencesTask -> RESOLVED_UNIT7
-  PropagateVariableTypeTask -> PROPAGATED_VARIABLE
-  PropagateVariableTypesInLibraryClosureTask -> LIBRARY_ELEMENT8
-  PropagateVariableTypesInLibraryTask -> LIBRARY_ELEMENT7
-  PropagateVariableTypesInUnitTask -> CREATED_RESOLVED_UNIT8
-  PropagateVariableTypesInUnitTask -> RESOLVED_UNIT8
   READY_LIBRARY_ELEMENT2 -> ComputeLibraryCycleTask
   READY_LIBRARY_ELEMENT2 -> ReadyLibraryElement2Task
   READY_LIBRARY_ELEMENT2 [shape=box]
   READY_LIBRARY_ELEMENT6 -> PartiallyResolveUnitReferencesTask
   READY_LIBRARY_ELEMENT6 -> ReadyLibraryElement5Task
   READY_LIBRARY_ELEMENT6 [shape=box]
-  READY_LIBRARY_ELEMENT7 -> PropagateVariableTypesInLibraryClosureTask
-  READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement6Task
+  READY_LIBRARY_ELEMENT7 -> ReadyLibraryElement7Task
+  READY_LIBRARY_ELEMENT7 -> ResolvedUnit7InLibraryClosureTask
   READY_LIBRARY_ELEMENT7 [shape=box]
   READY_RESOLVED_UNIT -> ResolveLibraryTask
   READY_RESOLVED_UNIT -> VerifyUnitTask
@@ -255,17 +240,15 @@
   RESOLVED_UNIT1 -> BuildLibraryElementTask
   RESOLVED_UNIT1 -> ResolveDirectiveElementsTask
   RESOLVED_UNIT1 [shape=box]
-  RESOLVED_UNIT10 -> InferInstanceMembersInUnitTask
+  RESOLVED_UNIT10 -> ResolveUnitTask
   RESOLVED_UNIT10 [shape=box]
-  RESOLVED_UNIT11 -> ResolveUnitTask
+  RESOLVED_UNIT11 -> EvaluateUnitConstantsTask
+  RESOLVED_UNIT11 -> GatherUsedImportedElementsTask
+  RESOLVED_UNIT11 -> GatherUsedLocalElementsTask
+  RESOLVED_UNIT11 -> ResolveLibraryReferencesTask
   RESOLVED_UNIT11 [shape=box]
-  RESOLVED_UNIT12 -> EvaluateUnitConstantsTask
-  RESOLVED_UNIT12 -> GatherUsedImportedElementsTask
-  RESOLVED_UNIT12 -> GatherUsedLocalElementsTask
-  RESOLVED_UNIT12 -> ResolveLibraryReferencesTask
+  RESOLVED_UNIT12 -> StrongModeVerifyUnitTask
   RESOLVED_UNIT12 [shape=box]
-  RESOLVED_UNIT13 -> StrongModeVerifyUnitTask
-  RESOLVED_UNIT13 [shape=box]
   RESOLVED_UNIT2 -> BuildEnumMemberElementsTask
   RESOLVED_UNIT2 [shape=box]
   RESOLVED_UNIT3 -> ResolveTopLevelUnitTypeBoundsTask
@@ -279,15 +262,13 @@
   RESOLVED_UNIT6 -> PartiallyResolveUnitReferencesTask
   RESOLVED_UNIT6 [shape=box]
   RESOLVED_UNIT7 -> ComputeInferableStaticVariableDependenciesTask
-  RESOLVED_UNIT7 -> ComputePropagableVariableDependenciesTask
-  RESOLVED_UNIT7 -> PropagateVariableTypeTask
-  RESOLVED_UNIT7 -> PropagateVariableTypesInUnitTask
+  RESOLVED_UNIT7 -> InferStaticVariableTypeTask
+  RESOLVED_UNIT7 -> InferStaticVariableTypesInUnitTask
+  RESOLVED_UNIT7 -> ResolvedUnit7InLibraryTask
   RESOLVED_UNIT7 [shape=box]
-  RESOLVED_UNIT8 -> InferStaticVariableTypeTask
-  RESOLVED_UNIT8 -> InferStaticVariableTypesInUnitTask
-  RESOLVED_UNIT8 -> PropagateVariableTypesInLibraryTask
+  RESOLVED_UNIT8 -> ResolveInstanceFieldsInUnitTask
   RESOLVED_UNIT8 [shape=box]
-  RESOLVED_UNIT9 -> ResolveInstanceFieldsInUnitTask
+  RESOLVED_UNIT9 -> InferInstanceMembersInUnitTask
   RESOLVED_UNIT9 [shape=box]
   RESOLVE_TYPE_BOUNDS_ERRORS -> LibraryUnitErrorsTask
   RESOLVE_TYPE_BOUNDS_ERRORS [shape=box]
@@ -297,13 +278,13 @@
   RESOLVE_UNIT_ERRORS [shape=box]
   ReadyLibraryElement2Task -> READY_LIBRARY_ELEMENT2
   ReadyLibraryElement5Task -> READY_LIBRARY_ELEMENT6
-  ReadyLibraryElement6Task -> READY_LIBRARY_ELEMENT7
+  ReadyLibraryElement7Task -> READY_LIBRARY_ELEMENT7
   ReadyResolvedUnitTask -> READY_RESOLVED_UNIT
   ResolveConstantExpressionTask -> CONSTANT_EXPRESSION_RESOLVED
   ResolveDirectiveElementsTask -> CREATED_RESOLVED_UNIT2
   ResolveDirectiveElementsTask -> RESOLVED_UNIT2
-  ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT10
-  ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT10
+  ResolveInstanceFieldsInUnitTask -> CREATED_RESOLVED_UNIT9
+  ResolveInstanceFieldsInUnitTask -> RESOLVED_UNIT9
   ResolveLibraryReferencesTask -> LIBRARY_ELEMENT9
   ResolveLibraryTask -> LIBRARY_ELEMENT
   ResolveLibraryTypeNamesTask -> LIBRARY_ELEMENT6
@@ -312,8 +293,8 @@
   ResolveTopLevelUnitTypeBoundsTask -> RESOLVED_UNIT4
   ResolveTopLevelUnitTypeBoundsTask -> RESOLVE_TYPE_BOUNDS_ERRORS
   ResolveUnitTask -> CONSTANT_EXPRESSIONS_DEPENDENCIES
-  ResolveUnitTask -> CREATED_RESOLVED_UNIT12
-  ResolveUnitTask -> RESOLVED_UNIT12
+  ResolveUnitTask -> CREATED_RESOLVED_UNIT11
+  ResolveUnitTask -> RESOLVED_UNIT11
   ResolveUnitTask -> RESOLVE_UNIT_ERRORS
   ResolveUnitTypeNamesTask -> CREATED_RESOLVED_UNIT5
   ResolveUnitTypeNamesTask -> RESOLVED_UNIT5
@@ -321,6 +302,8 @@
   ResolveVariableReferencesTask -> CREATED_RESOLVED_UNIT6
   ResolveVariableReferencesTask -> RESOLVED_UNIT6
   ResolveVariableReferencesTask -> VARIABLE_REFERENCE_ERRORS
+  ResolvedUnit7InLibraryClosureTask -> LIBRARY_ELEMENT8
+  ResolvedUnit7InLibraryTask -> LIBRARY_ELEMENT7
   SCAN_ERRORS -> dartErrorsForSource
   SCAN_ERRORS [shape=box]
   SOURCE_KIND -> BuildDirectiveElementsTask
@@ -347,7 +330,6 @@
   TYPE_PROVIDER -> InferInstanceMembersInUnitTask
   TYPE_PROVIDER -> InferStaticVariableTypeTask
   TYPE_PROVIDER -> PartiallyResolveUnitReferencesTask
-  TYPE_PROVIDER -> PropagateVariableTypeTask
   TYPE_PROVIDER -> ResolveInstanceFieldsInUnitTask
   TYPE_PROVIDER -> ResolveLibraryTypeNamesTask
   TYPE_PROVIDER -> ResolveTopLevelUnitTypeBoundsTask
diff --git a/pkg/compiler/lib/src/kernel/kernel_visitor.dart b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
index 68945d0..8c81f19 100644
--- a/pkg/compiler/lib/src/kernel/kernel_visitor.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_visitor.dart
@@ -205,6 +205,8 @@
     return node;
   }
 
+  final Map<ir.Node, Node> nodeToAst = <ir.Node, Node>{};
+
   bool isVoidContext = false;
 
   KernelVisitor(this.currentElement, this.elements, this.kernel);
@@ -898,7 +900,9 @@
 
   @override
   ir.SymbolLiteral visitLiteralSymbol(LiteralSymbol node) {
-    return new ir.SymbolLiteral(node.slowNameString);
+    var result = new ir.SymbolLiteral(node.slowNameString);
+    nodeToAst[result] = node;
+    return result;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ssa/builder.dart b/pkg/compiler/lib/src/ssa/builder.dart
index e44ebf3..83f22ab 100644
--- a/pkg/compiler/lib/src/ssa/builder.dart
+++ b/pkg/compiler/lib/src/ssa/builder.dart
@@ -417,9 +417,6 @@
 
   Map<JumpTarget, JumpHandler> jumpTargets = <JumpTarget, JumpHandler>{};
 
-  // We build the Ssa graph by simulating a stack machine.
-  List<HInstruction> stack = <HInstruction>[];
-
   /// Returns `true` if the current element is an `async` function.
   bool get isBuildingAsyncFunction {
     Element element = sourceElement;
@@ -1906,23 +1903,10 @@
     return graph;
   }
 
-  void push(HInstruction instruction) {
-    add(instruction);
-    stack.add(instruction);
-  }
-
   void pushWithPosition(HInstruction instruction, ast.Node node) {
     push(attachPosition(instruction, node));
   }
 
-  HInstruction pop() {
-    return stack.removeLast();
-  }
-
-  void dup() {
-    stack.add(stack.last);
-  }
-
   HInstruction popBoolified() {
     HInstruction value = pop();
     if (_checkOrTrustTypes) {
@@ -4915,7 +4899,7 @@
       instruction = new HInvokeStatic(element.declaration, arguments, typeMask,
           targetCanThrow: targetCanThrow)
         ..sourceInformation = sourceInformation;
-      if (!currentInlinedInstantiations.isEmpty) {
+      if (currentInlinedInstantiations.isNotEmpty) {
         instruction.instantiatedTypes =
             new List<DartType>.from(currentInlinedInstantiations);
       }
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index a44ea37..9c91c0f 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -4,16 +4,21 @@
 
 import 'package:kernel/ast.dart' as ir;
 
-import '../common/codegen.dart' show CodegenWorkItem;
+import '../common/codegen.dart' show CodegenRegistry, CodegenWorkItem;
 import '../common/tasks.dart' show CompilerTask;
 import '../compiler.dart';
+import '../diagnostics/spannable.dart';
 import '../elements/elements.dart';
 import '../io/source_information.dart';
 import '../js_backend/backend.dart' show JavaScriptBackend;
 import '../kernel/kernel.dart';
 import '../kernel/kernel_visitor.dart';
 import '../resolution/tree_elements.dart';
+import '../tree/dartstring.dart';
+import '../types/masks.dart';
+
 import 'graph_builder.dart';
+import 'kernel_ast_adapter.dart';
 import 'locals_handler.dart';
 import 'nodes.dart';
 
@@ -44,8 +49,10 @@
           element,
           work.resolvedAst,
           backend.compiler,
+          work.registry,
           sourceInformationFactory,
-          visitor.nodeToElement);
+          visitor,
+          kernel);
       return builder.build();
     });
   }
@@ -56,20 +63,23 @@
   final FunctionElement functionElement;
   final ResolvedAst resolvedAst;
   final Compiler compiler;
-  final Map<ir.Node, Element> nodeToElement;
+  final CodegenRegistry registry;
 
   JavaScriptBackend get backend => compiler.backend;
 
   LocalsHandler localsHandler;
   SourceInformationBuilder sourceInformationBuilder;
+  KernelAstAdapter astAdapter;
 
   KernelSsaBuilder(
       this.function,
       this.functionElement,
       this.resolvedAst,
       this.compiler,
+      this.registry,
       SourceInformationStrategy sourceInformationFactory,
-      this.nodeToElement) {
+      KernelVisitor visitor,
+      Kernel kernel) {
     graph.element = functionElement;
     // TODO(het): Should sourceInformationBuilder be in GraphBuilder?
     this.sourceInformationBuilder =
@@ -78,6 +88,8 @@
         sourceInformationBuilder.buildVariableDeclaration();
     this.localsHandler =
         new LocalsHandler(this, functionElement, null, compiler);
+    this.astAdapter = new KernelAstAdapter(compiler.backend, resolvedAst,
+        visitor.nodeToAst, visitor.nodeToElement, kernel.functions);
   }
 
   HGraph build() {
@@ -116,4 +128,111 @@
     if (!isAborted()) closeAndGotoExit(new HGoto());
     graph.finalize();
   }
+
+  @override
+  void visitBlock(ir.Block block) {
+    assert(!isAborted());
+    for (ir.Statement statement in block.statements) {
+      statement.accept(this);
+      if (!isReachable) {
+        // The block has been aborted by a return or a throw.
+        if (stack.isNotEmpty) {
+          compiler.reporter.internalError(
+              NO_LOCATION_SPANNABLE, 'Non-empty instruction stack.');
+        }
+        return;
+      }
+    }
+    assert(!current.isClosed());
+    if (stack.isNotEmpty) {
+      compiler.reporter
+          .internalError(NO_LOCATION_SPANNABLE, 'Non-empty instruction stack');
+    }
+  }
+
+  @override
+  void visitReturnStatement(ir.ReturnStatement returnStatement) {
+    HInstruction value;
+    if (returnStatement.expression == null) {
+      value = graph.addConstantNull(compiler);
+    } else {
+      returnStatement.expression.accept(this);
+      value = pop();
+      // TODO(het): Check or trust the type of value
+    }
+    // TODO(het): Add source information
+    // TODO(het): Set a return value instead of closing the function when we
+    // support inlining.
+    closeAndGotoExit(new HReturn(value, null));
+  }
+
+  @override
+  void visitIntLiteral(ir.IntLiteral intLiteral) {
+    stack.add(graph.addConstantInt(intLiteral.value, compiler));
+  }
+
+  @override
+  visitDoubleLiteral(ir.DoubleLiteral doubleLiteral) {
+    stack.add(graph.addConstantDouble(doubleLiteral.value, compiler));
+  }
+
+  @override
+  visitBoolLiteral(ir.BoolLiteral boolLiteral) {
+    stack.add(graph.addConstantBool(boolLiteral.value, compiler));
+  }
+
+  @override
+  visitStringLiteral(ir.StringLiteral stringLiteral) {
+    stack.add(graph.addConstantString(
+        new DartString.literal(stringLiteral.value), compiler));
+  }
+
+  @override
+  visitSymbolLiteral(ir.SymbolLiteral symbolLiteral) {
+    stack.add(graph.addConstant(
+        astAdapter.getConstantForSymbol(symbolLiteral), compiler));
+    registry?.registerConstSymbol(symbolLiteral.value);
+  }
+
+  @override
+  visitNullLiteral(ir.NullLiteral nullLiteral) {
+    stack.add(graph.addConstantNull(compiler));
+  }
+
+  @override
+  visitVariableGet(ir.VariableGet variableGet) {
+    LocalElement local = astAdapter.getElement(variableGet.variable);
+    stack.add(localsHandler.readLocal(local));
+  }
+
+  @override
+  visitStaticInvocation(ir.StaticInvocation invocation) {
+    List<HInstruction> inputs = <HInstruction>[];
+
+    for (ir.Expression argument in invocation.arguments.positional) {
+      argument.accept(this);
+      inputs.add(pop());
+    }
+    for (ir.NamedExpression argument in invocation.arguments.named) {
+      argument.value.accept(this);
+      inputs.add(pop());
+    }
+
+    ir.Procedure target = invocation.target;
+    bool targetCanThrow = astAdapter.getCanThrow(target);
+    TypeMask typeMask = astAdapter.returnTypeOf(target);
+
+    HInstruction instruction = new HInvokeStatic(
+        astAdapter.getElement(target).declaration, inputs, typeMask,
+        targetCanThrow: targetCanThrow);
+    instruction.sideEffects = astAdapter.getSideEffects(target);
+
+    push(instruction);
+  }
+
+  @override
+  visitExpressionStatement(ir.ExpressionStatement exprStatement) {
+    exprStatement.expression.accept(this);
+    pop();
+  }
 }
diff --git a/pkg/compiler/lib/src/ssa/graph_builder.dart b/pkg/compiler/lib/src/ssa/graph_builder.dart
index 969899f..1c4c689 100644
--- a/pkg/compiler/lib/src/ssa/graph_builder.dart
+++ b/pkg/compiler/lib/src/ssa/graph_builder.dart
@@ -14,6 +14,25 @@
   /// Holds the resulting SSA graph.
   final HGraph graph = new HGraph();
 
+  /// A stack of instructions.
+  ///
+  /// We build the SSA graph by simulating a stack machine.
+  List<HInstruction> stack = <HInstruction>[];
+
+
+  void push(HInstruction instruction) {
+    add(instruction);
+    stack.add(instruction);
+  }
+
+  HInstruction pop() {
+    return stack.removeLast();
+  }
+
+  void dup() {
+    stack.add(stack.last);
+  }
+
   HBasicBlock _current;
 
   /// The current block to add instructions to. Might be null, if we are
diff --git a/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
new file mode 100644
index 0000000..2076899
--- /dev/null
+++ b/pkg/compiler/lib/src/ssa/kernel_ast_adapter.dart
@@ -0,0 +1,61 @@
+// 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 'package:kernel/ast.dart' as ir;
+
+import '../constants/values.dart';
+import '../diagnostics/invariant.dart';
+import '../elements/elements.dart';
+import '../js_backend/js_backend.dart';
+import '../tree/tree.dart' as ast;
+import '../types/masks.dart';
+import '../universe/side_effects.dart';
+
+import 'types.dart';
+
+/// A helper class that abstracts all accesses of the AST from Kernel nodes.
+///
+/// The goal is to remove all need for the AST from the Kernel SSA builder.
+class KernelAstAdapter {
+  final JavaScriptBackend _backend;
+  final ResolvedAst _resolvedAst;
+  final Map<ir.Node, ast.Node> _nodeToAst;
+  final Map<ir.Node, Element> _nodeToElement;
+
+  KernelAstAdapter(this._backend, this._resolvedAst, this._nodeToAst,
+      this._nodeToElement, Map<FunctionElement, ir.Member> functions) {
+    for (FunctionElement functionElement in functions.keys) {
+      _nodeToElement[functions[functionElement]] = functionElement;
+    }
+  }
+
+  ConstantValue getConstantForSymbol(ir.SymbolLiteral node) {
+    ast.Node astNode = _nodeToAst[node];
+    ConstantValue constantValue = _backend.constants
+        .getConstantValueForNode(astNode, _resolvedAst.elements);
+    assert(invariant(astNode, constantValue != null,
+        message: 'No constant computed for $node'));
+    return constantValue;
+  }
+
+  Element getElement(ir.Node node) {
+    Element result = _nodeToElement[node];
+    assert(result != null);
+    return result;
+  }
+
+  bool getCanThrow(ir.Procedure procedure) {
+    FunctionElement function = getElement(procedure);
+    return !_backend.compiler.world.getCannotThrow(function);
+  }
+
+  TypeMask returnTypeOf(ir.Procedure node) {
+    return TypeMaskFactory.inferredReturnTypeForElement(
+        getElement(node), _backend.compiler);
+  }
+
+  SideEffects getSideEffects(ir.Node node) {
+    return _backend.compiler.world.getSideEffectsOfElement(getElement(node));
+  }
+}
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index 6ed6aef..929cb77 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -1262,8 +1262,9 @@
     HBasicBlock otherBlock = other.block;
     for (int i = 0, length = usedBy.length; i < length; i++) {
       HInstruction current = usedBy[i];
-      if (otherBlock.dominates(current.block)) {
-        if (identical(current.block, otherBlock)) usersInCurrentBlock++;
+      HBasicBlock currentBlock = current.block;
+      if (otherBlock.dominates(currentBlock)) {
+        if (identical(currentBlock, otherBlock)) usersInCurrentBlock++;
         users.add(current);
       }
     }
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 7564176..298d928 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -361,31 +361,47 @@
     TypeMask receiverType = receiver.instructionType;
     instruction.mask = receiverType;
 
-    // Try to specialize the receiver after this call.
-    if (receiver.dominatedUsers(instruction).length != 1 &&
-        !instruction.selector.isClosureCall) {
-      TypeMask newType = compiler.world.allFunctions
-          .receiverType(instruction.selector, instruction.mask);
-      newType = newType.intersection(receiverType, classWorld);
+    // Try to specialize the receiver after this call by instering a refinement
+    // node (HTypeKnown). There are two potentially expensive tests - are there
+    // any uses of the receiver dominated by and following this call?, and what
+    // is the refined type? The first is expensive if the receiver has many
+    // uses, the second is expensive if many classes implement the selector. So
+    // we try to do the least expensive test first.
+    const int _MAX_QUICK_USERS = 50;
+    if (!instruction.selector.isClosureCall) {
+      TypeMask newType;
+      TypeMask computeNewType() {
+        newType = compiler.world.allFunctions
+            .receiverType(instruction.selector, instruction.mask);
+        newType = newType.intersection(receiverType, classWorld);
+        return newType;
+      }
+
       var next = instruction.next;
       if (next is HTypeKnown && next.checkedInput == receiver) {
-        // We already have refined [receiver]. We still update the
-        // type of the [HTypeKnown] instruction because it may have
-        // been refined with a correct type at the time, but
-        // incorrect now.
-        if (next.instructionType != newType) {
+        // On a previous pass or iteration we already refined [receiver] by
+        // inserting a [HTypeKnown] instruction. That replaced several dominated
+        // uses with the refinement. We update the type of the [HTypeKnown]
+        // instruction because it may have been refined with a correct type at
+        // the time, but incorrect now.
+        if (next.instructionType != computeNewType()) {
           next.knownType = next.instructionType = newType;
           addDependentInstructionsToWorkList(next);
         }
-      } else if (newType != receiverType) {
-        // Insert a refinement node after the call and update all
-        // users dominated by the call to use that node instead of
-        // [receiver].
-        HTypeKnown converted =
-            new HTypeKnown.witnessed(newType, receiver, instruction);
-        instruction.block.addBefore(instruction.next, converted);
-        receiver.replaceAllUsersDominatedBy(converted.next, converted);
-        addDependentInstructionsToWorkList(converted);
+      } else {
+        bool hasCandidates() => receiver.dominatedUsers(instruction).length > 1;
+
+        if ((receiver.usedBy.length <= _MAX_QUICK_USERS)
+            ? (hasCandidates() && computeNewType() != receiverType)
+            : (computeNewType() != receiverType && hasCandidates())) {
+          // Insert a refinement node after the call and update all users
+          // dominated by the call to use that node instead of [receiver].
+          HTypeKnown converted =
+              new HTypeKnown.witnessed(newType, receiver, instruction);
+          instruction.block.addBefore(instruction.next, converted);
+          receiver.replaceAllUsersDominatedBy(converted.next, converted);
+          addDependentInstructionsToWorkList(converted);
+        }
       }
     }
 
diff --git a/pkg/compiler/lib/src/types/flat_type_mask.dart b/pkg/compiler/lib/src/types/flat_type_mask.dart
index f38c6f6..59b573a 100644
--- a/pkg/compiler/lib/src/types/flat_type_mask.dart
+++ b/pkg/compiler/lib/src/types/flat_type_mask.dart
@@ -681,19 +681,20 @@
         subclassesToCheck.any(needsNoSuchMethod);
   }
 
-  Element locateSingleElement(
-      Selector selector, TypeMask mask, Compiler compiler) {
+  Element locateSingleElement(Selector selector, Compiler compiler) {
     if (isEmptyOrNull) return null;
     Iterable<Element> targets =
-        compiler.world.allFunctions.filter(selector, mask);
+        compiler.world.allFunctions.filter(selector, this);
     if (targets.length != 1) return null;
     Element result = targets.first;
     ClassElement enclosing = result.enclosingClass;
-    // We only return the found element if it is guaranteed to be
-    // implemented on the exact receiver type. It could be found in a
-    // subclass or in an inheritance-wise unrelated class in case of
-    // subtype selectors.
-    return (base.isSubclassOf(enclosing)) ? result : null;
+    // We only return the found element if it is guaranteed to be implemented on
+    // all classes in the receiver type [this]. It could be found only in a
+    // subclass or in an inheritance-wise unrelated class in case of subtype
+    // selectors.
+    if (isSubtype) return null;
+    if (base.isSubclassOf(enclosing)) return result;
+    return null;
   }
 
   bool operator ==(var other) {
diff --git a/pkg/compiler/lib/src/types/forwarding_type_mask.dart b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
index bc9ce15..d886e99 100644
--- a/pkg/compiler/lib/src/types/forwarding_type_mask.dart
+++ b/pkg/compiler/lib/src/types/forwarding_type_mask.dart
@@ -101,9 +101,8 @@
     return forwardTo.canHit(element, selector, classWorld);
   }
 
-  Element locateSingleElement(
-      Selector selector, TypeMask mask, Compiler compiler) {
-    return forwardTo.locateSingleElement(selector, mask, compiler);
+  Element locateSingleElement(Selector selector, Compiler compiler) {
+    return forwardTo.locateSingleElement(selector, compiler);
   }
 
   bool equalsDisregardNull(other) {
diff --git a/pkg/compiler/lib/src/types/type_mask.dart b/pkg/compiler/lib/src/types/type_mask.dart
index 698d87e..d14bd95 100644
--- a/pkg/compiler/lib/src/types/type_mask.dart
+++ b/pkg/compiler/lib/src/types/type_mask.dart
@@ -358,6 +358,5 @@
    * on this mask. Returns null if there is none.
    */
   // TODO(johnniwinther): Move this method to [World].
-  Element locateSingleElement(
-      Selector selector, TypeMask mask, Compiler compiler);
+  Element locateSingleElement(Selector selector, Compiler compiler);
 }
diff --git a/pkg/compiler/lib/src/types/union_type_mask.dart b/pkg/compiler/lib/src/types/union_type_mask.dart
index 0f96e10..32e4e2a 100644
--- a/pkg/compiler/lib/src/types/union_type_mask.dart
+++ b/pkg/compiler/lib/src/types/union_type_mask.dart
@@ -331,11 +331,10 @@
     return disjointMasks.any((e) => e.canHit(element, selector, classWorld));
   }
 
-  Element locateSingleElement(
-      Selector selector, TypeMask mask, Compiler compiler) {
+  Element locateSingleElement(Selector selector, Compiler compiler) {
     Element candidate;
     for (FlatTypeMask mask in disjointMasks) {
-      Element current = mask.locateSingleElement(selector, mask, compiler);
+      Element current = mask.locateSingleElement(selector, compiler);
       if (current == null) {
         return null;
       } else if (candidate == null) {
diff --git a/pkg/compiler/lib/src/world.dart b/pkg/compiler/lib/src/world.dart
index 19fb9a2..88cd294 100644
--- a/pkg/compiler/lib/src/world.dart
+++ b/pkg/compiler/lib/src/world.dart
@@ -727,7 +727,7 @@
 
   Element locateSingleElement(Selector selector, TypeMask mask) {
     mask ??= compiler.commonMasks.dynamicType;
-    return mask.locateSingleElement(selector, mask, compiler);
+    return mask.locateSingleElement(selector, compiler);
   }
 
   TypeMask extendMaskIfReachesAll(Selector selector, TypeMask mask) {
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 49825b6..4fcaa30 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -568,6 +568,7 @@
     ]
     libs = [
       "launchpad",
+      "magenta",
       "runtime",
     ]
   }
diff --git a/runtime/bin/directory_fuchsia.cc b/runtime/bin/directory_fuchsia.cc
index 1e374d1..1593ff7 100644
--- a/runtime/bin/directory_fuchsia.cc
+++ b/runtime/bin/directory_fuchsia.cc
@@ -143,38 +143,89 @@
 
 
 bool Directory::SetCurrent(const char* path) {
-  UNIMPLEMENTED();
-  return false;
+  return (NO_RETRY_EXPECTED(chdir(path)) == 0);
 }
 
 
 bool Directory::Create(const char* dir_name) {
-  UNIMPLEMENTED();
-  return false;
+  // Create the directory with the permissions specified by the
+  // process umask.
+  int result = NO_RETRY_EXPECTED(mkdir(dir_name, 0777));
+  // If the directory already exists, treat it as a success.
+  if ((result == -1) && (errno == EEXIST)) {
+    return (Exists(dir_name) == EXISTS);
+  }
+  return (result == 0);
 }
 
 
 const char* Directory::SystemTemp() {
-  UNIMPLEMENTED();
-  return NULL;
+  PathBuffer path;
+  const char* temp_dir = getenv("TMPDIR");
+  if (temp_dir == NULL) {
+    temp_dir = getenv("TMP");
+  }
+  if (temp_dir == NULL) {
+    temp_dir = "/tmp";
+  }
+  if (!path.Add(temp_dir)) {
+    return NULL;
+  }
+
+  // Remove any trailing slash.
+  char* result = path.AsString();
+  int length = strlen(result);
+  if ((length > 1) && (result[length - 1] == '/')) {
+    result[length - 1] = '\0';
+  }
+  return path.AsScopedString();
 }
 
 
 const char* Directory::CreateTemp(const char* prefix) {
-  UNIMPLEMENTED();
-  return NULL;
+  // Returns a new, unused directory name, adding characters to the end
+  // of prefix.  Creates the directory with the permissions specified
+  // by the process umask.
+  // The return value is Dart_ScopeAllocated.
+  PathBuffer path;
+  if (!path.Add(prefix)) {
+    return NULL;
+  }
+  if (!path.Add("XXXXXX")) {
+    // Pattern has overflowed.
+    return NULL;
+  }
+  char* result;
+  do {
+    result = mkdtemp(path.AsString());
+  } while ((result == NULL) && (errno == EINTR));
+  if (result == NULL) {
+    return NULL;
+  }
+  return path.AsScopedString();
 }
 
 
 bool Directory::Delete(const char* dir_name, bool recursive) {
-  UNIMPLEMENTED();
-  return false;
+  if (!recursive) {
+    if ((File::GetType(dir_name, false) == File::kIsLink) &&
+        (File::GetType(dir_name, true) == File::kIsDirectory)) {
+      return NO_RETRY_EXPECTED(unlink(dir_name)) == 0;
+    }
+    return NO_RETRY_EXPECTED(rmdir(dir_name)) == 0;
+  } else {
+    UNIMPLEMENTED();
+    return false;
+  }
 }
 
 
 bool Directory::Rename(const char* path, const char* new_path) {
-  UNIMPLEMENTED();
-  return false;
+  ExistsResult exists = Exists(path);
+  if (exists != EXISTS) {
+    return false;
+  }
+  return (NO_RETRY_EXPECTED(rename(path, new_path)) == 0);
 }
 
 }  // namespace bin
diff --git a/runtime/bin/directory_test.cc b/runtime/bin/directory_test.cc
index d5b8175..35c0d22 100644
--- a/runtime/bin/directory_test.cc
+++ b/runtime/bin/directory_test.cc
@@ -28,8 +28,7 @@
   const char* current = dart::bin::Directory::Current();
   EXPECT_NOTNULL(current);
 
-  dart::bin::Directory::ExistsResult r =
-      dart::bin::Directory::Exists(current);
+  dart::bin::Directory::ExistsResult r = dart::bin::Directory::Exists(current);
   EXPECT_EQ(dart::bin::Directory::EXISTS, r);
 }
 
@@ -40,6 +39,16 @@
 }
 
 
+TEST_CASE(DirectorySystemTempExists) {
+  const char* system_temp = dart::bin::Directory::SystemTemp();
+  EXPECT_NOTNULL(system_temp);
+
+  dart::bin::Directory::ExistsResult r =
+      dart::bin::Directory::Exists(system_temp);
+  EXPECT_EQ(dart::bin::Directory::EXISTS, r);
+}
+
+
 TEST_CASE(DirectoryCreateTemp) {
   const char* kTempPrefix = "test_prefix";
   const char* system_temp = dart::bin::Directory::SystemTemp();
@@ -75,7 +84,7 @@
 
 
 TEST_CASE(DirectoryCreateDelete) {
-  const char* kTempDirName = "test_name";
+  const char* kTempDirName = "create_delete_test_name";
 
   const char* system_temp = dart::bin::Directory::SystemTemp();
   EXPECT_NOTNULL(system_temp);
@@ -100,7 +109,7 @@
 
 
 TEST_CASE(DirectoryRename) {
-  const char* kTempDirName = "test_name";
+  const char* kTempDirName = "rename_test_name";
 
   const char* system_temp = dart::bin::Directory::SystemTemp();
   EXPECT_NOTNULL(system_temp);
diff --git a/runtime/bin/loader.cc b/runtime/bin/loader.cc
index 2220478..122e851 100644
--- a/runtime/bin/loader.cc
+++ b/runtime/bin/loader.cc
@@ -667,6 +667,7 @@
   }
   // All cases should have been handled above.
   UNREACHABLE();
+  return Dart_Null();
 }
 
 
diff --git a/runtime/bin/run_vm_tests_fuchsia.cc b/runtime/bin/run_vm_tests_fuchsia.cc
index b75881d..35eee46 100644
--- a/runtime/bin/run_vm_tests_fuchsia.cc
+++ b/runtime/bin/run_vm_tests_fuchsia.cc
@@ -104,6 +104,11 @@
 const char* kBugs[] = {
   // Needs NativeSymbolResolver
   "Service_PersistentHandles",
+  // Needs lstat
+  "DirectoryCreateTemp",
+  "DirectoryCreateDelete",
+  // Needs rename
+  "DirectoryRename",
 };
 
 
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 43186d1..c237c9e 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -59,8 +59,10 @@
         Uint8List cstring = result[0];
         socket.addUtf8Text(cstring);
       }
-    } catch (_) {
+    } catch (e, st) {
       print("Ignoring error posting over WebSocket.");
+      print(e);
+      print(st);
     }
   }
 
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 42ba0f2..9ea762d 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -586,13 +586,6 @@
     Dart_GcPrologueCallback prologue_callback,
     Dart_GcEpilogueCallback epilogue_callback);
 
-typedef void (*Dart_GcPrologueWeakHandleCallback)(void* isolate_callback_data,
-                                                  Dart_WeakPersistentHandle obj,
-                                                  intptr_t num_native_fields,
-                                                  intptr_t* native_fields);
-
-DART_EXPORT Dart_Handle Dart_VisitPrologueWeakHandles(
-    Dart_GcPrologueWeakHandleCallback callback);
 
 /*
  * ==========================
diff --git a/runtime/lib/internal_patch.dart b/runtime/lib/internal_patch.dart
index 24f31de..d19430f 100644
--- a/runtime/lib/internal_patch.dart
+++ b/runtime/lib/internal_patch.dart
@@ -32,10 +32,6 @@
   static var platformScript;
 }
 
-@patch class CodeUnits {
-  static final int cid = ClassID.getID(new CodeUnits(""));
-}
-
 final bool is64Bit = _inquireIs64Bit();
 
 bool _inquireIs64Bit() native "Internal_inquireIs64Bit";
diff --git a/runtime/lib/typed_data.dart b/runtime/lib/typed_data.dart
index d8b4324..c010555 100644
--- a/runtime/lib/typed_data.dart
+++ b/runtime/lib/typed_data.dart
@@ -1273,7 +1273,7 @@
   }
 
   void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
-    if (ClassID.getID(iterable) == CodeUnits.cid) {
+    if (iterable is CodeUnits) {
       end = RangeError.checkValidRange(start, end, this.length);
       int length = end - start;
       int byteStart = this.offsetInBytes + start * Int16List.BYTES_PER_ELEMENT;
@@ -1339,7 +1339,7 @@
   }
 
   void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
-    if (ClassID.getID(iterable) == CodeUnits.cid) {
+    if (iterable is CodeUnits) {
       end = RangeError.checkValidRange(start, end, this.length);
       int length = end - start;
       int byteStart = this.offsetInBytes + start * Uint16List.BYTES_PER_ELEMENT;
@@ -3384,7 +3384,7 @@
   }
 
   void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
-    if (ClassID.getID(iterable) == CodeUnits.cid) {
+    if (iterable is CodeUnits) {
       end = RangeError.checkValidRange(start, end, this.length);
       int length = end - start;
       int byteStart = this.offsetInBytes + start * Int16List.BYTES_PER_ELEMENT;
@@ -3442,7 +3442,7 @@
   }
 
   void setRange(int start, int end, Iterable iterable, [int skipCount = 0]) {
-    if (ClassID.getID(iterable) == CodeUnits.cid) {
+    if (iterable is CodeUnits) {
       end = RangeError.checkValidRange(start, end, this.length);
       int length = end - start;
       int byteStart = this.offsetInBytes + start * Uint16List.BYTES_PER_ELEMENT;
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index efd2cb0..b915df1 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -6,12 +6,7 @@
 export 'package:observatory/src/elements/class_view.dart';
 export 'package:observatory/src/elements/code_view.dart';
 export 'package:observatory/src/elements/debugger.dart';
-export 'package:observatory/src/elements/error_view.dart';
-export 'package:observatory/src/elements/eval_box.dart';
 export 'package:observatory/src/elements/eval_link.dart';
-export 'package:observatory/src/elements/field_view.dart';
-export 'package:observatory/src/elements/function_view.dart';
-export 'package:observatory/src/elements/heap_map.dart';
 export 'package:observatory/src/elements/instance_view.dart';
 export 'package:observatory/src/elements/isolate_reconnect.dart';
 export 'package:observatory/src/elements/isolate_summary.dart';
@@ -20,15 +15,9 @@
 export 'package:observatory/src/elements/library_ref_as_value.dart';
 export 'package:observatory/src/elements/library_view.dart';
 export 'package:observatory/src/elements/logging.dart';
-export 'package:observatory/src/elements/megamorphiccache_view.dart';
 export 'package:observatory/src/elements/metrics.dart';
 export 'package:observatory/src/elements/object_view.dart';
-export 'package:observatory/src/elements/objectpool_view.dart';
-export 'package:observatory/src/elements/objectstore_view.dart';
 export 'package:observatory/src/elements/observatory_element.dart';
-export 'package:observatory/src/elements/persistent_handles.dart';
-export 'package:observatory/src/elements/script_inset.dart';
-export 'package:observatory/src/elements/script_view.dart';
 export 'package:observatory/src/elements/service_ref.dart';
 export 'package:observatory/src/elements/service_view.dart';
 export 'package:observatory/src/elements/timeline_page.dart';
@@ -55,12 +44,18 @@
 import 'package:observatory/src/elements/curly_block_wrapper.dart';
 import 'package:observatory/src/elements/error_ref.dart';
 import 'package:observatory/src/elements/error_ref_wrapper.dart';
+import 'package:observatory/src/elements/error_view.dart';
+import 'package:observatory/src/elements/eval_box.dart';
+import 'package:observatory/src/elements/eval_box_wrapper.dart';
 import 'package:observatory/src/elements/field_ref.dart';
 import 'package:observatory/src/elements/field_ref_wrapper.dart';
+import 'package:observatory/src/elements/field_view.dart';
 import 'package:observatory/src/elements/flag_list.dart';
 import 'package:observatory/src/elements/function_ref.dart';
 import 'package:observatory/src/elements/function_ref_wrapper.dart';
+import 'package:observatory/src/elements/function_view.dart';
 import 'package:observatory/src/elements/general_error.dart';
+import 'package:observatory/src/elements/heap_map.dart';
 import 'package:observatory/src/elements/heap_snapshot.dart';
 import 'package:observatory/src/elements/icdata_ref.dart';
 import 'package:observatory/src/elements/icdata_view.dart';
@@ -76,6 +71,7 @@
 import 'package:observatory/src/elements/library_ref_wrapper.dart';
 import 'package:observatory/src/elements/local_var_descriptors_ref.dart';
 import 'package:observatory/src/elements/megamorphiccache_ref.dart';
+import 'package:observatory/src/elements/megamorphiccache_view.dart';
 import 'package:observatory/src/elements/nav/bar.dart';
 import 'package:observatory/src/elements/nav/class_menu.dart';
 import 'package:observatory/src/elements/nav/class_menu_wrapper.dart';
@@ -98,15 +94,23 @@
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 import 'package:observatory/src/elements/nav/vm_menu_wrapper.dart';
 import 'package:observatory/src/elements/objectpool_ref.dart';
+import 'package:observatory/src/elements/objectpool_view.dart';
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/object_common_wrapper.dart';
+import 'package:observatory/src/elements/objectstore_view.dart';
 import 'package:observatory/src/elements/observatory_application.dart';
+import 'package:observatory/src/elements/persistent_handles.dart';
 import 'package:observatory/src/elements/pc_descriptors_ref.dart';
 import 'package:observatory/src/elements/ports.dart';
 import 'package:observatory/src/elements/sample_buffer_control.dart';
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/script_inset_wrapper.dart';
 import 'package:observatory/src/elements/script_ref.dart';
 import 'package:observatory/src/elements/script_ref_wrapper.dart';
+import 'package:observatory/src/elements/script_view.dart';
 import 'package:observatory/src/elements/sentinel_value.dart';
+import 'package:observatory/src/elements/source_inset.dart';
+import 'package:observatory/src/elements/source_inset_wrapper.dart';
 import 'package:observatory/src/elements/source_link.dart';
 import 'package:observatory/src/elements/source_link_wrapper.dart';
 import 'package:observatory/src/elements/stack_trace_tree_config.dart';
@@ -131,10 +135,15 @@
 export 'package:observatory/src/elements/cpu_profile_table.dart';
 export 'package:observatory/src/elements/curly_block.dart';
 export 'package:observatory/src/elements/error_ref.dart';
+export 'package:observatory/src/elements/error_view.dart';
+export 'package:observatory/src/elements/eval_box.dart';
 export 'package:observatory/src/elements/field_ref.dart';
+export 'package:observatory/src/elements/field_view.dart';
+export 'package:observatory/src/elements/function_view.dart';
 export 'package:observatory/src/elements/flag_list.dart';
 export 'package:observatory/src/elements/function_ref.dart';
 export 'package:observatory/src/elements/general_error.dart';
+export 'package:observatory/src/elements/heap_map.dart';
 export 'package:observatory/src/elements/heap_snapshot.dart';
 export 'package:observatory/src/elements/icdata_ref.dart';
 export 'package:observatory/src/elements/icdata_view.dart';
@@ -146,6 +155,7 @@
 export 'package:observatory/src/elements/library_ref.dart';
 export 'package:observatory/src/elements/local_var_descriptors_ref.dart';
 export 'package:observatory/src/elements/megamorphiccache_ref.dart';
+export 'package:observatory/src/elements/megamorphiccache_view.dart';
 export 'package:observatory/src/elements/nav/bar.dart';
 export 'package:observatory/src/elements/nav/class_menu.dart';
 export 'package:observatory/src/elements/nav/isolate_menu.dart';
@@ -159,13 +169,19 @@
 export 'package:observatory/src/elements/nav/top_menu.dart';
 export 'package:observatory/src/elements/nav/vm_menu.dart';
 export 'package:observatory/src/elements/objectpool_ref.dart';
+export 'package:observatory/src/elements/objectpool_view.dart';
+export 'package:observatory/src/elements/objectstore_view.dart';
 export 'package:observatory/src/elements/object_common.dart';
 export 'package:observatory/src/elements/observatory_application.dart';
+export 'package:observatory/src/elements/persistent_handles.dart';
 export 'package:observatory/src/elements/pc_descriptors_ref.dart';
 export 'package:observatory/src/elements/ports.dart';
 export 'package:observatory/src/elements/sample_buffer_control.dart';
+export 'package:observatory/src/elements/script_inset.dart';
 export 'package:observatory/src/elements/script_ref.dart';
+export 'package:observatory/src/elements/script_view.dart';
 export 'package:observatory/src/elements/sentinel_value.dart';
+export 'package:observatory/src/elements/source_inset.dart';
 export 'package:observatory/src/elements/source_link.dart';
 export 'package:observatory/src/elements/stack_trace_tree_config.dart';
 export 'package:observatory/src/elements/token_stream_ref.dart';
@@ -193,12 +209,18 @@
   CurlyBlockElementWrapper.tag.ensureRegistration();
   ErrorRefElement.tag.ensureRegistration();
   ErrorRefElementWrapper.tag.ensureRegistration();
+  ErrorViewElement.tag.ensureRegistration();
+  EvalBoxElement.tag.ensureRegistration();
+  EvalBoxElementWrapper.tag.ensureRegistration();
   FieldRefElement.tag.ensureRegistration();
   FieldRefElementWrapper.tag.ensureRegistration();
+  FieldViewElement.tag.ensureRegistration();
   FlagListElement.tag.ensureRegistration();
   FunctionRefElement.tag.ensureRegistration();
   FunctionRefElementWrapper.tag.ensureRegistration();
+  FunctionViewElement.tag.ensureRegistration();
   GeneralErrorElement.tag.ensureRegistration();
+  HeapMapElement.tag.ensureRegistration();
   HeapSnapshotElement.tag.ensureRegistration();
   ICDataRefElement.tag.ensureRegistration();
   ICDataViewElement.tag.ensureRegistration();
@@ -214,6 +236,7 @@
   LibraryRefElementWrapper.tag.ensureRegistration();
   LocalVarDescriptorsRefElement.tag.ensureRegistration();
   MegamorphicCacheRefElement.tag.ensureRegistration();
+  MegamorphicCacheViewElement.tag.ensureRegistration();
   NavBarElement.tag.ensureRegistration();
   NavClassMenuElement.tag.ensureRegistration();
   NavClassMenuElementWrapper.tag.ensureRegistration();
@@ -238,14 +261,21 @@
   ObjectCommonElement.tag.ensureRegistration();
   ObjectCommonElementWrapper.tag.ensureRegistration();
   ObjectPoolRefElement.tag.ensureRegistration();
+  ObjectPoolViewElement.tag.ensureRegistration();
+  ObjectStoreViewElement.tag.ensureRegistration();
   ObservatoryApplicationElement.tag.ensureRegistration();
+  PersistentHandlesPageElement.tag.ensureRegistration();
   PcDescriptorsRefElement.tag.ensureRegistration();
   PortsElement.tag.ensureRegistration();
-  ScriptRefElement.tag.ensureRegistration();
+  ScriptInsetElement.tag.ensureRegistration();
+  ScriptInsetElementWrapper.tag.ensureRegistration();
   SampleBufferControlElement.tag.ensureRegistration();
   ScriptRefElement.tag.ensureRegistration();
   ScriptRefElementWrapper.tag.ensureRegistration();
+  ScriptViewElement.tag.ensureRegistration();
   SentinelValueElement.tag.ensureRegistration();
+  SourceInsetElement.tag.ensureRegistration();
+  SourceInsetElementWrapper.tag.ensureRegistration();
   SourceLinkElement.tag.ensureRegistration();
   SourceLinkElementWrapper.tag.ensureRegistration();
   StackTraceTreeConfigElement.tag.ensureRegistration();
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index 2fcf818..dd4378b 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -3,12 +3,7 @@
 <link rel="import" href="src/elements/class_view.html">
 <link rel="import" href="src/elements/code_view.html">
 <link rel="import" href="src/elements/debugger.html">
-<link rel="import" href="src/elements/error_view.html">
-<link rel="import" href="src/elements/eval_box.html">
 <link rel="import" href="src/elements/eval_link.html">
-<link rel="import" href="src/elements/field_view.html">
-<link rel="import" href="src/elements/function_view.html">
-<link rel="import" href="src/elements/heap_map.html">
 <link rel="import" href="src/elements/instance_view.html">
 <link rel="import" href="src/elements/isolate_summary.html">
 <link rel="import" href="src/elements/isolate_view.html">
@@ -16,14 +11,8 @@
 <link rel="import" href="src/elements/library_ref_as_value.html">
 <link rel="import" href="src/elements/library_view.html">
 <link rel="import" href="src/elements/logging.html">
-<link rel="import" href="src/elements/megamorphiccache_view.html">
 <link rel="import" href="src/elements/metrics.html">
 <link rel="import" href="src/elements/object_view.html">
-<link rel="import" href="src/elements/objectpool_view.html">
-<link rel="import" href="src/elements/objectstore_view.html">
-<link rel="import" href="src/elements/persistent_handles.html">
-<link rel="import" href="src/elements/script_inset.html">
-<link rel="import" href="src/elements/script_view.html">
 <link rel="import" href="src/elements/service_ref.html">
 <link rel="import" href="src/elements/service_view.html">
 <link rel="import" href="src/elements/timeline_page.html">
diff --git a/runtime/observatory/lib/models.dart b/runtime/observatory/lib/models.dart
index 01178ad..bb3ee7e 100644
--- a/runtime/observatory/lib/models.dart
+++ b/runtime/observatory/lib/models.dart
@@ -35,7 +35,9 @@
 part 'src/models/objects/notification.dart';
 part 'src/models/objects/object.dart';
 part 'src/models/objects/objectpool.dart';
+part 'src/models/objects/objectstore.dart';
 part 'src/models/objects/pc_descriptors.dart';
+part 'src/models/objects/persistent_handles.dart';
 part 'src/models/objects/ports.dart';
 part 'src/models/objects/retaining_path.dart';
 part 'src/models/objects/sample_profile.dart';
@@ -51,13 +53,20 @@
 part 'src/models/repositories/allocation_profile.dart';
 part 'src/models/repositories/class.dart';
 part 'src/models/repositories/context.dart';
+part 'src/models/repositories/eval.dart';
 part 'src/models/repositories/event.dart';
+part 'src/models/repositories/field.dart';
 part 'src/models/repositories/flag.dart';
+part 'src/models/repositories/function.dart';
 part 'src/models/repositories/heap_snapshot.dart';
 part 'src/models/repositories/icdata.dart';
 part 'src/models/repositories/inbound_references.dart';
 part 'src/models/repositories/instance.dart';
+part 'src/models/repositories/megamorphiccache.dart';
 part 'src/models/repositories/notification.dart';
+part 'src/models/repositories/objectpool.dart';
+part 'src/models/repositories/objectstore.dart';
+part 'src/models/repositories/persistent_handles.dart';
 part 'src/models/repositories/ports.dart';
 part 'src/models/repositories/reachable_size.dart';
 part 'src/models/repositories/retained_size.dart';
diff --git a/runtime/observatory/lib/repositories.dart b/runtime/observatory/lib/repositories.dart
index cf6d202..006e0f2 100644
--- a/runtime/observatory/lib/repositories.dart
+++ b/runtime/observatory/lib/repositories.dart
@@ -18,13 +18,20 @@
 part 'src/repositories/allocation_profile.dart';
 part 'src/repositories/class.dart';
 part 'src/repositories/context.dart';
+part 'src/repositories/eval.dart';
 part 'src/repositories/event.dart';
+part 'src/repositories/field.dart';
 part 'src/repositories/flag.dart';
+part 'src/repositories/function.dart';
 part 'src/repositories/heap_snapshot.dart';
 part 'src/repositories/icdata.dart';
 part 'src/repositories/inbound_references.dart';
 part 'src/repositories/instance.dart';
+part 'src/repositories/megamorphiccache.dart';
 part 'src/repositories/notification.dart';
+part 'src/repositories/objectpool.dart';
+part 'src/repositories/objectstore.dart';
+part 'src/repositories/persistent_handles.dart';
 part 'src/repositories/ports.dart';
 part 'src/repositories/reachable_size.dart';
 part 'src/repositories/retaining_path.dart';
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index bad6c88..cd2b0cd 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -6,7 +6,10 @@
 
 AllocationProfileRepository _allocationProfileRepository
     = new AllocationProfileRepository();
+ClassRepository _classRepository = new ClassRepository();
 ContextRepository _contextRepository = new ContextRepository();
+FieldRepository _fieldRepository = new FieldRepository();
+FunctionRepository _functionRepository = new FunctionRepository();
 HeapSnapshotRepository _heapSnapshotRepository
     = new HeapSnapshotRepository();
 ICDataRepository _icdataRepository = new ICDataRepository();
@@ -15,7 +18,16 @@
 InstanceRepository _instanceRepository = new InstanceRepository();
 IsolateSampleProfileRepository _isolateSampleProfileRepository
     = new IsolateSampleProfileRepository();
+MegamorphicCacheRepository _megamorphicCacheRepository
+    = new MegamorphicCacheRepository();
+ObjectPoolRepository _objectPoolRepository
+    = new ObjectPoolRepository();
+ObjectStoreRepository _objectstoreRepository
+    = new ObjectStoreRepository();
+PersistentHandlesRepository _persistentHandlesRepository
+    = new PersistentHandlesRepository();
 PortsRepository _portsRepository = new PortsRepository();
+ScriptRepository _scriptRepository = new ScriptRepository();
 
 class IsolateNotFound implements Exception {
   String isolateId;
@@ -181,7 +193,9 @@
     assert(element != null);
   }
 
-  void _visitObject(obj) {
+  Future _visitObject(obj) async {
+    container.children = [];
+    await obj.reload();
     if (obj is Context) {
       container.children = [
         new ContextViewElement(app.vm, obj.isolate, obj, app.events,
@@ -194,6 +208,38 @@
                                _instanceRepository,
                                queue: app.queue)
       ];
+    } else if (obj is DartError) {
+      container.children = [
+        new ErrorViewElement(app.notifications, obj, queue: app.queue)
+      ];
+    } else if (obj is Field) {
+      container.children = [
+        new FieldViewElement(app.vm, obj.isolate, obj, app.events,
+                             app.notifications,
+                             _fieldRepository,
+                             _classRepository,
+                             _retainedSizeRepository,
+                             _reachableSizeRepository,
+                             _inboundReferencesRepository,
+                             _retainingPathRepository,
+                             _scriptRepository,
+                             _instanceRepository,
+                             queue: app.queue)
+      ];
+    } else if (obj is ServiceFunction) {
+      container.children = [
+        new FunctionViewElement(app.vm, obj.isolate, obj, app.events,
+                                app.notifications,
+                                _functionRepository,
+                                _classRepository,
+                                _retainedSizeRepository,
+                                _reachableSizeRepository,
+                                _inboundReferencesRepository,
+                                _retainingPathRepository,
+                                _scriptRepository,
+                                _instanceRepository,
+                                queue: app.queue)
+      ];
     } else if (obj is ICData) {
       container.children = [
         new ICDataViewElement(app.vm, obj.isolate, obj, app.events,
@@ -206,6 +252,48 @@
                                _instanceRepository,
                                queue: app.queue)
       ];
+    } else if (obj is MegamorphicCache) {
+      container.children = [
+        new MegamorphicCacheViewElement(app.vm, obj.isolate, obj, app.events,
+                                        app.notifications,
+                                        _megamorphicCacheRepository,
+                                        _retainedSizeRepository,
+                                        _reachableSizeRepository,
+                                        _inboundReferencesRepository,
+                                        _retainingPathRepository,
+                                        _instanceRepository,
+                                        queue: app.queue)
+      ];
+    } else if (obj is ObjectPool) {
+      container.children = [
+        new ObjectPoolViewElement(app.vm, obj.isolate, obj, app.events,
+                                  app.notifications,
+                                  _objectPoolRepository,
+                                  _retainedSizeRepository,
+                                  _reachableSizeRepository,
+                                  _inboundReferencesRepository,
+                                  _retainingPathRepository,
+                                  _instanceRepository,
+                                  queue: app.queue)
+      ];
+    } else if (obj is Script) {
+      var pos;
+      if (app.locationManager.internalArguments['pos'] != null) {
+        try {
+          pos = int.parse(app.locationManager.internalArguments['pos']);
+        } catch (_) {}
+      }
+      container.children = [
+        new ScriptViewElement(app.vm, obj.isolate, obj, app.events,
+                              app.notifications,
+                              _scriptRepository,
+                              _retainedSizeRepository,
+                              _reachableSizeRepository,
+                              _inboundReferencesRepository,
+                              _retainingPathRepository,
+                              _instanceRepository,
+                              pos: pos, queue: app.queue)
+      ];
     } else {
       ServiceObjectViewElement serviceElement =new Element.tag('service-view');
       serviceElement.object = obj;
@@ -234,7 +322,7 @@
                              isolate,
                              app.events,
                              app.notifications,
-                             new ClassRepository(isolate))
+                             _classRepository)
       ];
     });
   }
@@ -255,22 +343,30 @@
   }
 }
 
+class ObjectStorePage extends MatchingPage {
+  ObjectStorePage(app) : super('object-store', app);
 
-class ObjectStorePage extends SimplePage {
-  ObjectStorePage(app) : super('object-store', 'objectstore-view', app);
+  final DivElement container = new DivElement();
 
   void _visit(Uri uri) {
     super._visit(uri);
-    getIsolate(uri).then((isolate) {
-      isolate.getObjectStore().then((objectStore) {
-        if (element != null) {
-          /// Update the page.
-          ObjectStoreViewElement page = element;
-          page.objectStore = objectStore;
-        }
-      });
+    getIsolate(uri).then((isolate) async {
+      container.children = [
+        new ObjectStoreViewElement(isolate.vm, isolate,
+                                   app.events,
+                                   app.notifications,
+                                   _objectstoreRepository,
+                                   _instanceRepository)
+      ];
     });
   }
+
+  void onInstall() {
+    if (element == null) {
+      element = container;
+    }
+    assert(element != null);
+  }
 }
 
 class CpuProfilerPage extends MatchingPage {
@@ -374,34 +470,50 @@
   }
 }
 
-class PersistentHandlesPage extends SimplePage {
-  PersistentHandlesPage(app)
-      : super('persistent-handles', 'persistent-handles-page', app);
+class PersistentHandlesPage extends MatchingPage {
+  PersistentHandlesPage(app) : super('persistent-handles', app);
+
+  final DivElement container = new DivElement();
 
   void _visit(Uri uri) {
     super._visit(uri);
     getIsolate(uri).then((isolate) {
-      if (element != null) {
-        PersistentHandlesPageElement page = element;
-        page.isolate = isolate;
-      }
+      container.children = [
+        new PersistentHandlesPageElement(isolate.vm, isolate, app.events,
+                                         app.notifications,
+                                         _persistentHandlesRepository,
+                                         _instanceRepository, queue: app.queue)
+      ];
     });
   }
+
+  void onInstall() {
+    if (element == null) {
+      element = container;
+    }
+  }
 }
 
-class HeapMapPage extends SimplePage {
-  HeapMapPage(app) : super('heap-map', 'heap-map', app);
+class HeapMapPage extends MatchingPage {
+  HeapMapPage(app) : super('heap-map', app);
+
+  final DivElement container = new DivElement();
 
   void _visit(Uri uri) {
     super._visit(uri);
     getIsolate(uri).then((isolate) {
-      if (element != null) {
-        /// Update the page.
-        HeapMapElement page = element;
-        page.isolate = isolate;
-      }
+      container.children = [
+        new HeapMapElement(isolate.vm, isolate, app.events, app.notifications,
+                           queue: app.queue)
+      ];
     });
   }
+
+  void onInstall() {
+    if (element == null) {
+      element = container;
+    }
+  }
 }
 
 class HeapSnapshotPage extends MatchingPage {
diff --git a/runtime/observatory/lib/src/elements/allocation_profile.dart b/runtime/observatory/lib/src/elements/allocation_profile.dart
index 45e4d9f..d56b2a0 100644
--- a/runtime/observatory/lib/src/elements/allocation_profile.dart
+++ b/runtime/observatory/lib/src/elements/allocation_profile.dart
@@ -128,7 +128,7 @@
           new NavVMMenuElement(_vm, _events, queue: _r.queue),
           new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
           new NavMenuElement('allocation profile', last: true,
-              link: Uris.profiler(_isolate), queue: _r.queue),
+              link: Uris.allocationProfiler(_isolate), queue: _r.queue),
           new NavRefreshElement(label: 'Download', disabled: _profile == null,
               queue: _r.queue)
             ..onRefresh.listen((_) => _downloadCSV()),
diff --git a/runtime/observatory/lib/src/elements/class_tree.dart b/runtime/observatory/lib/src/elements/class_tree.dart
index 6fefdfd..0e2aed0 100644
--- a/runtime/observatory/lib/src/elements/class_tree.dart
+++ b/runtime/observatory/lib/src/elements/class_tree.dart
@@ -115,7 +115,7 @@
     _object = null;
     _subclasses.clear();
     _mixins.clear();
-    _object = await _register(await _classes.getObject());
+    _object = await _register(await _classes.getObject(_isolate));
     _r.dirty();
   }
 
@@ -129,7 +129,7 @@
   }
 
   Future<Iterable<M.Class>> _getActualChildrens(M.ClassRef ref) async {
-    var cls = await _classes.get(ref.id);
+    var cls = await _classes.get(_isolate, ref.id);
     if (cls.isPatch) {
       return const [];
     }
diff --git a/runtime/observatory/lib/src/elements/class_view.html b/runtime/observatory/lib/src/elements/class_view.html
index 14af953..f67e7f1 100644
--- a/runtime/observatory/lib/src/elements/class_view.html
+++ b/runtime/observatory/lib/src/elements/class_view.html
@@ -1,8 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="action_link.html">
-<link rel="import" href="eval_box.html">
 <link rel="import" href="eval_link.html">
-<link rel="import" href="script_inset.html">
 
 <polymer-element name="class-view">
   <template>
@@ -114,7 +112,7 @@
     <hr>
 
     <div class="content">
-      <eval-box callback="{{ evaluate }}"></eval-box>
+      <eval-box context="{{ cls }}"></eval-box>
     </div>
 
     <hr>
diff --git a/runtime/observatory/lib/src/elements/context_view.dart b/runtime/observatory/lib/src/elements/context_view.dart
index 98dcc20..4be588d 100644
--- a/runtime/observatory/lib/src/elements/context_view.dart
+++ b/runtime/observatory/lib/src/elements/context_view.dart
@@ -21,7 +21,7 @@
 import 'package:observatory/src/elements/object_common.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 
-class ContextViewElement  extends HtmlElement implements Renderable {
+class ContextViewElement extends HtmlElement implements Renderable {
   static const tag = const Tag<ContextViewElement>('context-view',
                                             dependencies: const [
                                               ContextRefElement.tag,
diff --git a/runtime/observatory/lib/src/elements/cpu_profile.dart b/runtime/observatory/lib/src/elements/cpu_profile.dart
index 75e2c07..672f6d3 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile.dart
@@ -101,7 +101,7 @@
           new NavTopMenuElement(queue: _r.queue),
           new NavVMMenuElement(_vm, _events, queue: _r.queue),
           new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
-          new NavMenuElement('cpu profile', link: Uris.profiler(_isolate),
+          new NavMenuElement('cpu profile', link: Uris.cpuProfiler(_isolate),
               last: true, queue: _r.queue),
           new NavRefreshElement(queue: _r.queue)
               ..onRefresh.listen(_refresh),
diff --git a/runtime/observatory/lib/src/elements/cpu_profile_table.dart b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
index 104b190..d7b09d7 100644
--- a/runtime/observatory/lib/src/elements/cpu_profile_table.dart
+++ b/runtime/observatory/lib/src/elements/cpu_profile_table.dart
@@ -133,7 +133,7 @@
           new NavVMMenuElement(_vm, _events, queue: _r.queue),
           new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
           new NavMenuElement('cpu profile (table)',
-              link: Uris.profiler(_isolate), last: true, queue: _r.queue),
+              link: Uris.cpuProfilerTable(_isolate), last: true, queue: _r.queue),
           new NavRefreshElement(queue: _r.queue)
               ..onRefresh.listen(_refresh),
           new NavRefreshElement(label: 'Clear', queue: _r.queue)
@@ -223,7 +223,10 @@
           ..text = '0%',
         new SpanElement()..classes = const ['name']
       ];
-    element.onClick.listen((_) {
+    element.onClick.listen((e) {
+      if (e.target is AnchorElement) {
+        return;
+      }
       _selected = _functions.getItemFromElement(element);
       _r.dirty();
     });
@@ -287,7 +290,10 @@
           ..text = '0%',
         new SpanElement()..classes = const ['name']
       ];
-    element.onClick.listen((_) {
+    element.onClick.listen((e) {
+      if (e.target is AnchorElement) {
+        return;
+      }
       _selected = _callees.getItemFromElement(element);
       _r.dirty();
     });
@@ -322,7 +328,10 @@
           ..text = '0%',
         new SpanElement()..classes = const ['name']
       ];
-    element.onClick.listen((_) {
+    element.onClick.listen((e) {
+      if (e.target is AnchorElement) {
+        return;
+      }
       _selected = _callers.getItemFromElement(element);
       _r.dirty();
     });
diff --git a/runtime/observatory/lib/src/elements/css/shared.css b/runtime/observatory/lib/src/elements/css/shared.css
index d378e68..a914e87 100644
--- a/runtime/observatory/lib/src/elements/css/shared.css
+++ b/runtime/observatory/lib/src/elements/css/shared.css
@@ -2,13 +2,17 @@
 * {
   margin: 0;
   padding: 0;
-  font: 400 14px 'Montserrat', sans-serif;
-  color: #333;
   box-sizing: border-box;
 }
 
 body {
   padding-top: 56px;
+  color: #333;
+  font: 400 14px 'Montserrat', sans-serif;
+}
+
+button {
+  font: 400 14px 'Montserrat', sans-serif;
 }
 
 .content {
@@ -32,6 +36,10 @@
   font: 400 18px 'Montserrat', sans-serif;
 }
 
+h2 {
+  font: 400 16px 'Montserrat', sans-serif;
+}
+
 .memberList {
   display: table;
 }
@@ -570,6 +578,21 @@
   margin-left: 0.5em;
 }
 
+/* context-ref */
+/* TODO(cbernaschina) fix context-ref-wrapped to context-ref when wrapper
+removed */
+
+context-ref-wrapped > a[href]:hover {
+    text-decoration: underline;
+}
+context-ref-wrapped > a[href] {
+    color: #0489c3;
+    text-decoration: none;
+}
+context-ref-wrapped > a[href] * {
+    color: inherit;
+}
+
 /* cpu-profile */
 
 cpu-profile {
@@ -761,13 +784,103 @@
 error-ref-wrapped > pre {
   background-color: #f5f5f5;
   border: 1px solid #ccc;
-  padding: 10px;
+  padding-left: 10px;
+  padding-right: 10px;
   font-family: consolas, courier, monospace;
   font-size: 1em;
   line-height: 1.2em;
   white-space: pre;
 }
 
+/* eval-box */
+/* TODO(cbernaschina) fix eval-box-wrapped to error-ref when wrapper
+removed */
+
+eval-box-wrapped a[href]:hover {
+    text-decoration: underline;
+}
+eval-box-wrapped a[href] {
+    color: #0489c3;
+    text-decoration: none;
+}
+eval-box-wrapped .quicks > button:hover {
+  background-color: transparent;
+  border: none;
+  text-decoration: underline;
+}
+eval-box-wrapped .quicks > button {
+  background-color: transparent;
+  border: none;
+  color: #0489c3;
+  padding: 0;
+  margin-right: 1em;
+  text-decoration: none;
+}
+eval-box-wrapped .empathize {
+  font-style: italic;
+}
+eval-box-wrapped .indent {
+  margin-left: 1.5em;
+  font: 400 14px 'Montserrat', sans-serif;
+  line-height: 150%;
+}
+eval-box-wrapped .stackTraceBox {
+  margin-left: 1.5em;
+  background-color: #f5f5f5;
+  border: 1px solid #ccc;
+  padding: 10px;
+  font-family: consolas, courier, monospace;
+  font-size: 12px;
+  white-space: pre;
+  overflow-x: auto;
+}
+eval-box-wrapped .heading {
+  line-height: 30px;
+  position: relative;
+  box-sizing: border-box;
+  width: 100%;
+  min-width: 450px;
+  padding-right: 150px;
+}
+eval-box-wrapped .heading .textbox {
+  width: 100%;
+  min-width: 300px;
+}
+eval-box-wrapped .heading .buttons {
+  position: absolute;
+  top: 0;
+  right: 0px;
+}
+eval-box-wrapped.historyExpr,
+eval-box-wrapped .historyValue {
+  vertical-align: text-top;
+  font: 400 14px 'Montserrat', sans-serif;
+}
+eval-box-wrapped .historyExpr button {
+  display: block;
+  color: black;
+  border: none;
+  background: none;
+  text-decoration: none;
+  padding: 6px 6px;
+  cursor: pointer;
+  white-space: pre-line;
+}
+eval-box-wrapped .historyExpr button:hover {
+  background-color: #fff3e3;
+}
+eval-box-wrapped .historyValue {
+  display: block;
+  padding: 6px 6px;
+}
+eval-box-wrapped .historyDelete button {
+  border: none;
+  background: none;
+}
+eval-box-wrapped .historyDelete button:hover {
+  color: #BB3311;
+}
+
 /* flag-list */
 
 flag-list .comment {
@@ -801,12 +914,10 @@
 
 /* heap-snapshot */
 
-
 heap-snapshot .statusMessage {
   font-size: 150%;
   font-weight: bold;
 }
-
 heap-snapshot .statusBox {
   height: 100%;
   padding: 1em;
@@ -973,6 +1084,8 @@
 isolate-shared-summary,
 isolate-shared-summary-wrapped {
   display: block;
+}
+isolate-shared-summary-wrapped > .summary {
   height: 300px;
   position: relative;
 }
@@ -1020,6 +1133,21 @@
   color: white;
 }
 
+/* megamorphic-cache-ref */
+/* TODO(cbernaschina) fix megamorphic-cache-ref-wrapped to megamorphic-cache-ref
+when wrapper removed */
+
+megamorphic-cache-ref-wrapped > a[href]:hover {
+    text-decoration: underline;
+}
+megamorphic-cache-ref-wrapped > a[href] {
+    color: #0489c3;
+    text-decoration: none;
+}
+megamorphic-cache-ref-wrapped > a[href] * {
+    color: inherit;
+}
+
 /* nav-notify */
 /* TODO(cbernaschina) fix nav-notify-wrapped to nav-notify when wrapper
 removed */
@@ -1151,6 +1279,12 @@
     color: inherit;
 }
 
+/* object-pool-view */
+
+object-pool-view .hexadecimal {
+  font-family: monospace;
+}
+
 /* observatory-application */
 
 observatory-application {
@@ -1163,6 +1297,69 @@
   height: 100%;
 }
 
+/* persistent-handles-page */
+
+persistent-handles-page {
+  display: block;
+  height: 100%;
+}
+persistent-handles-page .persistent-handles,
+persistent-handles-page .weak-persistent-handles {
+  margin-top: -70px;
+  padding-top: 70px;
+  height: 50%;
+}
+persistent-handles-page virtual-collection {
+  overflow-y: scroll;
+}
+persistent-handles-page .weak-item,
+persistent-handles-page .collection-item {
+  box-sizing: border-box;
+  line-height: 20px;
+  padding-left: 5%;
+  padding-right: 5%;
+}
+persistent-handles-page .header {
+  box-sizing: border-box;
+  line-height: 20px;
+}
+persistent-handles-page .header .weak-item:last-child {
+  margin-bottom: -3px;
+  border-bottom: solid 1px #AAAAAA;
+}
+persistent-handles-page .weak-item .external-size,
+persistent-handles-page .weak-item .peer,
+persistent-handles-page .weak-item .object {
+  display: inline-block;
+  width: 7em;
+  text-align: right;
+  padding-right: 0.5em;
+  line-height: 20px;
+}
+persistent-handles-page .weak-item .peer {
+  width: 11em;
+  font-family: monospace;
+}
+persistent-handles-page .weak-item .object {
+  text-align: left;
+  width: 25em;
+}
+persistent-handles-page .shifter .weak-item:hover {
+  background-color: #d2e7fe;
+}
+persistent-handles-page .weak-item .finalizer {
+  padding-left: 0.5em;
+}
+persistent-handles-page .weak-item > button,
+persistent-handles-page .weak-item > button:active {
+  background-color: transparent;
+  color: #0489c3;
+  border-style: none;
+}
+persistent-handles-page .weak-item > button:hover {
+  text-decoration: underline;
+}
+
 /* ports-page */
 
 ports-page .port-number {
@@ -1242,6 +1439,173 @@
               0 2px 5px 0 rgba(0, 0, 0, 0.26);
 }
 
+/* script-inset */
+/* TODO(cbernaschina) fix script-inset-wrapped to script-inset when wrapper
+removed */
+
+script-inset-wrapped {
+  position: relative;
+}
+script-inset-wrapped button.refresh,
+script-inset-wrapped button.toggle-profile {
+  background-color: transparent;
+  padding: 0;
+  margin: 0;
+  border: none;
+  position: absolute;
+  display: inline-block;
+  top: 5px;
+  color: #888888;
+  line-height: 30px;
+}
+script-inset-wrapped button.refresh {
+  right: 5px;
+  font-size: 25px;
+}
+script-inset-wrapped button.toggle-profile {
+  right: 30px;
+  font-size: 20px;
+}
+script-inset-wrapped button.toggle-profile.enabled {
+  color: #BB3322;
+}
+script-inset-wrapped a {
+  color: #0489c3;
+  text-decoration: none;
+}
+script-inset-wrapped a:hover {
+  text-decoration: underline;
+}
+script-inset-wrapped .sourceInset {
+}
+script-inset-wrapped .sourceTable {
+  position: relative;
+  background-color: #f5f5f5;
+  border: 1px solid #ccc;
+  padding: 10px;
+  width: 100%;
+  box-sizing: border-box;
+  overflow-x: scroll;
+}
+script-inset-wrapped .sourceRow {
+  display: flex;
+  flex-direction: row;
+  width: 100%;
+}
+script-inset-wrapped .sourceItem,
+script-inset-wrapped .sourceItemCurrent {
+  vertical-align: top;
+  font: 400 14px consolas, courier, monospace;
+  line-height: 125%;
+  white-space: pre;
+  max-width: 0;
+}
+script-inset-wrapped .currentLine {
+  background-color: #fff;
+}
+script-inset-wrapped .currentCol {
+  background-color: #6cf;
+}
+script-inset-wrapped .hitsCurrent,
+script-inset-wrapped .hitsNone,
+script-inset-wrapped .hitsNotExecuted,
+script-inset-wrapped .hitsExecuted,
+script-inset-wrapped .hitsCompiled,
+script-inset-wrapped .hitsNotCompiled {
+  display: table-cell;
+  vertical-align: top;
+  font: 400 14px consolas, courier, monospace;
+  margin-left: 5px;
+  margin-right: 5px;
+  text-align: right;
+  color: #a8a8a8;
+}
+script-inset-wrapped .hitsCurrent {
+  background-color: #6cf;
+  color: black;
+}
+script-inset-wrapped .hitsNotExecuted {
+  background-color: #faa;
+}
+script-inset-wrapped .hitsExecuted {
+  background-color: #aea;
+}
+script-inset-wrapped .hitsCompiled {
+  background-color: #e0e0e0;
+}
+script-inset-wrapped .hitsNotCompiled {
+  background-color: #f0c5c5;
+}
+script-inset-wrapped .noCopy {}
+script-inset-wrapped .emptyBreakpoint,
+script-inset-wrapped .possibleBreakpoint,
+script-inset-wrapped .busyBreakpoint,
+script-inset-wrapped .unresolvedBreakpoint,
+script-inset-wrapped .resolvedBreakpoint  {
+  display: table-cell;
+  vertical-align: top;
+  font: 400 14px consolas, courier, monospace;
+  width: 1em;
+  text-align: center;
+  cursor: pointer;
+}
+script-inset-wrapped .possibleBreakpoint {
+  color: #e0e0e0;
+}
+script-inset-wrapped .possibleBreakpoint:hover {
+  color: white;
+  background-color: #777;
+}
+script-inset-wrapped .busyBreakpoint {
+  color: white;
+  background-color: black;
+  cursor: wait;
+}
+script-inset-wrapped .unresolvedBreakpoint {
+  color: white;
+  background-color: #cac;
+}
+script-inset-wrapped .resolvedBreakpoint {
+  color: white;
+  background-color: #e66;
+}
+script-inset-wrapped .unresolvedBreakAnnotation {
+  color: white;
+  background-color: #cac;
+}
+script-inset-wrapped .resolvedBreakAnnotation {
+  color: white;
+  background-color: #e66;
+}
+script-inset-wrapped .notSourceProfile,
+script-inset-wrapped .noProfile,
+script-inset-wrapped .coldProfile,
+script-inset-wrapped .mediumProfile,
+script-inset-wrapped .hotProfile {
+  display: table-cell;
+  vertical-align: top;
+  font: 400 14px consolas, courier, monospace;
+  width: 4em;
+  text-align: right;
+  cursor: pointer;
+  margin-left: 5px;
+  margin-right: 5px;
+}
+script-inset-wrapped .notSourceProfile {
+}
+script-inset-wrapped .noProfile {
+  background-color: #e0e0e0;
+}
+script-inset-wrapped .coldProfile {
+  background-color: #aea;
+}
+script-inset-wrapped .mediumProfile {
+  background-color: #fe9;
+}
+script-inset-wrapped .hotProfile {
+  background-color: #faa;
+}
+
 /* stack-trace-tree-config */
 
 stack-trace-tree-config {
diff --git a/runtime/observatory/lib/src/elements/debugger.html b/runtime/observatory/lib/src/elements/debugger.html
index 42fb892..da96388 100644
--- a/runtime/observatory/lib/src/elements/debugger.html
+++ b/runtime/observatory/lib/src/elements/debugger.html
@@ -1,6 +1,5 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="eval_link.html">
-<link rel="import" href="script_inset.html">
 
 <!-- TODO(turnidge): Use core-icon once core_elements work properly in
      devtools -->
diff --git a/runtime/observatory/lib/src/elements/error_ref_wrapper.dart b/runtime/observatory/lib/src/elements/error_ref_wrapper.dart
index 50f8b9a..4b0e7e4 100644
--- a/runtime/observatory/lib/src/elements/error_ref_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/error_ref_wrapper.dart
@@ -51,7 +51,8 @@
         error-ref-wrapped > pre {
           background-color: #f5f5f5;
           border: 1px solid #ccc;
-          padding: 10px;
+          padding-left: 10px;
+          padding-right: 10px;
           font-family: consolas, courier, monospace;
           font-size: 1em;
           line-height: 1.2em;
diff --git a/runtime/observatory/lib/src/elements/error_view.dart b/runtime/observatory/lib/src/elements/error_view.dart
index 53582cc..aeb3aa8 100644
--- a/runtime/observatory/lib/src/elements/error_view.dart
+++ b/runtime/observatory/lib/src/elements/error_view.dart
@@ -4,14 +4,93 @@
 
 library error_view_element;
 
-import 'observatory_element.dart';
-import 'package:polymer/polymer.dart';
-import 'package:observatory/service.dart';
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/view_footer.dart';
 
-/// Displays an Error ServiceObject.
-@CustomTag('error-view')
-class ErrorViewElement extends ObservatoryElement {
-  @published DartError error;
+class ErrorViewElement extends HtmlElement implements Renderable{
+  static const tag = const Tag<ErrorViewElement>('error-view',
+                     dependencies: const [NavBarElement.tag,
+                                          NavTopMenuElement.tag,
+                                          NavNotifyElement.tag,
+                                          ViewFooterElement.tag]);
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<ErrorViewElement>> get onRendered =>
+      _r.onRendered;
+
+  M.Error _error;
+  M.NotificationRepository _notifications;
+
+  M.Error get error => _error;
+
+  factory ErrorViewElement(M.NotificationRepository notifications,
+                           M.Error error,
+                          {RenderingQueue queue}) {
+    assert(error != null);
+    assert(notifications != null);
+    ErrorViewElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._error = error;
+    e._notifications = notifications;
+    return e;
+  }
 
   ErrorViewElement.created() : super.created();
-}
\ No newline at end of file
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(last: true, queue: _r.queue),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()
+        ..classes = ['content-centered']
+        ..children = [
+          new HeadingElement.h1()
+            ..text = 'Error: ${_kindToString(_error.kind)}',
+          new BRElement(),
+          new DivElement()..classes = ['well']
+            ..children = [
+              new PreElement()..text = error.message
+            ]
+        ],
+      new ViewFooterElement(queue: _r.queue)
+    ];
+  }
+
+  static String _kindToString(M.ErrorKind kind) {
+    switch(kind) {
+      case M.ErrorKind.unhandledException:
+        return 'Unhandled Exception';
+      case M.ErrorKind.languageError:
+        return 'Language Error';
+      case M.ErrorKind.internalError:
+        return 'Internal Error';
+      case M.ErrorKind.terminationError:
+        return 'Termination Error';
+    }
+    throw new Exception('Unkown M.ErrorKind ($kind)');
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/error_view.html b/runtime/observatory/lib/src/elements/error_view.html
deleted file mode 100644
index aa40472..0000000
--- a/runtime/observatory/lib/src/elements/error_view.html
+++ /dev/null
@@ -1,19 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="error-view">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-    </nav-bar>
-    <div class="content-centered">
-      <h1>{{ error.kind }}</h1>
-      <br>
-      <div class="well">{{ error.message }}</div>
-    </div>
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="error_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/eval_box.dart b/runtime/observatory/lib/src/elements/eval_box.dart
index c6fd2c5..004d9e0 100644
--- a/runtime/observatory/lib/src/elements/eval_box.dart
+++ b/runtime/observatory/lib/src/elements/eval_box.dart
@@ -4,66 +4,207 @@
 
 library eval_box_element;
 
-import 'dart:async';
 import 'dart:html';
-import 'observatory_element.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
 
+class EvalBoxElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<EvalBoxElement>('eval-box-wrapped',
+                                                dependencies: const [
+                                                  InstanceRefElement.tag
+                                                ]);
 
-typedef Future evalType(String text);
+  RenderingScheduler<EvalBoxElement> _r;
 
+  Stream<RenderedEvent<EvalBoxElement>> get onRendered => _r.onRendered;
 
-@CustomTag('eval-box')
-class EvalBoxElement extends ObservatoryElement {
-  @observable String text;
-  @observable String lineMode = "1-line";
-  int _exprCount = 0;
+  M.IsolateRef _isolate;
+  M.ObjectRef _context;
+  M.InstanceRepository _instances;
+  M.EvalRepository _eval;
+  final _results = <_ExpressionDescription>[];
+  String _expression = '';
+  bool _multiline;
+  Iterable<String> _quickExpressions;
 
-  @published evalType callback;
-  @observable ObservableList results = toObservable([]);
+  M.IsolateRef get isolate => _isolate;
+  M.ObjectRef get context => _context;
 
-  void updateLineMode(Event e, var detail, Node target) {
-    lineMode = (e.target as InputElement).value;
-    if (lineMode == '1-line' && text != null) {
-      text = text.replaceAll('\n', ' ');
-    }
-  }
-
-  void evaluate(Event e, var detail, Node target) {
-    // Prevent any form action.
-    e.preventDefault();
-
-    // Clear the text box.
-    var expr = text;
-    text = '';
-
-    // Use provided callback to eval the expression.
-    if (callback != null) {
-      var map = toObservable({});
-      map['id'] = (_exprCount++).toString();
-      map['expr'] = expr;
-      results.insert(0, map);
-      callback(expr).then((result) {
-        map['value'] = result;
-      }).catchError((e, st) {
-        map['error'] = e.message;
-        app.handleException(e, st);
-      });
-    }
-  }
-
-  void selectExpr(MouseEvent e) {
-    assert(e.target is Element);
-    Element targetElement = e.target;
-    text = targetElement.getAttribute('expr');
-  }
-
-  void closeItem(MouseEvent e) {
-    assert(e.target is Element);
-    Element targetElement = e.target;
-    var closeId = targetElement.getAttribute('closeId');
-    results.removeWhere((item) => item['id'] == closeId);
+  factory EvalBoxElement(M.IsolateRef isolate, M.ObjectRef context,
+                         M.InstanceRepository instances,
+                         M.EvalRepository eval,
+                         {bool multiline: false,
+                          Iterable<String> quickExpressions: const [],
+                          RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(context != null);
+    assert(instances != null);
+    assert(eval != null);
+    assert(multiline != null);
+    assert(quickExpressions != null);
+    EvalBoxElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._context = context;
+    e._instances = instances;
+    e._eval = eval;
+    e._multiline = multiline;
+    e._quickExpressions = new List.unmodifiable(quickExpressions);
+    return e;
   }
 
   EvalBoxElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+    _results.clear();
+  }
+
+  void render() {
+    children = [
+      new DivElement()..classes = const ['quicks']
+        ..children = _quickExpressions.map((q) =>
+          new ButtonElement()
+            ..text = q
+            ..onClick.listen((_) {
+              _expression = q;
+              _run();
+            })
+        ),
+      new DivElement()..classes = const ['heading']
+        ..children = [
+          new FormElement()
+            ..autocomplete = 'on'
+            ..children = [
+              _multiline ? _createEvalTextArea() : _createEvalTextBox(),
+              new SpanElement()..classes = const ['buttons']
+                ..children = [
+                  _createEvalButton(),
+                  _createMultilineCheckbox(),
+                  new SpanElement()..text = 'multi-line'
+                ]
+            ]
+        ],
+      new TableElement()
+        ..children = _results.reversed.map((result) =>
+          new TableRowElement()
+            ..children = [
+              new TableCellElement()..classes = const ['historyExpr']
+                ..children = [
+                  new ButtonElement()..text = result.expression
+                    ..onClick.listen((_) {
+                      _expression = result.expression;
+                      _r.dirty();
+                    })
+                ],
+              new TableCellElement()..classes = const ['historyValue']
+                ..children = [
+                  result.isPending
+                    ? (new SpanElement()..text = 'Pending...')
+                    : anyRef(_isolate, result.value, _instances,
+                             queue: _r.queue)
+                ],
+              new TableCellElement()..classes = const ['historyDelete']
+                ..children = [
+                  new ButtonElement()..text = '✖ Remove'
+                    ..onClick.listen((_) {
+                      _results.remove(result);
+                      _r.dirty();
+                    })
+                ]
+            ]).toList()
+    ];
+  }
+
+  TextInputElement _createEvalTextArea() {
+    var area = new TextAreaElement()
+      ..classes = ['textbox']
+      ..placeholder = 'evaluate an expression'
+      ..value = _expression
+      ..onKeyUp
+        .where((e) => e.key == '\n')
+        .listen((e) {
+          e.preventDefault();
+          _run();
+        });
+    area.onInput.listen((e) {
+      _expression = area.value;
+    });
+    return area;
+  }
+
+  TextInputElement _createEvalTextBox() {
+    _expression = (_expression ?? '').split('\n')[0];
+    var textbox = new TextInputElement()
+      ..classes = ['textbox']
+      ..placeholder = 'evaluate an expression'
+      ..value = _expression
+      ..onKeyUp
+        .where((e) => e.key == '\n')
+        .listen((e) {
+          e.preventDefault();
+          _run();
+        });
+    textbox.onInput.listen((e) {
+      _expression = textbox.value;
+    });
+    return textbox;
+  }
+
+  ButtonElement _createEvalButton() {
+    final button = new ButtonElement()
+      ..text = 'evaluate'
+      ..onClick.listen((e) {
+        e.preventDefault();
+        _run();
+      });
+    return button;
+  }
+
+  CheckboxInputElement _createMultilineCheckbox() {
+    final checkbox = new CheckboxInputElement()
+      ..checked = _multiline;
+    checkbox.onClick.listen((e) {
+        e.preventDefault();
+        _multiline = checkbox.checked;
+        _r.dirty();
+      });
+    return checkbox;
+  }
+
+  Future _run() async {
+    if (_expression == null || _expression.isEmpty) return;
+    final expression = _expression;
+    _expression = null;
+    final result = new _ExpressionDescription.pending(expression);
+    _results.add(result);
+    _r.dirty();
+    final index = _results.indexOf(result);
+    _results[index] = new _ExpressionDescription(expression,
+        await _eval.evaluate(_isolate, _context, expression));
+    _r.dirty();
+  }
+}
+
+class _ExpressionDescription {
+  final String expression;
+  final M.ObjectRef value;
+  bool get isPending => value == null;
+
+  _ExpressionDescription(this.expression, this.value);
+  _ExpressionDescription.pending(this.expression)
+    : value = null;
 }
diff --git a/runtime/observatory/lib/src/elements/eval_box.html b/runtime/observatory/lib/src/elements/eval_box.html
deleted file mode 100644
index 8f9929f..0000000
--- a/runtime/observatory/lib/src/elements/eval_box.html
+++ /dev/null
@@ -1,115 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="eval-box">
-  <template>
-    <style>
-      .textbox {
-        flex-grow: 1;
-        font: 400 16px 'Montserrat', sans-serif;
-      }
-      .bigtextbox {
-        flex-grow: 1;
-        font: 400 16px 'Montserrat', sans-serif;
-      }
-      .button {
-        font: 400 16px 'Montserrat', sans-serif;
-        margin-left: 0.5em;
-        margin-right: 0.5em;
-      }
-      .radios {
-        display: inline;
-        padding-right: 30px;
-      }
-      .radios label{
-        padding-left: 10px;
-      }
-      .historyExpr, .historyValue {
-        vertical-align: text-top;
-        font: 400 14px 'Montserrat', sans-serif;
-      }
-      .historyExpr a {
-        display: block;
-        color: black;
-        text-decoration: none;
-        padding: 6px 6px;
-        cursor: pointer;
-        white-space: pre-line;
-      }
-      .historyExpr a:hover {
-        background-color: #fff3e3;
-      }
-      .historyValue {
-        display: block;
-        padding: 6px 6px;
-      }
-      a.boxclose {
-        margin-left: 20px;
-        valign: top;
-        display: block;
-        height: 18px;
-        width: 18px;
-        line-height: 16px;
-        border-radius: 9px;
-        color: black;
-        font-size: 18px;
-        cursor: pointer;
-        text-align: center;
-      }
-      a.boxclose:hover {
-        background: lightgray;
-      }
-    </style>
-    <form style="display:flex; flex-direction:row; align-items:flex-end">
-      <template if="{{ lineMode == '1-line' }}">
-        <input class="textbox" type="text" value="{{ text }}">
-      </template>
-      <template if="{{ lineMode == 'N-line' }}">
-        <textarea class="bigtextbox"
-                  value="{{ text }}"></textarea>
-      </template>
-
-      <input class="button" type="submit" value="Evaluate" on-click="{{ evaluate }}">
-      <div class="radios" on-change="{{ updateLineMode }}">
-        <label for="1-line">
-          <input type="radio" name="lineMode" value="1-line" checked>
-          1-line
-        </label>
-        <label for="N-line">
-          <input type="radio" name="lineMode" value="N-line">
-          N-line
-        </label>
-      </div>
-    </form>
-
-    <br>
-    <template if="{{ results.isNotEmpty }}">
-      <table>
-        <tr template repeat="{{ result in results }}">
-          <td class="historyExpr">
-            <a class="expr" on-click="{{ selectExpr }}"
-               expr="{{ result['expr'] }}">{{ result['expr'] }}</a>
-          </td>
-          <td class="historyValue">
-            <template if="{{ result['error'] != null}}">
-              <div style="color:red">{{ result['error'] }}</div>
-            </template>
-            <template if="{{ result['error'] == null}}">
-              <template if="{{ result['value'] != null }}">
-                <any-service-ref ref="{{ result['value'] }}"></any-service-ref>
-              </template>
-              <template if="{{ result['value'] == null }}">
-                <div style="color:#aaa;cursor:wait;">&lt;pending&gt;</div>
-              </template>
-            </template>
-          </td>
-          <td>
-            <a class="boxclose" on-click="{{ closeItem }}"
-               closeId="{{ result['id'] }}">&times;</a>
-          </td>
-        </tr>
-      </table>
-    </template>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="eval_box.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/eval_box_wrapper.dart b/runtime/observatory/lib/src/elements/eval_box_wrapper.dart
new file mode 100644
index 0000000..0bd132b
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/eval_box_wrapper.dart
@@ -0,0 +1,143 @@
+// 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:html';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/service_html.dart' show HeapObject;
+import 'package:observatory/src/elements/eval_box.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class EvalBoxElementWrapper extends HtmlElement {
+  static const binder = const Binder<EvalBoxElementWrapper>(const {
+      'context': #context
+    });
+
+  static const tag = const Tag<EvalBoxElementWrapper>('eval-box');
+
+  HeapObject _context;
+
+  HeapObject get context => _context;
+
+  void set context(HeapObject value) {
+    _context = value;
+    render();
+  }
+
+  EvalBoxElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  void render() {
+    shadowRoot.children = [];
+    if (_context == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        eval-box-wrapped a[href]:hover {
+            text-decoration: underline;
+        }
+        eval-box-wrapped a[href] {
+            color: #0489c3;
+            text-decoration: none;
+        }
+        eval-box-wrapped .quicks > button:hover {
+          background-color: transparent;
+          border: none;
+          text-decoration: underline;
+        }
+        eval-box-wrapped .quicks > button {
+          background-color: transparent;
+          border: none;
+          color: #0489c3;
+          padding: 0;
+          margin-right: 1em;
+          text-decoration: none;
+        }
+        eval-box-wrapped .empathize {
+          font-style: italic;
+        }
+        eval-box-wrapped .indent {
+          margin-left: 1.5em;
+          font: 400 14px 'Montserrat', sans-serif;
+          line-height: 150%;
+        }
+        eval-box-wrapped .stackTraceBox {
+          margin-left: 1.5em;
+          background-color: #f5f5f5;
+          border: 1px solid #ccc;
+          padding: 10px;
+          font-family: consolas, courier, monospace;
+          font-size: 12px;
+          white-space: pre;
+          overflow-x: auto;
+        }
+        eval-box-wrapped .heading {
+          line-height: 30px;
+          position: relative;
+          box-sizing: border-box;
+          width: 100%;
+          min-width: 450px;
+          padding-right: 150px;
+        }
+        eval-box-wrapped .heading .textbox {
+          width: 100%;
+          min-width: 300px;
+        }
+        eval-box-wrapped .heading .buttons {
+          position: absolute;
+          top: 0;
+          right: 0px;
+        }
+        eval-box-wrapped.historyExpr,
+        eval-box-wrapped .historyValue {
+          vertical-align: text-top;
+          font: 400 14px 'Montserrat', sans-serif;
+        }
+        eval-box-wrapped .historyExpr button {
+          display: block;
+          color: black;
+          border: none;
+          background: none;
+          text-decoration: none;
+          padding: 6px 6px;
+          cursor: pointer;
+          white-space: pre-line;
+        }
+        eval-box-wrapped .historyExpr button:hover {
+          background-color: #fff3e3;
+        }
+        eval-box-wrapped .historyValue {
+          display: block;
+          padding: 6px 6px;
+        }
+        eval-box-wrapped .historyDelete button {
+          border: none;
+          background: none;
+        }
+        eval-box-wrapped .historyDelete button:hover {
+          color: #BB3311;
+        }
+        ''',
+      new EvalBoxElement(_context.isolate, _context,
+                          new InstanceRepository(),
+                          new EvalRepository(),
+                          queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/field_view.dart b/runtime/observatory/lib/src/elements/field_view.dart
index 234336d..991fa24 100644
--- a/runtime/observatory/lib/src/elements/field_view.dart
+++ b/runtime/observatory/lib/src/elements/field_view.dart
@@ -5,16 +5,290 @@
 library field_view_element;
 
 import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/class_menu.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/source_link.dart';
+import 'package:observatory/src/elements/view_footer.dart';
 
-@CustomTag('field-view')
-class FieldViewElement extends ObservatoryElement {
-  @published Field field;
+class FieldViewElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<FieldViewElement>('field-view',
+                                            dependencies: const [
+                                              ClassRefElement.tag,
+                                              CurlyBlockElement.tag,
+                                              NavBarElement.tag,
+                                              NavClassMenuElement.tag,
+                                              NavLibraryMenuElement.tag,
+                                              NavTopMenuElement.tag,
+                                              NavVMMenuElement.tag,
+                                              NavIsolateMenuElement.tag,
+                                              NavMenuElement.tag,
+                                              NavRefreshElement.tag,
+                                              NavNotifyElement.tag,
+                                              ObjectCommonElement.tag,
+                                              ScriptInsetElement.tag,
+                                              SourceLinkElement.tag,
+                                              ViewFooterElement.tag
+                                            ]);
+
+  RenderingScheduler<FieldViewElement> _r;
+
+  Stream<RenderedEvent<FieldViewElement>> get onRendered => _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.Field _field;
+  M.LibraryRef _library;
+  M.FieldRepository _fields;
+  M.ClassRepository _classes;
+  M.RetainedSizeRepository _retainedSizes;
+  M.ReachableSizeRepository _reachableSizes;
+  M.InboundReferencesRepository _references;
+  M.RetainingPathRepository _retainingPaths;
+  M.ScriptRepository _scripts;
+  M.InstanceRepository _instances;
+
+
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+  M.Field get field => _field;
+
+  factory FieldViewElement(M.VM vm, M.IsolateRef isolate, M.Field field,
+                            M.EventRepository events,
+                            M.NotificationRepository notifications,
+                            M.FieldRepository fields,
+                            M.ClassRepository classes,
+                            M.RetainedSizeRepository retainedSizes,
+                            M.ReachableSizeRepository reachableSizes,
+                            M.InboundReferencesRepository references,
+                            M.RetainingPathRepository retainingPaths,
+                            M.ScriptRepository scripts,
+                            M.InstanceRepository instances,
+                            {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(field != null);
+    assert(fields != null);
+    assert(classes != null);
+    assert(retainedSizes != null);
+    assert(reachableSizes != null);
+    assert(references != null);
+    assert(retainingPaths != null);
+    assert(scripts != null);
+    assert(instances != null);
+    FieldViewElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._field = field;
+    e._fields = fields;
+    e._classes = classes;
+    e._retainedSizes = retainedSizes;
+    e._reachableSizes = reachableSizes;
+    e._references = references;
+    e._retainingPaths = retainingPaths;
+    e._scripts = scripts;
+    e._instances = instances;
+    if (field.dartOwner is M.LibraryRef) {
+      e._library = field.dartOwner;
+    }
+    return e;
+  }
+
   FieldViewElement.created() : super.created();
 
-  Future refresh() {
-    return field.reload();
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+    _refresh();
+  }
+
+  @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    var header = '';
+    if (_field.isStatic) {
+      if (_field.dartOwner is M.ClassRef) {
+        header += 'static ';
+      } else {
+        header += 'top-level ';
+      }
+    }
+    if (_field.isFinal) {
+      header += 'final ';
+    } else if (_field.isConst) {
+      header += 'const ';
+    }
+    if (_field.declaredType.name == 'dynamic'){
+      header += 'var';
+    } else {
+      header += _field.declaredType.name;
+    }
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = _createMenu(),
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h2()..text = '$header ${field.name}',
+          new HRElement(),
+          new ObjectCommonElement(_isolate, _field, _retainedSizes,
+                                  _reachableSizes, _references, _retainingPaths,
+                                  _instances, queue: _r.queue),
+          new BRElement(),
+          new DivElement()..classes = ['memberList']
+            ..children = _createMembers(),
+          new HRElement(),
+          new DivElement()
+            ..children = _field.location == null ? const []
+              : [
+                  new ScriptInsetElement(_isolate, _field.location.script,
+                                         _scripts, _instances, _events,
+                                         startPos: field.location.tokenPos,
+                                         endPos: field.location.tokenPos,
+                                         queue: _r.queue)
+              ],
+          new ViewFooterElement(queue: _r.queue)
+        ]
+      ];
+  }
+
+  List<Element> _createMenu() {
+    final menu = [
+      new NavTopMenuElement(queue: _r.queue),
+      new NavVMMenuElement(_vm, _events, queue: _r.queue),
+      new NavIsolateMenuElement(_isolate, _events, queue: _r.queue)
+    ];
+    if (_library != null) {
+      menu.add(new NavLibraryMenuElement(_isolate, _field.dartOwner,
+                                         queue: _r.queue));
+    } else if (_field.dartOwner is M.ClassRef) {
+      menu.add(
+        new NavClassMenuElement(_isolate, _field.dartOwner, queue: _r.queue),
+      );
+    }
+    menu.addAll([
+      new NavMenuElement(_field.name, last: true, queue: _r.queue),
+      new NavRefreshElement(queue: _r.queue)
+          ..onRefresh.listen((e) {
+            e.element.disabled = true;
+            _refresh();
+          }),
+      new NavNotifyElement(_notifications, queue: _r.queue)
+    ]);
+    return menu;
+  }
+
+  List<Element> _createMembers() {
+    final members = <Element>[
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'owner',
+          new DivElement()..classes = ['memberName']
+            ..children = [
+              _field.dartOwner == null
+                ? (new SpanElement()..text = '...')
+                : anyRef(_isolate, _field.dartOwner, _instances,
+                         queue: _r.queue)
+            ]
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'script',
+          new DivElement()..classes = ['memberName']
+            ..children = [
+              new SourceLinkElement(_isolate, field.location, _scripts,
+                                    queue: _r.queue)
+            ]
+        ]
+    ];
+    if (!_field.isStatic) {
+      members.add(
+        new DivElement()..classes = ['memberItem']
+          ..title = 'The types observed for this field at runtime. '
+                    'Fields that are observed to have a single type at runtime '
+                    'or to never be null may allow for additional optimization.'
+          ..children = [
+            new DivElement()..classes = ['memberName']
+              ..text = 'observed types',
+            new DivElement()..classes = ['memberName']
+              ..children = _createGuard()
+          ]
+      );
+    }
+    if (_field.staticValue != null) {
+      members.add(
+        new DivElement()..classes = ['memberItem']
+          ..children = [
+            new DivElement()..classes = ['memberName']
+              ..text = 'static value',
+            new DivElement()..classes = ['memberName']
+              ..children = [
+                anyRef(_isolate, _field.staticValue, _instances,
+                       queue: _r.queue)
+              ]
+          ]
+      );
+    }
+    return members;
+  }
+
+  List<Element> _createGuard() {
+    final guard = <Element>[];
+    switch (_field.guardClassKind) {
+      case M.GuardClassKind.unknown:
+        guard.add(new SpanElement()..text = 'none');
+        break;
+      case M.GuardClassKind.dynamic:
+        guard.add(new SpanElement()..text = 'various');
+        break;
+      case M.GuardClassKind.single:
+        guard.add(new ClassRefElement(_isolate, _field.guardClass,
+                                      queue: _r.queue));
+        break;
+    }
+    guard.add(new SpanElement()
+      ..text = _field.guardNullable ? '— null observed' : '— null not observed'
+    );
+    return guard;
+  }
+
+  Future _refresh() async {
+    _field = await _fields.get(_isolate, _field.id);
+    if (_field.dartOwner is M.LibraryRef) {
+      _library = _field.dartOwner;
+    } else if (_field.dartOwner is M.ClassRef) {
+      _library = (await _classes.get(_isolate, _field.dartOwner.id)).library;
+    }
+    _r.dirty();
   }
 }
diff --git a/runtime/observatory/lib/src/elements/field_view.html b/runtime/observatory/lib/src/elements/field_view.html
deleted file mode 100644
index 1ed32f9..0000000
--- a/runtime/observatory/lib/src/elements/field_view.html
+++ /dev/null
@@ -1,99 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="field-view">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ field.isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ field.isolate }}"></isolate-nav-menu>
-      <library-nav-menu library="{{ field.library }}"></library-nav-menu>
-      <template if="{{ field.dartOwner is ServiceClass }}">
-        <class-nav-menu cls="{{ field.dartOwner }}"></class-nav-menu>
-      </template>
-      <nav-menu link="{{ makeLink('/inspect', field) }}" anchor="{{ field.name }}" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-    </nav-bar>
-
-    <div class="content">
-      <h1>
-        field
-        <template if="{{ field.isStatic }}">static</template>
-        <template if="{{ field.isFinal }}">final</template>
-        <template if="{{ field.isConst }}">const</template>
-        <template if="{{ (field.declaredType.name == 'dynamic' &&
-                         !field.isFinal && !field.isConst) }}">
-          var
-        </template>
-        <template if="{{ (field.declaredType.name != 'dynamic') }}">
-          {{ field.declaredType.name }}
-        </template>
-        {{ field.name }}
-      </h1>
-
-      <object-common object="{{ field }}"></object-common>
-      <br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">owner</div>
-          <div class="memberValue">
-            <any-service-ref ref="{{ field.dartOwner }}"></any-service-ref>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">script</div>
-          <div class="memberValue">
-            <source-link location="{{ field.location }}"></source-link>
-          </div>
-        </div>
-        <template if="{{ !field.isStatic }}">
-          <div class="memberItem"
-               title="The types observed for this field at runtime.  Fields that are observed to have a single type at runtime or to never be null may allow for additional optimization.">
-            <div class="memberName">observed types</div>
-            <div class="memberValue">
-              <template if="{{ field.guardClass == 'dynamic' }}">
-                various
-              </template>
-              <template if="{{ field.guardClass == 'unknown' }}">
-                none
-              </template>
-              <template if="{{ field.guardClass != null &&
-                            field.guardClass != 'unknown' &&
-                            field.guardClass != 'dynamic' }}">
-                <class-ref ref="{{ field.guardClass }}"></class-ref>
-                <template if="{{ field.guardNullable }}">
-                  &mdash; null observed
-                </template>
-                <template if="{{ !field.guardNullable }}">
-                  &mdash; null not observed
-                </template>
-              </template>
-            </div>
-          </div>
-        </template>
-        <template if="{{ field.staticValue != null }}">
-          <div class="memberItem">
-            <div class="memberName">static value</div>
-            <div class="memberValue">
-              <any-service-ref ref="{{ field.staticValue }}"></any-service-ref>
-            </div>
-          </div>
-        </template>
-      </div>
-    </div>
-
-    <div class="content-centered-big">
-      <hr>
-      <script-inset script="{{ field.location.script }}"
-                    startPos="{{ field.location.tokenPos }}"
-                    endPos="{{ field.location.tokenPos }}">
-      </script-inset>
-    </div>
-
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="field_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/function_view.dart b/runtime/observatory/lib/src/elements/function_view.dart
index 58f206b..76c5360 100644
--- a/runtime/observatory/lib/src/elements/function_view.dart
+++ b/runtime/observatory/lib/src/elements/function_view.dart
@@ -5,17 +5,392 @@
 library function_view_element;
 
 import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/class_ref.dart';
+import 'package:observatory/src/elements/code_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/field_ref.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/class_menu.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/source_inset.dart';
+import 'package:observatory/src/elements/source_link.dart';
+import 'package:observatory/src/elements/view_footer.dart';
 
-import 'package:polymer/polymer.dart';
+class FunctionViewElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<FunctionViewElement>('function-view',
+                                            dependencies: const [
+                                              ClassRefElement.tag,
+                                              CodeRefElement.tag,
+                                              CurlyBlockElement.tag,
+                                              FieldRefElement.tag,
+                                              InstanceRefElement.tag,
+                                              NavBarElement.tag,
+                                              NavClassMenuElement.tag,
+                                              NavLibraryMenuElement.tag,
+                                              NavTopMenuElement.tag,
+                                              NavVMMenuElement.tag,
+                                              NavIsolateMenuElement.tag,
+                                              NavMenuElement.tag,
+                                              NavRefreshElement.tag,
+                                              NavNotifyElement.tag,
+                                              ObjectCommonElement.tag,
+                                              SourceLinkElement.tag,
+                                              SourceInsetElement.tag,
+                                              ViewFooterElement.tag
+                                            ]);
 
-@CustomTag('function-view')
-class FunctionViewElement extends ObservatoryElement {
-  @published ServiceFunction function;
+  RenderingScheduler<FunctionViewElement> _r;
+
+  Stream<RenderedEvent<FunctionViewElement>> get onRendered => _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.Function _function;
+  M.LibraryRef _library;
+  M.FunctionRepository _functions;
+  M.ClassRepository _classes;
+  M.RetainedSizeRepository _retainedSizes;
+  M.ReachableSizeRepository _reachableSizes;
+  M.InboundReferencesRepository _references;
+  M.RetainingPathRepository _retainingPaths;
+  M.ScriptRepository _scripts;
+  M.InstanceRepository _instances;
+
+
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+  M.Function get function => _function;
+
+  factory FunctionViewElement(M.VM vm, M.IsolateRef isolate, M.Function function,
+                              M.EventRepository events,
+                              M.NotificationRepository notifications,
+                              M.FunctionRepository functions,
+                              M.ClassRepository classes,
+                              M.RetainedSizeRepository retainedSizes,
+                              M.ReachableSizeRepository reachableSizes,
+                              M.InboundReferencesRepository references,
+                              M.RetainingPathRepository retainingPaths,
+                              M.ScriptRepository scripts,
+                              M.InstanceRepository instances,
+                              {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(function != null);
+    assert(functions != null);
+    assert(classes != null);
+    assert(retainedSizes != null);
+    assert(reachableSizes != null);
+    assert(references != null);
+    assert(retainingPaths != null);
+    assert(scripts != null);
+    assert(instances != null);
+    FunctionViewElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._function = function;
+    e._functions = functions;
+    e._classes = classes;
+    e._retainedSizes = retainedSizes;
+    e._reachableSizes = reachableSizes;
+    e._references = references;
+    e._retainingPaths = retainingPaths;
+    e._scripts = scripts;
+    e._instances = instances;
+    if (function.dartOwner is M.LibraryRef) {
+      e._library = function.dartOwner;
+    }
+    return e;
+  }
+
   FunctionViewElement.created() : super.created();
 
-  Future refresh() {
-    return function.reload();
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+    _refresh();
+  }
+
+  @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = _createMenu(),
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h2()..text = 'Function ${_function.name}',
+          new HRElement(),
+          new ObjectCommonElement(_isolate, _function, _retainedSizes,
+                                  _reachableSizes, _references, _retainingPaths,
+                                  _instances, queue: _r.queue),
+          new BRElement(),
+          new DivElement()..classes = ['memberList']
+            ..children = _createMembers(),
+          new HRElement(),
+          new DivElement()
+            ..children = _function.location == null ? const []
+              : [
+                  new SourceInsetElement(_isolate, _function.location, _scripts,
+                                         _instances, _events, queue: _r.queue)
+              ],
+          new ViewFooterElement(queue: _r.queue)
+        ]
+      ];
+  }
+
+  List<Element> _createMenu() {
+    final menu = [
+      new NavTopMenuElement(queue: _r.queue),
+      new NavVMMenuElement(_vm, _events, queue: _r.queue),
+      new NavIsolateMenuElement(_isolate, _events, queue: _r.queue)
+    ];
+    if (_library != null) {
+      menu.add(new NavLibraryMenuElement(_isolate, _function.dartOwner,
+                                         queue: _r.queue));
+    } else if (_function.dartOwner is M.ClassRef) {
+      menu.add(
+        new NavClassMenuElement(_isolate, _function.dartOwner, queue: _r.queue)
+      );
+    }
+    menu.addAll([
+      new NavMenuElement(_function.name, last: true, queue: _r.queue),
+      new NavRefreshElement(queue: _r.queue)
+          ..onRefresh.listen((e) {
+            e.element.disabled = true;
+            _refresh();
+          }),
+      new NavNotifyElement(_notifications, queue: _r.queue)
+    ]);
+    return menu;
+  }
+
+  List<Element> _createMembers() {
+    final members = <Element>[
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'kind',
+          new DivElement()..classes = ['memberName']
+            ..children = [
+              new SpanElement()
+                ..text = '${_function.isStatic ? "static ": ""}'
+                         '${_function.isConst ? "const ": ""}'
+                         '${_functionKindToString(_function.kind)}'
+            ]
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'owner',
+          new DivElement()..classes = ['memberName']
+            ..children = [
+              _function.dartOwner == null
+                ? (new SpanElement()..text = '...')
+                : anyRef(_isolate, _function.dartOwner, _instances,
+                         queue: _r.queue)
+            ]
+        ]
+    ];
+    if (_function.field != null) {
+      members.add(
+        new DivElement()..classes = ['memberItem']
+          ..children = [
+            new DivElement()..classes = ['memberName']
+              ..text = 'script',
+            new DivElement()..classes = ['memberName']
+              ..children = [
+                new FieldRefElement(_isolate, _function.field, _instances,
+                                    queue: _r.queue)
+              ]
+          ]
+      );
+    }
+    members.add(
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'script',
+          new DivElement()..classes = ['memberName']
+            ..children = [
+              new SourceLinkElement(_isolate, _function.location, _scripts,
+                                    queue: _r.queue)
+            ]
+        ]
+    );
+    if (_function.code != null) {
+      members.add(
+        new DivElement()..classes = ['memberItem']
+          ..children = [
+            new DivElement()..classes = ['memberName']
+              ..text = 'current code',
+            new DivElement()..classes = ['memberName']
+              ..children = [
+                new CodeRefElement(_isolate, _function.code, queue: _r.queue)
+              ]
+          ]
+      );
+    }
+    if (_function.unoptimizedCode != null) {
+      members.add(
+        new DivElement()..classes = ['memberItem']
+          ..children = [
+            new DivElement()..classes = ['memberName']
+              ..text = 'unoptimized code',
+            new DivElement()..classes = ['memberName']
+              ..children = [
+                new CodeRefElement(_isolate, _function.unoptimizedCode,
+                                   queue: _r.queue),
+                new SpanElement()
+                  ..title = 'This count is used to determine when a function '
+                             'will be optimized.  It is a combination of call '
+                             'counts and other factors.'
+                  ..text = ' (usage count: ${function.usageCounter })'
+              ]
+          ]
+      );
+    }
+    members.addAll([
+      new DivElement()..classes = ['memberItem']
+        ..text = ' ',
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'ic data array',
+          new DivElement()..classes = ['memberName']
+            ..children = [
+              new InstanceRefElement(_isolate, _function.icDataArray,
+                                     _instances, queue: _r.queue)
+            ]
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'deoptimizations',
+          new DivElement()..classes = ['memberName']
+            ..text = '${_function.deoptimizations}'
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'optimizable',
+          new DivElement()..classes = ['memberName']
+            ..text = _function.isOptimizable ? 'yes' : 'no'
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'inlinable',
+          new DivElement()..classes = ['memberName']
+            ..text = _function.isInlinable ? 'yes' : 'no'
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'intrinsic',
+          new DivElement()..classes = ['memberName']
+            ..text = _function.hasIntrinsic ? 'yes' : 'no'
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'recognized',
+          new DivElement()..classes = ['memberName']
+            ..text = _function.isRecognized ? 'yes' : 'no'
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'native',
+          new DivElement()..classes = ['memberName']
+            ..text = _function.isNative ? 'yes' : 'no'
+        ],
+      new DivElement()..classes = ['memberItem']
+        ..children = [
+          new DivElement()..classes = ['memberName']
+            ..text = 'vm name',
+          new DivElement()..classes = ['memberName']
+            ..text = _function.vmName
+        ]
+    ]);
+    return members;
+  }
+
+  Future _refresh() async {
+    _function = await _functions.get(_isolate, _function.id);
+    if (_function.dartOwner is M.LibraryRef) {
+      _library = _function.dartOwner;
+    } else if (_function.dartOwner is M.ClassRef) {
+      _library = (await _classes.get(_isolate, _function.dartOwner.id)).library;
+    }
+    _r.dirty();
+  }
+
+  static String _functionKindToString(M.FunctionKind kind) {
+    switch(kind) {
+      case M.FunctionKind.regular:
+        return 'regular';
+      case M.FunctionKind.closure:
+        return 'closure';
+      case M.FunctionKind.getter:
+        return 'getter';
+      case M.FunctionKind.setter:
+        return 'setter';
+      case M.FunctionKind.constructor:
+        return 'constructor';
+      case M.FunctionKind.implicitGetter:
+        return 'implicit getter';
+      case M.FunctionKind.implicitSetter:
+        return 'implicit setter';
+      case M.FunctionKind.implicitStaticFinalGetter:
+        return 'implicit static final getter';
+      case M.FunctionKind.irregexpFunction:
+        return 'irregexp function';
+      case M.FunctionKind.staticInitializer:
+        return 'static initializer';
+      case M.FunctionKind.methodExtractor:
+        return 'method extractor';
+      case M.FunctionKind.noSuchMethodDispatcher:
+        return 'noSuchMethod dispatcher';
+      case M.FunctionKind.invokeFieldDispatcher:
+        return 'invokeField dispatcher';
+      case M.FunctionKind.collected:
+        return 'collected';
+      case M.FunctionKind.native:
+        return 'native';
+      case M.FunctionKind.stub:
+        return 'stub';
+      case M.FunctionKind.tag:
+        return 'tag';
+      case M.FunctionKind.signatureFunction:
+        return 'signature function';
+    }
+    throw new Exception('Unknown Functionkind ($kind)');
   }
 }
diff --git a/runtime/observatory/lib/src/elements/function_view.html b/runtime/observatory/lib/src/elements/function_view.html
deleted file mode 100644
index a196455..0000000
--- a/runtime/observatory/lib/src/elements/function_view.html
+++ /dev/null
@@ -1,127 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="script_inset.html">
-
-<polymer-element name="function-view">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ function.isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ function.isolate }}"></isolate-nav-menu>
-      <library-nav-menu library="{{ function.library }}"></library-nav-menu>
-      <template if="{{ function.dartOwner is ServiceClass }}">
-        <class-nav-menu cls="{{ function.dartOwner }}"></class-nav-menu>
-      </template>
-      <nav-menu link="{{ makeLink('/inspect', function) }}" anchor="{{ function.name }}" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-    </nav-bar>
-
-    <div class="content">
-      <h1>function {{ function.qualifiedName }}</h1>
-
-      <object-common object="{{ function }}"></object-common>
-      <br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">kind</div>
-          <div class="memberValue">
-            <template if="{{ function.isStatic }}">static</template>
-            <template if="{{ function.isConst }}">const</template>
-            {{ function.kind.toString() }}
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">owner</div>
-          <div class="memberValue">
-            <any-service-ref ref="{{ function.dartOwner }}"></any-service-ref>
-          </div>
-        </div>
-        <template if="{{ function.field != null }}">
-          <div class="memberItem">
-            <div class="memberName">field</div>
-            <div class="memberValue">
-              <any-service-ref ref="{{ function.field }}"></any-service-ref>
-            </div>
-          </div>
-        </template>
-        <div class="memberItem">
-          <div class="memberName">script</div>
-          <div class="memberValue">
-            <source-link location="{{ function.location }}"></source-link>
-          </div>
-        </div>
-
-        <div class="memberItem">&nbsp;</div>
-
-        <template if="{{ function.code != null }}">
-          <div class="memberItem">
-            <div class="memberName">current code</div>
-            <div class="memberValue">
-              <code-ref ref="{{ function.code }}"></code-ref>
-            </div>
-          </div>
-        </template>
-        <template if="{{ function.unoptimizedCode != null }}">
-          <div class="memberItem">
-            <div class="memberName">unoptimized code</div>
-            <div class="memberValue">
-              <code-ref ref="{{ function.unoptimizedCode }}"></code-ref>
-            </div>
-              <div class="memberValue">
-                <span title="This count is used to determine when a function will be optimized.  It is a combination of call counts and other factors.">
-                  (usage count: {{ function.usageCounter }})
-                </span>
-             </div>
-           </div>
-         </template>
-         <div class="memberItem">
-           <div class="memberName">ic data array</div>
-           <div class="memberValue">
-             <instance-ref ref="{{ function.icDataArray }}"></instance-ref>
-           </div>
-         </div>
-         <div class="memberItem">
-           <div class="memberName">deoptimizations</div>
-           <div class="memberValue">{{ function.deoptimizations }}</div>
-         </div>
-         <div class="memberItem">
-           <div class="memberName">optimizable</div>
-           <div class="memberValue">{{ function.isOptimizable }}</div>
-         </div>
-         <div class="memberItem">
-           <div class="memberName">inlinable</div>
-           <div class="memberValue">{{ function.isInlinable }}</div>
-         </div>
-         <div class="memberItem">
-           <div class="memberName">intrinsic</div>
-           <div class="memberValue">{{ function.hasIntrinsic }}</div>
-         </div>
-         <div class="memberItem">
-           <div class="memberName">recognized</div>
-           <div class="memberValue">{{ function.isRecognized }}</div>
-         </div>
-         <div class="memberItem">
-           <div class="memberName">native</div>
-           <div class="memberValue">{{ function.isNative }}</div>
-         </div>
-         <template if="{{ function.name != function.vmName }}">
-           <div class="memberItem">
-             <div class="memberName">vm name</div>
-             <div class="memberValue">{{ function.vmName }}</div>
-           </div>
-         </template>
-       </div>
-    </div>
-
-    <div class="content-centered-big">
-      <hr>
-      <source-inset location="{{ function.location }}"></source-inset>
-    </div>
-
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="function_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/heap_map.dart b/runtime/observatory/lib/src/elements/heap_map.dart
index a91e316..1797239 100644
--- a/runtime/observatory/lib/src/elements/heap_map.dart
+++ b/runtime/observatory/lib/src/elements/heap_map.dart
@@ -7,10 +7,284 @@
 import 'dart:async';
 import 'dart:html';
 import 'dart:math';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:logging/logging.dart';
-import 'package:polymer/polymer.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/service.dart' as S;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+class HeapMapElement  extends HtmlElement implements Renderable {
+  static const tag = const Tag<HeapMapElement>('heap-map',
+                                            dependencies: const [
+                                              NavBarElement.tag,
+                                              NavTopMenuElement.tag,
+                                              NavVMMenuElement.tag,
+                                              NavIsolateMenuElement.tag,
+                                              NavMenuElement.tag,
+                                              NavRefreshElement.tag,
+                                              NavNotifyElement.tag,
+                                            ]);
+
+  RenderingScheduler<HeapMapElement> _r;
+
+  Stream<RenderedEvent<HeapMapElement>> get onRendered =>
+      _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+
+  factory HeapMapElement(M.VM vm, M.IsolateRef isolate,
+                         M.EventRepository events,
+                         M.NotificationRepository notifications,
+                         {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    HeapMapElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    return e;
+  }
+
+  HeapMapElement.created() : super.created();
+
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+    _refresh();
+  }
+
+  @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  CanvasElement _canvas;
+  var _fragmentationData;
+  double _pageHeight;
+  final _classIdToColor = {};
+  final _colorToClassId = {};
+  final _classIdToName = {};
+
+  static final _freeColor = [255, 255, 255, 255];
+  static final _pageSeparationColor = [0, 0, 0, 255];
+  static const _PAGE_SEPARATION_HEIGHT = 4;
+  // Many browsers will not display a very tall canvas.
+  // TODO(koda): Improve interface for huge heaps.
+  static const _MAX_CANVAS_HEIGHT = 6000;
+
+  String _status;
+  S.ServiceMap _fragmentation;
+
+  void render() {
+    if (_canvas == null) {
+      _canvas = new CanvasElement()
+                  ..width = 1
+                  ..height= 1
+                  ..onMouseMove.listen(_handleMouseMove)
+                  ..onMouseDown.listen(_handleClick);
+    }
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavMenuElement('heap map', last: true,
+              link: Uris.heapMap(_isolate), queue: _r.queue),
+          new NavRefreshElement(queue: _r.queue)
+            ..onRefresh.listen((_) => _refresh()),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h2()..text = _status,
+          new HRElement(),
+        ],
+        new DivElement()..classes = ['flex-row']
+          ..children = [_canvas]
+    ];
+  }
+
+  // Encode color as single integer, to enable using it as a map key.
+  int _packColor(Iterable<int> color) {
+    int packed = 0;
+    for (var component in color) {
+      packed = packed * 256 + component;
+    }
+    return packed;
+  }
+
+  void _addClass(int classId, String name, Iterable<int> color) {
+    _classIdToName[classId] = name.split('@')[0];
+    _classIdToColor[classId] = color;
+    _colorToClassId[_packColor(color)] = classId;
+  }
+
+  void _updateClassList(classList, int freeClassId) {
+    for (var member in classList['classes']) {
+      if (member is! S.Class) {
+        // TODO(turnidge): The printing for some of these non-class
+        // members is broken.  Fix this:
+        //
+        // Logger.root.info('$member');
+        print('Ignoring non-class in class list');
+        continue;
+      }
+      var classId = int.parse(member.id.split('/').last);
+      var color = _classIdToRGBA(classId);
+      _addClass(classId, member.name, color);
+    }
+    _addClass(freeClassId, 'Free', _freeColor);
+    _addClass(0, '', _pageSeparationColor);
+  }
+
+  Iterable<int> _classIdToRGBA(int classId) {
+    // TODO(koda): Pick random hue, but fixed saturation and value.
+    var rng = new Random(classId);
+    return [rng.nextInt(128), rng.nextInt(128), rng.nextInt(128), 255];
+  }
+
+  String _classNameAt(Point<int> point) {
+    var color = new PixelReference(_fragmentationData, point).color;
+    return _classIdToName[_colorToClassId[_packColor(color)]];
+  }
+
+  ObjectInfo _objectAt(Point<int> point) {
+    if (_fragmentation == null || _canvas == null) {
+      return null;
+    }
+    var pagePixels = _pageHeight * _fragmentationData.width;
+    var index = new PixelReference(_fragmentationData, point).index;
+    var pageIndex = index ~/ pagePixels;
+    var pageOffset = index % pagePixels;
+    var pages = _fragmentation['pages'];
+    if (pageIndex < 0 || pageIndex >= pages.length) {
+      return null;
+    }
+    // Scan the page to find start and size.
+    var page = pages[pageIndex];
+    var objects = page['objects'];
+    var offset = 0;
+    var size = 0;
+    for (var i = 0; i < objects.length; i += 2) {
+      size = objects[i];
+      offset += size;
+      if (offset > pageOffset) {
+        pageOffset = offset - size;
+        break;
+      }
+    }
+    return new ObjectInfo(int.parse(page['objectStart']) +
+                          pageOffset * _fragmentation['unitSizeBytes'],
+        size * _fragmentation['unitSizeBytes']);
+  }
+
+  void _handleMouseMove(MouseEvent event) {
+    var info = _objectAt(event.offset);
+    if (info == null) {
+      _status = '';
+      _r.dirty();
+      return;
+    }
+    var addressString = '${info.size}B @ 0x${info.address.toRadixString(16)}';
+    var className = _classNameAt(event.offset);
+    _status = (className == '') ? '-' : '$className $addressString';
+    _r.dirty();
+  }
+
+  void _handleClick(MouseEvent event) {
+    final isolate = _isolate as S.Isolate;
+    final address = _objectAt(event.offset).address.toRadixString(16);
+    isolate.getObjectByAddress(address).then((result) {
+      if (result.type != 'Sentinel') {
+        new AnchorElement(
+          href: Uris.inspect(_isolate, object: result as S.HeapObject)
+        ).click();
+      }
+    });
+  }
+
+  void _updateFragmentationData() {
+    if (_fragmentation == null || _canvas == null) {
+      return;
+    }
+    _updateClassList(
+        _fragmentation['classList'], _fragmentation['freeClassId']);
+    var pages = _fragmentation['pages'];
+    var width = _canvas.parent.client.width;
+    _pageHeight = _PAGE_SEPARATION_HEIGHT +
+        _fragmentation['pageSizeBytes'] ~/
+        _fragmentation['unitSizeBytes'] ~/ width;
+    var height = min(_pageHeight * pages.length, _MAX_CANVAS_HEIGHT);
+    _fragmentationData =
+        _canvas.context2D.createImageData(width, height);
+    _canvas.width = _fragmentationData.width;
+    _canvas.height = _fragmentationData.height;
+    _renderPages(0);
+  }
+
+  // Renders and draws asynchronously, one page at a time to avoid
+  // blocking the UI.
+  void _renderPages(int startPage) {
+    var pages = _fragmentation['pages'];
+    _status = 'Loaded $startPage of ${pages.length} pages';
+    _r.dirty();
+    var startY = startPage * _pageHeight;
+    var endY = startY + _pageHeight;
+    if (startPage >= pages.length || endY > _fragmentationData.height) {
+      return;
+    }
+    var pixel = new PixelReference(_fragmentationData, new Point(0, startY));
+    var objects = pages[startPage]['objects'];
+    for (var i = 0; i < objects.length; i += 2) {
+      var count = objects[i];
+      var classId = objects[i + 1];
+      var color = _classIdToColor[classId];
+      while (count-- > 0) {
+        pixel.color = color;
+        pixel = pixel.next();
+      }
+    }
+    while (pixel.point.y < endY) {
+      pixel.color = _pageSeparationColor;
+      pixel = pixel.next();
+    }
+    _canvas.context2D.putImageData(
+        _fragmentationData, 0, 0, 0, startY, _fragmentationData.width, endY);
+    // Continue with the next page, asynchronously.
+    new Future(() {
+      _renderPages(startPage + 1);
+    });
+  }
+
+  Future _refresh() {
+    final isolate = _isolate as S.Isolate;
+    return isolate.invokeRpc('_getHeapMap', {}).then((S.ServiceMap response) {
+      assert(response['type'] == 'HeapMap');
+      _fragmentation = response;
+      _updateFragmentationData();
+    });
+  }
+}
 
 // A reference to a particular pixel of ImageData.
 class PixelReference {
@@ -48,211 +322,3 @@
   final size;
   ObjectInfo(this.address, this.size);
 }
-
-@CustomTag('heap-map')
-class HeapMapElement extends ObservatoryElement {
-  CanvasElement _fragmentationCanvas;
-  var _fragmentationData;
-  var _pageHeight;
-  var _classIdToColor = {};
-  var _colorToClassId = {};
-  var _classIdToName = {};
-
-  static final _freeColor = [255, 255, 255, 255];
-  static final _pageSeparationColor = [0, 0, 0, 255];
-  static const _PAGE_SEPARATION_HEIGHT = 4;
-  // Many browsers will not display a very tall canvas.
-  // TODO(koda): Improve interface for huge heaps.
-  static const _MAX_CANVAS_HEIGHT = 6000;
-
-  @observable String status;
-  @published Isolate isolate;
-  @observable ServiceMap fragmentation;
-
-  HeapMapElement.created() : super.created() {
-  }
-
-  @override
-  void attached() {
-    super.attached();
-    _fragmentationCanvas = shadowRoot.querySelector("#fragmentation");
-    _fragmentationCanvas.onMouseMove.listen(_handleMouseMove);
-    _fragmentationCanvas.onMouseDown.listen(_handleClick);
-  }
-
-  // Encode color as single integer, to enable using it as a map key.
-  int _packColor(Iterable<int> color) {
-    int packed = 0;
-    for (var component in color) {
-      packed = packed * 256 + component;
-    }
-    return packed;
-  }
-
-  void _addClass(int classId, String name, Iterable<int> color) {
-    _classIdToName[classId] = name.split('@')[0];
-    _classIdToColor[classId] = color;
-    _colorToClassId[_packColor(color)] = classId;
-  }
-
-  void _updateClassList(classList, int freeClassId) {
-    for (var member in classList['classes']) {
-      if (member is! Class) {
-        // TODO(turnidge): The printing for some of these non-class
-        // members is broken.  Fix this:
-        //
-        // Logger.root.info('$member');
-        Logger.root.info('Ignoring non-class in class list');
-        continue;
-      }
-      var classId = int.parse(member.id.split('/').last);
-      var color = _classIdToRGBA(classId);
-      _addClass(classId, member.name, color);
-    }
-    _addClass(freeClassId, 'Free', _freeColor);
-    _addClass(0, '', _pageSeparationColor);
-  }
-
-  Iterable<int> _classIdToRGBA(int classId) {
-    // TODO(koda): Pick random hue, but fixed saturation and value.
-    var rng = new Random(classId);
-    return [rng.nextInt(128), rng.nextInt(128), rng.nextInt(128), 255];
-  }
-
-  String _classNameAt(Point<int> point) {
-    var color = new PixelReference(_fragmentationData, point).color;
-    return _classIdToName[_colorToClassId[_packColor(color)]];
-  }
-
-  ObjectInfo _objectAt(Point<int> point) {
-    if (fragmentation == null || _fragmentationCanvas == null) {
-      return null;
-    }
-    var pagePixels = _pageHeight * _fragmentationData.width;
-    var index = new PixelReference(_fragmentationData, point).index;
-    var pageIndex = index ~/ pagePixels;
-    var pageOffset = index % pagePixels;
-    var pages = fragmentation['pages'];
-    if (pageIndex < 0 || pageIndex >= pages.length) {
-      return null;
-    }
-    // Scan the page to find start and size.
-    var page = pages[pageIndex];
-    var objects = page['objects'];
-    var offset = 0;
-    var size = 0;
-    for (var i = 0; i < objects.length; i += 2) {
-      size = objects[i];
-      offset += size;
-      if (offset > pageOffset) {
-        pageOffset = offset - size;
-        break;
-      }
-    }
-    return new ObjectInfo(int.parse(page['objectStart']) +
-                          pageOffset * fragmentation['unitSizeBytes'],
-        size * fragmentation['unitSizeBytes']);
-  }
-
-  void _handleMouseMove(MouseEvent event) {
-    var info = _objectAt(event.offset);
-    if (info == null) {
-      status = '';
-      return;
-    }
-    var addressString = '${info.size}B @ 0x${info.address.toRadixString(16)}';
-    var className = _classNameAt(event.offset);
-    status = (className == '') ? '-' : '$className $addressString';
-  }
-
-  void _handleClick(MouseEvent event) {
-    var address = _objectAt(event.offset).address.toRadixString(16);
-    isolate.getObjectByAddress(address).then((result) {
-      if (result.type != 'Sentinel') {
-        app.locationManager.go(gotoLink('/inspect', result));
-      }
-    });
-  }
-
-  void _updateFragmentationData() {
-    if (fragmentation == null || _fragmentationCanvas == null) {
-      return;
-    }
-    _updateClassList(
-        fragmentation['classList'], fragmentation['freeClassId']);
-    var pages = fragmentation['pages'];
-    var width = _fragmentationCanvas.parent.client.width;
-    _pageHeight = _PAGE_SEPARATION_HEIGHT +
-        fragmentation['pageSizeBytes'] ~/
-        fragmentation['unitSizeBytes'] ~/ width;
-    var height = min(_pageHeight * pages.length, _MAX_CANVAS_HEIGHT);
-    _fragmentationData =
-        _fragmentationCanvas.context2D.createImageData(width, height);
-    _fragmentationCanvas.width = _fragmentationData.width;
-    _fragmentationCanvas.height = _fragmentationData.height;
-    _renderPages(0);
-  }
-
-  // Renders and draws asynchronously, one page at a time to avoid
-  // blocking the UI.
-  void _renderPages(int startPage) {
-    var pages = fragmentation['pages'];
-    status = 'Loaded $startPage of ${pages.length} pages';
-    var startY = startPage * _pageHeight;
-    var endY = startY + _pageHeight;
-    if (startPage >= pages.length || endY > _fragmentationData.height) {
-      return;
-    }
-    var pixel = new PixelReference(_fragmentationData, new Point(0, startY));
-    var objects = pages[startPage]['objects'];
-    for (var i = 0; i < objects.length; i += 2) {
-      var count = objects[i];
-      var classId = objects[i + 1];
-      var color = _classIdToColor[classId];
-      while (count-- > 0) {
-        pixel.color = color;
-        pixel = pixel.next();
-      }
-    }
-    while (pixel.point.y < endY) {
-      pixel.color = _pageSeparationColor;
-      pixel = pixel.next();
-    }
-    _fragmentationCanvas.context2D.putImageData(
-        _fragmentationData, 0, 0, 0, startY, _fragmentationData.width, endY);
-    // Continue with the next page, asynchronously.
-    new Future(() {
-      _renderPages(startPage + 1);
-    });
-  }
-
-  void isolateChanged(oldValue) {
-    if (isolate == null) {
-      fragmentation = null;
-      return;
-    }
-    isolate.invokeRpc('_getHeapMap', {}).then((ServiceMap response) {
-      assert(response['type'] == 'HeapMap');
-      fragmentation = response;
-    }).catchError((e, st) {
-      Logger.root.info('$e $st');
-    });
-  }
-
-  Future refresh() {
-    if (isolate == null) {
-      return new Future.value(null);
-    }
-    return isolate.invokeRpc('_getHeapMap', {}).then((ServiceMap response) {
-      assert(response['type'] == 'HeapMap');
-      fragmentation = response;
-    });
-  }
-
-  void fragmentationChanged(oldValue) {
-    // Async, in case attached has not yet run (observed in JS version).
-    new Future(() {
-      _updateFragmentationData();
-    });
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/heap_map.html b/runtime/observatory/lib/src/elements/heap_map.html
deleted file mode 100644
index d68aed2..0000000
--- a/runtime/observatory/lib/src/elements/heap_map.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="heap-map">
-<template>
-  <link rel="stylesheet" href="css/shared.css">
-  <style>
-    .hover {
-      position: fixed;
-      z-index: 999;
-      height: 16px;
-      width: 100%;
-      background: #ffffff;
-    }
-    .spacer {
-      height: 16px;
-      background-color: red;
-    }
-    #fragmentation {
-      width: 100%;
-      height: 100%;
-    }
-  </style>
-  <nav-bar pad="{{ false }}">
-    <top-nav-menu></top-nav-menu>
-    <vm-nav-menu vm="{{ fragmentation.isolate.vm }}"></vm-nav-menu>
-    <isolate-nav-menu isolate="{{ fragmentation.isolate }}"></isolate-nav-menu>
-    <nav-menu link="{{ makeLink('/heap-map', fragmentation.isolate) }}" anchor="heap map" last="{{ true }}"></nav-menu>
-    <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-  </nav-bar>
-  <div class="hover">
-    <p style="text-align:center">{{ status }}</p>
-  </div>
-  <div class="spacer">
-    <!-- Make sure no data is covered by hover bar initially -->
-  </div>
-  <div class="flex-row">
-    <canvas id="fragmentation" width="1px" height="1px"></canvas>
-  </div>
-  <view-footer></view-footer>
-</template>
-</polymer-element>
-
-<script type="application/dart" src="heap_map.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/heap_snapshot.dart b/runtime/observatory/lib/src/elements/heap_snapshot.dart
index 0913e1e..e0771eb 100644
--- a/runtime/observatory/lib/src/elements/heap_snapshot.dart
+++ b/runtime/observatory/lib/src/elements/heap_snapshot.dart
@@ -111,7 +111,7 @@
           new NavTopMenuElement(queue: _r.queue),
           new NavVMMenuElement(_vm, _events, queue: _r.queue),
           new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
-          new NavMenuElement('heap snapshot', link: Uris.profiler(_isolate),
+          new NavMenuElement('heap snapshot', link: Uris.heapSnapshot(_isolate),
               last: true, queue: _r.queue),
           new NavRefreshElement(queue: _r.queue)
               ..disabled = M.isHeapSnapshotProgressRunning(_progress?.status)
diff --git a/runtime/observatory/lib/src/elements/helpers/any_ref.dart b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
index 285b476..56e2ff8 100644
--- a/runtime/observatory/lib/src/elements/helpers/any_ref.dart
+++ b/runtime/observatory/lib/src/elements/helpers/any_ref.dart
@@ -23,8 +23,8 @@
 import 'package:observatory/src/elements/token_stream_ref.dart';
 import 'package:observatory/src/elements/unknown_ref.dart';
 
-Element anyRef(M.IsolateRef isolate, ref, M.InstanceRepository instances,
-    {RenderingQueue queue}) {
+Element anyRef(M.IsolateRef isolate, ref,
+    M.InstanceRepository instances, {RenderingQueue queue}) {
   if (ref is M.Guarded) {
     return anyRef(isolate, ref.asSentinel ?? ref.asValue, instances,
         queue: queue);
diff --git a/runtime/observatory/lib/src/elements/helpers/uris.dart b/runtime/observatory/lib/src/elements/helpers/uris.dart
index b243f78..05ec28a 100644
--- a/runtime/observatory/lib/src/elements/helpers/uris.dart
+++ b/runtime/observatory/lib/src/elements/helpers/uris.dart
@@ -42,8 +42,6 @@
       => _isolatePage('/persistent-handles', isolate);
   static String ports(M.IsolateRef isolate)
       => _isolatePage('/ports', isolate);
-  static String profiler(M.IsolateRef isolate)
-      => _isolatePage('/profiler', isolate);
   static String vm() => '#/vm';
   static String vmConnect() => '#/vm-connect';
 }
diff --git a/runtime/observatory/lib/src/elements/instance_view.html b/runtime/observatory/lib/src/elements/instance_view.html
index b7c9e13..0673496 100644
--- a/runtime/observatory/lib/src/elements/instance_view.html
+++ b/runtime/observatory/lib/src/elements/instance_view.html
@@ -1,6 +1,4 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="eval_box.html">
 <link rel="import" href="eval_link.html">
 
 <polymer-element name="instance-view">
@@ -17,355 +15,349 @@
       <nav-notify notifications="{{ app.notifications }}"></nav-notify>
     </nav-bar>
 
-    <template if="{{ instance.isError }}">
-      <error-view error_obj="{{ instance['error'] }}"></error-view>
-    </template>
+    <div class="content">
+      <template if="{{ instance.isAbstractType }}">
+        <h1>type {{ instance.name }}</h1>
+      </template>
+      <template if="{{ !instance.isAbstractType }}">
+        <h1>instance of {{ instance.clazz.name }}</h1>
+      </template>
 
-    <template if="{{ !instance.isError }}">
-      <div class="content">
-        <template if="{{ instance.isAbstractType }}">
-          <h1>type {{ instance.name }}</h1>
-        </template>
-        <template if="{{ !instance.isAbstractType }}">
-          <h1>instance of {{ instance.clazz.name }}</h1>
-        </template>
+      <object-common object="{{ instance }}"></object-common>
 
-        <object-common object="{{ instance }}"></object-common>
+      <div class="memberList">
+        <div class="memberItem">&nbsp;</div>
 
-        <div class="memberList">
-          <div class="memberItem">&nbsp;</div>
-
-          <template if="{{ instance.valueAsString != null }}">
-            <div class="memberItem">
-              <div class="memberName">value</div>
-              <div class="memberValue">
-                <pre>{{ instance.valueAsString }}</pre>
-              </div>
-            </div>
-          </template>
-
-          <template if="{{ instance.isString }}">
-            <div class="memberItem">
-              <div class="memberName">valueAsLiteral</div>
-              <div class="memberValue"> {{ asStringLiteral(instance.valueAsString, instance.valueAsStringIsTruncated) }}</div>
-            </div>
-          </template>
-
-          <template if="{{ instance.typeClass != null }}">
-            <div class="memberItem">
-              <div class="memberName">type class</div>
-              <div class="memberValue">
-                <class-ref ref="{{ instance.typeClass }}">
-                </class-ref>
-              </div>
-            </div>
-          </template>
-          <template if="{{ instance.typeArguments.length > 0 }}">
-            <div class="memberItem">
-              <div class="memberName">type arguments</div>
-              <div class="memberValue">
-                &lt;
-                <template repeat="{{ index in instance.typeArguments['types'].asMap().keys }}">
-                  <instance-ref ref="{{ instance.typeArguments['types'][index] }}">
-                  </instance-ref>
-                  <template if="{{ index < instance.typeArguments['types'].length - 1 }}">
-                    ,
-                  </template>
-                </template>
-                &gt;
-              </div>
-            </div>
-          </template>
-          <template if="{{ instance.parameterizedClass != null }}">
-            <div class="memberItem">
-              <div class="memberName">parameterized class</div>
-              <div class="memberValue">
-                <class-ref ref="{{ instance.parameterizedClass }}">
-                </class-ref>
-              </div>
-            </div>
-          </template>
-          <template if="{{ instance.parameterIndex != null }}">
-            <div class="memberItem">
-              <div class="memberName">parameter index</div>
-              <div class="memberValue">
-                {{ instance.parameterIndex }}
-              </div>
-            </div>
-          </template>
-          <template if="{{ instance.targetType != null }}">
-            <div class="memberItem">
-              <div class="memberName">target type</div>
-              <div class="memberValue">
-                <instance-ref ref="{{ instance.targetType }}">
-                </instance-ref>
-              </div>
-            </div>
-          </template>
-          <template if="{{ instance.bound != null }}">
-            <div class="memberItem">
-              <div class="memberName">bound</div>
-              <div class="memberValue">
-                <instance-ref ref="{{ instance.bound }}">
-                </instance-ref>
-              </div>
-            </div>
-          </template>
-
-          <template if="{{ instance.isClosure }}">
-            <div class="memberItem">
-              <div class="memberName">closure function</div>
-              <div class="memberValue">
-                <function-ref ref="{{ instance.closureFunction }}">
-                </function-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">closure context</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.context }}">
-                </any-service-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">closure breakpoint</div>
-              <div class="memberValue">
-                <template if="{{ instance.activationBreakpoint == null }}">
-                  <action-link callback="{{ setBreakOnActivation }}"
-                               label="break on activation">
-                  </action-link>
-                </template>
-                <template if="{{ instance.activationBreakpoint != null }}">
-                  {{ instance.activationBreakpoint.toString() }}
-                  <action-link callback="{{ clearBreakOnActivation }}"
-                               label="remove">
-                  </action-link>
-                </template>
-              </div>
-            </div>
-          </template>
-
-          <div class="memberItem">
-            <div class="memberName">toString()</div>
-            <div class="memberValue">
-              <eval-link callback="{{ evaluate }}" expr="toString()"></eval-link>
-            </div>
-          </div>
-          <div class="memberItem">
-            <div class="memberName">runtimeType</div>
-            <div class="memberValue">
-              <eval-link callback="{{ evaluate }}" expr="runtimeType"></eval-link>
-            </div>
-          </div>
-        </div>
-      </div>
-
-      <hr>
-
-      <div class="content">
-        <eval-box callback="{{ evaluate }}"></eval-box>
-      </div>
-
-      <hr>
-
-      <div class="content">
-        <template if="{{ instance.nativeFields.isNotEmpty }}">
-          native fields ({{ instance.nativeFields.length }})
-          <curly-block expand="{{ instance.nativeFields.length <= 100 }}">
-            <div class="memberList">
-              <template repeat="{{ field in instance.nativeFields }}">
-                <div class="memberItem">
-                  <div class="memberName">[{{ field['index']}}]</div>
-                  <div class="memberValue">[{{ field['value']}}]</div>
-                </div>
-              </template>
-            </div>
-          </curly-block><br><br>
-        </template>
-
-        <template if="{{ instance.fields.isNotEmpty }}">
-          fields ({{ instance.fields.length }})
-          <curly-block expand="{{ instance.fields.length <= 100 }}">
-            <div class="memberList">
-              <template repeat="{{ field in instance.fields }}">
-                <div class="memberItem">
-                  <div class="memberName">
-                    <field-ref ref="{{ field.decl }}"></field-ref>
-                  </div>
-                  <div class="memberValue">
-                    <any-service-ref ref="{{ field.value }}"></any-service-ref>
-                  </div>
-                </div>
-              </template>
-            </div>
-          </curly-block><br><br>
-        </template>
-
-        <template if="{{ instance.elements.isNotEmpty }}">
-          elements ({{ instance.length }})
-          <curly-block expand="{{ instance.elements.length <= 100 }}">
-            <div class="memberList">
-              <template repeat="{{ index in instance.elements.asMap().keys }}">
-                <div class="memberItem">
-                  <div class="memberName">[{{ index }}]</div>
-                  <div class="memberValue">
-                    <any-service-ref ref="{{ instance.elements[index] }}">
-                    </any-service-ref>
-                  </div>
-                </div>
-              </template>
-	      <template if="{{ instance.length != instance.elements.length }}">
-                <div class="memberItem">
-                  <div class="memberName">...</div>
-                  <div class="memberValue">
-                    <em>{{ instance.length - instance.elements.length }} omitted elements</em>
-                  </div>
-                </div>
-              </template>
-            </div>
-          </curly-block><br><br>
-        </template>
-
-        <template if="{{ instance.associations.isNotEmpty }}">
-          associations ({{ instance.length }})
-          <curly-block expand="{{ instance.associations.length <= 100 }}">
-            <div class="memberList">
-              <template repeat="{{ association in instance.associations }}">
-                <div class="memberItem">
-                  <div class="memberValue">
-                    [<any-service-ref ref="{{ association.key }}"></any-service-ref>]
-                  </div>
-                  <div class="memberValue">
-                    <any-service-ref ref="{{ association.value }}"></any-service-ref>
-                  </div>
-                </div>
-              </template>
-	      <template if="{{ instance.length != instance.associations.length }}">
-                <div class="memberItem">
-                  <div class="memberName">...</div>
-                  <div class="memberValue">
-                    <em>{{ instance.length - instance.associations.length }} omitted associations</em>
-                  </div>
-                </div>
-              </template>
-            </div>
-          </curly-block><br><br>
-        </template>
-
-        <template if="{{ instance.typedElements.isNotEmpty }}">
-          elements ({{ instance.length }})
-          <curly-block expand="{{ instance.typedElements.length <= 100 }}">
-            <div class="memberList">
-              <template repeat="{{ index in instance.typedElements.asMap().keys }}">
-                <div class="memberItem">
-                  <div class="memberName">[{{ index }}]</div>
-                  <div class="memberValue">{{ instance.typedElements[index].toString() }}</div>
-                </div>
-              </template>
-	      <template if="{{ instance.length != instance.typedElements.length }}">
-                <div class="memberItem">
-                  <div class="memberName">...</div>
-                  <div class="memberValue">
-                    <em>{{ instance.length - instance.elements.length }} omitted elements</em>
-                  </div>
-                </div>
-              </template>
-            </div>
-          </curly-block><br><br>
-        </template>
-
-        <template if="{{ instance.isRegExp }}">
-          <div class="memberList">
-            <div class="memberItem">
-              <div class="memberName">pattern</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.pattern }}"></any-service-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">isCaseSensitive</div>
-              <div class="memberValue">{{ instance.isCaseSensitive }}</div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">isMultiLine</div>
-              <div class="memberValue">{{ instance.isMultiLine }}</div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">oneByteFunction</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.oneByteFunction }}"></any-service-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">twoByteFunction</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.twoByteFunction }}"></any-service-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">externalOneByteFunction</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.externalOneByteFunction }}"></any-service-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">externalTwoByteFunction</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.externalTwoByteFunction }}"></any-service-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">oneByteBytecode</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.oneByteBytecode }}"></any-service-ref>
-              </div>
-            </div>
-            <div class="memberItem">
-              <div class="memberName">twoByteBytecode</div>
-              <div class="memberValue">
-                <any-service-ref ref="{{ instance.twoByteBytecode }}"></any-service-ref>
-              </div>
-            </div>
-          </div>
-        </template>
-
-        <template if="{{ instance.isMirrorReference }}">
-          <div class="memberItem">
-            <div class="memberName">referent</div>
-            <div class="memberValue">
-              <any-service-ref ref="{{ instance.referent }}">
-              </any-service-ref>
-            </div>
-          </div>
-        </template>
-
-        <template if="{{ instance.isWeakProperty }}">
-          <div class="memberItem">
-            <div class="memberName">key</div>
-            <div class="memberValue">
-              <any-service-ref ref="{{ instance.key }}"></any-service-ref>
-            </div>
-          </div>
+        <template if="{{ instance.valueAsString != null }}">
           <div class="memberItem">
             <div class="memberName">value</div>
             <div class="memberValue">
-              <any-service-ref ref="{{ instance.value }}"></any-service-ref>
+              <pre>{{ instance.valueAsString }}</pre>
             </div>
           </div>
         </template>
 
-      </div>
-
-      <div class="content-centered-big">
-        <template if="{{ instance.isClosure }}">
-          <source-inset location="{{ instance.closureFunction.location }}"></source-inset>
+        <template if="{{ instance.isString }}">
+          <div class="memberItem">
+            <div class="memberName">valueAsLiteral</div>
+            <div class="memberValue"> {{ asStringLiteral(instance.valueAsString, instance.valueAsStringIsTruncated) }}</div>
+          </div>
         </template>
+
         <template if="{{ instance.typeClass != null }}">
-          <source-inset location="{{ instance.typeClass.location }}"></source-inset>
+          <div class="memberItem">
+            <div class="memberName">type class</div>
+            <div class="memberValue">
+              <class-ref ref="{{ instance.typeClass }}">
+              </class-ref>
+            </div>
+          </div>
         </template>
-      </div>
+        <template if="{{ instance.typeArguments.length > 0 }}">
+          <div class="memberItem">
+            <div class="memberName">type arguments</div>
+            <div class="memberValue">
+              &lt;
+              <template repeat="{{ index in instance.typeArguments['types'].asMap().keys }}">
+                <instance-ref ref="{{ instance.typeArguments['types'][index] }}">
+                </instance-ref>
+                <template if="{{ index < instance.typeArguments['types'].length - 1 }}">
+                  ,
+                </template>
+              </template>
+              &gt;
+            </div>
+          </div>
+        </template>
+        <template if="{{ instance.parameterizedClass != null }}">
+          <div class="memberItem">
+            <div class="memberName">parameterized class</div>
+            <div class="memberValue">
+              <class-ref ref="{{ instance.parameterizedClass }}">
+              </class-ref>
+            </div>
+          </div>
+        </template>
+        <template if="{{ instance.parameterIndex != null }}">
+          <div class="memberItem">
+            <div class="memberName">parameter index</div>
+            <div class="memberValue">
+              {{ instance.parameterIndex }}
+            </div>
+          </div>
+        </template>
+        <template if="{{ instance.targetType != null }}">
+          <div class="memberItem">
+            <div class="memberName">target type</div>
+            <div class="memberValue">
+              <instance-ref ref="{{ instance.targetType }}">
+              </instance-ref>
+            </div>
+          </div>
+        </template>
+        <template if="{{ instance.bound != null }}">
+          <div class="memberItem">
+            <div class="memberName">bound</div>
+            <div class="memberValue">
+              <instance-ref ref="{{ instance.bound }}">
+              </instance-ref>
+            </div>
+          </div>
+        </template>
 
-    </template>
+        <template if="{{ instance.isClosure }}">
+          <div class="memberItem">
+            <div class="memberName">closure function</div>
+            <div class="memberValue">
+              <function-ref ref="{{ instance.closureFunction }}">
+              </function-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">closure context</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.context }}">
+              </any-service-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">closure breakpoint</div>
+            <div class="memberValue">
+              <template if="{{ instance.activationBreakpoint == null }}">
+                <action-link callback="{{ setBreakOnActivation }}"
+                             label="break on activation">
+                </action-link>
+              </template>
+              <template if="{{ instance.activationBreakpoint != null }}">
+                {{ instance.activationBreakpoint.toString() }}
+                <action-link callback="{{ clearBreakOnActivation }}"
+                             label="remove">
+                </action-link>
+              </template>
+            </div>
+          </div>
+        </template>
+
+        <div class="memberItem">
+          <div class="memberName">toString()</div>
+          <div class="memberValue">
+            <eval-link callback="{{ evaluate }}" expr="toString()"></eval-link>
+          </div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">runtimeType</div>
+          <div class="memberValue">
+            <eval-link callback="{{ evaluate }}" expr="runtimeType"></eval-link>
+          </div>
+        </div>
+      </div>
+    </div>
+
+    <hr>
+
+    <div class="content">
+      <eval-box context="{{ instance }}"></eval-box>
+    </div>
+
+    <hr>
+
+    <div class="content">
+      <template if="{{ instance.nativeFields.isNotEmpty }}">
+        native fields ({{ instance.nativeFields.length }})
+        <curly-block expand="{{ instance.nativeFields.length <= 100 }}">
+          <div class="memberList">
+            <template repeat="{{ field in instance.nativeFields }}">
+              <div class="memberItem">
+                <div class="memberName">[{{ field['index']}}]</div>
+                <div class="memberValue">[{{ field['value']}}]</div>
+              </div>
+            </template>
+          </div>
+        </curly-block><br><br>
+      </template>
+
+      <template if="{{ instance.fields.isNotEmpty }}">
+        fields ({{ instance.fields.length }})
+        <curly-block expand="{{ instance.fields.length <= 100 }}">
+          <div class="memberList">
+            <template repeat="{{ field in instance.fields }}">
+              <div class="memberItem">
+                <div class="memberName">
+                  <field-ref ref="{{ field.decl }}"></field-ref>
+                </div>
+                <div class="memberValue">
+                  <any-service-ref ref="{{ field.value }}"></any-service-ref>
+                </div>
+              </div>
+            </template>
+          </div>
+        </curly-block><br><br>
+      </template>
+
+      <template if="{{ instance.elements.isNotEmpty }}">
+        elements ({{ instance.length }})
+        <curly-block expand="{{ instance.elements.length <= 100 }}">
+          <div class="memberList">
+            <template repeat="{{ index in instance.elements.asMap().keys }}">
+              <div class="memberItem">
+                <div class="memberName">[{{ index }}]</div>
+                <div class="memberValue">
+                  <any-service-ref ref="{{ instance.elements[index] }}">
+                  </any-service-ref>
+                </div>
+              </div>
+            </template>
+      <template if="{{ instance.length != instance.elements.length }}">
+              <div class="memberItem">
+                <div class="memberName">...</div>
+                <div class="memberValue">
+                  <em>{{ instance.length - instance.elements.length }} omitted elements</em>
+                </div>
+              </div>
+            </template>
+          </div>
+        </curly-block><br><br>
+      </template>
+
+      <template if="{{ instance.associations.isNotEmpty }}">
+        associations ({{ instance.length }})
+        <curly-block expand="{{ instance.associations.length <= 100 }}">
+          <div class="memberList">
+            <template repeat="{{ association in instance.associations }}">
+              <div class="memberItem">
+                <div class="memberValue">
+                  [<any-service-ref ref="{{ association.key }}"></any-service-ref>]
+                </div>
+                <div class="memberValue">
+                  <any-service-ref ref="{{ association.value }}"></any-service-ref>
+                </div>
+              </div>
+            </template>
+      <template if="{{ instance.length != instance.associations.length }}">
+              <div class="memberItem">
+                <div class="memberName">...</div>
+                <div class="memberValue">
+                  <em>{{ instance.length - instance.associations.length }} omitted associations</em>
+                </div>
+              </div>
+            </template>
+          </div>
+        </curly-block><br><br>
+      </template>
+
+      <template if="{{ instance.typedElements.isNotEmpty }}">
+        elements ({{ instance.length }})
+        <curly-block expand="{{ instance.typedElements.length <= 100 }}">
+          <div class="memberList">
+            <template repeat="{{ index in instance.typedElements.asMap().keys }}">
+              <div class="memberItem">
+                <div class="memberName">[{{ index }}]</div>
+                <div class="memberValue">{{ instance.typedElements[index].toString() }}</div>
+              </div>
+            </template>
+      <template if="{{ instance.length != instance.typedElements.length }}">
+              <div class="memberItem">
+                <div class="memberName">...</div>
+                <div class="memberValue">
+                  <em>{{ instance.length - instance.elements.length }} omitted elements</em>
+                </div>
+              </div>
+            </template>
+          </div>
+        </curly-block><br><br>
+      </template>
+
+      <template if="{{ instance.isRegExp }}">
+        <div class="memberList">
+          <div class="memberItem">
+            <div class="memberName">pattern</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.pattern }}"></any-service-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">isCaseSensitive</div>
+            <div class="memberValue">{{ instance.isCaseSensitive }}</div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">isMultiLine</div>
+            <div class="memberValue">{{ instance.isMultiLine }}</div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">oneByteFunction</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.oneByteFunction }}"></any-service-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">twoByteFunction</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.twoByteFunction }}"></any-service-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">externalOneByteFunction</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.externalOneByteFunction }}"></any-service-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">externalTwoByteFunction</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.externalTwoByteFunction }}"></any-service-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">oneByteBytecode</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.oneByteBytecode }}"></any-service-ref>
+            </div>
+          </div>
+          <div class="memberItem">
+            <div class="memberName">twoByteBytecode</div>
+            <div class="memberValue">
+              <any-service-ref ref="{{ instance.twoByteBytecode }}"></any-service-ref>
+            </div>
+          </div>
+        </div>
+      </template>
+
+      <template if="{{ instance.isMirrorReference }}">
+        <div class="memberItem">
+          <div class="memberName">referent</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ instance.referent }}">
+            </any-service-ref>
+          </div>
+        </div>
+      </template>
+
+      <template if="{{ instance.isWeakProperty }}">
+        <div class="memberItem">
+          <div class="memberName">key</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ instance.key }}"></any-service-ref>
+          </div>
+        </div>
+        <div class="memberItem">
+          <div class="memberName">value</div>
+          <div class="memberValue">
+            <any-service-ref ref="{{ instance.value }}"></any-service-ref>
+          </div>
+        </div>
+      </template>
+
+    </div>
+
+    <div class="content-centered-big">
+      <template if="{{ instance.isClosure }}">
+        <source-inset location="{{ instance.closureFunction.location }}"></source-inset>
+      </template>
+      <template if="{{ instance.typeClass != null }}">
+        <source-inset location="{{ instance.typeClass.location }}"></source-inset>
+      </template>
+    </div>
+
     <view-footer></view-footer>
   </template>
 </polymer-element>
diff --git a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
index 14bc7ef..5f4290e 100644
--- a/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
+++ b/runtime/observatory/lib/src/elements/isolate/counter_chart.dart
@@ -51,11 +51,10 @@
     new ChartColumnSpec(label: 'Percent', formatter: (v) => v.toString())
   ];
 
-  final _series = [new ChartSeries("Work", const [1], new PieChartRenderer(
-    sortDataByValue: false
-  ))];
-
   void render() {
+    final _series = [new ChartSeries("Work", const [1], new PieChartRenderer(
+      sortDataByValue: false
+    ))];
     final areaHost = new DivElement()..classes = const ['host'];
     final  legendHost = new DivElement()..classes = const ['legend'];
     children = [areaHost, legendHost];
diff --git a/runtime/observatory/lib/src/elements/isolate/shared_summary.dart b/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
index 51fdc28..91bc2bb 100644
--- a/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
+++ b/runtime/observatory/lib/src/elements/isolate/shared_summary.dart
@@ -50,18 +50,11 @@
   }
 
   void render() {
-    children = [];
-    if (_isolate.error != null) {
-      children = [
-        new PreElement()..classes = const ["errorBox"]
-          ..text = _isolate.error.message
-      ];
-    }
     final newHeapUsed = Utils.formatSize(_isolate.newSpace.used);
     final newHeapCapacity = Utils.formatSize(_isolate.newSpace.capacity);
     final oldHeapUsed = Utils.formatSize(_isolate.oldSpace.used);
     final oldHeapCapacity = Utils.formatSize(_isolate.oldSpace.capacity);
-    children.addAll([
+    final content = [
       new DivElement()..classes = ['menu']
         ..children = [
           new DivElement()..classes = const ['memberList']
@@ -150,6 +143,19 @@
             ]
       ],
       new IsolateCounterChartElement(_isolate.counters, queue: _r.queue)
-    ]);
+    ];
+    if (_isolate.error != null) {
+      children = [
+        new PreElement()..classes = const ['errorBox']
+          ..text = _isolate.error.message,
+        new DivElement()..classes = const ['summary']
+          ..children = content
+      ];
+    } else {
+      children = [
+        new DivElement()..classes = const ['summary']
+          ..children = content
+      ];
+    }
   }
 }
diff --git a/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart b/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart
index 72b86c2..f51b5f0 100644
--- a/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/isolate/shared_summary_wrapper.dart
@@ -88,15 +88,17 @@
         }
         isolate-shared-summary-wrapped {
           display: block;
+        }
+        isolate-shared-summary-wrapped > .summary {
           height: 300px;
           position: relative;
         }
-        isolate-shared-summary-wrapped > .menu {
+        isolate-shared-summary-wrapped .menu {
           float: right;
           top: 0;
           right: 0;
         }
-        isolate-shared-summary-wrapped > isolate-counter-chart {
+        isolate-shared-summary-wrapped isolate-counter-chart {
           position: absolute;
           left: 0;
           top: 0;
diff --git a/runtime/observatory/lib/src/elements/isolate_summary.html b/runtime/observatory/lib/src/elements/isolate_summary.html
index 3c4924d..d34a708 100644
--- a/runtime/observatory/lib/src/elements/isolate_summary.html
+++ b/runtime/observatory/lib/src/elements/isolate_summary.html
@@ -1,6 +1,5 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="action_link.html">
-<link rel="import" href="script_inset.html">
 
 <polymer-element name="isolate-summary">
   <template>
diff --git a/runtime/observatory/lib/src/elements/isolate_view.html b/runtime/observatory/lib/src/elements/isolate_view.html
index 16d3150..c03fd22 100644
--- a/runtime/observatory/lib/src/elements/isolate_view.html
+++ b/runtime/observatory/lib/src/elements/isolate_view.html
@@ -1,8 +1,6 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="action_link.html">
-<link rel="import" href="eval_box.html">
 <link rel="import" href="isolate_summary.html">
-<link rel="import" href="script_inset.html">
 
 <polymer-element name="isolate-view">
   <template>
@@ -126,7 +124,7 @@
 
     <div class="content-centered">
       <hr>
-      <eval-box callback="{{ evaluate }}"></eval-box>
+      <eval-box context="{{ isolate.rootLibrary }}"></eval-box>
     </div>
 
     <div class="content-centered">
diff --git a/runtime/observatory/lib/src/elements/library_view.html b/runtime/observatory/lib/src/elements/library_view.html
index e18e2e6..01eef72 100644
--- a/runtime/observatory/lib/src/elements/library_view.html
+++ b/runtime/observatory/lib/src/elements/library_view.html
@@ -1,5 +1,4 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="eval_box.html">
 
 <polymer-element name="library-view">
   <template>
@@ -40,7 +39,7 @@
     <hr>
 
     <div class="content">
-      <eval-box callback="{{ evaluate }}"></eval-box>
+      <eval-box context="{{ library }}"></eval-box>
     </div>
 
     <hr>
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_view.dart b/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
index 59cb301..817beb1 100644
--- a/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
+++ b/runtime/observatory/lib/src/elements/megamorphiccache_view.dart
@@ -5,17 +5,180 @@
 library megamorphiccache_view;
 
 import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/view_footer.dart';
 
-@CustomTag('megamorphiccache-view')
-class MegamorphicCacheViewElement extends ObservatoryElement {
-  @published MegamorphicCache megamorphicCache;
+class MegamorphicCacheViewElement extends HtmlElement implements Renderable {
+  static const tag =
+         const Tag<MegamorphicCacheViewElement>('megamorphiccache-view',
+                                                dependencies: const [
+                                                  ContextRefElement.tag,
+                                                  CurlyBlockElement.tag,
+                                                  NavBarElement.tag,
+                                                  NavTopMenuElement.tag,
+                                                  NavVMMenuElement.tag,
+                                                  NavIsolateMenuElement.tag,
+                                                  NavMenuElement.tag,
+                                                  NavRefreshElement.tag,
+                                                  NavNotifyElement.tag,
+                                                  ObjectCommonElement.tag,
+                                                  ViewFooterElement.tag
+                                                ]);
+
+  RenderingScheduler<MegamorphicCacheViewElement> _r;
+
+  Stream<RenderedEvent<MegamorphicCacheViewElement>> get onRendered =>
+      _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.MegamorphicCache _cache;
+  M.MegamorphicCacheRepository _caches;
+  M.RetainedSizeRepository _retainedSizes;
+  M.ReachableSizeRepository _reachableSizes;
+  M.InboundReferencesRepository _references;
+  M.RetainingPathRepository _retainingPaths;
+  M.InstanceRepository _instances;
+
+
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+  M.MegamorphicCache get cache => _cache;
+
+  factory MegamorphicCacheViewElement(M.VM vm, M.IsolateRef isolate,
+                                      M.MegamorphicCache cache,
+                                      M.EventRepository events,
+                                      M.NotificationRepository notifications,
+                                      M.MegamorphicCacheRepository caches,
+                                      M.RetainedSizeRepository retainedSizes,
+                                      M.ReachableSizeRepository reachableSizes,
+                                      M.InboundReferencesRepository references,
+                                      M.RetainingPathRepository retainingPaths,
+                                      M.InstanceRepository instances,
+                                      {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(cache != null);
+    assert(caches != null);
+    assert(retainedSizes != null);
+    assert(reachableSizes != null);
+    assert(references != null);
+    assert(retainingPaths != null);
+    assert(instances != null);
+    MegamorphicCacheViewElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._cache = cache;
+    e._caches = caches;
+    e._retainedSizes = retainedSizes;
+    e._reachableSizes = reachableSizes;
+    e._references = references;
+    e._retainingPaths = retainingPaths;
+    e._instances = instances;
+    return e;
+  }
 
   MegamorphicCacheViewElement.created() : super.created();
 
-  Future refresh() {
-    return megamorphicCache.reload();
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavMenuElement('object', last: true, queue: _r.queue),
+          new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _cache = await _caches.get(_isolate, _cache.id);
+                _r.dirty();
+              }),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h2()..text = 'Megamorphic Cache',
+          new HRElement(),
+          new ObjectCommonElement(_isolate, _cache, _retainedSizes,
+                                  _reachableSizes, _references, _retainingPaths,
+                                  _instances, queue: _r.queue),
+          new BRElement(),
+          new DivElement()..classes = ['memberList']
+            ..children = [
+              new DivElement()..classes = ['memberItem']
+                ..children = [
+                  new DivElement()..classes = ['memberName']
+                    ..text = 'selector',
+                  new DivElement()..classes = ['memberName']
+                    ..text = '${_cache.selector}'
+                ],
+              new DivElement()..classes = ['memberItem']
+                ..children = [
+                  new DivElement()..classes = ['memberName']
+                    ..text = 'mask',
+                  new DivElement()..classes = ['memberName']
+                    ..text = '${_cache.mask}'
+                ],
+              new DivElement()..classes = ['memberItem']
+                ..children = [
+                  new DivElement()..classes = ['memberName']
+                    ..text = 'buckets',
+                  new DivElement()..classes = ['memberName']
+                    ..children = [
+                      anyRef(_isolate, _cache.buckets, _instances,
+                             queue: _r.queue)
+                    ]
+                ],
+              new DivElement()..classes = ['memberItem']
+                ..children = [
+                  new DivElement()..classes = ['memberName']
+                    ..text = 'argumentsDescriptor',
+                  new DivElement()..classes = ['memberName']
+                    ..children = [
+                      anyRef(_isolate, _cache.argumentsDescriptor, _instances,
+                             queue: _r.queue)
+                    ]
+                ]
+            ],
+          new HRElement(),
+          new ViewFooterElement(queue: _r.queue)
+        ]
+    ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/megamorphiccache_view.html b/runtime/observatory/lib/src/elements/megamorphiccache_view.html
deleted file mode 100644
index 3f2c804..0000000
--- a/runtime/observatory/lib/src/elements/megamorphiccache_view.html
+++ /dev/null
@@ -1,56 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="eval_link.html">
-
-<polymer-element name="megamorphiccache-view">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ megamorphicCache.isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ megamorphicCache.isolate }}"></isolate-nav-menu>
-      <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-    </nav-bar>
-
-    <div class="content">
-      <object-common object="{{ megamorphicCache }}"></object-common>
-
-      <br><br>
-
-      <div class="memberList">
-        <div class="memberItem">
-          <div class="memberName">selector</div>
-          <div class="memberValue">
-            {{ megamorphicCache.selector }}
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">argumentsDescriptor</div>
-          <div class="memberValue">
-            <any-service-ref ref="{{ megamorphicCache.argumentsDescriptor }}"></any-service-ref>
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">mask</div>
-          <div class="memberValue">
-            {{ megamorphicCache.mask }}
-          </div>
-        </div>
-        <div class="memberItem">
-          <div class="memberName">buckets</div>
-          <div class="memberValue">
-            <any-service-ref ref="{{ megamorphicCache.buckets }}"></any-service-ref>
-          </div>
-        </div>
-      </div>
-
-    </div>
-
-    <hr>
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="megamorphiccache_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/object_common.dart b/runtime/observatory/lib/src/elements/object_common.dart
index 6426032..f82c7ec 100644
--- a/runtime/observatory/lib/src/elements/object_common.dart
+++ b/runtime/observatory/lib/src/elements/object_common.dart
@@ -102,7 +102,10 @@
                 ..text = 'Class ',
               new DivElement()..classes = const ['memberValue']
                 ..children = [
-                  new ClassRefElement(_isolate, _object.clazz, queue: _r.queue)
+                  _object.clazz == null
+                    ? (new SpanElement()..text = '...')
+                    : new ClassRefElement(_isolate, _object.clazz,
+                                          queue: _r.queue)
                 ]
             ],
           new DivElement()..classes = const ['memberItem']
diff --git a/runtime/observatory/lib/src/elements/object_view.html b/runtime/observatory/lib/src/elements/object_view.html
index 7092ed5..bc4dd7b 100644
--- a/runtime/observatory/lib/src/elements/object_view.html
+++ b/runtime/observatory/lib/src/elements/object_view.html
@@ -1,5 +1,4 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="error_view.html">
 <link rel="import" href="eval_link.html">
 
 <polymer-element name="object-view">
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.dart b/runtime/observatory/lib/src/elements/objectpool_view.dart
index 1e08198..1ba83f2 100644
--- a/runtime/observatory/lib/src/elements/objectpool_view.dart
+++ b/runtime/observatory/lib/src/elements/objectpool_view.dart
@@ -5,19 +5,172 @@
 library objectpool_view;
 
 import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/view_footer.dart';
 
-@CustomTag('objectpool-view')
-class ObjectPoolViewElement extends ObservatoryElement {
-  @published ObjectPool pool;
+class ObjectPoolViewElement  extends HtmlElement implements Renderable {
+  static const tag = const Tag<ObjectPoolViewElement>('object-pool-view',
+                                                    dependencies: const [
+                                                      ContextRefElement.tag,
+                                                      CurlyBlockElement.tag,
+                                                      NavBarElement.tag,
+                                                      NavTopMenuElement.tag,
+                                                      NavVMMenuElement.tag,
+                                                      NavIsolateMenuElement.tag,
+                                                      NavMenuElement.tag,
+                                                      NavRefreshElement.tag,
+                                                      NavNotifyElement.tag,
+                                                      ObjectCommonElement.tag,
+                                                      ViewFooterElement.tag
+                                                    ]);
+
+  RenderingScheduler<ObjectPoolViewElement> _r;
+
+  Stream<RenderedEvent<ObjectPoolViewElement>> get onRendered => _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.ObjectPool _pool;
+  M.ObjectPoolRepository _pools;
+  M.RetainedSizeRepository _retainedSizes;
+  M.ReachableSizeRepository _reachableSizes;
+  M.InboundReferencesRepository _references;
+  M.RetainingPathRepository _retainingPaths;
+  M.InstanceRepository _instances;
+
+
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+  M.ObjectPoolRef get pool => _pool;
+
+  factory ObjectPoolViewElement(M.VM vm, M.IsolateRef isolate,
+                                M.ObjectPool pool,
+                                M.EventRepository events,
+                                M.NotificationRepository notifications,
+                                M.ObjectPoolRepository pools,
+                                M.RetainedSizeRepository retainedSizes,
+                                M.ReachableSizeRepository reachableSizes,
+                                M.InboundReferencesRepository references,
+                                M.RetainingPathRepository retainingPaths,
+                                M.InstanceRepository instances,
+                                {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(pool != null);
+    assert(pools != null);
+    assert(retainedSizes != null);
+    assert(reachableSizes != null);
+    assert(references != null);
+    assert(retainingPaths != null);
+    assert(instances != null);
+    ObjectPoolViewElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._pool = pool;
+    e._pools = pools;
+    e._retainedSizes = retainedSizes;
+    e._reachableSizes = reachableSizes;
+    e._references = references;
+    e._retainingPaths = retainingPaths;
+    e._instances = instances;
+    return e;
+  }
 
   ObjectPoolViewElement.created() : super.created();
 
-  bool isServiceObject(o) => o is ServiceObject;
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+  }
 
-  Future refresh() {
-    return pool.reload();
+  @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavMenuElement('instance', last: true, queue: _r.queue),
+          new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _pool = await _pools.get(_isolate, _pool.id);
+                _r.dirty();
+              }),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h2()..text = 'Object Pool',
+          new HRElement(),
+          new ObjectCommonElement(_isolate, _pool, _retainedSizes,
+                                  _reachableSizes, _references, _retainingPaths,
+                                  _instances, queue: _r.queue),
+          new HRElement(),
+          new HeadingElement.h3()..text = 'entries (${_pool.entries.length})',
+          new DivElement()..classes = const ['memberList']
+            ..children = _pool.entries.map((entry)
+              => new DivElement()..classes = const ['memberItem']
+                ..children = [
+                  new DivElement()..classes = const ['memberName',
+                                                     'hexadecimal']
+                    ..text = '[PP+0x${entry.offset.toRadixString(16)}]',
+                  new DivElement()..classes = const ['memberName']
+                    ..children = _createEntry(entry)
+                ]).toList(),
+          new HRElement(),
+          new ViewFooterElement(queue: _r.queue)
+        ]
+    ];
+  }
+
+  List<Element> _createEntry(M.ObjectPoolEntry entry) {
+    switch (entry.kind) {
+      case  M.ObjectPoolEntryKind.object:
+      return [
+        anyRef(_isolate, entry.asObject, _instances, queue: _r.queue)
+      ];
+      case  M.ObjectPoolEntryKind.immediate:
+      return [
+        new SpanElement()
+          ..text = 'Immediate 0x${entry.asInteger.toRadixString(16)}'
+      ];
+      case  M.ObjectPoolEntryKind.nativeEntry:
+      return [
+        new SpanElement()
+          ..text = 'NativeEntry 0x${entry.asInteger.toRadixString(16)}'
+      ];
+    }
+    throw new Exception('Unkown ObjectPoolEntryKind (${entry.kind})');
   }
 }
diff --git a/runtime/observatory/lib/src/elements/objectpool_view.html b/runtime/observatory/lib/src/elements/objectpool_view.html
deleted file mode 100644
index 555ddb4..0000000
--- a/runtime/observatory/lib/src/elements/objectpool_view.html
+++ /dev/null
@@ -1,50 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="eval_link.html">
-
-<polymer-element name="objectpool-view">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ pool.isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ pool.isolate }}"></isolate-nav-menu>
-      <nav-menu link="." anchor="object" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-    </nav-bar>
-
-    <div class="content">
-      <object-common object="{{ pool }}"></object-common>
-
-      <br><br>
-
-      entries ({{ pool.entries.length }})
-      <div class="memberList">
-        <template repeat="{{ entry in pool.entries }}">
-          <div class="memberItem">
-            <div class="memberName">[PP+0x{{ entry['offset'].toRadixString(16) }}]</div>
-            <div class="memberValue">
-              <template if="{{ entry['kind'] == 'Object' }}">
-                <any-service-ref ref="{{ entry['value'] }}">
-                </any-service-ref>
-              </template>
-              <template if="{{ entry['kind'] == 'Immediate' }}">
-                Immediate 0x{{ entry['value'].toRadixString(16) }}
-             </template>
-              <template if="{{ entry['kind'] == 'NativeEntry' }}">
-                NativeEntry 0x{{ entry['value'].toRadixString(16) }}
-             </template>
-            </div>
-          </div>
-        </template>
-      </div>
-
-    </div>
-
-    <hr>
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="objectpool_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/objectstore_view.dart b/runtime/observatory/lib/src/elements/objectstore_view.dart
index c5ff3bc..72a1596 100644
--- a/runtime/observatory/lib/src/elements/objectstore_view.dart
+++ b/runtime/observatory/lib/src/elements/objectstore_view.dart
@@ -5,20 +5,131 @@
 library objectstore_view_element;
 
 import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/view_footer.dart';
+
+class ObjectStoreViewElement  extends HtmlElement implements Renderable {
+  static const tag = const Tag<ObjectStoreViewElement>('objectstore-view',
+                                            dependencies: const [
+                                              InstanceRefElement.tag,
+                                              NavBarElement.tag,
+                                              NavTopMenuElement.tag,
+                                              NavVMMenuElement.tag,
+                                              NavIsolateMenuElement.tag,
+                                              NavRefreshElement.tag,
+                                              NavNotifyElement.tag,
+                                              ViewFooterElement.tag
+                                            ]);
+
+  RenderingScheduler<ObjectStoreViewElement> _r;
+
+  Stream<RenderedEvent<ObjectStoreViewElement>> get onRendered => _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.ObjectStore _store;
+  M.ObjectStoreRepository _stores;
+  M.InstanceRepository _instances;
 
 
-@CustomTag('objectstore-view')
-class ObjectStoreViewElement extends ObservatoryElement {
-  @published ObjectStore objectStore;
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+
+  factory ObjectStoreViewElement(M.VM vm, M.IsolateRef isolate,
+                                 M.EventRepository events,
+                                 M.NotificationRepository notifications,
+                                 M.ObjectStoreRepository stores,
+                                 M.InstanceRepository instances,
+                                 {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(stores != null);
+    assert(instances != null);
+    ObjectStoreViewElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._stores = stores;
+    e._instances = instances;
+    return e;
+  }
 
   ObjectStoreViewElement.created() : super.created();
 
-  Future refresh() {
-    return objectStore.isolate.getObjectStore().then((newObjectStore) {
-      objectStore = newObjectStore;
-    });
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+    _refresh();
+  }
+
+  @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    final fields = _store?.fields?.toList(growable: false);
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavRefreshElement(disabled: _store == null, queue: _r.queue)
+              ..onRefresh.listen((e) => _refresh()),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h1()
+            ..text = fields == null
+              ? 'Object Store'
+              : 'Object Store (${fields.length})',
+          new HRElement(),
+          fields == null
+            ? (new HeadingElement.h2()..text = 'Loading...')
+            : (new DivElement()..classes = const ['memberList']
+               ..children = fields.map((field) =>
+                 new DivElement()..classes = const ['memberItem']
+                   ..children = [
+                     new DivElement()..classes = const ['memberName']
+                       ..text = field.name,
+                     new DivElement()..classes = const ['memberValue']
+                       ..children = [
+                         anyRef(_isolate, field.value, _instances,
+                                queue: _r.queue)
+                       ]
+                   ]).toList()),
+          new ViewFooterElement(queue: _r.queue)
+        ]
+    ];
+  }
+
+  Future _refresh() async {
+    _store = null;
+    _r.dirty();
+    _store = await _stores.get(_isolate);
+    _r.dirty();
   }
 }
diff --git a/runtime/observatory/lib/src/elements/objectstore_view.html b/runtime/observatory/lib/src/elements/objectstore_view.html
deleted file mode 100644
index 1cdeb76..0000000
--- a/runtime/observatory/lib/src/elements/objectstore_view.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="eval_box.html">
-
-<polymer-element name="objectstore-view">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ objectStore.isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ objectStore.isolate }}" last="{{ true }}"></isolate-nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-    </nav-bar>
-
-    <div class="content-centered-big">
-      <h1>
-        object store ({{ objectStore.fields.length }})
-      </h1>
-
-      <hr>
-
-      <div class="memberList">
-        <template repeat="{{ field in objectStore.fields }}">
-          <div class="memberItem">
-            <div class="memberName">{{ field.name }}</div>
-            <div class="memberValue"><any-service-ref ref="{{ field.value }}"></any-service-ref></div>
-          </div>
-        </template>
-      </div>
-    </div>
-
-    <view-footer></view-footer>
- </template>
-</polymer-element>
-
-<script type="application/dart" src="library_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/observatory_element.dart b/runtime/observatory/lib/src/elements/observatory_element.dart
index a661ccf..ed52cf0 100644
--- a/runtime/observatory/lib/src/elements/observatory_element.dart
+++ b/runtime/observatory/lib/src/elements/observatory_element.dart
@@ -189,35 +189,4 @@
     anchorElement.onClick.listen(onClickGoto);
     shadowRoot.children.add(anchorElement);
   }
-
-
-  var _onCopySubscription;
-  /// Exclude nodes from being copied, for example the line numbers and
-  /// breakpoint toggles in script insets. Must be called after [root]'s
-  /// children have been added, and only supports one node at a time.
-  void makeCssClassUncopyable(Element root, String className) {
-    var noCopyNodes = root.getElementsByClassName(className);
-    for (var node in noCopyNodes) {
-      node.style.setProperty('-moz-user-select', 'none');
-      node.style.setProperty('-khtml-user-select', 'none');
-      node.style.setProperty('-webkit-user-select', 'none');
-      node.style.setProperty('-ms-user-select', 'none');
-      node.style.setProperty('user-select', 'none');
-    }
-    if (_onCopySubscription != null) {
-      _onCopySubscription.cancel();
-    }
-    _onCopySubscription = root.onCopy.listen((event) {
-      // Mark the nodes as hidden before the copy happens, then mark them as
-      // visible on the next event loop turn.
-      for (var node in noCopyNodes) {
-        node.style.visibility = 'hidden';
-      }
-      Timer.run(() {
-        for (var node in noCopyNodes) {
-          node.style.visibility = 'visible';
-        }
-      });
-    });
-  }
 }
diff --git a/runtime/observatory/lib/src/elements/persistent_handles.dart b/runtime/observatory/lib/src/elements/persistent_handles.dart
index f6ccfaf..7a7b333 100644
--- a/runtime/observatory/lib/src/elements/persistent_handles.dart
+++ b/runtime/observatory/lib/src/elements/persistent_handles.dart
@@ -6,173 +6,269 @@
 
 import 'dart:async';
 import 'dart:html';
-import 'observatory_element.dart';
-import 'package:observatory/app.dart';
-import 'package:observatory/elements.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/containers/virtual_collection.dart';
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
+import 'package:observatory/src/elements/instance_ref.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/utils.dart';
 
-class WeakPersistentHandlesSortedTable extends SortedTable {
-  factory WeakPersistentHandlesSortedTable() {
-    var columns = [
-      new SortedTableColumn.withFormatter('External Size',
-                                          Utils.formatSize),
-      new SortedTableColumn('Peer'),
-      new SortedTableColumn('Finalizer Callback'),
-      new SortedTableColumn(''),  // Spacer column.
-      new SortedTableColumn('Object'),
-    ];
-    WeakPersistentHandlesSortedTable result =
-        new WeakPersistentHandlesSortedTable._(columns);
-    // Sort by external size.
-    result.sortColumnIndex = 0;
-    return result;
-  }
-
-  WeakPersistentHandlesSortedTable._(columns) : super(columns);
-
-  @override
-  dynamic getSortKeyFor(int row, int col) {
-    return super.getSortKeyFor(row, col);
-  }
-
-  void update(List<ServiceMap> handles, HtmlElement tableBody) {
-    clearRows();
-    for (ServiceMap handle in handles) {
-      var row = [int.parse(handle['externalSize'], onError: (_) => 0),
-                 handle['peer'],
-                 handle['callbackSymbolName'] +
-                 '( ${handle['callbackAddress']} )',
-                 '', // Spacer column.
-                 handle['object']];
-      addRow(new SortedTableRow(row));
-      print(row);
-    }
-    sort();
-    _updateTableInDom(tableBody);
-  }
-
-  void sortAndDisplay(HtmlElement tableBody) {
-    sort();
-    _updateTableInDom(tableBody);
-  }
-
-
-  void _updateTableInDom(HtmlElement tableBody) {
-    assert(tableBody != null);
-    // Resize DOM table.
-    if (tableBody.children.length > sortedRows.length) {
-      // Shrink the table.
-      var deadRows =
-          tableBody.children.length - sortedRows.length;
-      for (var i = 0; i < deadRows; i++) {
-        tableBody.children.removeLast();
-      }
-    } else if (tableBody.children.length < sortedRows.length) {
-      // Grow table.
-      var newRows = sortedRows.length - tableBody.children.length;
-      for (var i = 0; i < newRows; i++) {
-        _addDomRow(tableBody);
-      }
-    }
-    assert(tableBody.children.length == sortedRows.length);
-    // Fill table.
-    for (var i = 0; i < sortedRows.length; i++) {
-      var rowIndex = sortedRows[i];
-      var tr = tableBody.children[i];
-      _fillDomRow(tr, rowIndex);
-    }
-  }
-
-  void _addDomRow(HtmlElement tableBody) {
-    // Add empty dom row.
-    var tr = new TableRowElement();
-
-    var cell;
-
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-    cell = tr.insertCell(-1);
-
-    // Add spacer.
-    cell = tr.insertCell(-1);
-    cell.classes.add('left-border-spacer');
-
-    // Add class ref.
-    cell = tr.insertCell(-1);
-    AnyServiceRefElement objectRef = new Element.tag('any-service-ref');
-    cell.children.add(objectRef);
-
-    // Add row to table.
-    tableBody.children.add(tr);
-  }
-
-  void _fillDomRow(TableRowElement tr, int rowIndex) {
-    var row = rows[rowIndex];
-
-    for (var i = 0; i < row.values.length - 2; i++) {
-      var cell = tr.children[i];
-      cell.title = row.values[i].toString();
-      cell.text = getFormattedValue(rowIndex, i);
-      cell.style.paddingLeft = '1em';
-      cell.style.paddingRight = '1em';
-    }
-
-    final int objectIndex = row.values.length - 1;
-    AnyServiceRefElement objectRef = tr.children[objectIndex].children[0];
-    objectRef.ref = row.values[objectIndex];
-  }
+enum _SortingField {
+  externalSize,
+  peer,
+  finalizerCallback
 }
 
+enum _SortingDirection {
+  ascending,
+  descending
+}
 
-@CustomTag('persistent-handles-page')
-class PersistentHandlesPageElement extends ObservatoryElement {
+class PersistentHandlesPageElement  extends HtmlElement implements Renderable {
+  static const tag =
+         const Tag<PersistentHandlesPageElement>('persistent-handles-page',
+                                                 dependencies: const [
+                                                   InstanceRefElement.tag,
+                                                   NavBarElement.tag,
+                                                   NavTopMenuElement.tag,
+                                                   NavVMMenuElement.tag,
+                                                   NavIsolateMenuElement.tag,
+                                                   NavMenuElement.tag,
+                                                   NavRefreshElement.tag,
+                                                   NavNotifyElement.tag,
+                                                   VirtualCollectionElement.tag
+                                                 ]);
+
+  RenderingScheduler<PersistentHandlesPageElement> _r;
+
+  Stream<RenderedEvent<PersistentHandlesPageElement>> get onRendered =>
+      _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.PersistentHandlesRepository _repository;
+  M.InstanceRepository _instances;
+  M.PersistentHandles _handles;
+  _SortingField _sortingField =
+      _SortingField.externalSize;
+  _SortingDirection _sortingDirection =
+      _SortingDirection.descending;
+
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+
+  factory PersistentHandlesPageElement(M.VM vm, M.IsolateRef isolate,
+                                   M.EventRepository events,
+                                   M.NotificationRepository notifications,
+                                   M.PersistentHandlesRepository repository,
+                                   M.InstanceRepository instances,
+                                   {RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(repository != null);
+    assert(instances != null);
+    PersistentHandlesPageElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._repository = repository;
+    e._instances = instances;
+    return e;
+  }
+
   PersistentHandlesPageElement.created() : super.created();
 
-  @observable Isolate isolate;
-  @observable var /*ObservableList | ServiceObject*/ persistentHandles;
-  @observable var /*ObservableList | ServiceObject*/ weakPersistentHandles;
-  @observable WeakPersistentHandlesSortedTable weakPersistentHandlesTable;
-  var _weakPersistentHandlesTableBody;
-
-  void isolateChanged(oldValue) {
-    if (isolate != null) {
-      refresh();
-    }
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+    _refresh();
   }
 
   @override
-  void attached() {
-    super.attached();
-    _weakPersistentHandlesTableBody =
-        shadowRoot.querySelector('#weakPersistentHandlesTableBody');
-    weakPersistentHandlesTable =
-        new WeakPersistentHandlesSortedTable();
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
   }
 
-  Future refresh() {
-    return isolate.getPersistentHandles().then(_refreshView);
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavMenuElement('persistent handles', last: true,
+              link: Uris.persistentHandles(_isolate), queue: _r.queue),
+          new NavRefreshElement(queue: _r.queue)
+            ..onRefresh.listen((_) => _refresh()),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ]
+    ]..addAll(_createHandlers('Persistent Handles',
+                              _handles?.elements?.toList(),
+                              _createLine,
+                              _updateLine))
+     ..add(new BRElement())
+     ..addAll(_createHandlers('Weak Persistent Handles',
+                              _handles == null
+                                ? null
+                                : (_handles.weakElements.toList()
+                                    ..sort(_createSorter())),
+                                _createWeakLine,
+                                _updateWeakLine,
+                                createHeader: _createWeakHeader));
   }
 
-  _refreshView(/*ObservableList | ServiceObject*/ object) {
-    persistentHandles = object['persistentHandles'];
-    weakPersistentHandles = object['weakPersistentHandles'];
-    weakPersistentHandlesTable.update(
-        weakPersistentHandles,
-        _weakPersistentHandlesTableBody);
+  List<Element> _createHandlers(String name, List items, create, update,
+                                {createHeader}) {
+    return [
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h1()
+            ..text = items == null ? '$name'
+                                   : '$name (${items.length})',
+          new HRElement(),
+        ],
+      new DivElement()..classes = const ['persistent-handles']
+        ..children = [
+          items == null
+            ? (new HeadingElement.h2()..classes = const ['content-centered-big']
+                ..text = 'Loading...')
+            : new VirtualCollectionElement(create, update, items: items,
+                                           createHeader: createHeader,
+                                           queue: _r.queue)
+        ]
+    ];
   }
 
-  @observable void changeSort(Event e, var detail, Element target) {
-    if (target is TableCellElement) {
-      if (weakPersistentHandlesTable.sortColumnIndex != target.cellIndex) {
-        weakPersistentHandlesTable.sortColumnIndex = target.cellIndex;
-        weakPersistentHandlesTable.sortDescending = true;
-      } else {
-        weakPersistentHandlesTable.sortDescending =
-            !weakPersistentHandlesTable.sortDescending;
-      }
-      weakPersistentHandlesTable.sortAndDisplay(
-          _weakPersistentHandlesTableBody);
+  _createSorter() {
+    var getter;
+    switch (_sortingField) {
+      case _SortingField.externalSize:
+        getter = _getExternalSize;
+        break;
+      case _SortingField.peer:
+        getter = _getPeer;
+        break;
+      case _SortingField.finalizerCallback:
+        getter = _getFinalizerCallback;
+        break;
+    }
+    switch (_sortingDirection) {
+      case _SortingDirection.ascending:
+        return (a, b) => getter(a).compareTo(getter(b));
+      case _SortingDirection.descending:
+        return (a, b) => getter(b).compareTo(getter(a));
     }
   }
+
+  static Element _createLine() =>
+    new DivElement()..classes = const ['collection-item']
+      ..text = 'object';
+
+  static Element _createWeakLine() =>
+    new DivElement()
+      ..classes = const ['weak-item']
+      ..children = [
+        new SpanElement()..classes = const ['external-size']
+          ..text = '0B',
+        new SpanElement()..classes = const ['peer']
+          ..text = '0x00000',
+        new SpanElement()..classes = const ['object'],
+        new SpanElement()..classes = const ['finalizer']
+          ..text = 'dart::Class::Method()'
+      ];
+
+  Element _createWeakHeader() =>
+    new DivElement()
+      ..classes = const ['weak-item']
+      ..children = [
+        _createHeaderButton(const ['external-size'], 'External Size',
+                            _SortingField.externalSize,
+                            _SortingDirection.descending),
+        _createHeaderButton(const ['peer'], 'Peer',
+                            _SortingField.peer,
+                            _SortingDirection.descending),
+        new SpanElement()..classes = const ['object']
+          ..text = 'Object',
+        _createHeaderButton(const ['finalizer'], 'Finalizer Callback',
+                            _SortingField.finalizerCallback,
+                            _SortingDirection.ascending)
+      ];
+
+  ButtonElement _createHeaderButton(List<String> classes,
+                                    String text,
+                                    _SortingField field,
+                                    _SortingDirection direction) =>
+      new ButtonElement()..classes = classes
+          ..text = _sortingField != field ? text :
+                     _sortingDirection == _SortingDirection.ascending
+                     ? '$textâ–¼' : '$textâ–²'
+          ..onClick.listen((_) => _setSorting(field, direction));
+
+
+  void _setSorting(_SortingField field,
+                   _SortingDirection defaultDirection) {
+    if (_sortingField == field) {
+      switch (_sortingDirection) {
+        case _SortingDirection.descending:
+          _sortingDirection = _SortingDirection.ascending;
+          break;
+        case _SortingDirection.ascending:
+          _sortingDirection = _SortingDirection.descending;
+          break;
+      }
+    } else {
+      _sortingDirection = defaultDirection;
+      _sortingField = field;
+    }
+    _r.dirty();
+  }
+
+  void _updateWeakLine(Element e, M.WeakPersistentHandle item,
+      index) {
+    e.children[0].text = Utils.formatSize(_getExternalSize(item));
+    e.children[1].text = '${_getPeer(item)}';
+    e.children[2] = anyRef(_isolate, item.object, _instances, queue: _r.queue)
+      ..classes = const ['object'];
+    e.children[3]..text = '${_getFinalizerCallback(item)}'
+                 ..title = '${_getFinalizerCallback(item)}';
+  }
+
+  void _updateLine(Element e, M.PersistentHandle item,
+      index) {
+    e.children = [
+      anyRef(_isolate, item.object, _instances, queue: _r.queue)
+       ..classes = const ['object']
+    ];
+  }
+
+  Future _refresh({bool gc: false, bool reset: false}) async {
+    _handles = null;
+    _r.dirty();
+    _handles = await _repository.get(_isolate);
+    _r.dirty();
+  }
+
+  static int _getExternalSize(M.WeakPersistentHandle h) => h.externalSize;
+  static String _getPeer(M.WeakPersistentHandle h) => h.peer;
+  static String _getFinalizerCallback(M.WeakPersistentHandle h) =>
+      '${h.callbackSymbolName} (${h.callbackAddress})';
 }
diff --git a/runtime/observatory/lib/src/elements/persistent_handles.html b/runtime/observatory/lib/src/elements/persistent_handles.html
deleted file mode 100644
index af92aa7..0000000
--- a/runtime/observatory/lib/src/elements/persistent_handles.html
+++ /dev/null
@@ -1,105 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="persistent-handles-page">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-    .table {
-      border-collapse: collapse!important;
-      margin-bottom: 20px
-      table-layout: fixed;
-      width: 100%;
-    }
-    .table td:nth-of-type(1) {
-      width: 30%;
-    }
-    .th, .td {
-      padding: 8px;
-      vertical-align: top;
-    }
-    .table thead > tr > th {
-      vertical-align: bottom;
-      text-align: left;
-      border-bottom:2px solid #ddd;
-    }
-    .spacer {
-      width: 16px;
-    }
-    .left-border-spacer {
-      width: 16px;
-      border-left: 1px solid;
-    }
-    .clickable {
-      color: #0489c3;
-      text-decoration: none;
-      cursor: pointer;
-    }
-    .clickable:hover {
-      text-decoration: underline;
-      cursor: pointer;
-    }
-    #weakPersistentHandlesTable tr:hover > td {
-      background-color: #F4C7C3;
-    }
-    .nav-option {
-      color: white;
-      float: right;
-      margin: 3px;
-      padding: 8px;
-    }
-    </style>
-    <nav-bar>
-      <top-nav-menu></top-nav-menu>
-      <vm-nav-menu vm="{{ isolate.vm }}"></vm-nav-menu>
-      <isolate-nav-menu isolate="{{ isolate }}"></isolate-nav-menu>
-      <nav-menu link="{{ makeLink('/persistent-handles', isolate) }}" anchor="persistent handles" last="{{ true }}"></nav-menu>
-      <nav-refresh callback="{{ refresh }}"></nav-refresh>
-      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-    </nav-bar>
-    <div class="content-centered-big">
-      <template if="{{ persistentHandles.isEmpty }}">
-        <h1>Persistent Handles (0)</h1>
-        <hr>
-      </template>
-      <template if="{{ persistentHandles.isNotEmpty }}">
-        <h1>Persistent Handles ({{ persistentHandles.length }})</h1>
-        <hr>
-        <curly-block expand="{{ persistentHandles.length <= 8 }}">
-          <div class="memberList">
-            <template repeat="{{ persistentHandle in persistentHandles }}">
-              <div class="memberItem">
-                <div class="memberValue">
-                  <any-service-ref ref="{{ persistentHandle['object'] }}">
-                  </any-service-ref>
-                </div>
-              </div>
-            </template>
-          </div>
-        </curly-block><br><br>
-      </template>
-      <br><br>
-      <template if="{{ weakPersistentHandles.isEmpty }}">
-        <h1>Weak Persistent Handles (0)</h1>
-        <hr>
-      </template>
-      <template if="{{ weakPersistentHandles.isNotEmpty }}">
-        <h1>Weak Persistent Handles ({{ weakPersistentHandles.length }})</h1>
-        <hr>
-      </template>
-      <table id="weakPersistentHandlesTable" class="flex-item-100-percent table">
-        <thead id="weakPersistentHandlesTableHead">
-          <tr>
-            <th on-click="{{changeSort}}" class="clickable" title="External Size">{{ weakPersistentHandlesTable.getColumnLabel(0) }}</th>
-            <th on-click="{{changeSort}}" class="clickable" title="Peer">{{ weakPersistentHandlesTable.getColumnLabel(1) }}</th>
-            <th on-click="{{changeSort}}" class="clickable" title="Finalizer Callback">{{ weakPersistentHandlesTable.getColumnLabel(2) }}</th>
-            <th class="spacer"></th>
-            <th on-click="{{changeSort}}" class="clickable" title="Object">{{ weakPersistentHandlesTable.getColumnLabel(4) }}</th>
-          </tr>
-        </thead>
-        <tbody id="weakPersistentHandlesTableBody">
-        </tbody>
-      </table>
-      <view-footer></view-footer>
-    </div>
-  </template>
-</polymer-element>
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index fbbef3a..d968fe0 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -6,14 +6,931 @@
 
 import 'dart:async';
 import 'dart:html';
-import 'dart:math';
-import 'observatory_element.dart';
-import 'service_ref.dart';
+import 'package:observatory/app.dart';
 import 'package:observatory/models.dart' as M;
-import 'package:observatory/service.dart';
+import 'package:observatory/service.dart' as S;
+import 'package:observatory/src/elements/helpers/any_ref.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/uris.dart';
 import 'package:observatory/utils.dart';
-import 'package:polymer/polymer.dart';
-import 'package:logging/logging.dart';
+
+class ScriptInsetElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ScriptInsetElement>('script-inset-wrapped');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<ScriptInsetElement>> get onRendered => _r.onRendered;
+
+
+  M.IsolateRef _isolate;
+  M.ScriptRef _script;
+  M.Script _loadedScript;
+  M.ScriptRepository _scripts;
+  M.InstanceRepository _instances;
+  M.EventRepository _events;
+  StreamSubscription _subscription;
+  int _startPos;
+  int _endPos;
+  int _currentPos;
+  bool _inDebuggerContext;
+  Iterable _variables;
+
+  M.IsolateRef get isolate => _isolate;
+  M.ScriptRef get script => _script;
+
+  factory ScriptInsetElement(M.IsolateRef isolate, M.ScriptRef script,
+                             M.ScriptRepository scripts,
+                             M.InstanceRepository instances,
+                             M.EventRepository events,
+                             {int startPos, int endPos, int currentPos,
+                              bool inDebuggerContext: false,
+                              Iterable variables: const [],
+                              RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(script != null);
+    assert(scripts != null);
+    assert(instances != null);
+    assert(events != null);
+    assert(inDebuggerContext != null);
+    assert(variables != null);
+    ScriptInsetElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._script = script;
+    e._scripts = scripts;
+    e._instances = instances;
+    e._events = events;
+    e._startPos = startPos;
+    e._endPos = endPos;
+    e._currentPos = currentPos;
+    e._inDebuggerContext = inDebuggerContext;
+    e._variables = new List.unmodifiable(variables);
+    return e;
+  }
+
+  ScriptInsetElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+    _subscription = _events.onDebugEvent
+      .where((e) => (e is M.BreakpointAddedEvent) ||
+                    (e is M.BreakpointResolvedEvent) ||
+                    (e is M.BreakpointRemovedEvent))
+      .map((e) => e.breakpoint)
+      .listen((M.Breakpoint b) {
+          final loc = b.location;
+          int line;
+          if (loc.script.id == script.id) {
+            if (loc.tokenPos != null) {
+              line = _loadedScript.tokenToLine(loc.tokenPos);
+            } else {
+              line = loc.line;
+            }
+          } else {
+            line = loc.line;
+          }
+          if ((line == null) || ((line >= _startLine) && (line <= _endLine))) {
+            _r.dirty();
+          }
+        });
+    _refresh();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+    _subscription.cancel();
+  }
+
+  void render() {
+    if (_loadedScript == null) {
+      children = [new SpanElement()..text = 'Loading...'];
+    } else {
+      final table = linesTable();
+      var firstBuild = false;
+      if (container == null) {
+        // Indirect to avoid deleting the style element.
+        container = new DivElement();
+
+        firstBuild = true;
+      }
+      children = [container];
+      container.children.clear();
+      container.children.add(table);
+      _makeCssClassUncopyable(table, "noCopy");
+      if (firstBuild) {
+        _scrollToCurrentPos();
+      }
+    }
+  }
+
+  Future _refresh() async {
+    _loadedScript = await _scripts.get(_isolate, _script.id);
+    await _refreshSourceReport();
+    await _computeAnnotations();
+    _r.dirty();
+  }
+
+  ButtonElement _refreshButton;
+  ButtonElement _toggleProfileButton;
+
+  int _currentLine;
+  int _currentCol;
+  int _startLine;
+  int _endLine;
+
+  Map<int, List<S.ServiceMap>> _rangeMap = {};
+  Set _callSites = new Set<S.CallSite>();
+  Set _possibleBreakpointLines = new Set<int>();
+  Map<int, ScriptLineProfile> _profileMap = {};
+
+  var _annotations = [];
+  var _annotationsCursor;
+
+  bool _includeProfile = false;
+
+  String makeLineClass(int line) {
+    return 'script-inset-line-$line';
+  }
+
+  void _scrollToCurrentPos() {
+    var lines = getElementsByClassName(makeLineClass(_currentLine));
+    if (lines.length > 0) {
+      lines[0].scrollIntoView();
+    }
+  }
+
+  Element a(String text) => new AnchorElement()..text = text;
+  Element span(String text) => new SpanElement()..text = text;
+
+  Element hitsCurrent(Element element) {
+    element.classes.add('hitsCurrent');
+    element.title = "";
+    return element;
+  }
+  Element hitsUnknown(Element element) {
+    element.classes.add('hitsNone');
+    element.title = "";
+    return element;
+  }
+  Element hitsNotExecuted(Element element) {
+    element.classes.add('hitsNotExecuted');
+    element.title = "Line did not execute";
+    return element;
+  }
+  Element hitsExecuted(Element element) {
+    element.classes.add('hitsExecuted');
+    element.title = "Line did execute";
+    return element;
+  }
+  Element hitsCompiled(Element element) {
+    element.classes.add('hitsCompiled');
+    element.title = "Line in compiled function";
+    return element;
+  }
+  Element hitsNotCompiled(Element element) {
+    element.classes.add('hitsNotCompiled');
+    element.title = "Line in uncompiled function";
+    return element;
+  }
+
+  Element container;
+
+  // Build _rangeMap and _callSites from a source report.
+  Future _refreshSourceReport() async {
+    var reports = [S.Isolate.kCallSitesReport,
+                   S.Isolate.kPossibleBreakpointsReport];
+    if (_includeProfile) {
+      reports.add(S.Isolate.kProfileReport);
+    }
+    S.Isolate isolate = _isolate as S.Isolate;
+    var sourceReport = await isolate.getSourceReport(
+        reports,
+        script, _startPos, _endPos);
+    _possibleBreakpointLines = S.getPossibleBreakpointLines(sourceReport,
+                                                            script);
+    _rangeMap.clear();
+    _callSites.clear();
+    _profileMap.clear();
+    for (var range in sourceReport['ranges']) {
+      int startLine = _loadedScript.tokenToLine(range['startPos']);
+      int endLine = _loadedScript.tokenToLine(range['endPos']);
+      // TODO(turnidge): Track down the root cause of null startLine/endLine.
+      if ((startLine != null) && (endLine != null)) {
+        for (var line = startLine; line <= endLine; line++) {
+          var rangeList = _rangeMap[line];
+          if (rangeList == null) {
+            _rangeMap[line] = [range];
+          } else {
+            rangeList.add(range);
+          }
+        }
+      }
+      if (_includeProfile && range['profile'] != null) {
+        List positions = range['profile']['positions'];
+        List exclusiveTicks = range['profile']['exclusiveTicks'];
+        List inclusiveTicks = range['profile']['inclusiveTicks'];
+        int sampleCount = range['profile']['metadata']['sampleCount'];
+        assert(positions.length == exclusiveTicks.length);
+        assert(positions.length == inclusiveTicks.length);
+        for (int i = 0; i < positions.length; i++) {
+          if (positions[i] is String) {
+            // String positions are classifying token positions.
+            // TODO(johnmccutchan): Add classifier data to UI.
+            continue;
+          }
+          int line = _loadedScript.tokenToLine(positions[i]);
+          ScriptLineProfile lineProfile = _profileMap[line];
+          if (lineProfile == null) {
+            lineProfile = new ScriptLineProfile(line, sampleCount);
+            _profileMap[line] = lineProfile;
+          }
+          lineProfile.process(exclusiveTicks[i], inclusiveTicks[i]);
+        }
+      }
+      if (range['compiled']) {
+        var rangeCallSites = range['callSites'];
+        if (rangeCallSites != null) {
+          for (var callSiteMap in rangeCallSites) {
+            _callSites.add(new S.CallSite.fromMap(callSiteMap, script));
+          }
+        }
+      }
+    }
+  }
+
+  Future _computeAnnotations() async {
+    _startLine = (_startPos != null
+                  ? _loadedScript.tokenToLine(_startPos)
+                  : 1 + _loadedScript.lineOffset);
+    _currentLine = (_currentPos != null
+                    ? _loadedScript.tokenToLine(_currentPos)
+                    : null);
+    _currentCol = (_currentPos != null
+                   ? (_loadedScript.tokenToCol(_currentPos))
+                   : null);
+    if (_currentCol != null) {
+      _currentCol--;  // make this 0-based.
+    }
+
+    S.Script script = _loadedScript as S.Script;
+
+    _endLine = (_endPos != null
+                ? _loadedScript.tokenToLine(_endPos)
+                : script.lines.length + _loadedScript.lineOffset);
+
+    if (_startLine == null || _endLine == null) {
+      return;
+    }
+
+    _annotations.clear();
+
+    addCurrentExecutionAnnotation();
+    addBreakpointAnnotations();
+
+    if (!_inDebuggerContext && script.library != null) {
+      await loadDeclarationsOfLibrary(script.library);
+      addLibraryAnnotations();
+      addDependencyAnnotations();
+      addPartAnnotations();
+      addClassAnnotations();
+      addFieldAnnotations();
+      addFunctionAnnotations();
+      addCallSiteAnnotations();
+    }
+
+    addLocalVariableAnnotations();
+
+    _annotations.sort();
+  }
+
+  void addCurrentExecutionAnnotation() {
+    if (_currentLine != null) {
+      var a = new CurrentExecutionAnnotation(_isolate, _instances, _r.queue);
+      a.line = _currentLine;
+      a.columnStart = _currentCol;
+      S.Script script = _loadedScript as S.Script;
+      var length = script.guessTokenLength(_currentLine, _currentCol);
+      if (length == null) {
+        length = 1;
+      }
+      a.columnStop = _currentCol + length;
+      _annotations.add(a);
+    }
+  }
+
+  void addBreakpointAnnotations() {
+    S.Script script = _loadedScript as S.Script;
+    for (var line = _startLine; line <= _endLine; line++) {
+      var bpts = script.getLine(line).breakpoints;
+      if (bpts != null) {
+        for (var bpt in bpts) {
+          if (bpt.location != null) {
+            _annotations.add(new BreakpointAnnotation(_isolate, _instances,
+                                                     _r.queue, bpt));
+          }
+        }
+      }
+    }
+  }
+
+  Future loadDeclarationsOfLibrary(S.Library lib) {
+    return lib.load().then((lib) {
+      var loads = [];
+      for (var func in lib.functions) {
+        loads.add(func.load());
+      }
+      for (var field in lib.variables) {
+        loads.add(field.load());
+      }
+      for (var cls in lib.classes) {
+        loads.add(loadDeclarationsOfClass(cls));
+      }
+      return Future.wait(loads);
+    });
+  }
+
+  Future loadDeclarationsOfClass(S.Class cls) {
+    return cls.load().then((cls) {
+      var loads = [];
+      for (var func in cls.functions) {
+        loads.add(func.load());
+      }
+      for (var field in cls.fields) {
+        loads.add(field.load());
+      }
+      return Future.wait(loads);
+    });
+  }
+
+  void addLibraryAnnotations() {
+    S.Script script = _loadedScript as S.Script;
+    for (S.ScriptLine line in script.lines) {
+      // TODO(rmacnak): Use a real scanner.
+      var pattern = new RegExp("library ${script.library.name}");
+      var match = pattern.firstMatch(line.text);
+      if (match != null) {
+        var anno = new LibraryAnnotation(_isolate, _instances, _r.queue,
+          _loadedScript.library,
+          Uris.inspect(isolate, object: _loadedScript.library));
+        anno.line = line.line;
+        anno.columnStart = match.start + 8;
+        anno.columnStop = match.end;
+        _annotations.add(anno);
+      }
+      // TODO(rmacnak): Use a real scanner.
+      pattern = new RegExp("part of ${script.library.name}");
+      match = pattern.firstMatch(line.text);
+      if (match != null) {
+        var anno = new LibraryAnnotation(_isolate, _instances, _r.queue,
+          _loadedScript.library,
+          Uris.inspect(isolate, object: _loadedScript.library));
+        anno.line = line.line;
+        anno.columnStart = match.start + 8;
+        anno.columnStop = match.end;
+        _annotations.add(anno);
+      }
+    }
+  }
+
+  M.Library resolveDependency(String relativeUri) {
+    S.Script script = _loadedScript as S.Script;
+    // This isn't really correct: we need to ask the embedder to do the
+    // uri canonicalization for us, but Observatory isn't in a position
+    // to invoke the library tag handler. Handle the most common cases.
+    var targetUri = Uri.parse(_loadedScript.library.uri).resolve(relativeUri);
+    for (M.Library l in script.isolate.libraries) {
+      if (targetUri.toString() == l.uri) {
+        return l;
+      }
+    }
+    if (targetUri.scheme == 'package') {
+      targetUri = "packages/${targetUri.path}";
+      for (M.Library l in script.isolate.libraries) {
+        if (targetUri.toString() == l.uri) {
+          return l;
+        }
+      }
+    }
+
+    print("Could not resolve library dependency: $relativeUri");
+    return null;
+  }
+
+  void addDependencyAnnotations() {
+    S.Script script = _loadedScript as S.Script;
+    // TODO(rmacnak): Use a real scanner.
+    var patterns = [
+      new RegExp("import '(.*)'"),
+      new RegExp('import "(.*)"'),
+      new RegExp("export '(.*)'"),
+      new RegExp('export "(.*)"'),
+    ];
+    for (S.ScriptLine line in script.lines) {
+      for (var pattern in patterns) {
+        var match = pattern.firstMatch(line.text);
+        if (match != null) {
+          M.Library target = resolveDependency(match[1]);
+          if (target != null) {
+            var anno = new LibraryAnnotation(_isolate, _instances, _r.queue,
+              target, Uris.inspect(isolate, object: target));
+            anno.line = line.line;
+            anno.columnStart = match.start + 8;
+            anno.columnStop = match.end - 1;
+            _annotations.add(anno);
+          }
+        }
+      }
+    }
+  }
+
+  M.Script resolvePart(String relativeUri) {
+    S.Script script = _loadedScript as S.Script;
+    var rootUri = Uri.parse(script.library.uri);
+    if (rootUri.scheme == 'dart') {
+      // The relative paths from dart:* libraries to their parts are not valid.
+      rootUri = new Uri.directory(script.library.uri);
+    }
+    var targetUri = rootUri.resolve(relativeUri);
+    for (M.Script s in script.library.scripts) {
+      if (targetUri.toString() == s.uri) {
+        return s;
+      }
+    }
+    print("Could not resolve part: $relativeUri");
+    return null;
+  }
+
+  void addPartAnnotations() {
+    S.Script script = _loadedScript as S.Script;
+    // TODO(rmacnak): Use a real scanner.
+    var patterns = [
+      new RegExp("part '(.*)'"),
+      new RegExp('part "(.*)"'),
+    ];
+    for (S.ScriptLine line in script.lines) {
+      for (var pattern in patterns) {
+        var match = pattern.firstMatch(line.text);
+        if (match != null) {
+          S.Script part = resolvePart(match[1]);
+          if (part != null) {
+            var anno = new PartAnnotation(_isolate, _instances, _r.queue, part,
+              Uris.inspect(isolate, object: part));
+            anno.line = line.line;
+            anno.columnStart = match.start + 6;
+            anno.columnStop = match.end - 1;
+            _annotations.add(anno);
+          }
+        }
+      }
+    }
+  }
+
+  void addClassAnnotations() {
+    S.Script script = _loadedScript as S.Script;
+    for (var cls in script.library.classes) {
+      if ((cls.location != null) && (cls.location.script == script)) {
+        var a = new ClassDeclarationAnnotation(_isolate, _instances, _r.queue,
+          cls, Uris.inspect(isolate, object: cls));
+        _annotations.add(a);
+      }
+    }
+  }
+
+  void addFieldAnnotations() {
+    S.Script script = _loadedScript as S.Script;
+    for (var field in script.library.variables) {
+      if ((field.location != null) && (field.location.script == script)) {
+        var a = new FieldDeclarationAnnotation(_isolate, _instances, _r.queue,
+          field, Uris.inspect(isolate, object: field));
+        _annotations.add(a);
+      }
+    }
+    for (var cls in script.library.classes) {
+      for (var field in cls.fields) {
+        if ((field.location != null) && (field.location.script == script)) {
+          var a = new FieldDeclarationAnnotation(_isolate, _instances, _r.queue,
+            field, Uris.inspect(isolate, object: field));
+          _annotations.add(a);
+        }
+      }
+    }
+  }
+
+  void addFunctionAnnotations() {
+    S.Script script = _loadedScript as S.Script;
+    for (var func in script.library.functions) {
+      if ((func.location != null) &&
+          (func.location.script == script) &&
+          (func.kind != M.FunctionKind.implicitGetter) &&
+          (func.kind != M.FunctionKind.implicitSetter)) {
+        // We annotate a field declaration with the field instead of the
+        // implicit getter or setter.
+        var a = new FunctionDeclarationAnnotation(_isolate, _instances,
+          _r.queue, func, Uris.inspect(isolate, object: func));
+        _annotations.add(a);
+      }
+    }
+    for (var cls in script.library.classes) {
+      S.Script script = _loadedScript as S.Script;
+      for (var func in cls.functions) {
+        if ((func.location != null) &&
+            (func.location.script == script) &&
+            (func.kind != M.FunctionKind.implicitGetter) &&
+            (func.kind != M.FunctionKind.implicitSetter)) {
+          // We annotate a field declaration with the field instead of the
+          // implicit getter or setter.
+          var a = new FunctionDeclarationAnnotation(_isolate, _instances,
+            _r.queue, func, Uris.inspect(isolate, object: func));
+          _annotations.add(a);
+        }
+      }
+    }
+  }
+
+  void addCallSiteAnnotations() {
+    for (var callSite in _callSites) {
+      _annotations.add(new CallSiteAnnotation(_isolate, _instances, _r.queue,
+        callSite));
+    }
+  }
+
+  void addLocalVariableAnnotations() {
+    S.Script script = _loadedScript as S.Script;
+    // We have local variable information.
+    if (_variables != null) {
+      // For each variable.
+      for (var variable in _variables) {
+        // Find variable usage locations.
+        var locations = script.scanForLocalVariableLocations(
+              variable['name'],
+              variable['_tokenPos'],
+              variable['_endTokenPos']);
+
+        // Annotate locations.
+        for (var location in locations) {
+          _annotations.add(new LocalVariableAnnotation(_isolate, _instances,
+                                                       _r.queue, location,
+                                                       variable['value']));
+        }
+      }
+    }
+  }
+
+  ButtonElement _newRefreshButton() {
+    var button = new ButtonElement();
+    button.classes = const ['refresh'];
+    button.onClick.listen((_) async {
+      button.disabled = true;
+      await _refresh();
+      button.disabled = false;
+    });
+    button.title = 'Refresh coverage';
+    button.text = '↺';
+    return button;
+  }
+
+  ButtonElement _newToggleProfileButton() {
+    ButtonElement button = new ButtonElement();
+    button.classes = _includeProfile ? const ['toggle-profile', 'enabled']
+                                     : const ['toggle-profile'];
+    button.title = 'Toggle CPU profile information';
+    button.onClick.listen((_) async {
+      _includeProfile = !_includeProfile;
+      button.classes.toggle('enabled');
+      button.disabled = true;
+      _refresh();
+      button.disabled = false;
+    });
+    button.text = '🔥';
+    return button;
+  }
+
+  Element linesTable() {
+    S.Script script = _loadedScript as S.Script;
+    var table = new DivElement();
+    table.classes.add("sourceTable");
+
+    _refreshButton = _newRefreshButton();
+    _toggleProfileButton = _newToggleProfileButton();
+    table.append(_refreshButton);
+    table.append(_toggleProfileButton);
+
+    if (_startLine == null || _endLine == null) {
+      return table;
+    }
+
+    var endLine = (_endPos != null
+                   ? _loadedScript.tokenToLine(_endPos)
+                   : script.lines.length + _loadedScript.lineOffset);
+    var lineNumPad = endLine.toString().length;
+
+    _annotationsCursor = 0;
+
+    int blankLineCount = 0;
+    for (int i = _startLine; i <= _endLine; i++) {
+      var line = script.getLine(i);
+      if (line.isBlank) {
+        // Try to introduce elipses if there are 4 or more contiguous
+        // blank lines.
+        blankLineCount++;
+      } else {
+        if (blankLineCount > 0) {
+          int firstBlank = i - blankLineCount;
+          int lastBlank = i - 1;
+          if (blankLineCount < 4) {
+            // Too few blank lines for an elipsis.
+            for (int j = firstBlank; j  <= lastBlank; j++) {
+              table.append(lineElement(script.getLine(j), lineNumPad));
+            }
+          } else {
+            // Add an elipsis for the skipped region.
+            table.append(lineElement(script.getLine(firstBlank), lineNumPad));
+            table.append(lineElement(null, lineNumPad));
+            table.append(lineElement(script.getLine(lastBlank), lineNumPad));
+          }
+          blankLineCount = 0;
+        }
+        table.append(lineElement(line, lineNumPad));
+      }
+    }
+
+    return table;
+  }
+
+  // Assumes annotations are sorted.
+  Annotation nextAnnotationOnLine(int line) {
+    if (_annotationsCursor >= _annotations.length) return null;
+    var annotation = _annotations[_annotationsCursor];
+
+    // Fast-forward past any annotations before the first line that
+    // we are displaying.
+    while (annotation.line < line) {
+      _annotationsCursor++;
+      if (_annotationsCursor >= _annotations.length) return null;
+      annotation = _annotations[_annotationsCursor];
+    }
+
+    // Next annotation is for a later line, don't advance past it.
+    if (annotation.line != line) return null;
+    _annotationsCursor++;
+    return annotation;
+  }
+
+  Element lineElement(S.ScriptLine line, int lineNumPad) {
+    var e = new DivElement();
+    e.classes.add("sourceRow");
+    e.append(lineBreakpointElement(line));
+    e.append(lineNumberElement(line, lineNumPad));
+    if (_includeProfile) {
+      e.append(lineProfileElement(line, false));
+      e.append(lineProfileElement(line, true));
+    }
+    e.append(lineSourceElement(line));
+    return e;
+  }
+
+  Element lineProfileElement(S.ScriptLine line, bool self) {
+    var e = span('');
+    e.classes.add('noCopy');
+    if (self) {
+      e.title = 'Self %';
+    } else {
+      e.title = 'Total %';
+    }
+
+    if (line == null) {
+      e.classes.add('notSourceProfile');
+      e.text = nbsp;
+      return e;
+    }
+
+    var ranges = _rangeMap[line.line];
+    if ((ranges == null) || ranges.isEmpty) {
+      e.classes.add('notSourceProfile');
+      e.text = nbsp;
+      return e;
+    }
+
+    ScriptLineProfile lineProfile = _profileMap[line.line];
+    if (lineProfile == null) {
+      e.classes.add('noProfile');
+      e.text = nbsp;
+      return e;
+    }
+
+    if (self) {
+      e.text = lineProfile.formattedSelfTicks;
+    } else {
+      e.text = lineProfile.formattedTotalTicks;
+    }
+
+    if (lineProfile.isHot(self)) {
+      e.classes.add('hotProfile');
+    } else if (lineProfile.isMedium(self)) {
+      e.classes.add('mediumProfile');
+    } else {
+      e.classes.add('coldProfile');
+    }
+
+    return e;
+  }
+
+  Element lineBreakpointElement(S.ScriptLine line) {
+    var e = new DivElement();
+    if (line == null || !_possibleBreakpointLines.contains(line.line)) {
+      e.classes.add('noCopy');
+      e.classes.add("emptyBreakpoint");
+      e.text = nbsp;
+      return e;
+    }
+
+    e.text = 'B';
+    var busy = false;
+    void update() {
+      e.classes.clear();
+      e.classes.add('noCopy');
+      if (busy) {
+        e.classes.add("busyBreakpoint");
+      } else if (line.breakpoints != null) {
+        bool resolved = false;
+        for (var bpt in line.breakpoints) {
+          if (bpt.resolved) {
+            resolved = true;
+            break;
+          }
+        }
+        if (resolved) {
+          e.classes.add("resolvedBreakpoint");
+        } else {
+          e.classes.add("unresolvedBreakpoint");
+        }
+      } else {
+        e.classes.add("possibleBreakpoint");
+      }
+    }
+
+    line.changes.listen((_) => update());
+    e.onClick.listen((event) {
+      if (busy) {
+        return;
+      }
+      busy = true;
+      if (line.breakpoints == null) {
+        // No breakpoint.  Add it.
+        line.script.isolate.addBreakpoint(line.script, line.line)
+          .catchError((e, st) {
+            if (e is! S.ServerRpcException ||
+                (e as S.ServerRpcException).code !=
+                S.ServerRpcException.kCannotAddBreakpoint) {
+              ObservatoryApplication.app.handleException(e, st);
+            }})
+          .whenComplete(() {
+            busy = false;
+            update();
+          });
+      } else {
+        // Existing breakpoint.  Remove it.
+        List pending = [];
+        for (var bpt in line.breakpoints) {
+          pending.add(line.script.isolate.removeBreakpoint(bpt));
+        }
+        Future.wait(pending).then((_) {
+          busy = false;
+          update();
+        });
+      }
+      update();
+    });
+    update();
+    return e;
+  }
+
+  Element lineNumberElement(S.ScriptLine line, int lineNumPad) {
+    var lineNumber = line == null ? "..." : line.line;
+    var e = span("$nbsp${lineNumber.toString().padLeft(lineNumPad,nbsp)}$nbsp");
+    e.classes.add('noCopy');
+    if (lineNumber == _currentLine) {
+      hitsCurrent(e);
+      return e;
+    }
+    var ranges = _rangeMap[lineNumber];
+    if ((ranges == null) || ranges.isEmpty) {
+      // This line is not code.
+      hitsUnknown(e);
+      return e;
+    }
+    bool compiled = true;
+    bool hasCallInfo = false;
+    bool executed = false;
+    for (var range in ranges) {
+      if (range['compiled']) {
+        for (var callSite in range['callSites']) {
+          var callLine = line.script.tokenToLine(callSite['tokenPos']);
+          if (lineNumber == callLine) {
+            // The call site is on the current line.
+            hasCallInfo = true;
+            for (var cacheEntry in callSite['cacheEntries']) {
+              if (cacheEntry['count'] > 0) {
+                // If any call site on the line has been executed, we
+                // mark the line as executed.
+                executed = true;
+                break;
+              }
+            }
+          }
+        }
+      } else {
+        // If any range isn't compiled, show the line as not compiled.
+        // This is necessary so that nested functions appear to be uncompiled.
+        compiled = false;
+      }
+    }
+    if (executed) {
+      hitsExecuted(e);
+    } else if (hasCallInfo) {
+      hitsNotExecuted(e);
+    } else if (compiled) {
+      hitsCompiled(e);
+    } else {
+      hitsNotCompiled(e);
+    }
+    return e;
+  }
+
+  Element lineSourceElement(S.ScriptLine line) {
+    var e = new DivElement();
+    e.classes.add("sourceItem");
+
+    if (line != null) {
+      e.classes.add(makeLineClass(line.line));
+      if (line.line == _currentLine) {
+        e.classes.add("currentLine");
+      }
+
+      var position = 0;
+      consumeUntil(var stop) {
+        if (stop <= position) {
+          return null;  // Empty gap between annotations/boundries.
+        }
+        if (stop > line.text.length) {
+          // Approximated token length can run past the end of the line.
+          stop = line.text.length;
+        }
+
+        var chunk = line.text.substring(position, stop);
+        var chunkNode = span(chunk);
+        e.append(chunkNode);
+        position = stop;
+        return chunkNode;
+      }
+
+      // TODO(rmacnak): Tolerate overlapping annotations.
+      var annotation;
+      while ((annotation = nextAnnotationOnLine(line.line)) != null) {
+        consumeUntil(annotation.columnStart);
+        annotation.applyStyleTo(consumeUntil(annotation.columnStop));
+      }
+      consumeUntil(line.text.length);
+    }
+
+    // So blank lines are included when copying script to the clipboard.
+    e.append(span('\n'));
+
+    return e;
+  }
+
+  /// Exclude nodes from being copied, for example the line numbers and
+  /// breakpoint toggles in script insets. Must be called after [root]'s
+  /// children have been added, and only supports one node at a time.
+  static void _makeCssClassUncopyable(Element root, String className) {
+    var noCopyNodes = root.getElementsByClassName(className);
+    for (var node in noCopyNodes) {
+      node.style.setProperty('-moz-user-select', 'none');
+      node.style.setProperty('-khtml-user-select', 'none');
+      node.style.setProperty('-webkit-user-select', 'none');
+      node.style.setProperty('-ms-user-select', 'none');
+      node.style.setProperty('user-select', 'none');
+    }
+    root.onCopy.listen((event) {
+      // Mark the nodes as hidden before the copy happens, then mark them as
+      // visible on the next event loop turn.
+      for (var node in noCopyNodes) {
+        node.style.visibility = 'hidden';
+      }
+      Timer.run(() {
+        for (var node in noCopyNodes) {
+          node.style.visibility = 'visible';
+        }
+      });
+    });
+  }
+}
 
 const nbsp = "\u00A0";
 
@@ -56,11 +973,16 @@
 
 
 abstract class Annotation implements Comparable<Annotation> {
+  M.IsolateRef _isolate;
+  M.InstanceRepository _instances;
+  RenderingQueue queue;
   int line;
   int columnStart;
   int columnStop;
   int get priority;
 
+  Annotation(this._isolate, this._instances, this.queue);
+
   void applyStyleTo(element);
 
   int compareTo(Annotation other) {
@@ -99,15 +1021,18 @@
   }
 
   Element serviceRef(object) {
-    AnyServiceRefElement e = new Element.tag("any-service-ref");
-    e.ref = object;
-    return e;
+    return anyRef(_isolate, object, _instances, queue: queue);
   }
 }
 
 class CurrentExecutionAnnotation extends Annotation {
   int priority = 0;  // highest priority.
 
+  CurrentExecutionAnnotation(M.IsolateRef isolate,
+                             M.InstanceRepository instances,
+                             RenderingQueue queue)
+    : super(isolate, instances, queue);
+
   void applyStyleTo(element) {
     if (element == null) {
       return;  // TODO(rmacnak): Handling overlapping annotations.
@@ -118,17 +1043,19 @@
 }
 
 class BreakpointAnnotation extends Annotation {
-  Breakpoint bpt;
+  M.Breakpoint bpt;
   int priority = 1;
 
-  BreakpointAnnotation(this.bpt) {
+  BreakpointAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+                       RenderingQueue queue, this.bpt)
+    : super(isolate, instances, queue) {
     var script = bpt.location.script;
     var location = bpt.location;
     if (location.tokenPos != null) {
       var pos = location.tokenPos;
       line = script.tokenToLine(pos);
       columnStart = script.tokenToCol(pos) - 1;  // tokenToCol is 1-origin.
-    } else if (location is UnresolvedSourceLocation) {
+    } else if (location is M.UnresolvedSourceLocation) {
       line = location.line;
       columnStart = location.column;
       if (columnStart == null) {
@@ -160,11 +1087,13 @@
 }
 
 class LibraryAnnotation extends Annotation {
-  Library target;
+  S.Library target;
   String url;
   int priority = 2;
 
-  LibraryAnnotation(this.target, this.url);
+  LibraryAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+                    RenderingQueue queue, this.target, this.url)
+    : super(isolate, instances, queue);
 
   void applyStyleTo(element) {
     if (element == null) {
@@ -176,11 +1105,13 @@
 }
 
 class PartAnnotation extends Annotation {
-  Script part;
+  S.Script part;
   String url;
   int priority = 2;
 
-  PartAnnotation(this.part, this.url);
+  PartAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+                RenderingQueue queue, this.part, this.url)
+    : super(isolate, instances, queue);
 
   void applyStyleTo(element) {
     if (element == null) {
@@ -195,7 +1126,9 @@
   final value;
   int priority = 2;
 
-  LocalVariableAnnotation(LocalVarLocation location, this.value) {
+  LocalVariableAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+                          RenderingQueue queue, S.LocalVarLocation location,
+                          this.value): super(isolate, instances, queue) {
     line = location.line;
     columnStart = location.column;
     columnStop = location.endColumn;
@@ -211,10 +1144,12 @@
 }
 
 class CallSiteAnnotation extends Annotation {
-  CallSite callSite;
+  S.CallSite callSite;
   int priority = 2;
 
-  CallSiteAnnotation(this.callSite) {
+  CallSiteAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+                     RenderingQueue queue, this.callSite)
+    : super(isolate, instances, queue) {
     line = callSite.line;
     columnStart = callSite.column - 1;  // Call site is 1-origin.
     var tokenLength = callSite.script.guessTokenLength(line, columnStart);
@@ -261,9 +1196,11 @@
   String url;
   int priority = 2;
 
-  DeclarationAnnotation(decl, this.url) {
+  DeclarationAnnotation(M.IsolateRef isolate, M.InstanceRepository instances,
+                        RenderingQueue queue, decl, this.url)
+    : super(isolate, instances, queue) {
     assert(decl.loaded);
-    SourceLocation location = decl.location;
+    S.SourceLocation location = decl.location;
     if (location == null) {
       line = 0;
       columnStart = 0;
@@ -271,7 +1208,7 @@
       return;
     }
 
-    Script script = location.script;
+    S.Script script = location.script;
     line = script.tokenToLine(location.tokenPos);
     columnStart = script.tokenToCol(location.tokenPos);
     if ((line == null) || (columnStart == null)) {
@@ -296,11 +1233,13 @@
 }
 
 class ClassDeclarationAnnotation extends DeclarationAnnotation {
-  Class klass;
+  S.Class klass;
 
-  ClassDeclarationAnnotation(Class cls, String url)
+  ClassDeclarationAnnotation(M.IsolateRef isolate,
+                             M.InstanceRepository instances,
+                             RenderingQueue queue, S.Class cls, String url)
     : klass = cls,
-      super(cls, url);
+      super(isolate, instances, queue, cls, url);
 
   void applyStyleTo(element) {
     if (element == null) {
@@ -312,11 +1251,13 @@
 }
 
 class FieldDeclarationAnnotation extends DeclarationAnnotation {
-  Field field;
+  S.Field field;
 
-  FieldDeclarationAnnotation(Field fld, String url)
+  FieldDeclarationAnnotation(M.IsolateRef isolate,
+                             M.InstanceRepository instances,
+                             RenderingQueue queue, S.Field fld, String url)
     : field = fld,
-      super(fld, url);
+      super(isolate, instances, queue, fld, url);
 
   void applyStyleTo(element) {
     if (element == null) {
@@ -329,11 +1270,14 @@
 }
 
 class FunctionDeclarationAnnotation extends DeclarationAnnotation {
-  ServiceFunction function;
+  S.ServiceFunction function;
 
-  FunctionDeclarationAnnotation(ServiceFunction func, String url)
+  FunctionDeclarationAnnotation(M.IsolateRef isolate,
+                                M.InstanceRepository instances,
+                                RenderingQueue queue, S.ServiceFunction func,
+                                String url)
     : function = func,
-      super(func, url);
+      super(isolate, instances, queue, func, url);
 
   void applyStyleTo(element) {
     if (element == null) {
@@ -400,980 +1344,3 @@
   bool isHot(bool self) => _percent(self) > kHotThreshold;
   bool isMedium(bool self) => _percent(self) > kMediumThreshold;
 }
-
-/// Box with script source code in it.
-@CustomTag('script-inset')
-class ScriptInsetElement extends ObservatoryElement {
-  @published Script script;
-  @published int startPos;
-  @published int endPos;
-
-  /// Set the height to make the script inset scroll.  Otherwise it
-  /// will show from startPos to endPos.
-  @published String height = null;
-
-  @published int currentPos;
-  @published bool inDebuggerContext = false;
-  @published ObservableList variables;
-
-  @published Element scroller;
-  RefreshButtonElement _refreshButton;
-  ToggleButtonElement _toggleProfileButton;
-
-  int _currentLine;
-  int _currentCol;
-  int _startLine;
-  int _endLine;
-
-  Map<int, List<ServiceMap>> _rangeMap = {};
-  Set _callSites = new Set<CallSite>();
-  Set _possibleBreakpointLines = new Set<int>();
-  Map<int, ScriptLineProfile> _profileMap = {};
-
-  var annotations = [];
-  var annotationsCursor;
-
-  StreamSubscription _scriptChangeSubscription;
-  Future<StreamSubscription> _debugSubscriptionFuture;
-  StreamSubscription _scrollSubscription;
-
-  bool hasLoadedLibraryDeclarations = false;
-  bool _includeProfile = false;
-
-  String makeLineId(int line) {
-    return 'line-$line';
-  }
-
-  void _scrollToCurrentPos() {
-    var line = shadowRoot.getElementById(makeLineId(_currentLine));
-    if (line != null) {
-      line.scrollIntoView();
-    }
-  }
-
-  void attached() {
-    super.attached();
-    _debugSubscriptionFuture =
-        app.vm.listenEventStream(VM.kDebugStream, _onDebugEvent);
-    if (scroller != null) {
-      _scrollSubscription = scroller.onScroll.listen(_onScroll);
-    } else {
-      _scrollSubscription = window.onScroll.listen(_onScroll);
-    }
-  }
-
-  void detached() {
-    cancelFutureSubscription(_debugSubscriptionFuture);
-    _debugSubscriptionFuture = null;
-    if (_scrollSubscription != null) {
-      _scrollSubscription.cancel();
-      _scrollSubscription = null;
-    }
-    if (_scriptChangeSubscription != null) {
-      // Don't leak. If only Dart and Javascript exposed weak references...
-      _scriptChangeSubscription.cancel();
-      _scriptChangeSubscription = null;
-    }
-    super.detached();
-  }
-
-  void _onScroll(event) {
-    if (_refreshButton != null) {
-      var newTop = _buttonTop(_refreshButton);
-      if (_refreshButton.style.top != newTop) {
-        _refreshButton.style.top = '${newTop}px';
-      }
-    }
-    if (_toggleProfileButton != null) {
-      var newTop = _buttonTop(_toggleProfileButton);
-      if (_toggleProfileButton.style.top != newTop) {
-        _toggleProfileButton.style.top = '${newTop}px';
-      }
-    }
-  }
-
-  void _onDebugEvent(event) {
-    if (script == null) {
-      return;
-    }
-    switch (event.kind) {
-      case ServiceEvent.kBreakpointAdded:
-      case ServiceEvent.kBreakpointResolved:
-      case ServiceEvent.kBreakpointRemoved:
-        var loc = event.breakpoint.location;
-        if (loc.script == script) {
-          int line;
-          if (loc.tokenPos != null) {
-            line = script.tokenToLine(loc.tokenPos);
-          } else {
-            line = loc.line;
-          }
-          if ((line >= _startLine) && (line <= _endLine)) {
-            _updateTask.queue();
-          }
-        }
-        break;
-      default:
-        // Ignore.
-        break;
-    }
-  }
-
-  void currentPosChanged(oldValue) {
-    _updateTask.queue();
-    _scrollToCurrentPos();
-  }
-
-  void startPosChanged(oldValue) {
-    _updateTask.queue();
-  }
-
-  void endPosChanged(oldValue) {
-    _updateTask.queue();
-  }
-
-  void scriptChanged(oldValue) {
-    _updateTask.queue();
-  }
-
-  void variablesChanged(oldValue) {
-    _updateTask.queue();
-  }
-
-  Element a(String text) => new AnchorElement()..text = text;
-  Element span(String text) => new SpanElement()..text = text;
-
-  Element hitsCurrent(Element element) {
-    element.classes.add('hitsCurrent');
-    element.title = "";
-    return element;
-  }
-  Element hitsUnknown(Element element) {
-    element.classes.add('hitsNone');
-    element.title = "";
-    return element;
-  }
-  Element hitsNotExecuted(Element element) {
-    element.classes.add('hitsNotExecuted');
-    element.title = "Line did not execute";
-    return element;
-  }
-  Element hitsExecuted(Element element) {
-    element.classes.add('hitsExecuted');
-    element.title = "Line did execute";
-    return element;
-  }
-  Element hitsCompiled(Element element) {
-    element.classes.add('hitsCompiled');
-    element.title = "Line in compiled function";
-    return element;
-  }
-  Element hitsNotCompiled(Element element) {
-    element.classes.add('hitsNotCompiled');
-    element.title = "Line in uncompiled function";
-    return element;
-  }
-
-  Element container;
-
-  Future _refresh() async {
-    await update();
-  }
-
-  // Build _rangeMap and _callSites from a source report.
-  Future _refreshSourceReport() async {
-    var reports = [Isolate.kCallSitesReport,
-                   Isolate.kPossibleBreakpointsReport];
-    if (_includeProfile) {
-      reports.add(Isolate.kProfileReport);
-    }
-    var sourceReport = await script.isolate.getSourceReport(
-        reports,
-        script, startPos, endPos);
-    _possibleBreakpointLines = getPossibleBreakpointLines(sourceReport, script);
-    _rangeMap.clear();
-    _callSites.clear();
-    _profileMap.clear();
-    for (var range in sourceReport['ranges']) {
-      int startLine = script.tokenToLine(range['startPos']);
-      int endLine = script.tokenToLine(range['endPos']);
-      // TODO(turnidge): Track down the root cause of null startLine/endLine.
-      if ((startLine != null) && (endLine != null)) {
-        for (var line = startLine; line <= endLine; line++) {
-          var rangeList = _rangeMap[line];
-          if (rangeList == null) {
-            _rangeMap[line] = [range];
-          } else {
-            rangeList.add(range);
-          }
-        }
-      }
-      if (_includeProfile && range['profile'] != null) {
-        List positions = range['profile']['positions'];
-        List exclusiveTicks = range['profile']['exclusiveTicks'];
-        List inclusiveTicks = range['profile']['inclusiveTicks'];
-        int sampleCount = range['profile']['metadata']['sampleCount'];
-        assert(positions.length == exclusiveTicks.length);
-        assert(positions.length == inclusiveTicks.length);
-        for (int i = 0; i < positions.length; i++) {
-          if (positions[i] is String) {
-            // String positions are classifying token positions.
-            // TODO(johnmccutchan): Add classifier data to UI.
-            continue;
-          }
-          int line = script.tokenToLine(positions[i]);
-          ScriptLineProfile lineProfile = _profileMap[line];
-          if (lineProfile == null) {
-            lineProfile = new ScriptLineProfile(line, sampleCount);
-            _profileMap[line] = lineProfile;
-          }
-          lineProfile.process(exclusiveTicks[i], inclusiveTicks[i]);
-        }
-      }
-      if (range['compiled']) {
-        var rangeCallSites = range['callSites'];
-        if (rangeCallSites != null) {
-          for (var callSiteMap in rangeCallSites) {
-            _callSites.add(new CallSite.fromMap(callSiteMap, script));
-          }
-        }
-      }
-    }
-  }
-
-  Task _updateTask;
-  Future update() async {
-    assert(_updateTask != null);
-    if (script == null) {
-      // We may have previously had a script.
-      if (container != null) {
-        container.children.clear();
-      }
-      return;
-    }
-    if (!script.loaded) {
-      await script.load();
-    }
-    if (_scriptChangeSubscription == null) {
-      _scriptChangeSubscription = script.changes.listen((_) => update());
-    }
-    await _refreshSourceReport();
-
-    computeAnnotations();
-
-    var table = linesTable();
-    var firstBuild = false;
-    if (container == null) {
-      // Indirect to avoid deleting the style element.
-      container = new DivElement();
-      shadowRoot.append(container);
-      firstBuild = true;
-    }
-    container.children.clear();
-    container.children.add(table);
-    makeCssClassUncopyable(table, "noCopy");
-    if (firstBuild) {
-      _scrollToCurrentPos();
-    }
-  }
-
-  void computeAnnotations() {
-    _startLine = (startPos != null
-                  ? script.tokenToLine(startPos)
-                  : 1 + script.lineOffset);
-    _currentLine = (currentPos != null
-                    ? script.tokenToLine(currentPos)
-                    : null);
-    _currentCol = (currentPos != null
-                   ? (script.tokenToCol(currentPos))
-                   : null);
-    if (_currentCol != null) {
-      _currentCol--;  // make this 0-based.
-    }
-
-    _endLine = (endPos != null
-                ? script.tokenToLine(endPos)
-                : script.lines.length + script.lineOffset);
-
-    if (_startLine == null || _endLine == null) {
-      return;
-    }
-
-    annotations.clear();
-
-    addCurrentExecutionAnnotation();
-    addBreakpointAnnotations();
-
-    if (!inDebuggerContext && script.library != null) {
-      if (hasLoadedLibraryDeclarations) {
-        addLibraryAnnotations();
-        addDependencyAnnotations();
-        addPartAnnotations();
-        addClassAnnotations();
-        addFieldAnnotations();
-        addFunctionAnnotations();
-        addCallSiteAnnotations();
-      } else {
-        loadDeclarationsOfLibrary(script.library).then((_) {
-          hasLoadedLibraryDeclarations = true;
-          update();
-        });
-      }
-    }
-
-    addLocalVariableAnnotations();
-
-    annotations.sort();
-  }
-
-  void addCurrentExecutionAnnotation() {
-    if (_currentLine != null) {
-      var a = new CurrentExecutionAnnotation();
-      a.line = _currentLine;
-      a.columnStart = _currentCol;
-      var length = script.guessTokenLength(_currentLine, _currentCol);
-      if (length == null) {
-        length = 1;
-      }
-      a.columnStop = _currentCol + length;
-      annotations.add(a);
-    }
-  }
-
-  void addBreakpointAnnotations() {
-    for (var line = _startLine; line <= _endLine; line++) {
-      var bpts = script.getLine(line).breakpoints;
-      if (bpts != null) {
-        for (var bpt in bpts) {
-          if (bpt.location != null) {
-            annotations.add(new BreakpointAnnotation(bpt));
-          }
-        }
-      }
-    }
-  }
-
-  Future loadDeclarationsOfLibrary(Library lib) {
-    return lib.load().then((lib) {
-      var loads = [];
-      for (var func in lib.functions) {
-        loads.add(func.load());
-      }
-      for (var field in lib.variables) {
-        loads.add(field.load());
-      }
-      for (var cls in lib.classes) {
-        loads.add(loadDeclarationsOfClass(cls));
-      }
-      return Future.wait(loads);
-    });
-  }
-
-  Future loadDeclarationsOfClass(Class cls) {
-    return cls.load().then((cls) {
-      var loads = [];
-      for (var func in cls.functions) {
-        loads.add(func.load());
-      }
-      for (var field in cls.fields) {
-        loads.add(field.load());
-      }
-      return Future.wait(loads);
-    });
-  }
-
-  String inspectLink(ServiceObject ref) {
-    return gotoLink('/inspect', ref);
-  }
-
-  void addLibraryAnnotations() {
-    for (ScriptLine line in script.lines) {
-      // TODO(rmacnak): Use a real scanner.
-      var pattern = new RegExp("library ${script.library.name}");
-      var match = pattern.firstMatch(line.text);
-      if (match != null) {
-        var anno = new LibraryAnnotation(script.library,
-                                         inspectLink(script.library));
-        anno.line = line.line;
-        anno.columnStart = match.start + 8;
-        anno.columnStop = match.end;
-        annotations.add(anno);
-      }
-      // TODO(rmacnak): Use a real scanner.
-      pattern = new RegExp("part of ${script.library.name}");
-      match = pattern.firstMatch(line.text);
-      if (match != null) {
-        var anno = new LibraryAnnotation(script.library,
-                                         inspectLink(script.library));
-        anno.line = line.line;
-        anno.columnStart = match.start + 8;
-        anno.columnStop = match.end;
-        annotations.add(anno);
-      }
-    }
-  }
-
-  Library resolveDependency(String relativeUri) {
-    // This isn't really correct: we need to ask the embedder to do the
-    // uri canonicalization for us, but Observatory isn't in a position
-    // to invoke the library tag handler. Handle the most common cases.
-    var targetUri = Uri.parse(script.library.uri).resolve(relativeUri);
-    for (Library l in script.isolate.libraries) {
-      if (targetUri.toString() == l.uri) {
-        return l;
-      }
-    }
-    if (targetUri.scheme == 'package') {
-      targetUri = "packages/${targetUri.path}";
-      for (Library l in script.isolate.libraries) {
-        if (targetUri.toString() == l.uri) {
-          return l;
-        }
-      }
-    }
-
-    Logger.root.info("Could not resolve library dependency: $relativeUri");
-    return null;
-  }
-
-  void addDependencyAnnotations() {
-    // TODO(rmacnak): Use a real scanner.
-    var patterns = [
-      new RegExp("import '(.*)'"),
-      new RegExp('import "(.*)"'),
-      new RegExp("export '(.*)'"),
-      new RegExp('export "(.*)"'),
-    ];
-    for (ScriptLine line in script.lines) {
-      for (var pattern in patterns) {
-        var match = pattern.firstMatch(line.text);
-        if (match != null) {
-          Library target = resolveDependency(match[1]);
-          if (target != null) {
-            var anno = new LibraryAnnotation(target, inspectLink(target));
-            anno.line = line.line;
-            anno.columnStart = match.start + 8;
-            anno.columnStop = match.end - 1;
-            annotations.add(anno);
-          }
-        }
-      }
-    }
-  }
-
-  Script resolvePart(String relativeUri) {
-    var rootUri = Uri.parse(script.library.uri);
-    if (rootUri.scheme == 'dart') {
-      // The relative paths from dart:* libraries to their parts are not valid.
-      rootUri = new Uri.directory(script.library.uri);
-    }
-    var targetUri = rootUri.resolve(relativeUri);
-    for (Script s in script.library.scripts) {
-      if (targetUri.toString() == s.uri) {
-        return s;
-      }
-    }
-    Logger.root.info("Could not resolve part: $relativeUri");
-    return null;
-  }
-
-  void addPartAnnotations() {
-    // TODO(rmacnak): Use a real scanner.
-    var patterns = [
-      new RegExp("part '(.*)'"),
-      new RegExp('part "(.*)"'),
-    ];
-    for (ScriptLine line in script.lines) {
-      for (var pattern in patterns) {
-        var match = pattern.firstMatch(line.text);
-        if (match != null) {
-          Script part = resolvePart(match[1]);
-          if (part != null) {
-            var anno = new PartAnnotation(part, inspectLink(part));
-            anno.line = line.line;
-            anno.columnStart = match.start + 6;
-            anno.columnStop = match.end - 1;
-            annotations.add(anno);
-          }
-        }
-      }
-    }
-  }
-
-  void addClassAnnotations() {
-    for (var cls in script.library.classes) {
-      if ((cls.location != null) && (cls.location.script == script)) {
-        var a = new ClassDeclarationAnnotation(cls, inspectLink(cls));
-        annotations.add(a);
-      }
-    }
-  }
-
-  void addFieldAnnotations() {
-    for (var field in script.library.variables) {
-      if ((field.location != null) && (field.location.script == script)) {
-        var a = new FieldDeclarationAnnotation(field, inspectLink(field));
-        annotations.add(a);
-      }
-    }
-    for (var cls in script.library.classes) {
-      for (var field in cls.fields) {
-        if ((field.location != null) && (field.location.script == script)) {
-          var a = new FieldDeclarationAnnotation(field, inspectLink(field));
-          annotations.add(a);
-        }
-      }
-    }
-  }
-
-  void addFunctionAnnotations() {
-    for (var func in script.library.functions) {
-      if ((func.location != null) &&
-          (func.location.script == script) &&
-          (func.kind != M.FunctionKind.implicitGetter) &&
-          (func.kind != M.FunctionKind.implicitSetter)) {
-        // We annotate a field declaration with the field instead of the
-        // implicit getter or setter.
-        var a = new FunctionDeclarationAnnotation(func, inspectLink(func));
-        annotations.add(a);
-      }
-    }
-    for (var cls in script.library.classes) {
-      for (var func in cls.functions) {
-        if ((func.location != null) &&
-            (func.location.script == script) &&
-            (func.kind != M.FunctionKind.implicitGetter) &&
-            (func.kind != M.FunctionKind.implicitSetter)) {
-          // We annotate a field declaration with the field instead of the
-          // implicit getter or setter.
-          var a = new FunctionDeclarationAnnotation(func, inspectLink(func));
-          annotations.add(a);
-        }
-      }
-    }
-  }
-
-  void addCallSiteAnnotations() {
-    for (var callSite in _callSites) {
-      annotations.add(new CallSiteAnnotation(callSite));
-    }
-  }
-
-  void addLocalVariableAnnotations() {
-    // We have local variable information.
-    if (variables != null) {
-      // For each variable.
-      for (var variable in variables) {
-        // Find variable usage locations.
-        var locations = script.scanForLocalVariableLocations(
-              variable['name'],
-              variable['_tokenPos'],
-              variable['_endTokenPos']);
-
-        // Annotate locations.
-        for (var location in locations) {
-          annotations.add(new LocalVariableAnnotation(location,
-                                                      variable['value']));
-        }
-      }
-    }
-  }
-
-  int _buttonTop(Element element) {
-    if (element == null) {
-      return 5;
-    }
-    const padding = 5;
-    // TODO (cbernaschina) check if this is needed.
-    const navbarHeight = 40;
-    var rect = getBoundingClientRect();
-    var buttonHeight = element.clientHeight;
-    return min(max(0, navbarHeight - rect.top) + padding,
-               rect.height - (buttonHeight + padding));
-  }
-
-  RefreshButtonElement _newRefreshButton() {
-    var button = new Element.tag('refresh-button');
-    button.style.position = 'absolute';
-    button.style.display = 'inline-block';
-    button.style.top = '${_buttonTop(null)}px';
-    button.style.right = '5px';
-    button.callback = _refresh;
-    button.title = 'Refresh coverage';
-    return button;
-  }
-
-  ToggleButtonElement _newToggleProfileButton() {
-    ToggleButtonElement button = new Element.tag('toggle-button');
-    button.style.position = 'absolute';
-    button.style.display = 'inline-block';
-    button.style.top = '${_buttonTop(null)}px';
-    button.style.right = '30px';
-    button.title = 'Toggle CPU profile information';
-    final String enabledColor = 'black';
-    final String disabledColor = 'rgba(0, 0, 0 ,.3)';
-    button.callback = (enabled) async {
-      _includeProfile = enabled;
-      if (button.children.length > 0) {
-        var content = button.children[0];
-        if (enabled) {
-          content.style.color = enabledColor;
-        } else {
-          content.style.color = disabledColor;
-        }
-      }
-      await update();
-    };
-    button.children.add(new Element.tag('icon-whatshot'));
-    button.children[0].style.color = disabledColor;
-    button.enabled = _includeProfile;
-    return button;
-  }
-
-  Element linesTable() {
-    var table = new DivElement();
-    table.classes.add("sourceTable");
-
-    _refreshButton = _newRefreshButton();
-    _toggleProfileButton = _newToggleProfileButton();
-    table.append(_refreshButton);
-    table.append(_toggleProfileButton);
-
-    if (_startLine == null || _endLine == null) {
-      return table;
-    }
-
-    var endLine = (endPos != null
-                   ? script.tokenToLine(endPos)
-                   : script.lines.length + script.lineOffset);
-    var lineNumPad = endLine.toString().length;
-
-    annotationsCursor = 0;
-
-    int blankLineCount = 0;
-    for (int i = _startLine; i <= _endLine; i++) {
-      var line = script.getLine(i);
-      if (line.isBlank) {
-        // Try to introduce elipses if there are 4 or more contiguous
-        // blank lines.
-        blankLineCount++;
-      } else {
-        if (blankLineCount > 0) {
-          int firstBlank = i - blankLineCount;
-          int lastBlank = i - 1;
-          if (blankLineCount < 4) {
-            // Too few blank lines for an elipsis.
-            for (int j = firstBlank; j  <= lastBlank; j++) {
-              table.append(lineElement(script.getLine(j), lineNumPad));
-            }
-          } else {
-            // Add an elipsis for the skipped region.
-            table.append(lineElement(script.getLine(firstBlank), lineNumPad));
-            table.append(lineElement(null, lineNumPad));
-            table.append(lineElement(script.getLine(lastBlank), lineNumPad));
-          }
-          blankLineCount = 0;
-        }
-        table.append(lineElement(line, lineNumPad));
-      }
-    }
-
-    return table;
-  }
-
-  // Assumes annotations are sorted.
-  Annotation nextAnnotationOnLine(int line) {
-    if (annotationsCursor >= annotations.length) return null;
-    var annotation = annotations[annotationsCursor];
-
-    // Fast-forward past any annotations before the first line that
-    // we are displaying.
-    while (annotation.line < line) {
-      annotationsCursor++;
-      if (annotationsCursor >= annotations.length) return null;
-      annotation = annotations[annotationsCursor];
-    }
-
-    // Next annotation is for a later line, don't advance past it.
-    if (annotation.line != line) return null;
-    annotationsCursor++;
-    return annotation;
-  }
-
-  Element lineElement(ScriptLine line, int lineNumPad) {
-    var e = new DivElement();
-    e.classes.add("sourceRow");
-    e.append(lineBreakpointElement(line));
-    e.append(lineNumberElement(line, lineNumPad));
-    if (_includeProfile) {
-      e.append(lineProfileElement(line, false));
-      e.append(lineProfileElement(line, true));
-    }
-    e.append(lineSourceElement(line));
-    return e;
-  }
-
-  Element lineProfileElement(ScriptLine line, bool self) {
-    var e = span('');
-    e.classes.add('noCopy');
-    if (self) {
-      e.title = 'Self %';
-    } else {
-      e.title = 'Total %';
-    }
-
-    if (line == null) {
-      e.classes.add('notSourceProfile');
-      e.text = nbsp;
-      return e;
-    }
-
-    var ranges = _rangeMap[line.line];
-    if ((ranges == null) || ranges.isEmpty) {
-      e.classes.add('notSourceProfile');
-      e.text = nbsp;
-      return e;
-    }
-
-    ScriptLineProfile lineProfile = _profileMap[line.line];
-    if (lineProfile == null) {
-      e.classes.add('noProfile');
-      e.text = nbsp;
-      return e;
-    }
-
-    if (self) {
-      e.text = lineProfile.formattedSelfTicks;
-    } else {
-      e.text = lineProfile.formattedTotalTicks;
-    }
-
-    if (lineProfile.isHot(self)) {
-      e.classes.add('hotProfile');
-    } else if (lineProfile.isMedium(self)) {
-      e.classes.add('mediumProfile');
-    } else {
-      e.classes.add('coldProfile');
-    }
-
-    return e;
-  }
-
-  Element lineBreakpointElement(ScriptLine line) {
-    var e = new DivElement();
-    if (line == null || !_possibleBreakpointLines.contains(line.line)) {
-      e.classes.add('noCopy');
-      e.classes.add("emptyBreakpoint");
-      e.text = nbsp;
-      return e;
-    }
-
-    e.text = 'B';
-    var busy = false;
-    void update() {
-      e.classes.clear();
-      e.classes.add('noCopy');
-      if (busy) {
-        e.classes.add("busyBreakpoint");
-      } else if (line.breakpoints != null) {
-        bool resolved = false;
-        for (var bpt in line.breakpoints) {
-          if (bpt.resolved) {
-            resolved = true;
-            break;
-          }
-        }
-        if (resolved) {
-          e.classes.add("resolvedBreakpoint");
-        } else {
-          e.classes.add("unresolvedBreakpoint");
-        }
-      } else {
-        e.classes.add("possibleBreakpoint");
-      }
-    }
-
-    line.changes.listen((_) => update());
-    e.onClick.listen((event) {
-      if (busy) {
-        return;
-      }
-      busy = true;
-      if (line.breakpoints == null) {
-        // No breakpoint.  Add it.
-        line.script.isolate.addBreakpoint(line.script, line.line)
-          .catchError((e, st) {
-            if (e is! ServerRpcException ||
-                (e as ServerRpcException).code !=
-                ServerRpcException.kCannotAddBreakpoint) {
-              app.handleException(e, st);
-            }})
-          .whenComplete(() {
-            busy = false;
-            update();
-          });
-      } else {
-        // Existing breakpoint.  Remove it.
-        List pending = [];
-        for (var bpt in line.breakpoints) {
-          pending.add(line.script.isolate.removeBreakpoint(bpt));
-        }
-        Future.wait(pending).then((_) {
-          busy = false;
-          update();
-        });
-      }
-      update();
-    });
-    update();
-    return e;
-  }
-
-  Element lineNumberElement(ScriptLine line, int lineNumPad) {
-    var lineNumber = line == null ? "..." : line.line;
-    var e = span("$nbsp${lineNumber.toString().padLeft(lineNumPad,nbsp)}$nbsp");
-    e.classes.add('noCopy');
-    if (lineNumber == _currentLine) {
-      hitsCurrent(e);
-      return e;
-    }
-    var ranges = _rangeMap[lineNumber];
-    if ((ranges == null) || ranges.isEmpty) {
-      // This line is not code.
-      hitsUnknown(e);
-      return e;
-    }
-    bool compiled = true;
-    bool hasCallInfo = false;
-    bool executed = false;
-    for (var range in ranges) {
-      if (range['compiled']) {
-        for (var callSite in range['callSites']) {
-          var callLine = line.script.tokenToLine(callSite['tokenPos']);
-          if (lineNumber == callLine) {
-            // The call site is on the current line.
-            hasCallInfo = true;
-            for (var cacheEntry in callSite['cacheEntries']) {
-              if (cacheEntry['count'] > 0) {
-                // If any call site on the line has been executed, we
-                // mark the line as executed.
-                executed = true;
-                break;
-              }
-            }
-          }
-        }
-      } else {
-        // If any range isn't compiled, show the line as not compiled.
-        // This is necessary so that nested functions appear to be uncompiled.
-        compiled = false;
-      }
-    }
-    if (executed) {
-      hitsExecuted(e);
-    } else if (hasCallInfo) {
-      hitsNotExecuted(e);
-    } else if (compiled) {
-      hitsCompiled(e);
-    } else {
-      hitsNotCompiled(e);
-    }
-    return e;
-  }
-
-  Element lineSourceElement(ScriptLine line) {
-    var e = new DivElement();
-    e.classes.add("sourceItem");
-
-    if (line != null) {
-      if (line.line == _currentLine) {
-        e.classes.add("currentLine");
-      }
-
-      e.id = makeLineId(line.line);
-
-      var position = 0;
-      consumeUntil(var stop) {
-        if (stop <= position) {
-          return null;  // Empty gap between annotations/boundries.
-        }
-        if (stop > line.text.length) {
-          // Approximated token length can run past the end of the line.
-          stop = line.text.length;
-        }
-
-        var chunk = line.text.substring(position, stop);
-        var chunkNode = span(chunk);
-        e.append(chunkNode);
-        position = stop;
-        return chunkNode;
-      }
-
-      // TODO(rmacnak): Tolerate overlapping annotations.
-      var annotation;
-      while ((annotation = nextAnnotationOnLine(line.line)) != null) {
-        consumeUntil(annotation.columnStart);
-        annotation.applyStyleTo(consumeUntil(annotation.columnStop));
-      }
-      consumeUntil(line.text.length);
-    }
-
-    // So blank lines are included when copying script to the clipboard.
-    e.append(span('\n'));
-
-    return e;
-  }
-
-  ScriptInsetElement.created()
-      : super.created() {
-    _updateTask = new Task(update);
-  }
-}
-
-@CustomTag('refresh-button')
-class RefreshButtonElement extends PolymerElement {
-  RefreshButtonElement.created() : super.created();
-
-  @published var callback = null;
-  bool busy = false;
-
-  Future buttonClick(var event, var b, var c) async {
-    if (busy) {
-      return;
-    }
-    busy = true;
-    if (callback != null) {
-      await callback();
-    }
-    busy = false;
-  }
-}
-
-
-@CustomTag('toggle-button')
-class ToggleButtonElement extends PolymerElement {
-  ToggleButtonElement.created() : super.created();
-
-  @published var callback = null;
-  @observable bool enabled = false;
-
-  Future buttonClick(var event, var b, var c) async {
-    enabled = !enabled;
-    if (callback != null) {
-      await callback(enabled);
-    }
-  }
-}
-
-
-@CustomTag('source-inset')
-class SourceInsetElement extends PolymerElement {
-  SourceInsetElement.created() : super.created();
-
-  @published SourceLocation location;
-  @published String height = null;
-  @published int currentPos;
-  @published bool inDebuggerContext = false;
-  @published ObservableList variables;
-  @published Element scroller;
-}
diff --git a/runtime/observatory/lib/src/elements/script_inset.html b/runtime/observatory/lib/src/elements/script_inset.html
deleted file mode 100644
index c8ea9df..0000000
--- a/runtime/observatory/lib/src/elements/script_inset.html
+++ /dev/null
@@ -1,223 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-
-<polymer-element name="icon-refresh" noscript>
-  <template>
-    <style>
-      svg {
-        fill: currentColor
-      }
-    </style>
-    <svg width="24" height="24">
-      <path d="M17.65 6.35C16.2 4.9 14.21 4 12 4c-4.42 0-7.99 3.58-7.99 8s3.57 8 7.99 8c3.73 0 6.84-2.55 7.73-6h-2.08c-.82 2.33-3.04 4-5.65 4-3.31 0-6-2.69-6-6s2.69-6 6-6c1.66 0 3.14.69 4.22 1.78L13 11h7V4l-2.35 2.35z"/>
-    </svg>
-  </template>
-</polymer-element>
-
-<polymer-element name="icon-whatshot" noscript>
-  <template>
-    <style>
-      svg {
-        fill: currentColor
-      }
-    </style>
-    <svg width="24" height="24">
-      <path d="M13.5.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z"></path>
-    </svg>
-  </template>
-</polymer-element>
-
-<polymer-element name="script-inset">
-  <template>
-    <style>
-      a {
-        color: #0489c3;
-        text-decoration: none;
-      }
-      a:hover {
-        text-decoration: underline;
-      }
-      .sourceInset {
-      }
-      .sourceTable {
-        position: relative;
-        background-color: #f5f5f5;
-        border: 1px solid #ccc;
-        padding: 10px;
-        width: 100%;
-        box-sizing: border-box;
-        overflow-x: scroll;
-      }
-      .sourceRow {
-        display: flex;
-        flex-direction: row;
-        width: 100%;
-      }
-      .sourceItem, .sourceItemCurrent {
-        vertical-align: top;
-        font: 400 14px consolas, courier, monospace;
-        line-height: 125%;
-        white-space: pre;
-        max-width: 0;
-      }
-      .currentLine {
-        background-color: #fff;
-      }
-      .currentCol {
-        background-color: #6cf;
-      }
-      .hitsCurrent, .hitsNone, .hitsNotExecuted, .hitsExecuted, .hitsCompiled, .hitsNotCompiled {
-        display: table-cell;
-        vertical-align: top;
-        font: 400 14px consolas, courier, monospace;
-        margin-left: 5px;
-        margin-right: 5px;
-        text-align: right;
-        color: #a8a8a8;
-      }
-      .hitsCurrent {
-        background-color: #6cf;
-        color: black;
-      }
-      .hitsNotExecuted {
-        background-color: #faa;
-      }
-      .hitsExecuted {
-        background-color: #aea;
-      }
-      .hitsCompiled {
-        background-color: #e0e0e0;
-      }
-      .hitsNotCompiled {
-        background-color: #f0c5c5;
-      }
-
-      .noCopy {}
-      .emptyBreakpoint, .possibleBreakpoint, .busyBreakpoint, .unresolvedBreakpoint, .resolvedBreakpoint  {
-        display: table-cell;
-        vertical-align: top;
-        font: 400 14px consolas, courier, monospace;
-        width: 1em;
-        text-align: center;
-        cursor: pointer;
-      }
-      .possibleBreakpoint {
-        color: #e0e0e0;
-      }
-      .possibleBreakpoint:hover {
-        color: white;
-        background-color: #777;
-      }
-      .busyBreakpoint {
-        color: white;
-        background-color: black;
-        cursor: wait;
-      }
-      .unresolvedBreakpoint {
-        color: white;
-        background-color: #cac;
-      }
-      .resolvedBreakpoint {
-        color: white;
-        background-color: #e66;
-      }
-      .unresolvedBreakAnnotation {
-        color: white;
-        background-color: #cac;
-      }
-      .resolvedBreakAnnotation {
-        color: white;
-        background-color: #e66;
-      }
-      .notSourceProfile, .noProfile, .coldProfile, .mediumProfile, .hotProfile {
-        display: table-cell;
-        vertical-align: top;
-        font: 400 14px consolas, courier, monospace;
-        width: 4em;
-        text-align: right;
-        cursor: pointer;
-        margin-left: 5px;
-        margin-right: 5px;
-      }
-      .notSourceProfile {
-      }
-      .noProfile {
-        background-color: #e0e0e0;
-      }
-      .coldProfile {
-        background-color: #aea;
-      }
-      .mediumProfile {
-        background-color: #fe9;
-      }
-      .hotProfile {
-        background-color: #faa;
-      }
-    </style>
-  </template>
-</polymer-element>
-
-<polymer-element name="refresh-button">
-  <template>
-    <style>
-      .refreshButton {
-        color: rgba(0,0,0,.3);
-      }
-      .refreshButton:hover {
-        color: black;
-      }
-      .refreshButtonDisabled {
-        color: white;
-        cursor: wait;
-      }
-    </style>
-    <template if="{{ callback != null }}">
-      <template if="{{ busy }}">
-        <icon-refresh id="refreshIcon" class="refreshButtonDisabled">
-        </icon-refresh>
-      </template>
-      <template if="{{ !busy }}">
-        <a on-click="{{ buttonClick }}">
-          <icon-refresh id="refreshIcon" class="refreshButton"></icon-refresh>
-        </a>
-      </template>
-    </template>
-  </template>
-</polymer-element>
-
-<polymer-element name="toggle-button">
-  <template>
-    <style>
-    </style>
-    <template if="{{ callback != null }}">
-      <template if="{{ enabled }}">
-        <a on-click="{{ buttonClick }}">
-          <content></content>
-        </a>
-      </template>
-      <template if="{{ !enabled }}">
-        <a on-click="{{ buttonClick }}">
-          <content></content>
-        </a>
-      </template>
-    </template>
-  </template>
-</polymer-element>
-
-<polymer-element name="source-inset">
-<template>
-  <template if="{{ location != null }}">
-    <script-inset script="{{ location.script }}"
-                  startPos="{{ location.tokenPos }}"
-                  scroller="{{ scroller }}"
-                  endPos="{{ location.endTokenPos }}"
-                  height="{{ height }}"
-                  currentPos="{{ currentPos }}"
-                  inDebuggerContext="{{ inDebuggerContext }}"
-                  variables="{{ variables }}">
-    </script-inset>
-  </template>
-</template>
-</polymer-element>
-
-<script type="application/dart" src="script_inset.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/script_inset_wrapper.dart b/runtime/observatory/lib/src/elements/script_inset_wrapper.dart
new file mode 100644
index 0000000..d3bcb68
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/script_inset_wrapper.dart
@@ -0,0 +1,265 @@
+// 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:html';
+import 'dart:async';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/service_html.dart' show Script;
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class ScriptInsetElementWrapper extends HtmlElement {
+  static const binder = const Binder<ScriptInsetElementWrapper>(const {
+      'script': #script, 'startpos': #startPos, 'endpos': #endPos,
+      'currentpos': #currentPos, 'indebuggercontext': #inDebuggerContext,
+      'variables': #variables, 'height': #height
+    });
+
+  static const tag = const Tag<ScriptInsetElementWrapper>('script-inset');
+
+  Script _script;
+  int _startPos;
+  int _endPos;
+  int _currentPos;
+  String _height;
+  bool _inDebuggerContext;
+  Iterable _variables;
+
+  Script get script => _script;
+  int get startPos => _startPos;
+  int get endPos => _endPos;
+  int get currentPos => _currentPos;
+  String get height => _height;
+  bool get inDebuggerContext => _inDebuggerContext;
+  Iterable get variables => _variables;
+
+  set script(Script value) {
+    _script = value;
+    render();
+  }
+  set startPos(int value) {
+    _startPos = value;
+    render();
+  }
+  set endPos(int value) {
+    _endPos = value;
+    render();
+  }
+  set currentPos(int value) {
+    _currentPos = value;
+    render();
+  }
+  set height(String value) {
+    _height = value;
+    render();
+  }
+  set inDebuggerContext(bool value) {
+    _inDebuggerContext = value;
+    render();
+  }
+  set variables(Iterable value) {
+    _variables = value;
+    render();
+  }
+
+  ScriptInsetElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  Future render() async {
+    shadowRoot.children = [];
+    if (_script == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        script-inset-wrapped {
+          position: relative;
+        }
+        script-inset-wrapped button.refresh,
+        script-inset-wrapped button.toggle-profile {
+          background-color: transparent;
+          padding: 0;
+          margin: 0;
+          border: none;
+          position: absolute;
+          display: inline-block;
+          top: 5px;
+          color: #888888;
+          line-height: 30px;
+        }
+        script-inset-wrapped button.refresh {
+          right: 5px;
+          font-size: 25px;
+        }
+        script-inset-wrapped button.toggle-profile {
+          right: 30px;
+          font-size: 20px;
+        }
+        script-inset-wrapped button.toggle-profile.enabled {
+          color: #BB3322;
+        }
+        script-inset-wrapped a {
+          color: #0489c3;
+          text-decoration: none;
+        }
+        script-inset-wrapped a:hover {
+          text-decoration: underline;
+        }
+        script-inset-wrapped .sourceInset {
+        }
+        script-inset-wrapped .sourceTable {
+          position: relative;
+          background-color: #f5f5f5;
+          border: 1px solid #ccc;
+          padding: 10px;
+          width: 100%;
+          box-sizing: border-box;
+          overflow-x: scroll;
+        }
+        script-inset-wrapped .sourceRow {
+          display: flex;
+          flex-direction: row;
+          width: 100%;
+        }
+        script-inset-wrapped .sourceItem,
+        script-inset-wrapped .sourceItemCurrent {
+          vertical-align: top;
+          font: 400 14px consolas, courier, monospace;
+          line-height: 125%;
+          white-space: pre;
+          max-width: 0;
+        }
+        script-inset-wrapped .currentLine {
+          background-color: #fff;
+        }
+        script-inset-wrapped .currentCol {
+          background-color: #6cf;
+        }
+        script-inset-wrapped .hitsCurrent,
+        script-inset-wrapped .hitsNone,
+        script-inset-wrapped .hitsNotExecuted,
+        script-inset-wrapped .hitsExecuted,
+        script-inset-wrapped .hitsCompiled,
+        script-inset-wrapped .hitsNotCompiled {
+          display: table-cell;
+          vertical-align: top;
+          font: 400 14px consolas, courier, monospace;
+          margin-left: 5px;
+          margin-right: 5px;
+          text-align: right;
+          color: #a8a8a8;
+        }
+        script-inset-wrapped .hitsCurrent {
+          background-color: #6cf;
+          color: black;
+        }
+        script-inset-wrapped .hitsNotExecuted {
+          background-color: #faa;
+        }
+        script-inset-wrapped .hitsExecuted {
+          background-color: #aea;
+        }
+        script-inset-wrapped .hitsCompiled {
+          background-color: #e0e0e0;
+        }
+        script-inset-wrapped .hitsNotCompiled {
+          background-color: #f0c5c5;
+        }
+        script-inset-wrapped .noCopy {}
+        script-inset-wrapped .emptyBreakpoint,
+        script-inset-wrapped .possibleBreakpoint,
+        script-inset-wrapped .busyBreakpoint,
+        script-inset-wrapped .unresolvedBreakpoint,
+        script-inset-wrapped .resolvedBreakpoint  {
+          display: table-cell;
+          vertical-align: top;
+          font: 400 14px consolas, courier, monospace;
+          width: 1em;
+          text-align: center;
+          cursor: pointer;
+        }
+        script-inset-wrapped .possibleBreakpoint {
+          color: #e0e0e0;
+        }
+        script-inset-wrapped .possibleBreakpoint:hover {
+          color: white;
+          background-color: #777;
+        }
+        script-inset-wrapped .busyBreakpoint {
+          color: white;
+          background-color: black;
+          cursor: wait;
+        }
+        script-inset-wrapped .unresolvedBreakpoint {
+          color: white;
+          background-color: #cac;
+        }
+        script-inset-wrapped .resolvedBreakpoint {
+          color: white;
+          background-color: #e66;
+        }
+        script-inset-wrapped .unresolvedBreakAnnotation {
+          color: white;
+          background-color: #cac;
+        }
+        script-inset-wrapped .resolvedBreakAnnotation {
+          color: white;
+          background-color: #e66;
+        }
+        script-inset-wrapped .notSourceProfile,
+        script-inset-wrapped .noProfile,
+        script-inset-wrapped .coldProfile,
+        script-inset-wrapped .mediumProfile,
+        script-inset-wrapped .hotProfile {
+          display: table-cell;
+          vertical-align: top;
+          font: 400 14px consolas, courier, monospace;
+          width: 4em;
+          text-align: right;
+          cursor: pointer;
+          margin-left: 5px;
+          margin-right: 5px;
+        }
+        script-inset-wrapped .notSourceProfile {
+        }
+        script-inset-wrapped .noProfile {
+          background-color: #e0e0e0;
+        }
+        script-inset-wrapped .coldProfile {
+          background-color: #aea;
+        }
+        script-inset-wrapped .mediumProfile {
+          background-color: #fe9;
+        }
+        script-inset-wrapped .hotProfile {
+          background-color: #faa;
+        }''',
+      new ScriptInsetElement(_script.isolate, _script,
+                             new ScriptRepository(),
+                             new InstanceRepository(),
+                             ObservatoryApplication.app.events,
+                             startPos: _startPos,
+                             endPos: _endPos,
+                             currentPos: _currentPos,
+                             inDebuggerContext: _inDebuggerContext ?? false,
+                             variables: _variables ?? const [],
+                             queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/script_view.dart b/runtime/observatory/lib/src/elements/script_view.dart
index c896b8d..fd763f4 100644
--- a/runtime/observatory/lib/src/elements/script_view.dart
+++ b/runtime/observatory/lib/src/elements/script_view.dart
@@ -2,22 +2,163 @@
 // 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 script_view_element;
+library script_view;
 
 import 'dart:async';
-import 'observatory_element.dart';
-import 'package:observatory/elements.dart';
-import 'package:observatory/service.dart';
-import 'package:polymer/polymer.dart';
+import 'dart:html';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/context_ref.dart';
+import 'package:observatory/src/elements/curly_block.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/nav/bar.dart';
+import 'package:observatory/src/elements/nav/isolate_menu.dart';
+import 'package:observatory/src/elements/nav/library_menu.dart';
+import 'package:observatory/src/elements/nav/menu.dart';
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/nav/top_menu.dart';
+import 'package:observatory/src/elements/nav/vm_menu.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/view_footer.dart';
 
-/// Displays an Script response.
-@CustomTag('script-view')
-class ScriptViewElement extends ObservatoryElement {
-  @published Script script;
+class ScriptViewElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<ScriptViewElement>('script-view',
+                                                  dependencies: const [
+                                                    ContextRefElement.tag,
+                                                    CurlyBlockElement.tag,
+                                                    NavBarElement.tag,
+                                                    NavTopMenuElement.tag,
+                                                    NavVMMenuElement.tag,
+                                                    NavIsolateMenuElement.tag,
+                                                    NavLibraryMenuElement.tag,
+                                                    NavMenuElement.tag,
+                                                    NavRefreshElement.tag,
+                                                    NavNotifyElement.tag,
+                                                    ObjectCommonElement.tag,
+                                                    ScriptInsetElement.tag,
+                                                    ViewFooterElement.tag
+                                                  ]);
+
+  RenderingScheduler<ScriptViewElement> _r;
+
+  Stream<RenderedEvent<ScriptViewElement>> get onRendered =>
+      _r.onRendered;
+
+  M.VM _vm;
+  M.IsolateRef _isolate;
+  M.EventRepository _events;
+  M.NotificationRepository _notifications;
+  M.Script _script;
+  M.ScriptRepository _scripts;
+  M.RetainedSizeRepository _retainedSizes;
+  M.ReachableSizeRepository _reachableSizes;
+  M.InboundReferencesRepository _references;
+  M.RetainingPathRepository _retainingPaths;
+  M.InstanceRepository _instances;
+  int _pos;
+
+
+  M.VMRef get vm => _vm;
+  M.IsolateRef get isolate => _isolate;
+  M.NotificationRepository get notifications => _notifications;
+  M.Script get script => _script;
+
+  factory ScriptViewElement(M.VM vm, M.IsolateRef isolate,
+                                      M.Script script,
+                                      M.EventRepository events,
+                                      M.NotificationRepository notifications,
+                                      M.ScriptRepository scripts,
+                                      M.RetainedSizeRepository retainedSizes,
+                                      M.ReachableSizeRepository reachableSizes,
+                                      M.InboundReferencesRepository references,
+                                      M.RetainingPathRepository retainingPaths,
+                                      M.InstanceRepository instances,
+                                      {int pos, RenderingQueue queue}) {
+    assert(vm != null);
+    assert(isolate != null);
+    assert(events != null);
+    assert(notifications != null);
+    assert(script != null);
+    assert(scripts != null);
+    assert(retainedSizes != null);
+    assert(reachableSizes != null);
+    assert(references != null);
+    assert(retainingPaths != null);
+    assert(instances != null);
+    ScriptViewElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._vm = vm;
+    e._isolate = isolate;
+    e._events = events;
+    e._notifications = notifications;
+    e._script = script;
+    e._scripts = scripts;
+    e._retainedSizes = retainedSizes;
+    e._reachableSizes = reachableSizes;
+    e._references = references;
+    e._retainingPaths = retainingPaths;
+    e._instances = instances;
+    e._pos = pos;
+    return e;
+  }
 
   ScriptViewElement.created() : super.created();
 
-  Future refresh() {
-    return script.reload();
+  @override
+  attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  detached() {
+    super.detached();
+    _r.disable(notify: true);
+    children = [];
+  }
+
+  void render() {
+    children = [
+      new NavBarElement(queue: _r.queue)
+        ..children = [
+          new NavTopMenuElement(queue: _r.queue),
+          new NavVMMenuElement(_vm, _events, queue: _r.queue),
+          new NavIsolateMenuElement(_isolate, _events, queue: _r.queue),
+          new NavLibraryMenuElement(_isolate, _script.library, queue: _r.queue),
+          new NavMenuElement('object', last: true, queue: _r.queue),
+          new NavRefreshElement(queue: _r.queue)
+              ..onRefresh.listen((e) async {
+                e.element.disabled = true;
+                _script = await _scripts.get(_isolate, _script.id);
+                _r.dirty();
+              }),
+          new NavNotifyElement(_notifications, queue: _r.queue)
+        ],
+      new DivElement()..classes = const ['content-centered-big']
+        ..children = [
+          new HeadingElement.h2()..text = 'Script',
+          new HRElement(),
+          new ObjectCommonElement(_isolate, _script, _retainedSizes,
+                                  _reachableSizes, _references, _retainingPaths,
+                                  _instances, queue: _r.queue),
+          new BRElement(),
+          new DivElement()..classes = ['memberList']
+            ..children = [
+              new DivElement()..classes = ['memberItem']
+                ..children = [
+                  new DivElement()..classes = ['memberName']
+                    ..text = 'load time',
+                  new DivElement()..classes = ['memberName']
+                    ..text = '${_script.loadTime}'
+                ],
+            ],
+          new HRElement(),
+          new ScriptInsetElement(_isolate, _script, _scripts, _instances,
+                                 _events, currentPos: _pos, queue: _r.queue),
+          new ViewFooterElement(queue: _r.queue)
+        ]
+    ];
   }
 }
diff --git a/runtime/observatory/lib/src/elements/script_view.html b/runtime/observatory/lib/src/elements/script_view.html
deleted file mode 100644
index b732128..0000000
--- a/runtime/observatory/lib/src/elements/script_view.html
+++ /dev/null
@@ -1,39 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="script_inset.html">
-
-<polymer-element name="script-view">
-<template>
-  <link rel="stylesheet" href="css/shared.css">
-  <nav-bar>
-    <top-nav-menu></top-nav-menu>
-    <vm-nav-menu vm="{{ script.isolate.vm }}"></vm-nav-menu>
-    <isolate-nav-menu isolate="{{ script.isolate }}"></isolate-nav-menu>
-    <library-nav-menu library="{{ script.library }}"></library-nav-menu>
-    <nav-menu link="{{ makeLink('/inspect', script) }}" anchor="{{ script.name }}" last="{{ true }}"></nav-menu>
-    <nav-refresh callback="{{ refresh }}"></nav-refresh>
-    <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-  </nav-bar>
-
-  <div class="content-centered-big">
-    <h1>script {{ script.name }}</h1>
-    <object-common object="{{ script }}"></object-common>
-    <br>
-
-    <div class="memberList">
-      <div class="memberItem">
-        <div class="memberName">loaded at</div>
-        <div class="memberValue">{{ script.loadTime.toString() }}</div>
-      </div>
-    </div>
-
-    <hr>
-    <script-inset id="scriptInset" script="{{ script }}"
-                  currentPos="{{ app.locationManager.internalArguments['pos'] | parseInt }}">
-    </script-inset>
-  </div>
-
-  <view-footer></view-footer>
-</template>
-</polymer-element>
-
-<script type="application/dart" src="script_view.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/service_view.dart b/runtime/observatory/lib/src/elements/service_view.dart
index 6bf3808..6cd9a3e 100644
--- a/runtime/observatory/lib/src/elements/service_view.dart
+++ b/runtime/observatory/lib/src/elements/service_view.dart
@@ -30,34 +30,9 @@
         CodeViewElement element = new Element.tag('code-view');
         element.code = object;
         return element;
-      case 'Error':
-        ErrorViewElement element = new Element.tag('error-view');
-        element.error = object;
-        return element;
-      case 'Field':
-        FieldViewElement element = new Element.tag('field-view');
-        element.field = object;
-        return element;
-      case 'Function':
-        FunctionViewElement element = new Element.tag('function-view');
-        element.function = object;
-        return element;
-      case 'HeapMap':
-        HeapMapElement element = new Element.tag('heap-map');
-        element.fragmentation = object;
-        return element;
       case 'Object':
         return (object) {
           switch (object.vmType) {
-            case 'MegamorphicCache':
-              MegamorphicCacheViewElement element =
-                  new Element.tag('megamorphiccache-view');
-              element.megamorphicCache = object;
-              return element;
-            case 'ObjectPool':
-              ObjectPoolViewElement element = new Element.tag('objectpool-view');
-              element.pool = object;
-              return element;
             default:
               ObjectViewElement element = new Element.tag('object-view');
               element.object = object;
@@ -72,10 +47,6 @@
         LibraryViewElement element = new Element.tag('library-view');
         element.library = object;
         return element;
-      case 'Script':
-        ScriptViewElement element = new Element.tag('script-view');
-        element.script = object;
-        return element;
       case 'VM':
         VMViewElement element = new Element.tag('vm-view');
         element.vm = object;
diff --git a/runtime/observatory/lib/src/elements/service_view.html b/runtime/observatory/lib/src/elements/service_view.html
index 6bd7e63..8b9b559 100644
--- a/runtime/observatory/lib/src/elements/service_view.html
+++ b/runtime/observatory/lib/src/elements/service_view.html
@@ -1,13 +1,8 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
 <link rel="import" href="class_view.html">
 <link rel="import" href="code_view.html">
-<link rel="import" href="error_view.html">
-<link rel="import" href="field_view.html">
-<link rel="import" href="function_view.html">
-<link rel="import" href="heap_map.html">
 <link rel="import" href="instance_view.html">
 <link rel="import" href="library_view.html">
-<link rel="import" href="script_view.html">
 <link rel="import" href="vm_view.html">
 <polymer-element name="service-view">
   <!-- This element explicitly manages the child elements to avoid setting
diff --git a/runtime/observatory/lib/src/elements/source_inset.dart b/runtime/observatory/lib/src/elements/source_inset.dart
new file mode 100644
index 0000000..b62376a
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/source_inset.dart
@@ -0,0 +1,89 @@
+// 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 source_inset_element;
+
+import 'dart:html';
+import 'dart:async';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/rendering_scheduler.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/script_inset.dart';
+
+class SourceInsetElement extends HtmlElement implements Renderable {
+  static const tag = const Tag<SourceInsetElement>('source-inset-wrapped');
+
+  RenderingScheduler _r;
+
+  Stream<RenderedEvent<SourceInsetElement>> get onRendered => _r.onRendered;
+
+
+  M.IsolateRef _isolate;
+  M.SourceLocation _location;
+  M.ScriptRepository _scripts;
+  M.InstanceRepository _instances;
+  M.EventRepository _events;
+  int _currentPos;
+  bool _inDebuggerContext;
+  Iterable _variables;
+
+  M.IsolateRef get isolate => _isolate;
+  M.SourceLocation get location => _location;
+
+  factory SourceInsetElement(M.IsolateRef isolate, M.SourceLocation location,
+                           M.ScriptRepository scripts,
+                           M.InstanceRepository instances,
+                           M.EventRepository events,
+                           {int currentPos,
+                           bool inDebuggerContext: false,
+                           Iterable variables: const [],
+                           RenderingQueue queue}) {
+    assert(isolate != null);
+    assert(location != null);
+    assert(scripts != null);
+    assert(instances != null);
+    assert(events != null);
+    assert(inDebuggerContext != null);
+    assert(variables != null);
+    SourceInsetElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._isolate = isolate;
+    e._location = location;
+    e._scripts = scripts;
+    e._instances = instances;
+    e._events = events;
+    e._currentPos = currentPos;
+    e._inDebuggerContext = inDebuggerContext;
+    e._variables = variables;
+    return e;
+  }
+
+  SourceInsetElement.created() : super.created();
+
+  @override
+  void attached() {
+    super.attached();
+    _r.enable();
+  }
+
+  @override
+  void detached() {
+    super.detached();
+    children = [];
+    _r.disable(notify: true);
+  }
+
+  void render() {
+    children = [
+      new ScriptInsetElement(_isolate, _location.script,
+                             _scripts, _instances, _events,
+                             startPos: _location.tokenPos,
+                             endPos: _location.endTokenPos,
+                             currentPos: _currentPos,
+                             inDebuggerContext: _inDebuggerContext,
+                             variables: _variables,
+                             queue: _r.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/source_inset_wrapper.dart b/runtime/observatory/lib/src/elements/source_inset_wrapper.dart
new file mode 100644
index 0000000..49292d6
--- /dev/null
+++ b/runtime/observatory/lib/src/elements/source_inset_wrapper.dart
@@ -0,0 +1,246 @@
+// 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:html';
+import 'dart:async';
+
+import 'package:observatory/app.dart';
+import 'package:observatory/repositories.dart';
+import 'package:observatory/service_html.dart' show SourceLocation;
+import 'package:observatory/src/elements/script_inset.dart';
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/shims/binding.dart';
+
+@bindable
+class SourceInsetElementWrapper extends HtmlElement {
+  static const binder = const Binder<SourceInsetElementWrapper>(const {
+      'location': #location, 'currentpos': #currentPos,
+      'indebuggercontext': #inDebuggerContext, 'variables': #variables
+    });
+
+  static const tag = const Tag<SourceInsetElementWrapper>('source-inset');
+
+  SourceLocation _location;
+  int _currentPos;
+  bool _inDebuggerContext;
+  Iterable _variables;
+
+  SourceLocation get location => _location;
+  int get currentPos => _currentPos;
+  bool get inDebuggerContext => _inDebuggerContext;
+  Iterable get variables => _variables;
+
+  set location(SourceLocation value) {
+    _location = value;
+    render();
+  }
+  set currentPos(int value) {
+    _currentPos = value;
+    render();
+  }
+  set inDebuggerContext(bool value) {
+    _inDebuggerContext = value;
+    render();
+  }
+  set variables(Iterable value) {
+    _variables = value;
+    render();
+  }
+
+  SourceInsetElementWrapper.created() : super.created() {
+    binder.registerCallback(this);
+    createShadowRoot();
+    render();
+  }
+
+  @override
+  void attached() {
+    super.attached();
+    render();
+  }
+
+  Future render() async {
+    shadowRoot.children = [];
+    if (_location == null) {
+      return;
+    }
+
+    shadowRoot.children = [
+      new StyleElement()
+        ..text = '''
+        script-inset-wrapped {
+          position: relative;
+        }
+        script-inset-wrapped button.refresh,
+        script-inset-wrapped button.toggle-profile {
+          background-color: transparent;
+          padding: 0;
+          margin: 0;
+          border: none;
+          position: absolute;
+          display: inline-block;
+          top: 5px;
+          color: #888888;
+          line-height: 30px;
+        }
+        script-inset-wrapped button.refresh {
+          right: 5px;
+          font-size: 25px;
+        }
+        script-inset-wrapped button.toggle-profile {
+          right: 30px;
+          font-size: 20px;
+        }
+        script-inset-wrapped button.toggle-profile.enabled {
+          color: #BB3322;
+        }
+        script-inset-wrapped a {
+          color: #0489c3;
+          text-decoration: none;
+        }
+        script-inset-wrapped a:hover {
+          text-decoration: underline;
+        }
+        script-inset-wrapped .sourceInset {
+        }
+        script-inset-wrapped .sourceTable {
+          position: relative;
+          background-color: #f5f5f5;
+          border: 1px solid #ccc;
+          padding: 10px;
+          width: 100%;
+          box-sizing: border-box;
+          overflow-x: scroll;
+        }
+        script-inset-wrapped .sourceRow {
+          display: flex;
+          flex-direction: row;
+          width: 100%;
+        }
+        script-inset-wrapped .sourceItem,
+        script-inset-wrapped .sourceItemCurrent {
+          vertical-align: top;
+          font: 400 14px consolas, courier, monospace;
+          line-height: 125%;
+          white-space: pre;
+          max-width: 0;
+        }
+        script-inset-wrapped .currentLine {
+          background-color: #fff;
+        }
+        script-inset-wrapped .currentCol {
+          background-color: #6cf;
+        }
+        script-inset-wrapped .hitsCurrent,
+        script-inset-wrapped .hitsNone,
+        script-inset-wrapped .hitsNotExecuted,
+        script-inset-wrapped .hitsExecuted,
+        script-inset-wrapped .hitsCompiled,
+        script-inset-wrapped .hitsNotCompiled {
+          display: table-cell;
+          vertical-align: top;
+          font: 400 14px consolas, courier, monospace;
+          margin-left: 5px;
+          margin-right: 5px;
+          text-align: right;
+          color: #a8a8a8;
+        }
+        script-inset-wrapped .hitsCurrent {
+          background-color: #6cf;
+          color: black;
+        }
+        script-inset-wrapped .hitsNotExecuted {
+          background-color: #faa;
+        }
+        script-inset-wrapped .hitsExecuted {
+          background-color: #aea;
+        }
+        script-inset-wrapped .hitsCompiled {
+          background-color: #e0e0e0;
+        }
+        script-inset-wrapped .hitsNotCompiled {
+          background-color: #f0c5c5;
+        }
+        script-inset-wrapped .noCopy {}
+        script-inset-wrapped .emptyBreakpoint,
+        script-inset-wrapped .possibleBreakpoint,
+        script-inset-wrapped .busyBreakpoint,
+        script-inset-wrapped .unresolvedBreakpoint,
+        script-inset-wrapped .resolvedBreakpoint  {
+          display: table-cell;
+          vertical-align: top;
+          font: 400 14px consolas, courier, monospace;
+          width: 1em;
+          text-align: center;
+          cursor: pointer;
+        }
+        script-inset-wrapped .possibleBreakpoint {
+          color: #e0e0e0;
+        }
+        script-inset-wrapped .possibleBreakpoint:hover {
+          color: white;
+          background-color: #777;
+        }
+        script-inset-wrapped .busyBreakpoint {
+          color: white;
+          background-color: black;
+          cursor: wait;
+        }
+        script-inset-wrapped .unresolvedBreakpoint {
+          color: white;
+          background-color: #cac;
+        }
+        script-inset-wrapped .resolvedBreakpoint {
+          color: white;
+          background-color: #e66;
+        }
+        script-inset-wrapped .unresolvedBreakAnnotation {
+          color: white;
+          background-color: #cac;
+        }
+        script-inset-wrapped .resolvedBreakAnnotation {
+          color: white;
+          background-color: #e66;
+        }
+        script-inset-wrapped .notSourceProfile,
+        script-inset-wrapped .noProfile,
+        script-inset-wrapped .coldProfile,
+        script-inset-wrapped .mediumProfile,
+        script-inset-wrapped .hotProfile {
+          display: table-cell;
+          vertical-align: top;
+          font: 400 14px consolas, courier, monospace;
+          width: 4em;
+          text-align: right;
+          cursor: pointer;
+          margin-left: 5px;
+          margin-right: 5px;
+        }
+        script-inset-wrapped .notSourceProfile {
+        }
+        script-inset-wrapped .noProfile {
+          background-color: #e0e0e0;
+        }
+        script-inset-wrapped .coldProfile {
+          background-color: #aea;
+        }
+        script-inset-wrapped .mediumProfile {
+          background-color: #fe9;
+        }
+        script-inset-wrapped .hotProfile {
+          background-color: #faa;
+        }''',
+      new ScriptInsetElement(_location.script.isolate, _location.script,
+                             new ScriptRepository(),
+                             new InstanceRepository(),
+                             ObservatoryApplication.app.events,
+                             startPos: _location.tokenPos,
+                             endPos: _location.endTokenPos,
+                             currentPos: _currentPos,
+                             inDebuggerContext: _inDebuggerContext ?? false,
+                             variables: _variables ?? const [],
+                             queue: ObservatoryApplication.app.queue)
+    ];
+  }
+}
diff --git a/runtime/observatory/lib/src/elements/source_link.dart b/runtime/observatory/lib/src/elements/source_link.dart
index 110b8e1..ca65709 100644
--- a/runtime/observatory/lib/src/elements/source_link.dart
+++ b/runtime/observatory/lib/src/elements/source_link.dart
@@ -44,7 +44,7 @@
   @override
   void attached() {
     super.attached();
-    _repository.get(_location.script.id).then((script) {
+    _repository.get(_isolate, _location.script.id).then((script) {
       _script = script;
       _r.dirty();
     });
diff --git a/runtime/observatory/lib/src/elements/source_link_wrapper.dart b/runtime/observatory/lib/src/elements/source_link_wrapper.dart
index 20221ea..199f949 100644
--- a/runtime/observatory/lib/src/elements/source_link_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/source_link_wrapper.dart
@@ -45,8 +45,6 @@
       return;
     }
 
-    ScriptRepository repository = new ScriptRepository(_location.isolate);
-
     shadowRoot.children = [
       new StyleElement()
         ..text = '''
@@ -57,7 +55,8 @@
             color: #0489c3;
             text-decoration: none;
         }''',
-      new SourceLinkElement(_location.isolate, _location, repository,
+      new SourceLinkElement(_location.isolate, _location,
+                            new ScriptRepository(),
                             queue: ObservatoryApplication.app.queue)
     ];
   }
diff --git a/runtime/observatory/lib/src/elements/vm_view.html b/runtime/observatory/lib/src/elements/vm_view.html
index 1a5481b..84738a2 100644
--- a/runtime/observatory/lib/src/elements/vm_view.html
+++ b/runtime/observatory/lib/src/elements/vm_view.html
@@ -1,5 +1,4 @@
 <link rel="import" href="../../../../packages/polymer/polymer.html">
-<link rel="import" href="eval_box.html">
 <link rel="import" href="isolate_summary.html">
 
 <polymer-element name="vm-view">
diff --git a/runtime/observatory/lib/src/models/objects/breakpoint.dart b/runtime/observatory/lib/src/models/objects/breakpoint.dart
index daf1277..de9e65a 100644
--- a/runtime/observatory/lib/src/models/objects/breakpoint.dart
+++ b/runtime/observatory/lib/src/models/objects/breakpoint.dart
@@ -7,7 +7,12 @@
 abstract class Breakpoint extends Object {
   /// A number identifying this breakpoint to the user.
   int get number;
-
   /// Has this breakpoint been assigned to a specific program location?
   bool get resolved;
+  /// [optional]Is this a breakpoint that was added synthetically as part of a
+  /// step OverAsyncSuspension resume command?
+  bool get isSyntheticAsyncContinuation;
+  /// SourceLocation when breakpoint is resolved, UnresolvedSourceLocation
+  /// when a breakpoint is not resolved.
+  Location get location;
 }
diff --git a/runtime/observatory/lib/src/models/objects/error.dart b/runtime/observatory/lib/src/models/objects/error.dart
index 8b36aed..06c6e61 100644
--- a/runtime/observatory/lib/src/models/objects/error.dart
+++ b/runtime/observatory/lib/src/models/objects/error.dart
@@ -17,7 +17,6 @@
 }
 
 abstract class ErrorRef extends ObjectRef {
-  String get id;
   ErrorKind get kind;
   String get message;
 }
diff --git a/runtime/observatory/lib/src/models/objects/field.dart b/runtime/observatory/lib/src/models/objects/field.dart
index 152c920..188f223 100644
--- a/runtime/observatory/lib/src/models/objects/field.dart
+++ b/runtime/observatory/lib/src/models/objects/field.dart
@@ -27,3 +27,21 @@
   /// Is this field static?
   bool get isStatic;
 }
+
+enum GuardClassKind {
+  unknown,
+  single,
+  dynamic
+}
+
+abstract class Field extends Object implements FieldRef {
+  /// [optional] The value of this field, if the field is static.
+  InstanceRef get staticValue;
+
+  /// [optional] The location of this field in the source code.
+  SourceLocation get location;
+
+  GuardClassKind get guardClassKind;
+  ClassRef get guardClass;
+  bool get guardNullable;
+}
diff --git a/runtime/observatory/lib/src/models/objects/function.dart b/runtime/observatory/lib/src/models/objects/function.dart
index 933954f..f73f0db 100644
--- a/runtime/observatory/lib/src/models/objects/function.dart
+++ b/runtime/observatory/lib/src/models/objects/function.dart
@@ -82,4 +82,17 @@
 
   /// The compiled code associated with this function. [optional]
   CodeRef get code;
+  /// [optional]
+  CodeRef get unoptimizedCode;
+  /// [optional]
+  FieldRef get field;
+  int get usageCounter;
+  InstanceRef get icDataArray;
+  int get deoptimizations;
+  bool get isOptimizable;
+  bool get isInlinable;
+  bool get hasIntrinsic;
+  bool get isRecognized;
+  bool get isNative;
+  String get vmName;
 }
diff --git a/runtime/observatory/lib/src/models/objects/library.dart b/runtime/observatory/lib/src/models/objects/library.dart
index 281242a..602231c 100644
--- a/runtime/observatory/lib/src/models/objects/library.dart
+++ b/runtime/observatory/lib/src/models/objects/library.dart
@@ -14,7 +14,7 @@
 
 abstract class Library extends Object implements LibraryRef {
   /// Is this library debuggable? Default true.
-  bool get debuggable;
+  //bool get debuggable;
 
   /// A list of the imports for this library.
   //LibraryDependency[] dependencies;
diff --git a/runtime/observatory/lib/src/models/objects/megamorphiccache.dart b/runtime/observatory/lib/src/models/objects/megamorphiccache.dart
index a87fb48..74657de 100644
--- a/runtime/observatory/lib/src/models/objects/megamorphiccache.dart
+++ b/runtime/observatory/lib/src/models/objects/megamorphiccache.dart
@@ -7,3 +7,10 @@
 abstract class MegamorphicCacheRef extends ObjectRef {
   String get selector;
 }
+
+abstract class MegamorphicCache extends Object implements MegamorphicCacheRef {
+  String get selector;
+  int get mask;
+  InstanceRef get buckets;
+  InstanceRef get argumentsDescriptor;
+}
diff --git a/runtime/observatory/lib/src/models/objects/objectpool.dart b/runtime/observatory/lib/src/models/objects/objectpool.dart
index c9be553..1f0b738 100644
--- a/runtime/observatory/lib/src/models/objects/objectpool.dart
+++ b/runtime/observatory/lib/src/models/objects/objectpool.dart
@@ -7,3 +7,20 @@
 abstract class ObjectPoolRef extends ObjectRef {
   int get length;
 }
+
+abstract class ObjectPool extends Object implements ObjectPoolRef {
+  Iterable<ObjectPoolEntry> get entries;
+}
+
+enum ObjectPoolEntryKind {
+  object,
+  immediate,
+  nativeEntry
+}
+
+abstract class ObjectPoolEntry {
+  int get offset;
+  ObjectPoolEntryKind get kind;
+  ObjectRef get asObject;
+  int get asInteger;
+}
diff --git a/runtime/observatory/lib/src/models/objects/objectstore.dart b/runtime/observatory/lib/src/models/objects/objectstore.dart
new file mode 100644
index 0000000..694f858
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/objectstore.dart
@@ -0,0 +1,14 @@
+// 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.
+
+part of models;
+
+abstract class ObjectStore {
+  Iterable<NamedField> get fields;
+}
+
+abstract class NamedField {
+  String get name;
+  ObjectRef get value;
+}
diff --git a/runtime/observatory/lib/src/models/objects/persistent_handles.dart b/runtime/observatory/lib/src/models/objects/persistent_handles.dart
new file mode 100644
index 0000000..ff81ff2
--- /dev/null
+++ b/runtime/observatory/lib/src/models/objects/persistent_handles.dart
@@ -0,0 +1,21 @@
+// 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.
+
+part of models;
+
+abstract class PersistentHandles {
+  Iterable<PersistentHandle> get elements;
+  Iterable<WeakPersistentHandle> get weakElements;
+}
+
+abstract class PersistentHandle {
+  ObjectRef get object;
+}
+
+abstract class WeakPersistentHandle implements PersistentHandle {
+  int get externalSize;
+  String get peer;
+  String get callbackSymbolName;
+  String get callbackAddress;
+}
diff --git a/runtime/observatory/lib/src/models/objects/script.dart b/runtime/observatory/lib/src/models/objects/script.dart
index 3736651..df4b63b 100644
--- a/runtime/observatory/lib/src/models/objects/script.dart
+++ b/runtime/observatory/lib/src/models/objects/script.dart
@@ -11,12 +11,18 @@
 
 abstract class Script extends Object implements ScriptRef {
   /// The library which owns this script.
-  // LibraryRef get library;
+  LibraryRef get library;
 
   /// The source code for this script. For certain built-in scripts,
   /// this may be reconstructed without source comments.
   String get source;
 
+  DateTime get loadTime;
+  int get firstTokenPos;
+  int get lastTokenPos;
+  int get lineOffset;
+  int get columnOffset;
+
   int tokenToLine(int token);
   int tokenToCol(int token);
 }
diff --git a/runtime/observatory/lib/src/models/objects/source_location.dart b/runtime/observatory/lib/src/models/objects/source_location.dart
index dd9f663..5fc8b6c 100644
--- a/runtime/observatory/lib/src/models/objects/source_location.dart
+++ b/runtime/observatory/lib/src/models/objects/source_location.dart
@@ -4,11 +4,28 @@
 
 part of models;
 
-abstract class SourceLocation {
+abstract class Location {
   /// The script containing the source location.
   ScriptRef get script;
-  /// The first token of the location.
+  /// The last token of the location if this is a range. [optional]
+  int get tokenPos;
+}
+
+abstract class SourceLocation implements Location {
+  /// The last token of the location if this is a range.
   int get tokenPos;
   /// The last token of the location if this is a range. [optional]
   int get endTokenPos;
 }
+
+abstract class UnresolvedSourceLocation implements Location {
+  // [optional] The uri of the script containing the source location if the
+  // script has yet to be loaded.
+  String get scriptUri;
+  /// [optional] An approximate line number for the source location. This may
+  /// change when the location is resolved.
+  int get line;
+  /// [optional] An approximate column number for the source location. This may
+  /// change when the location is resolved.
+  int get column;
+}
diff --git a/runtime/observatory/lib/src/models/repositories/class.dart b/runtime/observatory/lib/src/models/repositories/class.dart
index 388256e..6394377 100644
--- a/runtime/observatory/lib/src/models/repositories/class.dart
+++ b/runtime/observatory/lib/src/models/repositories/class.dart
@@ -5,6 +5,6 @@
 part of models;
 
 abstract class ClassRepository{
-  Future<Class> getObject();
-  Future<Class> get(String id);
+  Future<Class> getObject(IsolateRef isolate);
+  Future<Class> get(IsolateRef isolate, String id);
 }
diff --git a/runtime/observatory/lib/src/models/repositories/eval.dart b/runtime/observatory/lib/src/models/repositories/eval.dart
new file mode 100644
index 0000000..af38e4e
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/eval.dart
@@ -0,0 +1,10 @@
+// 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
+
+part of models;
+
+abstract class EvalRepository{
+  Future<ObjectRef> evaluate(IsolateRef isolate, ObjectRef context,
+                             String expression);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/field.dart b/runtime/observatory/lib/src/models/repositories/field.dart
new file mode 100644
index 0000000..8412ac9
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/field.dart
@@ -0,0 +1,9 @@
+// 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
+
+part of models;
+
+abstract class FieldRepository{
+  Future<Field> get(IsolateRef isolate, String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/function.dart b/runtime/observatory/lib/src/models/repositories/function.dart
new file mode 100644
index 0000000..8ae36f3
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/function.dart
@@ -0,0 +1,9 @@
+// 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
+
+part of models;
+
+abstract class FunctionRepository{
+  Future<Function> get(IsolateRef isolate, String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/megamorphiccache.dart b/runtime/observatory/lib/src/models/repositories/megamorphiccache.dart
new file mode 100644
index 0000000..9734e3e
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/megamorphiccache.dart
@@ -0,0 +1,9 @@
+// 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
+
+part of models;
+
+abstract class MegamorphicCacheRepository{
+  Future<MegamorphicCache> get(IsolateRef isolate, String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/objectpool.dart b/runtime/observatory/lib/src/models/repositories/objectpool.dart
new file mode 100644
index 0000000..36f51ba
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/objectpool.dart
@@ -0,0 +1,9 @@
+// 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
+
+part of models;
+
+abstract class ObjectPoolRepository {
+  Future<ObjectPool> get(IsolateRef isolate, String id);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/objectstore.dart b/runtime/observatory/lib/src/models/repositories/objectstore.dart
new file mode 100644
index 0000000..ee1735c
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/objectstore.dart
@@ -0,0 +1,9 @@
+// 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
+
+part of models;
+
+abstract class ObjectStoreRepository {
+  Future<ObjectStore> get(IsolateRef isolate);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/persistent_handles.dart b/runtime/observatory/lib/src/models/repositories/persistent_handles.dart
new file mode 100644
index 0000000..62d6323
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/persistent_handles.dart
@@ -0,0 +1,9 @@
+// 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
+
+part of models;
+
+abstract class PersistentHandlesRepository {
+  Future<PersistentHandles> get(IsolateRef isolate);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/script.dart b/runtime/observatory/lib/src/models/repositories/script.dart
index 3073c2e..3ba2dc3 100644
--- a/runtime/observatory/lib/src/models/repositories/script.dart
+++ b/runtime/observatory/lib/src/models/repositories/script.dart
@@ -5,5 +5,5 @@
 part of models;
 
 abstract class ScriptRepository {
-  Future<Script> get(String id);
+  Future<Script> get(IsolateRef isolate, String id);
 }
diff --git a/runtime/observatory/lib/src/repositories/class.dart b/runtime/observatory/lib/src/repositories/class.dart
index 911c363..4d80729 100644
--- a/runtime/observatory/lib/src/repositories/class.dart
+++ b/runtime/observatory/lib/src/repositories/class.dart
@@ -5,14 +5,14 @@
 part of repositories;
 
 class ClassRepository extends M.ClassRepository {
-  final S.Isolate isolate;
-
-  ClassRepository(this.isolate);
-
-  Future<M.Class> getObject() {
+  Future<M.Class> getObject(M.IsolateRef i) {
+    final isolate = i as S.Isolate;
+    assert(isolate != null);
     return isolate.getClassHierarchy();
   }
-  Future<M.Class> get(String id) async {
+  Future<M.Class> get(M.IsolateRef i, String id) async {
+    final isolate = i as S.Isolate;
+    assert(isolate != null);
     return (await isolate.getObject(id)) as S.Class;
   }
 }
diff --git a/runtime/observatory/lib/src/repositories/context.dart b/runtime/observatory/lib/src/repositories/context.dart
index a088428..5bb12e6 100644
--- a/runtime/observatory/lib/src/repositories/context.dart
+++ b/runtime/observatory/lib/src/repositories/context.dart
@@ -5,8 +5,6 @@
 part of repositories;
 
 class ContextRepository extends M.ContextRepository {
-  ContextRepository();
-
   Future<M.Context> get(M.IsolateRef i, String id) async{
     S.Isolate isolate = i as S.Isolate;
     assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/eval.dart b/runtime/observatory/lib/src/repositories/eval.dart
new file mode 100644
index 0000000..bf423ad
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/eval.dart
@@ -0,0 +1,16 @@
+// 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
+
+part of repositories;
+
+class EvalRepository extends M.EvalRepository {
+  Future<M.ObjectRef> evaluate(M.IsolateRef i, M.ObjectRef o, String e) async {
+    S.Isolate isolate = i as S.Isolate;
+    S.ServiceObject object = o as S.HeapObject;
+    assert(isolate != null);
+    assert(object != null);
+    assert(e != null);
+    return (await isolate.eval(object, e)) as M.ObjectRef;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/field.dart b/runtime/observatory/lib/src/repositories/field.dart
new file mode 100644
index 0000000..fce37d0
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/field.dart
@@ -0,0 +1,13 @@
+// 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
+
+part of repositories;
+
+class FieldRepository extends M.FieldRepository {
+  Future<M.Field> get(M.IsolateRef i, String id) async{
+    S.Isolate isolate = i as S.Isolate;
+    assert(isolate != null);
+    return (await isolate.getObject(id)) as S.Field;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/function.dart b/runtime/observatory/lib/src/repositories/function.dart
new file mode 100644
index 0000000..2ab1682
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/function.dart
@@ -0,0 +1,13 @@
+// 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
+
+part of repositories;
+
+class FunctionRepository extends M.FunctionRepository {
+  Future<M.Function> get(M.IsolateRef i, String id) async{
+    S.Isolate isolate = i as S.Isolate;
+    assert(isolate != null);
+    return (await isolate.getObject(id)) as S.ServiceFunction;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/icdata.dart b/runtime/observatory/lib/src/repositories/icdata.dart
index 18ce814..cf6165d 100644
--- a/runtime/observatory/lib/src/repositories/icdata.dart
+++ b/runtime/observatory/lib/src/repositories/icdata.dart
@@ -5,8 +5,6 @@
 part of repositories;
 
 class ICDataRepository extends M.ICDataRepository {
-  ICDataRepository();
-
   Future<M.ICData> get(M.IsolateRef i, String id) async{
     S.Isolate isolate = i as S.Isolate;
     assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/instance.dart b/runtime/observatory/lib/src/repositories/instance.dart
index 8f2b756..ad365d6 100644
--- a/runtime/observatory/lib/src/repositories/instance.dart
+++ b/runtime/observatory/lib/src/repositories/instance.dart
@@ -5,8 +5,6 @@
 part of repositories;
 
 class InstanceRepository extends M.InstanceRepository {
-  InstanceRepository();
-
   Future<M.Instance> get(M.IsolateRef i, String id,
                          {int count: S.kDefaultFieldLimit}) async{
     S.Isolate isolate = i as S.Isolate;
diff --git a/runtime/observatory/lib/src/repositories/megamorphiccache.dart b/runtime/observatory/lib/src/repositories/megamorphiccache.dart
new file mode 100644
index 0000000..59adbe3
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/megamorphiccache.dart
@@ -0,0 +1,13 @@
+// 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
+
+part of repositories;
+
+class MegamorphicCacheRepository extends M.MegamorphicCacheRepository {
+  Future<M.MegamorphicCache> get(M.IsolateRef i, String id) async{
+    S.Isolate isolate = i as S.Isolate;
+    assert(isolate != null);
+    return (await isolate.getObject(id)) as S.MegamorphicCache;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/objectpool.dart b/runtime/observatory/lib/src/repositories/objectpool.dart
new file mode 100644
index 0000000..b10c9dc
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/objectpool.dart
@@ -0,0 +1,13 @@
+// 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
+
+part of repositories;
+
+class ObjectPoolRepository extends M.ObjectPoolRepository {
+  Future<M.ObjectPool> get(M.IsolateRef i, String id) async{
+    S.Isolate isolate = i as S.Isolate;
+    assert(isolate != null);
+    return (await isolate.getObject(id)) as S.ObjectPool;
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/objectstore.dart b/runtime/observatory/lib/src/repositories/objectstore.dart
new file mode 100644
index 0000000..7456d9a
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/objectstore.dart
@@ -0,0 +1,13 @@
+// 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
+
+part of repositories;
+
+class ObjectStoreRepository implements M.ObjectStoreRepository {
+  Future<M.ObjectStore> get(M.IsolateRef i) async {
+    S.Isolate isolate = i as S.Isolate;
+    assert(isolate != null);
+    return isolate.getObjectStore();
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/persistent_handles.dart b/runtime/observatory/lib/src/repositories/persistent_handles.dart
new file mode 100644
index 0000000..db94cbc
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/persistent_handles.dart
@@ -0,0 +1,14 @@
+// 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
+
+part of repositories;
+
+class PersistentHandlesRepository implements M.PersistentHandlesRepository {
+  Future<M.PersistentHandles> get(M.IsolateRef i) async {
+    S.Isolate isolate = i as S.Isolate;
+    assert(isolate != null);
+    final response = await isolate.invokeRpc('_getPersistentHandles', {});
+    return new S.PersistentHandles(response);
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/reachable_size.dart b/runtime/observatory/lib/src/repositories/reachable_size.dart
index 945cd9f..e670942 100644
--- a/runtime/observatory/lib/src/repositories/reachable_size.dart
+++ b/runtime/observatory/lib/src/repositories/reachable_size.dart
@@ -5,7 +5,6 @@
 part of repositories;
 
 class ReachableSizeRepository implements M.ReachableSizeRepository {
-
   Future<M.Guarded<M.Instance>> get(M.IsolateRef i, String id) async {
     S.Isolate isolate = i as S.Isolate;
     assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/retained_size.dart b/runtime/observatory/lib/src/repositories/retained_size.dart
index b81da34..3869254 100644
--- a/runtime/observatory/lib/src/repositories/retained_size.dart
+++ b/runtime/observatory/lib/src/repositories/retained_size.dart
@@ -5,7 +5,6 @@
 part of repositories;
 
 class RetainedSizeRepository implements M.RetainedSizeRepository {
-
   Future<M.Guarded<M.Instance>> get(M.IsolateRef i, String id) async {
     S.Isolate isolate = i as S.Isolate;
     assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/retaining_path.dart b/runtime/observatory/lib/src/repositories/retaining_path.dart
index c658f91..1ff9835 100644
--- a/runtime/observatory/lib/src/repositories/retaining_path.dart
+++ b/runtime/observatory/lib/src/repositories/retaining_path.dart
@@ -5,7 +5,6 @@
 part of repositories;
 
 class RetainingPathRepository implements M.RetainingPathRepository {
-
   Future<M.RetainingPath> get(M.IsolateRef i, String id) async {
     S.Isolate isolate = i as S.Isolate;
     assert(isolate != null);
diff --git a/runtime/observatory/lib/src/repositories/script.dart b/runtime/observatory/lib/src/repositories/script.dart
index 918de35..e0fea2d 100644
--- a/runtime/observatory/lib/src/repositories/script.dart
+++ b/runtime/observatory/lib/src/repositories/script.dart
@@ -5,11 +5,10 @@
 part of repositories;
 
 class ScriptRepository implements M.ScriptRepository {
-  final S.Isolate isolate;
-
-  ScriptRepository(this.isolate);
-
-  Future<M.Script> get(String id) async {
+  Future<M.Script> get(M.IsolateRef i, String id) async {
+    S.Isolate isolate = i as S.Isolate;
+    assert(i != null);
+    assert(id != null);
     return (await isolate.getObject(id)) as M.Script;
   }
 }
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index 0ebf02e..0d67dde 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -418,7 +418,7 @@
   ServiceObject getFromMap(ObservableMap map);
 }
 
-abstract class Location  {
+abstract class Location implements M.Location {
   Script get script;
   int get tokenPos;
 }
@@ -469,7 +469,9 @@
 
 /// An [UnresolvedSourceLocation] represents a location in the source
 // code which has not been precisely mapped to a token position.
-class UnresolvedSourceLocation extends ServiceObject implements Location {
+class UnresolvedSourceLocation extends ServiceObject
+                               implements Location,
+                                          M.UnresolvedSourceLocation {
   Script script;
   String scriptUri;
   int line;
@@ -1137,6 +1139,39 @@
       handler = map['handler'];
 }
 
+class PersistentHandles implements M.PersistentHandles {
+  final Iterable<PersistentHandle> elements;
+  final Iterable<WeakPersistentHandle> weakElements;
+
+  PersistentHandles(ServiceMap map)
+    : this.elements = map['persistentHandles']
+        .map((rmap) => new PersistentHandle(rmap)),
+      this.weakElements = map['weakPersistentHandles']
+          .map((rmap) => new WeakPersistentHandle(rmap));
+}
+
+class PersistentHandle implements M.PersistentHandle {
+  final HeapObject object;
+
+  PersistentHandle(ServiceMap map)
+    : object = map['object'];
+}
+
+class WeakPersistentHandle implements M.WeakPersistentHandle {
+  final int externalSize;
+  final String peer;
+  final String callbackSymbolName;
+  final String callbackAddress;
+  final HeapObject object;
+
+  WeakPersistentHandle(ServiceMap map)
+    : externalSize = int.parse(map['externalSize']),
+      peer = map['peer'],
+      callbackSymbolName = map['callbackSymbolName'],
+      callbackAddress = map['callbackAddress'],
+      object = map['object'];
+}
+
 class HeapSpace extends Observable implements M.HeapSpace {
   @observable int used = 0;
   @observable int capacity = 0;
@@ -1710,7 +1745,7 @@
     });
   }
 
-  Future<ServiceObject> _eval(ServiceObject target,
+  Future<ServiceObject> eval(ServiceObject target,
                               String expression) {
     Map params = {
       'targetId': target.id,
@@ -1819,14 +1854,14 @@
 }
 
 
-class NamedField {
+class NamedField implements M.NamedField {
   final String name;
-  final ServiceObject value;
+  final M.ObjectRef value;
   NamedField(this.name, this.value);
 }
 
 
-class ObjectStore extends ServiceObject {
+class ObjectStore extends ServiceObject implements M.ObjectStore {
   @observable List<NamedField> fields = new List<NamedField>();
 
   ObjectStore._empty(ServiceObjectOwner owner) : super._empty(owner);
@@ -2209,7 +2244,7 @@
 }
 
 
-class Library extends HeapObject implements M.LibraryRef {
+class Library extends HeapObject implements M.Library {
   @observable String uri;
   @reflectable final dependencies = new ObservableList<LibraryDependency>();
   @reflectable final scripts = new ObservableList<Script>();
@@ -2261,7 +2296,7 @@
   }
 
   Future<ServiceObject> evaluate(String expression) {
-    return isolate._eval(this, expression);
+    return isolate.eval(this, expression);
   }
 
   Script get rootScript {
@@ -2429,7 +2464,7 @@
   }
 
   Future<ServiceObject> evaluate(String expression) {
-    return isolate._eval(this, expression);
+    return isolate.eval(this, expression);
   }
 
   Future<ServiceObject> setTraceAllocations(bool enable) {
@@ -2753,7 +2788,7 @@
   }
 
   Future<ServiceObject> evaluate(String expression) {
-    return isolate._eval(this, expression);
+    return isolate.eval(this, expression);
   }
 
   String toString() => 'Instance($shortName)';
@@ -2944,7 +2979,7 @@
   String toString() => 'Sentinel($kind)';
 }
 
-class Field extends HeapObject implements M.FieldRef {
+class Field extends HeapObject implements M.Field {
   // Library or Class.
   @observable HeapObject dartOwner;
   @observable Library library;
@@ -2957,7 +2992,8 @@
   @observable String vmName;
 
   @observable bool guardNullable;
-  @observable var /* Class | String */ guardClass;
+  M.GuardClassKind guardClassKind;
+  @observable Class guardClass;
   @observable String guardLength;
   @observable SourceLocation location;
 
@@ -2990,7 +3026,21 @@
     }
 
     guardNullable = map['_guardNullable'];
-    guardClass = map['_guardClass'];
+    if (map['_guardClass'] is Class) {
+        guardClass = map['_guardClass'];
+        guardClassKind = M.GuardClassKind.single;
+    } else {
+      switch (map['_guardClass']) {
+        case 'various':
+          guardClassKind = M.GuardClassKind.dynamic;
+          break;
+        case 'unknown':
+        default:
+          guardClassKind = M.GuardClassKind.unknown;
+          break;
+      }
+    }
+
     guardLength = map['_guardLength'];
     location = map['location'];
     _loaded = true;
@@ -3574,11 +3624,11 @@
   }
 }
 
-class ObjectPool extends HeapObject implements M.ObjectPoolRef {
+class ObjectPool extends HeapObject implements M.ObjectPool {
   bool get immutable => false;
 
   @observable int length;
-  @observable List entries;
+  @observable List<ObjectPoolEntry> entries;
 
   ObjectPool._empty(ServiceObjectOwner owner) : super._empty(owner);
 
@@ -3590,10 +3640,47 @@
     if (mapIsRef) {
       return;
     }
-    entries = map['_entries'];
+    entries = map['_entries'].map((map) => new ObjectPoolEntry(map));
   }
 }
 
+class ObjectPoolEntry implements M.ObjectPoolEntry {
+  final int offset;
+  final M.ObjectPoolEntryKind kind;
+  final M.ObjectRef asObject;
+  final int asInteger;
+
+  factory ObjectPoolEntry(map) {
+    M.ObjectPoolEntryKind kind = stringToObjectPoolEntryKind(map['kind']);
+    int offset = map['offset'];
+    switch (kind) {
+      case M.ObjectPoolEntryKind.object:
+        return new ObjectPoolEntry._fromObject(map['value'], offset);
+      default:
+        return new ObjectPoolEntry._fromInteger(kind, map['value'], offset);
+    }
+  }
+
+  ObjectPoolEntry._fromObject(this.asObject, this.offset)
+    : kind = M.ObjectPoolEntryKind.object,
+      asInteger = null;
+
+  ObjectPoolEntry._fromInteger(this.kind, this.asInteger, this.offset)
+    : asObject = null;
+}
+
+M.ObjectPoolEntryKind stringToObjectPoolEntryKind(String kind) {
+  switch (kind) {
+    case 'Object':
+      return M.ObjectPoolEntryKind.object;
+    case 'Immediate':
+      return M.ObjectPoolEntryKind.immediate;
+    case 'NativeEntry':
+      return M.ObjectPoolEntryKind.nativeEntry;
+  }
+  throw new Exception('Unknown ObjectPoolEntryKind ($kind)');
+}
+
 class ICData extends HeapObject implements M.ICData {
   @observable HeapObject dartOwner;
   @observable String selector;
@@ -3618,7 +3705,7 @@
   }
 }
 
-class MegamorphicCache extends HeapObject implements M.MegamorphicCacheRef {
+class MegamorphicCache extends HeapObject implements M.MegamorphicCache {
   @observable int mask;
   @observable Instance buckets;
   @observable String selector;
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 89113b9..982025a 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -63,23 +63,19 @@
     'lib/src/elements/error_ref.dart',
     'lib/src/elements/error_ref_wrapper.dart',
     'lib/src/elements/error_view.dart',
-    'lib/src/elements/error_view.html',
     'lib/src/elements/eval_box.dart',
-    'lib/src/elements/eval_box.html',
+    'lib/src/elements/eval_box_wrapper.dart',
     'lib/src/elements/eval_link.dart',
     'lib/src/elements/eval_link.html',
     'lib/src/elements/field_ref.dart',
     'lib/src/elements/field_ref_wrapper.dart',
     'lib/src/elements/field_view.dart',
-    'lib/src/elements/field_view.html',
     'lib/src/elements/flag_list.dart',
     'lib/src/elements/function_ref.dart',
     'lib/src/elements/function_ref_wrapper.dart',
     'lib/src/elements/function_view.dart',
-    'lib/src/elements/function_view.html',
     'lib/src/elements/general_error.dart',
     'lib/src/elements/heap_map.dart',
-    'lib/src/elements/heap_map.html',
     'lib/src/elements/heap_snapshot.dart',
     'lib/src/elements/helpers/any_ref.dart',
     'lib/src/elements/helpers/rendering_queue.dart',
@@ -119,7 +115,6 @@
     'lib/src/elements/logging.html',
     'lib/src/elements/megamorphiccache_ref.dart',
     'lib/src/elements/megamorphiccache_view.dart',
-    'lib/src/elements/megamorphiccache_view.html',
     'lib/src/elements/metrics.dart',
     'lib/src/elements/metrics.html',
     'lib/src/elements/nav/bar.dart',
@@ -149,29 +144,27 @@
     'lib/src/elements/object_view.html',
     'lib/src/elements/objectpool_ref.dart',
     'lib/src/elements/objectpool_view.dart',
-    'lib/src/elements/objectpool_view.html',
     'lib/src/elements/objectstore_view.dart',
-    'lib/src/elements/objectstore_view.html',
     'lib/src/elements/observatory_application.dart',
     'lib/src/elements/observatory_element.dart',
     'lib/src/elements/pc_descriptors_ref.dart',
     'lib/src/elements/persistent_handles.dart',
-    'lib/src/elements/persistent_handles.html',
     'lib/src/elements/ports.dart',
     'lib/src/elements/retaining_path.dart',
     'lib/src/elements/sample_buffer_control.dart',
     'lib/src/elements/script_inset.dart',
-    'lib/src/elements/script_inset.html',
+    'lib/src/elements/script_inset_wrapper.dart',
     'lib/src/elements/script_ref.dart',
     'lib/src/elements/script_ref_wrapper.dart',
     'lib/src/elements/script_view.dart',
-    'lib/src/elements/script_view.html',
     'lib/src/elements/sentinel_value.dart',
     'lib/src/elements/service_ref.dart',
     'lib/src/elements/service_ref.html',
     'lib/src/elements/service_view.dart',
     'lib/src/elements/service_view.html',
     'lib/src/elements/shims/binding.dart',
+    'lib/src/elements/source_inset.dart',
+    'lib/src/elements/source_inset_wrapper.dart',
     'lib/src/elements/source_link.dart',
     'lib/src/elements/source_link_wrapper.dart',
     'lib/src/elements/stack_trace_tree_config.dart',
@@ -213,7 +206,9 @@
     'lib/src/models/objects/notification.dart',
     'lib/src/models/objects/object.dart',
     'lib/src/models/objects/objectpool.dart',
+    'lib/src/models/objects/objectstore.dart',
     'lib/src/models/objects/pc_descriptors.dart',
+    'lib/src/models/objects/persistent_handles.dart',
     'lib/src/models/objects/ports.dart',
     'lib/src/models/objects/retaining_path.dart',
     'lib/src/models/objects/sample_profile.dart',
@@ -228,13 +223,20 @@
     'lib/src/models/repositories/allocation_profile.dart',
     'lib/src/models/repositories/class.dart',
     'lib/src/models/repositories/context.dart',
+    'lib/src/models/repositories/eval.dart',
     'lib/src/models/repositories/event.dart',
+    'lib/src/models/repositories/field.dart',
     'lib/src/models/repositories/flag.dart',
+    'lib/src/models/repositories/function.dart',
     'lib/src/models/repositories/heap_snapshot.dart',
     'lib/src/models/repositories/icdata.dart',
     'lib/src/models/repositories/inbound_references.dart',
     'lib/src/models/repositories/instance.dart',
+    'lib/src/models/repositories/megamorphiccache.dart',
     'lib/src/models/repositories/notification.dart',
+    'lib/src/models/repositories/objectpool.dart',
+    'lib/src/models/repositories/objectstore.dart',
+    'lib/src/models/repositories/persistent_handles.dart',
     'lib/src/models/repositories/ports.dart',
     'lib/src/models/repositories/reachable_size.dart',
     'lib/src/models/repositories/retained_size.dart',
@@ -245,13 +247,20 @@
     'lib/src/repositories/allocation_profile.dart',
     'lib/src/repositories/class.dart',
     'lib/src/repositories/context.dart',
+    'lib/src/repositories/eval.dart',
     'lib/src/repositories/event.dart',
+    'lib/src/repositories/field.dart',
     'lib/src/repositories/flag.dart',
+    'lib/src/repositories/function.dart',
     'lib/src/repositories/heap_snapshot.dart',
     'lib/src/repositories/icdata.dart',
     'lib/src/repositories/inbound_references.dart',
     'lib/src/repositories/instance.dart',
+    'lib/src/repositories/megamorphiccache.dart',
     'lib/src/repositories/notification.dart',
+    'lib/src/repositories/objectpool.dart',
+    'lib/src/repositories/objectstore.dart',
+    'lib/src/repositories/persistent_handles.dart',
     'lib/src/repositories/ports.dart',
     'lib/src/repositories/reachable_size.dart',
     'lib/src/repositories/retained_size.dart',
diff --git a/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart b/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
index 5d20331..f8c9785 100644
--- a/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
+++ b/runtime/observatory/tests/observatory_ui/class_tree/element_test.dart
@@ -39,11 +39,13 @@
       bool rendered = false;
       final e = new ClassTreeElement(vm, isolate, events, notifications,
           new ClassRepositoryMock(
-              object: expectAsync(() async {
+              object: expectAsync((i) async {
+                expect(i, equals(isolate));
                 expect(rendered, isFalse);
                 return object;
               }, count: 1),
-              getter: expectAsync((id) async {
+              getter: expectAsync((i, id) async {
+                expect(i, equals(isolate));
                 expect(ids.contains(id), isTrue);
                 switch (id) {
                   case child1_id: return child1;
diff --git a/runtime/observatory/tests/observatory_ui/error_view/element_test.dart b/runtime/observatory/tests/observatory_ui/error_view/element_test.dart
new file mode 100644
index 0000000..7d30a03
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/error_view/element_test.dart
@@ -0,0 +1,29 @@
+// 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/error_view.dart';
+import '../mocks.dart';
+
+main() {
+  ErrorViewElement.tag.ensureRegistration();
+
+  final notifs = new NotificationRepositoryMock();
+  final error = const ErrorMock();
+  test('instantiation', () {
+    final e = new ErrorViewElement(notifs, error);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.error, equals(error));
+  });
+  test('elements created after attachment', () async {
+    final e = new ErrorViewElement(notifs, error);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/error_view/element_test.html b/runtime/observatory/tests/observatory_ui/error_view/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/error_view/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart
new file mode 100644
index 0000000..06f3d65
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.dart
@@ -0,0 +1,60 @@
+// 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/megamorphiccache_view.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import '../mocks.dart';
+
+main() {
+  MegamorphicCacheViewElement.tag.ensureRegistration();
+
+  final cTag = ObjectCommonElement.tag.name;
+  final rTag = NavRefreshElement.tag.name;
+
+  const vm = const VMMock();
+  const isolate = const IsolateRefMock();
+  final events = new EventRepositoryMock();
+  final notifs = new NotificationRepositoryMock();
+  final cache = const MegamorphicCacheMock();
+  final caches = new MegamorphicCacheRepositoryMock();
+  final reachableSizes = new ReachableSizeRepositoryMock();
+  final retainedSizes = new RetainedSizeRepositoryMock();
+  final inbounds = new InboundReferencesRepositoryMock();
+  final paths = new RetainingPathRepositoryMock();
+  final instances = new InstanceRepositoryMock();
+  test('instantiation', () {
+    final e = new MegamorphicCacheViewElement(vm, isolate, cache, events,
+                                              notifs, caches, retainedSizes,
+                                              reachableSizes, inbounds, paths,
+                                              instances);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.cache, equals(cache));
+  });
+  test('elements created after attachment', () async {
+    final caches = new MegamorphicCacheRepositoryMock(
+      getter: expectAsync((i, id) async {
+        expect(i, equals(isolate));
+        expect(id, equals(cache.id));
+        return cache;
+      }, count: 1)
+    );
+    final e = new MegamorphicCacheViewElement(vm, isolate, cache, events,
+                                              notifs, caches, retainedSizes,
+                                              reachableSizes, inbounds, paths,
+                                              instances);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.querySelectorAll(cTag).length, equals(1));
+    (e.querySelector(rTag) as NavRefreshElement).refresh();
+    await e.onRendered.first;
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/megamorphiccache_view/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/mocks.dart b/runtime/observatory/tests/observatory_ui/mocks.dart
index 28bc264..f7f2b82 100644
--- a/runtime/observatory/tests/observatory_ui/mocks.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks.dart
@@ -31,7 +31,9 @@
 part 'mocks/objects/megamorphiccache.dart';
 part 'mocks/objects/notification.dart';
 part 'mocks/objects/objectpool.dart';
+part 'mocks/objects/objectstore.dart';
 part 'mocks/objects/pc_descriptors.dart';
+part 'mocks/objects/persistent_handles.dart';
 part 'mocks/objects/ports.dart';
 part 'mocks/objects/retaining_path.dart';
 part 'mocks/objects/sample_profile.dart';
@@ -52,8 +54,12 @@
 part 'mocks/repositories/icdata.dart';
 part 'mocks/repositories/inbound_references.dart';
 part 'mocks/repositories/instance.dart';
+part 'mocks/repositories/megamorphiccache.dart';
 part 'mocks/repositories/notification.dart';
+part 'mocks/repositories/objectpool.dart';
+part 'mocks/repositories/objectstore.dart';
 part 'mocks/repositories/ports.dart';
+part 'mocks/repositories/persistent_handles.dart';
 part 'mocks/repositories/reachable_size.dart';
 part 'mocks/repositories/retained_size.dart';
 part 'mocks/repositories/retaining_path.dart';
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
index 1a87016..f3a4798 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/error.dart
@@ -8,7 +8,10 @@
   final String id;
   final M.ErrorKind kind;
   final String message;
-  const ErrorRefMock({this.id, this.kind, this.message});
+
+  const ErrorRefMock({this.id: 'error-ref',
+                      this.kind: M.ErrorKind.internalError,
+                      this.message: 'Error Message'});
 }
 
 class ErrorMock implements M.Error {
@@ -17,5 +20,8 @@
   final int size;
   final M.ErrorKind kind;
   final String message;
-  const ErrorMock({this.id, this.clazz, this.size, this.kind, this.message});
+
+  const ErrorMock({this.id: 'error-id', this.clazz: const ClassMock(),
+                   this.size: 0, this.kind: M.ErrorKind.internalError,
+                   this.message: 'Error Message'});
 }
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
index 85eae71..d017211 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/function.dart
@@ -27,7 +27,22 @@
   final M.FunctionKind kind;
   final M.SourceLocation location;
   final M.CodeRef code;
+  final M.CodeRef unoptimizedCode;
+  final M.FieldRef field;
+  final int usageCounter;
+  final M.InstanceRef icDataArray;
+  final int deoptimizations;
+  final bool isOptimizable;
+  final bool isInlinable;
+  final bool hasIntrinsic;
+  final bool isRecognized;
+  final bool isNative;
+  final String vmName;
   const FunctionMock({this.id, this.name, this.clazz, this.size, this.dartOwner,
       this.isStatic : false, this.isConst : false, this.kind, this.location,
-      this.code});
+      this.code, this.unoptimizedCode, this.field, this.usageCounter: 0,
+      this.icDataArray: const InstanceRefMock(), this.deoptimizations: 0,
+      this.isOptimizable: false, this.isInlinable: false,
+      this.hasIntrinsic: false, this.isRecognized: false, this.isNative: false,
+      this.vmName: 'function-vm-name',});
 }
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
index 6e58941..07da7f1 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/megamorphiccache.dart
@@ -9,5 +9,20 @@
   final String selector;
 
   const MegamorphicCacheRefMock({this.id : 'megamorphiccache-id',
-                                 this.selector});
+                                 this.selector: 'selector'});
+}
+
+class MegamorphicCacheMock implements M.MegamorphicCache {
+  final String id;
+  final M.ClassRef clazz;
+  final int size;
+  final String selector;
+  final int mask;
+  final M.InstanceRef buckets;
+  final M.InstanceRef argumentsDescriptor;
+
+  const MegamorphicCacheMock({this.id : 'megamorphiccache-id',
+      this.clazz: const ClassRefMock(), this.size: 1, this.selector: 'selector',
+      this.mask: 0, this.buckets: const InstanceRefMock(),
+      this.argumentsDescriptor: const InstanceRefMock()});
 }
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
index 59932ee..0124fcd 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/objectpool.dart
@@ -10,3 +10,27 @@
 
   const ObjectPoolRefMock({this.id: 'objectpool-id', this.length: 0});
 }
+
+class ObjectPoolMock implements M.ObjectPool {
+  final String id;
+  final M.ClassRef clazz;
+  final int size;
+  final int length;
+  final Iterable<M.ObjectPoolEntry> entries;
+
+  const ObjectPoolMock({this.id: 'objectpool-id',
+                        this.clazz: const ClassRefMock(), this.size: 1,
+                        this.length: 0, this.entries: const []});
+}
+
+class ObjectPoolEntryMock implements M.ObjectPoolEntry {
+  final int offset;
+  final M.ObjectPoolEntryKind kind;
+  final M.ObjectRef asObject;
+  final int asInteger;
+
+  const ObjectPoolEntryMock({this.offset: 0,
+                             this.kind: M.ObjectPoolEntryKind.object,
+                             this.asObject: const InstanceRefMock(),
+                             this.asInteger: null});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart
new file mode 100644
index 0000000..ee1216c
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/objectstore.dart
@@ -0,0 +1,19 @@
+// 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.
+
+part of mocks;
+
+class ObjectStoreMock implements M.ObjectStore {
+  final Iterable<M.NamedField> fields;
+
+  const ObjectStoreMock({this.fields: const []});
+}
+
+class NamedFieldMock implements M.NamedField {
+  final String name;
+  final M.ObjectRef value;
+
+  const NamedFieldMock({this.name: 'field-name',
+                        this.value: const InstanceRefMock()});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart
new file mode 100644
index 0000000..5e65785
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/persistent_handles.dart
@@ -0,0 +1,32 @@
+// 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.
+
+part of mocks;
+
+class PersistentHandlesMock implements M.PersistentHandles {
+  final Iterable<M.PersistentHandle> elements;
+  final Iterable<M.WeakPersistentHandle> weakElements;
+
+  const PersistentHandlesMock({this.elements: const [],
+                               this.weakElements: const []});
+}
+
+class PersistentHandleMock implements M.PersistentHandle {
+  final M.ObjectRef object;
+
+  const PersistentHandleMock({this.object: const InstanceRefMock()});
+}
+
+class WeakPersistentHandleMock implements M.WeakPersistentHandle {
+  final M.ObjectRef object;
+  final int externalSize;
+  final String peer;
+  final String callbackSymbolName;
+  final String callbackAddress;
+
+  const WeakPersistentHandleMock({this.object: const InstanceRefMock(),
+                                  this.externalSize: 0, this.peer: '0x0',
+                                  this.callbackSymbolName: 'dart::Something()',
+                                  this.callbackAddress: '0x123456'});
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart b/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
index c5139bc..86e139f 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/objects/script.dart
@@ -19,15 +19,24 @@
   final int size;
   final String uri;
   final String source;
+  final M.LibraryRef library;
 
   final TokenToInt _tokenToLine;
   final TokenToInt _tokenToCol;
 
+  final DateTime loadTime;
+  final int firstTokenPos;
+  final int lastTokenPos;
+  final int lineOffset;
+  final int columnOffset;
+
   int tokenToLine(int token) => _tokenToLine(token);
   int tokenToCol(int token) => _tokenToCol(token);
 
   const ScriptMock({this.id, this.clazz, this.size, this.uri, this.source,
-      TokenToInt tokenToLine, TokenToInt tokenToCol})
+      this.library: const LibraryRefMock(), TokenToInt tokenToLine,
+      TokenToInt tokenToCol, this.loadTime, this.firstTokenPos,
+      this.lastTokenPos, this.lineOffset, this.columnOffset})
     : _tokenToLine = tokenToLine,
       _tokenToCol = tokenToCol;
 }
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
index 3c5fe7b..debb14c 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/class.dart
@@ -4,8 +4,9 @@
 
 part of mocks;
 
-typedef Future<M.Class> ClassRepositoryMockObjectCallback();
-typedef Future<M.Class> ClassRepositoryMockGetterCallback(String id);
+typedef Future<M.Class> ClassRepositoryMockObjectCallback(M.Isolate isolate);
+typedef Future<M.Class>
+        ClassRepositoryMockGetterCallback(M.Isolate isolate, String id);
 
 class ClassRepositoryMock implements M.ClassRepository {
   final ClassRepositoryMockObjectCallback _object;
@@ -16,16 +17,16 @@
     : _object = object,
       _get = getter;
 
-  Future<M.Class> getObject(){
+  Future<M.Class> getObject(M.IsolateRef i){
     if (_object != null) {
-      return _object();
+      return _object(i);
     }
     return new Future.value(null);
   }
 
-  Future<M.Class> get(String id){
+  Future<M.Class> get(M.IsolateRef i, String id){
     if (_get != null) {
-      return _get(id);
+      return _get(i, id);
     }
     return new Future.value(null);
   }
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.dart
new file mode 100644
index 0000000..340bad3
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/megamorphiccache.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.
+
+part of mocks;
+
+typedef Future<M.MegamorphicCache>
+        MegamorphicCacheRepositoryMockCallback(M.IsolateRef isolate, String id);
+
+class MegamorphicCacheRepositoryMock implements M.MegamorphicCacheRepository {
+  final MegamorphicCacheRepositoryMockCallback _get;
+
+  MegamorphicCacheRepositoryMock(
+    {MegamorphicCacheRepositoryMockCallback getter})
+    : _get = getter;
+
+  Future<M.MegamorphicCache> get(M.IsolateRef isolate, String id, {int count}){
+    if (_get != null) {
+      return _get(isolate, id);
+    }
+    return new Future.value(null);
+  }
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart
new file mode 100644
index 0000000..b3b139c
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectpool.dart
@@ -0,0 +1,22 @@
+// 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
+
+part of mocks;
+
+typedef Future<M.ObjectPool>
+        ObjectPoolRepositoryMockGetter(M.IsolateRef i, String id);
+
+class ObjectPoolRepositoryMock implements M.ObjectPoolRepository {
+  final ObjectPoolRepositoryMockGetter _getter;
+
+  Future<M.ObjectPool> get(M.IsolateRef i, String id) {
+    if (_getter != null) {
+      return _getter(i, id);
+    }
+    return new Future.value(new ObjectPoolMock());
+  }
+
+  ObjectPoolRepositoryMock({ObjectPoolRepositoryMockGetter getter})
+    : _getter = getter;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart
new file mode 100644
index 0000000..02bd9b4
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/objectstore.dart
@@ -0,0 +1,21 @@
+// 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
+
+part of mocks;
+
+typedef Future<M.ObjectStore> ObjectStoreRepositoryMockGetter(M.IsolateRef i);
+
+class ObjectStoreRepositoryMock implements M.ObjectStoreRepository {
+  final ObjectStoreRepositoryMockGetter _getter;
+
+  Future<M.ObjectStore> get(M.IsolateRef i) {
+    if (_getter != null) {
+      return _getter(i);
+    }
+    return new Future.value(new ObjectStoreMock());
+  }
+
+  ObjectStoreRepositoryMock({ObjectStoreRepositoryMockGetter getter})
+    : _getter = getter;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.dart
new file mode 100644
index 0000000..713be46
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/persistent_handles.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
+
+part of mocks;
+
+typedef Future<M.PersistentHandles>
+        PersistentHandlesRepositoryMockGetter(M.IsolateRef i);
+
+class PersistentHandlesRepositoryMock implements M.PersistentHandlesRepository {
+  final PersistentHandlesRepositoryMockGetter _getter;
+
+  Future<M.PersistentHandles> get(M.IsolateRef i) {
+    if (_getter != null) {
+      return _getter(i);
+    }
+    return new Future.value(new PortsMock());
+  }
+
+  PersistentHandlesRepositoryMock(
+      {PersistentHandlesRepositoryMockGetter getter})
+    : _getter = getter;
+}
diff --git a/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart b/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
index 78b9610..cb6d2eb 100644
--- a/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
+++ b/runtime/observatory/tests/observatory_ui/mocks/repositories/script.dart
@@ -4,7 +4,8 @@
 
 part of mocks;
 
-typedef Future<M.Script> ScriptRepositoryMockCallback(String id);
+typedef Future<M.Script>
+    ScriptRepositoryMockCallback(M.IsolateRef isolate, String id);
 
 class ScriptRepositoryMock implements M.ScriptRepository {
   final ScriptRepositoryMockCallback _get;
@@ -12,9 +13,9 @@
   ScriptRepositoryMock({ScriptRepositoryMockCallback getter})
     : _get = getter;
 
-  Future<M.Script> get(String id){
+  Future<M.Script> get(M.IsolateRef isolate, String id){
     if (_get != null) {
-      return _get(id);
+      return _get(isolate, id);
     }
     return new Future.value(null);
   }
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart
new file mode 100644
index 0000000..11f2ee9
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.dart
@@ -0,0 +1,58 @@
+// 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/nav/refresh.dart';
+import 'package:observatory/src/elements/object_common.dart';
+import 'package:observatory/src/elements/objectpool_view.dart';
+import '../mocks.dart';
+
+main() {
+  ObjectPoolViewElement.tag.ensureRegistration();
+
+  final cTag = ObjectCommonElement.tag.name;
+  final rTag = NavRefreshElement.tag.name;
+
+  const vm = const VMMock();
+  const isolate = const IsolateRefMock();
+  final events = new EventRepositoryMock();
+  final notifs = new NotificationRepositoryMock();
+  final pool = const ObjectPoolMock();
+  final pools = new ObjectPoolRepositoryMock();
+  final reachableSizes = new ReachableSizeRepositoryMock();
+  final retainedSizes = new RetainedSizeRepositoryMock();
+  final inbounds = new InboundReferencesRepositoryMock();
+  final paths = new RetainingPathRepositoryMock();
+  final instances = new InstanceRepositoryMock();
+  test('instantiation', () {
+    final e = new ObjectPoolViewElement(vm, isolate, pool, events, notifs,
+                                        pools, retainedSizes, reachableSizes,
+                                        inbounds, paths, instances);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+    expect(e.pool, equals(pool));
+  });
+  test('elements created after attachment', () async {
+    final pools = new ObjectPoolRepositoryMock(
+      getter: expectAsync((i, id) async {
+        expect(i, equals(isolate));
+        expect(id, equals(pool.id));
+        return pool;
+      }, count: 1)
+    );
+    final e = new ObjectPoolViewElement(vm, isolate, pool, events, notifs,
+                                        pools, retainedSizes, reachableSizes,
+                                        inbounds, paths, instances);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.querySelectorAll(cTag).length, equals(1));
+    (e.querySelector(rTag) as NavRefreshElement).refresh();
+    await e.onRendered.first;
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectpool_view/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart
new file mode 100644
index 0000000..1889b49
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.dart
@@ -0,0 +1,47 @@
+// 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/objectstore_view.dart';
+import '../mocks.dart';
+
+main() {
+  ObjectStoreViewElement.tag.ensureRegistration();
+
+  const vm = const VMMock();
+  const isolate = const IsolateRefMock();
+  final events = new EventRepositoryMock();
+  final notifs = new NotificationRepositoryMock();
+  final stores = new ObjectStoreRepositoryMock();
+  final instances = new InstanceRepositoryMock();
+  test('instantiation', () {
+    final e = new ObjectStoreViewElement(vm, isolate, events, notifs, stores, instances);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+  });
+  test('elements created after attachment', () async {
+    const fields = const [
+      const NamedFieldMock(name: 'field-1'),
+      const NamedFieldMock(name: 'field-2'),
+      const NamedFieldMock(name: 'field-3')
+    ];
+    const store = const ObjectStoreMock(fields: fields);
+    final stores = new ObjectStoreRepositoryMock(
+      getter: expectAsync((i) async {
+        expect(i, equals(isolate));
+        return store;
+      }, count: 1)
+    );
+    final instances = new InstanceRepositoryMock();
+    final e = new ObjectStoreViewElement(vm, isolate, events, notifs, stores, instances);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    expect(e.querySelectorAll('.memberItem').length, equals(fields.length));
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/objectstore_view/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/observatory_ui.status b/runtime/observatory/tests/observatory_ui/observatory_ui.status
index e307635..f683fd8 100644
--- a/runtime/observatory/tests/observatory_ui/observatory_ui.status
+++ b/runtime/observatory/tests/observatory_ui/observatory_ui.status
@@ -2,7 +2,7 @@
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
 
-[ $browser == false || $runtime == drt ]
+[ $browser == false || $runtime == drt || $fast_startup]
 *: SkipByDesign
 
 [ $runtime == dartium ]
@@ -12,3 +12,4 @@
 [ $runtime == ff || $runtime == safari ]
 allocation_profile: Skip
 cpu_profile_table: Skip
+persistent_handles_page: Skip
diff --git a/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart
new file mode 100644
index 0000000..f2e4b84
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.dart
@@ -0,0 +1,42 @@
+// 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:html';
+import 'package:unittest/unittest.dart';
+import 'package:observatory/src/elements/persistent_handles.dart';
+import '../mocks.dart';
+
+main() {
+  PersistentHandlesPageElement.tag.ensureRegistration();
+
+  const vm = const VMMock();
+  const isolate = const IsolateRefMock();
+  final events = new EventRepositoryMock();
+  final notifs = new NotificationRepositoryMock();
+  final repository = new PersistentHandlesRepositoryMock();
+  final instances = new InstanceRepositoryMock();
+  test('instantiation', () {
+    final e = new PersistentHandlesPageElement(vm, isolate, events, notifs,
+                                               repository, instances);
+    expect(e, isNotNull, reason: 'element correctly created');
+    expect(e.isolate, equals(isolate));
+  });
+  test('elements created after attachment', () async {
+    final repository = new PersistentHandlesRepositoryMock(
+      getter: expectAsync((i) async {
+        expect(i, equals(isolate));
+        return const PersistentHandlesMock();
+      }, count: 1)
+    );
+    final instances = new InstanceRepositoryMock();
+    final e = new PersistentHandlesPageElement(vm, isolate, events, notifs,
+                                               repository, instances);
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(e.children.length, isNonZero, reason: 'has elements');
+    e.remove();
+    await e.onRendered.first;
+    expect(e.children.length, isZero, reason: 'is empty');
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/persistent_handles_page/element_test.html
@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html>
+<head>
+  <meta http-equiv="X-UA-Compatible" content="IE=edge">
+  <meta name="dart.unittest" content="full-stack-traces">
+  <style>
+     .unittest-table { font-family:monospace; border:1px; }
+     .unittest-pass { background: #6b3;}
+     .unittest-fail { background: #d55;}
+     .unittest-error { background: #a11;}
+  </style>
+  <script src="/packages/web_components/webcomponents.js"></script>
+  <script src="/packages/web_components/dart_support.js"></script>
+</head>
+<body>
+  <script type="text/javascript"
+      src="/root_dart/tools/testing/dart/test_controller.js"></script>
+  %TEST_SCRIPTS%
+</body>
+</html>
diff --git a/runtime/observatory/tests/observatory_ui/source_link/element_test.dart b/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
index bd096b8..38218f3 100644
--- a/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
+++ b/runtime/observatory/tests/observatory_ui/source_link/element_test.dart
@@ -17,21 +17,23 @@
       tokenToLine: (int token) => 1, tokenToCol: (int token) => 2);
   final location = new SourceLocationMock(script: script, tokenPos: 0,
       endTokenPos: 1);
+  final repository = new ScriptRepositoryMock();
   test('instantiation', () {
-    final e = new SourceLinkElement(isolate, location,
-        new ScriptRepositoryMock());
+    final e = new SourceLinkElement(isolate, location, repository);
     expect(e, isNotNull, reason: 'element correctly created');
     expect(e.isolate, equals(isolate));
     expect(e.location, equals(location));
   });
   test('elements created after attachment', () async {
     bool rendered = false;
-    final e = new SourceLinkElement(isolate, location,
-        new ScriptRepositoryMock(getter: expectAsync((String id) async {
-          expect(rendered, isFalse);
-          expect(id, equals(script_id));
-          return script;
-        }, count: 1)));
+    final repository = new ScriptRepositoryMock(
+      getter: expectAsync((isolate, id) async {
+        expect(rendered, isFalse);
+        expect(id, equals(script_id));
+        return script;
+      }, count: 1)
+    );
+    final e = new SourceLinkElement(isolate, location, repository);
     document.body.append(e);
     await e.onRendered.first;
     rendered = true;
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index cf35eca..5f0a1ba 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -16,7 +16,10 @@
       }
     }
   } else {
-    libs = [ "runtime" ]
+    libs = [
+      "magenta",
+      "runtime",
+    ]
   }
 }
 
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index e8d8ae8..6a89478 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -211,6 +211,21 @@
 #endif
 
 
+#if defined(DART_PRECOMPILER)
+void ClassTable::Remap(intptr_t* old_to_new_cid) {
+  intptr_t num_cids = NumCids();
+  RawClass** cls_by_old_cid = new RawClass*[num_cids];
+  for (intptr_t i = 0; i < num_cids; i++) {
+    cls_by_old_cid[i] = table_[i];
+  }
+  for (intptr_t i = 0; i < num_cids; i++) {
+    table_[old_to_new_cid[i]] = cls_by_old_cid[i];
+  }
+  delete[] cls_by_old_cid;
+}
+#endif
+
+
 void ClassTable::VisitObjectPointers(ObjectPointerVisitor* visitor) {
   ASSERT(visitor != NULL);
   visitor->VisitPointers(reinterpret_cast<RawObject**>(&table_[0]), top_);
@@ -219,7 +234,7 @@
 
 void ClassTable::Validate() {
   Class& cls = Class::Handle();
-  for (intptr_t i = kNumPredefinedCids; i < top_; i++) {
+  for (intptr_t cid = kNumPredefinedCids; cid < top_; cid++) {
     // Some of the class table entries maybe NULL as we create some
     // top level classes but do not add them to the list of anonymous
     // classes in a library if there are no top level fields or functions.
@@ -227,9 +242,10 @@
     // not written into a full snapshot and will not be recreated when
     // we read back the full snapshot. These class slots end up with NULL
     // entries.
-    if (HasValidClassAt(i)) {
-      cls = At(i);
+    if (HasValidClassAt(cid)) {
+      cls = At(cid);
       ASSERT(cls.IsClass());
+      ASSERT(cls.id() == cid);
     }
   }
 }
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 1722dec..1ab7da1 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -191,6 +191,10 @@
   void Unregister(intptr_t index);
 #endif
 
+#if defined(DART_PRECOMPILER)
+  void Remap(intptr_t* old_to_new_cids);
+#endif
+
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
   void Validate();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index e64c399..560b600 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -730,7 +730,7 @@
 void FinalizablePersistentHandle::Finalize(
     Isolate* isolate, FinalizablePersistentHandle* handle) {
   if (!handle->raw()->IsHeapObject()) {
-    return;
+    return;  // Free handle.
   }
   Dart_WeakPersistentHandleFinalizer callback = handle->callback();
   ASSERT(callback != NULL);
@@ -1034,6 +1034,9 @@
   REUSABLE_OBJECT_HANDLESCOPE(thread);
   Object& ref = thread->ObjectHandle();
   ref = Api::UnwrapHandle(object);
+  if (!ref.raw()->IsHeapObject()) {
+    return NULL;
+  }
   FinalizablePersistentHandle* finalizable_ref =
       FinalizablePersistentHandle::New(thread->isolate(),
                                        ref,
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index d8a9299..ae0812c 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -1217,11 +1217,11 @@
     Isolate::Current()->heap()->new_space()->Scavenge(invoke_api_callbacks);
   }
 
-  static void WaitForFinalizationTasks() {
+  static void WaitForGCTasks() {
     Thread* thread = Thread::Current();
-    Heap* heap = thread->isolate()->heap();
-    MonitorLocker ml(heap->finalization_tasks_lock());
-    while (heap->finalization_tasks() > 0) {
+    PageSpace* old_space = thread->isolate()->heap()->old_space();
+    MonitorLocker ml(old_space->tasks_lock());
+    while (old_space->tasks() > 0) {
       ml.WaitWithSafepointCheck(thread);
     }
   }
@@ -1264,11 +1264,11 @@
     EXPECT_EQ(40, peer8);
     EXPECT_EQ(41, peer16);
     Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT_EQ(40, peer8);
     EXPECT_EQ(41, peer16);
     Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT_EQ(80, peer8);
     EXPECT_EQ(82, peer16);
   }
@@ -2380,6 +2380,13 @@
 }
 
 
+static void UnreachedCallback(void* isolate_callback_data,
+                              Dart_WeakPersistentHandle handle,
+                              void* peer) {
+  UNREACHABLE();
+}
+
+
 static void ExternalTypedDataFinalizer(void* isolate_callback_data,
                                        Dart_WeakPersistentHandle handle,
                                        void* peer) {
@@ -2405,39 +2412,25 @@
     TransitionNativeToVM transition(thread);
     EXPECT(peer == 0);
     Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT(peer == 0);
     Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT(peer == 42);
   }
 }
 
 
-static Monitor* slow_finalizers_monitor = NULL;
-static intptr_t slow_finalizers_waiting = 0;
-
-
 static void SlowFinalizer(void* isolate_callback_data,
                           Dart_WeakPersistentHandle handle,
                           void* peer) {
-  {
-    MonitorLocker ml(slow_finalizers_monitor);
-    slow_finalizers_waiting++;
-    while (slow_finalizers_waiting < 10) {
-      ml.Wait();
-    }
-    ml.NotifyAll();
-  }
-
+  OS::Sleep(10);
   intptr_t* count = reinterpret_cast<intptr_t*>(peer);
-  AtomicOperations::IncrementBy(count, 1);
+  (*count)++;
 }
 
 
 TEST_CASE(SlowFinalizer) {
-  slow_finalizers_monitor = new Monitor();
-
   intptr_t count = 0;
   for (intptr_t i = 0; i < 10; i++) {
     Dart_EnterScope();
@@ -2455,12 +2448,10 @@
 
   {
     TransitionNativeToVM transition(thread);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
   }
 
   EXPECT_EQ(20, count);
-
-  delete slow_finalizers_monitor;
 }
 
 
@@ -2515,7 +2506,7 @@
   {
     TransitionNativeToVM transition(thread);
     Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT(peer == 42);
   }
 }
@@ -2792,7 +2783,7 @@
     TransitionNativeToVM transition(thread);
     // Garbage collect new space again.
     GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
   }
 
   {
@@ -2808,7 +2799,7 @@
     TransitionNativeToVM transition(thread);
     // Garbage collect old space again.
     Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
   }
 
   {
@@ -2828,6 +2819,27 @@
 }
 
 
+TEST_CASE(WeakPersistentHandleErrors) {
+  Dart_EnterScope();
+
+  // NULL callback.
+  Dart_Handle obj1 = NewString("new string");
+  EXPECT_VALID(obj1);
+  Dart_WeakPersistentHandle ref1 = Dart_NewWeakPersistentHandle(
+      obj1, NULL, 0, NULL);
+  EXPECT_EQ(ref1, static_cast<void*>(NULL));
+
+  // Immediate object.
+  Dart_Handle obj2 = Dart_NewInteger(0);
+  EXPECT_VALID(obj2);
+  Dart_WeakPersistentHandle ref2 = Dart_NewWeakPersistentHandle(
+      obj2, NULL, 0, WeakPersistentHandleCallback);
+  EXPECT_EQ(ref2, static_cast<void*>(NULL));
+
+  Dart_ExitScope();
+}
+
+
 static void WeakPersistentHandlePeerFinalizer(void* isolate_callback_data,
                                               Dart_WeakPersistentHandle handle,
                                               void* peer) {
@@ -2853,7 +2865,7 @@
     Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
     EXPECT(peer == 0);
     GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT(peer == 42);
   }
 }
@@ -2880,7 +2892,7 @@
     Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
     EXPECT(peer == 0);
     GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT(peer == 0);
   }
 }
@@ -2941,7 +2953,7 @@
     // Collect weakly referenced string, and promote strongly referenced string.
     GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
     GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT(heap->ExternalInWords(Heap::kNew) == 0);
     EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize);
   }
@@ -2952,7 +2964,7 @@
   {
     TransitionNativeToVM transition(thread);
     Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
   }
 }
@@ -2998,7 +3010,7 @@
   {
     TransitionNativeToVM transition(thread);
     Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
     EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
   }
 }
@@ -3045,17 +3057,18 @@
   static const intptr_t kWeak1ExternalSize = 1 * KB;
   Dart_WeakPersistentHandle weak2 = NULL;
   static const intptr_t kWeak2ExternalSize = 2 * KB;
+  EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld));
   {
     Dart_EnterScope();
     Dart_Handle dart_true = Dart_True();  // VM heap object.
     EXPECT_VALID(dart_true);
     weak1 = Dart_NewWeakPersistentHandle(
-        dart_true, NULL, kWeak1ExternalSize, NopCallback);
+        dart_true, NULL, kWeak1ExternalSize, UnreachedCallback);
     EXPECT_VALID(AsHandle(weak1));
-    Dart_Handle zero = Dart_NewInteger(0);  // Smi.
+    Dart_Handle zero = Dart_False();  // VM heap object.
     EXPECT_VALID(zero);
     weak2 = Dart_NewWeakPersistentHandle(
-        zero, NULL, kWeak2ExternalSize, NopCallback);
+        zero, NULL, kWeak2ExternalSize, UnreachedCallback);
     EXPECT_VALID(AsHandle(weak2));
     // Both should be charged to old space.
     EXPECT(heap->ExternalInWords(Heap::kOld) ==
@@ -3065,6 +3078,7 @@
   Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
   Dart_DeleteWeakPersistentHandle(isolate, weak1);
   Dart_DeleteWeakPersistentHandle(isolate, weak2);
+  EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld));
   {
     TransitionNativeToVM transition(thread);
     Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
@@ -8824,7 +8838,7 @@
   {
     TransitionNativeToVM transition(thread);
     Isolate::Current()->heap()->CollectAllGarbage();
-    GCTestHelper::WaitForFinalizationTasks();
+    GCTestHelper::WaitForGCTasks();
   }
   EXPECT_EQ(80, peer8);
   EXPECT_EQ(82, peer16);
diff --git a/runtime/vm/dart_api_state.cc b/runtime/vm/dart_api_state.cc
index be30a2d..ed6ac3e 100644
--- a/runtime/vm/dart_api_state.cc
+++ b/runtime/vm/dart_api_state.cc
@@ -19,9 +19,9 @@
     isolate_(isolate),
     queue_(queue) {
   ASSERT(FLAG_background_finalization);
-  MonitorLocker ml(isolate->heap()->finalization_tasks_lock());
-  isolate->heap()->set_finalization_tasks(
-      isolate->heap()->finalization_tasks() + 1);
+  PageSpace* old_space = isolate->heap()->old_space();
+  MonitorLocker ml(old_space->tasks_lock());
+  old_space->set_tasks(old_space->tasks() + 1);
   ml.Notify();
 }
 
@@ -46,9 +46,9 @@
   Thread::ExitIsolateAsHelper();
 
   {
-    Heap* heap = isolate_->heap();
-    MonitorLocker ml(heap->finalization_tasks_lock());
-    heap->set_finalization_tasks(heap->finalization_tasks() - 1);
+    PageSpace* old_space = isolate_->heap()->old_space();
+    MonitorLocker ml(old_space->tasks_lock());
+    old_space->set_tasks(old_space->tasks() - 1);
     ml.Notify();
   }
 }
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 83bacb1..b9a74c7 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -35,8 +35,6 @@
       old_space_(this, max_old_gen_words, max_external_words),
       barrier_(new Monitor()),
       barrier_done_(new Monitor()),
-      finalization_tasks_lock_(new Monitor()),
-      finalization_tasks_(0),
       read_only_(false),
       gc_new_space_in_progress_(false),
       gc_old_space_in_progress_(false) {
@@ -53,7 +51,6 @@
 Heap::~Heap() {
   delete barrier_;
   delete barrier_done_;
-  delete finalization_tasks_lock_;
 
   for (int sel = 0;
        sel < kNumWeakSelectors;
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index d90adc4..63f35d8 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -253,10 +253,6 @@
   Monitor* barrier() const { return barrier_; }
   Monitor* barrier_done() const { return barrier_done_; }
 
-  Monitor* finalization_tasks_lock() const { return finalization_tasks_lock_; }
-  intptr_t finalization_tasks() const { return finalization_tasks_; }
-  void set_finalization_tasks(intptr_t count) { finalization_tasks_ = count; }
-
   void SetupExternalPage(void* pointer, uword size, bool is_executable) {
     old_space_.SetupExternalPage(pointer, size, is_executable);
   }
@@ -350,9 +346,6 @@
   Monitor* barrier_;
   Monitor* barrier_done_;
 
-  Monitor* finalization_tasks_lock_;
-  intptr_t finalization_tasks_;
-
   // GC stats collection.
   GCStats stats_;
 
@@ -365,6 +358,7 @@
   bool gc_old_space_in_progress_;
 
   friend class Become;  // VisitObjectPointers
+  friend class Precompiler;  // VisitObjects
   friend class ServiceEvent;
   friend class PageSpace;  // VerifyGC
   friend class IsolateReloadContext;  // VisitObjects
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 612d97e..f583fa1 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -1772,13 +1772,11 @@
     // We need temporaries for field object.
     summary->set_temp(0, Location::RequiresRegister());
     return summary;
-  } else {
-    LocationSummary* summary = new(zone) LocationSummary(
-        zone, kNumInputs, 0, LocationSummary::kNoCall);
-    summary->set_in(0, Location::RequiresRegister());
-    return summary;
   }
-  UNREACHABLE();
+  LocationSummary* summary = new(zone) LocationSummary(
+      zone, kNumInputs, 0, LocationSummary::kNoCall);
+  summary->set_in(0, Location::RequiresRegister());
+  return summary;
 }
 
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 3c6c88b..7d203bd 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1736,20 +1736,10 @@
   if (heap_ != NULL) {
     // Wait for any concurrent GC tasks to finish before shutting down.
     // TODO(koda): Support faster sweeper shutdown (e.g., after current page).
-    {
-      PageSpace* old_space = heap_->old_space();
-      MonitorLocker ml(old_space->tasks_lock());
-      while (old_space->tasks() > 0) {
-        ml.Wait();
-      }
-    }
-
-    // Wait for background finalization to finish before shutting down.
-    {
-      MonitorLocker ml(heap_->finalization_tasks_lock());
-      while (heap_->finalization_tasks() > 0) {
-        ml.Wait();
-      }
+    PageSpace* old_space = heap_->old_space();
+    MonitorLocker ml(old_space->tasks_lock());
+    while (old_space->tasks() > 0) {
+      ml.Wait();
     }
   }
 
@@ -1895,7 +1885,8 @@
   raw_class = class_table()->At(cid);
 #endif  // !PRODUCT
   ASSERT(raw_class != NULL);
-  ASSERT(raw_class->ptr()->id_ == cid);
+  // This is temporarily untrue during a class id remap.
+  // ASSERT(raw_class->ptr()->id_ == cid);
   return raw_class;
 }
 
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 4fa23bc..11a7b3b 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -198,6 +198,8 @@
       // because their class hasn't been finalized yet.
       FinalizeAllClasses();
 
+      SortClasses();
+
       // Precompile static initializers to compute result type information.
       PrecompileStaticInitializers();
 
@@ -344,8 +346,16 @@
       function.ClearICDataArray();
     }
   };
-  ClearCodeFunctionVisitor visitor;
-  VisitFunctions(&visitor);
+  ClearCodeFunctionVisitor function_visitor;
+  VisitFunctions(&function_visitor);
+
+  class ClearCodeClassVisitor : public ClassVisitor {
+    void Visit(const Class& cls) {
+      cls.DisableAllocationStub();
+    }
+  };
+  ClearCodeClassVisitor class_visitor;
+  VisitClasses(&class_visitor);
 }
 
 
@@ -2206,6 +2216,147 @@
 }
 
 
+void Precompiler::SortClasses() {
+  ClassTable* table = I->class_table();
+  intptr_t num_cids = table->NumCids();
+  intptr_t* old_to_new_cid = new intptr_t[num_cids];
+  for (intptr_t cid = 0; cid < kNumPredefinedCids; cid++) {
+    old_to_new_cid[cid] = cid;  // The predefined classes cannot change cids.
+  }
+  for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
+    old_to_new_cid[cid] = -1;
+  }
+
+  intptr_t next_new_cid = kNumPredefinedCids;
+  GrowableArray<intptr_t> dfs_stack;
+  Class& cls = Class::Handle(Z);
+  GrowableObjectArray& subclasses = GrowableObjectArray::Handle(Z);
+
+  // Object doesn't use its subclasses list.
+  for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
+    if (!table->HasValidClassAt(cid)) {
+      continue;
+    }
+    cls = table->At(cid);
+    if (cls.is_patch()) {
+      continue;
+    }
+    if (cls.SuperClass() == I->object_store()->object_class()) {
+      dfs_stack.Add(cid);
+    }
+  }
+
+  while (dfs_stack.length() > 0) {
+    intptr_t cid = dfs_stack.RemoveLast();
+    ASSERT(table->HasValidClassAt(cid));
+    cls = table->At(cid);
+    ASSERT(!cls.IsNull());
+    if (old_to_new_cid[cid] == -1) {
+      old_to_new_cid[cid] = next_new_cid++;
+      if (FLAG_trace_precompiler) {
+        THR_Print("%" Pd ": %s, was %" Pd "\n",
+                  old_to_new_cid[cid], cls.ToCString(), cid);
+      }
+    }
+    subclasses = cls.direct_subclasses();
+    if (!subclasses.IsNull()) {
+      for (intptr_t i = 0; i < subclasses.Length(); i++) {
+        cls ^= subclasses.At(i);
+        ASSERT(!cls.IsNull());
+        dfs_stack.Add(cls.id());
+      }
+    }
+  }
+
+  // Top-level classes, typedefs, patch classes, etc.
+  for (intptr_t cid = kNumPredefinedCids; cid < num_cids; cid++) {
+    if (old_to_new_cid[cid] == -1) {
+      old_to_new_cid[cid] = next_new_cid++;
+      if (FLAG_trace_precompiler && table->HasValidClassAt(cid)) {
+        cls = table->At(cid);
+        THR_Print("%" Pd ": %s, was %" Pd "\n",
+                  old_to_new_cid[cid], cls.ToCString(), cid);
+      }
+    }
+  }
+  ASSERT(next_new_cid == num_cids);
+
+  RemapClassIds(old_to_new_cid);
+  delete[] old_to_new_cid;
+}
+
+
+class CidRewriteVisitor : public ObjectVisitor {
+ public:
+  explicit CidRewriteVisitor(intptr_t* old_to_new_cids)
+      : old_to_new_cids_(old_to_new_cids) { }
+
+  intptr_t Map(intptr_t cid) {
+    ASSERT(cid != -1);
+    return old_to_new_cids_[cid];
+  }
+
+  void VisitObject(RawObject* obj) {
+    if (obj->IsClass()) {
+      RawClass* cls = Class::RawCast(obj);
+      cls->ptr()->id_ = Map(cls->ptr()->id_);
+    } else if (obj->IsField()) {
+      RawField* field = Field::RawCast(obj);
+      field->ptr()->guarded_cid_ = Map(field->ptr()->guarded_cid_);
+      field->ptr()->is_nullable_ = Map(field->ptr()->is_nullable_);
+    } else if (obj->IsTypeParameter()) {
+      RawTypeParameter* param = TypeParameter::RawCast(obj);
+      param->ptr()->parameterized_class_id_ =
+          Map(param->ptr()->parameterized_class_id_);
+    } else if (obj->IsType()) {
+      RawType* type = Type::RawCast(obj);
+      RawObject* id = type->ptr()->type_class_id_;
+      if (!id->IsHeapObject()) {
+        type->ptr()->type_class_id_ =
+            Smi::New(Map(Smi::Value(Smi::RawCast(id))));
+      }
+    } else {
+      intptr_t old_cid = obj->GetClassId();
+      intptr_t new_cid = Map(old_cid);
+      if (old_cid != new_cid) {
+        // Don't touch objects that are unchanged. In particular, Instructions,
+        // which are write-protected.
+        obj->SetClassId(new_cid);
+      }
+    }
+  }
+
+ private:
+  intptr_t* old_to_new_cids_;
+};
+
+
+void Precompiler::RemapClassIds(intptr_t* old_to_new_cid) {
+  // Code, ICData, allocation stubs have now-invalid cids.
+  ClearAllCode();
+
+  {
+    HeapIterationScope his;
+
+    // Update the class table. Do it before rewriting cids in headers, as the
+    // heap walkers load an object's size *after* calling the visitor.
+    I->class_table()->Remap(old_to_new_cid);
+
+    // Rewrite cids in headers and cids in Classes, Fields, Types and
+    // TypeParameters.
+    {
+      CidRewriteVisitor visitor(old_to_new_cid);
+      I->heap()->VisitObjects(&visitor);
+    }
+  }
+
+#if defined(DEBUG)
+  I->class_table()->Validate();
+  I->heap()->Verify();
+#endif
+}
+
+
 void Precompiler::ResetPrecompilerState() {
   changed_ = false;
   function_count_ = 0;
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index ad7f0ca..38e16fe 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -335,6 +335,8 @@
   void VisitClasses(ClassVisitor* visitor);
 
   void FinalizeAllClasses();
+  void SortClasses();
+  void RemapClassIds(intptr_t* old_to_new_cid);
 
   Thread* thread() const { return thread_; }
   Zone* zone() const { return zone_; }
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index d6fcec3..067f382 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -335,11 +335,9 @@
   char* native_symbol_name =
       NativeSymbolResolver::LookupSymbolName(pc, &start);
   if (native_symbol_name == NULL) {
-    OS::PrintErr("Frame[%" Pd "] = `unknown symbol` [0x%" Px "]\n",
-                 frame_index, pc);
+    OS::PrintErr("  [0x%" Pp "] Unknown symbol\n", pc);
   } else {
-    OS::PrintErr("Frame[%" Pd "] = `%s` [0x%" Px "]\n",
-                 frame_index, native_symbol_name, pc);
+    OS::PrintErr("  [0x%" Pp "] %s\n", pc, native_symbol_name);
     NativeSymbolResolver::FreeSymbolName(native_symbol_name);
   }
 }
@@ -1033,7 +1031,7 @@
                                               fp,
                                               sp);
   }
-  OS::PrintErr("-- End of DumpStackTrace");
+  OS::PrintErr("-- End of DumpStackTrace\n");
 }
 
 
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 6aed93c..d5ffcb9 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -816,6 +816,7 @@
       return hi;
     }
     UNREACHABLE();
+    return -1;
   }
 
  private:
@@ -2640,6 +2641,7 @@
     return func->Name();
   }
   UNREACHABLE();
+  return NULL;
 }
 
 
@@ -2663,6 +2665,7 @@
     return func->inclusive_ticks();
   }
   UNREACHABLE();
+  return -1;
 }
 
 
@@ -2678,6 +2681,7 @@
     return func->exclusive_ticks();
   }
   UNREACHABLE();
+  return -1;
 }
 
 
diff --git a/runtime/vm/raw_object.cc b/runtime/vm/raw_object.cc
index 73070ac..e4200b9 100644
--- a/runtime/vm/raw_object.cc
+++ b/runtime/vm/raw_object.cc
@@ -637,7 +637,6 @@
 
 intptr_t RawICData::VisitICDataPointers(RawICData* raw_obj,
                                         ObjectPointerVisitor* visitor) {
-  // Make sure that we got here with the tagged pointer as this.
   visitor->VisitPointers(raw_obj->from(), raw_obj->to());
   return ICData::InstanceSize();
 }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 1e975d7..14a9895 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -539,6 +539,11 @@
     return ClassIdTag::decode(tags);
   }
 
+  void SetClassId(intptr_t new_cid) {
+    uword tags = ptr()->tags_;
+    ptr()->tags_ = ClassIdTag::update(new_cid, tags);
+  }
+
   template<class TagBitField>
   void UpdateTagBit(bool value) {
     uword tags = ptr()->tags_;
@@ -596,6 +601,7 @@
   friend class Become;  // GetClassId
   friend class Bigint;
   friend class ByteBuffer;
+  friend class CidRewriteVisitor;
   friend class Closure;
   friend class Code;
   friend class Double;
@@ -719,6 +725,7 @@
   friend class RawInstructions;
   friend class SnapshotReader;
   friend class InstanceSerializationCluster;
+  friend class CidRewriteVisitor;
 };
 
 
@@ -947,6 +954,8 @@
   int8_t guarded_list_length_in_object_offset_;
 
   uint8_t kind_bits_;  // static, final, const, has initializer....
+
+  friend class CidRewriteVisitor;
 };
 
 
@@ -1681,6 +1690,8 @@
   }
   TokenPosition token_pos_;
   int8_t type_state_;
+
+  friend class CidRewriteVisitor;
 };
 
 
@@ -1713,6 +1724,8 @@
   TokenPosition token_pos_;
   int16_t index_;
   int8_t type_state_;
+
+  friend class CidRewriteVisitor;
 };
 
 
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index fe73042..104d22c 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3548,6 +3548,10 @@
   }
 
   void Append(FinalizablePersistentHandle* weak_persistent_handle) {
+    if (!weak_persistent_handle->raw()->IsHeapObject()) {
+      return;  // Free handle.
+    }
+
     JSONObject obj(handles_);
     obj.AddProperty("type", "_WeakPersistentHandle");
     const Object& object =
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index c26229d..7a937b3 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -31129,7 +31129,7 @@
  * For more examples of using this API, see
  * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
  * For details on using the Map API, see the
- * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
  * section of the library tour.
  */
 @DomName('Storage')
diff --git a/sdk/lib/html/dartium/html_dartium.dart b/sdk/lib/html/dartium/html_dartium.dart
index 0b536b6..e007fc3 100644
--- a/sdk/lib/html/dartium/html_dartium.dart
+++ b/sdk/lib/html/dartium/html_dartium.dart
@@ -35026,7 +35026,7 @@
  * For more examples of using this API, see
  * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
  * For details on using the Map API, see the
- * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
  * section of the library tour.
  */
 @DomName('Storage')
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index a0dd69f..cd1f320 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -496,6 +496,184 @@
 LibTest/core/Uri/Uri_A06_t03: Slow, Pass
 LibTest/math/Point/operator_mult_A02_t01: RuntimeError # Issue 1533
 
+[ $compiler == dart2js && $fast_startup ]
+Language/Classes/Instance_Methods/Operators/unary_minus: Fail # mirrors not supported
+Language/Expressions/Null/instance_of_class_null_t01: Fail # mirrors not supported
+Language/Metadata/before_class_t01: Fail # mirrors not supported
+Language/Metadata/before_ctor_t01: Fail # mirrors not supported
+Language/Metadata/before_ctor_t02: Fail # mirrors not supported
+Language/Metadata/before_export_t01: Fail # mirrors not supported
+Language/Metadata/before_factory_t01: Fail # mirrors not supported
+Language/Metadata/before_function_t01: Fail # mirrors not supported
+Language/Metadata/before_function_t02: Fail # mirrors not supported
+Language/Metadata/before_function_t03: Fail # mirrors not supported
+Language/Metadata/before_function_t04: Fail # mirrors not supported
+Language/Metadata/before_function_t05: Fail # mirrors not supported
+Language/Metadata/before_function_t06: Fail # mirrors not supported
+Language/Metadata/before_function_t07: Fail # mirrors not supported
+Language/Metadata/before_import_t01: Fail # mirrors not supported
+Language/Metadata/before_library_t01: Fail # mirrors not supported
+Language/Metadata/before_param_t01: Fail # mirrors not supported
+Language/Metadata/before_param_t02: Fail # mirrors not supported
+Language/Metadata/before_param_t03: Fail # mirrors not supported
+Language/Metadata/before_param_t04: Fail # mirrors not supported
+Language/Metadata/before_param_t05: Fail # mirrors not supported
+Language/Metadata/before_param_t06: Fail # mirrors not supported
+Language/Metadata/before_param_t07: Fail # mirrors not supported
+Language/Metadata/before_param_t08: Fail # mirrors not supported
+Language/Metadata/before_param_t09: Fail # mirrors not supported
+Language/Metadata/before_type_param_t01: Fail # mirrors not supported
+Language/Metadata/before_typedef_t01: Fail # mirrors not supported
+Language/Metadata/before_variable_t01: Fail # mirrors not supported
+Language/Metadata/before_variable_t02: Fail # mirrors not supported
+Language/Metadata/compilation_t01: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t02: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t03: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t04: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t05: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t06: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t07: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t08: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t09: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t10: Pass # mirrors not supported, fails for the wrong reason
+Language/Metadata/compilation_t11: Pass # mirrors not supported, fails for the wrong reason
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-004_t02: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/attributes/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/elements-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-element-interface/methods/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/extensions-to-event-interface/event-path-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-007_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-008_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-009_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-010_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-011_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-012_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-attributes/test-013_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-007_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/shadowroot-object/shadowroot-methods/test-010_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-004_t02: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-content-html-element/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-003_t02: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/elements-and-dom-objects/the-shadow-html-element/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-dispatch/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-dispatch/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-dispatch/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-retargeting/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/events/event-retargeting/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-retargeting/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/event-retargeting/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-005_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-007_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-008_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/events-that-are-always-stopped/test-009_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t02: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t03: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t04: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t05: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-001_t06: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-focus-events/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/events/retargeting-relatedtarget/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-004_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/html-elements-and-their-shadow-trees/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-001_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/html-forms/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/html-elements-in-shadow-trees/inert-html-elements/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/composition/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/custom-pseudo-elements/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/distributed-pseudo-element/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/hosting-multiple-shadow-trees/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/distribution-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/nested-shadow-trees/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/rendering-shadow-trees/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/reprojection/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-003_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-004_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-006_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-017_t01: Fail # custom elements not supported
+WebPlatformTest/shadow-dom/shadow-trees/satisfying-matching-criteria/test-017_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/selectors-api-002_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/shadow-root-001_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-005_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-007_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: Fail # please triage
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-011_t01: Fail # please triage
+WebPlatformTest/shadow-dom/testcommon: Fail # mirrors not supported
+
+[ $compiler == dart2js && $fast_startup && $runtime == jsshell ]
+LibTest/isolate/ReceivePort/asBroadcastStream_A03_t01: Fail # please triage
+
+[ $compiler == dart2js && $fast_startup && $browser ]
+LayoutTests/fast/dom/custom/document-register-on-create-callback_t01: Fail # please triage
+LayoutTests/fast/dom/custom/unresolved-pseudoclass_t01: Fail # please triage
+WebPlatformTest/custom-elements/concepts/type_A01_t01: Fail # custom elements not supported
+LayoutTests/fast/dom/custom/attribute-changed-callback_t01: Fail # custom elements not supported
+LayoutTests/fast/dom/custom/created-callback_t01: Fail # please triage
+LayoutTests/fast/dom/custom/document-register-namespace_t01: Fail # please triage
+LayoutTests/fast/dom/custom/document-register-type-extensions_t01: Fail # please triage
+LayoutTests/fast/dom/custom/element-type_t01: Fail # custom elements not supported
+LayoutTests/fast/dom/custom/element-upgrade_t01: Fail # please triage
+LayoutTests/fast/dom/custom/type-extensions_t01: Fail # custom elements not supported
+WebPlatformTest/custom-elements/concepts/type_A07_t01: Fail # custom elements not supported
+WebPlatformTest/custom-elements/concepts/type_A08_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/createElementNS_A01_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/createElementNS_A04_t01: Fail # custom elements not supported
+WebPlatformTest/custom-elements/instantiating/createElementNS_A05_t01: Fail # custom elements not supported
+WebPlatformTest/custom-elements/instantiating/createElement_A01_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/createElement_A05_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/isAttribute_A03_t01: Fail # please triage
+WebPlatformTest/custom-elements/instantiating/localName_A01_t01: Fail # please triage
+
+
 [ $compiler == dart2js && $checked != true ]
 Language/Expressions/Property_Extraction/General_Super_Property_Extraction/getter_lookup_t02: Timeout, Skip # Please triage this failure
 Language/Expressions/Property_Extraction/Super_Closurization/setter_closurization_t09: CompileTimeError # Please triage this failure
@@ -1442,7 +1620,6 @@
 WebPlatformTest/Utils/test/asyncTestFail_t01: RuntimeError # Please triage this failure
 WebPlatformTest/Utils/test/asyncTestFail_t02: RuntimeError # Please triage this failure
 WebPlatformTest/Utils/test/asyncTestTimeout_t01: Skip # Times out. Please triage this failure
-WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Issue 25155
@@ -1601,6 +1778,15 @@
 WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # Please triage this failure
 WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # Please triage this failure
 
+[ $compiler == dart2js && $runtime == chrome && $fast_startup ]
+WebPlatformTest/custom-elements/concepts/type_A04_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/createElement_A04_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/isAttribute_A02_t01: RuntimeError # Please triage this failure
+WebPlatformTest/custom-elements/instantiating/namespace_A01_t01: RuntimeError # Please triage this failure
+
+[ $compiler == dart2js && $runtime == chrome && $fast_startup == false ]
+WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
+
 [ $compiler == dart2js && $runtime == chrome && $checked ]
 LayoutTests/fast/css-intrinsic-dimensions/css-tables_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-intrinsic-dimensions/intrinsic-sized-absolutes_t01: RuntimeError # Please triage this failure
@@ -3205,7 +3391,6 @@
 
 [ $compiler == dart2js && $runtime == ff && $system == linux]
 LayoutTests/fast/canvas/webgl/*: Timeout, Pass # Issue 26725
-LayoutTests/fast/canvas/canvas-composite-text-alpha_t01: RuntimeError # co19 issue 16
 LayoutTests/fast/text/whitespace/nowrap-line-break-after-white-space_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/oes-element-index-uint_t01: Skip # Times out always
 LayoutTests/fast/canvas/webgl/texture-complete_t01: Skip # Times out sometimes
@@ -4020,7 +4205,6 @@
 LibTest/html/Element/getClientRects_A01_t02: RuntimeError # Please triage this failure
 LibTest/html/Element/getNamespacedAttributes_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Please triage this failure
-LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Please triage this failure
 LibTest/html/Element/isTagSupported_A01_t01: RuntimeError # Please triage this failure
 LibTest/html/Element/isTagSupported_A01_t02: RuntimeError # Please triage this failure
 LibTest/html/Element/leftView_A01_t01: RuntimeError # Please triage this failure
@@ -4365,7 +4549,6 @@
 LayoutTests/fast/forms/datalist/datalist-child-validation_t01: RuntimeError # Fails 10 out of 10.
 LayoutTests/fast/overflow/scrollbar-restored_t01: RuntimeError # Fails 10 out of 10.
 LibTest/html/Element/isContentEditable_A01_t01: RuntimeError # Fails 10 out of 10.
-LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Fails 10 out of 10.
 LibTest/html/IFrameElement/isContentEditable_A01_t01: RuntimeError, Pass # Fails 19 out of 20.
 
 LayoutTests/fast/flexbox/repaint-scrollbar_t01: Pass, RuntimeError # Fails 2 out of 10.
@@ -4378,6 +4561,9 @@
 
 LayoutTests/fast/canvas/webgl/glsl-conformance_t01: Skip # Times out 1 out of 20.
 
+[ $compiler == dart2js && $runtime == safari && $fast_startup == false ]
+LibTest/html/Element/isContentEditable_A02_t01: RuntimeError # Fails 10 out of 10.
+
 [ $compiler == dart2js && $runtime == safarimobilesim ]
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
@@ -7702,6 +7888,9 @@
 WebPlatformTest/webstorage/storage_builtins_t01: RuntimeError # Please triage this failure
 WebPlatformTest/webstorage/storage_local_setitem_quotaexceedederr_t01: Skip # Times out. Please triage this failure
 
+[ $compiler == dart2js && $runtime == ie10 && $fast_startup ]
+LayoutTests/fast/canvas/canvas-composite-image_t01: RuntimeError
+
 [ $compiler == dart2js && $runtime == ie11 ]
 Language/Variables/implicit_setter_void_t07: Skip # Times out. Please triage this failure
 Language/Functions/Formal_Parameters/scope_t01: Skip # Times out. Please triage this failure
diff --git a/tests/compiler/dart2js/kernel/helper.dart b/tests/compiler/dart2js/kernel/helper.dart
index 37dfe15..30512d8 100644
--- a/tests/compiler/dart2js/kernel/helper.dart
+++ b/tests/compiler/dart2js/kernel/helper.dart
@@ -36,5 +36,5 @@
 Future check(String code, {String entry: 'main'}) async {
   var original = await compile(code, entry: entry, useKernel: false);
   var kernel = await compile(code, entry: entry, useKernel: true);
-  expect(original, kernel);
+  expect(kernel, original);
 }
diff --git a/tests/compiler/dart2js/kernel/simple_function_test.dart b/tests/compiler/dart2js/kernel/simple_function_test.dart
new file mode 100644
index 0000000..5b1985d
--- /dev/null
+++ b/tests/compiler/dart2js/kernel/simple_function_test.dart
@@ -0,0 +1,43 @@
+import 'package:test/test.dart';
+
+import 'helper.dart' show check;
+
+main() {
+  group('compile function that returns a value', () {
+    test('constant int', () {
+      return check('main() { return 1; }');
+    });
+
+    test('constant double', () {
+      return check('main() { return 1.0; }');
+    });
+
+    test('constant string', () {
+      return check('main() { return "hello"; }');
+    });
+
+    test('constant bool', () {
+      return check('main() { return true; }');
+    });
+
+    test('constant symbol', () {
+      return check('main() { return #hello; }');
+    });
+
+    test('null', () {
+      return check('main() { return null; }');
+    });
+  });
+
+  test('compile function that returns its argument', () {
+    String code = '''
+      foo(x) {
+        return x;
+      }
+
+      main() {
+        foo(1);
+      }''';
+    return check(code, entry: 'foo');
+  });
+}
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index 6fa9843..596f35a 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -14,6 +14,44 @@
 variable_type_test/03: Fail, OK
 variable_type_test/01: Fail, OK
 
+[ $compiler == dart2js && $fast_startup ]
+21666_test: Fail # mirrors not supported
+23056_test: Fail # mirrors not supported
+closure_type_reflection2_test: Fail # mirrors not supported
+closure_type_reflection_test: Fail # mirrors not supported
+deferred/deferred_mirrors1_lib: Fail # mirrors not supported
+deferred/deferred_mirrors1_test: Fail # mirrors not supported
+deferred/deferred_mirrors2_lazy: Fail # mirrors not supported
+deferred/deferred_mirrors2_lib3: Fail # mirrors not supported
+deferred/deferred_mirrors2_test: Fail # mirrors not supported
+inference_nsm_mirrors_test: Fail # mirrors not supported
+invalid_annotation2_test/none: Fail # mirrors not supported
+invalid_annotation2_test/01: Pass # mirrors not supported, passes for the wrong reason
+lookup_map/dead_entry_through_mirrors_test: Fail # mirrors not supported
+lookup_map/live_entry_through_mirrors_test: Fail # mirrors not supported
+lookup_map/live_entry_through_mirrors_used_test: Fail # mirrors not supported
+mirror_enqueuer_regression_test: Fail # mirrors not supported
+mirror_invalid_field_access2_test: Fail # mirrors not supported
+mirror_invalid_field_access3_test: Fail # mirrors not supported
+mirror_invalid_field_access4_test: Fail # mirrors not supported
+mirror_invalid_field_access_test: Fail # mirrors not supported
+mirror_invalid_invoke2_test: Fail # mirrors not supported
+mirror_invalid_invoke3_test: Fail # mirrors not supported
+mirror_invalid_invoke_test: Fail # mirrors not supported
+mirror_printer_test: Fail # mirrors not supported
+mirror_test: Fail # mirrors not supported
+mirror_type_inference_field2_test: Fail # mirrors not supported
+mirror_type_inference_field_test: Fail # mirrors not supported
+mirror_type_inference_function_test: Fail # mirrors not supported
+mirrors_declarations_filtering_test: Fail # mirrors not supported
+mirrors_used_closure_test: Fail # mirrors not supported
+mirrors_used_metatargets_test: Fail # mirrors not supported
+mirrors_used_native_test: Fail # mirrors not supported
+mirrors_used_warning2_test: Fail # mirrors not supported
+mirrors_used_warning_test: Fail # mirrors not supported
+no_such_method_mirrors_test: Fail # mirrors not supported
+reflect_native_types_test: Fail # mirrors not supported
+
 [ $compiler == dart2js && ($runtime == d8 || $runtime == chrome || $runtime == drt) ]
 bound_closure_interceptor_type_test: Fail, Pass # v8 issue 3084. https://code.google.com/p/v8/issues/detail?id=3084
 
diff --git a/tests/compiler/dart2js_extra/locate_single_element_1_test.dart b/tests/compiler/dart2js_extra/locate_single_element_1_test.dart
new file mode 100644
index 0000000..5fe6e85
--- /dev/null
+++ b/tests/compiler/dart2js_extra/locate_single_element_1_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test for locateSingleElement bug.
+
+import 'package:expect/expect.dart';
+
+class T {
+  foo() => 'T.foo';  // This is the single element.
+}
+
+class C implements T {
+  // There is a warning that C does not implement 'foo'.
+}
+
+@NoInline() @AssumeDynamic()
+assumeT(x) {  // returns inferred subtype(T).
+  if (x is T) return x;
+  throw "Not T";
+}
+
+var log = [];
+demo() {
+  log.add(new T());  // T is created.
+  var a = assumeT(new C());  // C is created.
+
+  // The call "a.foo()" should be a NoSuchMethodError, but a bug in
+  // locateSingleElement used to lead to T.foo being inlined.  There is a single
+  // method. T.foo, that matches subtype(T), but it should be rejected because
+  // not all instantiated classes that are subtype(T) have that method.
+  log.add(a.foo());
+}
+
+main() {
+  Expect.throws(demo);
+}
diff --git a/tests/compiler/dart2js_native/dart2js_native.status b/tests/compiler/dart2js_native/dart2js_native.status
index cae6550..080c6e1 100644
--- a/tests/compiler/dart2js_native/dart2js_native.status
+++ b/tests/compiler/dart2js_native/dart2js_native.status
@@ -9,6 +9,13 @@
 native_no_such_method_exception4_frog_test: CompileTimeError # Issue 9631
 native_no_such_method_exception5_frog_test: CompileTimeError # Issue 9631
 
+[ $compiler == dart2js && $fast_startup ]
+mirror_intercepted_field_test: Fail # mirrors not supported
+native_mirror_test: Fail # mirrors not supported
+native_no_such_method_exception3_frog_test: Fail # mirrors not supported
+native_no_such_method_exception4_frog_test: Fail # mirrors not supported
+native_no_such_method_exception5_frog_test: Fail # mirrors not supported
+
 [ $compiler == dart2js && $cps_ir == false ]
 bound_closure_super_test: Fail
 fake_thing_test: Fail # Issue 13010
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 78010e9..24a5cd6 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -58,6 +58,9 @@
 int_modulo_arith_test/bignum: RuntimeError # No bigints.
 int_modulo_arith_test/modPow: RuntimeError # No bigints.
 
+[ $compiler == dart2js && $fast_startup ]
+apply3_test: Fail # mirrors not supported
+
 [ ($compiler == none || $compiler == precompiler || $compiler == dart2app || $compiler == dart2appjit) && $runtime != dartium && $runtime != drt ]
 symbol_test/02: MissingCompileTimeError # bug 11669
 symbol_test/03: MissingCompileTimeError # bug 11669
diff --git a/tests/html/html.status b/tests/html/html.status
index 36c0e8a..0c1830d 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -411,6 +411,33 @@
 window_nosuchmethod_test: StaticWarning
 js_typed_interop_default_arg_test/default_value: MissingCompileTimeError # Issue #25759
 
+[ $compiler == dart2js && $fast_startup ]
+custom/constructor_calls_created_synchronously_test: Fail # mirrors not supported
+custom/js_custom_test: Fail # mirrors not supported
+custom/mirrors_test: Fail # mirrors not supported
+mirrors_js_typed_interop_test: Fail # mirrors not supported
+
+[ $compiler == dart2js && $fast_startup && $browser ]
+custom/attribute_changed_callback_test/fully_supported: Fail # custom elements not supported
+custom/attribute_changed_callback_test/unsupported_on_polyfill: Fail # custom elements not supported
+custom/document_register_type_extensions_test/construction: Fail # custom elements not supported
+custom/document_register_type_extensions_test/functional: Fail # custom elements not supported
+custom/document_register_type_extensions_test/namespaces: Fail # custom elements not supported
+custom/document_register_type_extensions_test/parsing: Fail # custom elements not supported
+custom/document_register_type_extensions_test/registration: Fail # custom elements not supported
+custom/entered_left_view_test: Fail # custom elements not supported
+custom/element_upgrade_test: Fail # custom elements not supported
+custom/document_register_basic_test: Fail # custom elements not supported
+custom/document_register_type_extensions: Fail # custom elements not supported
+custom_elements_23127_test/baseline: Fail # custom elements not supported
+custom_elements_23127_test/c1t: Fail # custom elements not supported
+custom_elements_23127_test/c2: Fail # custom elements not supported
+js_function_getter_test: Fail # js-interop function's not supported
+js_typed_interop_callable_object_test: Fail # js-interop function's not supported
+js_typed_interop_test/closure: Fail # js-interop function's not supported
+js_typed_interop_test/method: Fail # js-interop function's not supported
+js_typed_interop_window_property_test/bind*: Fail # js-interop function's not supported
+
 [ $compiler == dart2js && $cps_ir && $browser ]
 js_typed_interop_side_cast_exp_test: RuntimeError # Corner case in package:js that we might want to remove (See comment in #24978).
 js_typed_interop_test/static_method_tearoff_1: RuntimeError # Tree-shaking a used tear-off (#24978, #25720).
diff --git a/tests/isolate/isolate.status b/tests/isolate/isolate.status
index ab8dec3..473e036 100644
--- a/tests/isolate/isolate.status
+++ b/tests/isolate/isolate.status
@@ -61,6 +61,32 @@
 [ $compiler == dart2js && $jscl ]
 spawn_uri_test: SkipByDesign # Loading another file is not supported in JS shell
 
+[ $compiler == dart2js && $fast_startup ]
+browser/compute_this_script_browser_test: Fail # mirrors not supported
+browser/typed_data_message_test: Fail # mirrors not supported
+count_test: Fail # mirrors not supported
+cross_isolate_message_test: Fail # mirrors not supported
+illegal_msg_function_test: Fail # mirrors not supported
+illegal_msg_mirror_test: Fail # mirrors not supported
+isolate_complex_messages_test: Fail # mirrors not supported
+mandel_isolate_test: Fail # mirrors not supported
+message2_test: Fail # mirrors not supported
+message_test: Fail # mirrors not supported
+mint_maker_test: Fail # mirrors not supported
+nested_spawn2_test: Fail # mirrors not supported
+nested_spawn_test: Fail # mirrors not supported
+raw_port_test: Fail # mirrors not supported
+remote_unittest_helper: Fail # mirrors not supported
+request_reply_test: Fail # mirrors not supported
+spawn_function_custom_class_test: Fail # mirrors not supported
+spawn_function_test: Fail # mirrors not supported
+stacktrace_message_test: Fail # mirrors not supported
+static_function_test: Fail # mirrors not supported
+unresolved_ports_test: Fail # mirrors not supported
+
+[ $compiler == dart2js && $fast_startup && $browser == false ]
+isolate_current_test: Fail  # please triage
+
 [ $csp ]
 deferred_in_isolate2_test: Skip # Issue 16898. Deferred loading does not work from an isolate in CSP-mode
 
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 8001ee7..b6e331a 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -38,6 +38,36 @@
 accessor_conflict_import_prefixed_test: RuntimeError # Issue 25626
 accessor_conflict_import_test: RuntimeError # Issue 25626
 
+[ $compiler == dart2js && $fast_startup ]
+const_evaluation_test/*: Fail # mirrors not supported
+deferred_constraints_constants_test/none: Fail # mirrors not supported
+deferred_constraints_constants_test/reference_after_load: Fail # mirrors not supported
+deferred_constraints_constants_test: Pass # mirrors not supported, passes for the wrong reason
+enum_mirror_test: Fail # mirrors not supported
+field_increment_bailout_test: Fail # mirrors not supported
+instance_creation_in_function_annotation_test: Fail # mirrors not supported
+invocation_mirror2_test: Fail # mirrors not supported
+invocation_mirror_invoke_on2_test: Fail # mirrors not supported
+invocation_mirror_invoke_on_test: Fail # mirrors not supported
+issue21079_test: Fail # mirrors not supported
+library_env_test/has_mirror_support: Fail # mirrors not supported
+library_env_test/has_no_mirror_support: Pass # fails for the wrong reason.
+many_overridden_no_such_method_test: Fail # mirrors not supported
+no_such_method_test: Fail # mirrors not supported
+null_test/0*: Pass # mirrors not supported, fails for the wrong reason
+null_test/none: Fail # mirrors not supported
+overridden_no_such_method_test: Fail # mirrors not supported
+redirecting_factory_reflection_test: Fail # mirrors not supported
+regress_13462_0_test: Fail # mirrors not supported
+regress_13462_1_test: Fail # mirrors not supported
+regress_18535_test: Fail # mirrors not supported
+super_call4_test: Fail # mirrors not supported
+super_getter_setter_test: Fail # mirrors not supported
+vm/reflect_core_vm_test: Fail # mirrors not supported
+
+[ $compiler == dart2js && $fast_startup && $checked ]
+generic_local_functions_test: Fail # reified type for generic function not generated correctly
+
 [ $compiler == dart2js && $runtime == jsshell ]
 await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
 async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index b280b4f..28cbf3d 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -104,6 +104,27 @@
 mirrors/mirrors_reader_test: Slow, RuntimeError # Issue 16589
 mirrors/regress_26187_test: RuntimeError # Issue 6490
 
+[ $compiler == dart2js && $fast_startup ]
+mirrors/*: Fail # mirrors not supported
+mirrors/circular_factory_redirection_test/0*: Pass # expects failure, but it fails for the wrong reason
+mirrors/library_imports_bad_metadata_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/library_metadata2_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_allowed_values_test/0*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_allowed_values_test/1*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_allowed_values_test/2*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_allowed_values_test/3*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_constructor_arguments_test/0*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_nested_constructor_call_test/0*: Pass # expects failure, but it fails for the wrong reason
+mirrors/metadata_scope_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/mirror_in_static_init_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/parameter_is_const_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/syntax_error_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/variable_is_const_test/01: Pass # expects failure, but it fails for the wrong reason
+mirrors/model_test: Pass # this is ok
+
+[ $compiler == dart2js && $fast_startup ]
+mirrors/regress_16321_test/01: Pass # expects failure, but if fails for the wrong reason
+
 [ $runtime == safari || $runtime == safarimobilesim ]
 typed_data/int32x4_test: Fail, Pass # Safari has an optimization bug (nightlies are already fine).
 typed_data/float32x4_test: Fail, Pass # Safari has an optimization bug (nightlies are already fine).
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 8163f89..df3c7a2 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -136,6 +136,9 @@
 medium_integer_test: Pass # The test only fails at runtime, not at compilation.
 oom_error_stacktrace_test: Pass # The test only fails at runtime.
 
+[ $compiler == dart2js && $fast_startup ]
+io/observatory_test: Fail # mirrors not supported.
+
 [ $compiler == dart2js && $browser ]
 *: Skip
 
diff --git a/tools/VERSION b/tools/VERSION
index 4f34f59..651739d 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 20
 PATCH 0
-PRERELEASE 0
+PRERELEASE 1
 PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 00ba641..683d7ad 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -40,6 +40,7 @@
   "http_parser_rev" : "@8b179e36aba985208e4c5fb15cfddd386b6370a4",
   "http_throttle_rev" : "@a81f08be942cdd608883c7b67795c12226abc235",
   "json_rpc_2_rev": "@a38eefd116d910199de205f962af92fed87c164c",
+  "kernel_rev": "@9509d282a62fe025f8d6242bb233b02e0a7fee04",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "matcher_tag": "@0.12.0",
   "mime_rev": "@75890811d4af5af080351ba8a2853ad4c8df98dd",
@@ -109,6 +110,8 @@
       (Var("github_mirror") % "http_parser") + Var("http_parser_rev"),
   "src/dart/third_party/pkg/http_throttle":
       (Var("github_mirror") % "http_throttle") + Var("http_throttle_rev"),
+  "src/dart/third_party/pkg/kernel":
+      (Var("github_mirror") % "kernel") + Var("kernel_rev"),
   "src/dart/third_party/pkg/logging":
       (Var("github_mirror") % "logging") + Var("logging_rev"),
   "src/dart/third_party/pkg/matcher":
diff --git a/tools/dom/templates/html/impl/impl_Storage.darttemplate b/tools/dom/templates/html/impl/impl_Storage.darttemplate
index 609355e..b3c3ac9 100644
--- a/tools/dom/templates/html/impl/impl_Storage.darttemplate
+++ b/tools/dom/templates/html/impl/impl_Storage.darttemplate
@@ -26,7 +26,7 @@
  * For more examples of using this API, see
  * [localstorage_test.dart](http://code.google.com/p/dart/source/browse/branches/bleeding_edge/dart/tests/html/localstorage_test.dart).
  * For details on using the Map API, see the
- * [Maps](http://www.dartlang.org/docs/library-tour/#maps-aka-dictionaries-or-hashes)
+ * [Maps](https://www.dartlang.org/guides/libraries/library-tour#maps)
  * section of the library tour.
  */
 $(ANNOTATIONS)$(NATIVESPEC)$(CLASS_MODIFIERS)class $CLASSNAME$EXTENDS
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index e008e71..d0e6f5f 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -303,9 +303,6 @@
       Map<String, String> environmentOverrides) {
     List compilerArguments = new List.from(arguments)
       ..addAll(extraDart2jsOptions);
-    if (useFastStartup) {
-      compilerArguments.add('--fast-startup');
-    }
     return new CommandArtifact(<Command>[
       this.computeCompilationCommand('$tempDir/out.js', buildDir,
           CommandBuilder.instance, compilerArguments, environmentOverrides)
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index fd8270d..183be62 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -2280,6 +2280,9 @@
     if (compiler == "dart2js" && configuration["cps_ir"]) {
       args.add("--use-cps-ir");
     }
+    if (compiler == "dart2js" && configuration["fast_startup"]) {
+      args.add("--fast-startup");
+    }
     if (compiler == "dart2analyzer") {
       args.add("--show-package-warnings");
       args.add("--enable-async");