Version 1.19.0-dev.1.0

Merge 'b78aeee6f20dcad020267443bae6b00017f1eae0' into dev
diff --git a/DEPS b/DEPS
index 3b3ac3b..700ff13 100644
--- a/DEPS
+++ b/DEPS
@@ -56,7 +56,7 @@
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.4",
   "dartdoc_tag" : "@v0.9.6+2",
-  "dev_compiler_rev": "@108f2a2a03b1926e640013f3244df625b42ec380",
+  "dev_compiler_rev": "@d39946fd7af11d02a8831dbd7a2b776c69099ff6",
   "fixnum_tag": "@0.10.5",
   "func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
@@ -71,7 +71,7 @@
   "isolate_tag": "@0.2.2",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@2.0.0",
-  "linter_rev": "@7ca3aab6ca45b988440e425c187993a533fbe27e",
+  "linter_rev": "@0abfb82a7d8c36946a2a9f00c699fa5a925abec3",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
   "matcher_tag": "@0.12.0",
@@ -81,7 +81,7 @@
   "oauth2_tag": "@1.0.0",
   "observatory_pub_packages_rev": "@e5e1e543bea10d4bed95b22ad3e7aa2b20a23584",
   "observe_rev": "@eee2b8ec34236fa46982575fbccff84f61202ac6",
-  "package_config_rev": "@0.1.5",
+  "package_config_rev": "@1.0.0",
   "path_tag": "@1.3.6",
   "plugin_tag": "@0.2.0",
   "ply_rev": "@604b32590ffad5cbb82e4afef1d305512d06ae93",
diff --git a/pkg/analysis_server/pubspec.yaml b/pkg/analysis_server/pubspec.yaml
index 9b4a4ff..0e3ba01 100644
--- a/pkg/analysis_server/pubspec.yaml
+++ b/pkg/analysis_server/pubspec.yaml
@@ -12,6 +12,7 @@
   isolate: ^0.2.2
   linter: ^0.1.16
   logging: any
+  package_config: '>=0.1.5 <2.0.0'
   path: any
   plugin: ^0.2.0
   watcher: any
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index 5b2416e..d0a2549 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -9,7 +9,6 @@
 import 'package:analysis_server/src/context_manager.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/error_processor.dart';
diff --git a/pkg/analysis_server/test/services/completion/completion_target_test.dart b/pkg/analysis_server/test/services/completion/completion_target_test.dart
index f7cca21..ce02343 100644
--- a/pkg/analysis_server/test/services/completion/completion_target_test.dart
+++ b/pkg/analysis_server/test/services/completion/completion_target_test.dart
@@ -64,11 +64,7 @@
   test_ArgumentList_InstanceCreationExpression2() {
     // ArgumentList  InstanceCreationExpression  Block
     addTestSource('main() {new Foo(a,^)}');
-    if (context.analysisOptions.enableTrailingCommas) {
-      assertTarget(')', '(a)', argIndex: 1);
-    } else {
-      assertTarget('', '(a, )', argIndex: 1);
-    }
+    assertTarget(')', '(a)', argIndex: 1);
   }
 
   test_ArgumentList_InstanceCreationExpression_functionArg2() {
@@ -104,11 +100,7 @@
   test_ArgumentList_MethodInvocation4() {
     // ArgumentList  MethodInvocation  Block
     addTestSource('main() {foo(n,^)}');
-    if (context.analysisOptions.enableTrailingCommas) {
-      assertTarget(')', '(n)', argIndex: 1);
-    } else {
-      assertTarget('', '(n, )', argIndex: 1);
-    }
+    assertTarget(')', '(n)', argIndex: 1);
   }
 
   test_ArgumentList_MethodInvocation_functionArg() {
diff --git a/pkg/analyzer/lib/src/context/cache.dart b/pkg/analyzer/lib/src/context/cache.dart
index 50207ac..efa8227 100644
--- a/pkg/analyzer/lib/src/context/cache.dart
+++ b/pkg/analyzer/lib/src/context/cache.dart
@@ -8,8 +8,6 @@
 import 'dart:collection';
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/element/element.dart'
-    show ElementImpl, Modifier;
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -559,7 +557,7 @@
 //      }
 //      valueStr = valueStr.replaceAll('\n', '\\n');
 //      print(
-//          'setValue $descriptor for $target value=$valueStr $dependedOn=$dependedOn');
+//          'setValue $descriptor for $target value=$valueStr dependedOn=$dependedOn');
 //    }
     _validateStateChange(descriptor, CacheState.VALID);
     TargetedResult thisResult = new TargetedResult(target, descriptor);
@@ -659,7 +657,7 @@
         return;
       }
     }
-//    if (deltaResult != null && deltaResult != DeltaResult.KEEP_CONTINUE) {
+//    if (deltaResult != null) {
 //      String indent = '  ' * level;
 //      String deltaResultName = deltaResult.toString().split('.').last;
 //      print('[$id]$indent$deltaResultName $descriptor for $target');
@@ -667,36 +665,43 @@
     if (deltaResult == DeltaResult.INVALIDATE_NO_DELTA) {
       delta = null;
     }
-    if (deltaResult == null ||
+    if (deltaResult == DeltaResult.INVALIDATE_KEEP_DEPENDENCIES) {
+      thisData.value = descriptor.defaultValue;
+      thisData.state = CacheState.INVALID;
+    } else if (deltaResult == null ||
         deltaResult == DeltaResult.INVALIDATE ||
         deltaResult == DeltaResult.INVALIDATE_NO_DELTA) {
       _resultMap.remove(descriptor);
-//      {
-//        String indent = '  ' * level;
-//        print('[$id]$indent invalidate $descriptor for $target');
-//      }
-    }
-    // Stop depending on other results.
-    if (deltaResult != DeltaResult.KEEP_CONTINUE) {
-      TargetedResult thisResult = new TargetedResult(target, descriptor);
-      List<AnalysisCache> caches = _partition.containingCaches;
-      int cacheLength = caches.length;
-      List<TargetedResult> results = thisData.dependedOnResults;
-      int resultLength = results.length;
-      for (int i = 0; i < resultLength; i++) {
-        TargetedResult dependedOnResult = results[i];
-        for (int j = 0; j < cacheLength; j++) {
-          AnalysisCache cache = caches[j];
-          CacheEntry entry = cache.get(dependedOnResult.target);
-          if (entry != null) {
-            ResultData data =
-                entry.getResultDataOrNull(dependedOnResult.result);
-            if (data != null) {
-              data.dependentResults.remove(thisResult);
+      // Stop depending on other results.
+      if (deltaResult != DeltaResult.KEEP_CONTINUE) {
+        TargetedResult thisResult = new TargetedResult(target, descriptor);
+        List<AnalysisCache> caches = _partition.containingCaches;
+        int cacheLength = caches.length;
+        List<TargetedResult> results = thisData.dependedOnResults;
+        int resultLength = results.length;
+        for (int i = 0; i < resultLength; i++) {
+          TargetedResult dependedOnResult = results[i];
+          for (int j = 0; j < cacheLength; j++) {
+            AnalysisCache cache = caches[j];
+            CacheEntry entry = cache.get(dependedOnResult.target);
+            if (entry != null) {
+              ResultData data =
+                  entry.getResultDataOrNull(dependedOnResult.result);
+              if (data != null) {
+                data.dependentResults.remove(thisResult);
+              }
             }
           }
         }
       }
+//      if (deltaResult == null) {
+//        String indent = '  ' * level;
+//        print('[$id]$indent invalidate $descriptor for $target');
+//        if ('$descriptor for $target' ==
+//            'READY_LIBRARY_ELEMENT2 for /Users/scheglov/tmp/limited-invalidation/async/lib/async.dart') {
+//          print('interesting');
+//        }
+//      }
     }
     // Invalidate results that depend on this result.
     _invalidateDependentResults(id, thisData, delta, level + 1);
@@ -1269,11 +1274,17 @@
 enum DeltaResult {
   /**
    * Invalidate this result and continue visiting dependent results
-   * with this [Delta].
+   * with this [Delta]. Remove the result and all its dependencies.
    */
   INVALIDATE,
 
   /**
+   * Invalidate this result and continue visiting dependent results
+   * with this [Delta]. Keep the dependencies of this result.
+   */
+  INVALIDATE_KEEP_DEPENDENCIES,
+
+  /**
    * Invalidate this result and stop using this [Delta], so unconditionally
    * invalidate all the dependent results.
    */
diff --git a/pkg/analyzer/lib/src/context/context.dart b/pkg/analyzer/lib/src/context/context.dart
index 7ef0108..ca3eebc 100644
--- a/pkg/analyzer/lib/src/context/context.dart
+++ b/pkg/analyzer/lib/src/context/context.dart
@@ -298,8 +298,7 @@
             options.enableStrictCallChecks ||
         this._options.enableGenericMethods != options.enableGenericMethods ||
         this._options.enableAsync != options.enableAsync ||
-        this._options.enableSuperMixins != options.enableSuperMixins ||
-        this._options.enableTrailingCommas != options.enableTrailingCommas;
+        this._options.enableSuperMixins != options.enableSuperMixins;
     int cacheSize = options.cacheSize;
     if (this._options.cacheSize != cacheSize) {
       this._options.cacheSize = cacheSize;
@@ -315,7 +314,6 @@
     this._options.enableAsync = options.enableAsync;
     this._options.enableSuperMixins = options.enableSuperMixins;
     this._options.enableTiming = options.enableTiming;
-    this._options.enableTrailingCommas = options.enableTrailingCommas;
     this._options.hint = options.hint;
     this._options.incremental = options.incremental;
     this._options.incrementalApi = options.incrementalApi;
@@ -1859,9 +1857,10 @@
         // TODO(scheglov) Incorrect implementation in general.
         entry.setState(TOKEN_STREAM, CacheState.FLUSHED);
         entry.setState(PARSED_UNIT, CacheState.FLUSHED);
-        List<Source> librarySources = getLibrariesContaining(source);
-        if (librarySources.length == 1) {
-          Source librarySource = librarySources[0];
+        SourceKind sourceKind = getKindOf(source);
+        List<Source> partSources = getResult(source, INCLUDED_PARTS);
+        if (sourceKind == SourceKind.LIBRARY && partSources.isEmpty) {
+          Source librarySource = source;
           // Try to find an old unit which has element model.
           CacheEntry unitEntry =
               getCacheEntry(new LibrarySpecificUnit(librarySource, source));
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 97defa6..6be013c 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -398,7 +398,7 @@
   @override
   void set correspondingPropagatedParameters(
       List<ParameterElement> parameters) {
-    if (parameters.length != _arguments.length) {
+    if (parameters != null && parameters.length != _arguments.length) {
       throw new IllegalArgumentException(
           "Expected ${_arguments.length} parameters, not ${parameters.length}");
     }
@@ -410,7 +410,7 @@
 
   @override
   void set correspondingStaticParameters(List<ParameterElement> parameters) {
-    if (parameters.length != _arguments.length) {
+    if (parameters != null && parameters.length != _arguments.length) {
       throw new IllegalArgumentException(
           "Expected ${_arguments.length} parameters, not ${parameters.length}");
     }
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 6c2cd97..b2c10e2 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -698,16 +698,12 @@
     if (staticInvokeType != null) {
       List<ParameterElement> parameters =
           _computeCorrespondingParameters(argumentList, staticInvokeType);
-      if (parameters != null) {
-        argumentList.correspondingStaticParameters = parameters;
-      }
+      argumentList.correspondingStaticParameters = parameters;
     }
     if (propagatedInvokeType != null) {
       List<ParameterElement> parameters =
           _computeCorrespondingParameters(argumentList, propagatedInvokeType);
-      if (parameters != null) {
-        argumentList.correspondingPropagatedParameters = parameters;
-      }
+      argumentList.correspondingPropagatedParameters = parameters;
     }
     //
     // Then check for error conditions.
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index 9cd12c7..bd08147 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -1087,12 +1087,6 @@
   bool get enableTiming;
 
   /**
-   * Return `true` to enable trailing commas in parameter and argument lists
-   * (sdk#26647).
-   */
-  bool get enableTrailingCommas;
-
-  /**
    * A flag indicating whether finer grained dependencies should be used
    * instead of just source level dependencies.
    *
@@ -1347,7 +1341,6 @@
     enableGenericMethods = options.enableGenericMethods;
     enableSuperMixins = options.enableSuperMixins;
     enableTiming = options.enableTiming;
-    enableTrailingCommas = options.enableTrailingCommas;
     generateImplicitErrors = options.generateImplicitErrors;
     generateSdkErrors = options.generateSdkErrors;
     hint = options.hint;
diff --git a/pkg/analyzer/lib/src/generated/parser.dart b/pkg/analyzer/lib/src/generated/parser.dart
index f63bb70..fcf9b01 100644
--- a/pkg/analyzer/lib/src/generated/parser.dart
+++ b/pkg/analyzer/lib/src/generated/parser.dart
@@ -2189,12 +2189,6 @@
   bool parseGenericMethodComments = false;
 
   /**
-   * A flag indicating whether the parser is to parse trailing commas in
-   * parameter and argument lists (sdk#26647).
-   */
-  bool parseTrailingCommas = false;
-
-  /**
    * Initialize a newly created parser to parse tokens in the given [_source]
    * and to report any errors that are found to the given [_errorListener].
    */
@@ -2330,7 +2324,7 @@
       bool foundNamedArgument = argument is NamedExpression;
       bool generatedError = false;
       while (_optional(TokenType.COMMA)) {
-        if (parseTrailingCommas && _matches(TokenType.CLOSE_PAREN)) {
+        if (_matches(TokenType.CLOSE_PAREN)) {
           break;
         }
         argument = parseArgument();
@@ -6146,7 +6140,7 @@
       type = _currentToken.type;
 
       // Advance past trailing commas as appropriate.
-      if (parseTrailingCommas && type == TokenType.COMMA) {
+      if (type == TokenType.COMMA) {
         // Only parse commas trailing normal (non-positional/named) params.
         if (rightSquareBracket == null && rightCurlyBracket == null) {
           Token next = _peek();
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index b662891..0705295 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -2855,10 +2855,12 @@
  * The resulting AST must have everything resolved that would have been resolved
  * by a [DirectiveElementBuilder].
  */
-class DirectiveResolver extends SimpleAstVisitor with ExistingElementResolver {
+class DirectiveResolver extends SimpleAstVisitor {
+  LibraryElement _enclosingLibrary;
+
   @override
   void visitCompilationUnit(CompilationUnit node) {
-    _enclosingUnit = node.element;
+    _enclosingLibrary = node.element.library;
     for (Directive directive in node.directives) {
       directive.accept(this);
     }
@@ -2866,124 +2868,31 @@
 
   @override
   void visitExportDirective(ExportDirective node) {
-    String uri = _getStringValue(node.uri);
-    if (uri != null) {
-      LibraryElement library = _enclosingUnit.library;
-      Source source = _enclosingUnit.context.sourceFactory
-          .resolveUri(_enclosingUnit.source, uri);
-      ExportElement exportElement = _findExport(node, library.exports, source);
-      node.element = exportElement;
-    } else {
-      node.element = null;
+    int nodeOffset = node.offset;
+    node.element = null;
+    for (ExportElement element in _enclosingLibrary.exports) {
+      if (element.nameOffset == nodeOffset) {
+        node.element = element;
+        break;
+      }
     }
   }
 
   @override
   void visitImportDirective(ImportDirective node) {
-    String uri = _getStringValue(node.uri);
-    if (uri != null) {
-      LibraryElement library = _enclosingUnit.library;
-      Source source = _enclosingUnit.context.sourceFactory
-          .resolveUri(_enclosingUnit.source, uri);
-      ImportElement importElement = _findImport(node, library.imports, source);
-      node.element = importElement;
-    } else {
-      node.element = null;
+    int nodeOffset = node.offset;
+    node.element = null;
+    for (ImportElement element in _enclosingLibrary.imports) {
+      if (element.nameOffset == nodeOffset) {
+        node.element = element;
+        break;
+      }
     }
   }
 
   @override
   void visitLibraryDirective(LibraryDirective node) {
-    node.element = _enclosingUnit.library;
-  }
-
-  /**
-   * Return the export element from the given list of [exports] whose library
-   * has the given [source]. Throw an [ElementMismatchException] if an element
-   * corresponding to the identifier cannot be found.
-   */
-  ExportElement _findExport(
-      ExportDirective node, List<ExportElement> exports, Source source) {
-    if (source == null) {
-      return null;
-    }
-    int length = exports.length;
-    for (int i = 0; i < length; i++) {
-      ExportElement export = exports[i];
-      if (export.exportedLibrary.source == source) {
-        // Must have the same offset.
-        if (export.nameOffset != node.offset) {
-          continue;
-        }
-        // In general we should also match combinators.
-        // But currently we invalidate element model on any directive change.
-        // So, either the combinators are the same, or we build new elements.
-        return export;
-      }
-    }
-    if (!_enclosingUnit.context.exists(source)) {
-      return null;
-    }
-    _mismatch("Could not find export element for '$source'", node);
-    return null; // Never reached
-  }
-
-  /**
-   * Return the import element from the given list of [imports] whose library
-   * has the given [source]. Throw an [ElementMismatchException] if an element
-   * corresponding to the [source] cannot be found.
-   */
-  ImportElement _findImport(
-      ImportDirective node, List<ImportElement> imports, Source source) {
-    if (source == null) {
-      return null;
-    }
-    SimpleIdentifier prefix = node.prefix;
-    bool foundSource = false;
-    int length = imports.length;
-    for (int i = 0; i < length; i++) {
-      ImportElement element = imports[i];
-      if (element.importedLibrary.source == source) {
-        foundSource = true;
-        // Must have the same offset.
-        if (element.nameOffset != node.offset) {
-          continue;
-        }
-        // Must have the same prefix.
-        if (element.prefix?.displayName != prefix?.name) {
-          continue;
-        }
-        // In general we should also match combinators.
-        // But currently we invalidate element model on any directive change.
-        // So, either the combinators are the same, or we build new elements.
-        return element;
-      }
-    }
-    if (!_enclosingUnit.context.exists(source)) {
-      return null;
-    }
-    if (foundSource) {
-      if (prefix == null) {
-        _mismatch(
-            "Could not find import element for '$source' with no prefix", node);
-      }
-      _mismatch(
-          "Could not find import element for '$source' with prefix ${prefix.name}",
-          node);
-    }
-    _mismatch("Could not find any import element for '$source'", node);
-    return null; // Never reached
-  }
-
-  /**
-   * Return the value of the given string [literal], or `null` if the string is
-   * not a constant string without any string interpolation.
-   */
-  String _getStringValue(StringLiteral literal) {
-    if (literal is StringInterpolation) {
-      return null;
-    }
-    return literal.stringValue;
+    node.element = _enclosingLibrary;
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index 0055866..062ce82 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -9,9 +9,11 @@
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/resynthesize.dart';
 import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
 import 'package:analyzer/task/dart.dart';
 import 'package:analyzer/task/model.dart';
 import 'package:path/path.dart' as pathos;
@@ -182,6 +184,18 @@
           return true;
         }
         return false;
+      } else if (result == CONTAINING_LIBRARIES) {
+        List<String> libraryUriStrings =
+            _dataStore.getContainingLibraryUris(uriString);
+        if (libraryUriStrings != null) {
+          List<Source> librarySources = libraryUriStrings
+              .map((libraryUriString) =>
+                  context.sourceFactory.resolveUri(target, libraryUriString))
+              .toList(growable: false);
+          entry.setValue(result, librarySources, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+        return false;
       }
     } else if (target is LibrarySpecificUnit) {
       if (result == CREATED_RESOLVED_UNIT1 ||
@@ -294,6 +308,31 @@
     }
   }
 
+  /**
+   * Return a list of absolute URIs of the libraries that contain the unit with
+   * the given [unitUriString], or `null` if no such library is in the store.
+   */
+  List<String> getContainingLibraryUris(String unitUriString) {
+    // The unit is the defining unit of a library.
+    if (linkedMap.containsKey(unitUriString)) {
+      return <String>[unitUriString];
+    }
+    // Check every unlinked unit whether it uses [unitUri] as a part.
+    List<String> libraryUriStrings = <String>[];
+    unlinkedMap.forEach((unlinkedUnitUriString, unlinkedUnit) {
+      Uri libraryUri = FastUri.parse(unlinkedUnitUriString);
+      for (String partUriString in unlinkedUnit.publicNamespace.parts) {
+        Uri partUri = FastUri.parse(partUriString);
+        String partAbsoluteUriString =
+            resolveRelativeUri(libraryUri, partUri).toString();
+        if (partAbsoluteUriString == unitUriString) {
+          libraryUriStrings.add(unlinkedUnitUriString);
+        }
+      }
+    });
+    return libraryUriStrings.isNotEmpty ? libraryUriStrings : null;
+  }
+
   void _fillMaps(String path) {
     io.File file = new io.File(path);
     List<int> buffer = file.readAsBytesSync();
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 6860903..0d3981f 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -2656,6 +2656,15 @@
         }
       }
     }
+    for (String name in references.extendedUsedUnnamedConstructorNames) {
+      for (ClassElementDelta classDelta in changedClasses.values) {
+        if (classDelta.name == name && classDelta.hasUnnamedConstructorChange) {
+          _log(() =>
+              '$refLibrary is affected by the default constructor of $name');
+          return true;
+        }
+      }
+    }
     return false;
   }
 
@@ -2717,6 +2726,12 @@
   @override
   DeltaResult validate(InternalAnalysisContext context, AnalysisTarget target,
       ResultDescriptor descriptor, Object value) {
+    // Always invalidate compounding results.
+    if (descriptor == LIBRARY_ELEMENT4 ||
+        descriptor == READY_LIBRARY_ELEMENT6 ||
+        descriptor == READY_LIBRARY_ELEMENT7) {
+      return DeltaResult.INVALIDATE_KEEP_DEPENDENCIES;
+    }
     // Prepare target source.
     Source targetUnit = target.source;
     Source targetLibrary = target.librarySource;
@@ -2759,7 +2774,7 @@
         return DeltaResult.INVALIDATE;
       }
       if (librariesWithAllValidResults.contains(targetLibrary)) {
-        return DeltaResult.STOP;
+        return DeltaResult.KEEP_CONTINUE;
       }
       // The library is almost, but not completely valid.
       // Some error results are invalid.
@@ -2784,7 +2799,7 @@
         return DeltaResult.KEEP_CONTINUE;
       }
       librariesWithAllValidResults.add(targetLibrary);
-      return DeltaResult.STOP;
+      return DeltaResult.KEEP_CONTINUE;
     }
     // We don't know what to do with the given target, invalidate it.
     return DeltaResult.INVALIDATE;
@@ -4047,7 +4062,6 @@
     parser.parseFunctionBodies = options.analyzeFunctionBodiesPredicate(source);
     parser.parseGenericMethods = options.enableGenericMethods;
     parser.parseGenericMethodComments = options.strongMode;
-    parser.parseTrailingCommas = options.enableTrailingCommas;
     CompilationUnit unit = parser.parseCompilationUnit(tokenStream);
     unit.lineInfo = lineInfo;
 
@@ -4783,6 +4797,13 @@
   final Map<String, Set<String>> superToSubs = <String, Set<String>>{};
 
   /**
+   * The names of extended classes for which the unnamed constructor is
+   * invoked. Because we cannot use the name of the constructor to identify
+   * whether the unit is affected, we need to use the class name.
+   */
+  final Set<String> extendedUsedUnnamedConstructorNames = new Set<String>();
+
+  /**
    * The names of instantiated classes.
    *
    * If one of these classes changes its set of members, it might change
@@ -4818,6 +4839,7 @@
   final Set<String> importPrefixNames = new Set<String>();
   final ReferencedNames names;
 
+  String enclosingSuperClassName;
   ReferencedNamesScope scope = new ReferencedNamesScope(null);
 
   int localLevel = 0;
@@ -4847,6 +4869,8 @@
     try {
       scope = new ReferencedNamesScope.forClass(scope, node);
       dependsOn = new Set<String>();
+      enclosingSuperClassName =
+          _getSimpleName(node.extendsClause?.superclass?.name);
       super.visitClassDeclaration(node);
       String className = node.name.name;
       names.userToDependsOn[className] = dependsOn;
@@ -4854,11 +4878,22 @@
       _addSuperNames(className, node.withClause?.mixinTypes);
       _addSuperNames(className, node.implementsClause?.interfaces);
     } finally {
+      enclosingSuperClassName = null;
       dependsOn = null;
       scope = outerScope;
     }
   }
 
+  static String _getSimpleName(Identifier identifier) {
+    if (identifier is SimpleIdentifier) {
+      return identifier.name;
+    }
+    if (identifier is PrefixedIdentifier) {
+      return identifier.identifier.name;
+    }
+    return null;
+  }
+
   @override
   visitClassTypeAlias(ClassTypeAlias node) {
     ReferencedNamesScope outerScope = scope;
@@ -4888,6 +4923,14 @@
   }
 
   @override
+  visitSuperConstructorInvocation(SuperConstructorInvocation node) {
+    if (node.constructorName == null && enclosingSuperClassName != null) {
+      names.extendedUsedUnnamedConstructorNames.add(enclosingSuperClassName);
+    }
+    super.visitSuperConstructorInvocation(node);
+  }
+
+  @override
   visitConstructorName(ConstructorName node) {
     if (node.parent is! ConstructorDeclaration) {
       super.visitConstructorName(node);
diff --git a/pkg/analyzer/lib/src/task/dart_work_manager.dart b/pkg/analyzer/lib/src/task/dart_work_manager.dart
index 6b2a96e..f3dd0b6 100644
--- a/pkg/analyzer/lib/src/task/dart_work_manager.dart
+++ b/pkg/analyzer/lib/src/task/dart_work_manager.dart
@@ -202,6 +202,7 @@
       }
     }
     List<Source> libraries = partLibrariesMap[part];
+    libraries ??= _getLibrariesContainingPartFromResultProvider(part);
     return libraries?.toList() ?? Source.EMPTY_LIST;
   }
 
@@ -350,11 +351,28 @@
     }
   }
 
+  /**
+   * The given unit was incrementally resolved. Some of its error results might
+   * have been invalidated, so we schedule it for computing errors.
+   */
   void unitIncrementallyResolved(Source librarySource, Source unitSource) {
     librarySourceQueue.add(librarySource);
   }
 
   /**
+   * Ask the [context]'s result provider for [CONTAINING_LIBRARIES].
+   * Return the list of containing libraries, or `null` if unknown.
+   */
+  List<Source> _getLibrariesContainingPartFromResultProvider(Source part) {
+    CacheEntry cacheEntry = context.getCacheEntry(part);
+    bool knows = context.aboutToComputeResult(cacheEntry, CONTAINING_LIBRARIES);
+    if (knows) {
+      return cacheEntry.getValue(CONTAINING_LIBRARIES);
+    }
+    return null;
+  }
+
+  /**
    * Return the SDK [DartWorkManager] or this one.
    */
   DartWorkManager _getSdkDartWorkManager() {
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index 7e5444d..f3247b6 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -686,9 +686,6 @@
   _UpdateElementOffsetsVisitor(this.map);
 
   void visitElement(Element element) {
-    if (element is LibraryElement) {
-      return;
-    }
     if (element is ElementImpl) {
       // name offset
       {
@@ -703,6 +700,10 @@
         }
         element.nameOffset = newOffset;
       }
+      // stop here for LibraryElement
+      if (element is LibraryElementImpl) {
+        return;
+      }
       // code range
       {
         int oldOffset = element.codeOffset;
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index a101147..6cf5585 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -49,7 +49,6 @@
   static const String enableGenericMethods = 'enableGenericMethods';
   static const String enableStrictCallChecks = 'enableStrictCallChecks';
   static const String enableSuperMixins = 'enableSuperMixins';
-  static const String enableTrailingCommas = 'enableTrailingCommas';
 
   static const String errors = 'errors';
   static const String exclude = 'exclude';
@@ -88,8 +87,7 @@
     enableAsync,
     enableGenericMethods,
     enableStrictCallChecks,
-    enableSuperMixins,
-    enableTrailingCommas
+    enableSuperMixins
   ];
 }
 
@@ -504,14 +502,6 @@
         context.analysisOptions = options;
       }
     }
-    if (feature == AnalyzerOptions.enableTrailingCommas) {
-      if (isTrue(value)) {
-        AnalysisOptionsImpl options =
-            new AnalysisOptionsImpl.from(context.analysisOptions);
-        options.enableTrailingCommas = true;
-        context.analysisOptions = options;
-      }
-    }
     if (feature == AnalyzerOptions.enableGenericMethods) {
       if (isTrue(value)) {
         AnalysisOptionsImpl options =
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 1eccd93..42691d9 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -11,7 +11,7 @@
   glob: ^1.0.3
   isolate: ^0.2.2
   html: ^0.12.0
-  package_config: ^0.1.5
+  package_config: '>=0.1.5 <2.0.0'
   path: '>=0.9.0 <2.0.0'
   plugin: ^0.2.0
   watcher: '>=0.9.6 <0.10.0'
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index e74309d..ee61b20 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -1197,21 +1197,11 @@
   }
 
   void test_extraCommaInParameterList() {
-    parseTrailingCommas = true;
-    parse4("parseFormalParameterList", "(int a, , int b)",
-        [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]);
-    parseTrailingCommas = false;
     parse4("parseFormalParameterList", "(int a, , int b)",
         [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_extraCommaTrailingNamedParameterGroup() {
-    parseTrailingCommas = true;
-    parse4("parseFormalParameterList", "({int b},)", [
-      ParserErrorCode.MISSING_IDENTIFIER,
-      ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
-    ]);
-    parseTrailingCommas = false;
     parse4("parseFormalParameterList", "({int b},)", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
@@ -1219,12 +1209,6 @@
   }
 
   void test_extraCommaTrailingPositionalParameterGroup() {
-    parseTrailingCommas = true;
-    parse4("parseFormalParameterList", "([int b],)", [
-      ParserErrorCode.MISSING_IDENTIFIER,
-      ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
-    ]);
-    parseTrailingCommas = false;
     parse4("parseFormalParameterList", "([int b],)", [
       ParserErrorCode.MISSING_IDENTIFIER,
       ParserErrorCode.NORMAL_BEFORE_OPTIONAL_PARAMETERS
@@ -1232,12 +1216,8 @@
   }
 
   void test_extraTrailingCommaInParameterList() {
-    parseTrailingCommas = true;
     parse4("parseFormalParameterList", "(a,,)",
         [ParserErrorCode.MISSING_IDENTIFIER]);
-    parseTrailingCommas = false;
-    parse4("parseFormalParameterList", "(a,,)",
-        [ParserErrorCode.MISSING_IDENTIFIER, ParserErrorCode.EXPECTED_TOKEN]);
   }
 
   void test_factoryTopLevelDeclaration_class() {
@@ -1740,7 +1720,6 @@
   }
 
   void test_missingIdentifierForParameterGroup() {
-    parseTrailingCommas = true;
     parse4("parseFormalParameterList", "(,)",
         [ParserErrorCode.MISSING_IDENTIFIER]);
   }
@@ -2807,12 +2786,6 @@
   bool enableGenericMethodComments = false;
 
   /**
-   * A flag indicating whether parsing trailing commas in parameter and argument
-   * lists should be enabled for this test.
-   */
-  bool parseTrailingCommas = false;
-
-  /**
    * Return a CommentAndMetadata object with the given values that can be used for testing.
    *
    * @param comment the comment to be wrapped in the object
@@ -2866,7 +2839,6 @@
     parser.parseGenericMethods = enableGenericMethods;
     parser.parseGenericMethodComments = enableGenericMethodComments;
     parser.parseFunctionBodies = parseFunctionBodies;
-    parser.parseTrailingCommas = parseTrailingCommas;
     Object result =
         invokeParserMethodImpl(parser, methodName, objects, tokenStream);
     //
@@ -4793,7 +4765,6 @@
   }
 
   void test_parseArgumentList_trailing_comma() {
-    parseTrailingCommas = true;
     ArgumentList argumentList = parse4("parseArgumentList", "(x, y, z,)");
     NodeList<Expression> arguments = argumentList.arguments;
     expect(arguments, hasLength(3));
@@ -5982,7 +5953,6 @@
   }
 
   void test_parseClassMember_method_trailing_commas() {
-    parseTrailingCommas = true;
     MethodDeclaration method =
         parse("parseClassMember", <Object>["C"], "void f(int x, int y,) {}");
     expect(method.documentationComment, isNull);
@@ -7899,7 +7869,6 @@
   }
 
   void test_parseFormalParameterList_named_trailing_comma() {
-    parseTrailingCommas = true;
     FormalParameterList parameterList =
         parse4("parseFormalParameterList", "(A a, {B b,})");
     expect(parameterList.leftParenthesis, isNotNull);
@@ -7950,7 +7919,6 @@
   }
 
   void test_parseFormalParameterList_normal_single_trailing_comma() {
-    parseTrailingCommas = true;
     FormalParameterList parameterList =
         parse4("parseFormalParameterList", "(A a,)");
     expect(parameterList.leftParenthesis, isNotNull);
@@ -7981,7 +7949,6 @@
   }
 
   void test_parseFormalParameterList_positional_trailing_comma() {
-    parseTrailingCommas = true;
     FormalParameterList parameterList =
         parse4("parseFormalParameterList", "(A a, [B b,])");
     expect(parameterList.leftParenthesis, isNotNull);
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index 28dceb7..0030f98 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -2850,6 +2850,28 @@
 ''');
   }
 
+  void test_class_constructor_named_parameters_change_usedSuper() {
+    // Update a.dart: change A.named().
+    //   b.dart is invalid, because it references A.named().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A.named(int a);
+}
+''',
+        r'''
+class A {
+  A.named(String a);
+}
+''',
+        r'''
+import 'a.dart';
+class B extends A {
+  B() : super.named(42);
+}
+''');
+  }
+
   void test_class_constructor_named_parameters_remove() {
     // Update a.dart: remove a new parameter of A.named().
     //   b.dart is invalid, because it references A.named().
@@ -2916,6 +2938,56 @@
 ''');
   }
 
+  void test_class_constructor_unnamed_parameters_change_notUsedSuper() {
+    // Update a.dart: change A().
+    //   Resolution of b.dart is valid, because it does not reference A().
+    //   Hints and verify errors are invalid, because it extends A.
+    // TODO(scheglov) we could keep valid hints and verify errors,
+    // because only constructor is changed - this cannot add/remove
+    // inherited unimplemented members.
+    _verifyTwoLibrariesInvalidHintsVerifyErrors(
+        r'''
+class A {
+  A(int a);
+  A.named(int a);
+}
+''',
+        r'''
+class A {
+  A(String a);
+  A.named(int a);
+}
+''',
+        r'''
+import 'a.dart';
+class B extends A {
+  B() : super.named(42);
+}
+''');
+  }
+
+  void test_class_constructor_unnamed_parameters_change_usedSuper() {
+    // Update a.dart: change A().
+    //   b.dart is invalid, because it references A().
+    _verifyTwoLibrariesInvalidatesResolution(
+        r'''
+class A {
+  A(int a);
+}
+''',
+        r'''
+class A {
+  A(String a);
+}
+''',
+        r'''
+import 'a.dart';
+class B extends A {
+  B() : super(42);
+}
+''');
+  }
+
   void test_class_constructor_unnamed_parameters_remove() {
     // Update a.dart: change A().
     //   b.dart is invalid, because it references A().
@@ -2962,8 +3034,8 @@
   }
 
   void test_class_constructor_unnamed_remove_used() {
-    // Update a.dart: remove A.named().
-    //   b.dart is invalid, because it references A.named().
+    // Update a.dart: remove A().
+    //   b.dart is invalid, because it references A().
     _verifyTwoLibrariesInvalidatesResolution(
         r'''
 class A {
@@ -3493,6 +3565,72 @@
     expect(context.getErrors(b).errors, hasLength(1));
   }
 
+  void test_sequence_clearParameterElements() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {
+  foo(int p) {}
+}
+final a = new A();
+main() {
+  a.foo(42);
+}
+''');
+    _performPendingAnalysisTasks();
+    Expression find42() {
+      CompilationUnit unit =
+          context.getResult(new LibrarySpecificUnit(a, a), RESOLVED_UNIT);
+      ExpressionStatement statement =
+          AstFinder.getStatementsInTopLevelFunction(unit, 'main').single;
+      MethodInvocation invocation = statement.expression;
+      return invocation.argumentList.arguments[0];
+    }
+    {
+      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'.
+    context.setContents(
+        a,
+        r'''
+class A {
+  foo(int p) {}
+}
+final A a = new A();
+main() {
+  a.foo(42);
+}
+''');
+    _performPendingAnalysisTasks();
+    {
+      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'.
+    context.setContents(
+        a,
+        r'''
+class A {
+  foo(int p) {}
+}
+final a = new A();
+main() {
+  a.foo(42);
+}
+''');
+    _performPendingAnalysisTasks();
+    {
+      Expression argument = find42();
+      expect(argument.staticParameterElement, isNull);
+      expect(argument.propagatedParameterElement, isNotNull);
+    }
+  }
+
   void test_sequence_closureParameterTypesPropagation() {
     Source a = addSource(
         '/a.dart',
@@ -3522,6 +3660,175 @@
     expect(parameterName.propagatedType, context.typeProvider.intType);
   }
 
+  void test_sequence_compoundingResults_exportNamespace() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A<T> {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+export 'a.dart';
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+import 'b.dart';
+main() {
+  new A<int>();
+}
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(c).errors, isEmpty);
+    // Update a.dart, so that `A<T>` has a type bound.
+    //   This should invalidate export namespace for b.dart.
+    //   Currently we invalidate the whole LIBRARY_ELEMENT4.
+    //   So, c.dart will see the new `A<T extends B>` and report an error.
+    context.setContents(
+        a,
+        r'''
+class A<T extends B> {}
+class B {}
+''');
+    _assertInvalid(b, LIBRARY_ELEMENT4);
+    // Analyze and validate that a new error is reported.
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(c).errors, hasLength(1));
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+    _assertValid(c, LIBRARY_ERRORS_READY);
+  }
+
+  void test_sequence_compoundingResults_invalidateButKeepDependency() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+import 'b.dart';
+class A {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+import 'a.dart';
+import 'c.dart';
+class B {}
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+class C {}
+''');
+    Source d = addSource(
+        '/d.dart',
+        r'''
+export 'b.dart';
+''');
+    _performPendingAnalysisTasks();
+    expect(context.getErrors(c).errors, isEmpty);
+    // Update: a.dart (limited) and b.dart (limited).
+    //   This should invalidate LIBRARY_ELEMENT4 in d.dart, but it should be
+    //   done in a way that keep dependency of other results od d.dart on
+    //   LIBRARY_ELEMENT4 of d.dart, so that when we perform unlimited
+    //   invalidation of c.dart, this makes d.dart invalid.
+    context.setContents(
+        a,
+        r'''
+import 'b.dart';
+class A2 {}
+''');
+    context.setContents(
+        b,
+        r'''
+import 'a.dart';
+import 'c.dart';
+class B2 {}
+''');
+    context.setContents(
+        c,
+        r'''
+import 'dart:async';
+class C {}
+''');
+    _assertInvalid(d, LIBRARY_ELEMENT4);
+    _assertInvalid(d, LIBRARY_ERRORS_READY);
+    // Analyze and validate that a new error is reported.
+    _performPendingAnalysisTasks();
+    _assertValid(a, EXPORT_SOURCE_CLOSURE);
+    _assertValid(b, EXPORT_SOURCE_CLOSURE);
+    _assertValid(c, EXPORT_SOURCE_CLOSURE);
+    _assertValid(d, EXPORT_SOURCE_CLOSURE);
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+    _assertValid(c, LIBRARY_ERRORS_READY);
+    _assertValid(d, LIBRARY_ERRORS_READY);
+  }
+
+  void test_sequence_compoundingResults_resolvedTypeNames() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+class A {}
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+class B<T> {
+  B(p);
+}
+''');
+    Source c = addSource(
+        '/c.dart',
+        r'''
+export 'a.dart';
+export 'b.dart';
+''');
+    Source d = addSource(
+        '/d.dart',
+        r'''
+import 'c.dart';
+main() {
+  new B<int>(null);
+}
+''');
+    _performPendingAnalysisTasks();
+    // Update a.dart and b.dart
+    //   This should invalidate most results in a.dart and b.dart
+    //
+    //   This should also invalidate "compounding" results in c.dart, such as
+    //   READY_LIBRARY_ELEMENT6, which represent a state of the whole source
+    //   closure, not a result of this single unit or a library.
+    //
+    //   The reason is that although type names (RESOLVED_UNIT5) b.dart will be
+    //   eventually resolved and set into b.dart elements, it may happen
+    //   after we attempted to re-resolve c.dart, which created Member(s), and
+    //   attempts to use elements without types set.
+    context.setContents(
+        a,
+        r'''
+class A2 {}
+''');
+    context.setContents(
+        b,
+        r'''
+class B<T> {
+  B(T p);
+}
+''');
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForChangedLibrary(b);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalid(c, READY_LIBRARY_ELEMENT6);
+    _assertInvalid(c, READY_LIBRARY_ELEMENT7);
+    // Analyze and validate that all results are valid.
+    _performPendingAnalysisTasks();
+    _assertValid(a, LIBRARY_ERRORS_READY);
+    _assertValid(b, LIBRARY_ERRORS_READY);
+    _assertValid(c, LIBRARY_ERRORS_READY);
+    _assertValid(d, LIBRARY_ERRORS_READY);
+  }
+
   void test_sequence_dependenciesWithCycles() {
     Source a = addSource(
         '/a.dart',
@@ -3795,6 +4102,64 @@
     expect(context.getErrors(b).errors, hasLength(0));
   }
 
+  void test_sequence_parts_disableForPart() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+library my_lib;
+part 'b.dart';
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+part of my_lib;
+class A {}
+''');
+    _performPendingAnalysisTasks();
+    // Update b.dart - it is a part, which we don't support.
+    // So, invalidate everything.
+    context.setContents(
+        b,
+        r'''
+part of my_lib;
+class A {}
+class B {}
+''');
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(a, RESOLVED_UNIT2);
+    _assertInvalidUnits(b, RESOLVED_UNIT1);
+  }
+
+  void test_sequence_parts_disableWithPart() {
+    Source a = addSource(
+        '/a.dart',
+        r'''
+library my_lib;
+part 'b.dart';
+''');
+    Source b = addSource(
+        '/b.dart',
+        r'''
+part of my_lib;
+class B {}
+''');
+    _performPendingAnalysisTasks();
+    // Update a.dart - it is a library with a part, which we don't support.
+    // So, invalidate everything.
+    context.setContents(
+        a,
+        r'''
+library my_lib;
+part 'b.dart';
+class A {}
+''');
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertInvalid(b, LIBRARY_ERRORS_READY);
+    _assertInvalidUnits(a, RESOLVED_UNIT1);
+    _assertInvalidUnits(b, RESOLVED_UNIT1);
+  }
+
   void test_sequence_reorder_localFunctions() {
     Source a = addSource(
         '/a.dart',
@@ -4338,10 +4703,13 @@
   }
 
   void _assertValidAllLibraryUnitResults(Source source, {Source library}) {
-    for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
-      _assertValid(source, result);
-    }
     library ??= source;
+    for (ResultDescriptor<LibraryElement> result in LIBRARY_ELEMENT_RESULTS) {
+      if (result == LIBRARY_ELEMENT4) {
+        continue;
+      }
+      _assertValid(library, result);
+    }
     LibrarySpecificUnit target = new LibrarySpecificUnit(library, source);
     for (ResultDescriptor<CompilationUnit> result in RESOLVED_UNIT_RESULTS) {
       _assertValid(target, result);
@@ -4441,6 +4809,20 @@
     _assertInvalid(b, LIBRARY_ERRORS_READY);
     _assertInvalidUnits(b, RESOLVED_UNIT4);
   }
+
+  void _verifyTwoLibrariesInvalidHintsVerifyErrors(
+      String firstCodeA, String secondCodeA, String codeB) {
+    Source a = addSource('/a.dart', firstCodeA);
+    Source b = addSource('/b.dart', codeB);
+    _performPendingAnalysisTasks();
+    context.setContents(a, secondCodeA);
+    _assertValidForChangedLibrary(a);
+    _assertInvalid(a, LIBRARY_ERRORS_READY);
+    _assertValidForDependentLibrary(b);
+    _assertValidAllResolution(b);
+    _assertUnitValid(b, RESOLVE_UNIT_ERRORS);
+    _assertInvalidHintsVerifyErrors(b);
+  }
 }
 
 class _AnalysisContextImplTest_Source_exists_true extends TestSource {
diff --git a/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
new file mode 100644
index 0000000..e446d19
--- /dev/null
+++ b/pkg/analyzer/test/src/summary/package_bundle_reader_test.dart
@@ -0,0 +1,229 @@
+// 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:analyzer/src/context/cache.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/package_bundle_reader.dart';
+import 'package:analyzer/src/task/dart.dart';
+import 'package:analyzer/src/util/fast_uri.dart';
+import 'package:analyzer/task/dart.dart';
+import 'package:typed_mock/typed_mock.dart';
+import 'package:unittest/unittest.dart';
+
+import '../../reflective_tests.dart';
+
+main() {
+  groupSep = ' | ';
+  runReflectiveTests(ResynthesizerResultProviderTest);
+  runReflectiveTests(SummaryDataStoreTest);
+}
+
+UnlinkedPublicNamespace _namespaceWithParts(List<String> parts) {
+  UnlinkedPublicNamespace namespace = new _UnlinkedPublicNamespaceMock();
+  when(namespace.parts).thenReturn(parts);
+  return namespace;
+}
+
+@reflectiveTest
+class ResynthesizerResultProviderTest {
+  SourceFactory sourceFactory = new _SourceFactoryMock();
+  InternalAnalysisContext context = new _InternalAnalysisContextMock();
+  UniversalCachePartition cachePartition;
+
+  Source source1 = new _SourceMock('package:p1/u1.dart', '/p1/lib/u1.dart');
+  Source source2 = new _SourceMock('package:p1/u2.dart', '/p1/lib/u2.dart');
+  Source source3 = new _SourceMock('package:p2/u1.dart', '/p2/lib/u1.dart');
+  CacheEntry entry1;
+  CacheEntry entry2;
+  CacheEntry entry3;
+
+  PackageBundle bundle = new _PackageBundleMock();
+  UnlinkedUnit unlinkedUnit1 = new _UnlinkedUnitMock();
+  UnlinkedUnit unlinkedUnit2 = new _UnlinkedUnitMock();
+  LinkedLibrary linkedLibrary = new _LinkedLibraryMock();
+
+  SummaryDataStore dataStore = new SummaryDataStore(<String>[]);
+  _TestResynthesizerResultProvider provider;
+
+  void setUp() {
+    cachePartition = new UniversalCachePartition(context);
+    entry1 = new CacheEntry(source1);
+    entry2 = new CacheEntry(source2);
+    entry3 = new CacheEntry(source3);
+    cachePartition.put(entry1);
+    cachePartition.put(entry2);
+    cachePartition.put(entry3);
+
+    when(sourceFactory.resolveUri(anyObject, 'package:p1/u1.dart'))
+        .thenReturn(source1);
+    when(sourceFactory.resolveUri(anyObject, 'package:p1/u2.dart'))
+        .thenReturn(source2);
+    when(context.sourceFactory).thenReturn(sourceFactory);
+
+    when(bundle.unlinkedUnitUris)
+        .thenReturn(<String>['package:p1/u1.dart', 'package:p1/u2.dart']);
+    when(bundle.unlinkedUnits)
+        .thenReturn(<UnlinkedUnit>[unlinkedUnit1, unlinkedUnit2]);
+    when(bundle.linkedLibraryUris).thenReturn(<String>['package:p1/u1.dart']);
+    when(bundle.linkedLibraries).thenReturn(<LinkedLibrary>[linkedLibrary]);
+    dataStore.addBundle('/p1.ds', bundle);
+
+    when(unlinkedUnit1.publicNamespace)
+        .thenReturn(_namespaceWithParts(['package:p1/u2.dart']));
+    when(unlinkedUnit2.publicNamespace).thenReturn(_namespaceWithParts([]));
+
+    provider = new _TestResynthesizerResultProvider(context, dataStore);
+    provider.sourcesWithResults.add(source1);
+    provider.sourcesWithResults.add(source2);
+  }
+
+  test_compute_CONTAINING_LIBRARIES_librarySource() {
+    bool success = provider.compute(entry1, CONTAINING_LIBRARIES);
+    expect(success, isTrue);
+    expect(entry1.getValue(CONTAINING_LIBRARIES), unorderedEquals([source1]));
+  }
+
+  test_compute_CONTAINING_LIBRARIES_partSource() {
+    bool success = provider.compute(entry2, CONTAINING_LIBRARIES);
+    expect(success, isTrue);
+    expect(entry2.getValue(CONTAINING_LIBRARIES), unorderedEquals([source1]));
+  }
+
+  test_compute_SOURCE_KIND_librarySource() {
+    bool success = provider.compute(entry1, SOURCE_KIND);
+    expect(success, isTrue);
+    expect(entry1.getValue(SOURCE_KIND), SourceKind.LIBRARY);
+  }
+
+  test_compute_SOURCE_KIND_noResults() {
+    bool success = provider.compute(entry3, SOURCE_KIND);
+    expect(success, isFalse);
+    expect(entry3.getState(SOURCE_KIND), CacheState.INVALID);
+  }
+
+  test_compute_SOURCE_KIND_partSource() {
+    bool success = provider.compute(entry2, SOURCE_KIND);
+    expect(success, isTrue);
+    expect(entry2.getValue(SOURCE_KIND), SourceKind.PART);
+  }
+}
+
+@reflectiveTest
+class SummaryDataStoreTest {
+  SummaryDataStore dataStore = new SummaryDataStore(<String>[]);
+
+  PackageBundle bundle1 = new _PackageBundleMock();
+  PackageBundle bundle2 = new _PackageBundleMock();
+  UnlinkedUnit unlinkedUnit11 = new _UnlinkedUnitMock();
+  UnlinkedUnit unlinkedUnit12 = new _UnlinkedUnitMock();
+  UnlinkedUnit unlinkedUnit21 = new _UnlinkedUnitMock();
+  LinkedLibrary linkedLibrary1 = new _LinkedLibraryMock();
+  LinkedLibrary linkedLibrary2 = new _LinkedLibraryMock();
+
+  void setUp() {
+    // bundle1
+    when(unlinkedUnit11.publicNamespace)
+        .thenReturn(_namespaceWithParts(['package:p1/u2.dart']));
+    when(unlinkedUnit12.publicNamespace).thenReturn(_namespaceWithParts([]));
+    when(bundle1.unlinkedUnitUris)
+        .thenReturn(<String>['package:p1/u1.dart', 'package:p1/u2.dart']);
+    when(bundle1.unlinkedUnits)
+        .thenReturn(<UnlinkedUnit>[unlinkedUnit11, unlinkedUnit12]);
+    when(bundle1.linkedLibraryUris).thenReturn(<String>['package:p1/u1.dart']);
+    when(bundle1.linkedLibraries).thenReturn(<LinkedLibrary>[linkedLibrary1]);
+    dataStore.addBundle('/p1.ds', bundle1);
+    // bundle2
+    when(unlinkedUnit21.publicNamespace).thenReturn(_namespaceWithParts([]));
+    when(bundle2.unlinkedUnitUris).thenReturn(<String>['package:p2/u1.dart']);
+    when(bundle2.unlinkedUnits).thenReturn(<UnlinkedUnit>[unlinkedUnit21]);
+    when(bundle2.linkedLibraryUris).thenReturn(<String>['package:p2/u1.dart']);
+    when(bundle2.linkedLibraries).thenReturn(<LinkedLibrary>[linkedLibrary2]);
+    dataStore.addBundle('/p2.ds', bundle2);
+  }
+
+  test_addBundle() {
+    expect(dataStore.bundles, unorderedEquals([bundle1, bundle2]));
+    expect(dataStore.uriToSummaryPath,
+        containsPair('package:p1/u1.dart', '/p1.ds'));
+    // unlinkedMap
+    expect(dataStore.unlinkedMap, hasLength(3));
+    expect(dataStore.unlinkedMap,
+        containsPair('package:p1/u1.dart', unlinkedUnit11));
+    expect(dataStore.unlinkedMap,
+        containsPair('package:p1/u2.dart', unlinkedUnit12));
+    expect(dataStore.unlinkedMap,
+        containsPair('package:p2/u1.dart', unlinkedUnit21));
+    // linkedMap
+    expect(dataStore.linkedMap, hasLength(2));
+    expect(dataStore.linkedMap,
+        containsPair('package:p1/u1.dart', linkedLibrary1));
+    expect(dataStore.linkedMap,
+        containsPair('package:p2/u1.dart', linkedLibrary2));
+  }
+
+  test_getContainingLibraryUris_libraryUri() {
+    String partUri = 'package:p1/u1.dart';
+    List<String> uris = dataStore.getContainingLibraryUris(partUri);
+    expect(uris, unorderedEquals([partUri]));
+  }
+
+  test_getContainingLibraryUris_partUri() {
+    String partUri = 'package:p1/u2.dart';
+    List<String> uris = dataStore.getContainingLibraryUris(partUri);
+    expect(uris, unorderedEquals(['package:p1/u1.dart']));
+  }
+
+  test_getContainingLibraryUris_unknownUri() {
+    String partUri = 'package:notInStore/foo.dart';
+    List<String> uris = dataStore.getContainingLibraryUris(partUri);
+    expect(uris, isNull);
+  }
+}
+
+class _InternalAnalysisContextMock extends TypedMock
+    implements InternalAnalysisContext {}
+
+class _LinkedLibraryMock extends TypedMock implements LinkedLibrary {}
+
+class _PackageBundleMock extends TypedMock implements PackageBundle {}
+
+class _SourceFactoryMock extends TypedMock implements SourceFactory {}
+
+class _SourceMock implements Source {
+  final Uri uri;
+  final String fullName;
+
+  _SourceMock(String uriStr, this.fullName) : uri = FastUri.parse(uriStr);
+
+  @override
+  Source get librarySource => null;
+
+  @override
+  Source get source => this;
+
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() => '$uri ($fullName)';
+}
+
+class _TestResynthesizerResultProvider extends ResynthesizerResultProvider {
+  final Set<Source> sourcesWithResults = new Set<Source>();
+
+  _TestResynthesizerResultProvider(
+      InternalAnalysisContext context, SummaryDataStore dataStore)
+      : super(context, dataStore);
+
+  @override
+  bool hasResultsForSource(Source source) {
+    return sourcesWithResults.contains(source);
+  }
+}
+
+class _UnlinkedPublicNamespaceMock extends TypedMock
+    implements UnlinkedPublicNamespace {}
+
+class _UnlinkedUnitMock extends TypedMock implements UnlinkedUnit {}
diff --git a/pkg/analyzer/test/src/summary/test_all.dart b/pkg/analyzer/test/src/summary/test_all.dart
index 2f9202b..b3a0467 100644
--- a/pkg/analyzer/test/src/summary/test_all.dart
+++ b/pkg/analyzer/test/src/summary/test_all.dart
@@ -13,6 +13,7 @@
 import 'index_unit_test.dart' as index_unit_test;
 import 'linker_test.dart' as linker_test;
 import 'name_filter_test.dart' as name_filter_test;
+import 'package_bundle_reader_test.dart' as package_bundle_reader_test;
 import 'prelinker_test.dart' as prelinker_test;
 import 'resynthesize_ast_test.dart' as resynthesize_ast_test;
 import 'resynthesize_strong_test.dart' as resynthesize_strong_test;
@@ -32,6 +33,7 @@
     index_unit_test.main();
     linker_test.main();
     name_filter_test.main();
+    package_bundle_reader_test.main();
     prelinker_test.main();
     resynthesize_ast_test.main();
     resynthesize_strong_test.main();
diff --git a/pkg/analyzer/test/src/task/dart_test.dart b/pkg/analyzer/test/src/task/dart_test.dart
index 8c081f7..cedcb9b 100644
--- a/pkg/analyzer/test/src/task/dart_test.dart
+++ b/pkg/analyzer/test/src/task/dart_test.dart
@@ -3695,6 +3695,22 @@
     expect(info.userToDependsOn['U'], unorderedEquals(['A', 'B']));
   }
 
+  test_class_extendedUsedUnnamedConstructorNames() {
+    ReferencedNames info = _computeReferencedNames('''
+class U1 extends A {
+  U1() : super();
+}
+class U2 extends p.B {
+  U2() : super();
+}
+class U3 extends p.C {
+  U3() : super.named();
+}
+''');
+    expect(
+        info.extendedUsedUnnamedConstructorNames, unorderedEquals(['A', 'B']));
+  }
+
   test_class_field() {
     ReferencedNames info = _computeReferencedNames('''
 class U {
diff --git a/pkg/analyzer/test/src/task/dart_work_manager_test.dart b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
index 31ee542..79f3071 100644
--- a/pkg/analyzer/test/src/task/dart_work_manager_test.dart
+++ b/pkg/analyzer/test/src/task/dart_work_manager_test.dart
@@ -329,6 +329,7 @@
   }
 
   void test_getLibrariesContainingPart() {
+    when(context.aboutToComputeResult(anyObject, anyObject)).thenReturn(false);
     Source part1 = new TestSource('part1.dart');
     Source part2 = new TestSource('part2.dart');
     Source part3 = new TestSource('part3.dart');
@@ -346,6 +347,33 @@
     expect(manager.getLibrariesContainingPart(part3), isEmpty);
   }
 
+  void test_getLibrariesContainingPart_askResultProvider() {
+    Source part1 = new TestSource('part1.dart');
+    Source part2 = new TestSource('part2.dart');
+    Source part3 = new TestSource('part3.dart');
+    Source library1 = new TestSource('library1.dart');
+    Source library2 = new TestSource('library2.dart');
+    // configure AnalysisContext mock
+    when(context.aboutToComputeResult(anyObject, CONTAINING_LIBRARIES))
+        .thenInvoke((CacheEntry entry, ResultDescriptor result) {
+      if (entry.target == part1) {
+        entry.setValue(result, <Source>[library1, library2], []);
+        return true;
+      }
+      if (entry.target == part2) {
+        entry.setValue(result, <Source>[library2], []);
+        return true;
+      }
+      return false;
+    });
+    // getLibrariesContainingPart
+    expect(manager.getLibrariesContainingPart(part1),
+        unorderedEquals([library1, library2]));
+    expect(
+        manager.getLibrariesContainingPart(part2), unorderedEquals([library2]));
+    expect(manager.getLibrariesContainingPart(part3), isEmpty);
+  }
+
   void test_getLibrariesContainingPart_inSDK() {
     Source part = new _SourceMock('part.dart');
     when(part.isInSystemLibrary).thenReturn(true);
@@ -764,6 +792,11 @@
     expect(manager.libraryPartsMap, isEmpty);
   }
 
+  void test_unitIncrementallyResolved() {
+    manager.unitIncrementallyResolved(source1, source2);
+    expect_librarySourceQueue([source1]);
+  }
+
   CacheEntry _getOrCreateEntry(Source source, [bool explicit = true]) {
     CacheEntry entry = cache.get(source);
     if (entry == null) {
diff --git a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
index ecd98cb..cdca3b4 100644
--- a/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
+++ b/pkg/analyzer/test/src/task/incremental_element_builder_test.dart
@@ -1065,6 +1065,27 @@
     }
   }
 
+  test_directives_library_updateOffset() {
+    _buildOldUnit(r'''
+#!/bin/sh
+library my_lib;
+class A {}
+''');
+    LibraryDirective libraryDirective = oldUnit.directives.single;
+    // Set the LibraryElement and check that its nameOffset is correct.
+    libraryDirective.element =
+        new LibraryElementImpl.forNode(context, libraryDirective.name);
+    expect(libraryDirective.element.nameOffset, libraryDirective.name.offset);
+    // Update and check again that the nameOffset is correct.
+    _buildNewUnit(r'''
+#!/bin/sh
+
+library my_lib;
+class A {}
+''');
+    expect(libraryDirective.element.nameOffset, libraryDirective.name.offset);
+  }
+
   test_directives_remove() {
     _buildOldUnit(r'''
 library test;
diff --git a/pkg/analyzer_cli/pubspec.yaml b/pkg/analyzer_cli/pubspec.yaml
index 4e45320..a19fecb 100644
--- a/pkg/analyzer_cli/pubspec.yaml
+++ b/pkg/analyzer_cli/pubspec.yaml
@@ -11,7 +11,7 @@
   bazel_worker: ^0.1.0
   cli_util: ^0.0.1
   linter: ^0.1.16
-  package_config: ^0.1.5
+  package_config: '>=0.1.5 <2.0.0'
   plugin: '>=0.1.0 <0.3.0'
   protobuf: ^0.5.0
   yaml: ^2.1.2
diff --git a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
index 65e7439..8286b33 100644
--- a/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
+++ b/pkg/compiler/lib/src/inferrer/inferrer_visitor.dart
@@ -314,10 +314,6 @@
 
   bool hasNoArguments() => positional.isEmpty && named.isEmpty;
 
-  bool hasOnePositionalArgumentThatMatches(bool f(T type)) {
-    return named.isEmpty && positional.length == 1 && f(positional[0]);
-  }
-
   void forEach(void f(T type)) {
     positional.forEach(f);
     named.values.forEach(f);
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
index d5492f1..dedb4e2 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_nodes.dart
@@ -856,10 +856,13 @@
   }
 
   /**
-   * We optimize certain operations on the [int] class because we know
-   * more about their return type than the actual Dart code. For
-   * example, we know int + int returns an int. The Dart code for
-   * [int.operator+] only says it returns a [num].
+   * We optimize certain operations on the [int] class because we know more
+   * about their return type than the actual Dart code. For example, we know int
+   * + int returns an int. The Dart library code for [int.operator+] only says
+   * it returns a [num].
+   *
+   * Returns the more precise TypeInformation, or `null` to defer to the library
+   * code.
    */
   TypeInformation handleIntrisifiedSelector(
       Selector selector, TypeMask mask, TypeGraphInferrerEngine inferrer) {
@@ -883,63 +886,78 @@
       return info.type
           .satisfies(classWorld.backend.positiveIntImplementation, classWorld);
     }
+    TypeInformation tryLater() => inferrer.types.nonNullEmptyType;
+
+    TypeInformation argument =
+        arguments.isEmpty ? null : arguments.positional.first;
 
     String name = selector.name;
-    // We are optimizing for the cases that are not expressed in the
-    // Dart code, for example:
-    // int + int -> int
-    // uint31 | uint31 -> uint31
-    if (name == '*' ||
-        name == '+' ||
-        name == '%' ||
-        name == 'remainder' ||
-        name == '~/') {
-      if (isPositiveInt(receiver) &&
-          arguments.hasOnePositionalArgumentThatMatches(isPositiveInt)) {
-        // uint31 + uint31 -> uint32
-        if (name == '+' &&
-            isUInt31(receiver) &&
-            arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
-          return inferrer.types.uint32Type;
-        } else {
+    // These are type inference rules only for useful cases that are not
+    // expressed in the library code, for example:
+    //
+    //     int + int        ->  int
+    //     uint31 | uint31  ->  uint31
+    //
+    switch (name) {
+      case '*':
+      case '+':
+      case '%':
+      case 'remainder':
+      case '~/':
+        if (isEmpty(argument)) return tryLater();
+        if (isPositiveInt(receiver) && isPositiveInt(argument)) {
+          // uint31 + uint31 -> uint32
+          if (name == '+' && isUInt31(receiver) && isUInt31(argument)) {
+            return inferrer.types.uint32Type;
+          }
           return inferrer.types.positiveIntType;
         }
-      } else if (arguments.hasOnePositionalArgumentThatMatches(isInt)) {
-        return inferrer.types.intType;
-      } else if (arguments.hasOnePositionalArgumentThatMatches(isEmpty)) {
-        return inferrer.types.nonNullEmptyType;
-      } else {
+        if (isInt(argument)) {
+          return inferrer.types.intType;
+        }
         return null;
-      }
-    } else if (name == '|' || name == '^') {
-      if (isUInt31(receiver) &&
-          arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
-        return inferrer.types.uint31Type;
-      }
-    } else if (name == '>>') {
-      if (isUInt31(receiver)) {
-        return inferrer.types.uint31Type;
-      }
-    } else if (name == '&') {
-      if (isUInt31(receiver) ||
-          arguments.hasOnePositionalArgumentThatMatches(isUInt31)) {
-        return inferrer.types.uint31Type;
-      }
-    } else if (name == 'unary-') {
-      // The receiver being an int, the return value will also be an
-      // int.
-      return inferrer.types.intType;
-    } else if (name == '-') {
-      if (arguments.hasOnePositionalArgumentThatMatches(isInt)) {
+
+      case '|':
+      case '^':
+        if (isEmpty(argument)) return tryLater();
+        if (isUInt31(receiver) && isUInt31(argument)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '>>':
+        if (isEmpty(argument)) return tryLater();
+        if (isUInt31(receiver)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '&':
+        if (isEmpty(argument)) return tryLater();
+        if (isUInt31(receiver) || isUInt31(argument)) {
+          return inferrer.types.uint31Type;
+        }
+        return null;
+
+      case '-':
+        if (isEmpty(argument)) return tryLater();
+        if (isInt(argument)) {
+          return inferrer.types.intType;
+        }
+        return null;
+
+      case 'unary-':
+        // The receiver being an int, the return value will also be an int.
         return inferrer.types.intType;
-      } else if (arguments.hasOnePositionalArgumentThatMatches(isEmpty)) {
-        return inferrer.types.nonNullEmptyType;
-      }
-      return null;
-    } else if (name == 'abs') {
-      return arguments.hasNoArguments() ? inferrer.types.positiveIntType : null;
+
+      case 'abs':
+        return arguments.hasNoArguments()
+            ? inferrer.types.positiveIntType
+            : null;
+
+      default:
+        return null;
     }
-    return null;
   }
 
   TypeMask computeType(TypeGraphInferrerEngine inferrer) {
diff --git a/pkg/compiler/lib/src/js_backend/namer.dart b/pkg/compiler/lib/src/js_backend/namer.dart
index c4a86ef..aeea76e 100644
--- a/pkg/compiler/lib/src/js_backend/namer.dart
+++ b/pkg/compiler/lib/src/js_backend/namer.dart
@@ -644,7 +644,9 @@
   String _jsNameHelper(Element e) {
     String jsInteropName = backend.nativeData.getJsInteropName(e);
     if (jsInteropName != null && jsInteropName.isNotEmpty) return jsInteropName;
-    return e.isLibrary ? 'self' : e.name;
+    return e.isLibrary
+        ? 'self'
+        : backend.nativeData.getUnescapedJSInteropName(e.name);
   }
 
   /// Returns a JavaScript path specifying the context in which
diff --git a/pkg/compiler/pubspec.yaml b/pkg/compiler/pubspec.yaml
index 922f69a..d8998ef 100644
--- a/pkg/compiler/pubspec.yaml
+++ b/pkg/compiler/pubspec.yaml
@@ -3,7 +3,7 @@
 name: compiler
 #version: do-not-upload
 dependencies:
-  package_config: ^0.1.1
+  package_config: '>=0.1.1 <2.0.0'
   pub_semver: ^1.2.1
   js:
     path: ../js
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 610115a..fb91ab7 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -504,4 +504,88 @@
       "//third_party",
     ]
   }
+
+  action("generate_snapshot_test_dat_file") {
+    snapshot_test_dat_file = "$root_gen_dir/snapshot_test.dat"
+    snapshot_test_in_dat_file = "../vm/snapshot_test_in.dat"
+    snapshot_test_dart_file = "../vm/snapshot_test.dart"
+    inputs = [
+      "../tools/create_string_literal.py",
+      snapshot_test_in_dat_file,
+      snapshot_test_dart_file,
+    ]
+
+    outputs = [
+      snapshot_test_dat_file,
+    ]
+
+    script = "../tools/create_string_literal.py"
+    args = [
+      "--output",
+      rebase_path(snapshot_test_dat_file),
+      "--input_cc",
+      rebase_path(snapshot_test_in_dat_file),
+      "--include",
+      "INTENTIONALLY_LEFT_BLANK",
+      "--var_name",
+      "INTENTIONALLY_LEFT_BLANK_TOO",
+      rebase_path(snapshot_test_dart_file),
+    ]
+  }
+
+  executable("run_vm_tests") {
+    testonly = true
+    configs += ["..:dart_config",
+                "..:dart_product_config",
+                "..:dart_precompiled_runtime_config",]
+    deps = [
+      "..:libdart",
+      ":libdart_builtin",
+      ":embedded_dart_io",
+      ":dart_snapshot_cc",
+      ":generate_snapshot_test_dat_file",
+      "../vm:libdart_platform",
+      "//third_party/zlib",
+    ]
+    include_dirs = [
+      "..",
+      "$target_gen_dir",
+    ]
+    defines = [
+      "TESTING",
+    ]
+
+    vm_tests_list = exec_script("../../tools/gypi_to_gn.py",
+                                  [rebase_path("../vm/vm_sources.gypi"),
+                                   "--keep_only=_test.cc",
+                                   "--keep_only=_test.h",],
+                                  "scope",
+                                  ["../vm/vm_sources.gypi"])
+    vm_tests = rebase_path(vm_tests_list.sources, ".", "../vm")
+
+    builtin_impl_tests_list =
+        exec_script("../../tools/gypi_to_gn.py",
+                    [rebase_path("builtin_impl_sources.gypi"),
+                     "--keep_only=_test.cc",
+                     "--keep_only=_test.h",],
+                    "scope",
+                    ["builtin_impl_sources.gypi"])
+
+    sources = [
+      "run_vm_tests.cc",
+    ] + builtin_impl_tests_list.sources + vm_tests
+  }
+
+  copy("fuchsia_vm_tests") {
+    sources = [ "fuchsia_vm_tests.txt" ]
+    outputs = [ "$root_out_dir/fuchsia_vm_tests.txt" ]
+  }
+
+  executable("run_vm_tests_fuchsia") {
+    testonly = true
+    configs += ["..:dart_config"]
+    sources = [
+      "run_vm_tests_fuchsia.cc"
+    ]
+  }
 }  # defined(is_fuchsia) && is_fuchsia
diff --git a/runtime/bin/fuchsia_vm_tests.txt b/runtime/bin/fuchsia_vm_tests.txt
new file mode 100644
index 0000000..665cf38
--- /dev/null
+++ b/runtime/bin/fuchsia_vm_tests.txt
@@ -0,0 +1,915 @@
+CircularLinkedList
+Read
+FileLength
+FilePosition
+Set
+StackAllocatedDestruction
+StackAllocatedLongJump
+StackResourceDestruction
+StackResourceLongJump
+StoreIntoObject
+ReadArgument
+AddressingModes
+JumpAroundCrash
+SimpleLoop
+Cmpb
+Testb
+Increment
+IncrementLong
+Decrement
+DecrementLong
+SignedMultiply
+UnsignedMultiply
+SignedMultiply64
+SignedMultiplyLong
+OverflowSignedMultiply
+SignedMultiply1
+SignedMultiply2
+UnsignedMultiplyLong
+SignedDivide
+UnsignedDivide
+SignedDivideLong
+UnsignedDivideLong
+Negate
+BitScanReverse
+MoveExtend
+MoveExtend32
+MoveExtendMemory
+MoveExtend32Memory
+MoveWord
+MoveWordRex
+LongAddReg
+LongAddImmediate
+LongAddAddress
+LongSubReg
+LongSubImmediate
+LongSubAddress
+AddReg
+AddImmediate
+AddAddress
+SubReg
+SubImmediate
+SubAddress
+Bitwise
+Bitwise64
+LogicalOps
+LogicalOps64
+LogicalTestL
+LogicalTestQ
+CompareSwapEQ
+CompareSwapNEQ
+Exchange
+LargeConstant
+CallSimpleLeaf
+JumpSimpleLeaf
+JumpIndirect
+SingleFPMoves
+SingleFPMoves2
+PackedDoubleAdd
+PackedDoubleSub
+PackedDoubleNegate
+PackedDoubleAbsolute
+PackedDoubleMul
+PackedDoubleDiv
+PackedDoubleSqrt
+PackedDoubleMin
+PackedDoubleMax
+PackedDoubleShuffle
+PackedDoubleToSingle
+PackedSingleToDouble
+SingleFPOperations
+PackedFPOperations
+PackedIntOperations
+PackedIntOperations2
+PackedFPOperations2
+PackedCompareEQ
+PackedCompareNEQ
+PackedCompareLT
+PackedCompareLE
+PackedCompareNLT
+PackedCompareNLE
+PackedNegate
+PackedAbsolute
+PackedSetWZero
+PackedMin
+PackedMax
+PackedLogicalOr
+PackedLogicalAnd
+PackedLogicalNot
+PackedMoveHighLow
+PackedMoveLowHigh
+PackedUnpackLow
+PackedUnpackHigh
+PackedUnpackLowPair
+PackedUnpackHighPair
+DoubleFPMoves
+DoubleFPOperations
+Int32ToDoubleConversion
+Int64ToDoubleConversion
+DoubleToInt64Conversion
+TestObjectCompare
+TestNop
+TestAlign0
+TestAlign1
+TestAlign1Offset1
+TestAlignLarge
+TestAdds
+TestNot
+TestNotInt32
+XorpdZeroing
+XorpdZeroing2
+Pxor
+SquareRootDouble
+DoubleFPUStackMoves
+Sine
+Cosine
+IntToDoubleConversion
+DoubleToDoubleTrunc
+DoubleAbs
+ExtractSignBits
+TestSetCC
+TestRepMovsBytes
+ConditionalMovesCompare
+BitTest
+ConditionalMovesEqual
+ConditionalMovesNoOverflow
+Assert
+Expect
+Fail0
+Fail1
+Fail2
+AstPrinter
+Ast
+FetchAndIncrement
+FetchAndDecrement
+IncrementBy
+DecrementBy
+LoadRelaxed
+CompareAndSwapWord
+CompareAndSwapUint32
+BigintSmi
+BigintInt64
+BigintUint64
+BigintDouble
+BigintHexStrings
+BigintDecStrings
+BigintCompare
+BigintDecimalStrings
+BitSetBasic
+BitVector
+BitFields
+BitmapBuilder
+BoolField
+ClassHierarchyAnalysis
+ClassFinalizer
+ClassFinalize_Cycles
+ClassFinalize_Resolve
+StackmapCodegen
+StackmapGC
+DescriptorList_TokenPositions
+CodeSourceMap_TokenPositions
+SimpleReturnCodegen
+SmiReturnCodegen
+SimpleStaticCallCodegen
+StaticCallReturnParameterCodegen
+StaticCallSmiParamSumCodegen
+SmiAddCodegen
+GenericAddCodegen
+SmiBinaryOpCodegen
+BoolNotCodegen
+BoolAndCodegen
+BinaryOpCodegen
+SmiUnaryOpCodegen
+DoubleUnaryOpCodegen
+StaticCallCodegen
+InstanceCallCodegen
+AllocateNewObjectCodegen
+IcDataAccess
+CompileScript
+CompileFunction
+CompileFunctionOnHelperThread
+RegenerateAllocStubs
+EvalExpression
+EvalExpressionWithLazyCompile
+EvalExpressionExhaustCIDs
+Id
+GetCpuModelTest
+CustomIsolates
+ErrorHandleBasics
+StacktraceInfo
+DeepStacktraceInfo
+StackOverflowStacktraceInfo
+OutOfMemoryStacktraceInfo
+CurrentStacktraceInfo
+ErrorHandleTypes
+UnhandleExceptionError
+Dart_PropagateError
+Dart_Error
+Null
+EmptyString
+IdentityEquals
+IdentityHash
+ObjectEquals
+InstanceValues
+InstanceGetType
+BooleanValues
+BooleanConstants
+DoubleValues
+NumberValues
+IntegerValues
+IntegerFitsIntoInt64
+IntegerFitsIntoUint64
+ArrayValues
+IsString
+NewString
+MalformedStringToUTF8
+ExternalStringCallback
+ExternalStringPretenure
+ExternalTypedDataPretenure
+ListAccess
+MapAccess
+IsFuture
+TypedDataViewListGetAsBytes
+TypedDataViewListIsTypedData
+TypedDataAccess
+ByteBufferAccess
+ByteDataAccess
+ExternalByteDataAccess
+OptimizedExternalByteDataAccess
+TypedDataDirectAccessUnverified
+TypedDataDirectAccessVerified
+TypedDataDirectAccess1Unverified
+TypedDataDirectAccess1Verified
+TypedDataViewDirectAccessUnverified
+TypedDataViewDirectAccessVerified
+ByteDataDirectAccessUnverified
+ByteDataDirectAccessVerified
+ExternalTypedDataAccess
+ExternalClampedTypedDataAccess
+ExternalUint8ClampedArrayAccess
+ExternalTypedDataCallback
+SlowFinalizer
+Float32x4List
+EnterExitScope
+PersistentHandles
+NewPersistentHandle_FromPersistentHandle
+AssignToPersistentHandle
+WeakPersistentHandle
+WeakPersistentHandleCallback
+WeakPersistentHandleNoCallback
+WeakPersistentHandlesCallbackShutdown
+WeakPersistentHandleExternalAllocationSize
+WeakPersistentHandleExternalAllocationSizeNewspaceGC
+WeakPersistentHandleExternalAllocationSizeOldspaceGC
+WeakPersistentHandleExternalAllocationSizeOddReferents
+ImplicitReferencesOldSpace
+ImplicitReferencesNewSpace
+SetGarbageCollectionCallbacks
+SingleGarbageCollectionCallback
+LocalHandles
+LocalZoneMemory
+Isolates
+CurrentIsolateData
+IsolateSetCheckedMode
+DebugName
+SetMessageCallbacks
+TypeGetNonParamtericTypes
+TypeGetParameterizedTypes
+FieldAccess
+SetField_FunnyValue
+InjectNativeFields1
+InjectNativeFields2
+InjectNativeFields3
+InjectNativeFields4
+TestNativeFieldsAccess
+InjectNativeFieldsSuperClass
+NativeFieldAccess
+ImplicitNativeFieldAccess
+NegativeNativeFieldAccess
+NegativeNativeFieldInIsolateMessage
+GetStaticField_RunsInitializer
+GetField_CheckIsolate
+SetField_CheckIsolate
+New
+New_Issue2971
+Invoke
+Invoke_PrivateStatic
+Invoke_FunnyArgs
+Invoke_Null
+InvokeNoSuchMethod
+Invoke_CrossLibrary
+InvokeClosure
+ThrowException
+GetNativeArguments
+GetNativeArgumentCount
+GetType
+InstanceOf
+LoadScript
+RootLibrary
+LoadScript_CompileError
+LookupLibrary
+LibraryName
+LibraryId
+LibraryUrl
+LibraryGetClassNames
+GetFunctionNames
+LibraryImportLibrary
+ImportLibraryWithPrefix
+LoadLibrary
+LoadLibrary_CompileError
+LoadSource
+LoadSource_LateLoad
+LoadPatch
+LoadPatchSignatureMismatch
+ParsePatchLibrary
+SetNativeResolver
+ImportLibrary2
+ImportLibrary3
+ImportLibrary4
+ImportLibrary5
+IllegalNewSendPort
+IllegalPost
+NewNativePort
+NativePortPostInteger
+NativePortReceiveNull
+NativePortReceiveInteger
+RunLoop_Success
+RunLoop_Exception
+IsolateShutdown
+IsolateShutdownRunDartCode
+NativeFunctionClosure
+NativeStaticFunctionClosure
+RangeLimits
+NewString_Null
+InvalidGetSetPeer
+OneNewSpacePeer
+CollectOneNewSpacePeer
+TwoNewSpacePeers
+CollectTwoNewSpacePeers
+CopyNewSpacePeers
+OnePromotedPeer
+OneOldSpacePeer
+CollectOneOldSpacePeer
+TwoOldSpacePeers
+CollectTwoOldSpacePeers
+MakeExternalString
+ExternalizeConstantStrings
+LazyLoadDeoptimizes
+GuardExternalizedString
+ExternalStringDeoptimize
+ExternalStringPolymorphicDeoptimize
+ExternalStringLoadElimination
+ExternalStringGuardFieldDeoptimize
+ExternalStringStaticFieldDeoptimize
+ExternalStringTrimDoubleParse
+ExternalStringDoubleParse
+ExternalStringIndexOf
+StringFromExternalTypedData
+Timeline_Dart_TimelineDuration
+Timeline_Dart_TimelineInstant
+Timeline_Dart_TimelineAsyncDisabled
+Timeline_Dart_TimelineAsync
+Timeline_Dart_TimelineGetTrace
+Timeline_Dart_TimelineGetTraceOnlyDartEvents
+Timeline_Dart_TimelineGetTraceWithDartEvents
+Timeline_Dart_TimelineGetTraceGlobalOverride
+Timeline_Dart_GlobalTimelineGetTrace
+Timeline_Dart_GlobalTimelineGetTrace_Threaded
+Timeline_Dart_EmbedderTimelineStartStopRecording
+Dart_LoadLibraryPatch_1
+Dart_LoadLibraryPatch_Error1
+Dart_LoadLibraryPatch_Error2
+Dart_LoadLibraryPatch_Error3
+DartEntry
+InvokeStatic_CompileError
+InvokeDynamic_CompileError
+Debugger_PrintBreakpointsToJSONArray
+Debugger_PauseEvent
+Debug_Breakpoint
+Debug_InspectStack_NotOptimized
+Debug_InspectStack_Optimized
+Debug_InspectStackWithClosure_NotOptimized
+Debug_InspectStackWithClosure_Optimized
+Debug_StepOut
+Debug_StepInto
+Debug_IgnoreBP
+Debug_DeoptimizeFunction
+Debug_SingleStep
+Debug_ClosureBreakpoint
+Debug_ExprClosureBreakpoint
+Debug_BreakpointStubPatching
+Debug_DeleteBreakpoint
+Debug_InspectStaticField
+Debug_InspectObject
+Debug_IsolateID
+Debug_InterruptIsolate
+Debug_StackTraceDump1
+Debug_StackTraceDump2
+Debug_EvaluateExpr
+Debug_EvaluateInActivationOfEvaluate
+Debug_BreakOnUnhandledException
+Debug_GetClosureInfo
+Debug_GetSupertype
+Debug_ListSuperType
+Debug_ScriptGetTokenInfo_Basic
+Debug_ScriptGetTokenInfo_MultiLineInterpolation
+Disassembler
+UnhandledExceptions
+FindCodeObject
+BasicFlags
+ParseFlags
+SourcePosition_InstanceCalls
+SourcePosition_If
+SourcePosition_ForLoop
+SourcePosition_While
+SourcePosition_WhileContinueBreak
+SourcePosition_LoadIndexed
+SourcePosition_StoreIndexed
+SourcePosition_BitwiseOperations
+SourcePosition_IfElse
+SourcePosition_Switch
+SourcePosition_TryCatchFinally
+SourcePosition_InstanceFields
+SourcePosition_Async
+SourcePosition_SyntheticTokens
+RangeTests
+RangeTestsInfinity
+RangeUtils
+RangeBinaryOp
+RangeAdd
+RangeSub
+RangeAnd
+RangeIntersectionMinMax
+RangeJoinMinMax
+FreeList
+FreeListProtected
+FreeListProtectedTinyObjects
+FreeListProtectedVariableSizeObjects
+GrowableArray
+MallocGrowableArray
+GrowableArraySort
+GrowableHandlePtr
+GuardFieldSimpleTest
+GuardFieldFinalListTest
+GuardFieldFinalVariableLengthListTest
+GuardFieldConstructorTest
+GuardFieldConstructor2Test
+AllocateZoneHandle
+AllocateScopeHandle
+DirectChainedHashMap
+MallocDirectChainedHashMap
+DirectChainedHashMapIterator
+HashTable
+Sets
+Maps
+OldGC
+OldGC_Unsync
+LargeSweep
+ClassHeapStats
+ArrayHeapStats
+FindObject
+IterateReadOnly
+BecomeFowardOldToOld
+BecomeFowardNewToNew
+BecomeFowardOldToNew
+BecomeFowardNewToOld
+BecomeForwardRememberedObject
+InstructionTests
+OptimizationTests
+IsolateReload_FunctionReplacement
+IsolateReload_BadClass
+IsolateReload_StaticValuePreserved
+IsolateReload_SavedClosure
+IsolateReload_TopLevelFieldAdded
+IsolateReload_ClassFieldAdded
+IsolateReload_ClassFieldAdded2
+IsolateReload_ClassFieldRemoved
+IsolateReload_ClassAdded
+IsolateReload_LibraryImportAdded
+IsolateReload_LibraryImportRemoved
+IsolateReload_LibraryDebuggable
+IsolateReload_ImplicitConstructorChanged
+IsolateReload_ConstructorChanged
+IsolateReload_SuperClassChanged
+IsolateReload_Generics
+IsolateReload_TypeIdentity
+IsolateReload_TypeIdentityGeneric
+IsolateReload_TypeIdentityParameter
+IsolateReload_MixinChanged
+IsolateReload_ComplexInheritanceChange
+IsolateReload_LiveStack
+IsolateReload_LibraryLookup
+IsolateReload_LibraryHide
+IsolateReload_LibraryShow
+IsolateReload_SmiFastPathStubs
+IsolateReload_ImportedMixinFunction
+IsolateReload_TopLevelParseError
+IsolateReload_PendingUnqualifiedCall_StaticToInstance
+IsolateReload_PendingUnqualifiedCall_InstanceToStatic
+IsolateReload_PendingConstructorCall_AbstractToConcrete
+IsolateReload_PendingConstructorCall_ConcreteToAbstract
+IsolateReload_PendingStaticCall_DefinedToNSM
+IsolateReload_PendingStaticCall_NSMToDefined
+IsolateReload_PendingSuperCall
+IsolateReload_EnumEquality
+IsolateReload_EnumIdentical
+IsolateReload_EnumReorderIdentical
+IsolateReload_EnumAddition
+IsolateReload_EnumToNotEnum
+IsolateReload_NotEnumToEnum
+IsolateReload_EnumDelete
+IsolateReload_EnumIdentityReload
+IsolateReload_ConstantIdentical
+IsolateReload_EnumValuesToString
+IsolateReload_DirectSubclasses_Success
+IsolateReload_DirectSubclasses_GhostSubclass
+IsolateReload_DirectSubclasses_Failure
+IsolateCurrent
+IsolateSpawn
+StackLimitInterrupts
+NoOOBMessageScope
+JSON_TextBuffer
+JSON_JSONStream_Primitives
+JSON_JSONStream_Array
+JSON_JSONStream_Object
+JSON_JSONStream_NestedObject
+JSON_JSONStream_ObjectArray
+JSON_JSONStream_ArrayArray
+JSON_JSONStream_Printf
+JSON_JSONStream_ObjectPrintf
+JSON_JSONStream_DartObject
+JSON_JSONStream_EscapedString
+JSON_JSONStream_DartString
+JSON_JSONStream_Params
+JSON_JSONStream_AppendJSONStreamConsumer
+Log_Macro
+Log_Basic
+Log_Block
+LongJump
+NullRegion
+NewRegion
+Subregion
+ExtendedRegion
+MessageHandler_PostMessage
+MessageHandler_HasOOBMessages
+MessageHandler_ClosePort
+MessageHandler_CloseAllPorts
+MessageHandler_HandleNextMessage
+MessageHandler_HandleNextMessage_ProcessOOBAfterError
+MessageHandler_HandleNextMessage_Shutdown
+MessageHandler_HandleOOBMessages
+MessageHandler_Run
+MessageQueue_BasicOperations
+MessageQueue_Clear
+Metric_Simple
+Metric_OnDemand
+ObjectGraph
+ObjectIdRingSerialWrapTest
+ObjectIdRingScavengeMoveTest
+ObjectIdRingOldGCTest
+ObjectIdRingExpiredEntryTest
+Class
+TypeArguments
+TokenStream
+GenerateExactSource
+Class_ComputeEndTokenPos
+InstanceClass
+Smi
+StringCompareTo
+StringEncodeIRI
+StringDecodeIRI
+StringDecodeIRIInvalid
+StringIRITwoByte
+Mint
+Double
+Bigint
+Integer
+String
+StringFormat
+StringConcat
+StringHashConcat
+StringSubStringDifferentWidth
+StringFromUtf8Literal
+StringEqualsUtf8
+StringEqualsUTF32
+ExternalOneByteString
+EscapeSpecialCharactersOneByteString
+EscapeSpecialCharactersExternalOneByteString
+EscapeSpecialCharactersTwoByteString
+EscapeSpecialCharactersExternalTwoByteString
+ExternalTwoByteString
+Symbol
+SymbolUnicode
+Bool
+Array
+ArrayLengthNegativeOne
+ArrayLengthSmiMin
+ArrayLengthOneTooMany
+ArrayLengthMaxElements
+Int8ListLengthNegativeOne
+Int8ListLengthSmiMin
+Int8ListLengthOneTooMany
+Int8ListLengthMaxElements
+StringCodePointIterator
+StringCodePointIteratorRange
+GrowableObjectArray
+InternalTypedData
+ExternalTypedData
+Script
+EmbeddedScript
+Context
+ContextScope
+Closure
+ObjectPrinting
+CheckedHandle
+Code
+CodeImmutability
+EmbedStringInCode
+EmbedSmiInCode
+EmbedSmiIn64BitCode
+ExceptionHandlers
+PcDescriptors
+PcDescriptorsLargeDeltas
+ClassDictionaryIterator
+ICData
+SubtypeTestCache
+FieldTests
+EqualsIgnoringPrivate
+ArrayNew_Overflow_Crash
+StackTraceFormat
+WeakProperty_PreserveCrossGen
+WeakProperty_PreserveRecurse
+WeakProperty_PreserveOne_NewSpace
+WeakProperty_PreserveTwo_NewSpace
+WeakProperty_PreserveTwoShared_NewSpace
+WeakProperty_PreserveOne_OldSpace
+WeakProperty_PreserveTwo_OldSpace
+WeakProperty_PreserveTwoShared_OldSpace
+WeakProperty_ClearOne_NewSpace
+WeakProperty_ClearTwoShared_NewSpace
+WeakProperty_ClearOne_OldSpace
+WeakProperty_ClearTwoShared_OldSpace
+MirrorReference
+FindClosureIndex
+FindInvocationDispatcherFunctionIndex
+Metadata
+FunctionSourceFingerprint
+FunctionWithBreakpointNotInlined
+SpecialClassesHaveEmptyArrays
+PrintJSON
+PrintJSONPrimitives
+InstanceEquality
+HashCode
+LinkedHashMap
+LinkedHashMap_iteration
+Symbols_FromConcatAll
+String_ScrubName
+Sleep
+SNPrint
+SNPrint_BadArgs
+OsFuncs
+OSAlignedAllocate
+Pages
+ParseClassDefinition
+Parser_TopLevel
+Parser_AllocateVariables_CapturedVar
+Parser_AllocateVariables_NestedCapturedVar
+Parser_AllocateVariables_TwoChains
+Parser_AllocateVariables_Issue7681
+Parser_AllocateVariables_CaptureLoopVar
+Parser_AllocateVariables_MiddleChain
+PortMap_CreateAndCloseOnePort
+PortMap_CreateAndCloseTwoPorts
+PortMap_ClosePorts
+PortMap_CreateManyPorts
+PortMap_SetPortState
+PortMap_PostMessage
+PortMap_PostIntegerMessage
+PortMap_PostNullMessage
+PortMap_PostMessageClosedPort
+Profiler_SampleBufferWrapTest
+Profiler_SampleBufferIterateTest
+Profiler_AllocationSampleTest
+Profiler_TrivialRecordAllocation
+Profiler_ToggleRecordAllocation
+Profiler_CodeTicks
+Profiler_FunctionTicks
+Profiler_IntrinsicAllocation
+Profiler_ArrayAllocation
+Profiler_ContextAllocation
+Profiler_ClosureAllocation
+Profiler_TypedArrayAllocation
+Profiler_StringAllocation
+Profiler_StringInterpolation
+Profiler_FunctionInline
+Profiler_InliningIntervalBoundry
+Profiler_ChainedSamples
+Profiler_BasicSourcePosition
+Profiler_BasicSourcePositionOptimized
+Profiler_SourcePosition
+Profiler_SourcePositionOptimized
+Profiler_BinaryOperatorSourcePosition
+Profiler_BinaryOperatorSourcePositionOptimized
+Profiler_GetSourceReport
+RegExp_OneByteString
+RegExp_TwoByteString
+RegExp_ExternalOneByteString
+RegExp_ExternalTwoByteString
+DartStaticResolve
+DartDynamicResolve
+RingBuffer
+Scanner_Test
+ZeroSizeScavenger
+LocalScope
+Service_IdZones
+Service_Code
+Service_TokenStream
+Service_PcDescriptors
+Service_LocalVarDescriptors
+Service_PersistentHandles
+Service_Address
+Service_EmbedderRootHandler
+Service_EmbedderIsolateHandler
+Service_Profile
+SerializeNull
+SerializeSmi1
+SerializeSmi2
+SerializeMints
+SerializeDouble
+SerializeTrue
+SerializeFalse
+SerializeCapability
+SerializeBigint
+SerializeBigint2
+SerializeSingletons
+SerializeString
+SerializeArray
+FailSerializeLargeArray
+FailSerializeLargeNestedArray
+FailSerializeLargeTypedDataInt8
+FailSerializeLargeTypedDataUint8
+FailSerializeLargeExternalTypedData
+SerializeEmptyArray
+SerializeByteArray
+SerializeTypedArray
+SerializeExternalTypedArray
+SerializeEmptyByteArray
+SerializeScript
+CanonicalizationInScriptSnapshots
+GenerateSource
+FullSnapshot
+FullSnapshot1
+ScriptSnapshot
+ScriptSnapshot1
+ScriptSnapshot2
+IntArrayMessage
+DartGeneratedMessages
+DartGeneratedListMessages
+DartGeneratedArrayLiteralMessages
+DartGeneratedListMessagesWithBackref
+DartGeneratedArrayLiteralMessagesWithBackref
+DartGeneratedListMessagesWithTypedData
+PostCObject
+OmittedObjectEncodingLength
+SourceReport_Coverage_NoCalls
+SourceReport_Coverage_SimpleCall
+SourceReport_Coverage_ForceCompile
+SourceReport_Coverage_UnusedClass_NoForceCompile
+SourceReport_Coverage_UnusedClass_ForceCompile
+SourceReport_Coverage_UnusedClass_ForceCompileError
+SourceReport_Coverage_NestedFunctions
+SourceReport_Coverage_RestrictedRange
+SourceReport_Coverage_AllFunctions
+SourceReport_Coverage_AllFunctions_ForceCompile
+SourceReport_CallSites_SimpleCall
+SourceReport_CallSites_PolymorphicCall
+SourceReport_MultipleReports
+SourceReport_PossibleBreakpoints_Simple
+EmptyStackFrameIteration
+EmptyDartStackFrameIteration
+ValidateStackFrameIteration
+ValidateNoSuchMethodStackFrameIteration
+CallRuntimeStubCode
+CallLeafRuntimeStubCode
+ThreadBarrier
+ThreadPool_Create
+ThreadPool_RunOne
+ThreadPool_RunMany
+ThreadPool_WorkerShutdown
+ThreadPool_WorkerTimeout
+ThreadPool_RecursiveSpawn
+Mutex
+Monitor
+ManyTasksWithZones
+ThreadRegistry
+SafepointTestDart
+SafepointTestVM
+RecursiveSafepointTest1
+ThreadIterator_Count
+ThreadIterator_FindSelf
+ThreadIterator_AddFindRemove
+SafepointTestVM2
+RecursiveSafepointTest2
+HelperAllocAndGC
+TimelineEventIsValid
+TimelineEventDuration
+TimelineEventDurationPrintJSON
+TimelineEventArguments
+TimelineEventArgumentsPrintJSON
+TimelineEventBufferPrintJSON
+TimelineEventCallbackRecorderBasic
+TimelineAnalysis_ThreadBlockCount
+TimelineRingRecorderJSONOrder
+TimelinePauses_Basic
+TimelinePauses_BeginEnd
+Utf8Decode
+ParseUri_WithScheme_NoQueryNoUser
+ParseUri_WithScheme_WithQuery
+ParseUri_WithScheme_WithFragment
+ParseUri_WithScheme_WithQueryWithFragment
+ParseUri_WithScheme_WithUser
+ParseUri_WithScheme_ShortPath
+ParseUri_WithScheme_EmptyPath
+ParseUri_WithScheme_Rootless1
+ParseUri_WithScheme_Rootless2
+ParseUri_NoScheme_AbsPath_WithAuthority
+ParseUri_NoScheme_AbsPath_NoAuthority
+ParseUri_NoScheme_AbsPath_StrayColon
+ParseUri_NoScheme_Rootless1
+ParseUri_NoScheme_Rootless2
+ParseUri_NoScheme_Empty
+ParseUri_NoScheme_QueryOnly
+ParseUri_NoScheme_FragmentOnly
+ParseUri_LowerCaseScheme
+ParseUri_NormalizeEscapes_PathQueryFragment
+ParseUri_NormalizeEscapes_UppercaseEscapesPreferred
+ParseUri_NormalizeEscapes_Authority
+ParseUri_NormalizeEscapes_UppercaseEscapeInHost
+ParseUri_BrokenEscapeSequence
+ResolveUri_WithScheme_NoAuthorityNoQuery
+ResolveUri_WithScheme_WithAuthorityWithQuery
+ResolveUri_NoScheme_WithAuthority
+ResolveUri_NoSchemeNoAuthority_AbsolutePath
+ResolveUri_NoSchemeNoAuthority_RelativePath
+ResolveUri_NoSchemeNoAuthority_RelativePathEmptyBasePath
+ResolveUri_NoSchemeNoAuthority_RelativePathWeirdBasePath
+ResolveUri_NoSchemeNoAuthority_EmptyPath
+ResolveUri_NoSchemeNoAuthority_EmptyPathWithQuery
+ResolveUri_NoSchemeNoAuthority_EmptyPathWithFragment
+ResolveUri_RemoveDots_RemoveOneDotSegment
+ResolveUri_RemoveDots_RemoveTwoDotSegments
+ResolveUri_RemoveDots_RemoveOneDotDotSegment
+ResolveUri_RemoveDots_RemoveTwoDotDotSegments
+ResolveUri_RemoveDots_RemoveTooManyDotDotSegments
+ResolveUri_RemoveDots_RemoveDotSegmentsNothingLeft1
+ResolveUri_RemoveDots_RemoveDotSegmentsNothingLeft2
+ResolveUri_RemoveDots_RemoveDotSegmentsInitialPrefix
+ResolveUri_RemoveDots_RemoveDotSegmentsMixed
+ResolveUri_NormalizeEscapes_PathQueryFragment
+ResolveUri_NormalizeEscapes_UppercaseHexPreferred
+ResolveUri_NormalizeEscapes_Authority
+ResolveUri_NormalizeEscapes_BrokenEscapeSequence
+ResolveUri_DataUri
+ResolveUri_RelativeBase_NotImplemented
+ResolveUri_TestUriPerRFCs
+ResolveUri_MoreDotSegmentTests
+Minimum
+Maximum
+IsPowerOfTwo
+ShiftForPowerOfTwo
+IsAligned
+RoundDown
+RoundUp
+RoundUpToPowerOfTwo
+CountOneBits
+CountZeros
+IsInt
+IsUint
+IsAbsoluteUint
+LowBits
+Endianity
+DoublesBitEqual
+AllocateVirtualMemory
+FreeVirtualMemory
+VirtualMemoryCommitPartial
+AllocateZone
+AllocGeneric_Success
+AllocGeneric_Overflow
+ZoneAllocated
+PrintToString
+CorelibCompileAll
+CorelibCompilerStats
+Dart2JSCompilerStats
+CorelibIsolateStartup
+UseDartApi
+DartStringAccess
+Dart2JSCompileAll
+FrameLookup
+CoreSnapshotSize
+StandaloneSnapshotSize
+CreateMirrorSystem
+EnterExitIsolate
+SerializeNull
+SerializeSmi
+SimpleMessage
+LargeMap
diff --git a/runtime/bin/run_vm_tests_fuchsia.cc b/runtime/bin/run_vm_tests_fuchsia.cc
new file mode 100644
index 0000000..3e7430a
--- /dev/null
+++ b/runtime/bin/run_vm_tests_fuchsia.cc
@@ -0,0 +1,255 @@
+// 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.
+
+#include <fcntl.h>
+#include <magenta/syscalls.h>
+#include <mxio/util.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+// This program runs Dart VM unit tests. The Dart VM unit tests are contained
+// in a separate binary whose location is defined in kRunVmTestsPath below.
+// That program accepts a command line argument --list to list all the available
+// tests, or the name of a single test to run. This program accepts a single
+// command line argument which is the path to a file containing a list of tests
+// to run, one per line.
+
+const char* kRunVmTestsPath = "/boot/bin/dart_vm_tests";
+
+// Tests that are invalid, wedge, or cause panics.
+const char* kSkip[] = {
+  // These expect a file to exist that we aren't putting in the image.
+  "Read",
+  "FileLength",
+  "FilePosition",
+  // Hangs.
+  "ArrayLengthMaxElements",
+  "Int8ListLengthMaxElements",
+  "ThreadPool_WorkerShutdown",
+  "LargeMap",
+  "CompileFunctionOnHelperThread",
+  // Kernel panic.
+  "ThreadBarrier",
+  // The profiler is turned off.
+  "Profiler_AllocationSampleTest",
+  "Profiler_ArrayAllocation",
+  "Profiler_BasicSourcePosition",
+  "Profiler_BasicSourcePositionOptimized",
+  "Profiler_BinaryOperatorSourcePosition",
+  "Profiler_BinaryOperatorSourcePositionOptimized",
+  "Profiler_ChainedSamples",
+  "Profiler_ClosureAllocation",
+  "Profiler_CodeTicks",
+  "Profiler_ContextAllocation",
+  "Profiler_FunctionInline",
+  "Profiler_FunctionTicks",
+  "Profiler_InliningIntervalBoundry",
+  "Profiler_IntrinsicAllocation",
+  "Profiler_SampleBufferIterateTest",
+  "Profiler_SampleBufferWrapTest",
+  "Profiler_SourcePosition",
+  "Profiler_SourcePositionOptimized",
+  "Profiler_StringAllocation",
+  "Profiler_StringInterpolation",
+  "Profiler_ToggleRecordAllocation",
+  "Profiler_TrivialRecordAllocation",
+  "Profiler_TypedArrayAllocation",
+  "Profiler_GetSourceReport",
+  "Service_Profile",
+  // No realpath.
+  "Dart2JSCompilerStats",
+  "Dart2JSCompileAll",
+};
+
+// Expected to fail/crash.
+const char* kExpectFail[] = {
+  "Fail0",
+  "Fail1",
+  "Fail2",
+  "IsolateReload_PendingUnqualifiedCall_InstanceToStatic",
+  "IsolateReload_PendingUnqualifiedCall_StaticToInstance",
+  "IsolateReload_PendingConstructorCall_AbstractToConcrete",
+  "IsolateReload_PendingConstructorCall_ConcreteToAbstract",
+  "IsolateReload_PendingStaticCall_DefinedToNSM",
+  "IsolateReload_PendingStaticCall_NSMToDefined",
+  "ArrayNew_Overflow_Crash",
+  "AllocGeneric_Overflow",
+  "CodeImmutability",
+  "SNPrint_BadArgs",
+};
+
+// Bugs to fix, or things that are not yet impelemnted.
+const char* kBugs[] = {
+  // pthreads not using specified stack size.
+  "StackOverflowStacktraceInfo",
+  // Needs OS::GetCurrentThreadCPUMicros.
+  "Timeline_Dart_TimelineDuration",
+  "Timeline_Dart_TimelineInstant"
+  "Timeline_Dart_TimelineAsyncDisabled",
+  "Timeline_Dart_TimelineAsync",
+  "Timeline_Dart_TimelineGetTrace",
+  "Timeline_Dart_TimelineGetTraceOnlyDartEvents",
+  "Timeline_Dart_TimelineGetTraceWithDartEvents",
+  "Timeline_Dart_TimelineGetTraceGlobalOverride",
+  "Timeline_Dart_GlobalTimelineGetTrace",
+  "Timeline_Dart_GlobalTimelineGetTrace_Threaded",
+  "TimelineEventDuration",
+  "TimelineEventDurationPrintJSON",
+  "TimelineEventArguments",
+  "TimelineEventArgumentsPrintJSON",
+  "TimelineEventBufferPrintJSON",
+  "TimelineEventCallbackRecorderBasic",
+  "TimelineAnalysis_ThreadBlockCount",
+  "TimelineRingRecorderJSONOrder",
+  "TimelinePauses_BeginEnd",
+  // Crash.
+  "FindCodeObject",
+  // Needs OS::Sleep.
+  "MessageHandler_Run",
+  "Sleep",
+  // Calls VirtualMemory::FreeSubSegment.
+  "GrowableObjectArray",
+  "PrintJSON",
+  "GenerateSource",
+  "FreeVirtualMemory",
+  // Several missing calls.
+  "OsFuncs",
+  // OS::AlignedAllocate.
+  "OSAlignedAllocate",
+  // Needs NativeSymbolResolver
+  "Service_PersistentHandles",
+  // Need to investigate:
+  "ThreadPool_RunOne",
+  "ThreadPool_WorkerTimeout",
+  "Monitor",
+  "ThreadIterator_AddFindRemove",
+  // Needs Utils::HostToBigEndian16
+  "Endianity",
+};
+
+
+static bool contains(const char** list, intptr_t len, const char* str) {
+  for (intptr_t i = 0; i < len; i++) {
+    if (strcmp(list[i], str) == 0) {
+      return true;
+    }
+  }
+  return false;
+}
+
+
+static bool isSkip(const char* test) {
+  return contains(
+      kSkip, sizeof(kSkip) / sizeof(kSkip[0]), test);
+}
+
+
+static bool isExpectFail(const char* test) {
+  return contains(
+      kExpectFail, sizeof(kExpectFail) / sizeof(kExpectFail[0]), test);
+}
+
+
+static bool isBug(const char* test) {
+  return contains(kBugs, sizeof(kBugs) / sizeof(kBugs[0]), test);
+}
+
+
+static int run_test(const char* test_name) {
+  const intptr_t kArgc = 2;
+  const char* argv[3];
+  argv[0] = kRunVmTestsPath;
+  argv[1] = test_name;
+
+  mx_handle_t p = mxio_start_process(argv[0], kArgc, argv);
+  if (p < 0) {
+    printf("process failed to start\n");
+    return -1;
+  }
+
+  mx_signals_state_t state;
+  mx_status_t r = mx_handle_wait_one(
+      p, MX_SIGNAL_SIGNALED, MX_TIME_INFINITE, &state);
+  if (r != NO_ERROR) {
+    printf("[process(%x): wait failed? %d]\n", p, r);
+    return -1;
+  }
+
+  mx_process_info_t proc_info;
+  mx_ssize_t ret = mx_handle_get_info(
+      p, MX_INFO_PROCESS, &proc_info, sizeof(proc_info));
+  if (ret != sizeof(proc_info)) {
+    printf("[process(%x): handle_get_info failed? %ld]\n", p, ret);
+    return -1;
+  }
+
+  mx_handle_close(p);
+  return proc_info.return_code;
+}
+
+
+static void trim(char* line) {
+  const intptr_t line_len = strlen(line);
+  if (line[line_len - 1] == '\n') {
+    line[line_len - 1] = '\0';
+  }
+}
+
+
+static bool should_run(const char* test) {
+  return !(test[0] == '#') && !isSkip(test);
+}
+
+
+static void handle_result(intptr_t result, const char* test) {
+  if (result != 0) {
+    if (!isExpectFail(test) && !isBug(test)) {
+      printf("******** Test %s FAILED\n", test);
+    }
+  } else {
+    if (isExpectFail(test)) {
+      printf("******** Test %s is expected to fail, but PASSED\n", test);
+    }
+    if (isBug(test)) {
+      printf("******** Test %s is marked as a bug, but PASSED\n", test);
+    }
+  }
+}
+
+
+int main(int argc, char** argv) {
+  if (argc <= 1) {
+    fprintf(stderr, "Pass the path to a file containing the list of tests\n");
+    return -1;
+  }
+  const char* tests_path = argv[1];
+
+  FILE* fp = fopen(tests_path, "r");
+  if (fp == NULL) {
+    fprintf(stderr, "Failed to read the file: %s\n", tests_path);
+    return -1;
+  }
+
+  char* test = NULL;
+  size_t len = 0;
+  ssize_t read;
+  while ((read = getline(&test, &len, fp)) != -1) {
+    trim(test);
+    if (!should_run(test)) {
+      continue;
+    }
+    intptr_t result = run_test(test);
+    handle_result(result, test);
+  }
+
+  fclose(fp);
+  if (test != NULL) {
+    free(test);
+  }
+  return 0;
+}
+
diff --git a/runtime/lib/function.cc b/runtime/lib/function.cc
index b7424f5..4241762 100644
--- a/runtime/lib/function.cc
+++ b/runtime/lib/function.cc
@@ -47,6 +47,19 @@
         const Object& receiver_b = Object::Handle(context_b.At(0));
         if (receiver_a.raw() == receiver_b.raw()) return Bool::True().raw();
       }
+    } else if (func_a.IsImplicitInstanceClosureFunction() &&
+               func_b.IsImplicitInstanceClosureFunction()) {
+      // TODO(rmacnak): Patch existing tears off during reload instead.
+      const Context& context_a = Context::Handle(receiver.context());
+      const Context& context_b = Context::Handle(
+          Closure::Cast(other).context());
+      const Object& receiver_a = Object::Handle(context_a.At(0));
+      const Object& receiver_b = Object::Handle(context_b.At(0));
+      if ((receiver_a.raw() == receiver_b.raw()) &&
+          (func_a.name() == func_b.name()) &&
+          (func_a.Owner() == func_b.Owner())) {
+        return Bool::True().raw();
+      }
     }
   }
   return Bool::False().raw();
diff --git a/runtime/observatory/lib/app.dart b/runtime/observatory/lib/app.dart
index 6212eb3..371c266 100644
--- a/runtime/observatory/lib/app.dart
+++ b/runtime/observatory/lib/app.dart
@@ -27,6 +27,5 @@
 part 'src/app/notification.dart';
 part 'src/app/page.dart';
 part 'src/app/settings.dart';
-part 'src/app/target_manager.dart';
 part 'src/app/view_model.dart';
 part 'src/app/analytics.dart';
diff --git a/runtime/observatory/lib/elements.dart b/runtime/observatory/lib/elements.dart
index e1889ac..4d9786e 100644
--- a/runtime/observatory/lib/elements.dart
+++ b/runtime/observatory/lib/elements.dart
@@ -83,7 +83,7 @@
 import 'package:observatory/src/elements/nav/vm_menu_wrapper.dart';
 import 'package:observatory/src/elements/view_footer.dart';
 import 'package:observatory/src/elements/vm_connect_target.dart';
-import 'package:observatory/src/elements/vm_connect_target_wrapper.dart';
+import 'package:observatory/src/elements/vm_connect.dart';
 
 export 'package:observatory/src/elements/helpers/rendering_queue.dart';
 
@@ -103,6 +103,7 @@
 export 'package:observatory/src/elements/nav/vm_menu.dart';
 export 'package:observatory/src/elements/view_footer.dart';
 export 'package:observatory/src/elements/vm_connect_target.dart';
+export 'package:observatory/src/elements/vm_connect.dart';
 
 // Even though this function does not invoke any asynchronous operation
 // it is marked as async to allow future backward compatible changes.
@@ -133,6 +134,6 @@
   NavVMMenuElement.tag.ensureRegistration();
   NavVMMenuElementWrapper.tag.ensureRegistration();
   ViewFooterElement.tag.ensureRegistration();
+  VMConnectElement.tag.ensureRegistration();
   VMConnectTargetElement.tag.ensureRegistration();
-  VMConnectTargetElementWrapper.tag.ensureRegistration();
 }
diff --git a/runtime/observatory/lib/elements.html b/runtime/observatory/lib/elements.html
index b1d51fa..731c907 100644
--- a/runtime/observatory/lib/elements.html
+++ b/runtime/observatory/lib/elements.html
@@ -42,5 +42,4 @@
 <link rel="import" href="src/elements/script_view.html">
 <link rel="import" href="src/elements/service_ref.html">
 <link rel="import" href="src/elements/timeline_page.html">
-<link rel="import" href="src/elements/vm_connect.html">
 <link rel="import" href="src/elements/vm_view.html">
diff --git a/runtime/observatory/lib/mocks.dart b/runtime/observatory/lib/mocks.dart
index 18d8805..facf17f 100644
--- a/runtime/observatory/lib/mocks.dart
+++ b/runtime/observatory/lib/mocks.dart
@@ -21,4 +21,6 @@
 part 'src/mocks/objects/target.dart';
 part 'src/mocks/objects/vm.dart';
 
+part 'src/mocks/repositories/crash_dump.dart';
 part 'src/mocks/repositories/notification.dart';
+part 'src/mocks/repositories/target.dart';
diff --git a/runtime/observatory/lib/models.dart b/runtime/observatory/lib/models.dart
index c047e9c..878a72c 100644
--- a/runtime/observatory/lib/models.dart
+++ b/runtime/observatory/lib/models.dart
@@ -25,4 +25,6 @@
 part 'src/models/objects/timeline_event.dart';
 part 'src/models/objects/vm.dart';
 
+part 'src/models/repositories/crash_dump.dart';
 part 'src/models/repositories/notification.dart';
+part 'src/models/repositories/target.dart';
diff --git a/runtime/observatory/lib/repositories.dart b/runtime/observatory/lib/repositories.dart
index 5e333ad..4e7cd44 100644
--- a/runtime/observatory/lib/repositories.dart
+++ b/runtime/observatory/lib/repositories.dart
@@ -5,6 +5,12 @@
 library repositories;
 
 import 'dart:async';
+import 'dart:convert';
+import 'dart:html';
 import 'package:observatory/models.dart' as M;
+import 'package:observatory/service_common.dart' as SC;
+import 'package:observatory/utils.dart';
 
 part 'src/repositories/notification.dart';
+part 'src/repositories/settings.dart';
+part 'src/repositories/target.dart';
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index b37eda2..a8bfabb 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -9,6 +9,7 @@
 class ObservatoryApplication extends Observable {
   static ObservatoryApplication app;
   final RenderingQueue queue = new RenderingQueue();
+  final TargetRepository targets = new TargetRepository();
   final NotificationRepository notifications = new NotificationRepository();
   final _pageRegistry = new List<Page>();
   LocationManager _locationManager;
@@ -17,7 +18,7 @@
   VM _vm;
   VM get vm => _vm;
 
-  set vm(VM vm) {
+  _setVM(VM vm) {
     if (_vm == vm) {
       // Do nothing.
       return;
@@ -31,9 +32,6 @@
       Logger.root.info('Registering new VM callbacks');
 
       vm.onConnect.then((_) {
-        if (vm is WebSocketVM) {
-          targets.add(vm.target);
-        }
         notifications.deleteDisconnectEvents();
       });
 
@@ -52,7 +50,6 @@
     }
     _vm = vm;
   }
-  final TargetManager targets;
   @reflectable final ObservatoryApplicationElement rootElement;
 
   TraceViewElement _traceView = null;
@@ -194,15 +191,20 @@
     currentPage = page;
   }
 
-  ObservatoryApplication(this.rootElement) :
-      targets = new TargetManager() {
+  ObservatoryApplication(this.rootElement) {
     _locationManager = new LocationManager(this);
-    vm = new WebSocketVM(targets.defaultTarget);
+    targets.onChange.listen((e) {
+      if (targets.current == null) return _setVM(null);
+      if ((_vm as WebSocketVM)?.target != targets.current) {
+        _setVM(new WebSocketVM(targets.current));
+      }
+    });
+    _setVM(new WebSocketVM(targets.current));
     _initOnce();
   }
 
   loadCrashDump(Map crashDump) {
-    this.vm = new FakeVM(crashDump['result']);
+    _setVM(new FakeVM(crashDump['result']));
     app.locationManager.go('#/vm');
   }
 
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index 7f51a8e..0129c34 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -18,7 +18,7 @@
   final ObservatoryApplication app;
   final ObservableMap<String, String> internalArguments =
       new ObservableMap<String, String>();
-  @observable ObservatoryElement element;
+  @observable HtmlElement element;
 
   Page(this.app);
 
@@ -370,7 +370,12 @@
 
   void onInstall() {
     if (element == null) {
-      element = new Element.tag('vm-connect');
+      element = new VMConnectElement(
+            ObservatoryApplication.app.targets,
+            new CrashDumpRepositoryMock(
+                load: ObservatoryApplication.app.loadCrashDump),
+            ObservatoryApplication.app.notifications,
+            queue: ObservatoryApplication.app.queue);
     }
     assert(element != null);
   }
diff --git a/runtime/observatory/lib/src/app/target_manager.dart b/runtime/observatory/lib/src/app/target_manager.dart
deleted file mode 100644
index 6620db0..0000000
--- a/runtime/observatory/lib/src/app/target_manager.dart
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-part of app;
-
-class ChromiumTargetLister {
-  /// Fetch the list of chromium [NetworkVMTargets].
-  static Future<List<WebSocketVMTarget>> fetch(String networkAddress) {
-    if (networkAddress == null) {
-      return new Future.error(null);
-    }
-    var encoded = Uri.encodeComponent(networkAddress);
-    var url = '/crdptargets/$encoded';
-    return HttpRequest.getString(url).then((String responseText) {
-      var list = JSON.decode(responseText);
-      if (list == null) {
-        return list;
-      }
-      for (var i = 0; i < list.length; i++) {
-        list[i] = new WebSocketVMTarget.fromMap(list[i]);
-      }
-      return list;
-    }).catchError((e) {
-      // An error occured while getting the list of Chrome targets.
-      // We eagerly request the list of targets, meaning this error can occur
-      // regularly. By catching it and dropping it, we avoid spamming errors
-      // on the console.
-    });
-  }
-}
-
-class TargetManager extends Observable {
-  static const _historyKey = 'history';
-  final SettingsGroup _settings = new SettingsGroup('targetManager');
-  final List history = new ObservableList();
-  WebSocketVMTarget defaultTarget;
-
-  String _networkAddressOfDefaultTarget() {
-    if (Utils.runningInJavaScript()) {
-      // We are running as JavaScript, use the same host that Observatory has
-      // been loaded from.
-      return 'ws://${window.location.host}/ws';
-    } else {
-      // Otherwise, assume we are running from Dart Editor and want to connect
-      // to the default host.
-      return 'ws://localhost:8181/ws';
-    }
-  }
-  TargetManager() {
-    _restore();
-    // Add a default standalone VM target.
-    defaultTarget = findOrMake(_networkAddressOfDefaultTarget());
-    assert(defaultTarget != null);
-    add(defaultTarget);
-  }
-
-  void clearHistory() {
-    history.clear();
-    _store();
-  }
-
-  WebSocketVMTarget findOrMake(String networkAddress) {
-    var target;
-    target = _find(networkAddress);
-    if (target != null) {
-      return target;
-    }
-    target = new WebSocketVMTarget(networkAddress);
-    return target;
-  }
-
-  /// Find by networkAddress.
-  WebSocketVMTarget _find(String networkAddress) {
-    var r;
-    history.forEach((item) {
-      if ((item.networkAddress == networkAddress) && (item.chrome == false)) {
-        r = item;
-      }
-    });
-    return r;
-  }
-
-  void add(WebSocketVMTarget item) {
-    if (item.chrome) {
-      // We don't store chrome tabs.
-      return;
-    }
-    if (history.contains(item)) {
-      return;
-    }
-    // Not inserting duplicates.
-    assert(_find(item.networkAddress) == null);
-    history.add(item);
-    _sort();
-    _store();
-  }
-
-  void remove(WebSocketVMTarget target) {
-    history.remove(target);
-    _sort();
-    _store();
-  }
-
-  void _sort() {
-    this.history.sort((WebSocketVMTarget a, WebSocketVMTarget b) {
-      return b.lastConnectionTime.compareTo(a.lastConnectionTime);
-    });
-  }
-
-  /// After making a change, update settings.
-  void _store() {
-    _sort();
-    _settings.set(_historyKey,  history);
-  }
-
-  /// Read settings from data store.
-  void _restore() {
-    this.history.clear();
-    var loaded = _settings.get(_historyKey);
-    if (loaded == null) {
-      return;
-    }
-    for (var i = 0; i < loaded.length; i++) {
-      loaded[i] = new WebSocketVMTarget.fromMap(loaded[i]);
-    }
-    this.history.addAll(loaded);
-    _sort();
-  }
-}
diff --git a/runtime/observatory/lib/src/elements/css/shared.css b/runtime/observatory/lib/src/elements/css/shared.css
index 75b35ce..1f32ad4 100644
--- a/runtime/observatory/lib/src/elements/css/shared.css
+++ b/runtime/observatory/lib/src/elements/css/shared.css
@@ -302,6 +302,11 @@
               0 2px 5px 0 rgba(0, 0, 0, 0.26);
 }
 
+input.textbox {
+  width: 20em;
+  font: 400 16px 'Montserrat', sans-serif;
+}
+
 @-webkit-keyframes fadeIn {
   0%   { opacity: 0; }
   100% { opacity: 1; }
@@ -473,16 +478,14 @@
 }
 
 /* vm-connect-target */
-/* TODO(cbernaschina) fix vm-connect-target-wrapped to vm-connect-target
-+when wrapper removed */
 
-vm-connect-target-wrapped > button.delete-button {
+vm-connect-target > button.delete-button {
   margin-left: 0.28em;
   padding: 4px;
   background: transparent;
   border: none !important;
 }
 
-vm-connect-target-wrapped > button.delete-button:hover {
+vm-connect-target > button.delete-button:hover {
   background: #ff0000;
 }
diff --git a/runtime/observatory/lib/src/elements/curly_block_wrapper.dart b/runtime/observatory/lib/src/elements/curly_block_wrapper.dart
index 2a141b5..4e2519a 100644
--- a/runtime/observatory/lib/src/elements/curly_block_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/curly_block_wrapper.dart
@@ -12,11 +12,13 @@
 typedef _callback();
 typedef CurlyBlockToggleCallback(bool a, _callback b);
 
+@bindable
 class CurlyBlockElementWrapper extends HtmlElement {
 
-  static final binder = new Binder<CurlyBlockElementWrapper>(
-    const [const Binding('expand'), const Binding('busy'),
-           const Binding('expandKey'), const Binding('callback')]);
+  static const binder = const Binder<CurlyBlockElementWrapper>(const {
+      'expand': #expand, 'busy': #busy, 'expandKey': #expandKey,
+      'callback': #callback
+    });
 
   static const tag = const Tag<CurlyBlockElementWrapper>('curly-block');
 
diff --git a/runtime/observatory/lib/src/elements/helpers/rendering_queue.dart b/runtime/observatory/lib/src/elements/helpers/rendering_queue.dart
index a6062c3..707de23 100644
--- a/runtime/observatory/lib/src/elements/helpers/rendering_queue.dart
+++ b/runtime/observatory/lib/src/elements/helpers/rendering_queue.dart
@@ -66,7 +66,8 @@
   Future _render() async {
     await _barrier.next;
     while (_queue.isNotEmpty) {
-      _queue.removeFirst().render();
+      _queue.first.render();
+      _queue.removeFirst();
     }
   }
 }
diff --git a/runtime/observatory/lib/src/elements/isolate_ref_wrapper.dart b/runtime/observatory/lib/src/elements/isolate_ref_wrapper.dart
index dc78739..93978c5 100644
--- a/runtime/observatory/lib/src/elements/isolate_ref_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/isolate_ref_wrapper.dart
@@ -13,10 +13,12 @@
 import 'package:observatory/src/elements/helpers/tag.dart';
 import 'package:observatory/src/elements/shims/binding.dart';
 
+@bindable
 class IsolateRefElementWrapper extends HtmlElement {
 
-  static final binder = new Binder<IsolateRefElementWrapper>(
-    const [const Binding('ref')]);
+  static const binder = const Binder<IsolateRefElementWrapper>(const {
+      'ref': #ref
+    });
 
   static const tag = const Tag<IsolateRefElementWrapper>('isolate-ref');
 
diff --git a/runtime/observatory/lib/src/elements/nav/class_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/class_menu_wrapper.dart
index d1e56ac..35fc448 100644
--- a/runtime/observatory/lib/src/elements/nav/class_menu_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/class_menu_wrapper.dart
@@ -10,9 +10,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/class_menu.dart';
 
+@bindable
 class NavClassMenuElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavClassMenuElementWrapper>(
-    const [const Binding('last'), const Binding('cls')]);
+  static const binder = const Binder<NavClassMenuElementWrapper>(const {
+      'last': #last, 'cls': #cls
+    });
 
   static const tag =
     const Tag<NavClassMenuElementWrapper>('class-nav-menu');
diff --git a/runtime/observatory/lib/src/elements/nav/isolate_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/isolate_menu_wrapper.dart
index c2cf8f3..3af85d2 100644
--- a/runtime/observatory/lib/src/elements/nav/isolate_menu_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/isolate_menu_wrapper.dart
@@ -13,9 +13,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/isolate_menu.dart';
 
+@bindable
 class NavIsolateMenuElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavIsolateMenuElementWrapper>(
-    const [const Binding('last'), const Binding('isolate')]);
+  static const binder = const Binder<NavIsolateMenuElementWrapper>(const {
+      'last':  #last, 'isolate': #isolate
+    });
 
   static const tag =
     const Tag<NavIsolateMenuElementWrapper>('isolate-nav-menu');
diff --git a/runtime/observatory/lib/src/elements/nav/library_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/library_menu_wrapper.dart
index 6e48155..1097bdc 100644
--- a/runtime/observatory/lib/src/elements/nav/library_menu_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/library_menu_wrapper.dart
@@ -10,9 +10,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/library_menu.dart';
 
+@bindable
 class NavLibraryMenuElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavLibraryMenuElementWrapper>(
-    const [const Binding('last'), const Binding('library')]);
+  static const binder = const Binder<NavLibraryMenuElementWrapper>(const {
+      'last': #last, 'library': #library
+    });
 
   static const tag =
     const Tag<NavLibraryMenuElementWrapper>('library-nav-menu');
diff --git a/runtime/observatory/lib/src/elements/nav/menu_item_wrapper.dart b/runtime/observatory/lib/src/elements/nav/menu_item_wrapper.dart
index 045d67a..7888745 100644
--- a/runtime/observatory/lib/src/elements/nav/menu_item_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/menu_item_wrapper.dart
@@ -9,9 +9,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/menu_item.dart';
 
+@bindable
 class NavMenuItemElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavMenuItemElementWrapper>(
-    const [const Binding('anchor'), const Binding('link')]);
+  static const binder = const Binder<NavMenuItemElementWrapper>(const {
+      'anchor': #anchor, 'link': #link
+    });
 
   static const tag =
     const Tag<NavMenuItemElementWrapper>('nav-menu-item');
diff --git a/runtime/observatory/lib/src/elements/nav/menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/menu_wrapper.dart
index c237fed..04577c6 100644
--- a/runtime/observatory/lib/src/elements/nav/menu_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/menu_wrapper.dart
@@ -9,10 +9,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/menu.dart';
 
+@bindable
 class NavMenuElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavMenuElementWrapper>(
-    const [const Binding('anchor'), const Binding('link'),
-           const Binding('last')]);
+  static const binder = const Binder<NavMenuElementWrapper>(const {
+      'anchor': #anchor, 'link': #link, 'last': #last
+    });
 
   static const tag =
     const Tag<NavMenuElementWrapper>('nav-menu');
diff --git a/runtime/observatory/lib/src/elements/nav/notify_wrapper.dart b/runtime/observatory/lib/src/elements/nav/notify_wrapper.dart
index 97f4ded..7676727 100644
--- a/runtime/observatory/lib/src/elements/nav/notify_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/notify_wrapper.dart
@@ -10,9 +10,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/notify.dart';
 
+@bindable
 class NavNotifyElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavNotifyElementWrapper>(
-    const [const Binding('notifications'), const Binding('notifyOnPause')]);
+  static const binder = const Binder<NavNotifyElementWrapper>(const {
+      'notifications': #notifications, 'notifyOnPause': #notifyOnPause
+    });
 
   static const tag = const Tag<NavNotifyElementWrapper>('nav-notify');
 
diff --git a/runtime/observatory/lib/src/elements/nav/refresh_wrapper.dart b/runtime/observatory/lib/src/elements/nav/refresh_wrapper.dart
index dcd1696..19e7cce 100644
--- a/runtime/observatory/lib/src/elements/nav/refresh_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/refresh_wrapper.dart
@@ -10,9 +10,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/refresh.dart';
 
+@bindable
 class NavRefreshElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavRefreshElementWrapper>(
-    const [const Binding('callback'), const Binding('label')]);
+  static const binder = const Binder<NavRefreshElementWrapper>(const {
+      'callback': #callback, 'label': #label
+    });
 
   static const tag = const Tag<NavRefreshElementWrapper>('nav-refresh');
 
diff --git a/runtime/observatory/lib/src/elements/nav/top_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/top_menu_wrapper.dart
index fbfebff..edc5e27 100644
--- a/runtime/observatory/lib/src/elements/nav/top_menu_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/top_menu_wrapper.dart
@@ -9,9 +9,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/top_menu.dart';
 
+@bindable
 class NavTopMenuElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavTopMenuElementWrapper>(
-    const [const Binding('last')]);
+  static const binder = const Binder<NavTopMenuElementWrapper>(const {
+      'last': #last
+    });
 
   static const tag = const Tag<NavTopMenuElementWrapper>('top-nav-menu');
 
diff --git a/runtime/observatory/lib/src/elements/nav/vm_menu_wrapper.dart b/runtime/observatory/lib/src/elements/nav/vm_menu_wrapper.dart
index ef71b2d..9327e19 100644
--- a/runtime/observatory/lib/src/elements/nav/vm_menu_wrapper.dart
+++ b/runtime/observatory/lib/src/elements/nav/vm_menu_wrapper.dart
@@ -14,9 +14,11 @@
 import 'package:observatory/src/elements/shims/binding.dart';
 import 'package:observatory/src/elements/nav/vm_menu.dart';
 
+@bindable
 class NavVMMenuElementWrapper extends HtmlElement {
-  static final binder = new Binder<NavVMMenuElementWrapper>(
-    const [const Binding('last'), const Binding('vm')]);
+  static const binder = const Binder<NavVMMenuElementWrapper>(const {
+      'last': #last, 'vm': #vm
+    });
 
   static const tag = const Tag<NavVMMenuElementWrapper>('vm-nav-menu');
 
diff --git a/runtime/observatory/lib/src/elements/shims/binding.dart b/runtime/observatory/lib/src/elements/shims/binding.dart
index 5e37609..c5425c4 100644
--- a/runtime/observatory/lib/src/elements/shims/binding.dart
+++ b/runtime/observatory/lib/src/elements/shims/binding.dart
@@ -5,57 +5,43 @@
 import 'dart:core';
 import 'dart:html';
 import 'dart:js';
+@MirrorsUsed(metaTargets: const [BindableAnnotation])
 import 'dart:mirrors';
 import 'package:js/js.dart';
 import 'package:js_util/js_util.dart';
 import 'package:polymer/polymer.dart';
 
-class Binding {
-  final String attribute;
-  final String property;
-  const Binding (attribute, [String property])
-      : attribute = attribute,
-        property = property == null ? attribute : property;
+const BindableAnnotation bindable = const BindableAnnotation();
+class BindableAnnotation {
+  const BindableAnnotation();
 }
 
+
 ///This is a temporary bridge between Polymer Bindings and the wrapper entities.
 class Binder<T extends HtmlElement> {
-  final List<Binding> attributes;
-  final callback;
+  final Map<String, Symbol> attributes;
 
-  Binder(List<Binding> attributes)
-      : attributes = attributes,
-        callback = _createCallback(T, attributes);
+  const Binder(Map<String, Symbol> attributes)
+      : attributes = attributes;
 
   registerCallback(T element) {
     assert(element != null);
-    setValue(element, 'bind', callback);
+    setValue(element, 'bind', allowInteropCaptureThis(_callback));
   }
 
-  static _createCallback(Type T, List<Binding> attributes){
-    final target = reflectClass(T);
-    final setters = <String, Symbol>{};
-    for (Binding binding in attributes){
-      var member = target.instanceMembers[new Symbol(binding.property + '=')];
-      if (!member.isSetter)
-        throw new ArgumentError(
-          '${binding.property} is not a Setter for class $T');
-      setters[binding.attribute] = new Symbol(binding.property);
+  void _callback(_this, name, value, [other]) {
+    final setter = attributes[name];
+    if (setter == null) return;
+    Bindable bindable;
+    if (identical(1, 1.0)) { // dart2js
+      bindable = getValue(getValue(value, '__dartBindable'), 'o') as Bindable;
+    } else { // vm
+      bindable = getValue(value, '__dartBindable');
     }
-    return allowInteropCaptureThis((_this, name, value, [other]) {
-      final setter = setters[name];
-      if (setter == null) return;
-      Bindable bindable;
-      if (identical(1, 1.0)) { // dart2js
-        bindable = getValue(getValue(value, '__dartBindable'), 'o') as Bindable;
-      } else { // vm
-        bindable = getValue(value, '__dartBindable');
-      }
-      var obj = reflect(_this);
-      obj.setField(setter, bindable.value);
-      bindable.open((value) {
-        obj.setField(setter, value);
-      });
+    var obj = reflect(_this);
+    obj.setField(setter, bindable.value);
+    bindable.open((value) {
+      obj.setField(setter, value);
     });
   }
 }
diff --git a/runtime/observatory/lib/src/elements/vm_connect.dart b/runtime/observatory/lib/src/elements/vm_connect.dart
index 37cc2a2..8539921 100644
--- a/runtime/observatory/lib/src/elements/vm_connect.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect.dart
@@ -4,61 +4,174 @@
 
 library vm_connect_element;
 
-import 'dart:convert';
 import 'dart:html';
+import 'dart:async';
+import 'dart:convert';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/helpers/tag.dart';
+import 'package:observatory/src/elements/helpers/rendering_scheduler.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';
+import 'package:observatory/src/elements/vm_connect_target.dart';
 
-import 'observatory_element.dart';
-import 'package:observatory/elements.dart';
-import 'package:observatory/service_html.dart';
-import 'package:polymer/polymer.dart';
+class VMConnectElement extends HtmlElement implements Renderable{
+  static const tag = const Tag<VMConnectElement>('vm-connect',
+                     dependencies: const [NavBarElement.tag,
+                                          NavTopMenuElement.tag,
+                                          NavNotifyElement.tag,
+                                          ViewFooterElement.tag,
+                                          VMConnectTargetElement.tag]);
 
-@CustomTag('vm-connect')
-class VMConnectElement extends ObservatoryElement {
-  @published String standaloneVmAddress = '';
+  RenderingScheduler _r;
 
-  VMConnectElement.created() : super.created() {
+  Stream<RenderedEvent<VMConnectElement>> get onRendered => _r.onRendered;
+
+  M.CrashDumpRepository _dump;
+  M.NotificationRepository _notifications;
+  M.TargetRepository _targets;
+  StreamSubscription _targetsSubscription;
+
+  String _address;
+
+  factory VMConnectElement(M.TargetRepository targets,
+                           M.CrashDumpRepository dump,
+                           M.NotificationRepository notifications,
+                           {String address: '', RenderingQueue queue}) {
+    assert(address != null);
+    assert(dump != null);
+    assert(notifications != null);
+    assert(targets != null);
+    VMConnectElement e = document.createElement(tag.name);
+    e._r = new RenderingScheduler(e, queue: queue);
+    e._address = address;
+    e._dump = dump;
+    e._notifications = notifications;
+    e._targets = targets;
+    return e;
   }
 
-  void _connect(WebSocketVMTarget target) {
-    app.vm = new WebSocketVM(target);
-    app.locationManager.goForwardingParameters('/vm');
-  }
+  VMConnectElement.created() : super.created();
 
   @override
   void attached() {
-    super.attached();
-    var fileInput = shadowRoot.querySelector('#crashDumpFile');
-    fileInput.onChange.listen(_onCrashDumpFileChange);
+    super.attached(); _r.enable();
+    _targetsSubscription = _targets.onChange.listen((_) => _r.dirty());
   }
 
-  String _normalizeStandaloneAddress(String networkAddress) {
+  @override
+  void detached() {
+    super.detached(); children = []; _r.disable(notify: true);
+    _targetsSubscription.cancel(); _targetsSubscription = null;
+  }
+
+  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 = 'Connect to a Dart VM',
+          new BRElement(), new HRElement(),
+          new DivElement()
+            ..classes = ['flex-row']
+            ..children = [
+              new DivElement()
+                ..classes = ['flex-item-40-percent']
+                ..children = [
+                  new HeadingElement.h2()..text = 'WebSocket',
+                  new BRElement(),
+                  new UListElement()
+                    ..children = _targets.list().map((target) {
+                      return new LIElement()
+                        ..children = [new VMConnectTargetElement(target,
+                          current: target == _targets.current, queue: _r.queue)
+                          ..onConnect.listen(_connect)
+                          ..onDelete.listen(_delete)
+                        ];
+                      }).toList(),
+                  new HRElement(),
+                  new FormElement()
+                    ..autocomplete = 'on'
+                    ..children = [
+                      _createAddressBox(),
+                      new SpanElement()..text = ' ',
+                      new ButtonElement()
+                        ..classes = ['vm_connect']
+                        ..text = 'Connect'
+                        ..onClick.listen((e) {
+                          e.preventDefault(); _create(); }),
+                    ],
+                  new BRElement(),
+                  new PreElement()
+                    ..classes = ['well']
+                    ..text = 'Run Standalone with: \'--observe\'',
+                  new HRElement()
+                ],
+              new DivElement()
+                ..classes = ['flex-item-20-percent'],
+              new DivElement()
+                ..classes = ['flex-item-40-percent']
+                ..children = [
+                  new HeadingElement.h2()..text = 'Crash dump',
+                  new BRElement(),
+                  _createCrushDumpLoader(),
+                  new BRElement(), new BRElement(),
+                  new PreElement()
+                    ..classes = ['well']
+                    ..text = 'Request a crash dump with:\n'
+                      '\'curl localhost:8181/_getCrashDump > dump.json\'',
+                  new HRElement()
+                ]
+            ],
+        ],
+      new ViewFooterElement(queue: _r.queue)
+    ];
+  }
+
+  TextInputElement _createAddressBox() {
+    var textbox = new TextInputElement()
+      ..classes = ['textbox']
+      ..placeholder = 'localhost:8181'
+      ..value = _address
+      ..onKeyUp
+        .where((e) => e.key == '\n')
+        .listen((e) { e.preventDefault(); _create(); });
+    textbox.onInput.listen((e) {
+      _address = textbox.value;
+    });
+    return textbox;
+  }
+
+  FileUploadInputElement _createCrushDumpLoader() {
+    FileUploadInputElement e = new FileUploadInputElement()
+      ..id = 'crashDumpFile';
+    e.onChange.listen((_) {
+      var reader = new FileReader();
+      reader.readAsText(e.files[0]);
+      reader.onLoad.listen((_) {
+        var crashDump = JSON.decode(reader.result);
+        _dump.load(crashDump);
+      });
+    });
+    return e;
+  }
+  void _create() {
+    if (_address == null || _address.isEmpty) return;
+    _targets.add(_normalizeStandaloneAddress(_address));
+  }
+  void _connect(TargetEvent e) => _targets.setCurrent(e.target);
+  void _delete(TargetEvent e) => _targets.delete(e.target);
+
+  static String _normalizeStandaloneAddress(String networkAddress) {
     if (networkAddress.startsWith('ws://')) {
       return networkAddress;
     }
     return 'ws://${networkAddress}/ws';
   }
-
-  void connectStandalone(Event e, var detail, Node target) {
-    // Prevent any form action.
-    e.preventDefault();
-    if (standaloneVmAddress == null) {
-      return;
-    }
-    if (standaloneVmAddress.isEmpty) {
-      return;
-    }
-    var targetAddress = _normalizeStandaloneAddress(standaloneVmAddress);
-    var target = app.targets.findOrMake(targetAddress);
-    _connect(target);
-  }
-
-  _onCrashDumpFileChange(e) {
-    var fileInput = shadowRoot.querySelector('#crashDumpFile');
-    var reader = new FileReader();
-    reader.readAsText(fileInput.files[0]);
-    reader.onLoad.listen((_) {
-      var crashDump = JSON.decode(reader.result);
-      app.loadCrashDump(crashDump);
-    });
-  }
 }
diff --git a/runtime/observatory/lib/src/elements/vm_connect.html b/runtime/observatory/lib/src/elements/vm_connect.html
deleted file mode 100644
index 53be73d..0000000
--- a/runtime/observatory/lib/src/elements/vm_connect.html
+++ /dev/null
@@ -1,60 +0,0 @@
-<link rel="import" href="../../../../packages/polymer/polymer.html">
-
-<polymer-element name="vm-connect">
-  <template>
-    <link rel="stylesheet" href="css/shared.css">
-    <style>
-      .textbox {
-        width: 20em;
-        font: 400 16px 'Montserrat', sans-serif;
-      }
-    </style>
-
-    <nav-bar>
-      <top-nav-menu last="{{ true }}"></top-nav-menu>
-      <nav-notify notifications="{{ app.notifications }}"></nav-notify>
-    </nav-bar>
-
-    <div class="content-centered">
-      <h1>Connect to a Dart VM</h1>
-      <br>
-      <hr>
-      <div class="flex-row">
-        <div class="flex-item-40-percent">
-          <h2>WebSocket</h2>
-          <br>
-          <ul>
-            <template repeat="{{ target in app.targets.history }}">
-              <template if="{{ target.standalone }}">
-                <li><vm-connect-target target="{{ target }}"></vm-connect-target></li>
-              </template>
-            </template>
-          </ul>
-          <hr>
-          <form autocomplete="on">
-            <input class="textbox" placeholder="localhost:8181" type="text" value="{{ standaloneVmAddress }}">
-            <input class="button" type="submit" value="Connect" on-click="{{ connectStandalone }}">
-          </form>
-          <br>
-          <pre class="well">Run Standalone with: '--observe'</pre>
-          <hr>
-        </div>
-
-        <div class="flex-item-20-percent"></div>
-        <div class="flex-item-40-percent">
-          <h2>Crash dump</h2>
-          <br>
-          <input type="file" id="crashDumpFile">
-          <br>
-          <br>
-          <pre class="well">Request a crash dump with:
-'curl localhost:8181/_getCrashDump > dump.json'</pre>
-          <hr>
-        </div>
-      </div>
-    </div>
-    <view-footer></view-footer>
-  </template>
-</polymer-element>
-
-<script type="application/dart" src="vm_connect.dart"></script>
diff --git a/runtime/observatory/lib/src/elements/vm_connect_target.dart b/runtime/observatory/lib/src/elements/vm_connect_target.dart
index befe6dd..3fa7d12 100644
--- a/runtime/observatory/lib/src/elements/vm_connect_target.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect_target.dart
@@ -18,7 +18,7 @@
 class VMConnectTargetElement extends HtmlElement implements Renderable{
 
   static const tag =
-    const Tag<VMConnectTargetElement>('vm-connect-target-wrapped');
+    const Tag<VMConnectTargetElement>('vm-connect-target');
 
   RenderingScheduler<VMConnectTargetElement> _r;
 
diff --git a/runtime/observatory/lib/src/elements/vm_connect_target_wrapper.dart b/runtime/observatory/lib/src/elements/vm_connect_target_wrapper.dart
deleted file mode 100644
index 1034061..0000000
--- a/runtime/observatory/lib/src/elements/vm_connect_target_wrapper.dart
+++ /dev/null
@@ -1,77 +0,0 @@
-// 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:observatory/app.dart';
-import 'package:observatory/service_html.dart';
-import 'package:observatory/src/elements/helpers/tag.dart';
-import 'package:observatory/src/elements/shims/binding.dart';
-import 'package:observatory/src/elements/vm_connect_target.dart';
-
-class VMConnectTargetElementWrapper extends HtmlElement {
-  static final binder = new Binder<VMConnectTargetElementWrapper>(
-    const [const Binding('target')]);
-
-  static const tag =
-    const Tag<VMConnectTargetElementWrapper>('vm-connect-target');
-
-  WebSocketVMTarget _target;
-  WebSocketVMTarget get target => _target;
-  void set target(WebSocketVMTarget target) { _target = target; render(); }
-
-  VMConnectTargetElementWrapper.created() : super.created() {
-    binder.registerCallback(this);
-    createShadowRoot();
-    render();
-  }
-
-  @override
-  void attached() {
-    super.attached();
-    render();
-  }
-
-  void render() {
-    if (target == null) return;
-
-    shadowRoot.children = [
-      new StyleElement()
-        ..text = '''
-        vm-connect-target-wrapped > button.delete-button {
-          margin-left: 0.28em;
-          padding: 4px;
-          background: transparent;
-          border: none !important;
-        }
-
-        vm-connect-target-wrapped > button.delete-button:hover {
-          background: #ff0000;
-        }''',
-      new VMConnectTargetElement(target, current: current,
-          queue: application.queue)
-        ..onConnect.listen(connectToVm)
-        ..onDelete.listen(deleteVm)
-    ];
-  }
-
-  static ObservatoryApplication get application => ObservatoryApplication.app;
-
-  bool get current {
-    if (application.vm == null) { return false; }
-    return (application.vm as WebSocketVM).target == target;
-  }
-
-  static void connectToVm(TargetEvent event) {
-    WebSocketVM currentVM = application.vm;
-    if ((currentVM == null) ||
-        currentVM.isDisconnected ||
-        (currentVM.target != event.target)) {
-      application.vm = new WebSocketVM(event.target);
-    }
-  }
-
-  static void deleteVm(TargetEvent event) {
-    application.targets.remove(event.target);
-  }
-}
diff --git a/runtime/observatory/lib/src/mocks/repositories/crash_dump.dart b/runtime/observatory/lib/src/mocks/repositories/crash_dump.dart
new file mode 100644
index 0000000..68488e9
--- /dev/null
+++ b/runtime/observatory/lib/src/mocks/repositories/crash_dump.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 void CrashDumpRepositoryMockCallback(Map);
+
+class CrashDumpRepositoryMock implements M.CrashDumpRepository {
+  final CrashDumpRepositoryMockCallback _load;
+
+  bool loadInvoked = false;
+
+  void load(Map dump) {
+    loadInvoked = true;
+    if (_load != null) {
+      _load(dump);
+    }
+  }
+
+  CrashDumpRepositoryMock({CrashDumpRepositoryMockCallback load})
+    : _load = load;
+}
diff --git a/runtime/observatory/lib/src/mocks/repositories/target.dart b/runtime/observatory/lib/src/mocks/repositories/target.dart
new file mode 100644
index 0000000..8321f86
--- /dev/null
+++ b/runtime/observatory/lib/src/mocks/repositories/target.dart
@@ -0,0 +1,72 @@
+// 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 TargetChangeEventMock implements M.TargetChangeEvent {
+  final TargetRepositoryMock repository;
+  const TargetChangeEventMock({this.repository});
+}
+
+typedef void TargetRepositoryMockStringCallback(String notification);
+typedef void TargetRepositoryMockTargetCallback(M.Target notification);
+
+class TargetRepositoryMock implements M.TargetRepository {
+  final StreamController<M.TargetChangeEvent> _onChange =
+      new StreamController<M.TargetChangeEvent>.broadcast();
+  Stream<M.TargetChangeEvent> get onChange => _onChange.stream;
+
+  bool get hasListeners => _onChange.hasListener;
+
+  final M.Target _current;
+  final Iterable<M.Target> _list;
+  final TargetRepositoryMockStringCallback _add;
+  final TargetRepositoryMockTargetCallback _setCurrent;
+  final TargetRepositoryMockTargetCallback _delete;
+
+  bool currentInvoked = false;
+  bool addInvoked = false;
+  bool listInvoked = false;
+  bool setCurrentInvoked = false;
+  bool deleteInvoked = false;
+
+  M.Target get current {
+    currentInvoked = true;
+    return _current;
+  }
+
+  void add(String val) {
+    addInvoked = true;
+    if (_add != null) _add(val);
+  }
+
+  Iterable<M.Target> list() {
+    listInvoked = true;
+    return _list;
+  }
+
+  void setCurrent(M.Target target) {
+    setCurrentInvoked = true;
+    if (_setCurrent != null) _setCurrent(target);
+  }
+
+  void delete(M.Target target) {
+    deleteInvoked = true;
+    if (_delete != null) _delete(target);
+  }
+
+  void triggerChangeEvent() {
+    _onChange.add(new TargetChangeEventMock(repository: this));
+  }
+
+  TargetRepositoryMock({M.Target current, Iterable<M.Target> list : const [],
+      TargetRepositoryMockStringCallback add,
+      TargetRepositoryMockTargetCallback setCurrent,
+      TargetRepositoryMockTargetCallback delete})
+    : _current = current,
+      _list = list,
+      _add = add,
+      _setCurrent = setCurrent,
+      _delete = delete;
+}
diff --git a/runtime/observatory/lib/src/models/repositories/crash_dump.dart b/runtime/observatory/lib/src/models/repositories/crash_dump.dart
new file mode 100644
index 0000000..8eb64c1
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/crash_dump.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 CrashDumpRepository {
+  void load(Map);
+}
diff --git a/runtime/observatory/lib/src/models/repositories/target.dart b/runtime/observatory/lib/src/models/repositories/target.dart
new file mode 100644
index 0000000..8df29ca
--- /dev/null
+++ b/runtime/observatory/lib/src/models/repositories/target.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 models;
+
+abstract class TargetChangeEvent {
+  TargetRepository get repository;
+}
+
+abstract class TargetRepository {
+  Stream<TargetChangeEvent> get onChange;
+
+  Target get current;
+  Iterable<Target> list();
+  void add(String);
+  void setCurrent(Target);
+  void delete(Target);
+}
diff --git a/runtime/observatory/lib/src/repositories/settings.dart b/runtime/observatory/lib/src/repositories/settings.dart
new file mode 100644
index 0000000..771c48e
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/settings.dart
@@ -0,0 +1,45 @@
+// 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;
+
+/// Static settings database.
+class _Settings {
+  static Storage _storage = window.localStorage;
+
+  /// Associated [value] with [key]. [value] must be JSON encodable.
+  static void set(String key, dynamic value) {
+    _storage[key] = JSON.encode(value);
+  }
+
+  /// Get value associated with [key]. Return value will be a JSON encodable
+  /// object.
+  static dynamic get(String key) {
+    var value = _storage[key];
+    if (value == null) {
+      return null;
+    }
+    return JSON.decode(value);
+  }
+}
+
+/// A group of settings each prefixed with group name and a dot.
+class SettingsRepository {
+  /// Group name
+  final String group;
+
+  SettingsRepository(this.group);
+
+  String _fullKey(String key) => '$group.$key';
+
+  void set(String key, dynamic value) {
+    var fullKey = _fullKey(key);
+    _Settings.set(fullKey, value);
+  }
+
+  dynamic get(String key) {
+    var fullKey = _fullKey(key);
+    return _Settings.get(fullKey);
+  }
+}
diff --git a/runtime/observatory/lib/src/repositories/target.dart b/runtime/observatory/lib/src/repositories/target.dart
new file mode 100644
index 0000000..69ba8c8
--- /dev/null
+++ b/runtime/observatory/lib/src/repositories/target.dart
@@ -0,0 +1,102 @@
+// 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 TargetChangeEvent implements M.TargetChangeEvent {
+  final TargetRepository repository;
+  TargetChangeEvent(this.repository);
+}
+
+class TargetRepository implements M.TargetRepository {
+
+  static const _historyKey = 'history';
+
+  final StreamController<TargetChangeEvent> _onChange;
+  final Stream<TargetChangeEvent> onChange;
+  final SettingsRepository _settings = new SettingsRepository('targetManager');
+
+  final List<SC.WebSocketVMTarget> _list = <SC.WebSocketVMTarget>[];
+  SC.WebSocketVMTarget current;
+
+  factory TargetRepository() {
+    var controller = new StreamController<TargetChangeEvent>();
+    var stream = controller.stream.asBroadcastStream();
+    return new TargetRepository._(controller, stream);
+  }
+
+  TargetRepository._(this._onChange, this.onChange) {
+    _restore();
+    if (_list.isEmpty) {
+      _list.add(new SC.WebSocketVMTarget(_networkAddressOfDefaultTarget()));
+    }
+    current = _list.first;
+  }
+
+  void add(String address) {
+    if (_find(address) != null) return;
+    _list.insert(0, new SC.WebSocketVMTarget(address));
+    _onChange.add(new TargetChangeEvent(this));
+    _store();
+  }
+
+  Iterable<SC.WebSocketVMTarget> list() => _list;
+
+  void setCurrent(M.Target t) {
+    SC.WebSocketVMTarget target = t as SC.WebSocketVMTarget;
+    if (!_list.contains(target)) return;
+    current = target;
+    _onChange.add(new TargetChangeEvent(this));
+  }
+
+  void delete(o) {
+    if (_list.remove(o)) {
+      if (o == current) {
+        current = null;
+      }
+      _onChange.add(new TargetChangeEvent(this));
+      _store();
+    }
+  }
+
+  /// Read settings from data store.
+  void _restore() {
+    _list.clear();
+    var loaded = _settings.get(_historyKey);
+    if (loaded == null) {
+      return;
+    }
+    _list.addAll(loaded.map((i) => new SC.WebSocketVMTarget.fromMap(i)));
+    _list.sort((SC.WebSocketVMTarget a, SC.WebSocketVMTarget b) {
+       return b.lastConnectionTime.compareTo(a.lastConnectionTime);
+    });
+  }
+
+  /// After making a change, update settings.
+  void _store() {
+    _settings.set(_historyKey,  _list);
+  }
+
+  /// Find by networkAddress.
+  SC.WebSocketVMTarget _find(String networkAddress) {
+    for (SC.WebSocketVMTarget item in _list) {
+      if (item.networkAddress == networkAddress) {
+        return item;
+      }
+    }
+    return null;
+  }
+
+  static String _networkAddressOfDefaultTarget() {
+    if (Utils.runningInJavaScript()) {
+      // We are running as JavaScript, use the same host that Observatory has
+      // been loaded from.
+      return 'ws://${window.location.host}/ws';
+    } else {
+      // Otherwise, assume we are running from Dart Editor and want to connect
+      // to the default host.
+      return 'ws://localhost:8181/ws';
+    }
+  }
+}
diff --git a/runtime/observatory/observatory_sources.gypi b/runtime/observatory/observatory_sources.gypi
index 30659e0..43099f1 100644
--- a/runtime/observatory/observatory_sources.gypi
+++ b/runtime/observatory/observatory_sources.gypi
@@ -25,7 +25,6 @@
     'lib/src/app/notification.dart',
     'lib/src/app/page.dart',
     'lib/src/app/settings.dart',
-    'lib/src/app/target_manager.dart',
     'lib/src/app/view_model.dart',
     'lib/src/cli/command.dart',
     'lib/src/cpu_profile/cpu_profile.dart',
@@ -170,9 +169,7 @@
     'lib/src/elements/timeline_page.html',
     'lib/src/elements/view_footer.dart',
     'lib/src/elements/vm_connect_target.dart',
-    'lib/src/elements/vm_connect_target_wrapper.dart',
     'lib/src/elements/vm_connect.dart',
-    'lib/src/elements/vm_connect.html',
     'lib/src/elements/vm_view.dart',
     'lib/src/elements/vm_view.html',
     'lib/src/mocks/exceptions/connection_exception.dart',
@@ -186,7 +183,9 @@
     'lib/src/mocks/objects/source_location.dart',
     'lib/src/mocks/objects/target.dart',
     'lib/src/mocks/objects/vm.dart',
+    'lib/src/mocks/repositories/crash_dump.dart',
     'lib/src/mocks/repositories/notification.dart',
+    'lib/src/mocks/repositories/target.dart',
     'lib/src/models/exceptions.dart',
     'lib/src/models/objects/breakpoint.dart',
     'lib/src/models/objects/class.dart',
@@ -204,8 +203,12 @@
     'lib/src/models/objects/target.dart',
     'lib/src/models/objects/timeline_event.dart',
     'lib/src/models/objects/vm.dart',
+    'lib/src/models/repositories/crash_dump.dart',
     'lib/src/models/repositories/notification.dart',
+    'lib/src/models/repositories/target.dart',
     'lib/src/repositories/notification.dart',
+    'lib/src/repositories/settings.dart',
+    'lib/src/repositories/target.dart',
     'lib/src/service/object.dart',
     'lib/tracer.dart',
     'lib/utils.dart',
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
new file mode 100644
index 0000000..15a853ca
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
@@ -0,0 +1,119 @@
+// 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/mocks.dart';
+import 'package:observatory/models.dart' as M;
+import 'package:observatory/src/elements/nav/notify.dart';
+import 'package:observatory/src/elements/vm_connect_target.dart';
+import 'package:observatory/src/elements/vm_connect.dart';
+
+main() {
+  VMConnectElement.tag.ensureRegistration();
+
+  final String nTag = NavNotifyElement.tag.name;
+  final String tTag = VMConnectTargetElement.tag.name;
+
+  group('instantiation', () {
+    test('default', () {
+      final VMConnectElement e = new VMConnectElement(
+          new TargetRepositoryMock(),
+          new CrashDumpRepositoryMock(),
+          new NotificationRepositoryMock());
+      expect(e, isNotNull, reason: 'element correctly created');
+    });
+  });
+  test('is correctly listening', () async {
+    final targets = new TargetRepositoryMock();
+    final VMConnectElement e = new VMConnectElement(targets,
+        new CrashDumpRepositoryMock(), new NotificationRepositoryMock());
+    document.body.append(e);
+    await e.onRendered.first;
+    expect(targets.hasListeners, isTrue, reason: 'is listening');
+    e.remove();
+    await e.onRendered.first;
+    expect(targets.hasListeners, isFalse, reason: 'is no more listening');
+  });
+  group('elements', () {
+    test('created after attachment', () async {
+      final targets = new TargetRepositoryMock(list: const [
+          const TargetMock(name: 't-1'), const TargetMock(name: 't-2'),
+          ]);
+      final VMConnectElement e = new VMConnectElement(targets,
+          new CrashDumpRepositoryMock(), new NotificationRepositoryMock());
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(targets.listInvoked, isTrue, reason: 'should invoke list()');
+      expect(targets.currentInvoked, isTrue, reason: 'should invoke current');
+      expect(e.children.length, isNonZero, reason: 'has elements');
+      expect(e.querySelectorAll(nTag).length, equals(1));
+      expect(e.querySelectorAll(tTag).length, equals(2));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+    test('react to update event', () async {
+      final list = <M.Target>[const TargetMock(name: 't-1')];
+      final targets = new TargetRepositoryMock(list: list);
+      final VMConnectElement e = new VMConnectElement(targets,
+          new CrashDumpRepositoryMock(), new NotificationRepositoryMock());
+      document.body.append(e);
+      await e.onRendered.first;
+      expect(e.querySelectorAll(tTag).length, equals(1));
+      list.add(const TargetMock(name: 't-2'));
+      targets.triggerChangeEvent();
+      await e.onRendered.first;
+      expect(e.querySelectorAll(tTag).length, equals(2));
+      e.remove();
+      await e.onRendered.first;
+      expect(e.children.length, isZero, reason: 'is empty');
+    });
+  });
+  group('invokes', () {
+    test('add on click', () async {
+      final address = 'ws://host:1234';
+      final list = <M.Target>[const TargetMock(name: 't-1')];
+      final targets = new TargetRepositoryMock(list: list,
+          add: expectAsync((String val) {
+            expect(val, equals(address));
+          }, count: 1, reason: 'should be invoked'));
+      final VMConnectElement e = new VMConnectElement(targets,
+          new CrashDumpRepositoryMock(), new NotificationRepositoryMock(),
+          address: address);
+      document.body.append(e);
+      await e.onRendered.first;
+      (e.querySelector('button.vm_connect') as ButtonElement).click();
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('connect', () async {
+      final list = <M.Target>[const TargetMock(name: 't-1')];
+      final targets = new TargetRepositoryMock(list: list,
+          setCurrent: expectAsync((M.Target t) {
+            expect(t, equals(list[0]));
+          }, count: 1, reason: 'should be invoked'));
+      final VMConnectElement e = new VMConnectElement(targets,
+          new CrashDumpRepositoryMock(), new NotificationRepositoryMock());
+      document.body.append(e);
+      await e.onRendered.first;
+      (e.querySelector(tTag) as VMConnectTargetElement).connect();
+      e.remove();
+      await e.onRendered.first;
+    });
+    test('delete', () async {
+      final list = <M.Target>[const TargetMock(name: 't-1')];
+      final targets = new TargetRepositoryMock(list: list,
+          delete: expectAsync((M.Target t) {
+            expect(t, equals(list[0]));
+          }, count: 1, reason: 'should be invoked'));
+      final VMConnectElement e = new VMConnectElement(targets,
+          new CrashDumpRepositoryMock(), new NotificationRepositoryMock());
+      document.body.append(e);
+      await e.onRendered.first;
+      (e.querySelector(tTag) as VMConnectTargetElement).delete();
+      e.remove();
+      await e.onRendered.first;
+    });
+  });
+}
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.html b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.html
new file mode 100644
index 0000000..f0e956d
--- /dev/null
+++ b/runtime/observatory/tests/observatory_ui/vm_connect/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/service/breakpoint_two_args_checked_test.dart b/runtime/observatory/tests/service/breakpoint_two_args_checked_test.dart
new file mode 100644
index 0000000..610af92
--- /dev/null
+++ b/runtime/observatory/tests/service/breakpoint_two_args_checked_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--error_on_bad_type --error_on_bad_override  --verbose_debug
+
+// This test is mostly interesting for DBC, which needs to patch two bytecodes
+// to create a breakpoint for fast Smi ops.
+
+import 'package:observatory/service_io.dart';
+import 'package:unittest/unittest.dart';
+import 'service_test_common.dart';
+import 'test_helper.dart';
+import 'dart:developer';
+
+const int LINE_A = 26;
+const int LINE_B = 27;
+const int LINE_C = 28;
+
+class NotGeneric { }
+
+testeeMain() {
+  var x = new List(1);
+  var y = 7;
+  debugger();
+  print("Statement");
+  x[0] = 3;         // Line A.
+  x is NotGeneric;  // Line B.
+  y & 4;            // Line C.
+}
+
+var tests = [
+
+hasStoppedAtBreakpoint,
+
+// Add breakpoints.
+(Isolate isolate) async {
+  var rootLib = await isolate.rootLibrary.load();
+  var script = rootLib.scripts[0];
+
+  var bpt1 = await isolate.addBreakpoint(script, LINE_A);
+  print(bpt1);
+  expect(bpt1.resolved, isTrue);
+  expect(await bpt1.location.getLine(), equals(LINE_A));
+
+  var bpt2 = await isolate.addBreakpoint(script, LINE_B);
+  print(bpt2);
+  expect(bpt2.resolved, isTrue);
+  expect(await bpt2.location.getLine(), equals(LINE_B));
+
+  var bpt3 = await isolate.addBreakpoint(script, LINE_C);
+  print(bpt3);
+  expect(bpt3.resolved, isTrue);
+  expect(await bpt3.location.getLine(), equals(LINE_C));
+},
+
+resumeIsolate,
+
+hasStoppedAtBreakpoint,
+stoppedAtLine(LINE_A),
+resumeIsolate,
+
+hasStoppedAtBreakpoint,
+stoppedAtLine(LINE_B),
+resumeIsolate,
+
+hasStoppedAtBreakpoint,
+stoppedAtLine(LINE_C),
+resumeIsolate,
+
+];
+
+main(args) => runIsolateTests(args, tests, testeeConcurrent: testeeMain);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 6318dfa..1233d18 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -14,7 +14,7 @@
 isolate_lifecycle_test: Pass, RuntimeError # Issue 24174
 
 # Disable on simulators.
-[ $arch == simarm || $arch == simmips || $arch == simarm64]
+[ $arch == simarm || $arch == simmips || $arch == simarm64 ]
 *: SkipSlow
 
 # All tests use dart:io
@@ -51,9 +51,12 @@
 evaluate_activation_in_method_class_test: CompileTimeError # Issue 24478
 
 [ $arch == simdbc || $arch == simdbc64 ]
-# TODO(vegorov) re-enable when debugger, coverage and profiling is completely
-# fixed for SIMDBC.
-*: Skip
+get_allocation_samples_test: RuntimeError # Profiling unimplemented.
+get_cpu_profile_timeline_rpc_test: RuntimeError # Profiling unimplemented.
+implicit_getter_setter_test: RuntimeError # Field guards unimplemented.
+get_stack_rpc_test: RuntimeError # Missing single stepping check at fast Smi op
+vm_restart_test: RuntimeError # Missing single stepping check at fast Smi op
+debugging_test: RuntimeError # Missing single stepping check at fast Smi op
 
 [ $hot_reload ]
 # Skip all service tests because random reloads interfere.
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index df140c5..15b1de4 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -191,8 +191,11 @@
   }
 
   Future<Process> _spawnCommon(String executable, List<String> arguments) {
-    print('** Launching $executable ${arguments.join(' ')}');
-    return Process.start(executable, arguments, environment: _TESTEE_SPAWN_ENV);
+    var environment = _TESTEE_SPAWN_ENV;
+    var bashEnvironment = new StringBuffer();
+    environment.forEach((k, v) => bashEnvironment.write("$k=$v "));
+    print('** Launching $bashEnvironment$executable ${arguments.join(' ')}');
+    return Process.start(executable, arguments, environment: environment);
   }
 
   Future<int> launch(bool pause_on_start,
@@ -327,7 +330,9 @@
                    pause_on_unhandled_exceptions,
                    trace_service, trace_compiler).then((port) async {
       if (mainArgs.contains("--gdb")) {
-        port = 8181;
+        var pid = process.process.pid;
+        var wait = new Duration(seconds: 10);
+        print("Testee has pid $pid, waiting $wait before continuing");
       }
       serviceWebsocketAddress = 'ws://localhost:$port/ws';
       serviceHttpAddress = 'http://localhost:$port';
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 7053458..f91c0bc 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -139,22 +139,6 @@
 cc/Profiler_TypedArrayAllocation: Skip
 cc/Profiler_GetSourceReport: Skip
 
-# TODO(vegorov) These tests are crashing because ICData objects can't be found
-cc/SourceReport_CallSites_PolymorphicCall: Skip
-cc/SourceReport_CallSites_SimpleCall: Skip
-cc/SourceReport_Coverage_AllFunctions: Skip
-cc/SourceReport_Coverage_ForceCompile: Skip
-cc/SourceReport_Coverage_AllFunctions_ForceCompile: Skip
-cc/SourceReport_Coverage_NestedFunctions: Skip
-cc/SourceReport_Coverage_SimpleCall: Skip
-cc/SourceReport_Coverage_UnusedClass_NoForceCompile: Skip
-cc/SourceReport_Coverage_UnusedClass_ForceCompile: Skip
-cc/SourceReport_Coverage_UnusedClass_ForceCompileError: Skip
-cc/SourceReport_MultipleReports: Skip
-cc/Coverage_Empty: Skip
-cc/Coverage_FilterFunction: Skip
-cc/Coverage_MainWithClass: Skip
-
 # TODO(vegorov) These tests don't seem to work if FLAG_interpret_irregexp
 # is switched on by default because they attempt to call regexp functions
 # directly instead of going through JSSyntaxRegExp_ExecuteMatch.
@@ -170,15 +154,7 @@
 cc/GuardFieldFinalVariableLengthListTest: Skip
 cc/GuardFieldSimpleTest: Skip
 
-# TODO(vegorov) Not all bytecodes have appropriate debug breaks.
-cc/Debug_BreakpointStubPatching: Skip
-cc/Debug_ExprClosureBreakpoint: Skip
-cc/Debug_StackTraceDump1: Skip
-cc/Debug_StepInto: Skip
-
-# TODO(vegorov) These parser tests rely on debugger.
-cc/Parser_AllocateVariables_CapturedVar: Skip
-cc/Parser_AllocateVariables_MiddleChain: Skip
+cc/Debug_StepInto: Fail # Missing single stepping check at fast Smi op
 
 # This test is meaningless for DBC as allocation stubs are not used.
 cc/RegenerateAllocStubs: Skip
diff --git a/runtime/tools/create_string_literal.py b/runtime/tools/create_string_literal.py
old mode 100644
new mode 100755
index 7b4b2ec..52a9b10
--- a/runtime/tools/create_string_literal.py
+++ b/runtime/tools/create_string_literal.py
@@ -1,3 +1,5 @@
+#!/usr/bin/env python
+#
 # Copyright (c) 2011, the Dart project authors.  Please see the AUTHORS file
 # for details. All rights reserved. Use of this source code is governed by a
 # BSD-style license that can be found in the LICENSE file.
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index b22a9d5..bb56889 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -45,17 +45,18 @@
   ]
 }
 
+
+vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
+                              [rebase_path("vm_sources.gypi")],
+                              "scope",
+                              ["vm_sources.gypi"])
+
+
 static_library("libdart_vm") {
   configs += ["..:dart_config",
               "..:dart_product_config",
               "..:dart_precompiled_runtime_config"]
   public_configs = [":libdart_vm_config"]
-
-  vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
-                                [rebase_path("vm_sources.gypi")],
-                                "scope",
-                                ["vm_sources.gypi"])
-
   set_sources_assignment_filter(["*_test.cc", "*_test.h"])
   sources = vm_sources_list.sources
   include_dirs = [
@@ -70,11 +71,6 @@
               "..:dart_precompiled_runtime_config"]
   public_configs = [":libdart_vm_config"]
   defines = [ "DART_NO_SNAPSHOT" ]
-  vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
-                                [rebase_path("vm_sources.gypi")],
-                                "scope",
-                                ["vm_sources.gypi"])
-
   set_sources_assignment_filter(["*_test.cc", "*_test.h"])
   sources = vm_sources_list.sources
   include_dirs = [
@@ -89,11 +85,6 @@
               "..:dart_precompiler_config"]
   public_configs = [":libdart_vm_config"]
   defines = [ "DART_NO_SNAPSHOT" ]
-  vm_sources_list = exec_script("../../tools/gypi_to_gn.py",
-                                [rebase_path("vm_sources.gypi")],
-                                "scope",
-                                ["vm_sources.gypi"])
-
   set_sources_assignment_filter(["*_test.cc", "*_test.h"])
   sources = vm_sources_list.sources
   include_dirs = [
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 1bc179c..ca099b5 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1874,10 +1874,7 @@
         ASSERT(error.IsNull());
 #ifndef PRODUCT
         Isolate* isolate = thread->isolate();
-        // We cannot aggregate stats if isolate is shutting down.
-        if (isolate->HasMutatorThread()) {
-          isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats());
-        }
+        isolate->aggregate_compiler_stats()->Add(*thread->compiler_stats());
         thread->compiler_stats()->Clear();
 #endif  // PRODUCT
 
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index e84ae57..564e963 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -754,6 +754,23 @@
     }
   }
 
+  DART_FORCE_INLINE static bool IsFastSmiOpcode(Instr instr) {
+    switch (DecodeOpcode(instr)) {
+      case Bytecode::kAddTOS:
+      case Bytecode::kSubTOS:
+      case Bytecode::kMulTOS:
+      case Bytecode::kBitOrTOS:
+      case Bytecode::kBitAndTOS:
+      case Bytecode::kEqualTOS:
+      case Bytecode::kLessThanTOS:
+      case Bytecode::kGreaterThanTOS:
+        return true;
+
+      default:
+        return false;
+    }
+  }
+
   DART_FORCE_INLINE static uint8_t DecodeArgc(Instr call) {
     ASSERT(IsCallOpcode(call));
     return (call >> 8) & 0xFF;
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 34a8d33..66894b5 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1344,11 +1344,10 @@
   CHECK_NO_ISOLATE(Isolate::Current());
   // TODO(16615): Validate isolate parameter.
   Isolate* iso = reinterpret_cast<Isolate*>(isolate);
-  if (iso->HasMutatorThread()) {
-    FATAL("Multiple mutators within one isolate is not supported.");
-  }
   if (!Thread::EnterIsolate(iso)) {
-    FATAL("Unable to Enter Isolate as Dart VM is shutting down");
+    FATAL("Unable to Enter Isolate : "
+          "Multiple mutators entering an isolate / "
+          "Dart VM is shutting down");
   }
   // A Thread structure has been associated to the thread, we do the
   // safepoint transition explicity here instead of using the
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index a52cf4a..6b50583 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1108,7 +1108,8 @@
 #if !defined(TARGET_ARCH_DBC)
       saved_value_(Code::null())
 #else
-      saved_value_(Bytecode::kTrap)
+      saved_value_(Bytecode::kTrap),
+      saved_value_fastsmi_(Bytecode::kTrap)
 #endif
     {
   ASSERT(!code.IsNull());
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 1d7e1ce..e78e839 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -235,6 +235,7 @@
   // DebugBreak. This is an instruction that was replaced. DebugBreak
   // will execute it after the breakpoint.
   Instr saved_value_;
+  Instr saved_value_fastsmi_;
 #endif
 
   friend class Debugger;
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 957bd6f..18fb194 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -54,12 +54,17 @@
                          CURRENT_FUNC, #param);                                \
   }
 
+#define CHECK_DEBUGGER(isolate)                                                \
+  if (isolate->debugger() == NULL) {                                           \
+    return Api::NewError("%s requires debugger support.", CURRENT_FUNC);       \
+  }
+
 
 DART_EXPORT intptr_t Dart_CacheObject(Dart_Handle object_in) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(object_in));
-  if (obj.IsApiError()) {
+  if (obj.IsApiError() || (I->debugger() == NULL)) {
     return -1;
   }
   return I->debugger()->CacheObject(obj);
@@ -69,6 +74,7 @@
 DART_EXPORT Dart_Handle Dart_GetCachedObject(intptr_t obj_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   if (!I->debugger()->IsValidObjectId(obj_id)) {
     return Api::NewError("%s: object id %" Pd " is invalid",
                          CURRENT_FUNC, obj_id);
@@ -208,6 +214,7 @@
                             Dart_ExceptionPauseInfo pause_info) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->SetExceptionPauseInfo(pause_info);
   return Api::Success();
 }
@@ -216,6 +223,9 @@
 DART_EXPORT Dart_ExceptionPauseInfo Dart_GetExceptionPauseInfo() {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  if (I->debugger() == NULL) {
+    return kNoPauseOnExceptions;
+  }
   return I->debugger()->GetExceptionPauseInfo();
 }
 
@@ -223,6 +233,7 @@
 DART_EXPORT Dart_Handle Dart_GetStackTrace(Dart_StackTrace* trace) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   CHECK_NOT_NULL(trace);
   *trace = reinterpret_cast<Dart_StackTrace>(
       I->debugger()->CurrentStackTrace());
@@ -233,6 +244,7 @@
 DART_EXPORT Dart_Handle Dart_GetStackTraceFromError(Dart_Handle handle,
                                                     Dart_StackTrace* trace) {
   DARTSCOPE(Thread::Current());
+  CHECK_DEBUGGER(T->isolate());
   CHECK_NOT_NULL(trace);
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
   if (obj.IsUnhandledException()) {
@@ -341,6 +353,7 @@
                             intptr_t line_number) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
 
   Debugger* debugger = I->debugger();
@@ -357,6 +370,7 @@
 DART_EXPORT Dart_Handle Dart_GetBreakpointURL(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   Debugger* debugger = I->debugger();
 
   Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
@@ -371,6 +385,7 @@
 DART_EXPORT Dart_Handle Dart_GetBreakpointLine(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   Debugger* debugger = I->debugger();
 
   Breakpoint* bpt = debugger->GetBreakpointById(bp_id);
@@ -392,6 +407,7 @@
                             Dart_Handle function_name_in) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   UNWRAP_AND_CHECK_PARAM(Library, library, library_in);
   UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in);
   UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in);
@@ -432,6 +448,7 @@
                             Dart_Handle function_name_in) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   UNWRAP_AND_CHECK_PARAM(Library, library, library_in);
   UNWRAP_AND_CHECK_PARAM(String, class_name, class_name_in);
   UNWRAP_AND_CHECK_PARAM(String, function_name, function_name_in);
@@ -468,6 +485,7 @@
 DART_EXPORT Dart_Handle Dart_RemoveBreakpoint(intptr_t bp_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->RemoveBreakpoint(bp_id);
   return Api::Success();
 }
@@ -476,6 +494,7 @@
 DART_EXPORT Dart_Handle Dart_SetStepOver() {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->SetStepOver();
   return Api::Success();
 }
@@ -484,6 +503,7 @@
 DART_EXPORT Dart_Handle Dart_SetStepInto() {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->SetSingleStep();
   return Api::Success();
 }
@@ -492,6 +512,7 @@
 DART_EXPORT Dart_Handle Dart_SetStepOut() {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   I->debugger()->SetStepOut();
   return Api::Success();
 }
@@ -500,6 +521,7 @@
 DART_EXPORT Dart_Handle Dart_GetInstanceFields(Dart_Handle object_in) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   UNWRAP_AND_CHECK_PARAM(Instance, obj, object_in);
   return Api::NewHandle(T, I->debugger()->GetInstanceFields(obj));
 }
@@ -508,6 +530,7 @@
 DART_EXPORT Dart_Handle Dart_GetStaticFields(Dart_Handle target) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   const Type& type_obj = Api::UnwrapTypeHandle(Z, target);
   if (type_obj.IsNull()) {
     return Api::NewError("%s expects argument 'target' to be a type",
@@ -521,6 +544,7 @@
 DART_EXPORT Dart_Handle Dart_GetLibraryFields(intptr_t library_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   const Library& lib =
       Library::Handle(Z, Library::GetLibrary(library_id));
   if (lib.IsNull()) {
@@ -534,6 +558,7 @@
 DART_EXPORT Dart_Handle Dart_GetGlobalVariables(intptr_t library_id) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
 
   const Library& lib = Library::Handle(Z, Library::GetLibrary(library_id));
   if (lib.IsNull()) {
@@ -548,6 +573,7 @@
                             Dart_ActivationFrame activation_frame,
                             Dart_Handle expr_in) {
   DARTSCOPE(Thread::Current());
+  CHECK_DEBUGGER(T->isolate());
   CHECK_AND_CAST(ActivationFrame, frame, activation_frame);
   UNWRAP_AND_CHECK_PARAM(String, expr, expr_in);
   return Api::NewHandle(T, frame->Evaluate(expr));
@@ -557,6 +583,7 @@
 DART_EXPORT Dart_Handle Dart_EvaluateExpr(Dart_Handle target_in,
                                           Dart_Handle expr_in) {
   DARTSCOPE(Thread::Current());
+  CHECK_DEBUGGER(T->isolate());
 
   const Object& target = Object::Handle(Z, Api::UnwrapHandle(target_in));
   if (target.IsError()) return target_in;
@@ -718,6 +745,7 @@
                             Dart_Handle* static_fields) {
   DARTSCOPE(Thread::Current());
   Isolate* I = T->isolate();
+  CHECK_DEBUGGER(I);
   if (!I->class_table()->IsValidIndex(cls_id)) {
     return Api::NewError("%s: %" Pd " is not a valid class id",
                          CURRENT_FUNC, cls_id);
@@ -967,6 +995,9 @@
 
 DART_EXPORT Dart_IsolateId Dart_GetIsolateId(Dart_Isolate dart_isolate) {
   Isolate* isolate = reinterpret_cast<Isolate*>(dart_isolate);
+  if (isolate->debugger() == NULL) {
+    return ILLEGAL_ISOLATE_ID;
+  }
   return isolate->debugger()->GetIsolateId();
 }
 
diff --git a/runtime/vm/debugger_dbc.cc b/runtime/vm/debugger_dbc.cc
index 5f82cd5..b4b6c1f 100644
--- a/runtime/vm/debugger_dbc.cc
+++ b/runtime/vm/debugger_dbc.cc
@@ -25,6 +25,11 @@
 }
 
 
+static Instr* FastSmiInstructionFromReturnAddress(uword pc) {
+  return reinterpret_cast<Instr*>(pc) - 2;
+}
+
+
 void CodeBreakpoint::PatchCode() {
   ASSERT(!is_enabled_);
   const Code& code = Code::Handle(code_);
@@ -54,6 +59,17 @@
       default:
         UNREACHABLE();
     }
+
+    // If this call is the fall-through for a fast Smi op, also disable the fast
+    // Smi op.
+    if ((Bytecode::DecodeOpcode(saved_value_) == Bytecode::kInstanceCall2) &&
+        Bytecode::IsFastSmiOpcode(*FastSmiInstructionFromReturnAddress(pc_))) {
+      saved_value_fastsmi_ = *FastSmiInstructionFromReturnAddress(pc_);
+      *FastSmiInstructionFromReturnAddress(pc_) =
+          Bytecode::Encode(Bytecode::kNop, 0, 0, 0);
+    } else {
+      saved_value_fastsmi_ = Bytecode::kTrap;
+    }
   }
   is_enabled_ = true;
 }
@@ -75,6 +91,12 @@
       default:
         UNREACHABLE();
     }
+
+    if (saved_value_fastsmi_ != Bytecode::kTrap) {
+      Instr current_instr = *FastSmiInstructionFromReturnAddress(pc_);
+      ASSERT(Bytecode::DecodeOpcode(current_instr) == Bytecode::kNop);
+      *FastSmiInstructionFromReturnAddress(pc_) = saved_value_fastsmi_;
+    }
   }
   is_enabled_ = false;
 }
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index ae38a71..e658740 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -7,6 +7,7 @@
 #include "vm/assembler.h"
 #include "vm/code_patcher.h"
 #include "vm/compiler.h"
+#include "vm/disassembler.h"
 #include "vm/intermediate_language.h"
 #include "vm/locations.h"
 #include "vm/parser.h"
@@ -52,6 +53,13 @@
       deoptimizing_code_(deoptimizing_code) {
   const TypedData& deopt_info = TypedData::Handle(
       code.GetDeoptInfoAtPc(frame->pc(), &deopt_reason_, &deopt_flags_));
+#if defined(DEBUG)
+  if (deopt_info.IsNull()) {
+    OS::PrintErr("Missing deopt info for pc %" Px "\n", frame->pc());
+    DisassembleToStdout formatter;
+    code.Disassemble(&formatter);
+  }
+#endif
   ASSERT(!deopt_info.IsNull());
   deopt_info_ = deopt_info.raw();
 
diff --git a/runtime/vm/intermediate_language_dbc.cc b/runtime/vm/intermediate_language_dbc.cc
index 0dda8e1..f1be32d 100644
--- a/runtime/vm/intermediate_language_dbc.cc
+++ b/runtime/vm/intermediate_language_dbc.cc
@@ -273,10 +273,10 @@
                  0, Location::NoLocation(),
                  LocationSummary::kCall) {
   __ CheckStack();
-  compiler->RecordSafepoint(locs());
-  compiler->AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
-                                 Thread::kNoDeoptId,
+  compiler->AddCurrentDescriptor(RawPcDescriptors::kOther,
+                                 deopt_id(),
                                  token_pos());
+  compiler->RecordAfterCall(this);
 }
 
 
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 697aef8..15091b5 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -989,6 +989,12 @@
 }
 
 
+Thread* Isolate::mutator_thread() const {
+  ASSERT(thread_registry() != NULL);
+  return thread_registry()->mutator_thread();
+}
+
+
 void Isolate::SetupInstructionsSnapshotPage(
     const uint8_t* instructions_snapshot_buffer) {
   InstructionsSnapshot snapshot(instructions_snapshot_buffer);
@@ -2585,6 +2591,11 @@
     // no_safepoint_scope_depth increments/decrements.
     MonitorLocker ml(threads_lock(), false);
 
+    // Check to make sure we don't already have a mutator thread.
+    if (is_mutator && mutator_thread_ != NULL) {
+      return NULL;
+    }
+
     // If a safepoint operation is in progress wait for it
     // to finish before scheduling this thread in.
     while (!bypass_safepoint && safepoint_handler()->SafepointInProgress()) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index b49d59b..9761071 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -177,15 +177,7 @@
     message_notify_callback_ = value;
   }
 
-  // Limited public access to BaseIsolate::mutator_thread_ for code that
-  // must treat the mutator as the default or a special case. Prefer code
-  // that works uniformly across all threads.
-  bool HasMutatorThread() {
-    return mutator_thread_ != NULL;
-  }
-  Thread* mutator_thread() const {
-    return mutator_thread_;
-  }
+  Thread* mutator_thread() const;
 
   const char* name() const { return name_; }
   const char* debugger_name() const { return debugger_name_; }
@@ -466,8 +458,7 @@
 
   // Mutator thread is used to aggregate compiler stats.
   CompilerStats* aggregate_compiler_stats() {
-    ASSERT(HasMutatorThread());
-    return mutator_thread_->compiler_stats();
+    return mutator_thread()->compiler_stats();
   }
 
   VMTagCounters* vm_tag_counters() {
@@ -693,8 +684,8 @@
   // DEPRECATED: Use Thread's methods instead. During migration, these default
   // to using the mutator thread (which must also be the current thread).
   Zone* current_zone() const {
-    ASSERT(Thread::Current() == mutator_thread_);
-    return mutator_thread_->zone();
+    ASSERT(Thread::Current() == mutator_thread());
+    return mutator_thread()->zone();
   }
 
   // Accessed from generated code:
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 158f655..b23dd3b 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -162,6 +162,20 @@
 }
 
 
+void InstanceMorpher::AppendTo(JSONArray* array) {
+  JSONObject jsobj(array);
+  jsobj.AddProperty("type", "Morpher");
+  jsobj.AddProperty("class", to_);
+  jsobj.AddProperty("instances", before()->length());
+  JSONArray map(&jsobj, "mapping");
+  for (int i = 0; i < mapping_.length(); i += 2) {
+    JSONArray pair(&map);
+    pair.AddValue(mapping_.At(i));
+    pair.AddValue(mapping_.At(i+1));
+  }
+}
+
+
 void ReasonForCancelling::Report(IsolateReloadContext* context) {
   const Error& error = Error::Handle(ToError());
   context->ReportError(error);
@@ -181,6 +195,22 @@
 }
 
 
+void ReasonForCancelling::AppendTo(JSONArray* array) {
+  JSONObject jsobj(array);
+  jsobj.AddProperty("type", "ReasonForCancelling");
+  const String& message = String::Handle(ToString());
+  jsobj.AddProperty("message", message);
+}
+
+
+void ClassReasonForCancelling::AppendTo(JSONArray* array) {
+  JSONObject jsobj(array);
+  jsobj.AddProperty("type", "ReasonForCancelling");
+  jsobj.AddProperty("class", from_);
+  const String& message = String::Handle(ToString());
+  jsobj.AddProperty("message", message);
+}
+
 RawError* IsolateReloadContext::error() const {
   ASSERT(has_error());
   // Report the first error to the surroundings.
@@ -190,6 +220,7 @@
   return error.raw();
 }
 
+
 class ScriptUrlSetTraits {
  public:
   static bool ReportStats() { return false; }
@@ -490,6 +521,31 @@
   }
 
   BackgroundCompiler::Enable();
+
+  if (FLAG_trace_reload) {
+    JSONStream stream;
+    ReportOnJSON(&stream);
+    OS::Print("\nJSON report:\n  %s\n", stream.ToCString());
+  }
+}
+
+
+void IsolateReloadContext::ReportOnJSON(JSONStream* stream) {
+  JSONObject jsobj(stream);
+  jsobj.AddProperty("type", "Reload");
+  jsobj.AddProperty("succeeded", !HasReasonsForCancelling());
+  if (HasReasonsForCancelling()) {
+    JSONArray array(&jsobj, "reasons");
+    for (intptr_t i = 0; i < reasons_to_cancel_reload_.length(); i++) {
+      ReasonForCancelling* reason = reasons_to_cancel_reload_.At(i);
+      reason->AppendTo(&array);
+    }
+  } else {
+    JSONArray array(&jsobj, "changes");
+    for (intptr_t i = 0; i < instance_morphers_.length(); i++) {
+      instance_morphers_.At(i)->AppendTo(&array);
+    }
+  }
 }
 
 
diff --git a/runtime/vm/isolate_reload.h b/runtime/vm/isolate_reload.h
index ce316f6..0a3b591 100644
--- a/runtime/vm/isolate_reload.h
+++ b/runtime/vm/isolate_reload.h
@@ -63,6 +63,9 @@
   // Dump the state of the morpher.
   void Dump() const;
 
+  // Append the morper info to JSON array.
+  void AppendTo(JSONArray* array);
+
   // Returns the list of objects that need to be morphed.
   ZoneGrowableArray<const Instance*>* before() const { return before_; }
   // Returns the list of morphed objects (matches order in before()).
@@ -100,6 +103,9 @@
   // Default implementation calls ToError.
   virtual RawString* ToString();
 
+  // Append the reason to JSON array.
+  virtual void AppendTo(JSONArray* array);
+
   // Concrete subclasses must override either ToError or ToString.
 };
 
@@ -110,6 +116,8 @@
   ClassReasonForCancelling(const Class& from, const Class& to)
       : from_(from), to_(to) { }
 
+  void AppendTo(JSONArray* array);
+
  protected:
   const Class& from_;
   const Class& to_;
@@ -163,9 +171,12 @@
   // Record problem for this reload.
   void AddReasonForCancelling(ReasonForCancelling* reason);
 
-  // Report all reasons for cancelling reload.
+  // Reports all reasons for cancelling reload.
   void ReportReasonsForCancelling();
 
+  // Reports the deails of a reload operation.
+  void ReportOnJSON(JSONStream* stream);
+
   // Store morphing operation.
   void AddInstanceMorpher(InstanceMorpher* morpher);
 
diff --git a/runtime/vm/isolate_reload_test.cc b/runtime/vm/isolate_reload_test.cc
index d060680..49672f6 100644
--- a/runtime/vm/isolate_reload_test.cc
+++ b/runtime/vm/isolate_reload_test.cc
@@ -1003,11 +1003,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("instance", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("instance", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-  EXPECT_EQ("instance", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("instance", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1043,11 +1043,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("static", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-  EXPECT_EQ("static", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1093,11 +1093,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("okay", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("okay", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-  EXPECT_EQ("okay", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("okay", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1143,11 +1143,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("exception", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-  EXPECT_EQ("exception", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1190,11 +1190,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("exception", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-  EXPECT_EQ("exception", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("exception", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1237,11 +1237,11 @@
 
   TestCase::SetReloadTestScript(kReloadScript);
 
-  EXPECT_EQ("static", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 
   lib = TestCase::GetReloadErrorOrRootLibrary();
   EXPECT_VALID(lib);
-  EXPECT_EQ("static", SimpleInvokeStr(lib, "main"));
+  EXPECT_STREQ("static", SimpleInvokeStr(lib, "main"));
 }
 
 
@@ -1289,6 +1289,109 @@
 }
 
 
+TEST_CASE(IsolateReload_TearOff_Equality) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo() => 'old';\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f1 = c.foo;\n"
+      "  reloadTest();\n"
+      "  var f2 = c.foo;\n"
+      "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo() => 'new';\n"
+      "}\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  var f1 = c.foo;\n"
+      "  reloadTest();\n"
+      "  var f2 = c.foo;\n"
+      "  return '${f1()} ${f2()} ${f1 == f2} ${identical(f1, f2)}';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("new new true false", SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
+TEST_CASE(IsolateReload_TearOff_List_Set) {
+  const char* kScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo() => 'old';\n"
+      "}\n"
+      "List list = new List(2);\n"
+      "Set set = new Set();\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  list[0] = c.foo;\n"
+      "  list[1] = c#foo;\n"
+      "  set.add(c.foo);\n"
+      "  set.add(c#foo);\n"
+      "  int countBefore = set.length;\n"
+      "  reloadTest();\n"
+      "  list[1] = c.foo;\n"
+      "  set.add(c.foo);\n"
+      "  set.add(c#foo);\n"
+      "  int countAfter = set.length;\n"
+      "  return '${list[0]()} ${list[1]()} ${list[0] == list[1]} '\n"
+      "         '${countBefore == 1} ${countAfter == 1} ${(set.first)()} '\n"
+      "         '${set.first == c.foo} ${set.first == c#foo} '\n"
+      "         '${set.remove(c#foo)}';\n"
+      "}\n";
+
+  Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
+  EXPECT_VALID(lib);
+
+  const char* kReloadScript =
+      "import 'test:isolate_reload_helper';\n"
+      "class C {\n"
+      "  foo() => 'new';\n"
+      "}\n"
+      "List list = new List(2);\n"
+      "Set set = new Set();\n"
+      "main() {\n"
+      "  var c = new C();\n"
+      "  list[0] = c.foo;\n"
+      "  list[1] = c#foo;\n"
+      "  set.add(c.foo);\n"
+      "  set.add(c#foo);\n"
+      "  int countBefore = set.length;\n"
+      "  reloadTest();\n"
+      "  list[1] = c.foo;\n"
+      "  set.add(c.foo);\n"
+      "  set.add(c#foo);\n"
+      "  int countAfter = set.length;\n"
+      "  return '${list[0]()} ${list[1]()} ${list[0] == list[1]} '\n"
+      "         '${countBefore == 1} ${countAfter == 1} ${(set.first)()} '\n"
+      "         '${set.first == c.foo} ${set.first == c#foo} '\n"
+      "         '${set.remove(c#foo)}';\n"
+      "}\n";
+
+  TestCase::SetReloadTestScript(kReloadScript);
+
+  EXPECT_STREQ("new new true true true new true true true",
+               SimpleInvokeStr(lib, "main"));
+
+  lib = TestCase::GetReloadErrorOrRootLibrary();
+  EXPECT_VALID(lib);
+}
+
+
 TEST_CASE(IsolateReload_EnumEquality) {
   const char* kScript =
       "enum Fruit {\n"
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 577cb91..c646dd6 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -412,6 +412,16 @@
     return String::NewFormatted(
         "Limitation: type parameters have changed for %s", from_.ToCString());
   }
+
+  void AppendTo(JSONArray* array) {
+    JSONObject jsobj(array);
+    jsobj.AddProperty("type", "ReasonForCancellingReload");
+    jsobj.AddProperty("kind", "TypeParametersChanged");
+    jsobj.AddProperty("class", to_);
+    jsobj.AddProperty("message",
+                      "Limitation: changing type parameters "
+                      "does not work with hot reload.");
+  }
 };
 
 
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 9e7dcbd..1b7cec3 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -1547,12 +1547,25 @@
       &Symbols::ClosureParameter(),
       &Object::dynamic_type());
 
-  const Function& parent = Function::ZoneHandle(func.parent_function());
-  if (parent.IsImplicitSetterFunction()) {
+  const Function& parent = Function::Handle(func.parent_function());
+  const String& target_name = String::Handle(parent.name());
+  const Class& owner = Class::Handle(parent.Owner());
+  Function& target = Function::ZoneHandle(owner.LookupFunction(target_name));
+  if (target.raw() != parent.raw()) {
+    ASSERT(Isolate::Current()->HasAttemptedReload());
+    if (target.IsNull() ||
+        (target.is_static() != parent.is_static()) ||
+        (target.kind() != parent.kind())) {
+      // TODO(26977): call noSuchMethod/throw NSME instead.
+      target = parent.raw();
+    }
+  }
+
+  if (target.IsImplicitSetterFunction()) {
     const TokenPosition ident_pos = func.token_pos();
     ASSERT(IsIdentifier());
     const String& field_name = *CurrentLiteral();
-    const Class& field_class = Class::ZoneHandle(Z, parent.Owner());
+    const Class& field_class = Class::ZoneHandle(Z, target.Owner());
     const Field& field =
         Field::ZoneHandle(Z, field_class.LookupInstanceField(field_name));
     const AbstractType& field_type = AbstractType::ZoneHandle(Z, field.type());
@@ -1560,7 +1573,7 @@
                              &Symbols::Value(),
                              &field_type);
     ASSERT(func.num_fixed_parameters() == 2);  // closure, value.
-  } else if (!parent.IsGetterFunction() && !parent.IsImplicitGetterFunction()) {
+  } else if (!target.IsGetterFunction() && !target.IsImplicitGetterFunction()) {
     const bool allow_explicit_default_values = true;
     SkipFunctionPreamble();
     ParseFormalParameterList(allow_explicit_default_values, false, &params);
@@ -1591,7 +1604,7 @@
     }
     func_args->set_names(arg_names);
   }
-  StaticCallNode* call = new StaticCallNode(token_pos, parent, func_args);
+  StaticCallNode* call = new StaticCallNode(token_pos, target, func_args);
   ReturnNode* return_node = new ReturnNode(token_pos, call);
   current_block_->statements->Add(return_node);
   return CloseBlock();
@@ -9293,7 +9306,16 @@
     LocalVariable* rethrow_stack_trace_var) {
   TRACE_PARSER("EnsureFinallyClause");
   ASSERT(parse || (is_async && (try_stack_ != NULL)));
-  OpenBlock();
+  // Increasing the loop level prevents the reuse of a parent context and forces
+  // the allocation of a local context to hold captured variables declared
+  // inside the finally clause. Otherwise, a captured variable gets allocated at
+  // different slots in the parent context each time the finally clause is
+  // reparsed, which is done to duplicate the ast. Since only one closure is
+  // kept due to canonicalization, it will access the correct slot in only one
+  // copy of the finally clause and the wrong slot in all others. By allocating
+  // a local context, all copies use the same slot in different local contexts.
+  // See issue #26948. This is a temporary fix until we eliminate reparsing.
+  OpenLoopBlock();
   if (parse) {
     ExpectToken(Token::kLBRACE);
   }
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index 394d795..6e3527a 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -53,7 +53,7 @@
 
 bool Profiler::initialized_ = false;
 SampleBuffer* Profiler::sample_buffer_ = NULL;
-
+ProfilerCounters Profiler::counters_;
 
 void Profiler::InitOnce() {
   // Place some sane restrictions on user controlled flags.
@@ -68,6 +68,8 @@
   NativeSymbolResolver::InitOnce();
   ThreadInterrupter::SetInterruptPeriod(FLAG_profile_period);
   ThreadInterrupter::Startup();
+  // Zero counters.
+  memset(&counters_, 0, sizeof(counters_));
   initialized_ = true;
 }
 
@@ -769,7 +771,9 @@
                           ProfilerDartStackWalker* dart_stack_walker,
                           uword pc,
                           uword fp,
-                          uword sp) {
+                          uword sp,
+                          ProfilerCounters* counters) {
+  ASSERT(counters != NULL);
 #if defined(TARGET_OS_WINDOWS)
   // Use structured exception handling to trap guard page access on Windows.
   __try {
@@ -783,14 +787,18 @@
 
   if (FLAG_profile_vm) {
     // Always walk the native stack collecting both native and Dart frames.
+    counters->stack_walker_native++;
     native_stack_walker->walk();
   } else if (StubCode::HasBeenInitialized() && exited_dart_code) {
+    counters->stack_walker_dart_exit++;
     // We have a valid exit frame info, use the Dart stack walker.
     dart_exit_stack_walker->walk();
   } else if (StubCode::HasBeenInitialized() && in_dart_code) {
+    counters->stack_walker_dart++;
     // We are executing Dart code. We have frame pointers.
     dart_stack_walker->walk();
   } else {
+    counters->stack_walker_none++;
     sample->SetAt(0, pc);
   }
 
@@ -1119,6 +1127,7 @@
 
   // Thread is not doing VM work.
   if (thread->task_kind() == Thread::kUnknownTask) {
+    counters_.bail_out_unknown_task++;
     return;
   }
 
@@ -1127,6 +1136,7 @@
     // The JumpToExceptionHandler stub manually adjusts the stack pointer,
     // frame pointer, and some isolate state before jumping to a catch entry.
     // It is not safe to walk the stack when executing this stub.
+    counters_.bail_out_jump_to_exception_handler++;
     return;
   }
 
@@ -1157,15 +1167,18 @@
   }
 
   if (!CheckIsolate(isolate)) {
+    counters_.bail_out_check_isolate++;
     return;
   }
 
   if (thread->IsMutatorThread() && isolate->IsDeoptimizing()) {
+    counters_.single_frame_sample_deoptimizing++;
     SampleThreadSingleFrame(thread, pc);
     return;
   }
 
   if (!InitialRegisterCheck(pc, fp, sp)) {
+    counters_.single_frame_sample_register_check++;
     SampleThreadSingleFrame(thread, pc);
     return;
   }
@@ -1177,6 +1190,7 @@
                                         sp,
                                         &stack_lower,
                                         &stack_upper)) {
+    counters_.single_frame_sample_get_and_validate_stack_bounds++;
     // Could not get stack boundary.
     SampleThreadSingleFrame(thread, pc);
     return;
@@ -1234,7 +1248,8 @@
                 &dart_stack_walker,
                 pc,
                 fp,
-                sp);
+                sp,
+                &counters_);
 }
 
 
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index b6b2417..dcea1d4 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -27,6 +27,23 @@
 class SampleBuffer;
 class ProfileTrieNode;
 
+struct ProfilerCounters {
+  // Count of bail out reasons:
+  int64_t bail_out_unknown_task;
+  int64_t bail_out_jump_to_exception_handler;
+  int64_t bail_out_check_isolate;
+  // Count of single frame sampling reasons:
+  int64_t single_frame_sample_deoptimizing;
+  int64_t single_frame_sample_register_check;
+  int64_t single_frame_sample_get_and_validate_stack_bounds;
+  // Count of stack walkers used:
+  int64_t stack_walker_native;
+  int64_t stack_walker_dart_exit;
+  int64_t stack_walker_dart;
+  int64_t stack_walker_none;
+};
+
+
 class Profiler : public AllStatic {
  public:
   static void InitOnce();
@@ -54,6 +71,11 @@
   static void SampleThread(Thread* thread,
                            const InterruptedThreadState& state);
 
+  static ProfilerCounters counters() {
+    // Copies the counter values.
+    return counters_;
+  }
+
  private:
   // Does not walk the thread's stack.
   static void SampleThreadSingleFrame(Thread* thread, uintptr_t pc);
@@ -61,6 +83,8 @@
 
   static SampleBuffer* sample_buffer_;
 
+  static ProfilerCounters counters_;
+
   friend class Thread;
 };
 
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index 6b3d839..f17f38f 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -2448,6 +2448,41 @@
   obj->AddProperty("timeSpan", MicrosecondsToSeconds(GetTimeSpan()));
   obj->AddPropertyTimeMicros("timeOriginMicros", min_time());
   obj->AddPropertyTimeMicros("timeExtentMicros", GetTimeSpan());
+
+  ProfilerCounters counters = Profiler::counters();
+  {
+    JSONObject counts(obj, "counters");
+    counts.AddProperty64(
+        "bail_out_unknown_task",
+        counters.bail_out_unknown_task);
+    counts.AddProperty64(
+        "bail_out_jump_to_exception_handler",
+        counters.bail_out_jump_to_exception_handler);
+    counts.AddProperty64(
+        "bail_out_check_isolate",
+        counters.bail_out_check_isolate);
+    counts.AddProperty64(
+        "single_frame_sample_deoptimizing",
+        counters.single_frame_sample_deoptimizing);
+    counts.AddProperty64(
+        "single_frame_sample_register_check",
+        counters.single_frame_sample_register_check);
+    counts.AddProperty64(
+        "single_frame_sample_get_and_validate_stack_bounds",
+        counters.single_frame_sample_get_and_validate_stack_bounds);
+    counts.AddProperty64(
+        "stack_walker_native",
+        counters.stack_walker_native);
+    counts.AddProperty64(
+        "stack_walker_dart_exit",
+        counters.stack_walker_dart_exit);
+    counts.AddProperty64(
+        "stack_walker_dart",
+        counters.stack_walker_dart);
+    counts.AddProperty64(
+        "stack_walker_none",
+        counters.stack_walker_none);
+  }
 }
 
 
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index 416dda5..de12ec7 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -122,6 +122,17 @@
     f->ptr()->usage_counter_++;
   }
 
+  DART_FORCE_INLINE static void IncrementICUsageCount(RawObject** entries,
+                                                      intptr_t offset,
+                                                      intptr_t args_tested) {
+    const intptr_t count_offset = ICData::CountIndexFor(args_tested);
+    const intptr_t raw_smi_old =
+        reinterpret_cast<intptr_t>(entries[offset + count_offset]);
+    const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1);
+    *reinterpret_cast<intptr_t*>(&entries[offset + count_offset]) =
+        raw_smi_new;
+  }
+
   DART_FORCE_INLINE static bool IsStrictEqualWithNumberCheck(RawObject* lhs,
                                                              RawObject* rhs) {
     if (lhs == rhs) {
@@ -588,7 +599,8 @@
                                                 RawObjectPool** pp,
                                                 uint32_t** pc,
                                                 RawObject*** FP,
-                                                RawObject*** SP) {
+                                                RawObject*** SP,
+                                                bool optimized) {
   ASSERT(icdata->GetClassId() == kICDataCid);
 
   const intptr_t kCheckedArgs = 1;
@@ -599,7 +611,8 @@
 
   bool found = false;
   const intptr_t length = Smi::Value(cache->length_);
-  for (intptr_t i = 0;
+  intptr_t i;
+  for (i = 0;
        i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
     if (cache->data()[i + 0] == receiver_cid) {
       top[0] = cache->data()[i + kCheckedArgs];
@@ -608,7 +621,11 @@
     }
   }
 
-  if (!found) {
+  if (found) {
+    if (!optimized) {
+      SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs);
+    }
+  } else {
     InlineCacheMiss(
         kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP);
   }
@@ -626,7 +643,8 @@
                                                 RawObjectPool** pp,
                                                 uint32_t** pc,
                                                 RawObject*** FP,
-                                                RawObject*** SP) {
+                                                RawObject*** SP,
+                                                bool optimized) {
   ASSERT(icdata->GetClassId() == kICDataCid);
 
   const intptr_t kCheckedArgs = 2;
@@ -638,7 +656,8 @@
 
   bool found = false;
   const intptr_t length = Smi::Value(cache->length_);
-  for (intptr_t i = 0;
+  intptr_t i;
+  for (i = 0;
        i < (length - (kCheckedArgs + 2)); i += (kCheckedArgs + 2)) {
     if ((cache->data()[i + 0] == receiver_cid) &&
         (cache->data()[i + 1] == arg0_cid)) {
@@ -648,7 +667,11 @@
     }
   }
 
-  if (!found) {
+  if (found) {
+    if (!optimized) {
+      SimulatorHelpers::IncrementICUsageCount(cache->data(), i, kCheckedArgs);
+    }
+  } else {
     InlineCacheMiss(
         kCheckedArgs, thread, icdata, call_base, top, *pc, *FP, *SP);
   }
@@ -762,12 +785,8 @@
     ASSERT(Bytecode::IsCallOpcode(*pc));                                       \
     const uint16_t kidx = Bytecode::DecodeD(*pc);                              \
     const RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));           \
-    RawObject** data = icdata->ptr()->ic_data_->ptr()->data();                 \
-    const intptr_t count_offset = ICData::CountIndexFor(2);                    \
-    const intptr_t raw_smi_old =                                               \
-        reinterpret_cast<intptr_t>(data[count_offset]);                        \
-    const intptr_t raw_smi_new = raw_smi_old + Smi::RawValue(1);               \
-    *reinterpret_cast<intptr_t*>(&data[count_offset]) = raw_smi_new;           \
+    RawObject** entries = icdata->ptr()->ic_data_->ptr()->data();              \
+    SimulatorHelpers::IncrementICUsageCount(entries, 0, 2);                    \
   } while (0);                                                                 \
 
 // Declare bytecode handler for a smi operation (e.g. AddTOS) with the
@@ -1389,8 +1408,9 @@
       // Lookup the funciton in the ICData.
       RawObject* ic_data_obj = SP[0];
       RawICData* ic_data = RAW_CAST(ICData, ic_data_obj);
-      RawArray* cache = ic_data->ptr()->ic_data_->ptr();
-      SP[0] = cache->data()[ICData::TargetIndexFor(
+      RawObject** data = ic_data->ptr()->ic_data_->ptr()->data();
+      SimulatorHelpers::IncrementICUsageCount(data, 0, 0);
+      SP[0] = data[ICData::TargetIndexFor(
           ic_data->ptr()->state_bits_ & 0x3)];
       RawObject** call_base = SP - argc;
       RawObject** call_top = SP;  // *SP contains function
@@ -1431,8 +1451,9 @@
       RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
       SimulatorHelpers::IncrementUsageCounter(
           RAW_CAST(Function, icdata->ptr()->owner_));
-      InstanceCall1(
-          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+      InstanceCall1(thread, icdata, call_base, call_top,
+                    &argdesc, &pp, &pc, &FP, &SP,
+                    false /* optimized */);
     }
 
     DISPATCH();
@@ -1456,8 +1477,9 @@
       RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
       SimulatorHelpers::IncrementUsageCounter(
           RAW_CAST(Function, icdata->ptr()->owner_));
-      InstanceCall2(
-          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+      InstanceCall2(thread, icdata, call_base, call_top,
+                    &argdesc, &pp, &pc, &FP, &SP,
+                    false /* optimized */);
     }
 
     DISPATCH();
@@ -1475,8 +1497,9 @@
 
       RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
       SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP));
-      InstanceCall1(
-          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+      InstanceCall1(thread, icdata, call_base, call_top,
+                    &argdesc, &pp, &pc, &FP, &SP,
+                    true /* optimized */);
     }
 
     DISPATCH();
@@ -1494,8 +1517,9 @@
 
       RawICData* icdata = RAW_CAST(ICData, LOAD_CONSTANT(kidx));
       SimulatorHelpers::IncrementUsageCounter(FrameFunction(FP));
-      InstanceCall2(
-          thread, icdata, call_base, call_top, &argdesc, &pp, &pc, &FP, &SP);
+      InstanceCall2(thread, icdata, call_base, call_top,
+                    &argdesc, &pp, &pc, &FP, &SP,
+                    true /* optimized */);
     }
 
     DISPATCH();
diff --git a/runtime/vm/simulator_dbc.h b/runtime/vm/simulator_dbc.h
index 7172bbe..2cbadce 100644
--- a/runtime/vm/simulator_dbc.h
+++ b/runtime/vm/simulator_dbc.h
@@ -127,7 +127,7 @@
               RawObject** call_top,
               RawObjectPool** pp,
               uint32_t** pc,
-              RawObject*** B,
+              RawObject*** FP,
               RawObject*** SP);
 
   void InlineCacheMiss(int checked_args,
@@ -136,7 +136,7 @@
                        RawObject** call_base,
                        RawObject** top,
                        uint32_t* pc,
-                       RawObject** B, RawObject** SP);
+                       RawObject** FP, RawObject** SP);
 
   void InstanceCall1(Thread* thread,
                      RawICData* icdata,
@@ -145,7 +145,8 @@
                      RawArray** argdesc,
                      RawObjectPool** pp,
                      uint32_t** pc,
-                     RawObject*** B, RawObject*** SP);
+                     RawObject*** FP, RawObject*** SP,
+                     bool optimized);
 
   void InstanceCall2(Thread* thread,
                      RawICData* icdata,
@@ -154,7 +155,8 @@
                      RawArray** argdesc,
                      RawObjectPool** pp,
                      uint32_t** pc,
-                     RawObject*** B, RawObject*** SP);
+                     RawObject*** FP, RawObject*** SP,
+                     bool optimized);
 
   // Longjmp support for exceptions.
   SimulatorSetjmpBuffer* last_setjmp_buffer() {
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index adf2a34..dd2c6df 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -26,6 +26,7 @@
 
   void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames);
   void PrepareForGC();
+  Thread* mutator_thread() const { return mutator_thread_; }
 
  private:
   Thread* active_list() const { return active_list_; }
diff --git a/runtime/vm/virtual_memory_android.cc b/runtime/vm/virtual_memory_android.cc
index f84e2ef..16aa834 100644
--- a/runtime/vm/virtual_memory_android.cc
+++ b/runtime/vm/virtual_memory_android.cc
@@ -83,7 +83,6 @@
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
   ASSERT(Thread::Current()->IsMutatorThread() ||
-         !Isolate::Current()->HasMutatorThread() ||
          Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
diff --git a/runtime/vm/virtual_memory_linux.cc b/runtime/vm/virtual_memory_linux.cc
index 8973345..0228f68 100644
--- a/runtime/vm/virtual_memory_linux.cc
+++ b/runtime/vm/virtual_memory_linux.cc
@@ -82,7 +82,6 @@
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
   ASSERT(Thread::Current()->IsMutatorThread() ||
-         !Isolate::Current()->HasMutatorThread() ||
          Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
diff --git a/runtime/vm/virtual_memory_macos.cc b/runtime/vm/virtual_memory_macos.cc
index 1d23ead..484ad78 100644
--- a/runtime/vm/virtual_memory_macos.cc
+++ b/runtime/vm/virtual_memory_macos.cc
@@ -83,7 +83,6 @@
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
   ASSERT(Thread::Current()->IsMutatorThread() ||
-         !Isolate::Current()->HasMutatorThread() ||
          Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
diff --git a/runtime/vm/virtual_memory_win.cc b/runtime/vm/virtual_memory_win.cc
index 8ea8fa5..2584613 100644
--- a/runtime/vm/virtual_memory_win.cc
+++ b/runtime/vm/virtual_memory_win.cc
@@ -66,7 +66,6 @@
 
 bool VirtualMemory::Protect(void* address, intptr_t size, Protection mode) {
   ASSERT(Thread::Current()->IsMutatorThread() ||
-         !Isolate::Current()->HasMutatorThread() ||
          Isolate::Current()->mutator_thread()->IsAtSafepoint());
   uword start_address = reinterpret_cast<uword>(address);
   uword end_address = start_address + size;
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index 79bfaa5..d61835c 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -400,7 +400,7 @@
  * To set the value of a header use the `set()` method:
  *
  *     request.headers.set(HttpHeaders.CACHE_CONTROL,
-                           'max-age=3600, must-revalidate');
+ *                         'max-age=3600, must-revalidate');
  *
  * To retrieve the value of a header use the `value()` method:
  *
diff --git a/tests/co19/co19-runtime.status b/tests/co19/co19-runtime.status
index 1af71e5..efbfd7a 100644
--- a/tests/co19/co19-runtime.status
+++ b/tests/co19/co19-runtime.status
@@ -194,9 +194,6 @@
 LibTest/typed_data/Float32x4/operator_division_A01_t02: RuntimeError # Issue #26675
 
 [ $hot_reload ]
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/getter_closurization_t08: Pass, Fail # Closure identity
-Language/Expressions/Property_Extraction/Ordinary_Member_Closurization/method_identical_t03: Pass, Fail # Closure identity
-Language/Expressions/Property_Extraction/conditional_t05: Pass, Fail # Closure identity
 Language/Expressions/Assignment/prefix_object_t02: Crash # Requires deferred libraries
 Language/Expressions/Constants/constant_constructor_t03: Crash # Requires deferred libraries
 Language/Expressions/Constants/identifier_denotes_a_constant_t06: Crash # Requires deferred libraries
diff --git a/tests/html/html.status b/tests/html/html.status
index c7afa75..ed15788 100644
--- a/tests/html/html.status
+++ b/tests/html/html.status
@@ -147,6 +147,7 @@
 text_event_test: RuntimeError # Issue 23437
 transition_event_test/functional: Skip # Times out. Issue 22167
 request_animation_frame_test: Skip # Times out. Issue 22167
+js_util_test/callConstructor: RuntimeError # Issue 26978
 
 [$runtime == ie10 ]
 # IE10 Feature support statuses-
@@ -170,6 +171,8 @@
 input_element_test/supported_month: Fail
 input_element_test/supported_time: Fail
 input_element_test/supported_week: Fail
+js_util_test/hasProperty: RuntimeError # Issue 26978
+js_util_test/getProperty: RuntimeError # Issue 26978
 media_stream_test/supported_MediaStreamEvent: Fail
 media_stream_test/supported_MediaStreamTrackEvent: Fail
 media_stream_test/supported_media: Fail
diff --git a/tests/language/language.status b/tests/language/language.status
index 61b35c9..34798b6 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -152,6 +152,7 @@
 stacktrace_rethrow_error_test: Pass, RuntimeError
 stacktrace_rethrow_nonerror_test: Pass, RuntimeError
 stacktrace_test: Pass, RuntimeError
+regress_26948_test: Skip # Crashes, regis investigating
 
 [ $noopt || $compiler == precompiler || $mode == product ]
 # Imports dart:mirrors
@@ -237,9 +238,6 @@
 library_env_test/has_mirror_support: RuntimeError, OK
 
 [ $arch == simdbc || $arch == simdbc64 ]
-# TODO(vegorov) StopInstr is unimplemented.
-vm/debug_break_enabled_vm_test/none: Skip
-
 # TODO(vegorov) Encoding limitation: StoreField bytecode only supports 256
 # fields in an object.
 large_class_declaration_test: Skip
@@ -249,7 +247,6 @@
 issue23244_test: Skip # Issue #26373
 
 [ $hot_reload ]
-bound_closure_equality_test: Pass, Fail # Closure identity
 static_closure_identical_test: Pass, Fail # Closure identity
 cha_deopt1_test: Crash # Requires deferred libraries
 cha_deopt2_test: Crash # Requires deferred libraries
diff --git a/tests/language/regress_26948_test.dart b/tests/language/regress_26948_test.dart
new file mode 100644
index 0000000..7e323f7
--- /dev/null
+++ b/tests/language/regress_26948_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import 'dart:async';
+import "package:expect/expect.dart";
+
+void check(Function f) {
+  Expect.isTrue(f());
+}
+
+Future doSync() async {
+   try {
+     await 123;
+  } finally {
+    var next = 5.0;
+    check(() => next == 5.0);
+  }
+}
+
+main() async {
+  for (int i = 0; i < 20; i++) {
+    await doSync();
+  }
+}
diff --git a/tools/VERSION b/tools/VERSION
index 8dbdf92..2092cfe 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 19
 PATCH 0
-PRERELEASE 0
+PRERELEASE 1
 PRERELEASE_PATCH 0
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index 9c2c9a4..19f4e04 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -9,7 +9,7 @@
 
 vars.update({
   "dartium_chromium_commit": "67a7ba9669f7bb0300ef35085d4e6bb98b1966cc",
-  "dartium_webkit_commit": "6d435325ef16ceb54f23f5ec6414650ce5ef79ef",
+  "dartium_webkit_commit": "241a4a90dd2aa42490243c2efcc8732ff8aa0a59",
   "chromium_base_revision": "338390",
 
   # We use mirrors of all github repos to guarantee reproducibility and
diff --git a/tools/gypi_to_gn.py b/tools/gypi_to_gn.py
index 1aa092c..ca62a12 100755
--- a/tools/gypi_to_gn.py
+++ b/tools/gypi_to_gn.py
@@ -129,10 +129,28 @@
   # Assume everything else is unchanged.
   return values
 
+def KeepOnly(values, filters):
+  """Recursively filters out strings not ending in "f" from "values"""
+
+  if isinstance(values, list):
+    return [v for v in values if v.endswith(tuple(filters))]
+
+  if isinstance(values, dict):
+    result = {}
+    for key, value in values.items():
+      new_key = KeepOnly(key, filters)
+      new_value = KeepOnly(value, filters)
+      result[new_key] = new_value
+    return result
+
+  return values
+
 def main():
   parser = OptionParser()
   parser.add_option("-r", "--replace", action="append",
     help="Replaces substrings. If passed a=b, replaces all substrs a with b.")
+  parser.add_option("-k", "--keep_only", default = [], action="append",
+    help="Keeps only files ending with the listed strings.")
   (options, args) = parser.parse_args()
 
   if len(args) != 1:
@@ -149,6 +167,9 @@
       assert len(split) == 2, "Replacement must be of the form 'key=value'."
       data = ReplaceSubstrings(data, split[0], split[1])
 
+  if options.keep_only != []:
+    data = KeepOnly(data, options.keep_only)
+
   # Sometimes .gypi files use the GYP syntax with percents at the end of the
   # variable name (to indicate not to overwrite a previously-defined value):
   #   'foo%': 'bar',