Version 1.17.0-dev.3.0

Merge commit 'c1e6aef400fd131ee8b260ef5bd90ef2aa9c9de1' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b247533..4daba9f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,21 @@
     `NetworkInterface.list` is supported, and `false` otherwise. Currently,
     `NetworkInterface.list` is not supported on Android.
 
+### Tool Changes
+
+* Pub
+  * TAR files created while publishing a package on Mac OS and Linux now use a
+    more portable format.
+
+  * Errors caused by invalid arguments now print the full usage information for
+    the command.
+
+  * SDK constraints for dependency overrides are no longer considered when
+    determining the total SDK constraint for a lockfile.
+
+  * A bug has been fixed in which a lockfile was considered up-to-date when it
+    actually wasn't.
+
 ## 1.16.0 - 2016-04-26
 
 ### Core library changes
diff --git a/DEPS b/DEPS
index a040da2..1339596 100644
--- a/DEPS
+++ b/DEPS
@@ -30,7 +30,7 @@
 
   # Revisions of /third_party/* dependencies.
   "args_tag": "@0.13.4",
-  "async_tag": "@1.9.0",
+  "async_tag": "@1.10.0",
   "barback-0.13.0_rev": "@34853",
   "barback-0.14.0_rev": "@36398",
   "barback-0.14.1_rev": "@38525",
@@ -41,7 +41,7 @@
   "charcode_tag": "@1.1.0",
   "chrome_rev" : "@19997",
   "cli_util_tag" : "@0.0.1+2",
-  "collection_rev": "@f6135e6350c63eb3f4dd12953b8d4363faff16fc",
+  "collection_tag": "@1.6.0",
   "convert_tag": "@1.0.0",
   "crypto_tag" : "@1.1.0",
   "csslib_tag" : "@0.12.0",
@@ -49,8 +49,8 @@
   "dart_services_rev" : "@7aea2574e6f3924bf409a80afb8ad52aa2be4f97",
   "dart_style_tag": "@0.2.4",
   "dartdoc_tag" : "@v0.9.0",
-  "dev_compiler_rev": "@ec95b3c45819f4d0de847588fdaa752a8e4651fb",
-  "fixnum_tag": "@0.10.4",
+  "dev_compiler_rev": "@a0557e2f76fc85a6e71fe8391d1beda69905a548",
+  "fixnum_tag": "@0.10.5",
   "func_rev": "@8d4aea75c21be2179cb00dc2b94a71414653094e",
   "glob_rev": "@704cf75e4f26b417505c5c611bdaacd8808467dd",
   "html_tag" : "@0.12.1+1",
@@ -62,7 +62,7 @@
   "intl_rev": "@a8b480b9c436f6c0ec16730804c914bdb4e30d53",
   "jinja2_rev": "@2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "@2.0.0",
-  "linter_rev": "@6d3bdf09b4326a411e44ff472953edd9003bc33a",
+  "linter_rev": "@ecfaed3ea52ea2b5a7d9e0a7db94cf1f92208280",
   "logging_rev": "@85d83e002670545e9039ad3985f0018ab640e597",
   "markdown_rev": "@4aaadf3d940bb172e1f6285af4d2b1710d309982",
   "matcher_tag": "@0.12.0",
@@ -79,7 +79,7 @@
   "pool_tag": "@1.2.1",
   "protobuf_tag": "@0.5.1+1",
   "pub_cache_tag": "@v0.1.0",
-  "pub_rev": "@217fc8ae2bdee58ebf4b11a6fa3d49624d90c0c4",
+  "pub_rev": "@0b96a97d61673cea04f69eb47b2ef2b5b37337d3",
   "pub_semver_tag": "@1.2.1",
   "quiver_tag": "@0.21.4",
   "resource_rev":"@a49101ba2deb29c728acba6fb86000a8f730f4b1",
@@ -102,7 +102,7 @@
   "typed_data_tag": "@1.1.2",
   "usage_rev": "@b5080dac0d26a5609b266f8fdb0d053bc4c1c638",
   "utf_rev": "@1f55027068759e2d52f2c12de6a57cce5f3c5ee6",
-  "watcher_tag": "@0.9.7",
+  "watcher_tag": "@0.9.7+2",
   "web_components_rev": "@6349e09f9118dce7ae1b309af5763745e25a9d61",
   "web_socket_channel_tag": "@1.0.0",
   "WebCore_rev": "@a86fe28efadcfc781f836037a80f27e22a5dad17",
@@ -163,7 +163,7 @@
   Var("dart_root") + "/third_party/pkg/cli_util":
       (Var("github_mirror") % "cli_util") + Var("cli_util_tag"),
   Var("dart_root") + "/third_party/pkg/collection":
-      (Var("github_mirror") % "collection") + Var("collection_rev"),
+      (Var("github_mirror") % "collection") + Var("collection_tag"),
   Var("dart_root") + "/third_party/pkg/convert":
       "https://github.com/dart-lang/convert.git" + Var("convert_tag"),
   Var("dart_root") + "/third_party/pkg/crypto":
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 5ba7fa1..833b0ec 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -9,12 +9,12 @@
 
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
+import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/dart/optype.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
-import 'package:analysis_server/src/services/completion/dart/optype.dart';
 
 const ASYNC = 'async';
 const ASYNC_STAR = 'async*';
@@ -221,11 +221,20 @@
 
   @override
   visitForStatement(ForStatement node) {
+    // Actual: for (va^)
+    // Parsed: for (va^; ;)
+    if (node.initialization == entity && entity is SimpleIdentifier) {
+      if (_isNextTokenSynthetic(entity, TokenType.SEMICOLON)) {
+        _addSuggestion(Keyword.VAR, DART_RELEVANCE_HIGH);
+      }
+    }
+    // Actual: for (int x i^)
+    // Parsed: for (int x; i^;)
     // Handle the degenerate case while typing - for (int x i^)
-    if (node.condition == entity && entity is SimpleIdentifier) {
-      Token entityToken = (entity as SimpleIdentifier).beginToken;
-      if (entityToken.previous.isSynthetic &&
-          entityToken.previous.type == TokenType.SEMICOLON) {
+    if (node.condition == entity &&
+        entity is SimpleIdentifier &&
+        node.variables != null) {
+      if (_isPreviousTokenSynthetic(entity, TokenType.SEMICOLON)) {
         _addSuggestion(Keyword.IN, DART_RELEVANCE_HIGH);
       }
     }
@@ -252,7 +261,11 @@
 
   @override
   visitIfStatement(IfStatement node) {
-    if (entity == node.thenStatement) {
+    if (_isPreviousTokenSynthetic(entity, TokenType.CLOSE_PAREN)) {
+      // Actual: if (x i^)
+      // Parsed: if (x) i^
+      _addSuggestion(Keyword.IS, DART_RELEVANCE_HIGH);
+    } else if (entity == node.thenStatement) {
       _addStatementKeywords(node);
     } else if (entity == node.condition) {
       _addExpressionKeywords(node);
@@ -570,4 +583,22 @@
 
   bool _inWhileLoop(AstNode node) =>
       node.getAncestor((p) => p is WhileStatement) != null;
+
+  static bool _isNextTokenSynthetic(Object entity, TokenType type) {
+    if (entity is AstNode) {
+      Token token = entity.beginToken;
+      Token nextToken = token.next;
+      return nextToken.isSynthetic && nextToken.type == type;
+    }
+    return false;
+  }
+
+  static bool _isPreviousTokenSynthetic(Object entity, TokenType type) {
+    if (entity is AstNode) {
+      Token token = entity.beginToken;
+      Token previousToken = token.previous;
+      return previousToken.isSynthetic && previousToken.type == type;
+    }
+    return false;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 5c10beb..b019d30 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -112,17 +112,19 @@
 
   @override
   void visitPropertyAccessorElement(PropertyAccessorElement element) {
-    int relevance;
-    if (element.library == containingLibrary) {
-      if (element.enclosingElement is ClassElement) {
-        relevance = DART_RELEVANCE_LOCAL_FIELD;
+    if (optype.includeReturnValueSuggestions) {
+      int relevance;
+      if (element.library == containingLibrary) {
+        if (element.enclosingElement is ClassElement) {
+          relevance = DART_RELEVANCE_LOCAL_FIELD;
+        } else {
+          relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
+        }
       } else {
-        relevance = DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE;
+        relevance = DART_RELEVANCE_DEFAULT;
       }
-    } else {
-      relevance = DART_RELEVANCE_DEFAULT;
+      addSuggestion(element, prefix: prefix, relevance: relevance);
     }
-    addSuggestion(element, prefix: prefix, relevance: relevance);
   }
 
   @override
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
index e8cc82d..3ddc75d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/optype.dart
@@ -464,12 +464,37 @@
 
   @override
   void visitForStatement(ForStatement node) {
-    optype.includeReturnValueSuggestions = true;
-    optype.includeTypeNameSuggestions = true;
-    optype.includeVoidReturnSuggestions = true;
-    // TODO (danrubel) void return suggestions only belong after
-    // the 2nd semicolon.  Return value suggestions only belong after the
-    // first or second semicolon.
+    var entity = this.entity;
+    if (_isEntityPrevTokenSynthetic()) {
+      // Actual: for (var v i^)
+      // Parsed: for (var i; i^;)
+    } else if (entity is Token &&
+        entity.isSynthetic &&
+        node.leftSeparator == entity) {
+      // Actual: for (String ^)
+      // Parsed: for (String; ;)
+      //                    ^
+      optype.includeVarNameSuggestions = true;
+    } else {
+      // for (^) {}
+      // for (Str^ str = null;) {}
+      // In theory it is possible to specify any expression in initializer,
+      // but for any practical use we need only types.
+      if (entity == node.initialization || entity == node.variables) {
+        optype.includeTypeNameSuggestions = true;
+      }
+      // for (; ^) {}
+      if (entity == node.condition) {
+        optype.includeTypeNameSuggestions = true;
+        optype.includeReturnValueSuggestions = true;
+      }
+      // for (; ; ^) {}
+      if (node.updaters.contains(entity)) {
+        optype.includeTypeNameSuggestions = true;
+        optype.includeReturnValueSuggestions = true;
+        optype.includeVoidReturnSuggestions = true;
+      }
+    }
   }
 
   @override
@@ -496,7 +521,10 @@
 
   @override
   void visitIfStatement(IfStatement node) {
-    if (identical(entity, node.condition)) {
+    if (_isEntityPrevTokenSynthetic()) {
+      // Actual: if (var v i^)
+      // Parsed: if (v) i^;
+    } else if (identical(entity, node.condition)) {
       optype.includeReturnValueSuggestions = true;
       optype.includeTypeNameSuggestions = true;
     } else if (identical(entity, node.thenStatement) ||
@@ -765,6 +793,16 @@
   }
 
   @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    if (entity is Token) {
+      Token token = entity;
+      if (token.isSynthetic || token.lexeme == ';') {
+        optype.includeVarNameSuggestions = true;
+      }
+    }
+  }
+
+  @override
   void visitTypeArgumentList(TypeArgumentList node) {
     NodeList<TypeName> arguments = node.arguments;
     for (TypeName typeName in arguments) {
@@ -817,16 +855,6 @@
   }
 
   @override
-  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
-   if (entity is Token) {
-     Token token = entity;
-     if (token.isSynthetic || token.lexeme == ';') {
-       optype.includeVarNameSuggestions = true;
-     }
-   }
-  }
-
-  @override
   void visitVariableDeclarationStatement(VariableDeclarationStatement node) {}
 
   @override
@@ -836,4 +864,20 @@
       optype.includeTypeNameSuggestions = true;
     }
   }
+
+  bool _isEntityPrevToken(TokenType expectedType) {
+    Object entity = this.entity;
+    if (entity is SimpleIdentifier && entity.token.isSynthetic) {
+      return entity.token.previous.type == expectedType;
+    }
+    return false;
+  }
+
+  bool _isEntityPrevTokenSynthetic() {
+    Object entity = this.entity;
+    if (entity is AstNode && entity.beginToken.previous?.isSynthetic ?? false) {
+      return true;
+    }
+    return false;
+  }
 }
diff --git a/pkg/analysis_server/lib/src/services/index/index.dart b/pkg/analysis_server/lib/src/services/index/index.dart
index bf5e47d..7270ac2 100644
--- a/pkg/analysis_server/lib/src/services/index/index.dart
+++ b/pkg/analysis_server/lib/src/services/index/index.dart
@@ -270,18 +270,22 @@
    * Index declarations in the given partially resolved [unit].
    */
   void indexDeclarations(CompilationUnit unit) {
-    PackageIndexAssembler assembler = new PackageIndexAssembler();
-    assembler.indexDeclarations(unit);
-    _putUnitIndexBuilder(unit, assembler);
+    String key = _getUnitKeyForElement(unit.element);
+    if (!indexMap.containsKey(key)) {
+      PackageIndexAssembler assembler = new PackageIndexAssembler();
+      assembler.indexDeclarations(unit);
+      _putUnitIndexBuilder(key, assembler);
+    }
   }
 
   /**
    * Index the given fully resolved [unit].
    */
   void indexUnit(CompilationUnit unit) {
+    String key = _getUnitKeyForElement(unit.element);
     PackageIndexAssembler assembler = new PackageIndexAssembler();
     assembler.indexUnit(unit);
-    _putUnitIndexBuilder(unit, assembler);
+    _putUnitIndexBuilder(key, assembler);
   }
 
   /**
@@ -315,13 +319,11 @@
     return locations;
   }
 
-  void _putUnitIndexBuilder(
-      CompilationUnit unit, PackageIndexAssembler assembler) {
+  void _putUnitIndexBuilder(String key, PackageIndexAssembler assembler) {
     PackageIndexBuilder indexBuilder = assembler.assemble();
     // Put the index into the map.
     List<int> indexBytes = indexBuilder.toBuffer();
     PackageIndex index = new PackageIndex.fromBuffer(indexBytes);
-    String key = _getUnitKeyForElement(unit.element);
     indexMap[key] = index;
   }
 }
diff --git a/pkg/analysis_server/test/integration/integration_tests.dart b/pkg/analysis_server/test/integration/integration_tests.dart
index 9b58405..58f4aaa 100644
--- a/pkg/analysis_server/test/integration/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/integration_tests.dart
@@ -17,9 +17,9 @@
 import 'integration_test_methods.dart';
 import 'protocol_matchers.dart';
 
-const Matcher isBool = const isInstanceOf<bool>('bool');
+const Matcher isBool = const isInstanceOf<bool>();
 
-const Matcher isInt = const isInstanceOf<int>('int');
+const Matcher isInt = const isInstanceOf<int>();
 
 const Matcher isNotification = const MatchesJsonObject(
     'notification', const {'event': isString},
@@ -27,7 +27,7 @@
 
 const Matcher isObject = isMap;
 
-const Matcher isString = const isInstanceOf<String>('String');
+const Matcher isString = const isInstanceOf<String>();
 
 final Matcher isResponse = new MatchesJsonObject('response', {'id': isString},
     optionalFields: {'result': anything, 'error': isRequestError});
diff --git a/pkg/analysis_server/test/mock_sdk.dart b/pkg/analysis_server/test/mock_sdk.dart
index 335a9b3..504d536 100644
--- a/pkg/analysis_server/test/mock_sdk.dart
+++ b/pkg/analysis_server/test/mock_sdk.dart
@@ -47,6 +47,7 @@
 }
 
 class bool extends Object {}
+
 abstract class num implements Comparable<num> {
   bool operator <(num other);
   bool operator <=(num other);
@@ -55,12 +56,21 @@
   num operator +(num other);
   num operator -(num other);
   num operator *(num other);
-  num operator %(num other);
   num operator /(num other);
+  int operator ^(int other);
+  int operator &(int other);
+  int operator |(int other);
+  int operator <<(int other);
+  int operator >>(int other);
+  int operator ~/(num other);
+  num operator %(num other);
+  int operator ~();
   int toInt();
+  double toDouble();
   num abs();
   int round();
 }
+
 abstract class int extends num {
   bool get isEven => false;
   int operator -();
@@ -68,7 +78,36 @@
                             { int radix,
                               int onError(String source) });
 }
-class double extends num {}
+
+abstract class double extends num {
+  static const double NAN = 0.0 / 0.0;
+  static const double INFINITY = 1.0 / 0.0;
+  static const double NEGATIVE_INFINITY = -INFINITY;
+  static const double MIN_POSITIVE = 5e-324;
+  static const double MAX_FINITE = 1.7976931348623157e+308;
+
+  double remainder(num other);
+  double operator +(num other);
+  double operator -(num other);
+  double operator *(num other);
+  double operator %(num other);
+  double operator /(num other);
+  int operator ~/(num other);
+  double operator -();
+  double abs();
+  double get sign;
+  int round();
+  int floor();
+  int ceil();
+  int truncate();
+  double roundToDouble();
+  double floorToDouble();
+  double ceilToDouble();
+  double truncateToDouble();
+  external static double parse(String source,
+                               [double onError(String source)]);
+}
+
 class DateTime extends Object {}
 class Null extends Object {}
 
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index 4547bcc..2dddbf9 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -252,9 +252,8 @@
     pumpEventQueue().then((_) {
       responseController.addError(new NoResponseException(request));
     });
-    return responseController.stream.firstWhere((response) {
-      return response.id == id;
-    });
+    return new Future<Response>(() =>
+        responseController.stream.firstWhere((response) => response.id == id));
   }
 }
 
@@ -297,7 +296,7 @@
     return socket1;
   }
 
-  void add(T text) => controller.add(text);
+  void add(dynamic text) => controller.add(text as T);
 
   void allowMultipleListeners() {
     stream = stream.asBroadcastStream();
@@ -306,14 +305,14 @@
   Future close([int code, String reason]) =>
       controller.close().then((_) => twin.controller.close());
 
-  StreamSubscription<T> listen(void onData(T event),
+  StreamSubscription<T> listen(void onData(dynamic event),
           {Function onError, void onDone(), bool cancelOnError}) =>
-      stream.listen(onData,
+      stream.listen((T data) => onData(data),
           onError: onError, onDone: onDone, cancelOnError: cancelOnError);
 
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
-  Stream<T> where(bool test(T t)) => stream.where(test);
+  Stream<T> where(bool test(dynamic t)) => stream.where((T data) => test(data));
 }
 
 class MockSource extends StringTypedMock implements Source {
diff --git a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
index 51125e7..84b1781 100644
--- a/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/imported_reference_contributor_test.dart
@@ -313,7 +313,7 @@
     // The current DartCompletionRequest#resolveExpression resolves
     // the world (which it should not) and causes the imported library
     // to be resolved.
-    assertSuggestFunction('hasLength',  /* null */ 'bool');
+    assertSuggestFunction('hasLength', /* null */ 'bool');
     assertNotSuggested('main');
   }
 
@@ -779,7 +779,7 @@
     //    'num',
     //    false,
     //    COMPLETION_RELEVANCE_LOW);
-    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T1');
     assertNotSuggested('_T2');
     //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
     assertNotSuggested('_T4');
@@ -902,7 +902,7 @@
     //    'num',
     //    false,
     //    COMPLETION_RELEVANCE_LOW);
-    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T1');
     assertNotSuggested('_T2');
     //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
     assertNotSuggested('_T4');
@@ -1009,7 +1009,7 @@
     //    'num',
     //    false,
     //    COMPLETION_RELEVANCE_LOW);
-    assertSuggestTopLevelVar('T1', null);
+    assertNotSuggested('T1');
     assertNotSuggested('_T2');
     //assertSuggestImportedTopLevelVar('T3', 'int', COMPLETION_RELEVANCE_LOW);
     assertNotSuggested('_T4');
@@ -2155,17 +2155,35 @@
   }
 
   test_ForStatement_initializer() async {
-    // SimpleIdentifier  ForStatement
-    addTestSource('main() {List a; for (^)}');
+    addTestSource('''
+import 'dart:math';
+main() {
+  List localVar;
+  for (^) {}
+}
+''');
 
     await computeSuggestions();
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNotSuggested('a');
+    assertNotSuggested('localVar');
+    assertNotSuggested('PI');
     assertSuggestClass('Object');
     assertSuggestClass('int');
   }
 
+  test_ForStatement_initializer_variableName_afterType() async {
+    addTestSource('main() { for (String ^) }');
+    await computeSuggestions();
+    assertNotSuggested('int');
+  }
+
+  test_ForStatement_typing_inKeyword() async {
+    addTestSource('main() { for (var v i^) }');
+    await computeSuggestions();
+    assertNotSuggested('int');
+  }
+
   test_ForStatement_updaters() async {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; index < 10; i^)}');
@@ -2347,7 +2365,7 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestClass('Object');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('F1');
     assertSuggestFunctionTypeAlias('D1', 'dynamic');
     assertSuggestClass('C1');
@@ -2379,7 +2397,7 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestClass('Object');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('F1');
     assertSuggestFunctionTypeAlias('D1', 'dynamic');
     assertSuggestClass('C1');
@@ -2412,7 +2430,7 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestClass('Object');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('F1');
     assertSuggestFunctionTypeAlias('D1', 'dynamic');
     assertSuggestClass('C1');
@@ -2498,6 +2516,12 @@
     assertNotSuggested('==');
   }
 
+  test_IfStatement_typing_isKeyword() async {
+    addTestSource('main() { if (v i^) }');
+    await computeSuggestions();
+    assertNotSuggested('int');
+  }
+
   test_ImportDirective_dart() async {
     // SimpleStringLiteral  ImportDirective
     addTestSource('''
@@ -2644,7 +2668,7 @@
     // The current DartCompletionRequest#resolveExpression resolves
     // the world (which it should not) and causes the imported library
     // to be resolved.
-    assertSuggestTopLevelVar('T1', /* null */ 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('T2');
   }
 
@@ -3304,7 +3328,7 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestClass('Object');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('F1');
     assertSuggestFunctionTypeAlias('D1', 'dynamic');
     assertSuggestClass('C1');
@@ -3335,7 +3359,7 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestClass('Object');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('F1');
     assertSuggestFunctionTypeAlias('D1', 'dynamic');
     assertSuggestClass('C1');
@@ -3366,7 +3390,7 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestClass('Object');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('F1');
     assertSuggestFunctionTypeAlias('D1', 'dynamic');
     assertSuggestClass('C1');
@@ -3399,7 +3423,7 @@
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
     assertSuggestClass('Object');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('F1');
     assertSuggestFunctionTypeAlias('D1', 'dynamic');
     assertSuggestClass('C1');
@@ -3618,7 +3642,7 @@
     // Suggested by LocalLibraryContributor
     assertNotSuggested('A');
     assertNotSuggested('F1');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('_d');
     assertNotSuggested('z');
     assertNotSuggested('m');
@@ -3658,7 +3682,7 @@
     // Suggested by LocalLibraryContributor
     assertNotSuggested('B');
     assertNotSuggested('F1');
-    assertSuggestTopLevelVar('T1', 'int');
+    assertNotSuggested('T1');
     assertNotSuggested('_d');
     assertNotSuggested('z');
     assertNotSuggested('m');
diff --git a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
index 2e7e48b..a52a862 100644
--- a/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/keyword_contributor_test.dart
@@ -658,6 +658,12 @@
     assertSuggestKeywords([Keyword.IN], relevance: DART_RELEVANCE_HIGH);
   }
 
+  test_for_expression_in_inInitializer() async {
+    addTestSource('main() {for (int i^)}');
+    await computeSuggestions();
+    assertSuggestKeywords([]);
+  }
+
   test_for_expression_init() async {
     addTestSource('main() {for (int x = i^)}');
     await computeSuggestions();
@@ -670,6 +676,12 @@
     assertSuggestKeywords(EXPRESSION_START_NO_INSTANCE);
   }
 
+  test_for_initialization_var() async {
+    addTestSource('main() {for (^)}');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.VAR], relevance: DART_RELEVANCE_HIGH);
+  }
+
   test_function_async() async {
     addTestSource('main()^');
     await computeSuggestions();
@@ -858,6 +870,18 @@
         pseudoKeywords: ['await', 'yield', 'yield*']);
   }
 
+  test_if_condition_isKeyword() async {
+    addTestSource('main() { if (v i^) {} }');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH);
+  }
+
+  test_if_condition_isKeyword2() async {
+    addTestSource('main() { if (v i^ && false) {} }');
+    await computeSuggestions();
+    assertSuggestKeywords([Keyword.IS], relevance: DART_RELEVANCE_HIGH);
+  }
+
   test_if_expression_in_class() async {
     addTestSource('class A {foo() {if (^) }}');
     await computeSuggestions();
diff --git a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
index a53e433..7851d49 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_library_contributor_test.dart
@@ -60,8 +60,7 @@
     assertNotSuggested('T1');
     assertNotSuggested('_d');
     assertNotSuggested('z');
-    assertSuggestTopLevelVar('m', 'dynamic',
-        relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
+    assertNotSuggested('m');
   }
 
   test_partFile_Constructor2() async {
diff --git a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
index a61c9da..ef90952 100644
--- a/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/local_reference_contributor_test.dart
@@ -2170,7 +2170,7 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertSuggestLocalVariable('a', 'List');
+    assertNotSuggested('a');
     assertNotSuggested('Object');
     assertNotSuggested('int');
   }
diff --git a/pkg/analysis_server/test/services/completion/dart/optype_test.dart b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
index f5c89bb..9a6982b6 100644
--- a/pkg/analysis_server/test/services/completion/dart/optype_test.dart
+++ b/pkg/analysis_server/test/services/completion/dart/optype_test.dart
@@ -99,6 +99,19 @@
     assertOpType(namedArgs: true, returnValue: true, typeNames: true);
   }
 
+  test_ArgumentList_namedParam() {
+    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
+    // ExpressionStatement
+    addTestSource('void main() {expect(foo: ^)}');
+    assertOpType(returnValue: true, typeNames: true);
+  }
+
+  test_ArgumentList_prefixedIdentifier() {
+    // SimpleIdentifier  PrefixedIdentifier  ArgumentList
+    addTestSource('void main() {expect(aa.^)}');
+    assertOpType(returnValue: true, typeNames: true, prefixed: true);
+  }
+
   test_ArgumentList_resolved() {
     // ArgumentList  MethodInvocation  ExpressionStatement  Block
     addTestSource('void main() {int.parse(^)}', resolved: true);
@@ -123,19 +136,6 @@
     assertOpType(namedArgs: true);
   }
 
-  test_ArgumentList_namedParam() {
-    // SimpleIdentifier  NamedExpression  ArgumentList  MethodInvocation
-    // ExpressionStatement
-    addTestSource('void main() {expect(foo: ^)}');
-    assertOpType(returnValue: true, typeNames: true);
-  }
-
-  test_ArgumentList_prefixedIdentifier() {
-    // SimpleIdentifier  PrefixedIdentifier  ArgumentList
-    addTestSource('void main() {expect(aa.^)}');
-    assertOpType(returnValue: true, typeNames: true, prefixed: true);
-  }
-
   test_AsExpression() {
     // SimpleIdentifier  TypeName  AsExpression
     addTestSource('class A {var b; X _c; foo() {var a; (a as ^).foo();}');
@@ -668,15 +668,29 @@
   test_ForStatement_condition() {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {for (int index = 0; i^)}');
-    // TODO (danrubel) may want to exclude methods/functions with void return
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+    assertOpType(returnValue: true, typeNames: true);
   }
 
   test_ForStatement_initializer() {
     // SimpleIdentifier  ForStatement
     addTestSource('main() {List a; for (^)}');
-    // TODO (danrubel) may want to exclude methods/functions with void return
-    assertOpType(returnValue: true, typeNames: true, voidReturn: true);
+    assertOpType(typeNames: true);
+  }
+
+  test_ForStatement_initializer_inKeyword() {
+    addTestSource('main() { for (var v i^) }');
+    assertOpType();
+  }
+
+  test_ForStatement_initializer_type() {
+    // SimpleIdentifier  ForStatement
+    addTestSource('main() {List a; for (i^ v = 0;)}');
+    assertOpType(typeNames: true);
+  }
+
+  test_ForStatement_initializer_variableNameEmpty_afterType() {
+    addTestSource('main() { for (String ^) }');
+    assertOpType(varNames: true);
   }
 
   test_ForStatement_updaters() {
diff --git a/pkg/analysis_server/test/services/index/index_test.dart b/pkg/analysis_server/test/services/index/index_test.dart
index a99d34a..5a1f093 100644
--- a/pkg/analysis_server/test/services/index/index_test.dart
+++ b/pkg/analysis_server/test/services/index/index_test.dart
@@ -248,6 +248,28 @@
     findLocationTest(locations, 'test();', false);
   }
 
+  test_indexDeclarations_afterIndexUnit() async {
+    resolveTestUnit('''
+var a = 0;
+var b = a + 1;
+''');
+    index.indexUnit(testUnit);
+    TopLevelVariableElement a = findElement('a');
+    // We can find references.
+    {
+      List<Location> locations = await index.getRelations(
+          a.getter, IndexRelationKind.IS_REFERENCED_BY);
+      findLocationTest(locations, 'a + 1', false);
+    }
+    // Attempt to index just declarations - we still can find references.
+    index.indexDeclarations(testUnit);
+    {
+      List<Location> locations = await index.getRelations(
+          a.getter, IndexRelationKind.IS_REFERENCED_BY);
+      findLocationTest(locations, 'a + 1', false);
+    }
+  }
+
   test_indexDeclarations_nullUnit() async {
     index.indexDeclarations(null);
   }
diff --git a/pkg/analysis_server/test/services/search/search_engine_test.dart b/pkg/analysis_server/test/services/search/search_engine_test.dart
index ffdfd4c..b67ce1a 100644
--- a/pkg/analysis_server/test/services/search/search_engine_test.dart
+++ b/pkg/analysis_server/test/services/search/search_engine_test.dart
@@ -36,8 +36,9 @@
     this.range = new SourceRange(offset, length);
   }
 
-  bool operator ==(SearchMatch match) {
-    return match.element == this.element &&
+  bool operator ==(Object match) {
+    return match is SearchMatch &&
+        match.element == this.element &&
         match.kind == this.kind &&
         match.isResolved == this.isResolved &&
         match.isQualified == this.isQualified &&
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 89be5a5..c33b26d 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -4579,16 +4579,22 @@
     NodeList<Combinator> combinators1 = import1.combinators;
     List<String> allHides1 = new List<String>();
     List<String> allShows1 = new List<String>();
-    for (Combinator combinator in combinators1) {
+    int length1 = combinators1.length;
+    for (int i = 0; i < length1; i++) {
+      Combinator combinator = combinators1[i];
       if (combinator is HideCombinator) {
         NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
-        for (SimpleIdentifier simpleIdentifier in hides) {
+        int hideLength = hides.length;
+        for (int j = 0; j < hideLength; j++) {
+          SimpleIdentifier simpleIdentifier = hides[j];
           allHides1.add(simpleIdentifier.name);
         }
       } else {
         NodeList<SimpleIdentifier> shows =
             (combinator as ShowCombinator).shownNames;
-        for (SimpleIdentifier simpleIdentifier in shows) {
+        int showLength = shows.length;
+        for (int j = 0; j < showLength; j++) {
+          SimpleIdentifier simpleIdentifier = shows[j];
           allShows1.add(simpleIdentifier.name);
         }
       }
@@ -4596,16 +4602,22 @@
     NodeList<Combinator> combinators2 = import2.combinators;
     List<String> allHides2 = new List<String>();
     List<String> allShows2 = new List<String>();
-    for (Combinator combinator in combinators2) {
+    int length2 = combinators2.length;
+    for (int i = 0; i < length2; i++) {
+      Combinator combinator = combinators2[i];
       if (combinator is HideCombinator) {
         NodeList<SimpleIdentifier> hides = combinator.hiddenNames;
-        for (SimpleIdentifier simpleIdentifier in hides) {
+        int hideLength = hides.length;
+        for (int j = 0; j < hideLength; j++) {
+          SimpleIdentifier simpleIdentifier = hides[j];
           allHides2.add(simpleIdentifier.name);
         }
       } else {
         NodeList<SimpleIdentifier> shows =
             (combinator as ShowCombinator).shownNames;
-        for (SimpleIdentifier simpleIdentifier in shows) {
+        int showLength = shows.length;
+        for (int j = 0; j < showLength; j++) {
+          SimpleIdentifier simpleIdentifier = shows[j];
           allShows2.add(simpleIdentifier.name);
         }
       }
diff --git a/pkg/analyzer/lib/dart/ast/token.dart b/pkg/analyzer/lib/dart/ast/token.dart
index 77226be..14ba3f9 100644
--- a/pkg/analyzer/lib/dart/ast/token.dart
+++ b/pkg/analyzer/lib/dart/ast/token.dart
@@ -360,7 +360,9 @@
   static Token lexicallyFirst(List<Token> tokens) {
     Token first = null;
     int offset = -1;
-    for (Token token in tokens) {
+    int length = tokens.length;
+    for (int i = 0; i < length; i++) {
+      Token token = tokens[i];
       if (token != null && (offset < 0 || token.offset < offset)) {
         first = token;
         offset = token.offset;
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index a320b8d..1a73457 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -1862,6 +1862,11 @@
  */
 abstract class TypeParameterizedElement implements Element {
   /**
+   * The type of this element, which will be a parameterized type.
+   */
+  ParameterizedType get type;
+
+  /**
    * Return a list containing all of the type parameters declared by this
    * element directly. This does not include type parameters that are declared
    * by any enclosing elements.
diff --git a/pkg/analyzer/lib/src/cancelable_future.dart b/pkg/analyzer/lib/src/cancelable_future.dart
index 803137d..307e1d9 100644
--- a/pkg/analyzer/lib/src/cancelable_future.dart
+++ b/pkg/analyzer/lib/src/cancelable_future.dart
@@ -248,7 +248,7 @@
   }
 
   @override
-  Future catchError(Function onError, {bool test(Object error)}) =>
+  Future<T> catchError(Function onError, {bool test(Object error)}) =>
       _completer._outerCompleter.future.catchError(onError, test: test);
 
   @override
@@ -284,7 +284,7 @@
   void cancel() {}
 
   @override
-  Future catchError(Function onError, {bool test(Object error)}) =>
+  Future<T> catchError(Function onError, {bool test(Object error)}) =>
       _future.catchError(onError, test: test);
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index ad6c9c8..e5509f1 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -69,7 +69,9 @@
 
   @override
   void _appendStringValue(StringBuffer buffer) {
-    for (StringLiteralImpl stringLiteral in strings) {
+    int length = strings.length;
+    for (int i = 0; i < length; i++) {
+      StringLiteralImpl stringLiteral = strings[i];
       stringLiteral._appendStringValue(buffer);
     }
   }
@@ -159,8 +161,10 @@
       _comment?.accept(visitor);
       _metadata.accept(visitor);
     } else {
-      for (AstNode child in sortedCommentAndAnnotations) {
-        child.accept(visitor);
+      List<AstNode> children = sortedCommentAndAnnotations;
+      int length = children.length;
+      for (int i = 0; i < length; i++) {
+        children[i].accept(visitor);
       }
     }
   }
@@ -1837,7 +1841,9 @@
 
   @override
   ConstructorDeclaration getConstructor(String name) {
-    for (ClassMember classMember in _members) {
+    int length = _members.length;
+    for (int i = 0; i < length; i++) {
+      ClassMember classMember = _members[i];
       if (classMember is ConstructorDeclaration) {
         ConstructorDeclaration constructor = classMember;
         SimpleIdentifier constructorName = constructor.name;
@@ -1854,12 +1860,16 @@
 
   @override
   VariableDeclaration getField(String name) {
-    for (ClassMember classMember in _members) {
+    int memberLength = _members.length;
+    for (int i = 0; i < memberLength; i++) {
+      ClassMember classMember = _members[i];
       if (classMember is FieldDeclaration) {
         FieldDeclaration fieldDeclaration = classMember;
         NodeList<VariableDeclaration> fields =
             fieldDeclaration.fields.variables;
-        for (VariableDeclaration field in fields) {
+        int fieldLength = fields.length;
+        for (int i = 0; i < fieldLength; i++) {
+          VariableDeclaration field = fields[i];
           SimpleIdentifier fieldName = field.name;
           if (fieldName != null && name == fieldName.name) {
             return field;
@@ -1872,7 +1882,9 @@
 
   @override
   MethodDeclaration getMethod(String name) {
-    for (ClassMember classMember in _members) {
+    int length = _members.length;
+    for (int i = 0; i < length; i++) {
+      ClassMember classMember = _members[i];
       if (classMember is MethodDeclaration) {
         MethodDeclaration method = classMember;
         SimpleIdentifier methodName = method.name;
@@ -2426,7 +2438,9 @@
       _directives.accept(visitor);
       _declarations.accept(visitor);
     } else {
-      for (AstNode child in sortedDirectivesAndDeclarations) {
+      int length = sortedDirectivesAndDeclarations.length;
+      for (int i = 0; i < length; i++) {
+        AstNode child = sortedDirectivesAndDeclarations[i];
         child.accept(visitor);
       }
     }
@@ -4671,7 +4685,9 @@
     // TODO(paulberry): include commas.
     ChildEntities result = new ChildEntities()..add(leftParenthesis);
     bool leftDelimiterNeeded = leftDelimiter != null;
-    for (FormalParameter parameter in _parameters) {
+    int length = _parameters.length;
+    for (int i = 0; i < length; i++) {
+      FormalParameter parameter = _parameters[i];
       if (leftDelimiterNeeded && leftDelimiter.offset < parameter.offset) {
         result.add(leftDelimiter);
         leftDelimiterNeeded = false;
@@ -6676,7 +6692,9 @@
   String get name {
     StringBuffer buffer = new StringBuffer();
     bool needsPeriod = false;
-    for (SimpleIdentifier identifier in _components) {
+    int length = _components.length;
+    for (int i = 0; i < length; i++) {
+      SimpleIdentifier identifier = _components[i];
       if (needsPeriod) {
         buffer.write(".");
       } else {
@@ -7672,9 +7690,18 @@
   @override
   bool addAll(Iterable<E> nodes) {
     if (nodes != null && !nodes.isEmpty) {
-      _elements.addAll(nodes);
-      for (E node in nodes) {
-        _owner._becomeParentOf(node as AstNodeImpl);
+      if (nodes is List<E>) {
+        int length = nodes.length;
+        for (int i = 0; i < length; i++) {
+          E node = nodes[i];
+          _elements.add(node);
+          _owner._becomeParentOf(node as AstNodeImpl);
+        }
+      } else {
+        for (E node in nodes) {
+          _elements.add(node);
+          _owner._becomeParentOf(node as AstNodeImpl);
+        }
       }
       return true;
     }
@@ -7813,8 +7840,10 @@
       _comment?.accept(visitor);
       _metadata.accept(visitor);
     } else {
-      for (AstNode child in sortedCommentAndAnnotations) {
-        child.accept(visitor);
+      List<AstNode> children = sortedCommentAndAnnotations;
+      int length = children.length;
+      for (int i = 0; i < length; i++) {
+        children[i].accept(visitor);
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/constant/utilities.dart b/pkg/analyzer/lib/src/dart/constant/utilities.dart
index 80e736b..62b3ec8 100644
--- a/pkg/analyzer/lib/src/dart/constant/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/constant/utilities.dart
@@ -48,6 +48,13 @@
   }
 
   @override
+  FunctionExpression visitFunctionExpression(FunctionExpression node) {
+    FunctionExpression expression = super.visitFunctionExpression(node);
+    expression.element = node.element;
+    return expression;
+  }
+
+  @override
   InstanceCreationExpression visitInstanceCreationExpression(
       InstanceCreationExpression node) {
     InstanceCreationExpression expression =
@@ -172,8 +179,10 @@
     super.visitAnnotation(node);
     ElementAnnotation elementAnnotation = node.elementAnnotation;
     if (elementAnnotation == null) {
-      // Analyzer ignores annotations on "part of" directives.
-      assert(node.parent is PartOfDirective);
+      // Analyzer ignores annotations on "part of" directives and on enum
+      // constant declarations.
+      assert(node.parent is PartOfDirective ||
+          node.parent is EnumConstantDeclaration);
     } else {
       constantsToCompute.add(elementAnnotation);
     }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 2175e9e..bcac6b1 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -208,7 +208,7 @@
       // Use a list to keep track of the classes we've seen, so that we won't
       // go into an infinite loop in the event of a non-trivial loop in the
       // class hierarchy.
-      List<ClassElementImpl> classesSeen = <ClassElementImpl>[this];
+      List<ClassElement> classesSeen = <ClassElement>[this];
       while (nearestNonMixinClass.isMixinApplication) {
         if (classesSeen.contains(nearestNonMixinClass)) {
           // Loop in the class hierarchy (which is reported elsewhere).  Don't
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 7d08ca8..f2e9a15 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -24,6 +24,13 @@
 typedef FunctionTypedElement FunctionTypedElementComputer();
 
 /**
+ * Computer of type arguments which is used to delay computing of type
+ * arguments until they are requested, instead of at the [ParameterizedType]
+ * creation time.
+ */
+typedef List<DartType> TypeArgumentsComputer();
+
+/**
  * A [Type] that represents the type 'bottom'.
  */
 class BottomTypeImpl extends TypeImpl {
@@ -1117,7 +1124,13 @@
   /**
    * A list containing the actual types of the type arguments.
    */
-  List<DartType> typeArguments = DartType.EMPTY_LIST;
+  List<DartType> _typeArguments = DartType.EMPTY_LIST;
+
+  /**
+   * If not `null` and [_typeArguments] is `null`, the actual type arguments
+   * should be computed (once) using this function.
+   */
+  TypeArgumentsComputer _typeArgumentsComputer;
 
   /**
    * The set of typedefs which should not be expanded when exploring this type,
@@ -1136,10 +1149,10 @@
    * with the given [name] and [typeArguments].
    */
   InterfaceTypeImpl.elementWithNameAndArgs(
-      ClassElement element, String name, List<DartType> typeArguments)
+      ClassElement element, String name, this._typeArgumentsComputer)
       : prunedTypedefs = null,
         super(element, name) {
-    this.typeArguments = typeArguments;
+    _typeArguments = null;
   }
 
   /**
@@ -1301,6 +1314,23 @@
   }
 
   @override
+  List<DartType> get typeArguments {
+    if (_typeArguments == null) {
+      _typeArguments = _typeArgumentsComputer();
+      _typeArgumentsComputer = null;
+    }
+    return _typeArguments;
+  }
+
+  /**
+   * Set [typeArguments].
+   */
+  void set typeArguments(List<DartType> typeArguments) {
+    _typeArguments = typeArguments;
+    _typeArgumentsComputer = null;
+  }
+
+  @override
   List<TypeParameterElement> get typeParameters => element.typeParameters;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
index 3f449de..6bdabc9 100644
--- a/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/inheritance_manager.dart
@@ -262,15 +262,13 @@
     } else {
       resultMap = new Map<String, ExecutableElement>();
     }
-    ClassElement superclassElt = null;
     InterfaceType supertype = classElt.supertype;
-    if (supertype != null) {
-      superclassElt = supertype.element;
-    } else {
+    if (supertype == null) {
       // classElt is Object
       _classLookup[classElt] = resultMap;
       return resultMap;
     }
+    ClassElement superclassElt = supertype.element;
     if (superclassElt != null) {
       if (!visitedClasses.contains(superclassElt)) {
         visitedClasses.add(superclassElt);
@@ -309,14 +307,9 @@
           visitedClasses.add(mixinElement);
           try {
             Map<String, ExecutableElement> map =
-                new Map<String, ExecutableElement>.from(
-                    _computeClassChainLookupMap(mixinElement, visitedClasses));
+                new Map<String, ExecutableElement>();
             //
-            // Substitute the super types down the hierarchy.
-            //
-            _substituteTypeParametersDownHierarchy(mixin, map);
-            //
-            // Include the members from the superclass in the resultMap.
+            // Include the members from the mixin in the resultMap.
             //
             _recordMapWithClassMembers(map, mixin, false);
             //
@@ -608,6 +601,16 @@
    */
   void _recordMapWithClassMembers(Map<String, ExecutableElement> map,
       InterfaceType type, bool doIncludeAbstract) {
+    Set<InterfaceType> seenTypes = new HashSet<InterfaceType>();
+    while (type.element.isMixinApplication) {
+      List<InterfaceType> mixins = type.mixins;
+      if (!seenTypes.add(type) || mixins.isEmpty) {
+        // In the case of a circularity in the type hierarchy, just don't add
+        // any members to the map.
+        return;
+      }
+      type = mixins.last;
+    }
     List<MethodElement> methods = type.methods;
     for (MethodElement method in methods) {
       if (method.isAccessibleIn(_library) &&
@@ -850,13 +853,8 @@
     for (Map<String, ExecutableElement> lookupMap in lookupMaps) {
       for (String memberName in lookupMap.keys) {
         // Get the list value out of the unionMap
-        List<ExecutableElement> list = unionMap[memberName];
-        // If we haven't created such a map for this key yet, do create it and
-        // put the list entry into the unionMap.
-        if (list == null) {
-          list = new List<ExecutableElement>();
-          unionMap[memberName] = list;
-        }
+        List<ExecutableElement> list = unionMap.putIfAbsent(
+            memberName, () => new List<ExecutableElement>());
         // Fetch the entry out of this lookupMap
         ExecutableElement newExecutableElementEntry = lookupMap[memberName];
         if (list.isEmpty) {
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index c7b502f..724ddc5 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -470,7 +470,10 @@
     SimpleIdentifier prefixNode = node.prefix;
     if (prefixNode != null) {
       String prefixName = prefixNode.name;
-      for (PrefixElement prefixElement in _definingLibrary.prefixes) {
+      List<PrefixElement> prefixes = _definingLibrary.prefixes;
+      int count = prefixes.length;
+      for (int i = 0; i < count; i++) {
+        PrefixElement prefixElement = prefixes[i];
         if (prefixElement.displayName == prefixName) {
           prefixNode.staticElement = prefixElement;
           break;
@@ -1391,7 +1394,10 @@
   Element _findImportWithoutPrefix(SimpleIdentifier identifier) {
     Element element = null;
     Scope nameScope = _resolver.nameScope;
-    for (ImportElement importElement in _definingLibrary.imports) {
+    List<ImportElement> imports = _definingLibrary.imports;
+    int length = imports.length;
+    for (int i = 0; i < length; i++) {
+      ImportElement importElement = imports[i];
       PrefixElement prefixElement = importElement.prefix;
       if (prefixElement != null) {
         Identifier prefixedIdentifier = new PrefixedIdentifierImpl.temp(
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 6d2f8b9..537ca31 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -5225,27 +5225,25 @@
     if (type == null) {
       return;
     }
-    // prepare ClassElement
     Element element = type.element;
-    if (element is ClassElement) {
+    if (element is TypeParameterizedElement) {
       // prepare type parameters
-      List<DartType> typeParameters = element.type.typeArguments;
-      List<TypeParameterElement> boundingElts = element.typeParameters;
+      List<TypeParameterElement> parameterElements = element.typeParameters;
+      List<DartType> parameterTypes = element.type.typeArguments;
+      List<DartType> arguments = (type as ParameterizedType).typeArguments;
       // iterate over each bounded type parameter and corresponding argument
       NodeList<TypeName> typeNameArgList = typeName.typeArguments.arguments;
-      List<DartType> typeArguments = (type as InterfaceType).typeArguments;
       int loopThroughIndex =
-          math.min(typeNameArgList.length, boundingElts.length);
-
-      bool shouldSubstitute = typeArguments.length != 0 &&
-          typeArguments.length == typeParameters.length;
+          math.min(typeNameArgList.length, parameterElements.length);
+      bool shouldSubstitute = arguments.length != 0 &&
+          arguments.length == parameterTypes.length;
       for (int i = 0; i < loopThroughIndex; i++) {
         TypeName argTypeName = typeNameArgList[i];
         DartType argType = argTypeName.type;
-        DartType boundType = boundingElts[i].bound;
+        DartType boundType = parameterElements[i].bound;
         if (argType != null && boundType != null) {
           if (shouldSubstitute) {
-            boundType = boundType.substitute2(typeArguments, typeParameters);
+            boundType = boundType.substitute2(arguments, parameterTypes);
           }
           if (!_typeSystem.isSubtypeOf(argType, boundType)) {
             ErrorCode errorCode;
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 7f00554..777d130 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1060,7 +1060,8 @@
    */
   static void patchTopLevelAccessors(LibraryElementImpl library) {
     // Without parts getters/setters already share the same variable element.
-    if (library.parts.isEmpty) {
+    List<CompilationUnitElement> parts = library.parts;
+    if (parts.isEmpty) {
       return;
     }
     // Collect getters and setters.
@@ -1068,11 +1069,15 @@
         new HashMap<String, PropertyAccessorElement>();
     List<PropertyAccessorElement> setters = <PropertyAccessorElement>[];
     _collectAccessors(getters, setters, library.definingCompilationUnit);
-    for (CompilationUnitElement unit in library.parts) {
+    int partLength = parts.length;
+    for (int i = 0; i < partLength; i++) {
+      CompilationUnitElement unit = parts[i];
       _collectAccessors(getters, setters, unit);
     }
     // Move every setter to the corresponding getter's variable (if exists).
-    for (PropertyAccessorElement setter in setters) {
+    int setterLength = setters.length;
+    for (int j = 0; j < setterLength; j++) {
+      PropertyAccessorElement setter = setters[j];
       PropertyAccessorElement getter = getters[setter.displayName];
       if (getter != null) {
         TopLevelVariableElementImpl variable = getter.variable;
@@ -1091,7 +1096,10 @@
    */
   static void _collectAccessors(Map<String, PropertyAccessorElement> getters,
       List<PropertyAccessorElement> setters, CompilationUnitElement unit) {
-    for (PropertyAccessorElement accessor in unit.accessors) {
+    List<PropertyAccessorElement> accessors = unit.accessors;
+    int length = accessors.length;
+    for (int i = 0; i < length; i++) {
+      PropertyAccessorElement accessor = accessors[i];
       if (accessor.isGetter) {
         if (!accessor.isSynthetic && accessor.correspondingSetter == null) {
           getters[accessor.displayName] = accessor;
@@ -1316,9 +1324,10 @@
       }
     }
     if (reportEqualKeys) {
-      for (Expression key in invalidKeys) {
+      int length = invalidKeys.length;
+      for (int i = 0; i < length; i++) {
         _errorReporter.reportErrorForNode(
-            StaticWarningCode.EQUAL_KEYS_IN_MAP, key);
+            StaticWarningCode.EQUAL_KEYS_IN_MAP, invalidKeys[i]);
       }
     }
     return null;
@@ -1470,7 +1479,9 @@
    * @param errorCode the error code to be used
    */
   void _reportErrors(List<AnalysisError> errors, ErrorCode errorCode) {
-    for (AnalysisError data in errors) {
+    int length = errors.length;
+    for (int i = 0; i < length; i++) {
+      AnalysisError data = errors[i];
       ErrorCode dataErrorCode = data.errorCode;
       if (identical(dataErrorCode,
               CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION) ||
@@ -1980,7 +1991,9 @@
               return null;
             }
           }
-          for (DartType type in visitedTypes) {
+          int length = visitedTypes.length;
+          for (int j = 0; j < length; j++) {
+            DartType type = visitedTypes[j];
             if (_typeSystem.isSubtypeOf(currentType, type)) {
               CatchClause lastCatchClause = catchClauses[numOfCatchClauses - 1];
               int offset = catchClause.offset;
@@ -2684,7 +2697,9 @@
   Element _findWithNameAndOffset(
       List<Element> elements, AstNode node, String name, int offset,
       {bool required: true}) {
-    for (Element element in elements) {
+    int length = elements.length;
+    for (int i = 0; i < length; i++) {
+      Element element = elements[i];
       if (element.nameOffset == offset && element.name == name) {
         return element;
       }
@@ -2692,7 +2707,8 @@
     if (!required) {
       return null;
     }
-    for (Element element in elements) {
+    for (int i = 0; i < length; i++) {
+      Element element = elements[i];
       if (element.name == name) {
         _mismatch(
             'Found element with name "$name" at ${element.nameOffset}, '
@@ -2853,7 +2869,9 @@
     if (source == null) {
       return null;
     }
-    for (ExportElement export in exports) {
+    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) {
@@ -2884,7 +2902,9 @@
     }
     SimpleIdentifier prefix = node.prefix;
     bool foundSource = false;
-    for (ImportElement element in imports) {
+    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.
@@ -3180,7 +3200,9 @@
     if (_fields == null) {
       return null;
     }
-    for (FieldElement field in _fields) {
+    int length = _fields.length;
+    for (int i = 0; i < length; i++) {
+      FieldElement field = _fields[i];
       if (field.name == fieldName) {
         return field;
       }
@@ -3192,7 +3214,9 @@
     if (_topLevelVariables == null) {
       return null;
     }
-    for (TopLevelVariableElement variable in _topLevelVariables) {
+    int length = _topLevelVariables.length;
+    for (int i = 0; i < length; i++) {
+      TopLevelVariableElement variable = _topLevelVariables[i];
       if (variable.name == variableName) {
         return variable;
       }
@@ -3980,7 +4004,10 @@
     // If the element is multiply defined then call this method recursively for
     // each of the conflicting elements.
     if (element is MultiplyDefinedElement) {
-      for (Element elt in element.conflictingElements) {
+      List<Element> conflictingElements = element.conflictingElements;
+      int length = conflictingElements.length;
+      for (int i = 0; i < length; i++) {
+        Element elt = conflictingElements[i];
         _visitIdentifier(identifier, elt);
       }
       return;
@@ -4206,7 +4233,9 @@
 
   void generateForLibrary() {
     PerformanceStatistics.hints.makeCurrentWhile(() {
-      for (CompilationUnit unit in _compilationUnits) {
+      int length = _compilationUnits.length;
+      for (int i = 0; i < length; i++) {
+        CompilationUnit unit = _compilationUnits[i];
         CompilationUnitElement element = unit.element;
         if (element != null) {
           _generateForCompilationUnit(unit, element.source);
@@ -4407,9 +4436,10 @@
    *          hints to
    */
   void generateDuplicateImportHints(ErrorReporter errorReporter) {
-    for (ImportDirective duplicateImport in _duplicateImports) {
+    int length = _duplicateImports.length;
+    for (int i = 0; i < length; i++) {
       errorReporter.reportErrorForNode(
-          HintCode.DUPLICATE_IMPORT, duplicateImport.uri);
+          HintCode.DUPLICATE_IMPORT, _duplicateImports[i].uri);
     }
   }
 
@@ -4422,7 +4452,9 @@
    *          hints
    */
   void generateUnusedImportHints(ErrorReporter errorReporter) {
-    for (ImportDirective unusedImport in _unusedImports) {
+    int length = _unusedImports.length;
+    for (int i = 0; i < length; i++) {
+      ImportDirective unusedImport = _unusedImports[i];
       // Check that the import isn't dart:core
       ImportElement importElement = unusedImport.element;
       if (importElement != null) {
@@ -4452,7 +4484,9 @@
         // This is then an "unused import", rather than unused shown names.
         return;
       }
-      for (Identifier identifier in identifiers) {
+      int length = identifiers.length;
+      for (int i = 0; i < length; i++) {
+        Identifier identifier = identifiers[i];
         reporter.reportErrorForNode(
             HintCode.UNUSED_SHOWN_NAME, identifier, [identifier.name]);
       }
@@ -4472,9 +4506,13 @@
         .forEach((PrefixElement prefix, List<Element> elements) {
       List<ImportDirective> importDirectives = _prefixElementMap[prefix];
       if (importDirectives != null) {
-        for (ImportDirective importDirective in importDirectives) {
+        int importLength = importDirectives.length;
+        for (int i = 0; i < importLength; i++) {
+          ImportDirective importDirective = importDirectives[i];
           _unusedImports.remove(importDirective);
-          for (Element element in elements) {
+          int elementLength = elements.length;
+          for (int j = 0; j < elementLength; j++) {
+            Element element = elements[j];
             _removeFromUnusedShownNamesMap(element, importDirective);
           }
         }
@@ -4522,7 +4560,10 @@
     if (!visitedLibraries.add(library)) {
       return;
     }
-    for (ExportElement exportElt in library.exports) {
+    List<ExportElement> exports = library.exports;
+    int length = exports.length;
+    for (int i = 0; i < length; i++) {
+      ExportElement exportElt = exports[i];
       LibraryElement exportedLibrary = exportElt.exportedLibrary;
       _putIntoLibraryMap(exportedLibrary, importDirective);
       _addAdditionalLibrariesForExports(
@@ -4597,7 +4638,9 @@
     if (identifiers == null) {
       return;
     }
-    for (Identifier identifier in identifiers) {
+    int length = identifiers.length;
+    for (int i = 0; i < length; i++) {
+      Identifier identifier = identifiers[i];
       if (element is PropertyAccessorElement) {
         // If the getter or setter of a variable is used, then the variable (the
         // shown name) is used.
@@ -4821,14 +4864,18 @@
           return true;
         }
 
-        for (final parent in t1.mixins) {
-          if (match(parent, visited)) {
+        List<InterfaceType> mixins = t1.mixins;
+        int mixinLength = mixins.length;
+        for (int i = 0; i < mixinLength; i++) {
+          if (match(mixins[i], visited)) {
             return true;
           }
         }
 
-        for (final parent in t1.interfaces) {
-          if (match(parent, visited)) {
+        List<InterfaceType> interfaces = t1.interfaces;
+        int interfaceLength = interfaces.length;
+        for (int j = 0; j < interfaceLength; j++) {
+          if (match(interfaces[j], visited)) {
             return true;
           }
         }
@@ -4995,7 +5042,14 @@
   void _resolveFieldDeclaration(FieldDeclaration node) {
     if (!node.isStatic) {
       for (VariableDeclaration field in node.fields.variables) {
-        field.initializer?.accept(this);
+        if (field.initializer != null) {
+          field.initializer.accept(this);
+          FieldElement fieldElement = field.name.staticElement;
+          if (fieldElement.initializer != null) {
+            (fieldElement.initializer as ExecutableElementImpl).returnType =
+                field.initializer.staticType;
+          }
+        }
       }
     }
   }
@@ -5158,7 +5212,9 @@
    * Add all of the [variables] with initializers to [propagableVariables].
    */
   void _addPropagableVariables(List<VariableDeclaration> variables) {
-    for (VariableDeclaration variable in variables) {
+    int length = variables.length;
+    for (int i = 0; i < length; i++) {
+      VariableDeclaration variable = variables[i];
       if (variable.name.name.isNotEmpty && variable.initializer != null) {
         VariableElement element = variable.element;
         if (element.isConst || element.isFinal) {
@@ -5176,7 +5232,9 @@
    * refer to a field whose type was inferred.
    */
   void _addStaticVariables(List<VariableDeclaration> variables) {
-    for (VariableDeclaration variable in variables) {
+    int length = variables.length;
+    for (int i = 0; i < length; i++) {
+      VariableDeclaration variable = variables[i];
       if (variable.name.name.isNotEmpty && variable.initializer != null) {
         staticVariables.add(variable.element);
       }
@@ -7388,7 +7446,9 @@
     int unnamedParameterCount = 0;
     List<ParameterElement> unnamedParameters = new List<ParameterElement>();
     HashMap<String, ParameterElement> namedParameters = null;
-    for (ParameterElement parameter in parameters) {
+    int length = parameters.length;
+    for (int i = 0; i < length; i++) {
+      ParameterElement parameter = parameters[i];
       ParameterKind kind = parameter.parameterKind;
       if (kind == ParameterKind.REQUIRED) {
         unnamedParameters.add(parameter);
@@ -7935,9 +7995,11 @@
             new CaughtException(new AnalysisException(), null));
       } else {
         nameScope = new EnclosedScope(nameScope);
-        for (TypeParameterElement typeParameter
-            in parameterElement.typeParameters) {
-          nameScope.define(typeParameter);
+        List<TypeParameterElement> typeParameters =
+            parameterElement.typeParameters;
+        int length = typeParameters.length;
+        for (int i = 0; i < length; i++) {
+          nameScope.define(typeParameters[i]);
         }
       }
       super.visitFunctionTypedFormalParameter(node);
@@ -8183,14 +8245,18 @@
       }
     }
     List<InterfaceType> interfaceTypes = classElement.interfaces;
-    for (InterfaceType interfaceType in interfaceTypes) {
+    int interfaceLength = interfaceTypes.length;
+    for (int i = 0; i < interfaceLength; i++) {
+      InterfaceType interfaceType = interfaceTypes[i];
       ClassElement interfaceElement = interfaceType.element;
       if (interfaceElement != null) {
         _putInSubtypeMap(interfaceElement, classElement);
       }
     }
     List<InterfaceType> mixinTypes = classElement.mixins;
-    for (InterfaceType mixinType in mixinTypes) {
+    int mixinLength = mixinTypes.length;
+    for (int i = 0; i < mixinLength; i++) {
+      InterfaceType mixinType = mixinTypes[i];
       ClassElement mixinElement = mixinType.element;
       if (mixinElement != null) {
         _putInSubtypeMap(mixinElement, classElement);
@@ -8207,7 +8273,9 @@
    */
   void _computeSubtypesInCompilationUnit(CompilationUnitElement unitElement) {
     List<ClassElement> classElements = unitElement.types;
-    for (ClassElement classElement in classElements) {
+    int length = classElements.length;
+    for (int i = 0; i < length; i++) {
+      ClassElement classElement = classElements[i];
       _computeSubtypesInClass(classElement);
     }
   }
@@ -8227,15 +8295,21 @@
     _visitedLibraries.add(libraryElement);
     _computeSubtypesInCompilationUnit(libraryElement.definingCompilationUnit);
     List<CompilationUnitElement> parts = libraryElement.parts;
-    for (CompilationUnitElement part in parts) {
+    int partLength = parts.length;
+    for (int i = 0; i < partLength; i++) {
+      CompilationUnitElement part = parts[i];
       _computeSubtypesInCompilationUnit(part);
     }
     List<LibraryElement> imports = libraryElement.importedLibraries;
-    for (LibraryElement importElt in imports) {
+    int importLength = imports.length;
+    for (int i = 0; i < importLength; i++) {
+      LibraryElement importElt = imports[i];
       _computeSubtypesInLibrary(importElt.library);
     }
     List<LibraryElement> exports = libraryElement.exportedLibraries;
-    for (LibraryElement exportElt in exports) {
+    int exportLength = exports.length;
+    for (int i = 0; i < exportLength; i++) {
+      LibraryElement exportElt = exports[i];
       _computeSubtypesInLibrary(exportElt.library);
     }
   }
@@ -8718,7 +8792,9 @@
    */
   InterfaceType _getTypeWhenMultiplyDefined(List<Element> elements) {
     InterfaceType type = null;
-    for (Element element in elements) {
+    int length = elements.length;
+    for (int i = 0; i < length; i++) {
+      Element element = elements[i];
       if (element is ClassElement) {
         if (type != null) {
           return null;
@@ -8940,7 +9016,9 @@
    * the branching, then its propagated type is reset to `null`.
    */
   void mergeOverrides(List<Map<VariableElement, DartType>> perBranchOverrides) {
-    for (Map<VariableElement, DartType> branch in perBranchOverrides) {
+    int length = perBranchOverrides.length;
+    for (int i = 0; i < length; i++) {
+      Map<VariableElement, DartType> branch = perBranchOverrides[i];
       branch.forEach((VariableElement variable, DartType branchType) {
         DartType currentType = currentScope.getType(variable);
         if (currentType != branchType) {
@@ -10562,7 +10640,9 @@
 
   factory UsedLocalElements.merge(List<UsedLocalElements> parts) {
     UsedLocalElements result = new UsedLocalElements();
-    for (UsedLocalElements part in parts) {
+    int length = parts.length;
+    for (int i = 0; i < length; i++) {
+      UsedLocalElements part = parts[i];
       result.elements.addAll(part.elements);
       result.catchExceptionElements.addAll(part.catchExceptionElements);
       result.catchStackTraceElements.addAll(part.catchStackTraceElements);
@@ -10801,7 +10881,9 @@
   @override
   DartObjectImpl visitSimpleIdentifier(SimpleIdentifier node) {
     Element element = node.staticElement;
-    for (ParameterElement parameterElement in parameterElements) {
+    int length = parameterElements.length;
+    for (int i = 0; i < length; i++) {
+      ParameterElement parameterElement = parameterElements[i];
       if (identical(parameterElement, element) && parameterElement != null) {
         DartType type = parameterElement.type;
         if (type != null) {
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 7eb4a8b..fefd3eb 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -341,14 +341,23 @@
     }
     ExecutableElement staticMethodElement = node.staticElement;
     DartType staticType = _computeStaticReturnType(staticMethodElement);
-    staticType = _refineBinaryExpressionType(node, staticType, _getStaticType);
+    staticType = _typeSystem.refineBinaryExpressionType(
+        _typeProvider,
+        node.leftOperand.staticType,
+        node.operator.type,
+        node.rightOperand.staticType,
+        staticType);
     _recordStaticType(node, staticType);
     MethodElement propagatedMethodElement = node.propagatedElement;
     if (!identical(propagatedMethodElement, staticMethodElement)) {
       DartType propagatedType =
           _computeStaticReturnType(propagatedMethodElement);
-      propagatedType =
-          _refineBinaryExpressionType(node, propagatedType, _getBestType);
+      propagatedType = _typeSystem.refineBinaryExpressionType(
+          _typeProvider,
+          node.leftOperand.bestType,
+          node.operator.type,
+          node.rightOperand.bestType,
+          propagatedType);
       _resolver.recordPropagatedTypeIfBetter(node, propagatedType);
     }
     return null;
@@ -1634,13 +1643,6 @@
   }
 
   /**
-   * Return the best type of the given [expression].
-   */
-  DartType _getBestType(Expression expression) {
-    return expression.bestType;
-  }
-
-  /**
    * If the given element name can be mapped to the name of a class defined within the given
    * library, return the type specified by the argument.
    *
@@ -2178,50 +2180,6 @@
   }
 
   /**
-   * Attempts to make a better guess for the type of the given binary
-   * [expression], given that resolution has so far produced the [currentType].
-   * The [typeAccessor] is used to access the corresponding type of the left
-   * and right operands.
-   */
-  DartType _refineBinaryExpressionType(
-      BinaryExpression expression, DartType currentType,
-      [DartType typeAccessor(Expression node)]) {
-    TokenType operator = expression.operator.type;
-    // bool
-    if (operator == TokenType.AMPERSAND_AMPERSAND ||
-        operator == TokenType.BAR_BAR ||
-        operator == TokenType.EQ_EQ ||
-        operator == TokenType.BANG_EQ) {
-      return _typeProvider.boolType;
-    }
-    DartType intType = _typeProvider.intType;
-    if (typeAccessor(expression.leftOperand) == intType) {
-      // int op double
-      if (operator == TokenType.MINUS ||
-          operator == TokenType.PERCENT ||
-          operator == TokenType.PLUS ||
-          operator == TokenType.STAR) {
-        DartType doubleType = _typeProvider.doubleType;
-        if (typeAccessor(expression.rightOperand) == doubleType) {
-          return doubleType;
-        }
-      }
-      // int op int
-      if (operator == TokenType.MINUS ||
-          operator == TokenType.PERCENT ||
-          operator == TokenType.PLUS ||
-          operator == TokenType.STAR ||
-          operator == TokenType.TILDE_SLASH) {
-        if (typeAccessor(expression.rightOperand) == intType) {
-          return intType;
-        }
-      }
-    }
-    // default
-    return currentType;
-  }
-
-  /**
    * Create a table mapping HTML tag names to the names of the classes (in 'dart:html') that
    * implement those tags.
    *
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 526d067..877944a 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -7,6 +7,7 @@
 import 'dart:collection';
 import 'dart:math' as math;
 
+import 'package:analyzer/dart/ast/token.dart' show TokenType;
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -347,6 +348,39 @@
   }
 
   @override
+  DartType refineBinaryExpressionType(
+      TypeProvider typeProvider,
+      DartType leftType,
+      TokenType operator,
+      DartType rightType,
+      DartType currentType) {
+    if (leftType is TypeParameterType &&
+        leftType.element.bound == typeProvider.numType) {
+      if (rightType == leftType || rightType == typeProvider.intType) {
+        if (operator == TokenType.PLUS ||
+            operator == TokenType.MINUS ||
+            operator == TokenType.STAR ||
+            operator == TokenType.PLUS_EQ ||
+            operator == TokenType.MINUS_EQ ||
+            operator == TokenType.STAR_EQ) {
+          return leftType;
+        }
+      }
+      if (rightType == typeProvider.doubleType) {
+        if (operator == TokenType.PLUS ||
+            operator == TokenType.MINUS ||
+            operator == TokenType.STAR ||
+            operator == TokenType.SLASH) {
+          return typeProvider.doubleType;
+        }
+      }
+      return currentType;
+    }
+    return super.refineBinaryExpressionType(
+        typeProvider, leftType, operator, rightType, currentType);
+  }
+
+  @override
   DartType typeToConcreteType(TypeProvider typeProvider, DartType t) {
     if (t is FunctionType) {
       return functionTypeToConcreteType(typeProvider, t);
@@ -942,6 +976,59 @@
   }
 
   /**
+   * Attempts to make a better guess for the type of a binary with the given
+   * [operator], given that resolution has so far produced the [currentType].
+   */
+  DartType refineBinaryExpressionType(
+      TypeProvider typeProvider,
+      DartType leftType,
+      TokenType operator,
+      DartType rightType,
+      DartType currentType) {
+    // bool
+    if (operator == TokenType.AMPERSAND_AMPERSAND ||
+        operator == TokenType.BAR_BAR ||
+        operator == TokenType.EQ_EQ ||
+        operator == TokenType.BANG_EQ) {
+      return typeProvider.boolType;
+    }
+    DartType intType = typeProvider.intType;
+    if (leftType == intType) {
+      // int op double
+      if (operator == TokenType.MINUS ||
+          operator == TokenType.PERCENT ||
+          operator == TokenType.PLUS ||
+          operator == TokenType.STAR ||
+          operator == TokenType.MINUS_EQ ||
+          operator == TokenType.PERCENT_EQ ||
+          operator == TokenType.PLUS_EQ ||
+          operator == TokenType.STAR_EQ) {
+        DartType doubleType = typeProvider.doubleType;
+        if (rightType == doubleType) {
+          return doubleType;
+        }
+      }
+      // int op int
+      if (operator == TokenType.MINUS ||
+          operator == TokenType.PERCENT ||
+          operator == TokenType.PLUS ||
+          operator == TokenType.STAR ||
+          operator == TokenType.TILDE_SLASH ||
+          operator == TokenType.MINUS_EQ ||
+          operator == TokenType.PERCENT_EQ ||
+          operator == TokenType.PLUS_EQ ||
+          operator == TokenType.STAR_EQ ||
+          operator == TokenType.TILDE_SLASH_EQ) {
+        if (rightType == intType) {
+          return intType;
+        }
+      }
+    }
+    // default
+    return currentType;
+  }
+
+  /**
    * Given a [DartType] type, return the [TypeParameterElement]s corresponding
    * to its formal type parameters (if any).
    *
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index b47ef55..9b80057 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -548,8 +548,7 @@
 
   /**
    * If this is an instantiation of a generic type or generic executable, the
-   * type arguments used to instantiate it.  Trailing type arguments of type
-   * `dynamic` are omitted.
+   * type arguments used to instantiate it (if any).
    */
   void set typeArguments(List<EntityRefBuilder> _value) {
     assert(!_finished);
@@ -3538,6 +3537,7 @@
   bool _finished = false;
 
   List<UnlinkedConstBuilder> _arguments;
+  List<String> _argumentNames;
   UnlinkedConstBuilder _expression;
   idl.UnlinkedConstructorInitializerKind _kind;
   String _name;
@@ -3555,6 +3555,19 @@
   }
 
   @override
+  List<String> get argumentNames => _argumentNames ??= <String>[];
+
+  /**
+   * If there are `m` [arguments] and `n` [argumentNames], then each argument
+   * from [arguments] with index `i` such that `n + i - m >= 0`, should be used
+   * with the name at `n + i - m`.
+   */
+  void set argumentNames(List<String> _value) {
+    assert(!_finished);
+    _argumentNames = _value;
+  }
+
+  @override
   UnlinkedConstBuilder get expression => _expression;
 
   /**
@@ -3591,8 +3604,9 @@
     _name = _value;
   }
 
-  UnlinkedConstructorInitializerBuilder({List<UnlinkedConstBuilder> arguments, UnlinkedConstBuilder expression, idl.UnlinkedConstructorInitializerKind kind, String name})
+  UnlinkedConstructorInitializerBuilder({List<UnlinkedConstBuilder> arguments, List<String> argumentNames, UnlinkedConstBuilder expression, idl.UnlinkedConstructorInitializerKind kind, String name})
     : _arguments = arguments,
+      _argumentNames = argumentNames,
       _expression = expression,
       _kind = kind,
       _name = name;
@@ -3609,11 +3623,15 @@
     assert(!_finished);
     _finished = true;
     fb.Offset offset_arguments;
+    fb.Offset offset_argumentNames;
     fb.Offset offset_expression;
     fb.Offset offset_name;
     if (!(_arguments == null || _arguments.isEmpty)) {
       offset_arguments = fbBuilder.writeList(_arguments.map((b) => b.finish(fbBuilder)).toList());
     }
+    if (!(_argumentNames == null || _argumentNames.isEmpty)) {
+      offset_argumentNames = fbBuilder.writeList(_argumentNames.map((b) => fbBuilder.writeString(b)).toList());
+    }
     if (_expression != null) {
       offset_expression = _expression.finish(fbBuilder);
     }
@@ -3624,6 +3642,9 @@
     if (offset_arguments != null) {
       fbBuilder.addOffset(3, offset_arguments);
     }
+    if (offset_argumentNames != null) {
+      fbBuilder.addOffset(4, offset_argumentNames);
+    }
     if (offset_expression != null) {
       fbBuilder.addOffset(1, offset_expression);
     }
@@ -3650,6 +3671,7 @@
   _UnlinkedConstructorInitializerImpl(this._bp);
 
   List<idl.UnlinkedConst> _arguments;
+  List<String> _argumentNames;
   idl.UnlinkedConst _expression;
   idl.UnlinkedConstructorInitializerKind _kind;
   String _name;
@@ -3661,6 +3683,12 @@
   }
 
   @override
+  List<String> get argumentNames {
+    _argumentNames ??= const fb.ListReader<String>(const fb.StringReader()).vTableGet(_bp, 4, const <String>[]);
+    return _argumentNames;
+  }
+
+  @override
   idl.UnlinkedConst get expression {
     _expression ??= const _UnlinkedConstReader().vTableGet(_bp, 1, null);
     return _expression;
@@ -3684,6 +3712,7 @@
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
     if (arguments.isNotEmpty) _result["arguments"] = arguments.map((_value) => _value.toJson()).toList();
+    if (argumentNames.isNotEmpty) _result["argumentNames"] = argumentNames;
     if (expression != null) _result["expression"] = expression.toJson();
     if (kind != idl.UnlinkedConstructorInitializerKind.field) _result["kind"] = kind.toString().split('.')[1];
     if (name != '') _result["name"] = name;
@@ -3693,6 +3722,7 @@
   @override
   Map<String, Object> toMap() => {
     "arguments": arguments,
+    "argumentNames": argumentNames,
     "expression": expression,
     "kind": kind,
     "name": name,
@@ -6477,8 +6507,8 @@
 
   /**
    * If this [UnlinkedPublicName] is a class, the list of members which can be
-   * referenced from constants or factory redirects - static constant fields,
-   * static methods, and constructors.  Otherwise empty.
+   * referenced statically - static fields, static methods, and constructors.
+   * Otherwise empty.
    *
    * Unnamed constructors are not included since they do not constitute a
    * separate name added to any namespace.
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index 44d5544..8df99fe 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -614,7 +614,15 @@
   /**
    * Pop the top value from the stack and raise an exception with this value.
    */
-  throwException
+  throwException,
+
+  /**
+   * Obtain two values `n` and `m` from [UnlinkedConst.ints].  Then, starting at
+   * the executable element for the expression being evaluated, if n > 0, pop to
+   * the nth enclosing function element.  Then, push the mth local function of
+   * that element onto the stack.
+   */
+  pushLocalFunctionReference
 }
 
 /**
@@ -902,8 +910,7 @@
 
   /**
    * If this is an instantiation of a generic type or generic executable, the
-   * type arguments used to instantiate it.  Trailing type arguments of type
-   * `dynamic` are omitted.
+   * type arguments used to instantiate it (if any).
    */
   typeArguments:[EntityRef] (id: 1);
 }
@@ -1471,6 +1478,13 @@
   arguments:[UnlinkedConst] (id: 3);
 
   /**
+   * If there are `m` [arguments] and `n` [argumentNames], then each argument
+   * from [arguments] with index `i` such that `n + i - m >= 0`, should be used
+   * with the name at `n + i - m`.
+   */
+  argumentNames:[string] (id: 4);
+
+  /**
    * If [kind] is `field`, the expression of the field initializer.
    * Otherwise `null`.
    */
@@ -2021,8 +2035,8 @@
 
   /**
    * If this [UnlinkedPublicName] is a class, the list of members which can be
-   * referenced from constants or factory redirects - static constant fields,
-   * static methods, and constructors.  Otherwise empty.
+   * referenced statically - static fields, static methods, and constructors.
+   * Otherwise empty.
    *
    * Unnamed constructors are not included since they do not constitute a
    * separate name added to any namespace.
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 7992ccc..65b092d 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -202,8 +202,7 @@
 
   /**
    * If this is an instantiation of a generic type or generic executable, the
-   * type arguments used to instantiate it.  Trailing type arguments of type
-   * `dynamic` are omitted.
+   * type arguments used to instantiate it (if any).
    */
   @Id(1)
   List<EntityRef> get typeArguments;
@@ -1454,6 +1453,14 @@
    * Pop the top value from the stack and raise an exception with this value.
    */
   throwException,
+
+  /**
+   * Obtain two values `n` and `m` from [UnlinkedConst.ints].  Then, starting at
+   * the executable element for the expression being evaluated, if n > 0, pop to
+   * the nth enclosing function element.  Then, push the mth local function of
+   * that element onto the stack.
+   */
+  pushLocalFunctionReference,
 }
 
 /**
@@ -1468,6 +1475,14 @@
   List<UnlinkedConst> get arguments;
 
   /**
+   * If there are `m` [arguments] and `n` [argumentNames], then each argument
+   * from [arguments] with index `i` such that `n + i - m >= 0`, should be used
+   * with the name at `n + i - m`.
+   */
+  @Id(4)
+  List<String> get argumentNames;
+
+  /**
    * If [kind] is `field`, the expression of the field initializer.
    * Otherwise `null`.
    */
@@ -2287,8 +2302,8 @@
 
   /**
    * If this [UnlinkedPublicName] is a class, the list of members which can be
-   * referenced from constants or factory redirects - static constant fields,
-   * static methods, and constructors.  Otherwise empty.
+   * referenced statically - static fields, static methods, and constructors.
+   * Otherwise empty.
    *
    * Unnamed constructors are not included since they do not constitute a
    * separate name added to any namespace.
diff --git a/pkg/analyzer/lib/src/summary/link.dart b/pkg/analyzer/lib/src/summary/link.dart
index e68b5df..bc2fc0d 100644
--- a/pkg/analyzer/lib/src/summary/link.dart
+++ b/pkg/analyzer/lib/src/summary/link.dart
@@ -180,14 +180,21 @@
     return result;
   } else if (type is TypeParameterType) {
     TypeParameterElementForLink element = type.element;
-    result.paramReference =
-        typeParameterContext.typeParameterNestingLevel - element.nestingLevel;
+    if (typeParameterContext.isTypeParameterInScope(element)) {
+      result.paramReference =
+          typeParameterContext.typeParameterNestingLevel - element.nestingLevel;
+    } else {
+      // Out-of-scope type parameters only occur in circumstances where they
+      // are irrelevant (i.e. when a type parameter is unused).  So we can
+      // safely convert them to `dynamic`.
+      result.reference = compilationUnit.addRawReference('dynamic');
+    }
     return result;
   } else if (type is FunctionType) {
     Element element = type.element;
     if (element is FunctionElementForLink_FunctionTypedParam) {
       result.reference =
-          compilationUnit.addReference(element.innermostExecutable);
+          compilationUnit.addReference(element.typeParameterContext);
       result.implicitFunctionTypeIndices = element.implicitFunctionTypeIndices;
       _storeTypeArguments(
           type.typeArguments, result, compilationUnit, typeParameterContext);
@@ -205,6 +212,29 @@
           type.typeArguments, result, compilationUnit, typeParameterContext);
       return result;
     }
+    if (element is FunctionTypeAliasElementForLink) {
+      result.reference = compilationUnit.addReference(element);
+      _storeTypeArguments(
+          type.typeArguments, result, compilationUnit, typeParameterContext);
+      return result;
+    }
+    if (element is FunctionElement && element.enclosingElement == null) {
+      // Element is a synthetic function element that was generated on the fly
+      // to represent a type that has no associated source code location.
+      result.syntheticReturnType = _createLinkedType(
+          element.returnType, compilationUnit, typeParameterContext);
+      result.syntheticParams = element.parameters
+          .map((ParameterElement param) => _serializeSyntheticParam(
+              param, compilationUnit, typeParameterContext))
+          .toList();
+      return result;
+    }
+    if (element is FunctionElement) {
+      // Element is a local function inside another executable.
+      result.reference = compilationUnit.addReference(element);
+      // TODO(paulberry): do I need to store type arguments?
+      return result;
+    }
     // TODO(paulberry): implement other cases.
     throw new UnimplementedError('${element.runtimeType}');
   }
@@ -213,10 +243,48 @@
 }
 
 /**
+ * Create an [UnlinkedParam] representing the given [parameter], which should be
+ * a parameter of a synthetic function type (e.g. one produced during type
+ * inference as a result of computing the least upper bound of two function
+ * types).
+ */
+UnlinkedParamBuilder _serializeSyntheticParam(
+    ParameterElement parameter,
+    CompilationUnitElementInBuildUnit compilationUnit,
+    TypeParameterizedElementForLink typeParameterContext) {
+  UnlinkedParamBuilder b = new UnlinkedParamBuilder();
+  b.name = parameter.name;
+  switch (parameter.parameterKind) {
+    case ParameterKind.REQUIRED:
+      b.kind = UnlinkedParamKind.required;
+      break;
+    case ParameterKind.POSITIONAL:
+      b.kind = UnlinkedParamKind.positional;
+      break;
+    case ParameterKind.NAMED:
+      b.kind = UnlinkedParamKind.named;
+      break;
+  }
+  DartType type = parameter.type;
+  if (!parameter.hasImplicitType) {
+    if (type is FunctionType && type.element.isSynthetic) {
+      b.isFunctionTyped = true;
+      b.type = _createLinkedType(
+          type.returnType, compilationUnit, typeParameterContext);
+      b.parameters = type.parameters
+          .map((parameter) => _serializeSyntheticParam(
+              parameter, compilationUnit, typeParameterContext))
+          .toList();
+    } else {
+      b.type = _createLinkedType(type, compilationUnit, typeParameterContext);
+    }
+  }
+  return b;
+}
+
+/**
  * Store the given [typeArguments] in [encodedType], using [compilationUnit] and
  * [typeParameterContext] to serialize them.
- *
- * Trailing arguments of type `dynamic` are dropped.
  */
 void _storeTypeArguments(
     List<DartType> typeArguments,
@@ -224,20 +292,13 @@
     CompilationUnitElementInBuildUnit compilationUnit,
     TypeParameterizedElementForLink typeParameterContext) {
   int count = typeArguments.length;
-  while (count > 0) {
-    if (typeArguments[count - 1].isDynamic) {
-      count--;
-    } else {
-      List<EntityRefBuilder> encodedTypeArguments =
-          new List<EntityRefBuilder>(count);
-      for (int i = 0; i < count; i++) {
-        encodedTypeArguments[i] = _createLinkedType(
-            typeArguments[i], compilationUnit, typeParameterContext);
-      }
-      encodedType.typeArguments = encodedTypeArguments;
-      break;
-    }
+  List<EntityRefBuilder> encodedTypeArguments =
+      new List<EntityRefBuilder>(count);
+  for (int i = 0; i < count; i++) {
+    encodedTypeArguments[i] = _createLinkedType(
+        typeArguments[i], compilationUnit, typeParameterContext);
   }
+  encodedType.typeArguments = encodedTypeArguments;
 }
 
 /**
@@ -306,6 +367,9 @@
   LibraryElementForLink get library => enclosingElement.library;
 
   @override
+  List<MethodElementForLink> get methods;
+
+  @override
   String get name;
 
   @override
@@ -319,20 +383,16 @@
       for (ConstructorElementForLink constructor in constructors) {
         _containedNames[constructor.name] = constructor;
       }
-      for (FieldElementForLink field in fields) {
-        // TODO(paulberry): do we need to handle nonstatic fields for
-        // consistent behavior with erroneous code?
-        if (field.isStatic) {
-          _containedNames[field.name] = field;
-        }
-      }
       for (PropertyAccessorElementForLink accessor in accessors) {
-        if (accessor.isStatic && !accessor.isSynthetic) {
-          // TODO(paulberry): add synthetic elements too?
+        if (accessor.isStatic) {
           _containedNames[accessor.name] = accessor;
         }
       }
-      // TODO(paulberry): add methods.
+      for (MethodElementForLink method in methods) {
+        if (method.isStatic) {
+          _containedNames[method.name] = method;
+        }
+      }
     }
     return _containedNames.putIfAbsent(
         name, () => UndefinedElementForLink.instance);
@@ -368,16 +428,16 @@
   List<MethodElementForLink> _methods;
   List<InterfaceType> _mixins;
   List<InterfaceType> _interfaces;
-  List<PropertyAccessorElement> _accessors;
+  List<PropertyAccessorElementForLink> _accessors;
 
   ClassElementForLink_Class(
       CompilationUnitElementForLink enclosingElement, this._unlinkedClass)
       : super(enclosingElement);
 
   @override
-  List<PropertyAccessorElement> get accessors {
+  List<PropertyAccessorElementForLink> get accessors {
     if (_accessors == null) {
-      _accessors = <PropertyAccessorElement>[];
+      _accessors = <PropertyAccessorElementForLink>[];
       Map<String, SyntheticVariableElementForLink> syntheticVariables =
           <String, SyntheticVariableElementForLink>{};
       for (UnlinkedExecutable unlinkedExecutable
@@ -392,7 +452,7 @@
           SyntheticVariableElementForLink syntheticVariable = syntheticVariables
               .putIfAbsent(name, () => new SyntheticVariableElementForLink());
           PropertyAccessorElementForLink_Executable accessor =
-              new PropertyAccessorElementForLink_Executable(
+              new PropertyAccessorElementForLink_Executable(enclosingElement,
                   this, unlinkedExecutable, syntheticVariable);
           _accessors.add(accessor);
           if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
@@ -403,11 +463,9 @@
         }
       }
       for (FieldElementForLink_ClassField field in fields) {
-        _accessors
-            .add(new PropertyAccessorElementForLink_Variable(field, false));
+        _accessors.add(field.getter);
         if (!field.isConst && !field.isFinal) {
-          _accessors
-              .add(new PropertyAccessorElementForLink_Variable(field, true));
+          _accessors.add(field.setter);
         }
       }
     }
@@ -415,6 +473,9 @@
   }
 
   @override
+  CompilationUnitElementForLink get compilationUnit => enclosingElement;
+
+  @override
   List<ConstructorElementForLink> get constructors {
     if (_constructors == null) {
       _constructors = <ConstructorElementForLink>[];
@@ -459,6 +520,9 @@
       _unlinkedClass.interfaces.map(_computeInterfaceType).toList();
 
   @override
+  bool get isMixinApplication => _unlinkedClass.isMixinApplication;
+
+  @override
   bool get isObject => _unlinkedClass.hasNoSupertype;
 
   @override
@@ -521,12 +585,13 @@
       DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
     int numTypeParameters = _unlinkedClass.typeParameters.length;
     if (numTypeParameters != 0) {
-      List<DartType> typeArguments = new List<DartType>(numTypeParameters);
-      for (int i = 0; i < numTypeParameters; i++) {
-        typeArguments[i] = getTypeArgument(i);
-      }
-      return new InterfaceTypeImpl.elementWithNameAndArgs(
-          this, name, typeArguments);
+      return new InterfaceTypeImpl.elementWithNameAndArgs(this, name, () {
+        List<DartType> typeArguments = new List<DartType>(numTypeParameters);
+        for (int i = 0; i < numTypeParameters; i++) {
+          typeArguments[i] = getTypeArgument(i);
+        }
+        return typeArguments;
+      });
     } else {
       return _type ??= new InterfaceTypeImpl(this);
     }
@@ -603,15 +668,22 @@
 
   InterfaceType _type;
   List<FieldElementForLink_EnumField> _fields;
+  List<PropertyAccessorElementForLink> _accessors;
+  DartType _valuesType;
 
   ClassElementForLink_Enum(
       CompilationUnitElementForLink enclosingElement, this._unlinkedEnum)
       : super(enclosingElement);
 
   @override
-  List<PropertyAccessorElement> get accessors {
-    // TODO(paulberry): do we need to include synthetic accessors?
-    return const [];
+  List<PropertyAccessorElementForLink> get accessors {
+    if (_accessors == null) {
+      _accessors = <PropertyAccessorElementForLink>[];
+      for (FieldElementForLink_EnumField field in fields) {
+        _accessors.add(field.getter);
+      }
+    }
+    return _accessors;
   }
 
   @override
@@ -639,7 +711,7 @@
   bool get isObject => false;
 
   @override
-  List<MethodElement> get methods => const [];
+  List<MethodElementForLink> get methods => const [];
 
   @override
   List<InterfaceType> get mixins => const [];
@@ -659,6 +731,12 @@
   @override
   ConstructorElementForLink get unnamedConstructor => null;
 
+  /**
+   * Get the type of the enum's static member `values`.
+   */
+  DartType get valuesType =>
+      _valuesType ??= library._linker.typeProvider.listType.instantiate([type]);
+
   @override
   DartType buildType(DartType getTypeArgument(int i),
           List<int> implicitFunctionTypeIndices) =>
@@ -699,6 +777,8 @@
   List<TopLevelVariableElementForLink> _topLevelVariables;
   List<ClassElementForLink_Enum> _enums;
   List<TopLevelFunctionElementForLink> _functions;
+  List<PropertyAccessorElementForLink> _accessors;
+  List<FunctionTypeAliasElementForLink> _functionTypeAliases;
 
   /**
    * Index of this unit in the list of units in the enclosing library.
@@ -711,6 +791,43 @@
         _unlinkedUnit = unlinkedUnit;
 
   @override
+  List<PropertyAccessorElementForLink> get accessors {
+    if (_accessors == null) {
+      _accessors = <PropertyAccessorElementForLink>[];
+      Map<String, SyntheticVariableElementForLink> syntheticVariables =
+          <String, SyntheticVariableElementForLink>{};
+      for (UnlinkedExecutable unlinkedExecutable in _unlinkedUnit.executables) {
+        if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter ||
+            unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
+          String name = unlinkedExecutable.name;
+          if (unlinkedExecutable.kind == UnlinkedExecutableKind.setter) {
+            assert(name.endsWith('='));
+            name = name.substring(0, name.length - 1);
+          }
+          SyntheticVariableElementForLink syntheticVariable = syntheticVariables
+              .putIfAbsent(name, () => new SyntheticVariableElementForLink());
+          PropertyAccessorElementForLink_Executable accessor =
+              new PropertyAccessorElementForLink_Executable(
+                  this, null, unlinkedExecutable, syntheticVariable);
+          _accessors.add(accessor);
+          if (unlinkedExecutable.kind == UnlinkedExecutableKind.getter) {
+            syntheticVariable._getter = accessor;
+          } else {
+            syntheticVariable._setter = accessor;
+          }
+        }
+      }
+      for (TopLevelVariableElementForLink variable in topLevelVariables) {
+        _accessors.add(variable.getter);
+        if (!variable.isConst && !variable.isFinal) {
+          _accessors.add(variable.setter);
+        }
+      }
+    }
+    return _accessors;
+  }
+
+  @override
   LibraryElementForLink get enclosingElement;
 
   @override
@@ -738,6 +855,13 @@
   }
 
   @override
+  List<FunctionTypeAliasElementForLink> get functionTypeAliases =>
+      _functionTypeAliases ??= _unlinkedUnit.typedefs
+          .map((UnlinkedTypedef t) =>
+              new FunctionTypeAliasElementForLink(this, t))
+          .toList();
+
+  @override
   String get identifier => _absoluteUri;
 
   /**
@@ -804,12 +928,16 @@
       for (ClassElementForLink_Enum enm in enums) {
         _containedNames[enm.name] = enm;
       }
-      for (TopLevelVariableElementForLink variable in topLevelVariables) {
-        _containedNames[variable.name] = variable;
-      }
       for (TopLevelFunctionElementForLink function in functions) {
         _containedNames[function.name] = function;
       }
+      for (PropertyAccessorElementForLink accessor in accessors) {
+        _containedNames[accessor.name] = accessor;
+      }
+      for (FunctionTypeAliasElementForLink functionTypeAlias
+          in functionTypeAliases) {
+        _containedNames[functionTypeAlias.name] = functionTypeAlias;
+      }
       // TODO(paulberry): fill in other top level entities (typedefs
       // and executables).
     }
@@ -950,11 +1078,22 @@
       int numTypeParameters: 0,
       int unitNum: 0,
       int containingReference: 0,
+      int localIndex: 0,
       ReferenceKind kind: ReferenceKind.classOrEnum}) {
     List<LinkedReferenceBuilder> linkedReferences = _linkedUnit.references;
     List<UnlinkedReference> unlinkedReferences = _unlinkedUnit.references;
     for (int i = 0; i < linkedReferences.length; i++) {
       LinkedReferenceBuilder linkedReference = linkedReferences[i];
+      int candidateContainingReference = i < unlinkedReferences.length
+          ? unlinkedReferences[i].prefixReference
+          : linkedReference.containingReference;
+      if (candidateContainingReference != 0 &&
+          linkedReferences[candidateContainingReference].kind ==
+              ReferenceKind.prefix) {
+        // We don't need to match containing references when they are prefixes,
+        // since the relevant information is in linkedReference.dependency.
+        candidateContainingReference = 0;
+      }
       if (linkedReference.dependency == dependency &&
           (i < unlinkedReferences.length
                   ? unlinkedReferences[i].name
@@ -962,11 +1101,9 @@
               name &&
           linkedReference.numTypeParameters == numTypeParameters &&
           linkedReference.unit == unitNum &&
-          (i < unlinkedReferences.length
-                  ? unlinkedReferences[i].prefixReference
-                  : linkedReference.containingReference) ==
-              containingReference &&
-          linkedReference.kind == kind) {
+          candidateContainingReference == containingReference &&
+          linkedReference.kind == kind &&
+          linkedReference.localIndex == localIndex) {
         return i;
       }
     }
@@ -977,7 +1114,8 @@
         numTypeParameters: numTypeParameters,
         unit: unitNum,
         containingReference: containingReference,
-        kind: kind));
+        kind: kind,
+        localIndex: localIndex));
     return result;
   }
 
@@ -992,6 +1130,12 @@
           dependency: library.addDependency(element.library),
           numTypeParameters: element.typeParameters.length,
           unitNum: element.enclosingElement.unitNum);
+    } else if (element is FunctionTypeAliasElementForLink) {
+      return addRawReference(element.name,
+          dependency: library.addDependency(element.library),
+          numTypeParameters: element.typeParameters.length,
+          unitNum: element.enclosingElement.unitNum,
+          kind: ReferenceKind.typedef);
     } else if (element is ExecutableElementForLink) {
       ClassElementForLink_Class enclosingClass = element.enclosingClass;
       ReferenceKind kind;
@@ -1013,6 +1157,28 @@
           containingReference:
               enclosingClass != null ? addReference(enclosingClass) : null,
           kind: kind);
+    } else if (element is FunctionElementForLink_Local) {
+      FunctionElementImpl parent = element.enclosingElement;
+      int localIndex = parent.functions.indexOf(element);
+      assert(localIndex != -1);
+      return addRawReference(element.name,
+          containingReference: addReference(parent),
+          kind: ReferenceKind.function,
+          localIndex: localIndex);
+    } else if (element is FunctionElementForLink_Initializer) {
+      return addRawReference('',
+          containingReference: addReference(element.enclosingElement),
+          kind: ReferenceKind.function);
+    } else if (element is TopLevelVariableElementForLink) {
+      return addRawReference(element.name,
+          kind: ReferenceKind.topLevelPropertyAccessor);
+    } else if (element is FieldElementForLink_ClassField) {
+      ClassElementForLink_Class enclosingClass = element.enclosingElement;
+      // TODO(paulberry): do we need to set numTypeParameters to nonzero if the
+      // class has type parameters?
+      return addRawReference(element.name,
+          containingReference: addReference(enclosingClass),
+          kind: ReferenceKind.propertyAccessor);
     }
     // TODO(paulberry): implement other cases
     throw new UnimplementedError('${element.runtimeType}');
@@ -1223,7 +1389,7 @@
         // Note: non-static const isn't allowed but we handle it anyway so
         // that we won't be confused by incorrect code.
         if ((field.isFinal || field.isConst) && !field.isStatic) {
-          safeAddDependency(field.asConstVariable);
+          safeAddDependency(field.getter.asConstVariable);
         }
       }
       for (ParameterElementForLink parameterElement
@@ -1242,7 +1408,7 @@
     EntityRef redirectedConstructor =
         constructorElement._unlinkedExecutable.redirectedConstructor;
     if (redirectedConstructor != null) {
-      return constructorElement.enclosingUnit
+      return constructorElement.compilationUnit
           ._resolveRef(redirectedConstructor.reference)
           .asConstructor;
     } else {
@@ -1619,7 +1785,6 @@
   DartType _declaredReturnType;
   DartType _inferredReturnType;
   FunctionTypeImpl _type;
-  List<TypeParameterElementForLink> _typeParameters;
   String _name;
   String _displayName;
 
@@ -1629,13 +1794,11 @@
    */
   final ClassElementForLink_Class enclosingClass;
 
-  /**
-   * Return the compilation unit in which this executable appears.
-   */
-  final CompilationUnitElementForLink enclosingUnit;
+  @override
+  final CompilationUnitElementForLink compilationUnit;
 
   ExecutableElementForLink(
-      this.enclosingUnit, this.enclosingClass, this._unlinkedExecutable);
+      this.compilationUnit, this.enclosingClass, this._unlinkedExecutable);
 
   /**
    * If the executable element had an explicitly declared return type, return
@@ -1646,7 +1809,7 @@
       return null;
     } else {
       return _declaredReturnType ??=
-          enclosingUnit._resolveTypeRef(_unlinkedExecutable.returnType, this);
+          compilationUnit._resolveTypeRef(_unlinkedExecutable.returnType, this);
     }
   }
 
@@ -1662,7 +1825,7 @@
   }
 
   @override
-  Element get enclosingElement => enclosingClass ?? enclosingUnit;
+  Element get enclosingElement => enclosingClass ?? compilationUnit;
 
   @override
   TypeParameterizedElementForLink get enclosingTypeParameterContext =>
@@ -1684,7 +1847,7 @@
     assert(_unlinkedExecutable.returnType == null);
     if (Linker._initializerTypeInferenceCycle != null &&
         Linker._initializerTypeInferenceCycle ==
-            enclosingUnit.library.libraryCycleForLink) {
+            compilationUnit.library.libraryCycleForLink) {
       // We are currently computing the type of an initializer expression in the
       // current library cycle, so type inference results should be ignored.
       return _computeDefaultReturnType();
@@ -1693,10 +1856,10 @@
       if (_unlinkedExecutable.kind == UnlinkedExecutableKind.constructor) {
         // TODO(paulberry): implement.
         throw new UnimplementedError();
-      } else if (enclosingUnit.isInBuildUnit) {
+      } else if (compilationUnit.isInBuildUnit) {
         _inferredReturnType = _computeDefaultReturnType();
       } else {
-        _inferredReturnType = enclosingUnit.getLinkedType(
+        _inferredReturnType = compilationUnit.getLinkedType(
             _unlinkedExecutable.inferredReturnTypeSlot, this);
       }
     }
@@ -1704,9 +1867,6 @@
   }
 
   @override
-  ExecutableElementForLink get innermostExecutable => this;
-
-  @override
   bool get isStatic => _unlinkedExecutable.isStatic;
 
   @override
@@ -1739,6 +1899,9 @@
   FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
 
   @override
+  TypeParameterizedElementForLink get typeParameterContext => this;
+
+  @override
   List<UnlinkedParam> get unlinkedParameters => _unlinkedExecutable.parameters;
 
   @override
@@ -1781,6 +1944,7 @@
 
 class ExprTypeComputer {
   VariableElementForLink variable;
+  FunctionElementForLink_Initializer initializer;
   CompilationUnitElementForLink unit;
   LibraryElementForLink library;
   Linker linker;
@@ -1795,6 +1959,7 @@
 
   ExprTypeComputer(VariableElementForLink variableElement) {
     this.variable = variableElement;
+    initializer = variableElement.initializer;
     unit = variableElement.compilationUnit;
     library = unit.enclosingElement;
     linker = library._linker;
@@ -1961,6 +2126,11 @@
           stack.removeLast();
           stack.add(BottomTypeImpl.instance);
           break;
+        case UnlinkedConstOperation.pushLocalFunctionReference:
+          int popCount = _getNextInt();
+          assert(popCount == 0); // TODO(paulberry): handle the nonzero case.
+          stack.add(initializer.functions[_getNextInt()].type);
+          break;
         default:
           // TODO(paulberry): implement.
           throw new UnimplementedError('$operation');
@@ -2108,12 +2278,23 @@
     ConstructorElementForLink element =
         unit._resolveRef(ref.reference).asConstructor;
     if (element != null) {
-      stack.add(element.enclosingClass.buildType(
-          (int i) => i >= ref.typeArguments.length
-              ? DynamicTypeImpl.instance
-              : unit._resolveTypeRef(
-                  ref.typeArguments[i], variable._typeParameterContext),
-          const []));
+      ClassElementForLink_Class enclosingClass = element.enclosingClass;
+      stack.add(enclosingClass.buildType((int i) {
+        // Type argument explicitly specified.
+        if (i < ref.typeArguments.length) {
+          return unit._resolveTypeRef(
+              ref.typeArguments[i], variable._typeParameterContext);
+        }
+        // In strong mode, type argument defaults to bound (if any).
+        if (linker.strongMode) {
+          TypeParameterElement typeParameter = enclosingClass.typeParameters[i];
+          if (typeParameter.bound != null) {
+            return typeParameter.bound;
+          }
+        }
+        // Otherwise type argument defaults to `dynamic`.
+        return DynamicTypeImpl.instance;
+      }, const []));
     } else {
       stack.add(DynamicTypeImpl.instance);
     }
@@ -2318,7 +2499,8 @@
       MethodElement method = left.lookUpMethod(operator.lexeme, library);
       if (method != null) {
         DartType type = method.returnType;
-        type = _refineBinaryExpressionType(operator, type, left, right);
+        type = linker.typeSystem.refineBinaryExpressionType(
+            typeProvider, left, operator, right, type);
         stack.add(type);
         return;
       }
@@ -2337,35 +2519,6 @@
     _pushBinaryOperatorType(propertyType, operator, operandType);
   }
 
-  DartType _refineBinaryExpressionType(TokenType operator, DartType currentType,
-      DartType leftType, DartType rightType) {
-    DartType intType = typeProvider.intType;
-    if (leftType == intType) {
-      // int op double
-      if (operator == TokenType.MINUS ||
-          operator == TokenType.PERCENT ||
-          operator == TokenType.PLUS ||
-          operator == TokenType.STAR) {
-        DartType doubleType = typeProvider.doubleType;
-        if (rightType == doubleType) {
-          return doubleType;
-        }
-      }
-      // int op int
-      if (operator == TokenType.MINUS ||
-          operator == TokenType.PERCENT ||
-          operator == TokenType.PLUS ||
-          operator == TokenType.STAR ||
-          operator == TokenType.TILDE_SLASH) {
-        if (rightType == intType) {
-          return intType;
-        }
-      }
-    }
-    // default
-    return currentType;
-  }
-
   static TokenType _convertAssignOperatorToTokenType(
       UnlinkedExprAssignOperator o) {
     switch (o) {
@@ -2418,8 +2571,13 @@
  * Element representing a field resynthesized from a summary during
  * linking.
  */
-abstract class FieldElementForLink
-    implements FieldElement, ReferenceableElementForLink {}
+abstract class FieldElementForLink implements FieldElement {
+  @override
+  PropertyAccessorElementForLink get getter;
+
+  @override
+  PropertyAccessorElementForLink get setter;
+}
 
 /**
  * Specialization of [FieldElementForLink] for class fields.
@@ -2481,27 +2639,16 @@
    */
   final UnlinkedEnumValue unlinkedEnumValue;
 
+  PropertyAccessorElementForLink_EnumField _getter;
+
   @override
   final ClassElementForLink_Enum enclosingElement;
 
   FieldElementForLink_EnumField(this.unlinkedEnumValue, this.enclosingElement);
 
   @override
-  ConstructorElementForLink get asConstructor => null;
-
-  @override
-  ConstVariableNode get asConstVariable {
-    // Even though enum fields are constants, there is no need to include them
-    // in the const dependency graph because they can't participate in a
-    // circularity.
-    return null;
-  }
-
-  @override
-  DartType get asStaticType => enclosingElement.type;
-
-  @override
-  TypeInferenceNode get asTypeInferenceNode => null;
+  PropertyAccessorElementForLink_EnumField get getter =>
+      _getter ??= new PropertyAccessorElementForLink_EnumField(this);
 
   @override
   bool get isStatic => true;
@@ -2514,13 +2661,9 @@
       unlinkedEnumValue == null ? 'values' : unlinkedEnumValue.name;
 
   @override
-  DartType buildType(DartType getTypeArgument(int i),
-          List<int> implicitFunctionTypeIndices) =>
-      DynamicTypeImpl.instance;
-
-  @override
-  ReferenceableElementForLink getContainedName(String name) =>
-      UndefinedElementForLink.instance;
+  DartType get type => unlinkedEnumValue == null
+      ? enclosingElement.valuesType
+      : enclosingElement.type;
 
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@@ -2540,7 +2683,7 @@
   final ParameterElementForLink enclosingElement;
 
   @override
-  final ExecutableElementForLink innermostExecutable;
+  final TypeParameterizedElementForLink typeParameterContext;
 
   @override
   final List<UnlinkedParam> unlinkedParameters;
@@ -2548,8 +2691,8 @@
   DartType _returnType;
   List<int> _implicitFunctionTypeIndices;
 
-  FunctionElementForLink_FunctionTypedParam(
-      this.enclosingElement, this.innermostExecutable, this.unlinkedParameters);
+  FunctionElementForLink_FunctionTypedParam(this.enclosingElement,
+      this.typeParameterContext, this.unlinkedParameters);
 
   @override
   List<int> get implicitFunctionTypeIndices {
@@ -2569,7 +2712,7 @@
         _returnType = DynamicTypeImpl.instance;
       } else {
         _returnType = enclosingElement.compilationUnit._resolveTypeRef(
-            enclosingElement._unlinkedParam.type, innermostExecutable);
+            enclosingElement._unlinkedParam.type, typeParameterContext);
       }
     }
     return _returnType;
@@ -2591,9 +2734,21 @@
    */
   final VariableElementForLink _variable;
 
+  List<FunctionElementForLink_Local> _functions;
+
   FunctionElementForLink_Initializer(this._variable);
 
   @override
+  VariableElementForLink get enclosingElement => _variable;
+
+  @override
+  List<FunctionElementForLink_Local> get functions => _functions ??= _variable
+      .unlinkedVariable.initializer.localFunctions
+      .map(
+          (UnlinkedExecutable ex) => new FunctionElementForLink_Local(this, ex))
+      .toList();
+
+  @override
   DartType get returnType {
     // If this is a variable whose type needs inferring, infer it.
     if (_variable.hasImplicitType) {
@@ -2619,6 +2774,135 @@
 }
 
 /**
+ * Element representing a local function (possibly a closure) inside another
+ * executable.
+ */
+class FunctionElementForLink_Local implements FunctionElementImpl {
+  /**
+   * The unlinked representation of the local function in the summary.
+   */
+  final UnlinkedExecutable _executable;
+
+  @override
+  final FunctionElementImpl enclosingElement;
+
+  DartType _type;
+
+  FunctionElementForLink_Local(this.enclosingElement, this._executable);
+
+  @override
+  String get name => _executable.name;
+
+  @override
+  DartType get type => _type ??= new FunctionTypeImpl(this);
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
+ * Element representing a typedef resynthesized from a summary during linking.
+ */
+class FunctionTypeAliasElementForLink extends Object
+    with TypeParameterizedElementForLink, ParameterParentElementForLink
+    implements
+        FunctionTypeAliasElement,
+        ReferenceableElementForLink,
+        ElementImpl {
+  @override
+  final CompilationUnitElementForLink enclosingElement;
+
+  /**
+   * The unlinked representation of the typedef in the summary.
+   */
+  final UnlinkedTypedef _unlinkedTypedef;
+
+  FunctionTypeImpl _type;
+  DartType _returnType;
+
+  FunctionTypeAliasElementForLink(this.enclosingElement, this._unlinkedTypedef);
+
+  @override
+  ConstructorElementForLink get asConstructor => null;
+
+  @override
+  ConstVariableNode get asConstVariable {
+    // When a typedef name is used as a constant variable, it doesn't depend on
+    // anything, so it is not necessary to include it in the constant
+    // dependency graph.
+    return null;
+  }
+
+  @override
+  DartType get asStaticType {
+    return enclosingElement.enclosingElement._linker.typeProvider.typeType;
+  }
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => null;
+
+  @override
+  CompilationUnitElementForLink get compilationUnit => enclosingElement;
+
+  @override
+  TypeParameterizedElementForLink get enclosingTypeParameterContext => null;
+
+  @override
+  String get identifier => _unlinkedTypedef.name;
+
+  @override
+  List<int> get implicitFunctionTypeIndices => const <int>[];
+
+  @override
+  bool get isSynthetic => false;
+
+  @override
+  LibraryElementForLink get library => enclosingElement.library;
+
+  @override
+  String get name => _unlinkedTypedef.name;
+
+  @override
+  DartType get returnType => _returnType ??=
+      enclosingElement._resolveTypeRef(_unlinkedTypedef.returnType, this);
+
+  @override
+  TypeParameterizedElementForLink get typeParameterContext => this;
+
+  @override
+  List<UnlinkedParam> get unlinkedParameters => _unlinkedTypedef.parameters;
+
+  @override
+  List<UnlinkedTypeParam> get _unlinkedTypeParams =>
+      _unlinkedTypedef.typeParameters;
+
+  @override
+  DartType buildType(
+      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
+    int numTypeParameters = _unlinkedTypedef.typeParameters.length;
+    if (numTypeParameters != 0) {
+      List<DartType> typeArguments = new List<DartType>(numTypeParameters);
+      for (int i = 0; i < numTypeParameters; i++) {
+        typeArguments[i] = getTypeArgument(i);
+      }
+      return new FunctionTypeImpl.elementWithNameAndArgs(
+          this, name, typeArguments, true);
+    } else {
+      return _type ??= new FunctionTypeImpl.forTypedef(this);
+    }
+  }
+
+  @override
+  ReferenceableElementForLink getContainedName(String name) {
+    // TODO(paulberry): implement.
+    throw new UnimplementedError();
+  }
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+}
+
+/**
  * Specialization of [DependencyWalker] for linking library cycles.
  */
 class LibraryCycleDependencyWalker extends DependencyWalker<LibraryCycleNode> {
@@ -3164,19 +3448,42 @@
  * Element representing a method resynthesized from a summary during linking.
  */
 class MethodElementForLink extends ExecutableElementForLink
-    implements MethodElementImpl {
+    implements MethodElementImpl, ReferenceableElementForLink {
   MethodElementForLink(ClassElementForLink_Class enclosingClass,
       UnlinkedExecutable unlinkedExecutable)
       : super(enclosingClass.enclosingElement, enclosingClass,
             unlinkedExecutable);
 
   @override
+  ConstructorElementForLink get asConstructor => null;
+
+  @override
+  ConstVariableNode get asConstVariable => null;
+
+  @override
+  DartType get asStaticType => type;
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => null;
+
+  @override
   String get identifier => name;
 
   @override
   ElementKind get kind => ElementKind.METHOD;
 
   @override
+  DartType buildType(DartType getTypeArgument(int i),
+          List<int> implicitFunctionTypeIndices) =>
+      DynamicTypeImpl.instance;
+
+  @override
+  ReferenceableElementForLink getContainedName(String name) {
+    // TODO(paulberry): handle references to `call`.
+    return UndefinedElementForLink.instance;
+  }
+
+  @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
   @override
@@ -3226,47 +3533,61 @@
  * Element used for references that result from trying to access a non-static
  * member of an element that is not a container (e.g. accessing the "length"
  * property of a constant).
+ *
+ * Accesses to a chain of non-static members separated by '.' are andled by
+ * creating a [NonstaticMemberElementForLink] that points to another
+ * [NonstaticMemberElementForLink], to whatever nesting level is necessary.
  */
 class NonstaticMemberElementForLink implements ReferenceableElementForLink {
   /**
-   * The non-static element of this link element.
+   * The [ReferenceableElementForLink] which is the target of the non-static
+   * reference.
    */
-  final Element element;
+  final ReferenceableElementForLink _target;
 
   /**
-   * If the thing from which a member was accessed is a constant, the
-   * associated [ConstNode].  Otherwise `null`.
+   * The name of the non-static members that is being accessed.
    */
-  final ConstVariableNode _constNode;
+  final String _name;
 
-  NonstaticMemberElementForLink(this.element, this._constNode);
+  /**
+   * The library in which the access occurs.  This determines whether private
+   * names are accessible.
+   */
+  final LibraryElementForLink _library;
+
+  NonstaticMemberElementForLink(this._library, this._target, this._name);
 
   @override
   ConstructorElementForLink get asConstructor => null;
 
   @override
-  ConstVariableNode get asConstVariable => _constNode;
+  ConstVariableNode get asConstVariable => _target.asConstVariable;
 
   @override
   DartType get asStaticType {
-    Element element = this.element;
-    if (element is PropertyAccessorElement) {
-      if (element.isGetter) {
-        return element.returnType;
+    if (_library._linker.strongMode) {
+      DartType targetType = _target.asStaticType;
+      if (targetType is InterfaceType) {
+        PropertyAccessorElement getter =
+            targetType.lookUpGetter(_name, _library);
+        if (getter != null) {
+          return getter.returnType;
+        }
+        MethodElement method = targetType.lookUpMethod(_name, _library);
+        if (method != null) {
+          return method.type;
+        }
       }
-      return DynamicTypeImpl.instance;
+      // TODO(paulberry): handle .call on function types and .toString or
+      // .hashCode on all types.
     }
-    if (element is MethodElement) {
-      return element.type;
-    }
+    // TODO(paulberry, scheglov): implement for propagated types
     return DynamicTypeImpl.instance;
   }
 
   @override
-  TypeInferenceNode get asTypeInferenceNode {
-    // TODO(paulberry): implement.
-    return null;
-  }
+  TypeInferenceNode get asTypeInferenceNode => _target.asTypeInferenceNode;
 
   @override
   DartType buildType(DartType getTypeArgument(int i),
@@ -3275,15 +3596,7 @@
 
   @override
   ReferenceableElementForLink getContainedName(String name) {
-    if (element != null) {
-      DartType type = asStaticType;
-      if (type is InterfaceType) {
-        Element nameElement = type.lookUpGetter(name, element.library);
-        nameElement ??= type.lookUpMethod(name, element.library);
-        return new NonstaticMemberElementForLink(nameElement, _constNode);
-      }
-    }
-    return this;
+    return new NonstaticMemberElementForLink(_library, this, name);
   }
 }
 
@@ -3298,9 +3611,9 @@
   final UnlinkedParam _unlinkedParam;
 
   /**
-   * The innermost executable element containing this parameter.
+   * The innermost enclosing element that can declare type parameters.
    */
-  final ExecutableElementForLink _innermostExecutable;
+  final TypeParameterizedElementForLink _typeParameterContext;
 
   /**
    * If this parameter has a default value and the enclosing library
@@ -3326,13 +3639,16 @@
   DartType _declaredType;
 
   ParameterElementForLink(this.enclosingElement, this._unlinkedParam,
-      this._innermostExecutable, this.compilationUnit, this._parameterIndex) {
+      this._typeParameterContext, this.compilationUnit, this._parameterIndex) {
     if (_unlinkedParam.defaultValue != null) {
       _constNode = new ConstParameterNode(this);
     }
   }
 
   @override
+  String get displayName => _unlinkedParam.name;
+
+  @override
   bool get hasImplicitType =>
       !_unlinkedParam.isFunctionTyped && _unlinkedParam.type == null;
 
@@ -3359,18 +3675,18 @@
       if (_unlinkedParam.isFunctionTyped) {
         _declaredType = new FunctionTypeImpl(
             new FunctionElementForLink_FunctionTypedParam(
-                this, _innermostExecutable, _unlinkedParam.parameters));
+                this, _typeParameterContext, _unlinkedParam.parameters));
       } else if (_unlinkedParam.type == null) {
         if (!compilationUnit.isInBuildUnit) {
           _inferredType = compilationUnit.getLinkedType(
-              _unlinkedParam.inferredTypeSlot, _innermostExecutable);
+              _unlinkedParam.inferredTypeSlot, _typeParameterContext);
           return _inferredType;
         } else {
           _declaredType = DynamicTypeImpl.instance;
         }
       } else {
         _declaredType = compilationUnit._resolveTypeRef(
-            _unlinkedParam.type, _innermostExecutable);
+            _unlinkedParam.type, _typeParameterContext);
       }
     }
     return _declaredType;
@@ -3388,7 +3704,7 @@
    */
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     compilationUnit._storeLinkedType(
-        _unlinkedParam.inferredTypeSlot, _inferredType, _innermostExecutable);
+        _unlinkedParam.inferredTypeSlot, _inferredType, _typeParameterContext);
   }
 
   @override
@@ -3437,12 +3753,6 @@
   List<int> get implicitFunctionTypeIndices;
 
   /**
-   * Get the innermost enclosing ExecutableElement (which may be [this], or may
-   * be a parent when there are function-typed parameters).
-   */
-  ExecutableElementForLink get innermostExecutable;
-
-  /**
    * Get all the parameters of this element.
    */
   List<ParameterElementForLink> get parameters {
@@ -3453,13 +3763,20 @@
       for (int i = 0; i < numParameters; i++) {
         UnlinkedParam unlinkedParam = unlinkedParameters[i];
         _parameters[i] = new ParameterElementForLink(this, unlinkedParam,
-            innermostExecutable, innermostExecutable.enclosingUnit, i);
+            typeParameterContext, typeParameterContext.compilationUnit, i);
       }
     }
     return _parameters;
   }
 
   /**
+   * Get the innermost enclosing element that can declare type parameters (which
+   * may be [this], or may be a parent when there are function-typed
+   * parameters).
+   */
+  TypeParameterizedElementForLink get typeParameterContext;
+
+  /**
    * Get the list of unlinked parameters of this element.
    */
   List<UnlinkedParam> get unlinkedParameters;
@@ -3475,6 +3792,92 @@
 }
 
 /**
+ * Specialization of [PropertyAccessorElementForLink] for synthetic accessors
+ * implied by the synthetic fields of an enum declaration.
+ */
+class PropertyAccessorElementForLink_EnumField
+    implements PropertyAccessorElementForLink {
+  @override
+  final FieldElementForLink_EnumField variable;
+
+  FunctionTypeImpl _type;
+
+  PropertyAccessorElementForLink_EnumField(this.variable);
+
+  @override
+  ConstructorElementForLink get asConstructor => null;
+
+  @override
+  ConstVariableNode get asConstVariable => null;
+
+  @override
+  DartType get asStaticType => returnType;
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => null;
+
+  @override
+  Element get enclosingElement => variable.enclosingElement;
+
+  @override
+  bool get isGetter => true;
+
+  @override
+  bool get isSetter => false;
+
+  @override
+  bool get isStatic => variable.isStatic;
+
+  @override
+  bool get isSynthetic => true;
+
+  @override
+  ElementKind get kind => ElementKind.GETTER;
+
+  @override
+  LibraryElementForLink get library =>
+      variable.enclosingElement.enclosingElement.enclosingElement;
+
+  @override
+  String get name => variable.name;
+
+  @override
+  List<ParameterElement> get parameters => const [];
+
+  @override
+  DartType get returnType => variable.type;
+
+  @override
+  FunctionTypeImpl get type => _type ??= new FunctionTypeImpl(this);
+
+  @override
+  List<TypeParameterElement> get typeParameters => const [];
+
+  @override
+  DartType buildType(DartType getTypeArgument(int i),
+          List<int> implicitFunctionTypeIndices) =>
+      DynamicTypeImpl.instance;
+
+  @override
+  ReferenceableElementForLink getContainedName(String name) {
+    return new NonstaticMemberElementForLink(library, this, name);
+  }
+
+  @override
+  bool isAccessibleIn(LibraryElement library) =>
+      !Identifier.isPrivateName(name) || identical(this.library, library);
+
+  @override
+  void link(CompilationUnitElementInBuildUnit compilationUnit) {}
+
+  @override
+  noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
+
+  @override
+  String toString() => '$enclosingElement.$name';
+}
+
+/**
  * Specialization of [PropertyAccessorElementForLink] for non-synthetic
  * accessors explicitly declared in the source code.
  */
@@ -3484,11 +3887,11 @@
   SyntheticVariableElementForLink variable;
 
   PropertyAccessorElementForLink_Executable(
+      CompilationUnitElementForLink enclosingUnit,
       ClassElementForLink_Class enclosingClass,
       UnlinkedExecutable unlinkedExecutable,
       this.variable)
-      : super(enclosingClass.enclosingElement, enclosingClass,
-            unlinkedExecutable);
+      : super(enclosingUnit, enclosingClass, unlinkedExecutable);
 
   @override
   ConstructorElementForLink get asConstructor => null;
@@ -3524,8 +3927,9 @@
       DynamicTypeImpl.instance;
 
   @override
-  ReferenceableElementForLink getContainedName(String name) =>
-      UndefinedElementForLink.instance;
+  ReferenceableElementForLink getContainedName(String name) {
+    return new NonstaticMemberElementForLink(library, this, name);
+  }
 
   @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
@@ -3550,6 +3954,18 @@
   PropertyAccessorElementForLink_Variable(this.variable, this.isSetter);
 
   @override
+  ConstructorElementForLink get asConstructor => null;
+
+  @override
+  ConstVariableNode get asConstVariable => variable._constNode;
+
+  @override
+  DartType get asStaticType => returnType;
+
+  @override
+  TypeInferenceNode get asTypeInferenceNode => variable._typeInferenceNode;
+
+  @override
   Element get enclosingElement => variable.enclosingElement;
 
   @override
@@ -3600,6 +4016,11 @@
     return const [];
   }
 
+  @override
+  DartType buildType(DartType getTypeArgument(int i),
+          List<int> implicitFunctionTypeIndices) =>
+      DynamicTypeImpl.instance;
+
   /**
    * Compute the type of the corresponding variable, which may depend on the
    * progress of type inference.
@@ -3619,6 +4040,11 @@
   }
 
   @override
+  ReferenceableElementForLink getContainedName(String name) {
+    return new NonstaticMemberElementForLink(library, this, name);
+  }
+
+  @override
   bool isAccessibleIn(LibraryElement library) =>
       !Identifier.isPrivateName(name) || identical(this.library, library);
 
@@ -3786,14 +4212,20 @@
  */
 class TopLevelVariableElementForLink extends VariableElementForLink
     implements TopLevelVariableElement {
-  TopLevelVariableElementForLink(CompilationUnitElement enclosingElement,
+  TopLevelVariableElementForLink(CompilationUnitElementForLink enclosingElement,
       UnlinkedVariable unlinkedVariable)
       : super(unlinkedVariable, enclosingElement);
 
   @override
+  CompilationUnitElementForLink get enclosingElement => compilationUnit;
+
+  @override
   bool get isStatic => true;
 
   @override
+  LibraryElementForLink get library => compilationUnit.library;
+
+  @override
   TypeParameterizedElementForLink get _typeParameterContext => null;
 
   /**
@@ -3802,7 +4234,7 @@
    */
   void link(CompilationUnitElementInBuildUnit compilationUnit) {
     if (hasImplicitType) {
-      TypeInferenceNode typeInferenceNode = this.asTypeInferenceNode;
+      TypeInferenceNode typeInferenceNode = this._typeInferenceNode;
       if (typeInferenceNode != null) {
         compilationUnit._storeLinkedType(
             unlinkedVariable.inferredTypeSlot, inferredType, null);
@@ -3918,6 +4350,9 @@
           new ExprTypeComputer(variableElement).compute();
     }
   }
+
+  @override
+  String toString() => 'TypeInferenceNode($variableElement)';
 }
 
 /**
@@ -3942,6 +4377,8 @@
   TypeParameterTypeImpl _type;
   ElementLocation _location;
 
+  DartType _bound;
+
   TypeParameterElementForLink(
       this.enclosingElement, this._unlinkedTypeParam, this.nestingLevel);
 
@@ -3950,8 +4387,8 @@
     if (_unlinkedTypeParam.bound == null) {
       return null;
     }
-    // TODO(scheglov) implement
-    throw new UnimplementedError();
+    return _bound ??= enclosingElement.compilationUnit
+        ._resolveTypeRef(_unlinkedTypeParam.bound, enclosingElement);
   }
 
   @override
@@ -3984,6 +4421,11 @@
   int _nestingLevel;
 
   /**
+   * Get the compilation unit in which this element is declared.
+   */
+  CompilationUnitElementForLink get compilationUnit;
+
+  /**
    * Get the type parameter context enclosing this one, if any.
    */
   TypeParameterizedElementForLink get enclosingTypeParameterContext;
@@ -4045,6 +4487,20 @@
       throw new RangeError('Invalid type parameter index');
     }
   }
+
+  /**
+   * Find out if the given [typeParameter] is in scope in this context.
+   */
+  bool isTypeParameterInScope(TypeParameterElementForLink typeParameter) {
+    if (typeParameter.enclosingElement == this) {
+      return true;
+    } else if (enclosingTypeParameterContext != null) {
+      return enclosingTypeParameterContext
+          .isTypeParameterInScope(typeParameter);
+    } else {
+      return false;
+    }
+  }
 }
 
 class TypeProviderForLink implements TypeProvider {
@@ -4227,11 +4683,8 @@
  * Element representing a top level variable resynthesized from a
  * summary during linking.
  */
-class VariableElementForLink
-    implements
-        VariableElementImpl,
-        PropertyInducingElement,
-        ReferenceableElementForLink {
+abstract class VariableElementForLink
+    implements VariableElementImpl, PropertyInducingElement {
   /**
    * The unlinked representation of the variable in the summary.
    */
@@ -4254,6 +4707,8 @@
   FunctionElementForLink_Initializer _initializer;
   DartType _inferredType;
   DartType _declaredType;
+  PropertyAccessorElementForLink_Variable _getter;
+  PropertyAccessorElementForLink_Variable _setter;
 
   /**
    * The compilation unit in which this variable appears.
@@ -4269,18 +4724,6 @@
     }
   }
 
-  @override
-  ConstructorElementForLink get asConstructor => null;
-
-  @override
-  ConstVariableNode get asConstVariable => _constNode;
-
-  @override
-  DartType get asStaticType => type;
-
-  @override
-  TypeInferenceNode get asTypeInferenceNode => _typeInferenceNode;
-
   /**
    * If the variable has an explicitly declared return type, return it.
    * Otherwise return `null`.
@@ -4295,6 +4738,10 @@
   }
 
   @override
+  PropertyAccessorElementForLink_Variable get getter =>
+      _getter ??= new PropertyAccessorElementForLink_Variable(this, false);
+
+  @override
   bool get hasImplicitType => unlinkedVariable.type == null;
 
   /**
@@ -4356,6 +4803,16 @@
   }
 
   @override
+  PropertyAccessorElementForLink_Variable get setter {
+    if (!isConst && !isFinal) {
+      return _setter ??=
+          new PropertyAccessorElementForLink_Variable(this, true);
+    } else {
+      return null;
+    }
+  }
+
+  @override
   DartType get type => declaredType ?? inferredType;
 
   @override
@@ -4370,34 +4827,8 @@
   TypeParameterizedElementForLink get _typeParameterContext;
 
   @override
-  DartType buildType(DartType getTypeArgument(int i),
-          List<int> implicitFunctionTypeIndices) =>
-      DynamicTypeImpl.instance;
-
-  ReferenceableElementForLink getContainedName(String name) {
-    Element element = _getContainedElement(name);
-    return new NonstaticMemberElementForLink(element, _constNode);
-  }
-
-  @override
   noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
 
-  /**
-   * Return the contained element with the given [name], or `null` if the lookup
-   * fails.  Currently only static types are supported in the linker, so lookup
-   * is performed only in the strong mode.
-   */
-  Element _getContainedElement(String name) {
-    Linker linker = compilationUnit.library._linker;
-    if (linker.strongMode) {
-      DartType type = asStaticType;
-      if (type is InterfaceType) {
-        Element result = type.lookUpGetter(name, compilationUnit.library);
-        result ??= type.lookUpMethod(name, compilationUnit.library);
-        return result;
-      }
-    }
-    // TODO(scheglov): implement for propagated types
-    return null;
-  }
+  @override
+  String toString() => '$enclosingElement.$name';
 }
diff --git a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
index e765fae..eb6020f 100644
--- a/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
+++ b/pkg/analyzer/lib/src/summary/package_bundle_reader.dart
@@ -3,6 +3,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/resolver.dart';
@@ -86,6 +87,36 @@
         }
         return false;
       }
+    } else if (target is LibrarySpecificUnit) {
+      String uriString = target.library.uri.toString();
+      if (!_resynthesizer.hasLibrarySummary(uriString)) {
+        return false;
+      }
+      if (result == CREATED_RESOLVED_UNIT1 ||
+          result == CREATED_RESOLVED_UNIT2 ||
+          result == CREATED_RESOLVED_UNIT3 ||
+          result == CREATED_RESOLVED_UNIT4 ||
+          result == CREATED_RESOLVED_UNIT5 ||
+          result == CREATED_RESOLVED_UNIT6 ||
+          result == CREATED_RESOLVED_UNIT7 ||
+          result == CREATED_RESOLVED_UNIT8 ||
+          result == CREATED_RESOLVED_UNIT9 ||
+          result == CREATED_RESOLVED_UNIT10 ||
+          result == CREATED_RESOLVED_UNIT11 ||
+          result == CREATED_RESOLVED_UNIT12) {
+        entry.setValue(result, true, TargetedResult.EMPTY_LIST);
+        return true;
+      }
+      if (result == COMPILATION_UNIT_ELEMENT) {
+        String libraryUri = target.library.uri.toString();
+        String unitUri = target.unit.uri.toString();
+        CompilationUnitElement unit = _resynthesizer.getElement(
+            new ElementLocationImpl.con3(<String>[libraryUri, unitUri]));
+        if (unit != null) {
+          entry.setValue(result, unit, TargetedResult.EMPTY_LIST);
+          return true;
+        }
+      }
     } else if (target is VariableElement) {
       if (!_resynthesizer
           .hasLibrarySummary(target.library.source.uri.toString())) {
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index 684113e..9cd9007 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -68,9 +68,7 @@
         node.typeParameters?.typeParameters?.length ?? 0);
     if (cls != null) {
       for (ClassMember member in node.members) {
-        if (member is FieldDeclaration &&
-            member.isStatic &&
-            member.fields.isConst) {
+        if (member is FieldDeclaration && member.isStatic) {
           for (VariableDeclaration field in member.fields.variables) {
             String name = field.name.name;
             if (isPublic(name)) {
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index 749812e..acc6ff3 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -283,9 +283,10 @@
 
   _ConstExprBuilder(this.resynthesizer, this.uc);
 
-  Expression get expr => stack.single;
-
   Expression build() {
+    if (!uc.isValidConst) {
+      return AstFactory.identifier3(r'$$invalidConstExpr$$');
+    }
     for (UnlinkedConstOperation operation in uc.operations) {
       switch (operation) {
         case UnlinkedConstOperation.pushNull:
@@ -459,7 +460,9 @@
         case UnlinkedConstOperation.typeCast:
         case UnlinkedConstOperation.typeCheck:
         case UnlinkedConstOperation.throwException:
-          throw new UnimplementedError('$operation');
+        case UnlinkedConstOperation.pushLocalFunctionReference:
+          throw new UnimplementedError(
+              'Unexpected $operation in a constant expression.');
       }
     }
     return stack.single;
@@ -511,10 +514,13 @@
   TypeName _buildTypeAst(DartType type) {
     List<TypeName> argumentNodes;
     if (type is ParameterizedType) {
-      List<DartType> typeArguments = type.typeArguments;
-      argumentNodes = typeArguments.every((a) => a.isDynamic)
-          ? null
-          : typeArguments.map(_buildTypeAst).toList();
+      if (!resynthesizer.libraryResynthesizer.typesWithImplicitTypeArguments
+          .contains(type)) {
+        List<DartType> typeArguments = type.typeArguments;
+        argumentNodes = typeArguments.every((a) => a.isDynamic)
+            ? null
+            : typeArguments.map(_buildTypeAst).toList();
+      }
     }
     TypeName node = AstFactory.typeName4(type.name, argumentNodes);
     node.type = type;
@@ -940,6 +946,13 @@
   final Map<String, Map<String, Element>> resynthesizedElements =
       <String, Map<String, Element>>{};
 
+  /**
+   * Types with implicit type arguments, which are the same as type parameter
+   * bounds (in strong mode), or `dynamic` (in spec mode).
+   */
+  final Set<DartType> typesWithImplicitTypeArguments =
+      new Set<DartType>.identity();
+
   _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
       this.unlinkedUnits, this.librarySource) {
     isCoreLibrary = librarySource.uri.toString() == 'dart:core';
@@ -1248,8 +1261,8 @@
     String partUri;
     if (unit != 0) {
       String uri = dependency.parts[unit - 1];
-      Source partSource = summaryResynthesizer.sourceFactory
-          .resolveUri(referencedLibrarySource, uri);
+      Source partSource =
+          summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
       partUri = partSource.uri.toString();
     } else {
       partUri = referencedLibraryUri;
@@ -1277,6 +1290,11 @@
  */
 class _ReferenceInfo {
   /**
+   * The [_LibraryResynthesizer] which is being used to obtain summaries.
+   */
+  final _LibraryResynthesizer libraryResynthesizer;
+
+  /**
    * The enclosing [_ReferenceInfo], or `null` for top-level elements.
    */
   final _ReferenceInfo enclosing;
@@ -1314,12 +1332,12 @@
    * the type itself.  Otherwise, pass `null` and the type will be computed
    * when appropriate.
    */
-  _ReferenceInfo(this.enclosing, this.name, this.element, DartType specialType,
-      this.numTypeParameters) {
+  _ReferenceInfo(this.libraryResynthesizer, this.enclosing, this.name,
+      this.element, DartType specialType, this.numTypeParameters) {
     if (specialType != null) {
       type = specialType;
     } else {
-      type = _buildType((_) => DynamicTypeImpl.instance, const []);
+      type = _buildType(true, 0, (_) => DynamicTypeImpl.instance, const []);
     }
   }
 
@@ -1336,12 +1354,13 @@
    * If the entity referred to by this [_ReferenceInfo] is not a type, `null`
    * is returned.
    */
-  DartType buildType(
+  DartType buildType(bool instantiateToBoundsAllowed, int numTypeArguments,
       DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
     DartType result =
         (numTypeParameters == 0 && implicitFunctionTypeIndices.isEmpty)
             ? type
-            : _buildType(getTypeArgument, implicitFunctionTypeIndices);
+            : _buildType(instantiateToBoundsAllowed, numTypeArguments,
+                getTypeArgument, implicitFunctionTypeIndices);
     if (result == null) {
       // TODO(paulberry): figure out how to handle this case (which should
       // only occur in the event of erroneous code).
@@ -1351,27 +1370,51 @@
   }
 
   /**
-   * If this reference refers to a type, build a [DartType] which instantiates
-   * it with type arguments returned by [getTypeArgument].  Otherwise return
-   * `null`.
+   * If this reference refers to a type, build a [DartType].  Otherwise return
+   * `null`.  If [numTypeArguments] is the same as the [numTypeParameters],
+   * the type in instantiated with type arguments returned by [getTypeArgument],
+   * otherwise it is instantiated with type parameter bounds (if strong mode),
+   * or with `dynamic` type arguments.
    *
    * If [implicitFunctionTypeIndices] is not null, a [DartType] should be
    * created which refers to a function type implicitly defined by one of the
    * element's parameters.  [implicitFunctionTypeIndices] is interpreted as in
    * [EntityRef.implicitFunctionTypeIndices].
    */
-  DartType _buildType(
+  DartType _buildType(bool instantiateToBoundsAllowed, int numTypeArguments,
       DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
     ElementHandle element = this.element; // To allow type promotion
     if (element is ClassElementHandle) {
-      return new InterfaceTypeImpl.elementWithNameAndArgs(element, name,
-          _buildTypeArguments(numTypeParameters, getTypeArgument));
-    } else if (element is FunctionTypeAliasElementHandle) {
-      return new FunctionTypeImpl.elementWithNameAndArgs(
-          element,
-          name,
-          _buildTypeArguments(numTypeParameters, getTypeArgument),
-          numTypeParameters != 0);
+      List<DartType> typeArguments = null;
+      // If type arguments are specified, use them.
+      // Otherwise, delay until they are requested.
+      if (numTypeParameters == 0) {
+        typeArguments = const <DartType>[];
+      } else if (numTypeArguments == numTypeParameters) {
+        typeArguments = new List<DartType>(numTypeParameters);
+        for (int i = 0; i < numTypeParameters; i++) {
+          typeArguments[i] = getTypeArgument(i);
+        }
+      }
+      InterfaceTypeImpl type =
+          new InterfaceTypeImpl.elementWithNameAndArgs(element, name, () {
+        if (typeArguments == null) {
+          typeArguments = element.typeParameters.map((typeParameter) {
+            DartType bound = typeParameter.bound;
+            return libraryResynthesizer.summaryResynthesizer.strongMode &&
+                instantiateToBoundsAllowed &&
+                bound != null ? bound : DynamicTypeImpl.instance;
+          }).toList();
+        }
+        return typeArguments;
+      });
+      // Mark the type as having implicit type arguments, so that we don't
+      // attempt to request them during constant expression resynthesizing.
+      if (typeArguments == null) {
+        libraryResynthesizer.typesWithImplicitTypeArguments.add(type);
+      }
+      // Done.
+      return type;
     } else if (element is FunctionTypedElement) {
       int numTypeArguments;
       FunctionTypedElementComputer computer;
@@ -1384,6 +1427,12 @@
           }
           return element;
         };
+      } else if (element is FunctionTypeAliasElementHandle) {
+        return new FunctionTypeImpl.elementWithNameAndArgs(
+            element,
+            name,
+            _buildTypeArguments(numTypeParameters, getTypeArgument),
+            numTypeParameters != 0);
       } else {
         // For a type that refers to a generic executable, the type arguments are
         // not supposed to include the arguments to the executable itself.
@@ -1675,29 +1724,6 @@
   }
 
   /**
-   * Resynthesize the [ConstructorInitializer] in context of
-   * [currentConstructor], which is used to resolve constructor parameter names.
-   */
-  ConstructorInitializer buildConstantInitializer(
-      UnlinkedConstructorInitializer serialized) {
-    UnlinkedConstructorInitializerKind kind = serialized.kind;
-    String name = serialized.name;
-    List<Expression> arguments =
-        serialized.arguments.map(_buildConstExpression).toList();
-    switch (kind) {
-      case UnlinkedConstructorInitializerKind.field:
-        return AstFactory.constructorFieldInitializer(
-            false, name, _buildConstExpression(serialized.expression));
-      case UnlinkedConstructorInitializerKind.superInvocation:
-        return AstFactory.superConstructorInvocation2(
-            name.isNotEmpty ? name : null, arguments);
-      case UnlinkedConstructorInitializerKind.thisInvocation:
-        return AstFactory.redirectingConstructorInvocation2(
-            name.isNotEmpty ? name : null, arguments);
-    }
-  }
-
-  /**
    * Resynthesize a [ConstructorElement] and place it in the given [holder].
    * [classType] is the type of the class for which this element is a
    * constructor.
@@ -1723,7 +1749,7 @@
     currentConstructor.const2 = serializedExecutable.isConst;
     currentConstructor.constantInitializers = serializedExecutable
         .constantInitializers
-        .map(buildConstantInitializer)
+        .map(buildConstructorInitializer)
         .toList();
     if (serializedExecutable.isRedirectedConstructor) {
       if (serializedExecutable.isFactory) {
@@ -1749,6 +1775,41 @@
   }
 
   /**
+   * Resynthesize the [ConstructorInitializer] in context of
+   * [currentConstructor], which is used to resolve constructor parameter names.
+   */
+  ConstructorInitializer buildConstructorInitializer(
+      UnlinkedConstructorInitializer serialized) {
+    UnlinkedConstructorInitializerKind kind = serialized.kind;
+    String name = serialized.name;
+    List<Expression> arguments = <Expression>[];
+    {
+      int numArguments = serialized.arguments.length;
+      int numNames = serialized.argumentNames.length;
+      for (int i = 0; i < numArguments; i++) {
+        Expression expression = _buildConstExpression(serialized.arguments[i]);
+        int nameIndex = numNames + i - numArguments;
+        if (nameIndex >= 0) {
+          expression = AstFactory.namedExpression2(
+              serialized.argumentNames[nameIndex], expression);
+        }
+        arguments.add(expression);
+      }
+    }
+    switch (kind) {
+      case UnlinkedConstructorInitializerKind.field:
+        return AstFactory.constructorFieldInitializer(
+            false, name, _buildConstExpression(serialized.expression));
+      case UnlinkedConstructorInitializerKind.superInvocation:
+        return AstFactory.superConstructorInvocation2(
+            name.isNotEmpty ? name : null, arguments);
+      case UnlinkedConstructorInitializerKind.thisInvocation:
+        return AstFactory.redirectingConstructorInvocation2(
+            name.isNotEmpty ? name : null, arguments);
+    }
+  }
+
+  /**
    * Build the documentation for the given [element].  Does nothing if
    * [serializedDocumentationComment] is `null`.
    */
@@ -2139,13 +2200,20 @@
       FunctionElementImpl parameterTypeElement =
           new FunctionElementImpl('', -1);
       parameterTypeElement.synthetic = true;
-      parameterElement.parameters =
-          serializedParameter.parameters.map(buildParameter).toList();
-      parameterTypeElement.enclosingElement = parameterElement;
-      parameterTypeElement.shareParameters(parameterElement.parameters);
+      List<ParameterElement> subParameters = serializedParameter.parameters
+          .map((UnlinkedParam p) => buildParameter(p, synthetic: synthetic))
+          .toList();
+      if (synthetic) {
+        parameterTypeElement.parameters = subParameters;
+      } else {
+        parameterElement.parameters = subParameters;
+        parameterTypeElement.shareParameters(subParameters);
+        parameterTypeElement.enclosingElement = parameterElement;
+      }
       parameterTypeElement.returnType = buildType(serializedParameter.type);
       parameterElement.type = new FunctionTypeImpl.elementWithNameAndArgs(
           parameterTypeElement, null, getCurrentTypeArguments(), false);
+      parameterTypeElement.type = parameterElement.type;
     } else {
       if (serializedParameter.isInitializingFormal &&
           serializedParameter.type == null) {
@@ -2195,7 +2263,8 @@
    * deserialized, so handles are used to avoid having to deserialize other
    * libraries in the process.
    */
-  DartType buildType(EntityRef type, {bool defaultVoid: false}) {
+  DartType buildType(EntityRef type,
+      {bool defaultVoid: false, bool instantiateToBoundsAllowed: true}) {
     if (type == null) {
       if (defaultVoid) {
         return VoidTypeImpl.instance;
@@ -2226,7 +2295,10 @@
       }
       _ReferenceInfo referenceInfo = referenceInfos[type.reference];
       return referenceInfo.buildType(
-          getTypeArgument, type.implicitFunctionTypeIndices);
+          instantiateToBoundsAllowed,
+          type.typeArguments.length,
+          getTypeArgument,
+          type.implicitFunctionTypeIndices);
     }
   }
 
@@ -2371,7 +2443,8 @@
   void finishTypeParameter(UnlinkedTypeParam serializedTypeParameter,
       TypeParameterElementImpl typeParameterElement) {
     if (serializedTypeParameter.bound != null) {
-      typeParameterElement.bound = buildType(serializedTypeParameter.bound);
+      typeParameterElement.bound = buildType(serializedTypeParameter.bound,
+          instantiateToBoundsAllowed: false);
     }
   }
 
@@ -2523,7 +2596,7 @@
             break;
         }
       }
-      referenceInfos[i] = new _ReferenceInfo(
+      referenceInfos[i] = new _ReferenceInfo(libraryResynthesizer,
           enclosingInfo, name, element, type, numTypeParameters);
     }
   }
@@ -2610,7 +2683,7 @@
     bool isClass = info.element is ClassElement;
     _ReferenceInfo classInfo = isClass ? info : info.enclosing;
     List<DartType> typeArguments = typeArgumentRefs.map(buildType).toList();
-    return classInfo.buildType((i) {
+    return classInfo.buildType(true, typeArguments.length, (i) {
       if (i < typeArguments.length) {
         return typeArguments[i];
       } else {
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index 35c6d01..8349428 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -29,12 +29,21 @@
   final _SummarizeAstVisitor visitor;
 
   /**
+   * If the expression being serialized can contain closures, map whose
+   * keys are the offsets of local function nodes representing those closures,
+   * and whose values are indices of those local functions relative to their
+   * siblings.
+   */
+  final Map<int, int> localClosureIndexMap;
+
+  /**
    * If a constructor initializer expression is being serialized, the names of
    * the constructor parameters.  Otherwise `null`.
    */
   final Set<String> constructorParameterNames;
 
-  _ConstExprSerializer(this.visitor, this.constructorParameterNames);
+  _ConstExprSerializer(
+      this.visitor, this.localClosureIndexMap, this.constructorParameterNames);
 
   @override
   bool isConstructorParameterName(String name) {
@@ -74,6 +83,18 @@
     }
   }
 
+  @override
+  List<int> serializeFunctionExpression(FunctionExpression functionExpression) {
+    int localIndex;
+    if (localClosureIndexMap == null) {
+      return null;
+    } else {
+      localIndex = localClosureIndexMap[functionExpression.offset];
+      assert(localIndex != null);
+      return <int>[0, localIndex];
+    }
+  }
+
   EntityRefBuilder serializeIdentifier(Identifier identifier) {
     EntityRefBuilder b = new EntityRefBuilder();
     if (identifier is SimpleIdentifier) {
@@ -317,6 +338,14 @@
   Block enclosingBlock = null;
 
   /**
+   * If an expression is being serialized which can contain closures, map whose
+   * keys are the offsets of local function nodes representing those closures,
+   * and whose values are indices of those local functions relative to their
+   * siblings.
+   */
+  Map<int, int> _localClosureIndexMap;
+
+  /**
    * Create a slot id for storing a propagated or inferred type or const cycle
    * info.
    */
@@ -359,7 +388,9 @@
       return const <UnlinkedConstBuilder>[];
     }
     return annotations.map((Annotation a) {
-      _ConstExprSerializer serializer = new _ConstExprSerializer(this, null);
+      Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
+      _ConstExprSerializer serializer =
+          new _ConstExprSerializer(this, localClosureIndexMap, null);
       serializer.serializeAnnotation(a);
       return serializer.toBuilder();
     }).toList();
@@ -487,10 +518,11 @@
   /**
    * Serialize the given [expression], creating an [UnlinkedConstBuilder].
    */
-  UnlinkedConstBuilder serializeConstExpr(Expression expression,
+  UnlinkedConstBuilder serializeConstExpr(
+      Map<int, int> localClosureIndexMap, Expression expression,
       [Set<String> constructorParameterNames]) {
-    _ConstExprSerializer serializer =
-        new _ConstExprSerializer(this, constructorParameterNames);
+    _ConstExprSerializer serializer = new _ConstExprSerializer(
+        this, localClosureIndexMap, constructorParameterNames);
     serializer.serialize(expression);
     return serializer.toBuilder();
   }
@@ -793,20 +825,8 @@
             'Unexpected identifier type: ${identifier.runtimeType}');
       }
       if (typeArguments != null) {
-        // Trailing type arguments of type 'dynamic' should be omitted.
-        NodeList<TypeName> args = typeArguments.arguments;
-        int numArgsToSerialize = args.length;
-        while (
-            numArgsToSerialize > 0 && isDynamic(args[numArgsToSerialize - 1])) {
-          --numArgsToSerialize;
-        }
-        if (numArgsToSerialize > 0) {
-          List<EntityRefBuilder> serializedArguments = <EntityRefBuilder>[];
-          for (int i = 0; i < numArgsToSerialize; i++) {
-            serializedArguments.add(serializeTypeName(args[i]));
-          }
-          b.typeArguments = serializedArguments;
-        }
+        b.typeArguments =
+            typeArguments.arguments.map(serializeTypeName).toList();
       }
       return b;
     }
@@ -862,12 +882,15 @@
       b.documentationComment = serializeDocumentation(documentationComment);
       b.annotations = serializeAnnotations(annotations);
       b.codeRange = serializeCodeRange(variables.parent);
+      Map<int, int> localClosureIndexMap = _withLocalClosureIndexMap(() {
+        b.initializer = serializeInitializerFunction(variable.initializer);
+      });
       if (variable.isConst ||
           variable.isFinal && isField && !isDeclaredStatic ||
           variables.type == null) {
         Expression initializer = variable.initializer;
         if (initializer != null) {
-          b.constExpr = serializeConstExpr(initializer);
+          b.constExpr = serializeConstExpr(localClosureIndexMap, initializer);
         }
       }
       if (variable.initializer != null &&
@@ -881,7 +904,6 @@
       }
       b.visibleOffset = scopeNode?.offset;
       b.visibleLength = scopeNode?.length;
-      b.initializer = serializeInitializerFunction(variable.initializer);
       this.variables.add(b);
     }
   }
@@ -965,9 +987,11 @@
       if (node.redirectedConstructor != null) {
         b.isRedirectedConstructor = true;
         TypeName typeName = node.redirectedConstructor.type;
-        b.redirectedConstructor = new _ConstExprSerializer(this, null)
-            .serializeConstructorRef(null, typeName.name,
-                typeName.typeArguments, node.redirectedConstructor.name);
+        Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
+        b.redirectedConstructor =
+            new _ConstExprSerializer(this, localClosureIndexMap, null)
+                .serializeConstructorRef(null, typeName.name,
+                    typeName.typeArguments, node.redirectedConstructor.name);
       }
     } else {
       for (ConstructorInitializer initializer in node.initializers) {
@@ -988,10 +1012,12 @@
     if (node.constKeyword != null) {
       Set<String> constructorParameterNames =
           node.parameters.parameters.map((p) => p.identifier.name).toSet();
+      Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
       b.constantInitializers = node.initializers
           .map((ConstructorInitializer initializer) =>
               serializeConstructorInitializer(initializer, (Expression expr) {
-                return serializeConstExpr(expr, constructorParameterNames);
+                return serializeConstExpr(
+                    localClosureIndexMap, expr, constructorParameterNames);
               }))
           .toList();
     }
@@ -1004,7 +1030,9 @@
       DefaultFormalParameter node) {
     UnlinkedParamBuilder b = node.parameter.accept(this);
     if (node.defaultValue != null) {
-      b.defaultValue = serializeConstExpr(node.defaultValue);
+      Map<int, int> localClosureIndexMap = null; // TODO(paulberry): fix.
+      b.defaultValue =
+          serializeConstExpr(localClosureIndexMap, node.defaultValue);
       b.defaultValueCode = node.defaultValue.toSource();
     }
     b.initializer = serializeInitializerFunction(node.defaultValue);
@@ -1107,6 +1135,9 @@
   @override
   void visitFunctionExpression(FunctionExpression node) {
     if (node.parent is! FunctionDeclaration) {
+      if (_localClosureIndexMap != null) {
+        _localClosureIndexMap[node.offset] = executables.length;
+      }
       executables.add(serializeExecutable(
           node,
           null,
@@ -1269,6 +1300,21 @@
   }
 
   /**
+   * Execute [callback], gathering any local closures in
+   * [_localClosureIndexMap], and return the resulting map.
+   *
+   * Properly handles cases where one closure is nested within another.
+   */
+  Map<int, int> _withLocalClosureIndexMap(void callback()) {
+    Map<int, int> prevLocalClosureIndexMap = _localClosureIndexMap;
+    _localClosureIndexMap = <int, int>{};
+    callback();
+    Map<int, int> localClosureIndexMap = _localClosureIndexMap;
+    _localClosureIndexMap = prevLocalClosureIndexMap;
+    return localClosureIndexMap;
+  }
+
+  /**
    * Helper method to determine if a given [typeName] refers to `dynamic`.
    */
   static bool isDynamic(TypeName typeName) {
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index 17a0b51..f8f6aab 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -22,19 +22,35 @@
         name: node.fieldName.name,
         expression: serializeConstExpr(node.expression));
   }
+
+  List<UnlinkedConstBuilder> arguments = <UnlinkedConstBuilder>[];
+  List<String> argumentNames = <String>[];
+  void serializeArguments(List<Expression> args) {
+    for (Expression arg in args) {
+      if (arg is NamedExpression) {
+        NamedExpression namedExpression = arg;
+        argumentNames.add(namedExpression.name.label.name);
+        arg = namedExpression.expression;
+      }
+      arguments.add(serializeConstExpr(arg));
+    }
+  }
+
   if (node is RedirectingConstructorInvocation) {
+    serializeArguments(node.argumentList.arguments);
     return new UnlinkedConstructorInitializerBuilder(
         kind: UnlinkedConstructorInitializerKind.thisInvocation,
         name: node?.constructorName?.name,
-        arguments:
-            node.argumentList.arguments.map(serializeConstExpr).toList());
+        arguments: arguments,
+        argumentNames: argumentNames);
   }
   if (node is SuperConstructorInvocation) {
+    serializeArguments(node.argumentList.arguments);
     return new UnlinkedConstructorInitializerBuilder(
         kind: UnlinkedConstructorInitializerKind.superInvocation,
         name: node?.constructorName?.name,
-        arguments:
-            node.argumentList.arguments.map(serializeConstExpr).toList());
+        arguments: arguments,
+        argumentNames: argumentNames);
   }
   throw new StateError('Unexpected initializer type ${node.runtimeType}');
 }
@@ -45,11 +61,16 @@
  */
 abstract class AbstractConstExprSerializer {
   /**
-   * See [UnlinkedConstBuilder.isInvalid].
+   * See [UnlinkedConstBuilder.isValidConst].
    */
   bool isValidConst = true;
 
   /**
+   * See [UnlinkedConstBuilder.nmae].
+   */
+  String name = null;
+
+  /**
    * See [UnlinkedConstBuilder.operations].
    */
   final List<UnlinkedConstOperation> operations = <UnlinkedConstOperation>[];
@@ -91,6 +112,11 @@
    */
   void serialize(Expression expr) {
     try {
+      if (expr is NamedExpression) {
+        NamedExpression namedExpression = expr;
+        name = namedExpression.name.label.name;
+        expr = namedExpression.expression;
+      }
       _serialize(expr);
     } on StateError {
       isValidConst = false;
@@ -117,6 +143,18 @@
   EntityRefBuilder serializeIdentifier(Identifier identifier);
 
   /**
+   * Return a pair of ints showing how the given [functionExpression] is nested
+   * within the constant currently being serialized.  The first int indicates
+   * how many levels of function nesting must be popped in order to reach the
+   * parent of the [functionExpression].  The second int is the index of the
+   * [functionExpression] within its parent element.
+   *
+   * If the constant being summarized is in a context where local function
+   * references are not allowed, return `null`.
+   */
+  List<int> serializeFunctionExpression(FunctionExpression functionExpression);
+
+  /**
    * Return [EntityRefBuilder] that corresponds to the given [expr], which
    * must be a sequence of identifiers.
    */
@@ -277,8 +315,14 @@
       _serializeCascadeExpression(expr);
     } else if (expr is FunctionExpression) {
       isValidConst = false;
-      // TODO(scheglov) implement
-      operations.add(UnlinkedConstOperation.pushNull);
+      List<int> indices = serializeFunctionExpression(expr);
+      if (indices != null) {
+        ints.addAll(serializeFunctionExpression(expr));
+        operations.add(UnlinkedConstOperation.pushLocalFunctionReference);
+      } else {
+        // Invalid expression; just push null.
+        operations.add(UnlinkedConstOperation.pushNull);
+      }
     } else if (expr is FunctionExpressionInvocation) {
       isValidConst = false;
       // TODO(scheglov) implement
@@ -456,8 +500,8 @@
     ArgumentList argumentList = invocation.argumentList;
     if (_isIdentifierSequence(methodName)) {
       EntityRefBuilder ref = serializeIdentifierSequence(methodName);
-      references.add(ref);
       _serializeArguments(argumentList);
+      references.add(ref);
       operations.add(UnlinkedConstOperation.invokeMethodRef);
     } else {
       if (!invocation.isCascaded) {
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index b8828ec..cd2adec 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -355,7 +355,7 @@
             kind: ReferenceKind.classOrEnum,
             name: cls.name,
             numTypeParameters: cls.typeParameters.length,
-            members: serializeClassConstMembers(cls)));
+            members: serializeClassStaticMembers(cls)));
       }
     }
     for (ClassElement enm in compilationUnit.enums) {
@@ -363,7 +363,7 @@
         names.add(new UnlinkedPublicNameBuilder(
             kind: ReferenceKind.classOrEnum,
             name: enm.name,
-            members: serializeClassConstMembers(enm)));
+            members: serializeClassStaticMembers(enm)));
       }
     }
     for (FunctionElement function in compilationUnit.functions) {
@@ -519,7 +519,7 @@
     }
     return element.metadata.map((ElementAnnotation a) {
       _ConstExprSerializer serializer =
-          new _ConstExprSerializer(this, element, null);
+          new _ConstExprSerializer(this, element, null, null);
       serializer
           .serializeAnnotation((a as ElementAnnotationImpl).annotationAst);
       return serializer.toBuilder();
@@ -594,11 +594,11 @@
   }
 
   /**
-   * If [cls] is a class, return the list of its members available for
-   * constants - static constant fields, static methods and constructors.
-   * Otherwise return `null`.
+   * If [cls] is a class, return the list of its static members - static
+   * constant fields, static methods and constructors.  Otherwise return `null`.
    */
-  List<UnlinkedPublicNameBuilder> serializeClassConstMembers(ClassElement cls) {
+  List<UnlinkedPublicNameBuilder> serializeClassStaticMembers(
+      ClassElement cls) {
     if (cls.isMixinApplication) {
       // Mixin application members can't be determined directly from the AST so
       // we can't store them in UnlinkedPublicName.
@@ -607,16 +607,6 @@
     }
     if (cls.kind == ElementKind.CLASS) {
       List<UnlinkedPublicNameBuilder> bs = <UnlinkedPublicNameBuilder>[];
-      for (FieldElement field in cls.fields) {
-        if (field.isStatic && field.isConst && field.isPublic) {
-          // TODO(paulberry): include non-consts
-          // TODO(paulberry): should numTypeParameters include class params?
-          bs.add(new UnlinkedPublicNameBuilder(
-              name: field.name,
-              kind: ReferenceKind.propertyAccessor,
-              numTypeParameters: 0));
-        }
-      }
       for (MethodElement method in cls.methods) {
         if (method.isStatic && method.isPublic) {
           // TODO(paulberry): should numTypeParameters include class params?
@@ -627,11 +617,7 @@
         }
       }
       for (PropertyAccessorElement accessor in cls.accessors) {
-        if (accessor.isStatic &&
-            accessor.isGetter &&
-            accessor.isPublic &&
-            !accessor.isSynthetic) {
-          // TODO(paulberry): combine with field code above.
+        if (accessor.isStatic && accessor.isGetter && accessor.isPublic) {
           // TODO(paulberry): should numTypeParameters include class params?
           bs.add(new UnlinkedPublicNameBuilder(
               name: accessor.name, kind: ReferenceKind.propertyAccessor));
@@ -678,11 +664,11 @@
   /**
    * Serialize the given [expression], creating an [UnlinkedConstBuilder].
    */
-  UnlinkedConstBuilder serializeConstExpr(
-      Element context, Expression expression,
+  UnlinkedConstBuilder serializeConstExpr(Element context,
+      ExecutableElement executableContext, Expression expression,
       [Set<String> constructorParameterNames]) {
-    _ConstExprSerializer serializer =
-        new _ConstExprSerializer(this, context, constructorParameterNames);
+    _ConstExprSerializer serializer = new _ConstExprSerializer(
+        this, context, executableContext, constructorParameterNames);
     serializer.serialize(expression);
     return serializer.toBuilder();
   }
@@ -797,7 +783,7 @@
               .map((ConstructorInitializer initializer) =>
                   serializeConstructorInitializer(
                       initializer,
-                      (expr) => serializeConstExpr(
+                      (expr) => serializeConstExpr(executableElement,
                           executableElement, expr, constructorParameterNames)))
               .toList();
         }
@@ -937,7 +923,10 @@
       ConstVariableElement constParameter = parameter as ConstVariableElement;
       Expression initializer = constParameter.constantInitializer;
       if (initializer != null) {
-        b.defaultValue = serializeConstExpr(parameter, initializer);
+        b.defaultValue = serializeConstExpr(
+            parameter,
+            parameter.getAncestor((Element e) => e is ExecutableElement),
+            initializer);
         b.defaultValueCode = parameter.defaultValueCode;
       }
     }
@@ -1063,19 +1052,19 @@
         ParameterElement parameterElement = typeElement.enclosingElement;
         while (true) {
           Element parent = parameterElement.enclosingElement;
-          if (parent is ExecutableElement) {
-            Element grandParent = parent.enclosingElement;
+          if (parent is ParameterElement) {
+            // Function-typed parameter inside a function-typed parameter.
             b.implicitFunctionTypeIndices
                 .insert(0, parent.parameters.indexOf(parameterElement));
-            if (grandParent is ParameterElement) {
-              // Function-typed parameter inside a function-typed parameter.
-              parameterElement = grandParent;
-              continue;
-            } else {
-              // Function-typed parameter inside a top level function or method.
-              b.reference = _getElementReferenceId(parent);
-              break;
-            }
+            parameterElement = parent;
+            continue;
+          } else if (parent is FunctionTypedElement) {
+            b.implicitFunctionTypeIndices
+                .insert(0, parent.parameters.indexOf(parameterElement));
+            // Function-typed parameter inside a top level function, method, or
+            // typedef.
+            b.reference = _getElementReferenceId(parent);
+            break;
           } else {
             throw new StateError(
                 'Unexpected element enclosing parameter: ${parent.runtimeType}');
@@ -1086,20 +1075,9 @@
       }
       List<DartType> typeArguments = getTypeArguments(type);
       if (typeArguments != null) {
-        // Trailing type arguments of type 'dynamic' should be omitted.
-        int numArgsToSerialize = typeArguments.length;
-        while (numArgsToSerialize > 0 &&
-            typeArguments[numArgsToSerialize - 1].isDynamic) {
-          --numArgsToSerialize;
-        }
-        if (numArgsToSerialize > 0) {
-          List<EntityRefBuilder> serializedArguments = <EntityRefBuilder>[];
-          for (int i = 0; i < numArgsToSerialize; i++) {
-            serializedArguments
-                .add(serializeTypeRef(typeArguments[i], context));
-          }
-          b.typeArguments = serializedArguments;
-        }
+        b.typeArguments = typeArguments
+            .map((typeArgument) => serializeTypeRef(typeArgument, context))
+            .toList();
       }
     }
     return b;
@@ -1159,7 +1137,8 @@
       ConstVariableElement constVariable = variable as ConstVariableElement;
       Expression initializer = constVariable.constantInitializer;
       if (initializer != null) {
-        b.constExpr = serializeConstExpr(variable, initializer);
+        b.constExpr =
+            serializeConstExpr(variable, variable.initializer, initializer);
       }
     }
     if (variable is PropertyInducingElement) {
@@ -1319,6 +1298,7 @@
 class _ConstExprSerializer extends AbstractConstExprSerializer {
   final _CompilationUnitSerializer serializer;
   final Element context;
+  final ExecutableElement executableContext;
 
   /**
    * If a constructor initializer expression is being serialized, the names of
@@ -1326,8 +1306,8 @@
    */
   final Set<String> constructorParameterNames;
 
-  _ConstExprSerializer(
-      this.serializer, this.context, this.constructorParameterNames);
+  _ConstExprSerializer(this.serializer, this.context, this.executableContext,
+      this.constructorParameterNames);
 
   @override
   bool isConstructorParameterName(String name) {
@@ -1388,6 +1368,21 @@
     }
   }
 
+  @override
+  List<int> serializeFunctionExpression(FunctionExpression functionExpression) {
+    if (executableContext == null) {
+      return null;
+    }
+    ExecutableElement functionElement = functionExpression.element;
+    // TOOD(paulberry): handle the situation where [functionExpression] is not
+    // an immediate child of [executableContext].
+    assert(functionElement.enclosingElement == executableContext);
+    int popCount = 0;
+    int localIndex = executableContext.functions.indexOf(functionElement);
+    assert(localIndex != -1);
+    return <int>[popCount, localIndex];
+  }
+
   EntityRefBuilder serializeIdentifier(Identifier identifier,
       {int prefixReference: 0}) {
     if (identifier is SimpleIdentifier) {
diff --git a/pkg/analyzer/lib/src/summary/summary_sdk.dart b/pkg/analyzer/lib/src/summary/summary_sdk.dart
index 77303c3..2dfa154 100644
--- a/pkg/analyzer/lib/src/summary/summary_sdk.dart
+++ b/pkg/analyzer/lib/src/summary/summary_sdk.dart
@@ -104,7 +104,8 @@
           result == CREATED_RESOLVED_UNIT8 ||
           result == CREATED_RESOLVED_UNIT9 ||
           result == CREATED_RESOLVED_UNIT10 ||
-          result == CREATED_RESOLVED_UNIT11) {
+          result == CREATED_RESOLVED_UNIT11 ||
+          result == CREATED_RESOLVED_UNIT12) {
         entry.setValue(result, true, TargetedResult.EMPTY_LIST);
         return true;
       }
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index ca0f09d..b1b6d95 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -1234,7 +1234,10 @@
     // Build the enum members if they have not already been created.
     //
     EnumDeclaration findFirstEnum() {
-      for (CompilationUnitMember member in unit.declarations) {
+      NodeList<CompilationUnitMember> members = unit.declarations;
+      int length = members.length;
+      for (int i = 0; i < length; i++) {
+        CompilationUnitMember member = members[i];
         if (member is EnumDeclaration) {
           return member;
         }
@@ -1407,7 +1410,9 @@
         definingCompilationUnit.element;
     Map<Source, CompilationUnit> partUnitMap =
         new HashMap<Source, CompilationUnit>();
-    for (CompilationUnit partUnit in partUnits) {
+    int partLength = partUnits.length;
+    for (int i = 0; i < partLength; i++) {
+      CompilationUnit partUnit = partUnits[i];
       Source partSource = partUnit.element.source;
       partUnitMap[partSource] = partUnit;
     }
@@ -1422,7 +1427,10 @@
     List<Directive> directivesToResolve = <Directive>[];
     List<CompilationUnitElementImpl> sourcedCompilationUnits =
         <CompilationUnitElementImpl>[];
-    for (Directive directive in definingCompilationUnit.directives) {
+    NodeList<Directive> directives = definingCompilationUnit.directives;
+    int directiveLength = directives.length;
+    for (int i = 0; i < directiveLength; i++) {
+      Directive directive = directives[i];
       if (directive is LibraryDirective) {
         libraryNameNode = directive.name;
         directivesToResolve.add(directive);
@@ -1533,7 +1541,9 @@
     // TODO(brianwilkerson) This updates the state of the AST structures but
     // does not associate a new result with it.
     //
-    for (Directive directive in directivesToResolve) {
+    int length = directivesToResolve.length;
+    for (int i = 0; i < length; i++) {
+      Directive directive = directivesToResolve[i];
       directive.element = libraryElement;
     }
     //
@@ -1549,7 +1559,10 @@
    * [element] does not define an entry point.
    */
   FunctionElement _findEntryPoint(CompilationUnitElementImpl element) {
-    for (FunctionElement function in element.functions) {
+    List<FunctionElement> functions = element.functions;
+    int length = functions.length;
+    for (int i = 0; i < length; i++) {
+      FunctionElement function = functions[i];
       if (function.isEntryPoint) {
         return function;
       }
@@ -1563,7 +1576,10 @@
    */
   String _getPartLibraryName(Source partSource, CompilationUnit partUnit,
       List<Directive> directivesToResolve) {
-    for (Directive directive in partUnit.directives) {
+    NodeList<Directive> directives = partUnit.directives;
+    int length = directives.length;
+    for (int i = 0; i < length; i++) {
+      Directive directive = directives[i];
       if (directive is PartOfDirective) {
         directivesToResolve.add(directive);
         LibraryIdentifier libraryName = directive.libraryName;
@@ -1580,7 +1596,10 @@
    * import directive with a `dart-ext:` URI.
    */
   bool _hasExtUri(CompilationUnit unit) {
-    for (Directive directive in unit.directives) {
+    NodeList<Directive> directives = unit.directives;
+    int length = directives.length;
+    for (int i = 0; i < length; i++) {
+      Directive directive = directives[i];
       if (directive is ImportDirective) {
         if (DartUriResolver.isDartExtUri(directive.uriContent)) {
           return true;
@@ -1921,7 +1940,9 @@
     } else {
       List<ConstantEvaluationTarget> constantsInCycle =
           <ConstantEvaluationTarget>[];
-      for (WorkItem workItem in dependencyCycle) {
+      int length = dependencyCycle.length;
+      for (int i = 0; i < length; i++) {
+        WorkItem workItem = dependencyCycle[i];
         if (workItem.descriptor == DESCRIPTOR) {
           constantsInCycle.add(workItem.target);
         }
@@ -2104,9 +2125,11 @@
           deps.addAll(l.units);
         }
       }
-      for (LibraryElement l in component) {
-        l.importedLibraries.forEach(addLibrary);
-        l.exportedLibraries.forEach(addLibrary);
+      int length = component.length;
+      for (int i = 0; i < length; i++) {
+        LibraryElement library = component[i];
+        library.importedLibraries.forEach(addLibrary);
+        library.exportedLibraries.forEach(addLibrary);
       }
       //
       // Record outputs.
@@ -2385,7 +2408,9 @@
     if (targetSource != null) {
       List<Source> librarySources =
           context.getLibrariesContaining(targetSource);
-      for (Source librarySource in librarySources) {
+      int length = librarySources.length;
+      for (int i = 0; i < length; i++) {
+        Source librarySource = librarySources[i];
         AnalysisCache cache = context.analysisCache;
         ReferencedNames referencedNames =
             cache.getValue(librarySource, REFERENCED_NAMES);
@@ -2443,11 +2468,17 @@
     // Prepare inputs.
     //
     EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin;
-    for (ResultDescriptor result in enginePlugin.dartErrorsForSource) {
+    List<ResultDescriptor> errorsForSource = enginePlugin.dartErrorsForSource;
+    int sourceLength = errorsForSource.length;
+    for (int i = 0; i < sourceLength; i++) {
+      ResultDescriptor result = errorsForSource[i];
       String inputName = result.name + '_input';
       errorLists.add(getRequiredInput(inputName));
     }
-    for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) {
+    List<ResultDescriptor> errorsForUnit = enginePlugin.dartErrorsForUnit;
+    int unitLength = errorsForUnit.length;
+    for (int i = 0; i < unitLength; i++) {
+      ResultDescriptor result = errorsForUnit[i];
       String inputName = result.name + '_input';
       Map<Source, List<AnalysisError>> errorMap = getRequiredInput(inputName);
       for (List<AnalysisError> errors in errorMap.values) {
@@ -2544,12 +2575,18 @@
     inputs[PARSED_UNIT_INPUT] = PARSED_UNIT.of(source);
     EnginePlugin enginePlugin = AnalysisEngine.instance.enginePlugin;
     // for Source
-    for (ResultDescriptor result in enginePlugin.dartErrorsForSource) {
+    List<ResultDescriptor> errorsForSource = enginePlugin.dartErrorsForSource;
+    int sourceLength = errorsForSource.length;
+    for (int i = 0; i < sourceLength; i++) {
+      ResultDescriptor result = errorsForSource[i];
       String inputName = result.name + '_input';
       inputs[inputName] = result.of(source);
     }
     // for LibrarySpecificUnit
-    for (ResultDescriptor result in enginePlugin.dartErrorsForUnit) {
+    List<ResultDescriptor> errorsForUnit = enginePlugin.dartErrorsForUnit;
+    int unitLength = errorsForUnit.length;
+    for (int i = 0; i < unitLength; i++) {
+      ResultDescriptor result = errorsForUnit[i];
       String inputName = result.name + '_input';
       inputs[inputName] =
           CONTAINING_LIBRARIES.of(source).toMap((Source library) {
@@ -2936,7 +2973,9 @@
 
     bool timeVisits = analysisOptions.enableTiming;
     List<Linter> linters = getLints(context);
-    for (Linter linter in linters) {
+    int length = linters.length;
+    for (int i = 0; i < length; i++) {
+      Linter linter = linters[i];
       AstVisitor visitor = linter.getVisitor();
       if (visitor != null) {
         linter.reporter = errorReporter;
@@ -3586,7 +3625,10 @@
     HashSet<Source> explicitlyImportedSourceSet = new HashSet<Source>();
     HashSet<Source> exportedSourceSet = new HashSet<Source>();
     HashSet<Source> includedSourceSet = new HashSet<Source>();
-    for (Directive directive in unit.directives) {
+    NodeList<Directive> directives = unit.directives;
+    int length = directives.length;
+    for (int i = 0; i < length; i++) {
+      Directive directive = directives[i];
       if (directive is PartOfDirective) {
         hasPartOfDirective = true;
       } else {
@@ -4666,8 +4708,9 @@
     List<CompilationUnit> units = getRequiredInput(UNITS_INPUT);
     // Compute referenced names.
     ReferencedNames referencedNames = new ReferencedNames();
-    for (CompilationUnit unit in units) {
-      new ReferencedNamesBuilder(referencedNames).build(unit);
+    int length = units.length;
+    for (int i = 0; i < length; i++) {
+      new ReferencedNamesBuilder(referencedNames).build(units[i]);
     }
     //
     // Record outputs.
@@ -5595,7 +5638,10 @@
    * exists and report an error if it does not.
    */
   void validateDirectives(CompilationUnit unit) {
-    for (Directive directive in unit.directives) {
+    NodeList<Directive> directives = unit.directives;
+    int length = directives.length;
+    for (int i = 0; i < length; i++) {
+      Directive directive = directives[i];
       if (directive is UriBasedDirective) {
         validateReferencedSource(directive);
       }
@@ -5717,14 +5763,20 @@
     if (_libraries.add(library)) {
       if (kind == _SourceClosureKind.IMPORT ||
           kind == _SourceClosureKind.IMPORT_EXPORT) {
-        for (ImportElement importElement in library.imports) {
+        List<ImportElement> imports = library.imports;
+        int length = imports.length;
+        for (int i = 0; i < length; i++) {
+          ImportElement importElement = imports[i];
           Source importedSource = importElement.importedLibrary.source;
           _newSources.add(importedSource);
         }
       }
       if (kind == _SourceClosureKind.EXPORT ||
           kind == _SourceClosureKind.IMPORT_EXPORT) {
-        for (ExportElement exportElement in library.exports) {
+        List<ExportElement> exports = library.exports;
+        int length = exports.length;
+        for (int i = 0; i < length; i++) {
+          ExportElement exportElement = exports[i];
           Source exportedSource = exportElement.exportedLibrary.source;
           _newSources.add(exportedSource);
         }
diff --git a/pkg/analyzer/lib/src/task/strong/checker.dart b/pkg/analyzer/lib/src/task/strong/checker.dart
index 3e6f6f5..6b0049b 100644
--- a/pkg/analyzer/lib/src/task/strong/checker.dart
+++ b/pkg/analyzer/lib/src/task/strong/checker.dart
@@ -622,8 +622,8 @@
       var staticInfo;
       var rhsType = _getStaticType(expr.rightHandSide);
       var lhsType = _getStaticType(expr.leftHandSide);
-      var returnType = _specializedBinaryReturnType(
-          op, lhsType, rhsType, functionType.returnType);
+      var returnType = rules.refineBinaryExpressionType(
+          typeProvider, lhsType, op, rhsType, functionType.returnType);
 
       if (!rules.isSubtypeOf(returnType, lhsType)) {
         final numType = typeProvider.numType;
@@ -921,32 +921,6 @@
       CoercionInfo.set(info.node, info);
     }
   }
-
-  DartType _specializedBinaryReturnType(
-      TokenType op, DartType t1, DartType t2, DartType normalReturnType) {
-    // This special cases binary return types as per 16.26 and 16.27 of the
-    // Dart language spec.
-    switch (op) {
-      case TokenType.PLUS:
-      case TokenType.MINUS:
-      case TokenType.STAR:
-      case TokenType.TILDE_SLASH:
-      case TokenType.PERCENT:
-      case TokenType.PLUS_EQ:
-      case TokenType.MINUS_EQ:
-      case TokenType.STAR_EQ:
-      case TokenType.TILDE_SLASH_EQ:
-      case TokenType.PERCENT_EQ:
-        if (t1 == typeProvider.intType && t2 == typeProvider.intType) return t1;
-        if (t1 == typeProvider.doubleType && t2 == typeProvider.doubleType)
-          return t1;
-        // This particular combo is not spelled out in the spec, but all
-        // implementations and analyzer seem to follow this.
-        if (t1 == typeProvider.doubleType && t2 == typeProvider.intType)
-          return t1;
-    }
-    return normalReturnType;
-  }
 }
 
 /// Checks for overriding declarations of fields and methods. This is used to
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 126b5a6..9e15c290 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.27.4-alpha.1
+version: 0.27.4-alpha.2
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
diff --git a/pkg/analyzer/test/generated/inheritance_manager_test.dart b/pkg/analyzer/test/generated/inheritance_manager_test.dart
index e4f8395..06d6c98 100644
--- a/pkg/analyzer/test/generated/inheritance_manager_test.dart
+++ b/pkg/analyzer/test/generated/inheritance_manager_test.dart
@@ -280,6 +280,32 @@
     _assertNoErrors(classB);
   }
 
+  void test_getMapOfMembersInheritedFromInterfaces_field_indirectWith() {
+    // class A { int f; }
+    // class B extends A {}
+    // class C extends Object with B {}
+    ClassElementImpl classA = ElementFactory.classElement2('A');
+    String fieldName = "f";
+    FieldElement fieldF = ElementFactory.fieldElement(
+        fieldName, false, false, false, _typeProvider.intType);
+    classA.fields = <FieldElement>[fieldF];
+    classA.accessors = <PropertyAccessorElement>[fieldF.getter, fieldF.setter];
+
+    ClassElementImpl classB = ElementFactory.classElement('B', classA.type);
+
+    ClassElementImpl classC = ElementFactory.classElement2('C');
+    classC.mixins = <InterfaceType>[classB.type];
+
+    Map<String, ExecutableElement> mapC =
+        _inheritanceManager.getMembersInheritedFromInterfaces(classC);
+    expect(mapC, hasLength(_numOfMembersInObject + 2));
+    expect(mapC[fieldName], same(fieldF.getter));
+    expect(mapC['$fieldName='], same(fieldF.setter));
+    _assertNoErrors(classA);
+    _assertNoErrors(classB);
+    _assertNoErrors(classC);
+  }
+
   void test_getMapOfMembersInheritedFromInterfaces_implicitExtends() {
     // class A {}
     ClassElementImpl classA = ElementFactory.classElement2("A");
@@ -869,6 +895,30 @@
     _assertNoErrors(classA);
   }
 
+  void test_getMembersInheritedFromClasses_field_indirectWith() {
+    // class A { int f; }
+    // class B extends A {}
+    // class C extends Object with B {}
+    ClassElementImpl classA = ElementFactory.classElement2('A');
+    String fieldName = "f";
+    FieldElement fieldF = ElementFactory.fieldElement(
+        fieldName, false, false, false, _typeProvider.intType);
+    classA.fields = <FieldElement>[fieldF];
+    classA.accessors = <PropertyAccessorElement>[fieldF.getter, fieldF.setter];
+
+    ClassElementImpl classB = ElementFactory.classElement('B', classA.type);
+
+    ClassElementImpl classC = ElementFactory.classElement2('C');
+    classC.mixins = <InterfaceType>[classB.type];
+
+    Map<String, ExecutableElement> mapC =
+        _inheritanceManager.getMembersInheritedFromClasses(classC);
+    expect(mapC, hasLength(_numOfMembersInObject));
+    _assertNoErrors(classA);
+    _assertNoErrors(classB);
+    _assertNoErrors(classC);
+  }
+
   void test_lookupInheritance_interface_getter() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     String getterName = "g";
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index e458070..41a5185 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -5112,6 +5112,30 @@
     verify([source]);
   }
 
+  void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_hasBound() {
+    Source source = addSource(r'''
+class A {}
+class B extends A {}
+typedef F<T extends A>();
+F<A> fa;
+F<B> fb;
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
+  void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias_noBound() {
+    Source source = addSource(r'''
+typedef F<T>();
+F<int> f1;
+F<String> f2;
+''');
+    computeLibrarySourceErrors(source);
+    assertNoErrors(source);
+    verify([source]);
+  }
+
   void test_typeArgumentNotMatchingBounds_typeArgumentList_0() {
     Source source = addSource("abstract class A<T extends A>{}");
     computeLibrarySourceErrors(source);
diff --git a/pkg/analyzer/test/generated/static_type_warning_code_test.dart b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
index 9b3f082..381313e 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -1381,6 +1381,17 @@
         [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
   }
 
+  void test_typeArgumentNotMatchingBounds_ofFunctionTypeAlias() {
+    assertErrorsInCode(
+        r'''
+class A {}
+class B {}
+typedef F<T extends A>();
+F<B> fff;
+''',
+        [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]);
+  }
+
   void test_typeArgumentNotMatchingBounds_parameter() {
     assertErrorsInCode(
         r'''
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index f8fc40d..9eb44ab 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -4,6 +4,7 @@
 
 library analyzer.test.generated.static_warning_code_test;
 
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:unittest/unittest.dart';
@@ -2862,6 +2863,23 @@
     verify([source]);
   }
 
+  void
+      test_nonAbstractClassInheritsAbstractMemberTwo_variable_fromMixin_missingBoth() {
+    // 26411
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource(r'''
+class A {
+  int f;
+}
+class B extends A {}
+class C extends Object with B {}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source,
+        [StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_TWO]);
+    verify([source]);
+  }
+
   void test_nonTypeInCatchClause_noElement() {
     Source source = addSource(r'''
 f() {
diff --git a/pkg/analyzer/test/generated/utilities_test.dart b/pkg/analyzer/test/generated/utilities_test.dart
index f6f898a..344612b 100644
--- a/pkg/analyzer/test/generated/utilities_test.dart
+++ b/pkg/analyzer/test/generated/utilities_test.dart
@@ -1588,886 +1588,918 @@
 class DirectedGraphTest_Node {}
 
 class Getter_NodeReplacerTest_test_annotation
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<Annotation, ArgumentList> {
   @override
   ArgumentList get(Annotation node) => node.arguments;
 }
 
 class Getter_NodeReplacerTest_test_annotation_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<Annotation, Identifier> {
   @override
   Identifier get(Annotation node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_annotation_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<Annotation, SimpleIdentifier> {
   @override
   SimpleIdentifier get(Annotation node) => node.constructorName;
 }
 
 class Getter_NodeReplacerTest_test_asExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<AsExpression, TypeName> {
   @override
   TypeName get(AsExpression node) => node.type;
 }
 
 class Getter_NodeReplacerTest_test_asExpression_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<AsExpression, Expression> {
   @override
   Expression get(AsExpression node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_assertStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<AssertStatement, Expression> {
   @override
   Expression get(AssertStatement node) => node.condition;
 }
 
 class Getter_NodeReplacerTest_test_assertStatement_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<AssertStatement, Expression> {
   @override
   Expression get(AssertStatement node) => node.message;
 }
 
 class Getter_NodeReplacerTest_test_assignmentExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<AssignmentExpression, Expression> {
   @override
   Expression get(AssignmentExpression node) => node.rightHandSide;
 }
 
 class Getter_NodeReplacerTest_test_assignmentExpression_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<AssignmentExpression, Expression> {
   @override
   Expression get(AssignmentExpression node) => node.leftHandSide;
 }
 
 class Getter_NodeReplacerTest_test_awaitExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<AwaitExpression, Expression> {
   @override
   Expression get(AwaitExpression node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_binaryExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<BinaryExpression, Expression> {
   @override
   Expression get(BinaryExpression node) => node.leftOperand;
 }
 
 class Getter_NodeReplacerTest_test_binaryExpression_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<BinaryExpression, Expression> {
   @override
   Expression get(BinaryExpression node) => node.rightOperand;
 }
 
 class Getter_NodeReplacerTest_test_blockFunctionBody
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<BlockFunctionBody, Block> {
   @override
   Block get(BlockFunctionBody node) => node.block;
 }
 
 class Getter_NodeReplacerTest_test_breakStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<BreakStatement, SimpleIdentifier> {
   @override
   SimpleIdentifier get(BreakStatement node) => node.label;
 }
 
 class Getter_NodeReplacerTest_test_cascadeExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<CascadeExpression, Expression> {
   @override
   Expression get(CascadeExpression node) => node.target;
 }
 
 class Getter_NodeReplacerTest_test_catchClause
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<CatchClause, SimpleIdentifier> {
   @override
   SimpleIdentifier get(CatchClause node) => node.stackTraceParameter;
 }
 
 class Getter_NodeReplacerTest_test_catchClause_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<CatchClause, SimpleIdentifier> {
   @override
   SimpleIdentifier get(CatchClause node) => node.exceptionParameter;
 }
 
 class Getter_NodeReplacerTest_test_catchClause_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<CatchClause, TypeName> {
   @override
   TypeName get(CatchClause node) => node.exceptionType;
 }
 
 class Getter_NodeReplacerTest_test_classDeclaration
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassDeclaration, ImplementsClause> {
   @override
   ImplementsClause get(ClassDeclaration node) => node.implementsClause;
 }
 
 class Getter_NodeReplacerTest_test_classDeclaration_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassDeclaration, WithClause> {
   @override
   WithClause get(ClassDeclaration node) => node.withClause;
 }
 
 class Getter_NodeReplacerTest_test_classDeclaration_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassDeclaration, NativeClause> {
   @override
   NativeClause get(ClassDeclaration node) => node.nativeClause;
 }
 
 class Getter_NodeReplacerTest_test_classDeclaration_4
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassDeclaration, ExtendsClause> {
   @override
   ExtendsClause get(ClassDeclaration node) => node.extendsClause;
 }
 
 class Getter_NodeReplacerTest_test_classDeclaration_5
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassDeclaration, TypeParameterList> {
   @override
   TypeParameterList get(ClassDeclaration node) => node.typeParameters;
 }
 
 class Getter_NodeReplacerTest_test_classDeclaration_6
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassDeclaration, SimpleIdentifier> {
   @override
   SimpleIdentifier get(ClassDeclaration node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_classTypeAlias
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassTypeAlias, TypeName> {
   @override
   TypeName get(ClassTypeAlias node) => node.superclass;
 }
 
 class Getter_NodeReplacerTest_test_classTypeAlias_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassTypeAlias, ImplementsClause> {
   @override
   ImplementsClause get(ClassTypeAlias node) => node.implementsClause;
 }
 
 class Getter_NodeReplacerTest_test_classTypeAlias_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassTypeAlias, WithClause> {
   @override
   WithClause get(ClassTypeAlias node) => node.withClause;
 }
 
 class Getter_NodeReplacerTest_test_classTypeAlias_4
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassTypeAlias, SimpleIdentifier> {
   @override
   SimpleIdentifier get(ClassTypeAlias node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_classTypeAlias_5
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ClassTypeAlias, TypeParameterList> {
   @override
   TypeParameterList get(ClassTypeAlias node) => node.typeParameters;
 }
 
 class Getter_NodeReplacerTest_test_commentReference
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<CommentReference, Identifier> {
   @override
   Identifier get(CommentReference node) => node.identifier;
 }
 
 class Getter_NodeReplacerTest_test_compilationUnit
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<CompilationUnit, ScriptTag> {
   @override
   ScriptTag get(CompilationUnit node) => node.scriptTag;
 }
 
 class Getter_NodeReplacerTest_test_conditionalExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ConditionalExpression, Expression> {
   @override
   Expression get(ConditionalExpression node) => node.elseExpression;
 }
 
 class Getter_NodeReplacerTest_test_conditionalExpression_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ConditionalExpression, Expression> {
   @override
   Expression get(ConditionalExpression node) => node.thenExpression;
 }
 
 class Getter_NodeReplacerTest_test_conditionalExpression_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ConditionalExpression, Expression> {
   @override
   Expression get(ConditionalExpression node) => node.condition;
 }
 
 class Getter_NodeReplacerTest_test_constructorDeclaration
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<ConstructorDeclaration, ConstructorName> {
   @override
   ConstructorName get(ConstructorDeclaration node) =>
       node.redirectedConstructor;
 }
 
 class Getter_NodeReplacerTest_test_constructorDeclaration_2
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<ConstructorDeclaration, SimpleIdentifier> {
   @override
   SimpleIdentifier get(ConstructorDeclaration node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_constructorDeclaration_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ConstructorDeclaration, Identifier> {
   @override
   Identifier get(ConstructorDeclaration node) => node.returnType;
 }
 
 class Getter_NodeReplacerTest_test_constructorDeclaration_4
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<ConstructorDeclaration, FormalParameterList> {
   @override
   FormalParameterList get(ConstructorDeclaration node) => node.parameters;
 }
 
 class Getter_NodeReplacerTest_test_constructorDeclaration_5
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ConstructorDeclaration, FunctionBody> {
   @override
   FunctionBody get(ConstructorDeclaration node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_constructorFieldInitializer
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<ConstructorFieldInitializer, SimpleIdentifier> {
   @override
   SimpleIdentifier get(ConstructorFieldInitializer node) => node.fieldName;
 }
 
 class Getter_NodeReplacerTest_test_constructorFieldInitializer_2
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<ConstructorFieldInitializer, Expression> {
   @override
   Expression get(ConstructorFieldInitializer node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_constructorName
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ConstructorName, TypeName> {
   @override
   TypeName get(ConstructorName node) => node.type;
 }
 
 class Getter_NodeReplacerTest_test_constructorName_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ConstructorName, SimpleIdentifier> {
   @override
   SimpleIdentifier get(ConstructorName node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_continueStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ContinueStatement, SimpleIdentifier> {
   @override
   SimpleIdentifier get(ContinueStatement node) => node.label;
 }
 
 class Getter_NodeReplacerTest_test_declaredIdentifier
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<DeclaredIdentifier, TypeName> {
   @override
   TypeName get(DeclaredIdentifier node) => node.type;
 }
 
 class Getter_NodeReplacerTest_test_declaredIdentifier_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<DeclaredIdentifier, SimpleIdentifier> {
   @override
   SimpleIdentifier get(DeclaredIdentifier node) => node.identifier;
 }
 
 class Getter_NodeReplacerTest_test_defaultFormalParameter
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<DefaultFormalParameter, NormalFormalParameter> {
   @override
   NormalFormalParameter get(DefaultFormalParameter node) => node.parameter;
 }
 
 class Getter_NodeReplacerTest_test_defaultFormalParameter_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<DefaultFormalParameter, Expression> {
   @override
   Expression get(DefaultFormalParameter node) => node.defaultValue;
 }
 
 class Getter_NodeReplacerTest_test_doStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<DoStatement, Expression> {
   @override
   Expression get(DoStatement node) => node.condition;
 }
 
 class Getter_NodeReplacerTest_test_doStatement_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<DoStatement, Statement> {
   @override
   Statement get(DoStatement node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_enumConstantDeclaration
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<EnumConstantDeclaration, SimpleIdentifier> {
   @override
   SimpleIdentifier get(EnumConstantDeclaration node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_enumDeclaration
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<EnumDeclaration, SimpleIdentifier> {
   @override
   SimpleIdentifier get(EnumDeclaration node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_expressionFunctionBody
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ExpressionFunctionBody, Expression> {
   @override
   Expression get(ExpressionFunctionBody node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_expressionStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ExpressionStatement, Expression> {
   @override
   Expression get(ExpressionStatement node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_extendsClause
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ExtendsClause, TypeName> {
   @override
   TypeName get(ExtendsClause node) => node.superclass;
 }
 
 class Getter_NodeReplacerTest_test_fieldDeclaration
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<FieldDeclaration, VariableDeclarationList> {
   @override
   VariableDeclarationList get(FieldDeclaration node) => node.fields;
 }
 
 class Getter_NodeReplacerTest_test_fieldFormalParameter
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<FieldFormalParameter, FormalParameterList> {
   @override
   FormalParameterList get(FieldFormalParameter node) => node.parameters;
 }
 
 class Getter_NodeReplacerTest_test_fieldFormalParameter_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FieldFormalParameter, TypeName> {
   @override
   TypeName get(FieldFormalParameter node) => node.type;
 }
 
 class Getter_NodeReplacerTest_test_forEachStatement_withIdentifier
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForEachStatement, Statement> {
   @override
   Statement get(ForEachStatement node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_forEachStatement_withIdentifier_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForEachStatement, SimpleIdentifier> {
   @override
   SimpleIdentifier get(ForEachStatement node) => node.identifier;
 }
 
 class Getter_NodeReplacerTest_test_forEachStatement_withIdentifier_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForEachStatement, Expression> {
   @override
   Expression get(ForEachStatement node) => node.iterable;
 }
 
 class Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForEachStatement, Expression> {
   @override
   Expression get(ForEachStatement node) => node.iterable;
 }
 
 class Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForEachStatement, DeclaredIdentifier> {
   @override
   DeclaredIdentifier get(ForEachStatement node) => node.loopVariable;
 }
 
 class Getter_NodeReplacerTest_test_forEachStatement_withLoopVariable_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForEachStatement, Statement> {
   @override
   Statement get(ForEachStatement node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_forStatement_withInitialization
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForStatement, Statement> {
   @override
   Statement get(ForStatement node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_forStatement_withInitialization_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForStatement, Expression> {
   @override
   Expression get(ForStatement node) => node.condition;
 }
 
 class Getter_NodeReplacerTest_test_forStatement_withInitialization_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForStatement, Expression> {
   @override
   Expression get(ForStatement node) => node.initialization;
 }
 
 class Getter_NodeReplacerTest_test_forStatement_withVariables
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForStatement, Statement> {
   @override
   Statement get(ForStatement node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_forStatement_withVariables_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForStatement, VariableDeclarationList> {
   @override
   VariableDeclarationList get(ForStatement node) => node.variables;
 }
 
 class Getter_NodeReplacerTest_test_forStatement_withVariables_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ForStatement, Expression> {
   @override
   Expression get(ForStatement node) => node.condition;
 }
 
 class Getter_NodeReplacerTest_test_functionDeclaration
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FunctionDeclaration, TypeName> {
   @override
   TypeName get(FunctionDeclaration node) => node.returnType;
 }
 
 class Getter_NodeReplacerTest_test_functionDeclaration_2
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<FunctionDeclaration, FunctionExpression> {
   @override
   FunctionExpression get(FunctionDeclaration node) => node.functionExpression;
 }
 
 class Getter_NodeReplacerTest_test_functionDeclaration_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FunctionDeclaration, SimpleIdentifier> {
   @override
   SimpleIdentifier get(FunctionDeclaration node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_functionDeclarationStatement
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<FunctionDeclarationStatement,
+            FunctionDeclaration> {
   @override
   FunctionDeclaration get(FunctionDeclarationStatement node) =>
       node.functionDeclaration;
 }
 
 class Getter_NodeReplacerTest_test_functionExpression
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<FunctionExpression, FormalParameterList> {
   @override
   FormalParameterList get(FunctionExpression node) => node.parameters;
 }
 
 class Getter_NodeReplacerTest_test_functionExpression_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FunctionExpression, FunctionBody> {
   @override
   FunctionBody get(FunctionExpression node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_functionExpressionInvocation
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<FunctionExpressionInvocation, Expression> {
   @override
   Expression get(FunctionExpressionInvocation node) => node.function;
 }
 
 class Getter_NodeReplacerTest_test_functionExpressionInvocation_2
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<FunctionExpressionInvocation, ArgumentList> {
   @override
   ArgumentList get(FunctionExpressionInvocation node) => node.argumentList;
 }
 
 class Getter_NodeReplacerTest_test_functionTypeAlias
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FunctionTypeAlias, TypeParameterList> {
   @override
   TypeParameterList get(FunctionTypeAlias node) => node.typeParameters;
 }
 
 class Getter_NodeReplacerTest_test_functionTypeAlias_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FunctionTypeAlias, FormalParameterList> {
   @override
   FormalParameterList get(FunctionTypeAlias node) => node.parameters;
 }
 
 class Getter_NodeReplacerTest_test_functionTypeAlias_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FunctionTypeAlias, TypeName> {
   @override
   TypeName get(FunctionTypeAlias node) => node.returnType;
 }
 
 class Getter_NodeReplacerTest_test_functionTypeAlias_4
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FunctionTypeAlias, SimpleIdentifier> {
   @override
   SimpleIdentifier get(FunctionTypeAlias node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_functionTypedFormalParameter
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<FunctionTypedFormalParameter, TypeName> {
   @override
   TypeName get(FunctionTypedFormalParameter node) => node.returnType;
 }
 
 class Getter_NodeReplacerTest_test_functionTypedFormalParameter_2
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<FunctionTypedFormalParameter,
+            FormalParameterList> {
   @override
   FormalParameterList get(FunctionTypedFormalParameter node) => node.parameters;
 }
 
 class Getter_NodeReplacerTest_test_ifStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<IfStatement, Expression> {
   @override
   Expression get(IfStatement node) => node.condition;
 }
 
 class Getter_NodeReplacerTest_test_ifStatement_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<IfStatement, Statement> {
   @override
   Statement get(IfStatement node) => node.elseStatement;
 }
 
 class Getter_NodeReplacerTest_test_ifStatement_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<IfStatement, Statement> {
   @override
   Statement get(IfStatement node) => node.thenStatement;
 }
 
 class Getter_NodeReplacerTest_test_importDirective
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ImportDirective, SimpleIdentifier> {
   @override
   SimpleIdentifier get(ImportDirective node) => node.prefix;
 }
 
 class Getter_NodeReplacerTest_test_indexExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<IndexExpression, Expression> {
   @override
   Expression get(IndexExpression node) => node.target;
 }
 
 class Getter_NodeReplacerTest_test_indexExpression_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<IndexExpression, Expression> {
   @override
   Expression get(IndexExpression node) => node.index;
 }
 
 class Getter_NodeReplacerTest_test_instanceCreationExpression
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<InstanceCreationExpression, ArgumentList> {
   @override
   ArgumentList get(InstanceCreationExpression node) => node.argumentList;
 }
 
 class Getter_NodeReplacerTest_test_instanceCreationExpression_2
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<InstanceCreationExpression, ConstructorName> {
   @override
   ConstructorName get(InstanceCreationExpression node) => node.constructorName;
 }
 
 class Getter_NodeReplacerTest_test_interpolationExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<InterpolationExpression, Expression> {
   @override
   Expression get(InterpolationExpression node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_isExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<IsExpression, Expression> {
   @override
   Expression get(IsExpression node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_isExpression_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<IsExpression, TypeName> {
   @override
   TypeName get(IsExpression node) => node.type;
 }
 
-class Getter_NodeReplacerTest_test_label implements NodeReplacerTest_Getter {
+class Getter_NodeReplacerTest_test_label
+    implements NodeReplacerTest_Getter<Label, SimpleIdentifier> {
   @override
   SimpleIdentifier get(Label node) => node.label;
 }
 
 class Getter_NodeReplacerTest_test_labeledStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<LabeledStatement, Statement> {
   @override
   Statement get(LabeledStatement node) => node.statement;
 }
 
 class Getter_NodeReplacerTest_test_libraryDirective
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<LibraryDirective, LibraryIdentifier> {
   @override
   LibraryIdentifier get(LibraryDirective node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_mapLiteralEntry
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MapLiteralEntry, Expression> {
   @override
   Expression get(MapLiteralEntry node) => node.value;
 }
 
 class Getter_NodeReplacerTest_test_mapLiteralEntry_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MapLiteralEntry, Expression> {
   @override
   Expression get(MapLiteralEntry node) => node.key;
 }
 
 class Getter_NodeReplacerTest_test_methodDeclaration
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MethodDeclaration, TypeName> {
   @override
   TypeName get(MethodDeclaration node) => node.returnType;
 }
 
 class Getter_NodeReplacerTest_test_methodDeclaration_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MethodDeclaration, FunctionBody> {
   @override
   FunctionBody get(MethodDeclaration node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_methodDeclaration_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MethodDeclaration, SimpleIdentifier> {
   @override
   SimpleIdentifier get(MethodDeclaration node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_methodDeclaration_4
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MethodDeclaration, FormalParameterList> {
   @override
   FormalParameterList get(MethodDeclaration node) => node.parameters;
 }
 
 class Getter_NodeReplacerTest_test_methodInvocation
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MethodInvocation, ArgumentList> {
   @override
   ArgumentList get(MethodInvocation node) => node.argumentList;
 }
 
 class Getter_NodeReplacerTest_test_methodInvocation_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MethodInvocation, Expression> {
   @override
   Expression get(MethodInvocation node) => node.target;
 }
 
 class Getter_NodeReplacerTest_test_methodInvocation_3
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<MethodInvocation, SimpleIdentifier> {
   @override
   SimpleIdentifier get(MethodInvocation node) => node.methodName;
 }
 
 class Getter_NodeReplacerTest_test_namedExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<NamedExpression, Label> {
   @override
   Label get(NamedExpression node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_namedExpression_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<NamedExpression, Expression> {
   @override
   Expression get(NamedExpression node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_nativeClause
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<NativeClause, StringLiteral> {
   @override
   StringLiteral get(NativeClause node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_nativeFunctionBody
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<NativeFunctionBody, StringLiteral> {
   @override
   StringLiteral get(NativeFunctionBody node) => node.stringLiteral;
 }
 
 class Getter_NodeReplacerTest_test_parenthesizedExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ParenthesizedExpression, Expression> {
   @override
   Expression get(ParenthesizedExpression node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_partOfDirective
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<PartOfDirective, LibraryIdentifier> {
   @override
   LibraryIdentifier get(PartOfDirective node) => node.libraryName;
 }
 
 class Getter_NodeReplacerTest_test_postfixExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<PostfixExpression, Expression> {
   @override
   Expression get(PostfixExpression node) => node.operand;
 }
 
 class Getter_NodeReplacerTest_test_prefixedIdentifier
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<PrefixedIdentifier, SimpleIdentifier> {
   @override
   SimpleIdentifier get(PrefixedIdentifier node) => node.identifier;
 }
 
 class Getter_NodeReplacerTest_test_prefixedIdentifier_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<PrefixedIdentifier, SimpleIdentifier> {
   @override
   SimpleIdentifier get(PrefixedIdentifier node) => node.prefix;
 }
 
 class Getter_NodeReplacerTest_test_prefixExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<PrefixExpression, Expression> {
   @override
   Expression get(PrefixExpression node) => node.operand;
 }
 
 class Getter_NodeReplacerTest_test_propertyAccess
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<PropertyAccess, Expression> {
   @override
   Expression get(PropertyAccess node) => node.target;
 }
 
 class Getter_NodeReplacerTest_test_propertyAccess_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<PropertyAccess, SimpleIdentifier> {
   @override
   SimpleIdentifier get(PropertyAccess node) => node.propertyName;
 }
 
 class Getter_NodeReplacerTest_test_redirectingConstructorInvocation
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<RedirectingConstructorInvocation,
+            SimpleIdentifier> {
   @override
   SimpleIdentifier get(RedirectingConstructorInvocation node) =>
       node.constructorName;
 }
 
 class Getter_NodeReplacerTest_test_redirectingConstructorInvocation_2
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<RedirectingConstructorInvocation,
+            ArgumentList> {
   @override
   ArgumentList get(RedirectingConstructorInvocation node) => node.argumentList;
 }
 
 class Getter_NodeReplacerTest_test_returnStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ReturnStatement, Expression> {
   @override
   Expression get(ReturnStatement node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_simpleFormalParameter
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<SimpleFormalParameter, TypeName> {
   @override
   TypeName get(SimpleFormalParameter node) => node.type;
 }
 
 class Getter_NodeReplacerTest_test_superConstructorInvocation
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<SuperConstructorInvocation, SimpleIdentifier> {
   @override
   SimpleIdentifier get(SuperConstructorInvocation node) => node.constructorName;
 }
 
 class Getter_NodeReplacerTest_test_superConstructorInvocation_2
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<SuperConstructorInvocation, ArgumentList> {
   @override
   ArgumentList get(SuperConstructorInvocation node) => node.argumentList;
 }
 
 class Getter_NodeReplacerTest_test_switchCase
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<SwitchCase, Expression> {
   @override
   Expression get(SwitchCase node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_switchStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<SwitchStatement, Expression> {
   @override
   Expression get(SwitchStatement node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_throwExpression
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<ThrowExpression, Expression> {
   @override
   Expression get(ThrowExpression node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_test_topLevelVariableDeclaration
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<TopLevelVariableDeclaration,
+            VariableDeclarationList> {
   @override
   VariableDeclarationList get(TopLevelVariableDeclaration node) =>
       node.variables;
 }
 
 class Getter_NodeReplacerTest_test_tryStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<TryStatement, Block> {
   @override
   Block get(TryStatement node) => node.finallyBlock;
 }
 
 class Getter_NodeReplacerTest_test_tryStatement_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<TryStatement, Block> {
   @override
   Block get(TryStatement node) => node.body;
 }
 
-class Getter_NodeReplacerTest_test_typeName implements NodeReplacerTest_Getter {
+class Getter_NodeReplacerTest_test_typeName
+    implements NodeReplacerTest_Getter<TypeName, TypeArgumentList> {
   @override
   TypeArgumentList get(TypeName node) => node.typeArguments;
 }
 
 class Getter_NodeReplacerTest_test_typeName_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<TypeName, Identifier> {
   @override
   Identifier get(TypeName node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_typeParameter
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<TypeParameter, TypeName> {
   @override
   TypeName get(TypeParameter node) => node.bound;
 }
 
 class Getter_NodeReplacerTest_test_typeParameter_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<TypeParameter, SimpleIdentifier> {
   @override
   SimpleIdentifier get(TypeParameter node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_variableDeclaration
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<VariableDeclaration, SimpleIdentifier> {
   @override
   SimpleIdentifier get(VariableDeclaration node) => node.name;
 }
 
 class Getter_NodeReplacerTest_test_variableDeclaration_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<VariableDeclaration, Expression> {
   @override
   Expression get(VariableDeclaration node) => node.initializer;
 }
 
 class Getter_NodeReplacerTest_test_variableDeclarationList
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<VariableDeclarationList, TypeName> {
   @override
   TypeName get(VariableDeclarationList node) => node.type;
 }
 
 class Getter_NodeReplacerTest_test_variableDeclarationStatement
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<VariableDeclarationStatement,
+            VariableDeclarationList> {
   @override
   VariableDeclarationList get(VariableDeclarationStatement node) =>
       node.variables;
 }
 
 class Getter_NodeReplacerTest_test_whileStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<WhileStatement, Expression> {
   @override
   Expression get(WhileStatement node) => node.condition;
 }
 
 class Getter_NodeReplacerTest_test_whileStatement_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<WhileStatement, Statement> {
   @override
   Statement get(WhileStatement node) => node.body;
 }
 
 class Getter_NodeReplacerTest_test_yieldStatement
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<YieldStatement, Expression> {
   @override
   Expression get(YieldStatement node) => node.expression;
 }
 
 class Getter_NodeReplacerTest_testAnnotatedNode
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<AnnotatedNode, Comment> {
   @override
   Comment get(AnnotatedNode node) => node.documentationComment;
 }
 
 class Getter_NodeReplacerTest_testNormalFormalParameter
-    implements NodeReplacerTest_Getter {
+    implements
+        NodeReplacerTest_Getter<NormalFormalParameter, SimpleIdentifier> {
   @override
   SimpleIdentifier get(NormalFormalParameter node) => node.identifier;
 }
 
 class Getter_NodeReplacerTest_testNormalFormalParameter_2
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<NormalFormalParameter, Comment> {
   @override
   Comment get(NormalFormalParameter node) => node.documentationComment;
 }
 
 class Getter_NodeReplacerTest_testTypedLiteral
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<TypedLiteral, TypeArgumentList> {
   @override
   TypeArgumentList get(TypedLiteral node) => node.typeArguments;
 }
 
 class Getter_NodeReplacerTest_testUriBasedDirective
-    implements NodeReplacerTest_Getter {
+    implements NodeReplacerTest_Getter<UriBasedDirective, StringLiteral> {
   @override
   StringLiteral get(UriBasedDirective node) => node.uri;
 }
diff --git a/pkg/analyzer/test/src/context/mock_sdk.dart b/pkg/analyzer/test/src/context/mock_sdk.dart
index e7021f0..6539e67 100644
--- a/pkg/analyzer/test/src/context/mock_sdk.dart
+++ b/pkg/analyzer/test/src/context/mock_sdk.dart
@@ -141,7 +141,36 @@
                             { int radix,
                               int onError(String source) });
 }
-class double extends num {}
+
+abstract class double extends num {
+  static const double NAN = 0.0 / 0.0;
+  static const double INFINITY = 1.0 / 0.0;
+  static const double NEGATIVE_INFINITY = -INFINITY;
+  static const double MIN_POSITIVE = 5e-324;
+  static const double MAX_FINITE = 1.7976931348623157e+308;
+
+  double remainder(num other);
+  double operator +(num other);
+  double operator -(num other);
+  double operator *(num other);
+  double operator %(num other);
+  double operator /(num other);
+  int operator ~/(num other);
+  double operator -();
+  double abs();
+  double get sign;
+  int round();
+  int floor();
+  int ceil();
+  int truncate();
+  double roundToDouble();
+  double floorToDouble();
+  double ceilToDouble();
+  double truncateToDouble();
+  external static double parse(String source,
+                               [double onError(String source)]);
+}
+
 class DateTime extends Object {}
 class Null extends Object {}
 
diff --git a/pkg/analyzer/test/src/dart/constant/utilities_test.dart b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
index a922cf5..f4fd958 100644
--- a/pkg/analyzer/test/src/dart/constant/utilities_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/utilities_test.dart
@@ -61,6 +61,15 @@
     expect(_findAnnotations(), contains(_node));
   }
 
+  void test_visitAnnotation_enumConstant() {
+    // Analyzer ignores annotations on enum constant declarations.
+    Annotation annotation = AstFactory.annotation2(
+        AstFactory.identifier3('A'), null, AstFactory.argumentList());
+    _node = new EnumConstantDeclaration(
+        null, <Annotation>[annotation], AstFactory.identifier3('C'));
+    expect(_findConstants(), isEmpty);
+  }
+
   /**
    * Test an annotation that represents the invocation of a constant
    * constructor.
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index ef33f95..3883876 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -587,14 +587,57 @@
   void test_parameterParentElementForLink_innermostExecutable() {
     createLinker('void f(void g(void h())) {}');
     TopLevelFunctionElementForLink f = testLibrary.getContainedName('f');
-    expect(f.innermostExecutable, same(f));
+    expect(f.typeParameterContext, same(f));
     ParameterElementForLink g = f.parameters[0];
     FunctionType gType = g.type;
     FunctionElementForLink_FunctionTypedParam gTypeElement = gType.element;
-    expect(gTypeElement.innermostExecutable, same(f));
+    expect(gTypeElement.typeParameterContext, same(f));
     ParameterElementForLink h = gTypeElement.parameters[0];
     FunctionType hType = h.type;
     FunctionElementForLink_FunctionTypedParam hTypeElement = hType.element;
-    expect(hTypeElement.innermostExecutable, same(f));
+    expect(hTypeElement.typeParameterContext, same(f));
+  }
+
+  void test_typeParameter_isTypeParameterInScope_direct() {
+    createLinker('class C<T, U> {}');
+    ClassElementForLink_Class c = testLibrary.getContainedName('C');
+    TypeParameterElementForLink t = c.typeParameters[0];
+    TypeParameterElementForLink u = c.typeParameters[1];
+    expect(c.isTypeParameterInScope(t), true);
+    expect(c.isTypeParameterInScope(u), true);
+  }
+
+  void test_typeParameter_isTypeParameterInScope_indirect() {
+    createLinker('class C<T, U> { f<V, W>() {} }');
+    ClassElementForLink_Class c = testLibrary.getContainedName('C');
+    MethodElementForLink f = c.methods[0];
+    TypeParameterElementForLink t = c.typeParameters[0];
+    TypeParameterElementForLink u = c.typeParameters[1];
+    expect(f.isTypeParameterInScope(t), true);
+    expect(f.isTypeParameterInScope(u), true);
+  }
+
+  void test_typeParameter_isTypeParameterInScope_reversed() {
+    createLinker('class C<T, U> { f<V, W>() {} }');
+    ClassElementForLink_Class c = testLibrary.getContainedName('C');
+    MethodElementForLink f = c.methods[0];
+    TypeParameterElementForLink v = f.typeParameters[0];
+    TypeParameterElementForLink w = f.typeParameters[1];
+    expect(c.isTypeParameterInScope(v), false);
+    expect(c.isTypeParameterInScope(w), false);
+  }
+
+  void test_typeParameter_isTypeParameterInScope_unrelated() {
+    createLinker('class C<T, U> {} class D<V, W> {}');
+    ClassElementForLink_Class c = testLibrary.getContainedName('C');
+    ClassElementForLink_Class d = testLibrary.getContainedName('D');
+    TypeParameterElementForLink t = c.typeParameters[0];
+    TypeParameterElementForLink u = c.typeParameters[1];
+    TypeParameterElementForLink v = d.typeParameters[0];
+    TypeParameterElementForLink w = d.typeParameters[1];
+    expect(c.isTypeParameterInScope(v), false);
+    expect(c.isTypeParameterInScope(w), false);
+    expect(d.isTypeParameterInScope(t), false);
+    expect(d.isTypeParameterInScope(u), false);
   }
 }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index 420b70f..47faf81 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -66,7 +66,7 @@
   }
 
   @override
-  void compareLocalVariableElementLists(ExecutableElement resynthesized,
+  void compareLocalElementsOfExecutable(ExecutableElement resynthesized,
       ExecutableElement original, String desc) {
     // We don't resynthesize local elements during link.
     // So, we should not compare them.
@@ -124,12 +124,6 @@
 
   @override
   @failingTest
-  void test_blockBodiedLambdas_doesNotInferBottom_sync_topLevel() {
-    super.test_blockBodiedLambdas_doesNotInferBottom_sync_topLevel();
-  }
-
-  @override
-  @failingTest
   void test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel() {
     super.test_blockBodiedLambdas_doesNotInferBottom_syncStar_topLevel();
   }
@@ -153,15 +147,9 @@
   }
 
   @override
-  @failingTest
-  void test_downwardsInferenceOnFunctionOfTUsingTheT() {
-    super.test_downwardsInferenceOnFunctionOfTUsingTheT();
-  }
-
-  @override
-  @failingTest
-  void test_downwardsInferenceOnGenericFunctionExpressions() {
-    super.test_downwardsInferenceOnGenericFunctionExpressions();
+  void test_canInferAlsoFromStaticAndInstanceFieldsFlagOn() {
+    variablesWithNotConstInitializers.add('a2');
+    super.test_canInferAlsoFromStaticAndInstanceFieldsFlagOn();
   }
 
   @override
@@ -523,42 +511,6 @@
     super.test_inferenceInCyclesIsDeterministic();
   }
 
-  @override
-  @failingTest
-  void test_instantiateToBounds_generic2_hasBound_definedAfter() {
-    super.test_instantiateToBounds_generic2_hasBound_definedAfter();
-  }
-
-  @override
-  @failingTest
-  void test_instantiateToBounds_generic2_hasBound_definedBefore() {
-    super.test_instantiateToBounds_generic2_hasBound_definedBefore();
-  }
-
-  @override
-  @failingTest
-  void test_instantiateToBounds_generic2_noBound() {
-    super.test_instantiateToBounds_generic2_noBound();
-  }
-
-  @override
-  @failingTest
-  void test_instantiateToBounds_generic_hasBound_definedAfter() {
-    super.test_instantiateToBounds_generic_hasBound_definedAfter();
-  }
-
-  @override
-  @failingTest
-  void test_instantiateToBounds_generic_hasBound_definedBefore() {
-    super.test_instantiateToBounds_generic_hasBound_definedBefore();
-  }
-
-  @override
-  @failingTest
-  void test_instantiateToBounds_notGeneric() {
-    super.test_instantiateToBounds_notGeneric();
-  }
-
   void test_invokeMethod_notGeneric_genericClass() {
     var unit = checkFile(r'''
 class C<T> {
@@ -579,12 +531,6 @@
     expect(unit.topLevelVariables[0].type.toString(), 'int');
   }
 
-  @override
-  @failingTest
-  void test_nullLiteralShouldNotInferAsBottom() {
-    super.test_nullLiteralShouldNotInferAsBottom();
-  }
-
   LibraryElementImpl _checkSource(
       SummaryResynthesizer resynthesizer, Source source) {
     LibraryElementImpl resynthesized =
@@ -624,12 +570,6 @@
   void test_inferred_function_type_in_generic_class_constructor() {
     super.test_inferred_function_type_in_generic_class_constructor();
   }
-
-  @override
-  @failingTest
-  void test_type_reference_to_import_part_in_subdir() {
-    super.test_type_reference_to_import_part_in_subdir();
-  }
 }
 
 /**
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index c3ae04d..30221bb 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -43,6 +43,12 @@
 abstract class AbstractResynthesizeTest extends AbstractSingleUnitTest {
   Set<Source> otherLibrarySources = new Set<Source>();
 
+  /**
+   * Names of variables which have initializers that are not valid constants,
+   * so they are not resynthesized.
+   */
+  Set<String> variablesWithNotConstInitializers = new Set<String>();
+
   bool get checkPropagatedTypes => true;
 
   /**
@@ -334,7 +340,11 @@
       } else if (oItem is ConstructorFieldInitializer &&
           rItem is ConstructorFieldInitializer) {
         compareConstAsts(rItem.fieldName, oItem.fieldName, desc);
-        compareConstAsts(rItem.expression, oItem.expression, desc);
+        if (variablesWithNotConstInitializers.contains(rItem.fieldName.name)) {
+          _assertUnresolvedIdentifier(rItem.expression, desc);
+        } else {
+          compareConstAsts(rItem.expression, oItem.expression, desc);
+        }
       } else if (oItem is SuperConstructorInvocation &&
           rItem is SuperConstructorInvocation) {
         compareElements(rItem.staticElement, oItem.staticElement, desc);
@@ -648,7 +658,13 @@
     }
     expect(original, isNotNull);
     expect(resynthesized, isNotNull, reason: desc);
-    expect(rImpl.runtimeType, oImpl.runtimeType);
+    if (rImpl is DefaultParameterElementImpl && oImpl is ParameterElementImpl) {
+      // This is ok provided the resynthesized parameter element doesn't have
+      // any evaluation result.
+      expect(rImpl.evaluationResult, isNull);
+    } else {
+      expect(rImpl.runtimeType, oImpl.runtimeType);
+    }
     expect(resynthesized.kind, original.kind);
     expect(resynthesized.location, original.location, reason: desc);
     expect(resynthesized.name, original.name);
@@ -702,27 +718,7 @@
           original.typeParameters[i],
           '$desc type parameter ${original.typeParameters[i].name}');
     }
-    if (original is! Member) {
-      List<FunctionElement> rFunctions = resynthesized.functions;
-      List<FunctionElement> oFunctions = original.functions;
-      expect(rFunctions, hasLength(oFunctions.length));
-      for (int i = 0; i < oFunctions.length; i++) {
-        compareFunctionElements(rFunctions[i], oFunctions[i],
-            '$desc local function ${oFunctions[i].name}');
-      }
-    }
-    if (original is! Member) {
-      List<LabelElement> rLabels = resynthesized.labels;
-      List<LabelElement> oLabels = original.labels;
-      expect(rLabels, hasLength(oLabels.length));
-      for (int i = 0; i < oLabels.length; i++) {
-        compareLabelElements(
-            rLabels[i], oLabels[i], '$desc label ${oLabels[i].name}');
-      }
-    }
-    if (original is! Member) {
-      compareLocalVariableElementLists(resynthesized, original, desc);
-    }
+    compareLocalElementsOfExecutable(resynthesized, original, desc);
   }
 
   void compareExportElements(ExportElementImpl resynthesized,
@@ -800,14 +796,34 @@
     compareElements(resynthesized, original, desc);
   }
 
-  void compareLocalVariableElementLists(ExecutableElement resynthesized,
+  void compareLocalElementsOfExecutable(ExecutableElement resynthesized,
       ExecutableElement original, String desc) {
-    List<LocalVariableElement> rVariables = resynthesized.localVariables;
-    List<LocalVariableElement> oVariables = original.localVariables;
-    expect(rVariables, hasLength(oVariables.length));
-    for (int i = 0; i < oVariables.length; i++) {
-      compareVariableElements(rVariables[i], oVariables[i],
-          '$desc local variable ${oVariables[i].name}');
+    if (original is! Member) {
+      List<FunctionElement> rFunctions = resynthesized.functions;
+      List<FunctionElement> oFunctions = original.functions;
+      expect(rFunctions, hasLength(oFunctions.length));
+      for (int i = 0; i < oFunctions.length; i++) {
+        compareFunctionElements(rFunctions[i], oFunctions[i],
+            '$desc local function ${oFunctions[i].name}');
+      }
+    }
+    if (original is! Member) {
+      List<LabelElement> rLabels = resynthesized.labels;
+      List<LabelElement> oLabels = original.labels;
+      expect(rLabels, hasLength(oLabels.length));
+      for (int i = 0; i < oLabels.length; i++) {
+        compareLabelElements(
+            rLabels[i], oLabels[i], '$desc label ${oLabels[i].name}');
+      }
+    }
+    if (original is! Member) {
+      List<LocalVariableElement> rVariables = resynthesized.localVariables;
+      List<LocalVariableElement> oVariables = original.localVariables;
+      expect(rVariables, hasLength(oVariables.length));
+      for (int i = 0; i < oVariables.length; i++) {
+        compareVariableElements(rVariables[i], oVariables[i],
+            '$desc local variable ${oVariables[i].name}');
+      }
     }
   }
 
@@ -1078,8 +1094,12 @@
             resynthesized.constantValue, original.constantValue, desc);
       } else {
         Expression initializer = resynthesizedActual.constantInitializer;
-        compareConstAsts(initializer, originalActual.constantInitializer,
-            '$desc initializer');
+        if (variablesWithNotConstInitializers.contains(resynthesized.name)) {
+          _assertUnresolvedIdentifier(initializer, desc);
+        } else {
+          compareConstAsts(initializer, originalActual.constantInitializer,
+              '$desc initializer');
+        }
       }
     }
     checkPossibleMember(resynthesized, original, desc);
@@ -1195,6 +1215,12 @@
     super.setUp();
     prepareAnalysisContext(createOptions());
   }
+
+  void _assertUnresolvedIdentifier(Expression initializer, String desc) {
+    expect(initializer, new isInstanceOf<SimpleIdentifier>(), reason: desc);
+    SimpleIdentifier identifier = initializer;
+    expect(identifier.staticElement, isNull, reason: desc);
+  }
 }
 
 @reflectiveTest
@@ -1657,6 +1683,7 @@
   }
 
   test_const_invalid_field_const() {
+    variablesWithNotConstInitializers.add('f');
     checkLibrary(
         r'''
 class C {
@@ -1668,6 +1695,7 @@
   }
 
   test_const_invalid_field_final() {
+    variablesWithNotConstInitializers.add('f');
     checkLibrary(
         r'''
 class C {
@@ -1679,6 +1707,7 @@
   }
 
   test_const_invalid_topLevel() {
+    variablesWithNotConstInitializers.add('v');
     checkLibrary(
         r'''
 const v = 1 + foo();
@@ -2421,6 +2450,7 @@
   }
 
   test_constructor_initializers_field_notConst() {
+    variablesWithNotConstInitializers.add('x');
     checkLibrary(
         '''
 class C {
@@ -2452,6 +2482,17 @@
 ''');
   }
 
+  test_constructor_initializers_superInvocation_namedExpression() {
+    checkLibrary('''
+class A {
+  const A.aaa(a, {int b});
+}
+class C extends A {
+  const C() : super.aaa(1, b: 2);
+}
+''');
+  }
+
   test_constructor_initializers_superInvocation_unnamed() {
     checkLibrary('''
 class A {
@@ -2472,6 +2513,15 @@
 ''');
   }
 
+  test_constructor_initializers_thisInvocation_namedExpression() {
+    checkLibrary('''
+class C {
+  const C() : this.named(1, b: 2);
+  const C.named(a, {int b});
+}
+''');
+  }
+
   test_constructor_initializers_thisInvocation_unnamed() {
     checkLibrary('''
 class C {
@@ -3191,6 +3241,14 @@
     checkLibrary('import "a.dart"; import "b.dart"; C c; D d;');
   }
 
+  void test_inferedType_usesSyntheticFunctionType_functionTypedParam() {
+    checkLibrary('''
+int f(int x(String y)) => null;
+String g(int x(String y)) => null;
+var v = [f, g];
+''');
+  }
+
   test_inferred_function_type_for_variable_in_generic_function() {
     // In the code below, `x` has an inferred type of `() => int`, with 2
     // (unused) type parameters from the enclosing top level function.
@@ -3296,6 +3354,14 @@
         ' abstract class D<U, V> { Map<V, U> get v; }');
   }
 
+  void test_inferred_type_refers_to_function_typed_param_of_typedef() {
+    checkLibrary('''
+typedef void F(int g(String s));
+h(F f) => null;
+var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
+''');
+  }
+
   test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
     checkLibrary('class C<T, U> extends D<U, int> { void f(int x, g) {} }'
         ' abstract class D<V, W> { void f(int x, W g(V s)); }');
@@ -3314,6 +3380,20 @@
         ' abstract class D { void f(int x, int g(String s)); }');
   }
 
+  test_inferred_type_refers_to_nested_function_typed_param() {
+    checkLibrary('''
+f(void g(int x, void h())) => null;
+var v = f((x, y) {});
+''');
+  }
+
+  test_inferred_type_refers_to_nested_function_typed_param_named() {
+    checkLibrary('''
+f({void g(int x, void h())}) => null;
+var v = f(g: (x, y) {});
+''');
+  }
+
   test_inferred_type_refers_to_setter_function_typed_parameter_type() {
     checkLibrary('class C extends D { void set f(g) {} }'
         ' abstract class D { void set f(int g(String s)); }');
diff --git a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
index 13f10ce..b034228 100644
--- a/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
+++ b/pkg/analyzer/test/src/summary/summarize_ast_strong_test.dart
@@ -66,6 +66,24 @@
 
   @override
   @failingTest
+  test_inferred_type_refers_to_function_typed_param_of_typedef() {
+    super.test_inferred_type_refers_to_function_typed_param_of_typedef();
+  }
+
+  @override
+  @failingTest
+  test_inferred_type_refers_to_nested_function_typed_param() {
+    super.test_inferred_type_refers_to_nested_function_typed_param();
+  }
+
+  @override
+  @failingTest
+  test_inferred_type_refers_to_nested_function_typed_param_named() {
+    super.test_inferred_type_refers_to_nested_function_typed_param_named();
+  }
+
+  @override
+  @failingTest
   test_initializer_executable_with_bottom_return_type() {
     super.test_initializer_executable_with_bottom_return_type();
   }
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 7e25284..0abc4de 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -43,7 +43,8 @@
     Map<String, Object> result = <String, Object>{};
     obj.toMap().forEach((String key, Object value) {
       bool orderByName = false;
-      if (obj is UnlinkedPublicNamespace && key == 'names') {
+      if (obj is UnlinkedPublicNamespace && key == 'names' ||
+          obj is UnlinkedPublicName && key == 'members') {
         orderByName = true;
       }
       result[key] = canonicalize(value, orderByName: orderByName);
@@ -356,7 +357,7 @@
    */
   void checkInferredTypeSlot(
       int slotId, String absoluteUri, String relativeUri, String expectedName,
-      {bool allowTypeParameters: false,
+      {int numTypeArguments: 0,
       ReferenceKind expectedKind: ReferenceKind.classOrEnum,
       int expectedTargetUnit: 0,
       LinkedUnit linkedSourceUnit,
@@ -365,7 +366,7 @@
       bool onlyInStrongMode: true}) {
     if (strongMode || !onlyInStrongMode) {
       checkLinkedTypeSlot(slotId, absoluteUri, relativeUri, expectedName,
-          allowTypeArguments: allowTypeParameters,
+          numTypeArguments: numTypeArguments,
           expectedKind: expectedKind,
           expectedTargetUnit: expectedTargetUnit,
           linkedSourceUnit: linkedSourceUnit,
@@ -399,10 +400,17 @@
   }
 
   /**
+   * Verify that the given [typeRef] represents the type `dynamic`.
+   */
+  void checkLinkedDynamicTypeRef(EntityRef typeRef) {
+    checkLinkedTypeRef(typeRef, null, null, 'dynamic');
+  }
+
+  /**
    * Verify that the given [typeRef] represents a reference to a type declared
    * in a file reachable via [absoluteUri] and [relativeUri], having name
-   * [expectedName].  If [allowTypeArguments] is true, allow the type
-   * reference to supply type arguments.  [expectedKind] is the kind of object
+   * [expectedName].  Verify that the number of type arguments
+   * is equal to [numTypeArguments].  [expectedKind] is the kind of object
    * referenced.  [linkedSourceUnit] and [unlinkedSourceUnit] refer to the
    * compilation unit within which the [typeRef] appears; if not specified they
    * are assumed to refer to the defining compilation unit.
@@ -413,7 +421,7 @@
    */
   void checkLinkedTypeRef(EntityRef typeRef, String absoluteUri,
       String relativeUri, String expectedName,
-      {bool allowTypeArguments: false,
+      {int numTypeArguments: 0,
       ReferenceKind expectedKind: ReferenceKind.classOrEnum,
       int expectedTargetUnit: 0,
       LinkedUnit linkedSourceUnit,
@@ -424,9 +432,7 @@
         reason: 'No entry in linkedSourceUnit.types matching slotId');
     expect(typeRef.paramReference, 0);
     int index = typeRef.reference;
-    if (!allowTypeArguments) {
-      expect(typeRef.typeArguments, isEmpty);
-    }
+    expect(typeRef.typeArguments, hasLength(numTypeArguments));
     checkReferenceIndex(index, absoluteUri, relativeUri, expectedName,
         expectedKind: expectedKind,
         expectedTargetUnit: expectedTargetUnit,
@@ -438,8 +444,8 @@
   /**
    * Verify that the given [slotId] represents a reference to a type declared
    * in a file reachable via [absoluteUri] and [relativeUri], having name
-   * [expectedName].  If [allowTypeArguments] is true, allow the type
-   * reference to supply type arguments.  [expectedKind] is the kind of object
+   * [expectedName].  Verify that the number of type arguments
+   * is equal to [numTypeArguments].  [expectedKind] is the kind of object
    * referenced.  [linkedSourceUnit] and [unlinkedSourceUnit] refer to the
    * compilation unit within which the [typeRef] appears; if not specified they
    * are assumed to refer to the defining compilation unit.
@@ -450,7 +456,7 @@
    */
   void checkLinkedTypeSlot(
       int slotId, String absoluteUri, String relativeUri, String expectedName,
-      {bool allowTypeArguments: false,
+      {int numTypeArguments: 0,
       ReferenceKind expectedKind: ReferenceKind.classOrEnum,
       int expectedTargetUnit: 0,
       LinkedUnit linkedSourceUnit,
@@ -467,7 +473,7 @@
         absoluteUri,
         relativeUri,
         expectedName,
-        allowTypeArguments: allowTypeArguments,
+        numTypeArguments: numTypeArguments,
         expectedKind: expectedKind,
         expectedTargetUnit: expectedTargetUnit,
         linkedSourceUnit: linkedSourceUnit,
@@ -572,8 +578,8 @@
    * Verify that the given [typeRef] represents a reference to a type declared
    * in a file reachable via [absoluteUri] and [relativeUri], having name
    * [expectedName].  If [expectedPrefix] is supplied, verify that the type is
-   * reached via the given prefix.  If [allowTypeParameters] is true, allow the
-   * type reference to supply type parameters.  [expectedKind] is the kind of
+   * reached via the given prefix.  Verify that the number of type arguments
+   * is equal to [numTypeArguments].  [expectedKind] is the kind of
    * object referenced.  [linkedSourceUnit] and [unlinkedSourceUnit] refer
    * to the compilation unit within which the [typeRef] appears; if not
    * specified they are assumed to refer to the defining compilation unit.
@@ -589,7 +595,7 @@
       String expectedName,
       {String expectedPrefix,
       List<_PrefixExpectation> prefixExpectations,
-      bool allowTypeParameters: false,
+      int numTypeArguments: 0,
       ReferenceKind expectedKind: ReferenceKind.classOrEnum,
       int expectedTargetUnit: 0,
       LinkedUnit linkedSourceUnit,
@@ -601,9 +607,7 @@
     expect(typeRef, new isInstanceOf<EntityRef>());
     expect(typeRef.paramReference, 0);
     int index = typeRef.reference;
-    if (!allowTypeParameters) {
-      expect(typeRef.typeArguments, isEmpty);
-    }
+    expect(typeRef.typeArguments, hasLength(numTypeArguments));
     UnlinkedReference reference = checkReferenceIndex(
         index, absoluteUri, relativeUri, expectedName,
         expectedKind: expectedKind,
@@ -1097,7 +1101,12 @@
   test_class_alias_reference_generic() {
     EntityRef typeRef = serializeTypeText('C',
         otherDeclarations: 'class C<D, E> = F with G; class F {} class G {}');
-    checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
+    checkTypeRef(typeRef, null, null, 'C',
+        numTypeParameters: 2, numTypeArguments: !checkAstDerivedData ? 2 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(typeRef.typeArguments[0]);
+      checkDynamicTypeRef(typeRef.typeArguments[1]);
+    }
   }
 
   test_class_alias_reference_generic_imported() {
@@ -1106,7 +1115,11 @@
     EntityRef typeRef =
         serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
     checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
-        numTypeParameters: 2);
+        numTypeParameters: 2, numTypeArguments: !checkAstDerivedData ? 2 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(typeRef.typeArguments[0]);
+      checkDynamicTypeRef(typeRef.typeArguments[1]);
+    }
   }
 
   test_class_alias_supertype() {
@@ -1156,17 +1169,19 @@
     Map<String, UnlinkedPublicName> executablesMap =
         <String, UnlinkedPublicName>{};
     className.members.forEach((e) => executablesMap[e.name] = e);
-    expect(executablesMap, hasLength(2));
-    {
-      UnlinkedPublicName executable = executablesMap['fieldStaticConst'];
-      expect(executable.kind, ReferenceKind.propertyAccessor);
+    expect(executablesMap, hasLength(4));
+    Map<String, ReferenceKind> expectedExecutableKinds =
+        <String, ReferenceKind>{
+      'fieldStaticConst': ReferenceKind.propertyAccessor,
+      'fieldStaticFinal': ReferenceKind.propertyAccessor,
+      'fieldStatic': ReferenceKind.propertyAccessor,
+      'methodStaticPublic': ReferenceKind.method,
+    };
+    expectedExecutableKinds.forEach((String name, ReferenceKind expectedKind) {
+      UnlinkedPublicName executable = executablesMap[name];
+      expect(executable.kind, expectedKind);
       expect(executable.members, isEmpty);
-    }
-    {
-      UnlinkedPublicName executable = executablesMap['methodStaticPublic'];
-      expect(executable.kind, ReferenceKind.method);
-      expect(executable.members, isEmpty);
-    }
+    });
   }
 
   test_class_constMembers_constructors() {
@@ -1317,7 +1332,12 @@
   test_class_reference_generic() {
     EntityRef typeRef =
         serializeTypeText('C', otherDeclarations: 'class C<D, E> {}');
-    checkTypeRef(typeRef, null, null, 'C', numTypeParameters: 2);
+    checkTypeRef(typeRef, null, null, 'C',
+        numTypeParameters: 2, numTypeArguments: !checkAstDerivedData ? 2 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(typeRef.typeArguments[0]);
+      checkDynamicTypeRef(typeRef.typeArguments[1]);
+    }
   }
 
   test_class_reference_generic_imported() {
@@ -1325,7 +1345,11 @@
     EntityRef typeRef =
         serializeTypeText('C', otherDeclarations: 'import "lib.dart";');
     checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'C',
-        numTypeParameters: 2);
+        numTypeParameters: 2, numTypeArguments: !checkAstDerivedData ? 2 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(typeRef.typeArguments[0]);
+      checkDynamicTypeRef(typeRef.typeArguments[1]);
+    }
   }
 
   test_class_superclass() {
@@ -1344,10 +1368,16 @@
   test_class_type_param_bound() {
     UnlinkedClass cls = serializeClassText('class C<T extends List> {}');
     expect(cls.typeParameters, hasLength(1));
-    expect(cls.typeParameters[0].name, 'T');
-    expect(cls.typeParameters[0].bound, isNotNull);
-    checkTypeRef(cls.typeParameters[0].bound, 'dart:core', 'dart:core', 'List',
-        allowTypeParameters: true, numTypeParameters: 1);
+    {
+      UnlinkedTypeParam typeParameter = cls.typeParameters[0];
+      expect(typeParameter.name, 'T');
+      expect(typeParameter.bound, isNotNull);
+      checkTypeRef(typeParameter.bound, 'dart:core', 'dart:core', 'List',
+          numTypeParameters: 1, numTypeArguments: !checkAstDerivedData ? 1 : 0);
+      if (!checkAstDerivedData) {
+        checkDynamicTypeRef(typeParameter.bound.typeArguments[0]);
+      }
+    }
   }
 
   test_class_type_param_f_bound() {
@@ -1742,6 +1772,57 @@
         strings: ['T']);
   }
 
+  test_constExpr_functionExpression_asArgument() {
+    // Even though function expressions are not allowed in constant
+    // declarations, they might occur due to erroneous code, so make sure they
+    // function correctly.
+    UnlinkedVariable variable = serializeVariableText('''
+const v = foo(5, () => 42);
+foo(a, b) {}
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushLocalFunctionReference,
+      UnlinkedConstOperation.invokeMethodRef
+    ], ints: [
+      5,
+      0,
+      0,
+      0,
+      2
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+          expectedKind: ReferenceKind.topLevelFunction)
+    ]);
+  }
+
+  test_constExpr_functionExpression_asArgument_multiple() {
+    // Even though function expressions are not allowed in constant
+    // declarations, they might occur due to erroneous code, so make sure they
+    // function correctly.
+    UnlinkedVariable variable = serializeVariableText('''
+const v = foo(5, () => 42, () => 43);
+foo(a, b, c) {}
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushLocalFunctionReference,
+      UnlinkedConstOperation.pushLocalFunctionReference,
+      UnlinkedConstOperation.invokeMethodRef
+    ], ints: [
+      5,
+      0,
+      0,
+      0,
+      1,
+      0,
+      3
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+          expectedKind: ReferenceKind.topLevelFunction)
+    ]);
+  }
+
   test_constExpr_invokeConstructor_generic_named() {
     UnlinkedVariable variable = serializeVariableText('''
 class C<K, V> {
@@ -1762,7 +1843,7 @@
               new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
                   numTypeParameters: 2)
             ],
-            allowTypeParameters: true);
+            numTypeArguments: 2);
         checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
         checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
       }
@@ -1796,7 +1877,7 @@
                   relativeUri: 'a.dart',
                   numTypeParameters: 2)
             ],
-            allowTypeParameters: true);
+            numTypeArguments: 2);
         checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
         checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
       }
@@ -1831,7 +1912,7 @@
                   numTypeParameters: 2),
               new _PrefixExpectation(ReferenceKind.prefix, 'p')
             ],
-            allowTypeParameters: true);
+            numTypeArguments: 2);
         checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
         checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
       }
@@ -1855,7 +1936,7 @@
         checkTypeRef(r, null, null, 'C',
             expectedKind: ReferenceKind.classOrEnum,
             numTypeParameters: 2,
-            allowTypeParameters: true);
+            numTypeArguments: 2);
         checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
         checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
       }
@@ -1884,7 +1965,7 @@
         checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
             expectedKind: ReferenceKind.classOrEnum,
             numTypeParameters: 2,
-            allowTypeParameters: true);
+            numTypeArguments: 2);
         checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
         checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
       }
@@ -1913,7 +1994,7 @@
         checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
             expectedKind: ReferenceKind.classOrEnum,
             numTypeParameters: 2,
-            allowTypeParameters: true,
+            numTypeArguments: 2,
             prefixExpectations: [
               new _PrefixExpectation(ReferenceKind.prefix, 'p')
             ]);
@@ -3433,6 +3514,57 @@
         operators: [UnlinkedConstOperation.pushString], strings: ['bbb']);
   }
 
+  test_constructor_initializers_thisInvocation_namedExpression() {
+    UnlinkedExecutable executable =
+        findExecutable('', executables: serializeClassText(r'''
+class C {
+  const C() : this.named(1, b: 2, c: 3);
+  const C.named(a, {int b, int c});
+}
+''').executables);
+    expect(executable.constantInitializers, hasLength(1));
+    UnlinkedConstructorInitializer initializer =
+        executable.constantInitializers[0];
+    expect(initializer.kind, UnlinkedConstructorInitializerKind.thisInvocation);
+    expect(initializer.name, 'named');
+    expect(initializer.expression, isNull);
+    expect(initializer.arguments, hasLength(3));
+    _assertUnlinkedConst(initializer.arguments[0],
+        operators: [UnlinkedConstOperation.pushInt], ints: [1]);
+    _assertUnlinkedConst(initializer.arguments[1],
+        operators: [UnlinkedConstOperation.pushInt], ints: [2]);
+    _assertUnlinkedConst(initializer.arguments[2],
+        operators: [UnlinkedConstOperation.pushInt], ints: [3]);
+    expect(initializer.argumentNames, ['b', 'c']);
+  }
+
+  test_constructor_initializers_superInvocation_namedExpression() {
+    UnlinkedExecutable executable =
+        findExecutable('', executables: serializeClassText(r'''
+class A {
+  const A(a, {int b, int c});
+}
+class C extends A {
+  const C() : super(1, b: 2, c: 3);
+}
+''').executables);
+    expect(executable.constantInitializers, hasLength(1));
+    UnlinkedConstructorInitializer initializer =
+        executable.constantInitializers[0];
+    expect(
+        initializer.kind, UnlinkedConstructorInitializerKind.superInvocation);
+    expect(initializer.name, '');
+    expect(initializer.expression, isNull);
+    expect(initializer.arguments, hasLength(3));
+    _assertUnlinkedConst(initializer.arguments[0],
+        operators: [UnlinkedConstOperation.pushInt], ints: [1]);
+    _assertUnlinkedConst(initializer.arguments[1],
+        operators: [UnlinkedConstOperation.pushInt], ints: [2]);
+    _assertUnlinkedConst(initializer.arguments[2],
+        operators: [UnlinkedConstOperation.pushInt], ints: [3]);
+    expect(initializer.argumentNames, ['b', 'c']);
+  }
+
   test_constructor_initializers_thisInvocation_unnamed() {
     UnlinkedExecutable executable =
         findExecutable('named', executables: serializeClassText(r'''
@@ -3734,7 +3866,7 @@
           new _PrefixExpectation(ReferenceKind.classOrEnum, 'D',
               numTypeParameters: 2)
         ],
-        allowTypeParameters: true);
+        numTypeArguments: 2);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
   }
@@ -3797,7 +3929,7 @@
               absoluteUri: absUri('/foo.dart'),
               relativeUri: 'foo.dart')
         ],
-        allowTypeParameters: true);
+        numTypeArguments: 2);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
   }
@@ -3862,7 +3994,7 @@
               relativeUri: 'foo.dart'),
           new _PrefixExpectation(ReferenceKind.prefix, 'foo')
         ],
-        allowTypeParameters: true);
+        numTypeArguments: 2);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
   }
@@ -3901,7 +4033,7 @@
     expect(executable.isFactory, isTrue);
     expect(executable.redirectedConstructorName, isEmpty);
     checkTypeRef(executable.redirectedConstructor, null, null, 'D',
-        allowTypeParameters: true, numTypeParameters: 2);
+        numTypeParameters: 2, numTypeArguments: 2);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
   }
@@ -3954,7 +4086,7 @@
     expect(executable.redirectedConstructorName, isEmpty);
     checkTypeRef(
         executable.redirectedConstructor, absUri('/foo.dart'), 'foo.dart', 'D',
-        allowTypeParameters: true, numTypeParameters: 2);
+        numTypeParameters: 2, numTypeArguments: 2);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
   }
@@ -4008,7 +4140,7 @@
     expect(executable.redirectedConstructorName, isEmpty);
     checkTypeRef(
         executable.redirectedConstructor, absUri('/foo.dart'), 'foo.dart', 'D',
-        allowTypeParameters: true, numTypeParameters: 2, expectedPrefix: 'foo');
+        numTypeParameters: 2, expectedPrefix: 'foo', numTypeArguments: 2);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[0], 1);
     checkParamTypeRef(executable.redirectedConstructor.typeArguments[1], 2);
   }
@@ -6723,11 +6855,13 @@
 ''');
     _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
       UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.pushNull,
+      UnlinkedConstOperation.pushLocalFunctionReference,
       UnlinkedConstOperation.invokeMethodRef
     ], ints: [
       5,
       0,
+      0,
+      0,
       2
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'foo',
@@ -6735,6 +6869,33 @@
     ]);
   }
 
+  test_expr_functionExpression_asArgument_multiple() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+final v = foo(5, () => 42, () => 43);
+foo(a, b, c) {}
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushInt,
+      UnlinkedConstOperation.pushLocalFunctionReference,
+      UnlinkedConstOperation.pushLocalFunctionReference,
+      UnlinkedConstOperation.invokeMethodRef
+    ], ints: [
+      5,
+      0,
+      0,
+      0,
+      1,
+      0,
+      3
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'foo',
+          expectedKind: ReferenceKind.topLevelFunction)
+    ]);
+  }
+
   test_expr_functionExpression_withBlockBody() {
     if (skipNonConstInitializers) {
       return;
@@ -6743,7 +6904,9 @@
 final v = () { return 42; };
 ''');
     _assertUnlinkedConst(variable.constExpr,
-        isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+        isValidConst: false,
+        operators: [UnlinkedConstOperation.pushLocalFunctionReference],
+        ints: [0, 0]);
   }
 
   test_expr_functionExpression_withExpressionBody() {
@@ -6754,7 +6917,9 @@
 final v = () => 42;
 ''');
     _assertUnlinkedConst(variable.constExpr,
-        isValidConst: false, operators: [UnlinkedConstOperation.pushNull]);
+        isValidConst: false,
+        operators: [UnlinkedConstOperation.pushLocalFunctionReference],
+        ints: [0, 0]);
   }
 
   test_expr_functionExpressionInvocation_withBlockBody() {
@@ -6882,6 +7047,29 @@
     ]);
   }
 
+  test_expr_invokeMethodRef_with_reference_arg() {
+    if (skipNonConstInitializers) {
+      return;
+    }
+    UnlinkedVariable variable = serializeVariableText('''
+f(x) => null;
+final u = null;
+final v = f(u);
+''');
+    _assertUnlinkedConst(variable.constExpr, isValidConst: false, operators: [
+      UnlinkedConstOperation.pushReference,
+      UnlinkedConstOperation.invokeMethodRef
+    ], ints: [
+      0,
+      1
+    ], referenceValidators: [
+      (EntityRef r) => checkTypeRef(r, null, null, 'u',
+          expectedKind: ReferenceKind.topLevelPropertyAccessor),
+      (EntityRef r) => checkTypeRef(r, null, null, 'f',
+          expectedKind: ReferenceKind.topLevelFunction)
+    ]);
+  }
+
   test_expr_throwException() {
     if (skipNonConstInitializers) {
       return;
@@ -6946,6 +7134,9 @@
     expect(variable.constExpr, isNull);
     expect(findExecutable('i', executables: cls.executables), isNull);
     expect(findExecutable('i=', executables: cls.executables), isNull);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+    expect(unlinkedUnits[0].publicNamespace.names[0].members, isEmpty);
   }
 
   test_field_const() {
@@ -7096,6 +7287,17 @@
         serializeClassText('class C { static int i; }').fields[0];
     expect(variable.isStatic, isTrue);
     expect(variable.constExpr, isNull);
+    expect(unlinkedUnits[0].publicNamespace.names, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].name, 'C');
+    expect(unlinkedUnits[0].publicNamespace.names[0].members, hasLength(1));
+    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].name, 'i');
+    expect(unlinkedUnits[0].publicNamespace.names[0].members[0].kind,
+        ReferenceKind.propertyAccessor);
+    expect(
+        unlinkedUnits[0].publicNamespace.names[0].members[0].numTypeParameters,
+        0);
+    expect(
+        unlinkedUnits[0].publicNamespace.names[0].members[0].members, isEmpty);
   }
 
   test_field_static_final() {
@@ -7389,7 +7591,12 @@
     UnlinkedVariable variable =
         serializeVariableText('import "dart:async" as a; a.Future v;');
     checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
-        expectedPrefix: 'a', numTypeParameters: 1);
+        expectedPrefix: 'a',
+        numTypeParameters: 1,
+        numTypeArguments: !checkAstDerivedData ? 1 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(variable.type.typeArguments[0]);
+    }
   }
 
   test_import_prefixes_take_precedence_over_imported_names() {
@@ -7419,7 +7626,10 @@
     UnlinkedVariable variable =
         serializeVariableText('import "dart:async"; Future v;');
     checkTypeRef(variable.type, 'dart:async', 'dart:async', 'Future',
-        numTypeParameters: 1);
+        numTypeParameters: 1, numTypeArguments: !checkAstDerivedData ? 1 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(variable.type.typeArguments[0]);
+    }
   }
 
   test_import_reference_merged_no_prefix() {
@@ -7430,10 +7640,24 @@
 Future f;
 Stream s;
 ''');
-    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
-        numTypeParameters: 1);
-    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
-        expectedTargetUnit: 1, numTypeParameters: 1);
+    {
+      EntityRef typeRef = findVariable('f').type;
+      checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Future',
+          numTypeParameters: 1, numTypeArguments: !checkAstDerivedData ? 1 : 0);
+      if (!checkAstDerivedData) {
+        checkDynamicTypeRef(typeRef.typeArguments[0]);
+      }
+    }
+    {
+      EntityRef typeRef = findVariable('s').type;
+      checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Stream',
+          expectedTargetUnit: 1,
+          numTypeParameters: 1,
+          numTypeArguments: !checkAstDerivedData ? 1 : 0);
+      if (!checkAstDerivedData) {
+        checkDynamicTypeRef(typeRef.typeArguments[0]);
+      }
+    }
   }
 
   test_import_reference_merged_prefixed() {
@@ -7444,10 +7668,27 @@
 a.Future f;
 a.Stream s;
 ''');
-    checkTypeRef(findVariable('f').type, 'dart:async', 'dart:async', 'Future',
-        expectedPrefix: 'a', numTypeParameters: 1);
-    checkTypeRef(findVariable('s').type, 'dart:async', 'dart:async', 'Stream',
-        expectedTargetUnit: 1, expectedPrefix: 'a', numTypeParameters: 1);
+    {
+      EntityRef typeRef = findVariable('f').type;
+      checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Future',
+          expectedPrefix: 'a',
+          numTypeParameters: 1,
+          numTypeArguments: !checkAstDerivedData ? 1 : 0);
+      if (!checkAstDerivedData) {
+        checkDynamicTypeRef(typeRef.typeArguments[0]);
+      }
+    }
+    {
+      EntityRef typeRef = findVariable('s').type;
+      checkTypeRef(typeRef, 'dart:async', 'dart:async', 'Stream',
+          expectedTargetUnit: 1,
+          expectedPrefix: 'a',
+          numTypeParameters: 1,
+          numTypeArguments: !checkAstDerivedData ? 1 : 0);
+      if (!checkAstDerivedData) {
+        checkDynamicTypeRef(typeRef.typeArguments[0]);
+      }
+    }
   }
 
   test_import_reference_merged_prefixed_separate_libraries() {
@@ -7513,6 +7754,34 @@
     expect(unlinkedUnits[0].imports[0].uri, 'dart:async');
   }
 
+  test_inferred_function_type_parameter_type_with_unrelated_type_param() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    // The type that is inferred for C.f's parameter g is "() -> void".
+    // Since the associated element for that function type is B.f's parameter g,
+    // and B has a type parameter, the inferred type will record a type
+    // parameter.  However, since that type parameter is irrelevant, the summary
+    // should encode it as `dynamic`.
+    UnlinkedClass c = serializeClassText('''
+abstract class B<T> {
+  void f(void g());
+}
+class C<T> extends B<T> {
+  void f(g) {}
+}
+''');
+    expect(c.executables, hasLength(1));
+    UnlinkedExecutable f = c.executables[0];
+    expect(f.parameters, hasLength(1));
+    UnlinkedParam g = f.parameters[0];
+    expect(g.name, 'g');
+    EntityRef typeRef = getTypeRefForSlot(g.inferredTypeSlot);
+    checkLinkedTypeRef(typeRef, null, null, 'f',
+        expectedKind: ReferenceKind.method, numTypeArguments: 1);
+    checkLinkedDynamicTypeRef(typeRef.typeArguments[0]);
+  }
+
   test_inferred_type_keeps_leading_dynamic() {
     if (!strongMode || skipFullyLinkedData) {
       return;
@@ -7522,12 +7791,24 @@
     EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
     // Check that x has inferred type `Map<dynamic, int>`.
     checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
-        allowTypeArguments: true, numTypeParameters: 2);
-    expect(type.typeArguments, hasLength(2));
+        numTypeParameters: 2, numTypeArguments: 2);
     checkLinkedTypeRef(type.typeArguments[0], null, null, 'dynamic');
     checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int');
   }
 
+  test_inferred_type_reference_shared_prefixed() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    // Variable `y` has an inferred type of `p.C`.  Verify that the reference
+    // used by the explicit type of `x` is re-used for the inferred type.
+    addNamedSource('/a.dart', 'class C {}');
+    serializeLibraryText('import "a.dart" as p; p.C x; var y = new p.C();');
+    EntityRef xType = findVariable('x').type;
+    EntityRef yType = getTypeRefForSlot(findVariable('y').inferredTypeSlot);
+    expect(yType.reference, xType.reference);
+  }
+
   test_inferred_type_refers_to_bound_type_param() {
     if (!strongMode || skipFullyLinkedData) {
       return;
@@ -7539,11 +7820,31 @@
     EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
     // Check that v has inferred type Map<T, int>.
     checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
-        allowTypeArguments: true, numTypeParameters: 2);
+        numTypeParameters: 2, numTypeArguments: 2);
     checkParamTypeRef(type.typeArguments[0], 1);
     checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int');
   }
 
+  test_inferred_type_refers_to_function_typed_param_of_typedef() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedVariable v = serializeVariableText('''
+typedef void F(int g(String s));
+h(F f) => null;
+var v = h((y) {});
+''');
+    expect(v.initializer.localFunctions, hasLength(1));
+    UnlinkedExecutable closure = v.initializer.localFunctions[0];
+    expect(closure.parameters, hasLength(1));
+    UnlinkedParam y = closure.parameters[0];
+    expect(y.name, 'y');
+    EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+    checkLinkedTypeRef(typeRef, null, null, 'F',
+        expectedKind: ReferenceKind.typedef);
+    expect(typeRef.implicitFunctionTypeIndices, [0]);
+  }
+
   test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
     if (!strongMode || skipFullyLinkedData) {
       return;
@@ -7636,6 +7937,44 @@
     checkReferenceIndex(linkedReference.containingReference, null, null, 'D');
   }
 
+  test_inferred_type_refers_to_nested_function_typed_param() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedVariable v = serializeVariableText('''
+f(void g(int x, void h())) => null;
+var v = f((x, y) {});
+''');
+    expect(v.initializer.localFunctions, hasLength(1));
+    UnlinkedExecutable closure = v.initializer.localFunctions[0];
+    expect(closure.parameters, hasLength(2));
+    UnlinkedParam y = closure.parameters[1];
+    expect(y.name, 'y');
+    EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+    checkLinkedTypeRef(typeRef, null, null, 'f',
+        expectedKind: ReferenceKind.topLevelFunction);
+    expect(typeRef.implicitFunctionTypeIndices, [0, 1]);
+  }
+
+  test_inferred_type_refers_to_nested_function_typed_param_named() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedVariable v = serializeVariableText('''
+f({void g(int x, void h())}) => null;
+var v = f(g: (x, y) {});
+''');
+    expect(v.initializer.localFunctions, hasLength(1));
+    UnlinkedExecutable closure = v.initializer.localFunctions[0];
+    expect(closure.parameters, hasLength(2));
+    UnlinkedParam y = closure.parameters[1];
+    expect(y.name, 'y');
+    EntityRef typeRef = getTypeRefForSlot(y.inferredTypeSlot);
+    checkLinkedTypeRef(typeRef, null, null, 'f',
+        expectedKind: ReferenceKind.topLevelFunction);
+    expect(typeRef.implicitFunctionTypeIndices, [0, 1]);
+  }
+
   test_inferred_type_refers_to_setter_function_typed_parameter_type() {
     if (!strongMode || skipFullyLinkedData) {
       return;
@@ -7672,12 +8011,11 @@
     UnlinkedClass cls =
         serializeClassText('class C { final x = <int, dynamic>{}; }');
     EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
-    // Check that x has inferred type `Map<int>`.  The trailing type argument
-    // `dynamic` is omitted.
+    // Check that x has inferred type `Map<int, dynamic>`.
     checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
-        allowTypeArguments: true, numTypeParameters: 2);
-    expect(type.typeArguments, hasLength(1));
+        numTypeParameters: 2, numTypeArguments: 2);
     checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
+    checkLinkedDynamicTypeRef(type.typeArguments[1]);
   }
 
   test_inferred_type_skips_unnecessary_dynamic() {
@@ -7686,9 +8024,9 @@
     }
     UnlinkedClass cls = serializeClassText('class C { final x = []; }');
     EntityRef type = getTypeRefForSlot(cls.fields[0].inferredTypeSlot);
-    // Check that x has inferred type `List`, not `List<dynamic>`.
+    // Check that x has inferred type `List<dynamic>`.
     checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'List',
-        numTypeParameters: 1);
+        numTypeParameters: 1, numTypeArguments: 1);
   }
 
   test_initializer_executable_with_bottom_return_type() {
@@ -8694,8 +9032,8 @@
     // ids should be reused.
     addNamedSource('/a.dart', 'part of foo; final v = 0;');
     serializeLibraryText('library foo; part "a.dart"; final w = 0;');
-    expect(unlinkedUnits[0].variables[0].propagatedTypeSlot, 1);
-    expect(unlinkedUnits[1].variables[0].propagatedTypeSlot, 1);
+    expect(unlinkedUnits[1].variables[0].propagatedTypeSlot,
+        unlinkedUnits[0].variables[0].propagatedTypeSlot);
   }
 
   test_syntheticFunctionType_genericClosure() {
@@ -8821,32 +9159,29 @@
   test_type_arguments_explicit() {
     EntityRef typeRef = serializeTypeText('List<int>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
-        allowTypeParameters: true, numTypeParameters: 1);
-    expect(typeRef.typeArguments, hasLength(1));
+        numTypeParameters: 1, numTypeArguments: 1);
     checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
   }
 
   test_type_arguments_explicit_dynamic() {
     EntityRef typeRef = serializeTypeText('List<dynamic>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
-        allowTypeParameters: true, numTypeParameters: 1);
-    expect(typeRef.typeArguments, isEmpty);
+        numTypeParameters: 1, numTypeArguments: 1);
+    checkDynamicTypeRef(typeRef.typeArguments[0]);
   }
 
   test_type_arguments_explicit_dynamic_dynamic() {
     EntityRef typeRef = serializeTypeText('Map<dynamic, dynamic>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
-        allowTypeParameters: true, numTypeParameters: 2);
-    // Trailing type arguments of type `dynamic` are omitted.
-    expect(typeRef.typeArguments, isEmpty);
+        numTypeParameters: 2, numTypeArguments: 2);
+    checkDynamicTypeRef(typeRef.typeArguments[0]);
+    checkDynamicTypeRef(typeRef.typeArguments[1]);
   }
 
   test_type_arguments_explicit_dynamic_int() {
     EntityRef typeRef = serializeTypeText('Map<dynamic, int>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
-        allowTypeParameters: true, numTypeParameters: 2);
-    // Leading type arguments of type `dynamic` are not omitted.
-    expect(typeRef.typeArguments.length, 2);
+        numTypeParameters: 2, numTypeArguments: 2);
     checkDynamicTypeRef(typeRef.typeArguments[0]);
     checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int');
   }
@@ -8855,26 +9190,24 @@
     EntityRef typeRef =
         serializeTypeText('F<dynamic>', otherDeclarations: 'typedef T F<T>();');
     checkTypeRef(typeRef, null, null, 'F',
-        allowTypeParameters: true,
         expectedKind: ReferenceKind.typedef,
-        numTypeParameters: 1);
-    expect(typeRef.typeArguments, isEmpty);
+        numTypeParameters: 1,
+        numTypeArguments: 1);
+    checkDynamicTypeRef(typeRef.typeArguments[0]);
   }
 
   test_type_arguments_explicit_String_dynamic() {
     EntityRef typeRef = serializeTypeText('Map<String, dynamic>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
-        allowTypeParameters: true, numTypeParameters: 2);
-    // Trailing type arguments of type `dynamic` are omitted.
-    expect(typeRef.typeArguments.length, 1);
+        numTypeParameters: 2, numTypeArguments: 2);
     checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String');
+    checkDynamicTypeRef(typeRef.typeArguments[1]);
   }
 
   test_type_arguments_explicit_String_int() {
     EntityRef typeRef = serializeTypeText('Map<String, int>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
-        allowTypeParameters: true, numTypeParameters: 2);
-    expect(typeRef.typeArguments.length, 2);
+        numTypeParameters: 2, numTypeArguments: 2);
     checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'String');
     checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'int');
   }
@@ -8883,35 +9216,53 @@
     EntityRef typeRef =
         serializeTypeText('F<int>', otherDeclarations: 'typedef T F<T>();');
     checkTypeRef(typeRef, null, null, 'F',
-        allowTypeParameters: true,
         expectedKind: ReferenceKind.typedef,
-        numTypeParameters: 1);
-    expect(typeRef.typeArguments, hasLength(1));
+        numTypeParameters: 1,
+        numTypeArguments: 1);
     checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
   }
 
   test_type_arguments_implicit() {
     EntityRef typeRef = serializeTypeText('List');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'List',
-        allowTypeParameters: true, numTypeParameters: 1);
-    expect(typeRef.typeArguments, isEmpty);
+        numTypeParameters: 1, numTypeArguments: !checkAstDerivedData ? 1 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(typeRef.typeArguments[0]);
+    }
   }
 
   test_type_arguments_implicit_typedef() {
     EntityRef typeRef =
         serializeTypeText('F', otherDeclarations: 'typedef T F<T>();');
     checkTypeRef(typeRef, null, null, 'F',
-        allowTypeParameters: true,
         expectedKind: ReferenceKind.typedef,
-        numTypeParameters: 1);
-    expect(typeRef.typeArguments, isEmpty);
+        numTypeParameters: 1,
+        numTypeArguments: !checkAstDerivedData ? 1 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(typeRef.typeArguments[0]);
+    }
+  }
+
+  test_type_arguments_implicit_typedef_withBound() {
+    EntityRef typeRef = serializeTypeText('F',
+        otherDeclarations: 'typedef T F<T extends num>();');
+    checkTypeRef(typeRef, null, null, 'F',
+        expectedKind: ReferenceKind.typedef,
+        numTypeParameters: 1,
+        numTypeArguments: !checkAstDerivedData ? 1 : 0);
+    if (!checkAstDerivedData) {
+      if (strongMode) {
+        checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'num');
+      } else {
+        checkDynamicTypeRef(typeRef.typeArguments[0]);
+      }
+    }
   }
 
   test_type_arguments_order() {
     EntityRef typeRef = serializeTypeText('Map<int, Object>');
     checkTypeRef(typeRef, 'dart:core', 'dart:core', 'Map',
-        allowTypeParameters: true, numTypeParameters: 2);
-    expect(typeRef.typeArguments, hasLength(2));
+        numTypeParameters: 2, numTypeArguments: 2);
     checkTypeRef(typeRef.typeArguments[0], 'dart:core', 'dart:core', 'int');
     checkTypeRef(typeRef.typeArguments[1], 'dart:core', 'dart:core', 'Object');
   }
@@ -9235,7 +9586,13 @@
     EntityRef typeRef =
         serializeTypeText('F', otherDeclarations: 'typedef void F<A, B>();');
     checkTypeRef(typeRef, null, null, 'F',
-        numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
+        numTypeParameters: 2,
+        expectedKind: ReferenceKind.typedef,
+        numTypeArguments: !checkAstDerivedData ? 2 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(typeRef.typeArguments[0]);
+      checkDynamicTypeRef(typeRef.typeArguments[1]);
+    }
   }
 
   test_typedef_reference_generic_imported() {
@@ -9243,7 +9600,13 @@
     EntityRef typeRef =
         serializeTypeText('F', otherDeclarations: 'import "lib.dart";');
     checkTypeRef(typeRef, absUri('/lib.dart'), 'lib.dart', 'F',
-        numTypeParameters: 2, expectedKind: ReferenceKind.typedef);
+        numTypeParameters: 2,
+        expectedKind: ReferenceKind.typedef,
+        numTypeArguments: !checkAstDerivedData ? 2 : 0);
+    if (!checkAstDerivedData) {
+      checkDynamicTypeRef(typeRef.typeArguments[0]);
+      checkDynamicTypeRef(typeRef.typeArguments[1]);
+    }
   }
 
   test_typedef_return_type_explicit() {
@@ -9531,9 +9894,9 @@
     UnlinkedVariable v = serializeVariableText('final v = <int, dynamic>{};');
     EntityRef type = getTypeRefForSlot(v.propagatedTypeSlot);
     checkLinkedTypeRef(type, 'dart:core', 'dart:core', 'Map',
-        allowTypeArguments: true, numTypeParameters: 2);
-    expect(type.typeArguments, hasLength(1));
+        numTypeParameters: 2, numTypeArguments: 2);
     checkLinkedTypeRef(type.typeArguments[0], 'dart:core', 'dart:core', 'int');
+    checkLinkedDynamicTypeRef(type.typeArguments[1]);
   }
 
   test_variable_propagatedTypeSlot_const() {
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 28ab23a..5fbc192 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -2051,7 +2051,7 @@
       typedef void ToVoid<T>(T x);
       class F {
         void set f(ToVoid<dynamic> x) {}
-        void set g(ToVoid<int> x) {} 
+        void set g(ToVoid<int> x) {}
         void set h(dynamic x) {}
         void set i(int x) {}
      }
@@ -2343,8 +2343,8 @@
 
             x = /*info:DOWN_CAST_IMPLICIT*/x + z;
             x += /*info:DOWN_CAST_IMPLICIT*/z;
-            y = /*info:DOWN_CAST_IMPLICIT*/y + z;
-            y += /*info:DOWN_CAST_IMPLICIT*/z;
+            y = y + z;
+            y += z;
 
             dynamic w = 42;
             x += /*info:DYNAMIC_CAST*/w;
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index d1ebb09..83d6485 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -382,7 +382,7 @@
 }
 ''');
     var f = mainUnit.functions[0].localVariables[0];
-    expect(f.type.toString(), '() → (int) → num');
+    expect(f.type.toString(), '() → (int) → double');
   }
 
   void test_blockBodiedLambdas_nestedLambdas_topLevel() {
@@ -393,7 +393,7 @@
 };
 ''');
     var f = mainUnit.topLevelVariables[0];
-    expect(f.type.toString(), '() → (int) → num');
+    expect(f.type.toString(), '() → (int) → double');
   }
 
   void test_blockBodiedLambdas_noReturn() {
@@ -1257,6 +1257,17 @@
     expect(x.type.toString(), 'int');
   }
 
+  void test_fieldRefersToTopLevelGetter() {
+    var mainUnit = checkFile('''
+class C {
+  final x = y;
+}
+int get y => null;
+''');
+    var x = mainUnit.types[0].fields[0];
+    expect(x.type.toString(), 'int');
+  }
+
   void test_genericMethods_basicDownwardInference() {
     checkFile(r'''
 /*=T*/ f/*<S, T>*/(/*=S*/ s) => null;
@@ -1383,6 +1394,48 @@
   ''');
   }
 
+  void test_genericMethods_inferGenericFunctionParameterType() {
+    var mainUnit = checkFile('''
+class C<T> extends D<T> {
+  f/*<U>*/(x) {}
+}
+class D<T> {
+  F/*<U>*/ f/*<U>*/(/*=U*/ u) => null;
+}
+typedef void F<V>(V v);
+''');
+    var f = mainUnit.getType('C').methods[0];
+    expect(f.type.toString(), '<U>(U) → (U) → void');
+  }
+
+  void test_genericMethods_inferGenericFunctionParameterType2() {
+    var mainUnit = checkFile('''
+class C<T> extends D<T> {
+  f/*<U>*/(g) => null;
+}
+abstract class D<T> {
+  void f/*<U>*/(G/*<U>*/ g);
+}
+typedef List<V> G<V>();
+''');
+    var f = mainUnit.getType('C').methods[0];
+    expect(f.type.toString(), '<U>(() → List<U>) → void');
+  }
+
+  void test_genericMethods_inferGenericFunctionReturnType() {
+    var mainUnit = checkFile('''
+class C<T> extends D<T> {
+  f/*<U>*/(x) {}
+}
+class D<T> {
+  F/*<U>*/ f/*<U>*/(/*=U*/ u) => null;
+}
+typedef V F<V>();
+''');
+    var f = mainUnit.getType('C').methods[0];
+    expect(f.type.toString(), '<U>(U) → () → U');
+  }
+
   void test_genericMethods_inferGenericInstantiation() {
     checkFile('''
 import 'dart:math' as math;
@@ -1790,6 +1843,56 @@
 ''');
   }
 
+  void test_inferedType_usesSyntheticFunctionType() {
+    var mainUnit = checkFile('''
+int f() => null;
+String g() => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), 'List<() → Object>');
+  }
+
+  void test_inferedType_usesSyntheticFunctionType_functionTypedParam() {
+    var mainUnit = checkFile('''
+int f(int x(String y)) => null;
+String g(int x(String y)) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), 'List<((String) → int) → Object>');
+  }
+
+  void test_inferedType_usesSyntheticFunctionType_namedParam() {
+    var mainUnit = checkFile('''
+int f({int x}) => null;
+String g({int x}) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), 'List<({x: int}) → Object>');
+  }
+
+  void test_inferedType_usesSyntheticFunctionType_positionalParam() {
+    var mainUnit = checkFile('''
+int f([int x]) => null;
+String g([int x]) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), 'List<([int]) → Object>');
+  }
+
+  void test_inferedType_usesSyntheticFunctionType_requiredParam() {
+    var mainUnit = checkFile('''
+int f(int x) => null;
+String g(int x) => null;
+var v = /*info:INFERRED_TYPE_LITERAL*/[f, g];
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), 'List<(int) → Object>');
+  }
+
   void test_inferenceInCyclesIsDeterministic() {
     addFile(
         '''
@@ -2143,6 +2246,39 @@
   ''');
   }
 
+  void test_inferred_nonstatic_field_depends_on_static_field_complex() {
+    var mainUnit = checkFile('''
+class C {
+  static var x = 'x';
+  var y = /*info:INFERRED_TYPE_LITERAL*/{
+    'a': /*info:INFERRED_TYPE_LITERAL*/{'b': 'c'},
+    'd': /*info:INFERRED_TYPE_LITERAL*/{'e': x}
+  };
+}
+''');
+    var x = mainUnit.getType('C').fields[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'String');
+    var y = mainUnit.getType('C').fields[1];
+    expect(y.name, 'y');
+    expect(y.type.toString(), 'Map<String, Map<String, String>>');
+  }
+
+  void test_inferred_nonstatic_field_depends_on_toplevel_var_simple() {
+    var mainUnit = checkFile('''
+var x = 'x';
+class C {
+  var y = x;
+}
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.name, 'x');
+    expect(x.type.toString(), 'String');
+    var y = mainUnit.getType('C').fields[0];
+    expect(y.name, 'y');
+    expect(y.type.toString(), 'String');
+  }
+
   void test_inferredInitializingFormalChecksDefaultValue() {
     checkFile('''
 class Foo {
@@ -2151,6 +2287,60 @@
 }''');
   }
 
+  void test_inferredType_blockBodiedClosure_noArguments() {
+    var mainUnit = checkFile('''
+class C {
+  static final v = () {};
+}
+''');
+    var v = mainUnit.getType('C').fields[0];
+    expect(v.type.toString(), '() → dynamic');
+  }
+
+  void test_inferredType_blockClosure_noArgs_noReturn() {
+    var mainUnit = checkFile('''
+var f = () {};
+''');
+    var f = mainUnit.topLevelVariables[0];
+    expect(f.type.toString(), '() → dynamic');
+  }
+
+  void test_inferredType_isEnum() {
+    var mainUnit = checkFile('''
+enum E { v1 }
+final x = E.v1;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.type.toString(), 'E');
+  }
+
+  void test_inferredType_isEnumValues() {
+    var mainUnit = checkFile('''
+enum E { v1 }
+final x = E.values;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.type.toString(), 'List<E>');
+  }
+
+  void test_inferredType_isTypedef() {
+    var mainUnit = checkFile('''
+typedef void F();
+final x = <String, F>{};
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.type.toString(), 'Map<String, () → void>');
+  }
+
+  void test_inferredType_isTypedef_parameterized() {
+    var mainUnit = checkFile('''
+typedef T F<T>();
+final x = <String, F<int>>{};
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.type.toString(), 'Map<String, () → int>');
+  }
+
   void test_inferStaticsTransitively() {
     addFile(
         '''
@@ -2667,6 +2857,22 @@
     expect(unit.topLevelVariables[0].type.toString(), 'A<int>');
   }
 
+  void test_instantiateToBounds_invokeConstructor_noBound() {
+    var unit = checkFile('''
+class C<T> {}
+var x = new C();
+''');
+    expect(unit.topLevelVariables[0].type.toString(), 'C<dynamic>');
+  }
+
+  void test_instantiateToBounds_invokeConstructor_typeArgsExact() {
+    var unit = checkFile('''
+class C<T extends num> {}
+var x = new C<int>();
+''');
+    expect(unit.topLevelVariables[0].type.toString(), 'C<int>');
+  }
+
   void test_instantiateToBounds_notGeneric() {
     var unit = checkFile(r'''
 class A {}
@@ -2912,6 +3118,109 @@
 ''');
   }
 
+  void test_referenceToFieldOfStaticField() {
+    var mainUnit = checkFile('''
+class C {
+  static D d;
+}
+class D {
+  int i;
+}
+final x = C.d.i;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.type.toString(), 'int');
+  }
+
+  void test_referenceToFieldOfStaticGetter() {
+    var mainUnit = checkFile('''
+class C {
+  static D get d => null;
+}
+class D {
+  int i;
+}
+final x = C.d.i;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.type.toString(), 'int');
+  }
+
+  void test_referenceToTypedef() {
+    var mainUnit = checkFile('''
+typedef void F();
+final x = F;
+''');
+    var x = mainUnit.topLevelVariables[0];
+    expect(x.type.toString(), 'Type');
+  }
+
+  void test_refineBinaryExpressionType_typeParameter_T_double() {
+    checkFile('''
+class C<T extends num> {
+  T a;
+
+  void op(double b) {
+    double r1 = a + b;
+    double r2 = a - b;
+    double r3 = a * b;
+    double r4 = a / b;
+  }
+}
+  ''');
+  }
+
+  void test_refineBinaryExpressionType_typeParameter_T_int() {
+    checkFile('''
+class C<T extends num> {
+  T a;
+
+  void op(int b) {
+    T r1 = a + b;
+    T r2 = a - b;
+    T r3 = a * b;
+  }
+
+  void opEq(int b) {
+    a += b;
+    a -= b;
+    a *= b;
+  }
+}
+  ''');
+  }
+
+  void test_refineBinaryExpressionType_typeParameter_T_T() {
+    checkFile('''
+class C<T extends num> {
+  T a;
+
+  void op(T b) {
+    T r1 = a + b;
+    T r2 = a - b;
+    T r3 = a * b;
+  }
+
+  void opEq(T b) {
+    a += b;
+    a -= b;
+    a *= b;
+  }
+}
+  ''');
+  }
+
+  void test_staticMethod_tearoff() {
+    var mainUnit = checkFile('''
+const v = C.f;
+class C {
+  static int f(String s) => null;
+}
+''');
+    var v = mainUnit.topLevelVariables[0];
+    expect(v.type.toString(), '(String) → int');
+  }
+
   void test_staticRefersToNonStaticField_inOtherLibraryCycle() {
     addFile(
         '''
@@ -2962,6 +3271,42 @@
 }
 ''');
   }
+
+  void test_typeInferenceDependency_staticVariable_inIdentifierSequence() {
+    // Check that type inference dependencies are properly checked when a static
+    // variable appears in the middle of a string of identifiers separated by
+    // '.'.
+    var mainUnit = checkFile('''
+final a = /*info:DYNAMIC_INVOKE*/C.d.i;
+class C {
+  static final d = new D(a);
+}
+class D {
+  D(_);
+  int i;
+}
+''');
+    // No type should be inferred for a because there is a circular reference
+    // between a and C.d.
+    var a = mainUnit.topLevelVariables[0];
+    expect(a.type.toString(), 'dynamic');
+  }
+
+  void test_typeInferenceDependency_topLevelVariable_inIdentifierSequence() {
+    // Check that type inference dependencies are properly checked when a top
+    // level variable appears at the beginning of a string of identifiers
+    // separated by '.'.
+    var mainUnit = checkFile('''
+final a = /*info:DYNAMIC_INVOKE*/c.i;
+final c = new C(a);
+class C {
+  C(_);
+  int i;
+}
+''');
+    // No type should be inferred for a because there is a circular reference
+    // between a and c.
+  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/tool/summary/dump_inferred_types.dart b/pkg/analyzer/tool/summary/dump_inferred_types.dart
index 8b38e73..a964675 100644
--- a/pkg/analyzer/tool/summary/dump_inferred_types.dart
+++ b/pkg/analyzer/tool/summary/dump_inferred_types.dart
@@ -18,8 +18,10 @@
   for (String arg in args) {
     PackageBundle bundle =
         new PackageBundle.fromBuffer(new File(arg).readAsBytesSync());
-    collector.visitPackageBundle(bundle);
+    collector.visitPackageBundle(bundle, arg);
   }
+  collector.dumpLibraryIndex();
+  collector.dumpPartIndex();
   collector.dumpCollectedTypes();
 }
 
@@ -32,6 +34,8 @@
   LinkedUnit linkedUnit;
   final Map<String, String> inferredTypes = <String, String>{};
   List<String> typeParamsInScope = <String>[];
+  final Map<String, Set<String>> libraryIndex = <String, Set<String>>{};
+  final Map<String, Set<String>> partIndex = <String, Set<String>>{};
 
   /**
    * If an inferred type exists matching the given [slot], record that it is the
@@ -63,6 +67,11 @@
       properties.remove('initializer');
     } else if (obj is UnlinkedExecutable) {
       collectInferredType(obj.inferredReturnTypeSlot, path);
+      // As a temporary measure, prevent recursion into the executable's local
+      // variables and local functions, since AST-based type inference doesn't
+      // infer locals correctly yet.  TODO(paulberry): fix if necessary.
+      properties.remove('localFunctions');
+      properties.remove('localVariables');
     } else if (obj is UnlinkedParam) {
       collectInferredType(obj.inferredTypeSlot, path);
       // As a temporary measure, prevent recursion into the parameter's
@@ -76,6 +85,7 @@
    * Print out all the inferred types collected so far, in alphabetical order.
    */
   void dumpCollectedTypes() {
+    print('Collected types (${inferredTypes.length}):');
     List<String> paths = inferredTypes.keys.toList();
     paths.sort();
     for (String path in paths) {
@@ -84,6 +94,38 @@
   }
 
   /**
+   * Print out an index mapping library names to the summary files containing
+   * them.
+   */
+  void dumpLibraryIndex() {
+    print('Library index:');
+    List<String> libraryNames = libraryIndex.keys.toList();
+    libraryNames.sort();
+    for (String libraryName in libraryNames) {
+      List<String> summaryFiles = libraryIndex[libraryName].toList();
+      summaryFiles.sort();
+      print('$libraryName -> ${summaryFiles.join(', ')}');
+    }
+    print('');
+  }
+
+  /**
+   * Print out an index mapping part file names to the summary files containing
+   * them.
+   */
+  void dumpPartIndex() {
+    print('Part index:');
+    List<String> partNames = partIndex.keys.toList();
+    partNames.sort();
+    for (String partName in partNames) {
+      List<String> summaryFiles = partIndex[partName].toList();
+      summaryFiles.sort();
+      print('$partName -> ${summaryFiles.join(', ')}');
+    }
+    print('');
+  }
+
+  /**
    * Interpret the given [param] as a parameter in a synthetic typedef, and
    * format it as a string.
    */
@@ -173,8 +215,12 @@
           typeParamsInScope.length - entityRef.paramReference];
     }
     String result = formatReference(entityRef.reference, typeOf: true);
-    if (entityRef.typeArguments.isNotEmpty) {
-      result += '<${entityRef.typeArguments.map(formatType).join(', ')}>';
+    List<EntityRef> typeArguments = entityRef.typeArguments.toList();
+    while (typeArguments.isNotEmpty && isDynamic(typeArguments.last)) {
+      typeArguments.removeLast();
+    }
+    if (typeArguments.isNotEmpty) {
+      result += '<${typeArguments.map(formatType).join(', ')}>';
     }
     if (implicitFunctionTypeIndices.isNotEmpty) {
       result =
@@ -184,6 +230,17 @@
   }
 
   /**
+   * Determine if the given [entityRef] represents the pseudo-type `dynamic`.
+   */
+  bool isDynamic(EntityRef entityRef) {
+    if (entityRef.syntheticReturnType != null ||
+        entityRef.paramReference != 0) {
+      return false;
+    }
+    return formatReference(entityRef.reference, typeOf: true) == 'dynamic';
+  }
+
+  /**
    * Collect all the inferred types contained in [obj], which is reachable via
    * [path].  [properties] is the result of calling `obj.toMap()`, and may be
    * modified before returning.
@@ -223,14 +280,18 @@
   /**
    * Collect all the inferred types contained in [bundle].
    */
-  void visitPackageBundle(PackageBundle bundle) {
+  void visitPackageBundle(PackageBundle bundle, String summaryPath) {
     Map<String, LinkedLibrary> linkedLibraries = <String, LinkedLibrary>{};
     Map<String, UnlinkedUnit> unlinkedUnits = <String, UnlinkedUnit>{};
     for (int i = 0; i < bundle.linkedLibraryUris.length; i++) {
       linkedLibraries[bundle.linkedLibraryUris[i]] = bundle.linkedLibraries[i];
     }
     for (int i = 0; i < bundle.unlinkedUnitUris.length; i++) {
-      unlinkedUnits[bundle.unlinkedUnitUris[i]] = bundle.unlinkedUnits[i];
+      String unitUriString = bundle.unlinkedUnitUris[i];
+      partIndex
+          .putIfAbsent(unitUriString, () => new Set<String>())
+          .add(summaryPath);
+      unlinkedUnits[unitUriString] = bundle.unlinkedUnits[i];
     }
     // Figure out which unlinked units are a part of another library so we won't
     // visit them redundantly.
@@ -248,6 +309,9 @@
       if (partOfUris.contains(libraryUriString)) {
         return;
       }
+      libraryIndex
+          .putIfAbsent(libraryUriString, () => new Set<String>())
+          .add(summaryPath);
       Uri libraryUri = Uri.parse(libraryUriString);
       UnlinkedUnit definingUnlinkedUnit = unlinkedUnits[libraryUriString];
       if (definingUnlinkedUnit != null) {
diff --git a/pkg/analyzer_cli/lib/src/analyzer_impl.dart b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
index b3e9398..6c4fbcd 100644
--- a/pkg/analyzer_cli/lib/src/analyzer_impl.dart
+++ b/pkg/analyzer_cli/lib/src/analyzer_impl.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart';
-import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/generated/utilities_general.dart';
@@ -25,8 +24,6 @@
 /// The maximum number of sources for which AST structures should be kept in the cache.
 const int _maxCacheSize = 512;
 
-DirectoryBasedDartSdk sdk;
-
 int currentTimeMillis() => new DateTime.now().millisecondsSinceEpoch;
 
 /// Analyzes single library [File].
diff --git a/pkg/analyzer_cli/lib/src/build_mode.dart b/pkg/analyzer_cli/lib/src/build_mode.dart
index e60ec09..d49a519 100644
--- a/pkg/analyzer_cli/lib/src/build_mode.dart
+++ b/pkg/analyzer_cli/lib/src/build_mode.dart
@@ -324,6 +324,11 @@
       // Parse the source and serialize its AST.
       Uri uri = Uri.parse(absoluteUri);
       Source source = context.sourceFactory.forUri2(uri);
+      if (!source.exists()) {
+        // TODO(paulberry): we should report a warning/error because DDC
+        // compilations are unlikely to work.
+        return null;
+      }
       return uriToUnit.putIfAbsent(uri, () {
         CompilationUnit unit = context.computeResult(source, PARSED_UNIT);
         UnlinkedUnitBuilder unlinkedUnit = serializeAstUnlinked(unit);
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 6a67547..aaff20d 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -73,9 +73,6 @@
   /// The plugins that are defined outside the `analyzer_cli` package.
   List<Plugin> _userDefinedPlugins = <Plugin>[];
 
-  /// Indicates whether the analyzer is running in batch mode.
-  bool _isBatch;
-
   /// The context that was most recently created by a call to [_analyzeAll], or
   /// `null` if [_analyzeAll] hasn't been called yet.
   AnalysisContext _context;
@@ -93,6 +90,9 @@
   @override
   ResolverProvider packageResolverProvider;
 
+  /// SDK instance.
+  DirectoryBasedDartSdk sdk;
+
   /// Collected analysis statistics.
   final AnalysisStats stats = new AnalysisStats();
 
@@ -120,9 +120,6 @@
     // Parse commandline options.
     CommandLineOptions options = CommandLineOptions.parse(args);
 
-    // Cache options of interest to inform analysis.
-    _setupEnv(options);
-
     // Do analysis.
     if (options.buildMode) {
       ErrorSeverity severity = _buildModeAnalyze(options);
@@ -130,7 +127,7 @@
       if (severity == ErrorSeverity.ERROR) {
         exitCode = severity.ordinal;
       }
-    } else if (_isBatch) {
+    } else if (options.shouldBatch) {
       _BatchRunner.runAsBatch(args, (List<String> args) {
         CommandLineOptions options = CommandLineOptions.parse(args);
         return _analyzeAll(options);
@@ -306,7 +303,7 @@
   /// [AnalyzeFunctionBodiesPredicate] that implements this policy.
   AnalyzeFunctionBodiesPredicate _chooseDietParsingPolicy(
       CommandLineOptions options) {
-    if (_isBatch) {
+    if (options.shouldBatch) {
       // As analyzer is currently implemented, once a file has been diet
       // parsed, it can't easily be un-diet parsed without creating a brand new
       // context and losing caching.  In batch mode, we can't predict which
@@ -507,19 +504,22 @@
     // Create a context.
     _context = AnalysisEngine.instance.createAnalysisContext();
 
-    // Choose a package resolution policy and a diet parsing policy based on
-    // the command-line options.
-    SourceFactory sourceFactory = _chooseUriResolutionPolicy(
-        options, (_context as InternalAnalysisContext).embedderYamlLocator);
     AnalyzeFunctionBodiesPredicate dietParsingPolicy =
         _chooseDietParsingPolicy(options);
-
-    _context.sourceFactory = sourceFactory;
-
     setAnalysisContextOptions(_context, options,
         (AnalysisOptionsImpl contextOptions) {
       contextOptions.analyzeFunctionBodiesPredicate = dietParsingPolicy;
     });
+
+    // Once options are processed, setup the SDK.
+    _setupSdk(options);
+
+    // Choose a package resolution policy and a diet parsing policy based on
+    // the command-line options.
+    SourceFactory sourceFactory = _chooseUriResolutionPolicy(
+        options, (_context as InternalAnalysisContext).embedderYamlLocator);
+
+    _context.sourceFactory = sourceFactory;
   }
 
   /// Return discovered packagespec, or `null` if none is found.
@@ -582,15 +582,17 @@
     return errorSeverity;
   }
 
-  void _setupEnv(CommandLineOptions options) {
-    // In batch mode, SDK is specified on the main command line rather than in
-    // the command lines sent to stdin.  So process it before deciding whether
-    // to activate batch mode.
+  void _setupSdk(CommandLineOptions options) {
     if (sdk == null) {
-      sdk = new DirectoryBasedDartSdk(new JavaFile(options.dartSdkPath));
-      sdk.analysisOptions = createAnalysisOptionsForCommandLineOptions(options);
+      String dartSdkPath = options.dartSdkPath;
+      sdk = new DirectoryBasedDartSdk(new JavaFile(dartSdkPath));
+      sdk.useSummary = options.sourceFiles.every((String sourcePath) {
+            sourcePath = path.absolute(sourcePath);
+            sourcePath = path.normalize(sourcePath);
+            return !path.isWithin(dartSdkPath, sourcePath);
+          });
+      sdk.analysisOptions = context.analysisOptions;
     }
-    _isBatch = options.shouldBatch;
   }
 
   static AnalysisOptionsImpl createAnalysisOptionsForCommandLineOptions(
diff --git a/pkg/analyzer_cli/lib/src/options.dart b/pkg/analyzer_cli/lib/src/options.dart
index 3f26109..ae8466c 100644
--- a/pkg/analyzer_cli/lib/src/options.dart
+++ b/pkg/analyzer_cli/lib/src/options.dart
@@ -508,7 +508,7 @@
         exitHandler(0);
         return null; // Only reachable in testing.
       } else {
-        if (results.rest.isEmpty) {
+        if (results.rest.isEmpty && !results['build-mode']) {
           _showUsage(parser);
           exitHandler(15);
           return null; // Only reachable in testing.
diff --git a/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options b/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
index 1d2a841..c0f4f1c 100644
--- a/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
+++ b/pkg/analyzer_cli/test/data/options_tests_project/.analysis_options
@@ -1,4 +1,5 @@
 analyzer:
+  strong-mode: true
   errors:
     unused_local_variable: ignore
     missing_return: error
diff --git a/pkg/analyzer_cli/test/driver_test.dart b/pkg/analyzer_cli/test/driver_test.dart
index 0b48331..6c85880 100644
--- a/pkg/analyzer_cli/test/driver_test.dart
+++ b/pkg/analyzer_cli/test/driver_test.dart
@@ -263,6 +263,15 @@
           doDrive();
           expect(driver.context.analysisOptions.enableSuperMixins, isTrue);
         });
+
+        test('strongMode', () {
+          doDrive();
+          expect(driver.context.analysisOptions.strongMode, isTrue);
+          //https://github.com/dart-lang/sdk/issues/26129
+          AnalysisContext sdkContext =
+              driver.context.sourceFactory.dartSdk.context;
+          expect(sdkContext.analysisOptions.strongMode, isTrue);
+        });
       });
 
       group('with flags', () {
diff --git a/pkg/analyzer_cli/test/options_test.dart b/pkg/analyzer_cli/test/options_test.dart
index 620c047..29bde19 100644
--- a/pkg/analyzer_cli/test/options_test.dart
+++ b/pkg/analyzer_cli/test/options_test.dart
@@ -257,6 +257,12 @@
     expect(options.buildMode, isTrue);
   }
 
+  test_buildMode_allowsEmptyFileList() {
+    _parse(['--build-mode']);
+    expect(options.buildMode, isTrue);
+    expect(options.sourceFiles, isEmpty);
+  }
+
   test_buildSummaryFallback() {
     _parse([
       '--build-mode',
diff --git a/pkg/compiler/lib/src/common/resolution.dart b/pkg/compiler/lib/src/common/resolution.dart
index 0b9f990..250a038 100644
--- a/pkg/compiler/lib/src/common/resolution.dart
+++ b/pkg/compiler/lib/src/common/resolution.dart
@@ -57,6 +57,8 @@
   Iterable<ConstantExpression> get constantLiterals {
     return const <ConstantExpression>[];
   }
+
+  Iterable<dynamic> get nativeData => const <dynamic>[];
 }
 
 /// A language feature seen during resolution.
diff --git a/pkg/compiler/lib/src/compile_time_constants.dart b/pkg/compiler/lib/src/compile_time_constants.dart
index 629d457..724e6f6 100644
--- a/pkg/compiler/lib/src/compile_time_constants.dart
+++ b/pkg/compiler/lib/src/compile_time_constants.dart
@@ -29,6 +29,9 @@
   /// The [ConstantSystem] used by this environment.
   ConstantSystem get constantSystem;
 
+  /// Returns `true` if a value has been computed for [expression].
+  bool hasConstantValue(ConstantExpression expression);
+
   /// Returns the constant value computed for [expression].
   // TODO(johnniwinther): Support directly evaluation of [expression].
   ConstantValue getConstantValue(ConstantExpression expression);
@@ -287,6 +290,10 @@
     return null;
   }
 
+  bool hasConstantValue(ConstantExpression expression) {
+    return constantValueMap.containsKey(expression);
+  }
+
   ConstantValue getConstantValue(ConstantExpression expression) {
     return constantValueMap[expression];
   }
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 4aa08fd..7dbee2a 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -1932,15 +1932,12 @@
   ResolvedAst getResolvedAst(ExecutableElement element) {
     assert(invariant(element, element.isDeclaration,
         message: "Element $element must be the declaration."));
-    if (hasResolvedAst(element)) {
-      if (compiler.serialization.isDeserialized(element)) {
-        return compiler.serialization.getResolvedAst(element);
-      }
-      return element.resolvedAst;
-    }
     assert(invariant(element, hasResolvedAst(element),
         message: "ResolvedAst not available for $element."));
-    return null;
+    if (compiler.serialization.isDeserialized(element)) {
+      return compiler.serialization.getResolvedAst(element);
+    }
+    return element.resolvedAst;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/constants/expressions.dart b/pkg/compiler/lib/src/constants/expressions.dart
index 4019e16..3b4317f 100644
--- a/pkg/compiler/lib/src/constants/expressions.dart
+++ b/pkg/compiler/lib/src/constants/expressions.dart
@@ -124,6 +124,21 @@
         'ConstantExpression.toString()');
     return toDartText();
   }
+
+  /// Returns `true` if this expression is implicitly constant, that is, that
+  /// it doesn't declare its constness with the 'const' keyword.
+  ///
+  /// Implicit constants are simple literals, like bool, int and string
+  /// literals, constant references and compositions of implicit constants.
+  /// Explicit constants are constructor constants, and constant map and list
+  /// literals.
+  bool get isImplicit => true;
+
+  /// Returns `true` if this expression is only potentially constant, that is,
+  /// if it contains positional or named references, used to define constant
+  /// constructors.
+  // TODO(johnniwinther): Maybe make this final if we use it outside assertions.
+  bool get isPotential => true;
 }
 
 /// A synthetic constant used to recover from errors.
@@ -183,6 +198,12 @@
   }
 
   ConstantExpressionKind get kind => ConstantExpressionKind.SYNTHETIC;
+
+  @override
+  bool get isPotential => false;
+
+  @override
+  bool get isImplicit => false;
 }
 
 /// A boolean, int, double, string, or null constant.
@@ -422,6 +443,12 @@
 
   @override
   DartType getKnownType(CoreTypes coreTypes) => type;
+
+  @override
+  bool get isImplicit => false;
+
+  @override
+  bool get isPotential => values.any((e) => e.isPotential);
 }
 
 /// Literal map constant.
@@ -491,6 +518,14 @@
 
   @override
   DartType getKnownType(CoreTypes coreTypes) => type;
+
+  @override
+  bool get isImplicit => false;
+
+  @override
+  bool get isPotential {
+    return keys.any((e) => e.isPotential) || values.any((e) => e.isPotential);
+  }
 }
 
 /// Invocation of a const constructor.
@@ -571,6 +606,14 @@
     }
     return true;
   }
+
+  @override
+  bool get isImplicit => false;
+
+  @override
+  bool get isPotential {
+    return arguments.any((e) => e.isPotential);
+  }
 }
 
 /// String literal with juxtaposition and/or interpolations.
@@ -650,6 +693,11 @@
 
   @override
   DartType getKnownType(CoreTypes coreTypes) => coreTypes.stringType;
+
+  @override
+  bool get isPotential {
+    return expressions.any((e) => e.isPotential);
+  }
 }
 
 /// Symbol literal.
@@ -895,6 +943,11 @@
         right == other.right;
   }
 
+  @override
+  bool get isPotential {
+    return left.isPotential || right.isPotential;
+  }
+
   static const Map<BinaryOperatorKind, int> PRECEDENCE_MAP = const {
     BinaryOperatorKind.EQ: 6,
     BinaryOperatorKind.NOT_EQ: 6,
@@ -968,6 +1021,11 @@
 
   @override
   DartType getKnownType(CoreTypes coreTypes) => coreTypes.boolType;
+
+  @override
+  bool get isPotential {
+    return left.isPotential || right.isPotential;
+  }
 }
 
 /// A unary constant expression like `-a`.
@@ -1021,6 +1079,11 @@
     return expression.getKnownType(coreTypes);
   }
 
+  @override
+  bool get isPotential {
+    return expression.isPotential;
+  }
+
   static const Map<UnaryOperatorKind, int> PRECEDENCE_MAP = const {
     UnaryOperatorKind.NOT: 14,
     UnaryOperatorKind.COMPLEMENT: 14,
@@ -1076,6 +1139,11 @@
 
   @override
   DartType getKnownType(CoreTypes coreTypes) => coreTypes.intType;
+
+  @override
+  bool get isPotential {
+    return expression.isPotential;
+  }
 }
 
 /// A constant conditional expression like `a ? b : c`.
@@ -1149,6 +1217,11 @@
     }
     return null;
   }
+
+  @override
+  bool get isPotential {
+    return condition.isPotential || trueExp.isPotential || falseExp.isPotential;
+  }
 }
 
 /// A reference to a position parameter.
@@ -1185,6 +1258,11 @@
       Environment environment, ConstantSystem constantSystem) {
     throw new UnsupportedError('PositionalArgumentReference.evaluate');
   }
+
+  @override
+  bool get isPotential {
+    return true;
+  }
 }
 
 /// A reference to a named parameter.
@@ -1221,6 +1299,11 @@
       Environment environment, ConstantSystem constantSystem) {
     throw new UnsupportedError('NamedArgumentReference.evaluate');
   }
+
+  @override
+  bool get isPotential {
+    return true;
+  }
 }
 
 abstract class FromEnvironmentConstantExpression extends ConstantExpression {
@@ -1238,6 +1321,17 @@
   bool _equals(FromEnvironmentConstantExpression other) {
     return name == other.name && defaultValue == other.defaultValue;
   }
+
+  @override
+  bool get isImplicit {
+    return false;
+  }
+
+  @override
+  bool get isPotential {
+    return name.isPotential ||
+        (defaultValue != null && defaultValue.isPotential);
+  }
 }
 
 /// A `const bool.fromEnvironment` constant.
@@ -1471,6 +1565,11 @@
   accept(ConstantExpressionVisitor visitor, [context]) {
     return visitor.visitDeferred(this, context);
   }
+
+  @override
+  bool get isPotential {
+    return expression.isPotential;
+  }
 }
 
 abstract class ConstantExpressionVisitor<R, A> {
diff --git a/pkg/compiler/lib/src/dart_backend/backend.dart b/pkg/compiler/lib/src/dart_backend/backend.dart
index d8cef91..5f3eed9 100644
--- a/pkg/compiler/lib/src/dart_backend/backend.dart
+++ b/pkg/compiler/lib/src/dart_backend/backend.dart
@@ -465,6 +465,11 @@
   ConstantSystem get constantSystem => constantCompiler.constantSystem;
 
   @override
+  bool hasConstantValue(ConstantExpression expression) {
+    return constantCompiler.hasConstantValue(expression);
+  }
+
+  @override
   ConstantValue getConstantValue(ConstantExpression expression) {
     return constantCompiler.getConstantValue(expression);
   }
diff --git a/pkg/compiler/lib/src/deferred_load.dart b/pkg/compiler/lib/src/deferred_load.dart
index b75a6ab..bbd91ae 100644
--- a/pkg/compiler/lib/src/deferred_load.dart
+++ b/pkg/compiler/lib/src/deferred_load.dart
@@ -336,14 +336,29 @@
         TreeElements treeElements = analyzableElement.resolvedAst.elements;
         assert(treeElements != null);
 
+        // TODO(johnniwinther): Add only expressions that are actually needed.
+        // Currently we have some noise here: Some potential expressions are
+        // seen that should never be added (for instance field initializers
+        // in constant constructors, like `this.field = parameter`). And some
+        // implicit constant expression are seen that we should be able to add
+        // (like primitive constant literals like `true`, `"foo"` and `0`).
+        // See dartbug.com/26406 for context.
         treeElements
             .forEachConstantNode((Node node, ConstantExpression expression) {
           // Explicitly depend on the backend constants.
-          ConstantValue value = backend.constants.getConstantValue(expression);
-          assert(invariant(node, value != null,
-              message:
-                  "No constant value for ${expression.toStructuredText()}."));
-          constants.add(value);
+          if (backend.constants.hasConstantValue(expression)) {
+            ConstantValue value =
+                backend.constants.getConstantValue(expression);
+            assert(invariant(node, value != null,
+                message: "Constant expression without value: "
+                         "${expression.toStructuredText()}."));
+            constants.add(value);
+          } else {
+            assert(invariant(node,
+                expression.isImplicit || expression.isPotential,
+                message: "Unexpected unevaluated constant expression: "
+                    "${expression.toStructuredText()}."));
+          }
         });
       }
     }
diff --git a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
index 62a9efd..1cac7aa 100644
--- a/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
+++ b/pkg/compiler/lib/src/inferrer/type_graph_inferrer.dart
@@ -856,6 +856,9 @@
             if (constant != null) {
               ConstantValue value =
                   compiler.backend.constants.getConstantValue(constant);
+              assert(invariant(fieldElement, value != null,
+                  message: "Constant expression without value: "
+                           "${constant.toStructuredText()}."));
               if (value.isFunction) {
                 FunctionConstantValue functionConstant = value;
                 type = types.allocateClosure(node, functionConstant.element);
diff --git a/pkg/compiler/lib/src/js_backend/backend.dart b/pkg/compiler/lib/src/js_backend/backend.dart
index f5eac4a..15b8de4 100644
--- a/pkg/compiler/lib/src/js_backend/backend.dart
+++ b/pkg/compiler/lib/src/js_backend/backend.dart
@@ -1477,6 +1477,9 @@
       ConstantExpression constant = variableElement.constant;
       if (constant != null) {
         ConstantValue initialValue = constants.getConstantValue(constant);
+        assert(invariant(variableElement, initialValue != null,
+            message: "Constant expression without value: "
+                "${constant.toStructuredText()}."));
         registerCompileTimeConstant(initialValue, work.registry);
         addCompileTimeConstantForEmission(initialValue);
         // We don't need to generate code for static or top-level
@@ -2623,6 +2626,11 @@
 
   BackendImpacts get impacts => backend.impacts;
 
+  // TODO(johnniwinther): Avoid this dependency.
+  ResolutionEnqueuer get resolutionEnqueuer {
+    return backend.compiler.enqueuer.resolution;
+  }
+
   @override
   WorldImpact transformResolutionImpact(ResolutionImpact worldImpact) {
     TransformedWorldImpact transformed =
@@ -2782,8 +2790,7 @@
         registerBackendImpact(transformed, impacts.closure);
         LocalFunctionElement closure = staticUse.element;
         if (closure.type.containsTypeVariables) {
-          backend.compiler.enqueuer.resolution.universe
-              .closuresWithFreeTypeVariables
+          resolutionEnqueuer.universe.closuresWithFreeTypeVariables
               .add(closure);
           registerBackendImpact(transformed, impacts.computeSignature);
         }
@@ -2813,6 +2820,11 @@
       }
     }
 
+    for (native.NativeBehavior behavior in worldImpact.nativeData) {
+      resolutionEnqueuer.nativeEnqueuer
+          .registerNativeBehavior(behavior, worldImpact);
+    }
+
     return transformed;
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
index 2383662..5aefd39 100644
--- a/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_handler_javascript.dart
@@ -26,6 +26,11 @@
   ConstantSystem get constantSystem => dartConstantCompiler.constantSystem;
 
   @override
+  bool hasConstantValue(ConstantExpression expression) {
+    return dartConstantCompiler.hasConstantValue(expression);
+  }
+
+  @override
   ConstantValue getConstantValue(ConstantExpression expression) {
     return dartConstantCompiler.getConstantValue(expression);
   }
@@ -249,7 +254,11 @@
   ConstantValue getConstantValue(ConstantExpression expression) {
     assert(invariant(CURRENT_ELEMENT_SPANNABLE, expression != null,
         message: "ConstantExpression is null in getConstantValue."));
-    evaluate(expression);
+    // TODO(johhniwinther): ensure expressions have been evaluated at this
+    // point. This can't be enabled today due to dartbug.com/26406.
+    if (compiler.serialization.supportsDeserialization) {
+      evaluate(expression);
+    }
     ConstantValue value = super.getConstantValue(expression);
     if (value == null &&
         expression != null &&
diff --git a/pkg/compiler/lib/src/native/enqueue.dart b/pkg/compiler/lib/src/native/enqueue.dart
index c04509b..e15f185 100644
--- a/pkg/compiler/lib/src/native/enqueue.dart
+++ b/pkg/compiler/lib/src/native/enqueue.dart
@@ -606,11 +606,8 @@
    *
    */
   NativeBehavior resolveJsCall(Send node, ForeignResolver resolver) {
-    NativeBehavior behavior = NativeBehavior.ofJsCall(
+    return NativeBehavior.ofJsCall(
         node, reporter, compiler.parsingContext, compiler.coreTypes, resolver);
-    // TODO(johnniwinther): Move registration to the world impact application.
-    registerNativeBehavior(behavior, node);
-    return behavior;
   }
 
   /**
@@ -624,11 +621,8 @@
    */
   NativeBehavior resolveJsEmbeddedGlobalCall(
       Send node, ForeignResolver resolver) {
-    NativeBehavior behavior = NativeBehavior.ofJsEmbeddedGlobalCall(
+    return NativeBehavior.ofJsEmbeddedGlobalCall(
         node, reporter, compiler.parsingContext, compiler.coreTypes, resolver);
-    // TODO(johnniwinther): Move registration to the world impact application.
-    registerNativeBehavior(behavior, node);
-    return behavior;
   }
 
   /**
@@ -641,11 +635,8 @@
    *
    */
   NativeBehavior resolveJsBuiltinCall(Send node, ForeignResolver resolver) {
-    NativeBehavior behavior = NativeBehavior.ofJsBuiltinCall(
+    return NativeBehavior.ofJsBuiltinCall(
         node, reporter, compiler.parsingContext, compiler.coreTypes, resolver);
-    // TODO(johnniwinther): Move registration to the world impact application.
-    registerNativeBehavior(behavior, node);
-    return behavior;
   }
 }
 
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index 9a81401..c9c60f69 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -38,5 +38,7 @@
     return _allowedDartSchemePaths.contains(uri.path);
   }
 
-  return allowedTestLibrary() || allowedDartLibary();
+  return allowedTestLibrary() ||
+      allowedDartLibary() ||
+      compiler.options.allowNativeExtensions;
 }
diff --git a/pkg/compiler/lib/src/parser/element_listener.dart b/pkg/compiler/lib/src/parser/element_listener.dart
index 0cd21ac..6fe019c 100644
--- a/pkg/compiler/lib/src/parser/element_listener.dart
+++ b/pkg/compiler/lib/src/parser/element_listener.dart
@@ -755,7 +755,8 @@
     throw new ParserError(message);
   }
 
-  void reportError(Spannable spannable, MessageKind errorCode,
+  @override
+  void reportErrorHelper(Spannable spannable, MessageKind errorCode,
       [Map arguments = const {}]) {
     if (currentMemberHasParseError) return; // Error already reported.
     if (suppressParseErrors) return;
diff --git a/pkg/compiler/lib/src/parser/listener.dart b/pkg/compiler/lib/src/parser/listener.dart
index 1294bf1..afd2997 100644
--- a/pkg/compiler/lib/src/parser/listener.dart
+++ b/pkg/compiler/lib/src/parser/listener.dart
@@ -548,6 +548,15 @@
 
   void reportError(Spannable spannable, MessageKind messageKind,
       [Map arguments = const {}]) {
+    if (spannable is ErrorToken) {
+      reportErrorToken(spannable);
+    } else {
+      reportErrorHelper(spannable, messageKind, arguments);
+    }
+  }
+
+  void reportErrorHelper(Spannable spannable, MessageKind messageKind,
+      [Map arguments = const {}]) {
     MessageTemplate template = MessageTemplate.TEMPLATES[messageKind];
     String message = template.message(arguments, true).toString();
     Token token;
@@ -568,7 +577,7 @@
         String padding = "0000".substring(hex.length);
         hex = "$padding$hex";
       }
-      reportError(
+      reportErrorHelper(
           token, MessageKind.BAD_INPUT_CHARACTER, {'characterHex': hex});
     } else if (token is UnterminatedToken) {
       MessageKind kind;
@@ -601,11 +610,11 @@
           kind = MessageKind.UNTERMINATED_TOKEN;
           break;
       }
-      reportError(token, kind, arguments);
+      reportErrorHelper(token, kind, arguments);
     } else if (token is UnmatchedToken) {
       String begin = token.begin.value;
       String end = closeBraceFor(begin);
-      reportError(
+      reportErrorHelper(
           token, MessageKind.UNMATCHED_TOKEN, {'begin': begin, 'end': end});
     } else {
       throw new SpannableAssertionFailure(token, token.assertionMessage);
diff --git a/pkg/compiler/lib/src/resolution/registry.dart b/pkg/compiler/lib/src/resolution/registry.dart
index 7008c9a..7de89c2 100644
--- a/pkg/compiler/lib/src/resolution/registry.dart
+++ b/pkg/compiler/lib/src/resolution/registry.dart
@@ -36,6 +36,7 @@
   Setlet<ListLiteralUse> _listLiterals;
   Setlet<String> _constSymbolNames;
   Setlet<ConstantExpression> _constantLiterals;
+  Setlet<dynamic> _nativeData;
 
   _ResolutionWorldImpact(this.name);
 
@@ -104,6 +105,19 @@
         : const <ConstantExpression>[];
   }
 
+  void registerNativeData(dynamic nativeData) {
+    assert(nativeData != null);
+    if (_nativeData == null) {
+      _nativeData = new Setlet<dynamic>();
+    }
+    _nativeData.add(nativeData);
+  }
+
+  @override
+  Iterable<dynamic> get nativeData {
+    return _nativeData != null ? _nativeData : const <dynamic>[];
+  }
+
   String toString() {
     StringBuffer sb = new StringBuffer();
     sb.write('_ResolutionWorldImpact($name)');
@@ -359,7 +373,9 @@
     var nativeData = backend.resolveForeignCall(node, element, callStructure,
         new ForeignResolutionResolver(visitor, this));
     if (nativeData != null) {
+      // Split impact from resolution result.
       mapping.registerNativeData(node, nativeData);
+      worldImpact.registerNativeData(nativeData);
     }
   }
 
diff --git a/pkg/compiler/lib/src/serialization/equivalence.dart b/pkg/compiler/lib/src/serialization/equivalence.dart
index 969ef40..be8ff7f 100644
--- a/pkg/compiler/lib/src/serialization/equivalence.dart
+++ b/pkg/compiler/lib/src/serialization/equivalence.dart
@@ -276,6 +276,13 @@
   }
 }
 
+/// Returns `true` if nodes [a] and [b] are equivalent.
+bool areNodesEquivalent(Node node1, Node node2) {
+  if (identical(node1, node2)) return true;
+  if (node1 == null || node2 == null) return false;
+  return node1.accept1(const NodeEquivalenceVisitor(), node2);
+}
+
 /// Strategy for testing equivalence.
 ///
 /// Use this strategy to determine equivalence without failing on inequivalence.
@@ -323,6 +330,11 @@
       List<ConstantExpression> list1, List<ConstantExpression> list2) {
     return areConstantListsEquivalent(list1, list2);
   }
+
+  bool testNodes(
+      Object object1, Object object2, String property, Node node1, Node node2) {
+    return areNodesEquivalent(node1, node2);
+  }
 }
 
 /// Visitor that checks for equivalence of [Element]s.
@@ -765,15 +777,33 @@
     // Nothing more to check.
     return true;
   }
-  return strategy.testElements(resolvedAst1, resolvedAst2, 'element',
+  bool result = strategy.testElements(resolvedAst1, resolvedAst2, 'element',
           resolvedAst1.element, resolvedAst2.element) &&
-      new NodeEquivalenceVisitor(strategy).testNodes(resolvedAst1, resolvedAst2,
-          'node', resolvedAst1.node, resolvedAst2.node) &&
-      new NodeEquivalenceVisitor(strategy).testNodes(resolvedAst1, resolvedAst2,
-          'body', resolvedAst1.body, resolvedAst2.body) &&
+      strategy.testNodes(resolvedAst1, resolvedAst2, 'node', resolvedAst1.node,
+          resolvedAst2.node) &&
+      strategy.testNodes(resolvedAst1, resolvedAst2, 'body', resolvedAst1.body,
+          resolvedAst2.body) &&
       testTreeElementsEquivalence(resolvedAst1, resolvedAst2, strategy) &&
       strategy.test(resolvedAst1, resolvedAst2, 'sourceUri',
           resolvedAst1.sourceUri, resolvedAst2.sourceUri);
+  if (resolvedAst1.element is FunctionElement) {
+    FunctionElement element1 = resolvedAst1.element;
+    FunctionElement element2 = resolvedAst2.element;
+    for (int index = 0; index < element1.parameters.length; index++) {
+      var parameter1 = element1.parameters[index];
+      var parameter2 = element2.parameters[index];
+      result = result &&
+          strategy.testNodes(parameter1, parameter2, 'node',
+              parameter1.implementation.node, parameter2.implementation.node) &&
+          strategy.testNodes(
+              parameter1,
+              parameter2,
+              'initializer',
+              parameter1.implementation.initializer,
+              parameter2.implementation.initializer);
+    }
+  }
+  return result;
 }
 
 /// Tests the equivalence of the data stored in the [TreeElements] of
diff --git a/pkg/compiler/lib/src/serialization/impact_serialization.dart b/pkg/compiler/lib/src/serialization/impact_serialization.dart
index 7e74259..b2aa0455 100644
--- a/pkg/compiler/lib/src/serialization/impact_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/impact_serialization.dart
@@ -25,8 +25,10 @@
   final ListEncoder staticUses;
   final ListEncoder dynamicUses;
   final ListEncoder typeUses;
+  final SerializerPlugin nativeDataSerializer;
 
-  ImpactSerializer(this.element, ObjectEncoder objectEncoder)
+  ImpactSerializer(
+      this.element, ObjectEncoder objectEncoder, this.nativeDataSerializer)
       : this.objectEncoder = objectEncoder,
         staticUses = objectEncoder.createList(Key.STATIC_USES),
         dynamicUses = objectEncoder.createList(Key.DYNAMIC_USES),
@@ -56,6 +58,12 @@
         useEncoder.setBool(Key.IS_EMPTY, use.isEmpty);
       }
     }
+    if (resolutionImpact.nativeData.isNotEmpty) {
+      ListEncoder encoder = objectEncoder.createList(Key.NATIVE);
+      for (dynamic data in resolutionImpact.nativeData) {
+        nativeDataSerializer.onData(data, encoder.createObject());
+      }
+    }
   }
 
   @override
@@ -91,6 +99,7 @@
   final Iterable<MapLiteralUse> mapLiterals;
   final Iterable<StaticUse> staticUses;
   final Iterable<TypeUse> typeUses;
+  final Iterable<dynamic> nativeData;
 
   DeserializedResolutionImpact(
       {this.constSymbolNames: const <String>[],
@@ -100,7 +109,8 @@
       this.listLiterals: const <ListLiteralUse>[],
       this.mapLiterals: const <MapLiteralUse>[],
       this.staticUses: const <StaticUse>[],
-      this.typeUses: const <TypeUse>[]})
+      this.typeUses: const <TypeUse>[],
+      this.nativeData: const <dynamic>[]})
       : this._features = features;
 
   Iterable<Feature> get features {
@@ -112,8 +122,8 @@
 
 class ImpactDeserializer {
   /// Deserializes a [WorldImpact] from [objectDecoder].
-  static ResolutionImpact deserializeImpact(
-      Element element, ObjectDecoder objectDecoder) {
+  static ResolutionImpact deserializeImpact(Element element,
+      ObjectDecoder objectDecoder, DeserializerPlugin nativeDataDeserializer) {
     ListDecoder staticUseDecoder = objectDecoder.getList(Key.STATIC_USES);
     List<StaticUse> staticUses = <StaticUse>[];
     for (int index = 0; index < staticUseDecoder.length; index++) {
@@ -180,6 +190,20 @@
       }
     }
 
+    ListDecoder nativeDataDecoder =
+        objectDecoder.getList(Key.NATIVE, isOptional: true);
+    List<dynamic> nativeData = const <dynamic>[];
+    if (nativeDataDecoder != null) {
+      nativeData = <dynamic>[];
+      for (int i = 0; i < nativeDataDecoder.length; i++) {
+        dynamic data =
+            nativeDataDeserializer.onData(nativeDataDecoder.getObject(i));
+        if (data != null) {
+          nativeData.add(data);
+        }
+      }
+    }
+
     return new DeserializedResolutionImpact(
         constSymbolNames: constSymbolNames,
         constantLiterals: constantLiterals,
@@ -188,6 +212,7 @@
         listLiterals: listLiterals,
         mapLiterals: mapLiterals,
         staticUses: staticUses,
-        typeUses: typeUses);
+        typeUses: typeUses,
+        nativeData: nativeData);
   }
 }
diff --git a/pkg/compiler/lib/src/serialization/modelz.dart b/pkg/compiler/lib/src/serialization/modelz.dart
index b280d69..7772956 100644
--- a/pkg/compiler/lib/src/serialization/modelz.dart
+++ b/pkg/compiler/lib/src/serialization/modelz.dart
@@ -1867,13 +1867,13 @@
   @override
   FunctionSignature get functionSignature => _unsupported('functionSignature');
 
-  // TODO(johnniwinther): HACK. Remove [initializer] and [node] on
+  // TODO(johnniwinther): Remove [initializer] and [node] on
   // [ParameterElementZ] when the inference does need these.
   @override
-  Expression get initializer => null;
+  Expression initializer;
 
   @override
-  Node get node => null;
+  Node node;
 
   @override
   bool get isNamed => _decoder.getBool(Key.IS_NAMED);
diff --git a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
index 613bd61..633b65e 100644
--- a/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
+++ b/pkg/compiler/lib/src/serialization/resolved_ast_serialization.dart
@@ -22,6 +22,7 @@
 import '../universe/selector.dart';
 import '../util/util.dart';
 import 'keys.dart';
+import 'modelz.dart';
 import 'serialization.dart';
 import 'serialization_util.dart';
 
@@ -165,6 +166,19 @@
         serializeLabelDefinition(labelDefinition, list.createObject());
       }
     }
+    if (element is FunctionElement) {
+      FunctionElement function = element;
+      function.functionSignature.forEachParameter((ParameterElement parameter) {
+        ParameterElement parameterImpl = parameter.implementation;
+        // TODO(johnniwinther): Should we support element->node mapping as well?
+        getNodeDataEncoder(parameterImpl.node)
+            .setElement(PARAMETER_NODE, parameter);
+        if (parameter.initializer != null) {
+          getNodeDataEncoder(parameterImpl.initializer)
+              .setElement(PARAMETER_INITIALIZER, parameter);
+        }
+      });
+    }
   }
 
   /// Serialize [target] into [encoder].
@@ -203,7 +217,9 @@
 
   /// Computes the [ObjectEncoder] for serializing data for [node].
   ObjectEncoder getNodeDataEncoder(Node node) {
+    assert(invariant(element, node != null, message: "Node must be non-null."));
     int id = nodeIndices[node];
+    assert(invariant(element, id != null, message: "Node without id: $node"));
     return nodeData.putIfAbsent(id, () {
       ObjectEncoder objectEncoder = nodeDataEncoder.createObject();
       objectEncoder.setInt(Key.ID, id);
@@ -650,6 +666,18 @@
           resolvedAstMap[function] = new ParsedResolvedAst(function,
               functionExpression, functionExpression.body, elements, uri);
         }
+        // TODO(johnniwinther): Remove these when inference doesn't need `.node`
+        // and `.initializer` of [ParameterElement]s.
+        ParameterElementZ parameter =
+            objectDecoder.getElement(PARAMETER_NODE, isOptional: true);
+        if (parameter != null) {
+          parameter.node = node;
+        }
+        parameter =
+            objectDecoder.getElement(PARAMETER_INITIALIZER, isOptional: true);
+        if (parameter != null) {
+          parameter.initializer = node;
+        }
       }
     }
     assert(invariant(element, !resolvedAstMap.containsKey(element),
@@ -658,3 +686,6 @@
         new ParsedResolvedAst(element, root, body, elements, uri);
   }
 }
+
+const Key PARAMETER_NODE = const Key('parameter.node');
+const Key PARAMETER_INITIALIZER = const Key('parameter.initializer');
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 1639c32..6ca4636 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -34,6 +34,9 @@
   // retained, for instance impacts, resolution data etc.
   bool supportSerialization = false;
 
+  /// If `true`, deserialized data is supported.
+  bool get supportsDeserialization => deserializer != null;
+
   /// Returns the [LibraryElement] for [resolvedUri] if available from
   /// serialization.
   Future<LibraryElement> readLibrary(Uri resolvedUri) {
diff --git a/pkg/meta/.analysis_options b/pkg/meta/.analysis_options
new file mode 100644
index 0000000..a10d4c5
--- /dev/null
+++ b/pkg/meta/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+  strong-mode: true
diff --git a/pkg/pkg.status b/pkg/pkg.status
index c991ab2..a78a08d6c 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -22,6 +22,9 @@
 [ $runtime == vm && $mode == debug ]
 analysis_server/test/completion_test: Pass, Slow
 
+[ $runtime == vm && $checked ]
+analysis_server/test/completion_test: Pass, Slow
+
 [ $runtime == vm && $system == windows]
 analysis_server/test/analysis/get_errors_test: Skip # runtime error, Issue 22180
 analysis_server/test/integration/analysis/analysis_options_test: RuntimeError # Issue 24796
diff --git a/runtime/BUILD.gn b/runtime/BUILD.gn
index bd091d9a..ad030b8 100644
--- a/runtime/BUILD.gn
+++ b/runtime/BUILD.gn
@@ -26,6 +26,8 @@
   # this unspecified results in automatic target architecture detection.
   # Available options are: arm, arm64, mips, x64 and ia32
   dart_target_arch = ""
+
+  dart_experimental_interpreter = false
 }
 
 config("dart_public_config") {
@@ -70,13 +72,19 @@
       print("Debug and release mode are mutually exclusive.")
     }
     assert(!dart_debug)
-    defines += ["DART_PRECOMPILED_RUNTIME"]
+
+    if (!dart_experimental_interpreter) {
+      defines += ["DART_PRECOMPILED_RUNTIME"]
+    }
   } else if (dart_runtime_mode == "profile") {
     if (dart_debug) {
       print("Debug and profile mode are mutually exclusive.")
     }
     assert(!dart_debug)
-    defines += ["DART_PRECOMPILED_RUNTIME"]
+
+    if (!dart_experimental_interpreter) {
+      defines += ["DART_PRECOMPILED_RUNTIME"]
+    }
   }
 }
 
@@ -89,6 +97,10 @@
 config("dart_config") {
   defines = []
 
+  if (dart_experimental_interpreter) {
+    dart_target_arch = "dbc"
+  }
+
   if (dart_target_arch != "") {
     if (dart_target_arch == "arm") {
       defines += [ "TARGET_ARCH_ARM" ]
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index b5ce6e6..bff1387 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -5,6 +5,7 @@
 
 declare_args() {
   dart_io_support = false
+  dart_boringssl_path = "../../third_party/boringssl"
 }
 
 
@@ -330,7 +331,7 @@
     ]
   } else {
     deps = [
-      "../../third_party/boringssl",
+      rebase_path(dart_boringssl_path, "."),
     ]
   }
 
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 0018712..3905ad7 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -8,6 +8,18 @@
 
     'io_cc_file': '<(gen_source_dir)/io_gen.cc',
     'io_patch_cc_file': '<(gen_source_dir)/io_patch_gen.cc',
+    'html_cc_file': '<(gen_source_dir)/html_gen.cc',
+    'html_common_cc_file': '<(gen_source_dir)/html_common_gen.cc',
+    'js_cc_file': '<(gen_source_dir)/js_gen.cc',
+    'blink_cc_file': '<(gen_source_dir)/blink_gen.cc',
+    'indexeddb_cc_file': '<(gen_source_dir)/indexeddb_gen.cc',
+    'cached_patches_cc_file': '<(gen_source_dir)/cached_patches_gen.cc',
+    'web_gl_cc_file': '<(gen_source_dir)/web_gl_gen.cc',
+    'metadata_cc_file': '<(gen_source_dir)/metadata_gen.cc',
+    'websql_cc_file': '<(gen_source_dir)/websql_gen.cc',
+    'svg_cc_file': '<(gen_source_dir)/svg_gen.cc',
+    'webaudio_cc_file': '<(gen_source_dir)/webaudio_gen.cc',
+
     'builtin_in_cc_file': 'builtin_in.cc',
     'builtin_cc_file': '<(gen_source_dir)/builtin_gen.cc',
     'snapshot_in_cc_file': 'snapshot_in.cc',
@@ -120,6 +132,364 @@
       ]
     },
     {
+      'target_name': 'generate_html_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+        '../../sdk/lib/html/dartium/html_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_html_cc',
+        'inputs': [
+          '../tools/gen_library_src_paths.py',
+          '<(builtin_in_cc_file)',
+          '<@(_sources)',
+        ],
+        'outputs': [
+          '<(html_cc_file)',
+        ],
+        'action': [
+          'python',
+          'tools/gen_library_src_paths.py',
+          '--output', '<(html_cc_file)',
+          '--input_cc', '<(builtin_in_cc_file)',
+          '--include', 'bin/builtin.h',
+          '--var_name', 'dart::bin::Builtin::html_source_paths_',
+          '--library_name', 'dart:html',
+          '<@(_sources)',
+        ],
+        'message': 'Generating ''<(html_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_html_common_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/html/html_common/html_common.dart',
+      '../../sdk/lib/html/html_common/css_class_set.dart',
+      '../../sdk/lib/html/html_common/device.dart',
+      '../../sdk/lib/html/html_common/filtered_element_list.dart',
+      '../../sdk/lib/html/html_common/lists.dart',
+      '../../sdk/lib/html/html_common/conversions.dart',
+      '../../sdk/lib/html/html_common/conversions_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_html_common_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(html_common_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(html_common_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::html_common_source_paths_',
+        '--library_name', 'dart:html_common',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(html_common_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_js_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/js/dartium/js_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_js_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(js_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(js_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::js_source_paths_',
+        '--library_name', 'dart:js',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(js_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_blink_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/_blink/dartium/_blink_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_blink_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(blink_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(blink_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::blink_source_paths_',
+        '--library_name', 'dart:_blink',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(blink_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_indexeddb_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/indexed_db/dartium/indexed_db_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_indexeddb_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(indexeddb_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(indexeddb_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::indexeddb_source_paths_',
+        '--library_name', 'dart:indexed_db',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(indexeddb_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_cached_patches_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/js/dartium/cached_patches.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_cached_patches_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(cached_patches_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(cached_patches_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::cached_patches_source_paths_',
+        '--library_name', 'cached_patches.dart',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(cached_patches_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_web_gl_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/web_gl/dartium/web_gl_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_web_gl_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(web_gl_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(web_gl_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::web_gl_source_paths_',
+        '--library_name', 'dart:web_gl',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(web_gl_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_metadata_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/html/html_common/metadata.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_metadata_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(metadata_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(metadata_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::metadata_source_paths_',
+        '--library_name', 'metadata.dart',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(metadata_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_websql_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/web_sql/dartium/web_sql_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_websql_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(websql_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(websql_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::websql_source_paths_',
+        '--library_name', 'dart:web_sql',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(websql_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_svg_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/svg/dartium/svg_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_svg_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(svg_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(svg_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::svg_source_paths_',
+        '--library_name', 'dart:svg',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(svg_cc_file)'' file.'
+      },
+      ]
+    },
+    {
+      'target_name': 'generate_webaudio_cc_file',
+      'type': 'none',
+      'toolsets':['host'],
+      'sources': [
+      '../../sdk/lib/web_audio/dartium/web_audio_dartium.dart',
+      ],
+      'actions': [
+      {
+        'action_name': 'generate_webaudio_cc',
+        'inputs': [
+        '../tools/gen_library_src_paths.py',
+        '<(builtin_in_cc_file)',
+        '<@(_sources)',
+        ],
+        'outputs': [
+        '<(webaudio_cc_file)',
+        ],
+        'action': [
+        'python',
+        'tools/gen_library_src_paths.py',
+        '--output', '<(webaudio_cc_file)',
+        '--input_cc', '<(builtin_in_cc_file)',
+        '--include', 'bin/builtin.h',
+        '--var_name', 'dart::bin::Builtin::webaudio_source_paths_',
+        '--library_name', 'dart:web_audio',
+        '<@(_sources)',
+        ],
+        'message': 'Generating ''<(webaudio_cc_file)'' file.'
+      },
+      ]
+    },
+   {
       'target_name': 'libdart_builtin',
       'type': 'static_library',
       'toolsets':['target','host'],
@@ -127,6 +497,17 @@
         'generate_builtin_cc_file#host',
         'generate_io_cc_file#host',
         'generate_io_patch_cc_file#host',
+        'generate_html_cc_file#host',
+        'generate_html_common_cc_file#host',
+        'generate_js_cc_file#host',
+        'generate_blink_cc_file#host',
+        'generate_indexeddb_cc_file#host',
+        'generate_cached_patches_cc_file#host',
+        'generate_web_gl_cc_file#host',
+        'generate_metadata_cc_file#host',
+        'generate_websql_cc_file#host',
+        'generate_svg_cc_file#host',
+        'generate_webaudio_cc_file#host',
       ],
       'include_dirs': [
         '..',
@@ -866,6 +1247,18 @@
         '<(builtin_cc_file)',
         '<(io_cc_file)',
         '<(io_patch_cc_file)',
+        '<(html_cc_file)',
+        '<(html_common_cc_file)',
+        '<(js_cc_file)',
+        '<(blink_cc_file)',
+        '<(indexeddb_cc_file)',
+        '<(cached_patches_cc_file)',
+        '<(web_gl_cc_file)',
+        '<(metadata_cc_file)',
+        '<(websql_cc_file)',
+        '<(svg_cc_file)',
+        '<(webaudio_cc_file)',
+
         '<(resources_cc_file)',
       ],
       'defines': [
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index 272976f..c26a762 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -18,9 +18,29 @@
   { DartUtils::kBuiltinLibURL, _builtin_source_paths_, NULL, NULL, true },
   { DartUtils::kIOLibURL, io_source_paths_,
     DartUtils::kIOLibPatchURL, io_patch_paths_, true },
+
+#if defined(DART_NO_SNAPSHOT)
+  // Only include these libraries in the dart_bootstrap case for now.
+  { "dart:html", html_source_paths_, NULL, NULL, true },
+  { "dart:html_common", html_common_source_paths_, NULL, NULL, true},
+  { "dart:js", js_source_paths_, NULL, NULL, true},
+  { "dart:_blink", blink_source_paths_, NULL, NULL, true },
+  { "dart:indexed_db", indexeddb_source_paths_, NULL, NULL, true },
+  { "cached_patches.dart", cached_patches_source_paths_, NULL, NULL, true },
+  { "dart:web_gl", web_gl_source_paths_, NULL, NULL, true },
+  { "metadata.dart", metadata_source_paths_, NULL, NULL, true },
+  { "dart:web_sql", websql_source_paths_, NULL, NULL, true },
+  { "dart:svg", svg_source_paths_, NULL, NULL, true },
+  { "dart:web_audio", webaudio_source_paths_, NULL, NULL, true },
+#endif  // defined(DART_NO_SNAPSHOT)
+
+  // End marker.
+  { NULL, NULL, NULL, NULL, false }
 };
 
 Dart_Port Builtin::load_port_ = ILLEGAL_PORT;
+const int Builtin::num_libs_ =
+    sizeof(Builtin::builtin_libraries_) / sizeof(Builtin::builtin_lib_props);
 
 // Patch all the specified patch files in the array 'patch_files' into the
 // library specified in 'library'.
@@ -48,9 +68,8 @@
 
 
 Dart_Handle Builtin::Source(BuiltinLibraryId id) {
-  ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
-         kInvalidLibrary);
-  ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+  ASSERT(static_cast<int>(id) >= 0);
+  ASSERT(static_cast<int>(id) < num_libs_);
 
   // Try to read the source using the path specified for the uri.
   const char* uri = builtin_libraries_[id].url_;
@@ -60,9 +79,8 @@
 
 
 Dart_Handle Builtin::PartSource(BuiltinLibraryId id, const char* part_uri) {
-  ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
-         kInvalidLibrary);
-  ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+  ASSERT(static_cast<int>(id) >= 0);
+  ASSERT(static_cast<int>(id) < num_libs_);
 
   // Try to read the source using the path specified for the uri.
   const char** source_paths = builtin_libraries_[id].source_paths_;
@@ -97,6 +115,9 @@
 
 
 Dart_Handle Builtin::LoadLibrary(Dart_Handle url, BuiltinLibraryId id) {
+  ASSERT(static_cast<int>(id) >= 0);
+  ASSERT(static_cast<int>(id) < num_libs_);
+
   Dart_Handle library = Dart_LoadLibrary(url, Source(id), 0, 0);
   if (!Dart_IsError(library) && (builtin_libraries_[id].has_natives_)) {
     // Setup the native resolver for built in library functions.
@@ -113,10 +134,24 @@
 }
 
 
+Builtin::BuiltinLibraryId Builtin::FindId(const char* url_string) {
+  int id = 0;
+  while (true) {
+    if (builtin_libraries_[id].url_ == NULL) {
+      return kInvalidLibrary;
+    }
+    if (strcmp(url_string, builtin_libraries_[id].url_) == 0) {
+      return static_cast<BuiltinLibraryId>(id);
+    }
+    id++;
+  }
+}
+
+
 Dart_Handle Builtin::LoadAndCheckLibrary(BuiltinLibraryId id) {
-  ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
-         kInvalidLibrary);
-  ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+  ASSERT(static_cast<int>(id) >= 0);
+  ASSERT(static_cast<int>(id) < num_libs_);
+
   Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_);
   Dart_Handle library = Dart_LookupLibrary(url);
   if (Dart_IsError(library)) {
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index 59ccec3..f0c0cdc 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -67,6 +67,13 @@
 // command line.
 bool _traceLoading = false;
 
+// This is currently a build time flag only. We measure the time from the first
+// load request (opening the receive port) to completing the last load
+// request (closing the receive port). Future, deferred load operations will
+// add to this time.
+bool _timeLoading = false;
+Stopwatch _stopwatch;
+
 // A port for communicating with the service isolate for I/O.
 SendPort _loadPort;
 // The receive port for a load request. Multiple sources can be fetched in
@@ -358,9 +365,10 @@
   }
 
   if (!_pendingLoads() && (_dataPort != null)) {
+    _stopwatch.stop();
     // Close the _dataPort now that there are no more requests outstanding.
-    if (_traceLoading) {
-      _log("Closing loading port.");
+    if (_traceLoading || _timeLoading) {
+      _log("Closing loading port: ${_stopwatch.elapsedMilliseconds} ms");
     }
     _dataPort.close();
     _dataPort = null;
@@ -408,8 +416,13 @@
     if (_traceLoading) {
       _log("Initializing load port.");
     }
+    // Allocate the Stopwatch if necessary.
+    if (_stopwatch == null) {
+      _stopwatch = new Stopwatch();
+    }
     assert(_dataPort == null);
     _dataPort = new RawReceivePort(_handleLoaderReply);
+    _stopwatch.start();
   }
   // Register the load request and send it to the VM service isolate.
   var req = new _LoadRequest(tag, uri, resourceUri, context);
diff --git a/runtime/bin/builtin.h b/runtime/bin/builtin.h
index ab871af..a4893d9 100644
--- a/runtime/bin/builtin.h
+++ b/runtime/bin/builtin.h
@@ -28,10 +28,9 @@
   // Note: Changes to this enum should be accompanied with changes to
   // the builtin_libraries_ array in builtin.cc and builtin_nolib.cc.
   enum BuiltinLibraryId {
+    kInvalidLibrary = -1,
     kBuiltinLibrary = 0,
-    kIOLibrary,
-
-    kInvalidLibrary,
+    kIOLibrary
   };
 
   // Get source corresponding to built in library specified in 'id'.
@@ -44,6 +43,7 @@
   static void SetNativeResolver(BuiltinLibraryId id);
 
   static Dart_Handle LoadLibrary(Dart_Handle url, BuiltinLibraryId id);
+  static BuiltinLibraryId FindId(const char* url_string);
 
   // Check if built in library specified in 'id' is already loaded, if not
   // load it.
@@ -66,7 +66,20 @@
   static const char* _builtin_source_paths_[];
   static const char* io_source_paths_[];
   static const char* io_patch_paths_[];
+  static const char* html_source_paths_[];
+  static const char* html_common_source_paths_[];
+  static const char* js_source_paths_[];
+  static const char* blink_source_paths_[];
+  static const char* indexeddb_source_paths_[];
+  static const char* cached_patches_source_paths_[];
+  static const char* web_gl_source_paths_[];
+  static const char* metadata_source_paths_[];
+  static const char* websql_source_paths_[];
+  static const char* svg_source_paths_[];
+  static const char* webaudio_source_paths_[];
+
   static Dart_Port load_port_;
+  static const int num_libs_;
 
   typedef struct {
     const char* url_;
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index 96280df..dc6ee17 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -44,6 +44,12 @@
 };
 
 
+void Builtin_DummyNative(Dart_NativeArguments args) {
+  UNREACHABLE();
+}
+
+
+
 /**
  * Looks up native functions in both libdart_builtin and libdart_io.
  */
@@ -51,8 +57,8 @@
                                           int argument_count,
                                           bool* auto_setup_scope) {
   const char* function_name = NULL;
-  Dart_Handle result = Dart_StringToCString(name, &function_name);
-  DART_CHECK_VALID(result);
+  Dart_Handle err = Dart_StringToCString(name, &function_name);
+  DART_CHECK_VALID(err);
   ASSERT(function_name != NULL);
   ASSERT(auto_setup_scope != NULL);
   *auto_setup_scope = true;
@@ -64,7 +70,12 @@
       return reinterpret_cast<Dart_NativeFunction>(entry->function_);
     }
   }
-  return IONativeLookup(name, argument_count, auto_setup_scope);
+  Dart_NativeFunction result =
+      IONativeLookup(name, argument_count, auto_setup_scope);
+  if (result == NULL) {
+    result = Builtin_DummyNative;
+  }
+  return result;
 }
 
 
diff --git a/runtime/bin/builtin_nolib.cc b/runtime/bin/builtin_nolib.cc
index 428927f..5ccf5c8 100644
--- a/runtime/bin/builtin_nolib.cc
+++ b/runtime/bin/builtin_nolib.cc
@@ -17,9 +17,15 @@
   /* { url_, source_, patch_url_, patch_source_, has_natives_ } */
   { DartUtils::kBuiltinLibURL, NULL, NULL, NULL, true },
   { DartUtils::kIOLibURL, NULL, NULL, NULL, true  },
+
+  // End marker.
+  { NULL, NULL, NULL, NULL, false }
 };
 
 Dart_Port Builtin::load_port_ = ILLEGAL_PORT;
+const int Builtin::num_libs_ =
+    sizeof(Builtin::builtin_libraries_) / sizeof(Builtin::builtin_lib_props);
+
 
 Dart_Handle Builtin::Source(BuiltinLibraryId id) {
   return DartUtils::NewError("Unreachable code in Builtin::Source (%d).", id);
@@ -39,9 +45,9 @@
 
 
 void Builtin::SetNativeResolver(BuiltinLibraryId id) {
-  ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
-         kInvalidLibrary);
-  ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+  ASSERT(static_cast<int>(id) >= 0);
+  ASSERT(static_cast<int>(id) < num_libs_);
+
   if (builtin_libraries_[id].has_natives_) {
     Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_);
     Dart_Handle library = Dart_LookupLibrary(url);
@@ -59,10 +65,15 @@
 }
 
 
+Builtin::BuiltinLibraryId Builtin::FindId(const char* url_string) {
+  return kInvalidLibrary;
+}
+
+
 Dart_Handle Builtin::LoadAndCheckLibrary(BuiltinLibraryId id) {
-  ASSERT((sizeof(builtin_libraries_) / sizeof(builtin_lib_props)) ==
-         kInvalidLibrary);
-  ASSERT(id >= kBuiltinLibrary && id < kInvalidLibrary);
+  ASSERT(static_cast<int>(id) >= 0);
+  ASSERT(static_cast<int>(id) < num_libs_);
+
   Dart_Handle url = DartUtils::NewString(builtin_libraries_[id].url_);
   Dart_Handle library = Dart_LookupLibrary(url);
   return library;
diff --git a/runtime/bin/dartutils.cc b/runtime/bin/dartutils.cc
index e180479..02f6016 100644
--- a/runtime/bin/dartutils.cc
+++ b/runtime/bin/dartutils.cc
@@ -406,51 +406,45 @@
   }
 
   bool is_dart_scheme_url = DartUtils::IsDartSchemeURL(url_string);
-  bool is_io_library = DartUtils::IsDartIOLibURL(library_url_string);
+  bool is_dart_library = DartUtils::IsDartSchemeURL(library_url_string);
 
-  // Handle URI canonicalization requests.
-  if (tag == Dart_kCanonicalizeUrl) {
-    // If this is a Dart Scheme URL or 'part' of a io library
-    // then it is not modified as it will be handled internally.
-    if (is_dart_scheme_url || is_io_library) {
+  // Handle canonicalization, 'import' and 'part' of 'dart:' libraries.
+  if (is_dart_scheme_url || is_dart_library) {
+    if (tag == Dart_kCanonicalizeUrl) {
+      // These will be handled internally.
       return url;
-    }
-    // Resolve the url within the context of the library's URL.
-    return ResolveUri(library_url, url);
-  }
-
-  // Handle 'import' of dart scheme URIs (i.e they start with 'dart:').
-  if (is_dart_scheme_url) {
-    if (tag == Dart_kImportTag) {
-      // Handle imports of other built-in libraries present in the SDK.
-      if (DartUtils::IsDartIOLibURL(url_string)) {
-        return Builtin::LoadLibrary(url, Builtin::kIOLibrary);
+    } else if (tag == Dart_kImportTag) {
+      Builtin::BuiltinLibraryId id = Builtin::FindId(url_string);
+      if (id == Builtin::kInvalidLibrary) {
+        return NewError("The built-in library '%s' is not available"
+                        " on the stand-alone VM.\n", url_string);
       }
-      return NewError("The built-in library '%s' is not available"
-                      " on the stand-alone VM.\n", url_string);
+      return Builtin::LoadLibrary(url, id);
     } else {
       ASSERT(tag == Dart_kSourceTag);
-      return NewError("Unable to load source '%s' ", url_string);
-    }
-  }
-
-  // Handle 'part' of IO library.
-  if (is_io_library) {
-    if (tag == Dart_kSourceTag) {
+      Builtin::BuiltinLibraryId id = Builtin::FindId(library_url_string);
+      if (id == Builtin::kInvalidLibrary) {
+        return NewError("The built-in library '%s' is not available"
+                        " on the stand-alone VM. Trying to load"
+                        " '%s'.\n", library_url_string, url_string);
+      }
       // Prepend the library URI to form a unique script URI for the part.
       intptr_t len = snprintf(NULL, 0, "%s/%s", library_url_string, url_string);
       char* part_uri = reinterpret_cast<char*>(malloc(len + 1));
       snprintf(part_uri, len + 1, "%s/%s", library_url_string, url_string);
       Dart_Handle part_uri_obj = DartUtils::NewString(part_uri);
       free(part_uri);
-      return Dart_LoadSource(
-          library,
-          part_uri_obj,
-          Builtin::PartSource(Builtin::kIOLibrary, url_string), 0, 0);
-    } else {
-      ASSERT(tag == Dart_kImportTag);
-      return NewError("Unable to import '%s' ", url_string);
+      return Dart_LoadSource(library,
+                             part_uri_obj,
+                             Builtin::PartSource(id, url_string), 0, 0);
     }
+    // All cases should have been handled above.
+    UNREACHABLE();
+  }
+
+  if (tag == Dart_kCanonicalizeUrl) {
+    // Resolve the url within the context of the library's URL.
+    return ResolveUri(library_url, url);
   }
 
   if (DartUtils::IsDartExtensionSchemeURL(url_string)) {
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index fb8b338..ab45b95 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -52,10 +52,16 @@
  * - Running the full application snapshot generated above :
  * dart --run-full-snapshot=<filename> <script_uri> [<script_options>]
  */
-static bool generate_script_snapshot = false;
-static bool generate_full_snapshot_after_run = false;
-static bool run_full_snapshot = false;
+static bool run_app_snapshot = false;
 static const char* snapshot_filename = NULL;
+enum SnapshotKind {
+  kNone,
+  kScript,
+  kAppAOT,
+  kAppJITAfterRun,
+  kAppAfterRun,
+};
+static SnapshotKind gen_snapshot_kind = kNone;
 
 // Value of the --package-root flag.
 // (This pointer points into an argv buffer and does not need to be
@@ -73,27 +79,11 @@
 static bool compile_all = false;
 
 
-// Global flag that is used to indicate that we want to compile all the
-// dart functions before running main and not compile anything thereafter.
-static bool gen_precompiled_snapshot = false;
-
-
-// Global flag that is used to indicate that we want to run from a precompiled
-// snapshot.
-static bool run_precompiled_snapshot = false;
-
-
 // Global flag that is used to indicate that we want to use blobs/mmap instead
 // of assembly/shared libraries for precompilation.
 static bool use_blobs = false;
 
 
-// Value of the --gen/run_precompiled_snapshot flag.
-// (This pointer points into an argv buffer and does not need to be
-// free'd.)
-static const char* precompiled_snapshot_directory = NULL;
-
-
 // Global flag that is used to indicate that we want to compile everything in
 // the same way as precompilation before main, then continue running in the
 // same process.
@@ -108,14 +98,13 @@
 extern const char* kPrecompiledLibraryName;
 extern const char* kPrecompiledInstructionsSymbolName;
 extern const char* kPrecompiledDataSymbolName;
-static const char* kPrecompiledVmIsolateName = "precompiled.vmisolate";
-static const char* kPrecompiledIsolateName = "precompiled.isolate";
-static const char* kPrecompiledAssemblyName = "precompiled.S";
-static const char* kPrecompiledInstructionsBlobName =
-    "precompiled.instructions";
-static const char* kPrecompiledRodataBlobName = "precompiled.rodata";
-static const char* kVMIsolateSuffix = "vmisolate";
-static const char* kIsolateSuffix = "isolate";
+
+static const char* kVMIsolateSuffix = "snapshot.vmisolate";
+static const char* kIsolateSuffix = "snapshot.isolate";
+static const char* kAssemblySuffix = "snapshot.S";
+static const char* kInstructionsSuffix = "snapshot.instructions";
+static const char* kRODataSuffix = "snapshot.rodata";
+
 
 // Global flag that is used to indicate that we want to trace resolution of
 // URIs and the loading of libraries, parts and scripts.
@@ -345,97 +334,43 @@
 }
 
 
-static bool ProcessGenPrecompiledSnapshotOption(
-    const char* arg,
-    CommandLineOptions* vm_options) {
-#if !defined(DART_PRECOMPILER)
-  Log::PrintErr("Precompiled snapshots must be generated with "
-                "dart_bootstrap.\n");
-  return false;
-#else  // defined(DART_PRECOMPILER)
-  ASSERT(arg != NULL);
-  if ((arg[0] == '=') || (arg[0] == ':')) {
-    precompiled_snapshot_directory = &arg[1];
-  } else {
-    precompiled_snapshot_directory = arg;
-  }
-  gen_precompiled_snapshot = true;
-  vm_options->AddArgument("--precompilation");
-  return true;
-#endif  // defined(DART_PRECOMPILER)
-}
-
-
-static bool ProcessRunPrecompiledSnapshotOption(
-    const char* arg,
-    CommandLineOptions* vm_options) {
-  ASSERT(arg != NULL);
-  precompiled_snapshot_directory = arg;
-  if ((precompiled_snapshot_directory[0] == '=') ||
-      (precompiled_snapshot_directory[0] == ':')) {
-    precompiled_snapshot_directory = &precompiled_snapshot_directory[1];
-  }
-  run_precompiled_snapshot = true;
-  vm_options->AddArgument("--precompilation");
-  return true;
-}
-
-
-static bool ProcessSnapshotOptionHelper(const char* filename,
-                                        bool* snapshot_option) {
-  ASSERT((filename != NULL) && (strlen(filename) != 0));
+static bool ProcessSnapshotFilenameOption(const char* filename,
+                                          CommandLineOptions* vm_options) {
   snapshot_filename = filename;
-  *snapshot_option = true;
-  if (generate_script_snapshot && generate_full_snapshot_after_run) {
-    Log::PrintErr("--snapshot and --snapshot-after-run options"
-                  " cannot be specified at the same time\n");
-    *snapshot_option = false;
-    return false;
+  if (gen_snapshot_kind == kNone) {
+    gen_snapshot_kind = kScript;  // Default behavior.
   }
   return true;
 }
 
 
-static bool ProcessScriptSnapshotOption(const char* filename,
-                                        CommandLineOptions* vm_options) {
-  if ((filename == NULL) || (strlen(filename) == 0)) {
-    return false;
+static bool ProcessSnapshotKindOption(const char* kind,
+                                      CommandLineOptions* vm_options) {
+  if (strcmp(kind, "script") == 0) {
+    gen_snapshot_kind = kScript;
+    return true;
+  } else if (strcmp(kind, "app-aot") == 0) {
+    gen_snapshot_kind = kAppAOT;
+    return true;
+  } else if (strcmp(kind, "app-jit-after-run") == 0) {
+    gen_snapshot_kind = kAppJITAfterRun;
+    return true;
+  } else if (strcmp(kind, "app-after-run") == 0) {
+    gen_snapshot_kind = kAppAfterRun;
+    return true;
   }
-  // Ensure that we are already running using a full snapshot.
-  if (isolate_snapshot_buffer == NULL) {
-    Log::PrintErr("Script snapshots cannot be generated in this version of"
-                  " Dart\n");
-    return false;
-  }
-  return ProcessSnapshotOptionHelper(filename, &generate_script_snapshot);
-}
-
-
-static bool ProcessFullSnapshotAfterRunOption(
-    const char* filename, CommandLineOptions* vm_options) {
-  if ((filename == NULL) || (strlen(filename) == 0)) {
-    return false;
-  }
-  // Ensure that we are running 'dart_bootstrap'.
-  if (isolate_snapshot_buffer != NULL) {
-    Log::PrintErr("Full Application snapshots must be generated with"
-                  " dart_bootstrap\n");
-    return false;
-  }
-  return ProcessSnapshotOptionHelper(filename,
-                                     &generate_full_snapshot_after_run);
-}
-
-
-static bool ProcessRunFullSnapshotOption(
-    const char* filename, CommandLineOptions* vm_options) {
-#if !defined(PRODUCT)
-  Log::PrintErr("Full Application snapshots can only be be run with"
-                " product mode\n");
+  Log::PrintErr("Unrecognized snapshot kind: '%s'\nValid kinds are: "
+                "script, app-aot, app-jit-after-run, app-after-run\n", kind);
   return false;
-#else
-  return ProcessSnapshotOptionHelper(filename, &run_full_snapshot);
-#endif  // defined(PRODUCT)
+}
+
+
+static bool ProcessRunAppSnapshotOption(
+    const char* filename, CommandLineOptions* vm_options) {
+  ASSERT(filename != NULL);
+  snapshot_filename = filename;
+  run_app_snapshot = true;
+  return true;
 }
 
 
@@ -532,15 +467,13 @@
 
   // VM specific options to the standalone dart program.
   { "--compile_all", ProcessCompileAllOption },
-  { "--use_blobs", ProcessUseBlobsOption },
   { "--enable-vm-service", ProcessEnableVmServiceOption },
-  { "--gen-precompiled-snapshot", ProcessGenPrecompiledSnapshotOption },
   { "--observe", ProcessObserveOption },
-  { "--run-precompiled-snapshot", ProcessRunPrecompiledSnapshotOption },
   { "--shutdown", ProcessShutdownOption },
-  { "--snapshot=", ProcessScriptSnapshotOption },
-  { "--full-snapshot-after-run=", ProcessFullSnapshotAfterRunOption },
-  { "--run-full-snapshot=", ProcessRunFullSnapshotOption },
+  { "--snapshot=", ProcessSnapshotFilenameOption },
+  { "--snapshot-kind=", ProcessSnapshotKindOption },
+  { "--run-app-snapshot=", ProcessRunAppSnapshotOption },
+  { "--use-blobs", ProcessUseBlobsOption },
   { "--trace-loading", ProcessTraceLoadingOption },
   { NULL, NULL }
 };
@@ -657,25 +590,15 @@
                   "file is invalid.\n");
     return -1;
   }
-  if (is_noopt) {
-    if (gen_precompiled_snapshot) {
-      Log::PrintErr("Running dart_noopt with --gen_precompiled_snapshot"
-                    " is invalid.\n");
-      return -1;
-    }
-    if (run_precompiled_snapshot) {
-      Log::PrintErr("Running dart_noopt with --run_precompiled_snapshot"
-                    " is invalid.\n");
-      return -1;
-    }
-  }
-  if (run_full_snapshot && run_precompiled_snapshot) {
-    Log::PrintErr("Specifying --run_full_snapshot and"
-                  " --run_precompiled_snapshot is invalid.\n");
+  if (is_noopt && gen_snapshot_kind != kNone) {
+    Log::PrintErr("Generating a snapshot with dart_noopt is invalid.\n");
     return -1;
   }
-  if ((generate_full_snapshot_after_run || gen_precompiled_snapshot) &&
-      (run_full_snapshot || run_precompiled_snapshot)) {
+  if ((gen_snapshot_kind != kNone) && (snapshot_filename == NULL)) {
+    Log::PrintErr("Generating a snapshot requires a filename (--snapshot).\n");
+    return -1;
+  }
+  if ((gen_snapshot_kind != kNone) && run_app_snapshot) {
     Log::PrintErr("Specifying an option to generate a snapshot and"
                   " run using a snapshot is invalid.\n");
     return -1;
@@ -766,16 +689,16 @@
                                                 int* exit_code) {
   ASSERT(script_uri != NULL);
 
+  const bool needs_load_port = !run_app_snapshot;
 #if defined(PRODUCT)
-  const bool run_service_isolate = !run_full_snapshot &&
-                                   !run_precompiled_snapshot;
+  const bool run_service_isolate = needs_load_port;
 #else
-  const bool run_service_isolate = !run_full_snapshot;
+  // Always create the service isolate in DEBUG and RELEASE modes for profiling,
+  // even if we don't need it for loading.
+  const bool run_service_isolate = true;
 #endif  // PRODUCT
   if (!run_service_isolate &&
       (strcmp(script_uri, DART_VM_SERVICE_ISOLATE_NAME) == 0)) {
-    // We do not create a service isolate when running a full application
-    // snapshot or a precompiled snapshot in product mode.
     return NULL;
   }
 
@@ -807,9 +730,10 @@
 
   if (Dart_IsServiceIsolate(isolate)) {
     // If this is the service isolate, load embedder specific bits and return.
+    bool skip_library_load = run_app_snapshot;
     if (!VmService::Setup(vm_service_server_ip,
                           vm_service_server_port,
-                          run_precompiled_snapshot)) {
+                          skip_library_load)) {
       *error = strdup(VmService::GetErrorMessage());
       return NULL;
     }
@@ -828,12 +752,9 @@
   result = DartUtils::PrepareForScriptLoading(false, trace_loading);
   CHECK_RESULT(result);
 
-  if (!run_precompiled_snapshot && !run_full_snapshot) {
+  if (needs_load_port) {
     // Set up the load port provided by the service isolate so that we can
     // load scripts.
-    // With a full snapshot or a precompiled snapshot in product mode, there is
-    // no service isolate. A precompiled snapshot in release or debug mode does
-    // have the service isolate, but it doesn't use it for loading.
     result = DartUtils::SetupServiceLoadPort();
     CHECK_RESULT(result);
   }
@@ -845,7 +766,10 @@
   result = Dart_SetEnvironmentCallback(EnvironmentCallback);
   CHECK_RESULT(result);
 
-  if (!run_precompiled_snapshot && !run_full_snapshot) {
+  if (run_app_snapshot) {
+    result = DartUtils::SetupIOLibrary(script_uri);
+    CHECK_RESULT(result);
+  } else {
     // Load the specified application script into the newly created isolate.
     result = DartUtils::LoadScript(script_uri);
     CHECK_RESULT(result);
@@ -862,9 +786,6 @@
 
     result = DartUtils::SetupIOLibrary(script_uri);
     CHECK_RESULT(result);
-  } else if (run_full_snapshot) {
-    result = DartUtils::SetupIOLibrary(script_uri);
-    CHECK_RESULT(result);
   }
 
   // Make the isolate runnable so that it is ready to handle messages.
@@ -1206,19 +1127,13 @@
     qualified_libname = libname;
   }
   void* library = Extensions::LoadExtensionLibrary(qualified_libname);
-  if (library == NULL) {
-    Log::PrintErr("Error: Failed to load library '%s'\n", qualified_libname);
-    Platform::Exit(kErrorExitCode);
-  }
-  void* symbol = Extensions::ResolveSymbol(library, symname);
-  if (symbol == NULL) {
-    Log::PrintErr("Error: Failed to load symbol '%s'\n", symname);
-    Platform::Exit(kErrorExitCode);
-  }
   if (concat != NULL) {
     delete concat;
   }
-  return symbol;
+  if (library == NULL) {
+    return NULL;
+  }
+  return Extensions::ResolveSymbol(library, symname);
 }
 
 
@@ -1235,16 +1150,107 @@
 }
 
 
-static void ComputeSnapshotFilenames(const char* filename,
-                                     char** vm_snapshot_fname,
-                                     char** isolate_snapshot_fname) {
-  intptr_t len = snprintf(NULL, 0, "%s.%s", filename, kVMIsolateSuffix);
-  *vm_snapshot_fname = new char[len + 1];
-  snprintf(*vm_snapshot_fname, len + 1, "%s.%s", filename, kVMIsolateSuffix);
+static void GeneratePrecompiledSnapshot() {
+  uint8_t* vm_isolate_buffer = NULL;
+  intptr_t vm_isolate_size = 0;
+  uint8_t* isolate_buffer = NULL;
+  intptr_t isolate_size = 0;
+  uint8_t* assembly_buffer = NULL;
+  intptr_t assembly_size = 0;
+  uint8_t* instructions_blob_buffer = NULL;
+  intptr_t instructions_blob_size = 0;
+  uint8_t* rodata_blob_buffer = NULL;
+  intptr_t rodata_blob_size = 0;
+  Dart_Handle result;
+  if (use_blobs) {
+    result = Dart_CreatePrecompiledSnapshotBlob(
+        &vm_isolate_buffer,
+        &vm_isolate_size,
+        &isolate_buffer,
+        &isolate_size,
+        &instructions_blob_buffer,
+        &instructions_blob_size,
+        &rodata_blob_buffer,
+        &rodata_blob_size);
+  } else {
+    result = Dart_CreatePrecompiledSnapshotAssembly(
+        &vm_isolate_buffer,
+        &vm_isolate_size,
+        &isolate_buffer,
+        &isolate_size,
+        &assembly_buffer,
+        &assembly_size);
+  }
+  if (Dart_IsError(result)) {
+    ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
+  }
+  WriteSnapshotFile(snapshot_filename, kVMIsolateSuffix,
+                    false,
+                    vm_isolate_buffer,
+                    vm_isolate_size);
+  WriteSnapshotFile(snapshot_filename, kIsolateSuffix,
+                    false,
+                    isolate_buffer,
+                    isolate_size);
+  if (use_blobs) {
+    WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
+                      false,
+                      instructions_blob_buffer,
+                      instructions_blob_size);
+    WriteSnapshotFile(snapshot_filename, kRODataSuffix,
+                      false,
+                      rodata_blob_buffer,
+                      rodata_blob_size);
+  } else {
+    WriteSnapshotFile(snapshot_filename, kAssemblySuffix,
+                      false,
+                      assembly_buffer,
+                      assembly_size);
+  }
+}
 
-  len = snprintf(NULL, 0, "%s.%s", filename, kIsolateSuffix);
-  *isolate_snapshot_fname = new char[len + 1];
-  snprintf(*isolate_snapshot_fname, len + 1, "%s.%s", filename, kIsolateSuffix);
+
+static void GeneratePrecompiledJITSnapshot() {
+  if (!use_blobs) {
+    ErrorExit(kErrorExitCode,
+              "Generating app JIT snapshots as assembly unimplemented\n");
+  }
+  uint8_t* vm_isolate_buffer = NULL;
+  intptr_t vm_isolate_size = 0;
+  uint8_t* isolate_buffer = NULL;
+  intptr_t isolate_size = 0;
+  uint8_t* instructions_blob_buffer = NULL;
+  intptr_t instructions_blob_size = 0;
+  uint8_t* rodata_blob_buffer = NULL;
+  intptr_t rodata_blob_size = 0;
+  Dart_Handle result = Dart_CreatePrecompiledJITSnapshotBlob(
+      &vm_isolate_buffer,
+      &vm_isolate_size,
+      &isolate_buffer,
+      &isolate_size,
+      &instructions_blob_buffer,
+      &instructions_blob_size,
+      &rodata_blob_buffer,
+      &rodata_blob_size);
+  if (Dart_IsError(result)) {
+    ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
+  }
+  WriteSnapshotFile(snapshot_filename, kVMIsolateSuffix,
+                    false,
+                    vm_isolate_buffer,
+                    vm_isolate_size);
+  WriteSnapshotFile(snapshot_filename, kIsolateSuffix,
+                    false,
+                    isolate_buffer,
+                    isolate_size);
+  WriteSnapshotFile(snapshot_filename, kInstructionsSuffix,
+                    false,
+                    instructions_blob_buffer,
+                    instructions_blob_size);
+  WriteSnapshotFile(snapshot_filename, kRODataSuffix,
+                    false,
+                    rodata_blob_buffer,
+                    rodata_blob_size);
 }
 
 
@@ -1255,8 +1261,6 @@
   intptr_t vm_isolate_size = 0;
   uint8_t* isolate_buffer = NULL;
   intptr_t isolate_size = 0;
-  char* vm_snapshot_fname = NULL;
-  char* isolate_snapshot_fname = NULL;
 
   result = Dart_CreateSnapshot(&vm_isolate_buffer,
                                &vm_isolate_size,
@@ -1266,17 +1270,13 @@
     ErrorExit(kErrorExitCode, "%s\n", Dart_GetError(result));
   }
 
-  // Compute snapshot file names and write out the snapshot files.
-  ComputeSnapshotFilenames(snapshot_filename,
-                           &vm_snapshot_fname,
-                           &isolate_snapshot_fname);
-  WriteSnapshotFile(NULL,
-                    vm_snapshot_fname,
+  WriteSnapshotFile(snapshot_filename,
+                    kVMIsolateSuffix,
                     false,
                     vm_isolate_buffer,
                     vm_isolate_size);
-  WriteSnapshotFile(NULL,
-                    isolate_snapshot_fname,
+  WriteSnapshotFile(snapshot_filename,
+                    kIsolateSuffix,
                     false,
                     isolate_buffer,
                     isolate_size);
@@ -1339,7 +1339,7 @@
 
   Dart_EnterScope();
 
-  if (generate_script_snapshot) {
+  if (gen_snapshot_kind == kScript) {
     GenerateScriptSnapshot();
   } else {
     // Lookup the library of the root script.
@@ -1351,9 +1351,12 @@
     result = Dart_LibraryImportLibrary(
         isolate_data->builtin_lib(), root_lib, Dart_Null());
 #if !defined(PRODUCT)
-    if (is_noopt || gen_precompiled_snapshot) {
+    if (is_noopt ||
+        (gen_snapshot_kind == kAppAfterRun) ||
+        (gen_snapshot_kind == kAppAOT) ||
+        (gen_snapshot_kind == kAppJITAfterRun)) {
       // Load the embedder's portion of the VM service's Dart code so it will
-      // be included in the precompiled snapshot.
+      // be included in the app snapshot.
       if (!VmService::LoadForGenPrecompiled()) {
         fprintf(stderr,
                 "VM service loading failed: %s\n",
@@ -1369,7 +1372,7 @@
       CHECK_RESULT(result);
     }
 
-    if (is_noopt || gen_precompiled_snapshot) {
+    if (is_noopt || (gen_snapshot_kind == kAppAOT)) {
       Dart_QualifiedFunctionName standalone_entry_points[] = {
         { "dart:_builtin", "::", "_getMainClosure" },
         { "dart:_builtin", "::", "_getPrintClosure" },
@@ -1404,71 +1407,13 @@
         { NULL, NULL, NULL }  // Must be terminated with NULL entries.
       };
 
-      const bool reset_fields = gen_precompiled_snapshot;
+      const bool reset_fields = gen_snapshot_kind == kAppAOT;
       result = Dart_Precompile(standalone_entry_points, reset_fields);
       CHECK_RESULT(result);
     }
 
-    if (gen_precompiled_snapshot) {
-      uint8_t* vm_isolate_buffer = NULL;
-      intptr_t vm_isolate_size = 0;
-      uint8_t* isolate_buffer = NULL;
-      intptr_t isolate_size = 0;
-      uint8_t* assembly_buffer = NULL;
-      intptr_t assembly_size = 0;
-      uint8_t* instructions_blob_buffer = NULL;
-      intptr_t instructions_blob_size = 0;
-      uint8_t* rodata_blob_buffer = NULL;
-      intptr_t rodata_blob_size = 0;
-      if (use_blobs) {
-        result = Dart_CreatePrecompiledSnapshotBlob(
-            &vm_isolate_buffer,
-            &vm_isolate_size,
-            &isolate_buffer,
-            &isolate_size,
-            &instructions_blob_buffer,
-            &instructions_blob_size,
-            &rodata_blob_buffer,
-            &rodata_blob_size);
-        CHECK_RESULT(result);
-      } else {
-        result = Dart_CreatePrecompiledSnapshotAssembly(
-            &vm_isolate_buffer,
-            &vm_isolate_size,
-            &isolate_buffer,
-            &isolate_size,
-            &assembly_buffer,
-            &assembly_size);
-        CHECK_RESULT(result);
-      }
-      WriteSnapshotFile(precompiled_snapshot_directory,
-                        kPrecompiledVmIsolateName,
-                        false,
-                        vm_isolate_buffer,
-                        vm_isolate_size);
-      WriteSnapshotFile(precompiled_snapshot_directory,
-                        kPrecompiledIsolateName,
-                        false,
-                        isolate_buffer,
-                        isolate_size);
-      if (use_blobs) {
-        WriteSnapshotFile(precompiled_snapshot_directory,
-                          kPrecompiledInstructionsBlobName,
-                          false,
-                          instructions_blob_buffer,
-                          instructions_blob_size);
-        WriteSnapshotFile(precompiled_snapshot_directory,
-                          kPrecompiledRodataBlobName,
-                          false,
-                          rodata_blob_buffer,
-                          rodata_blob_size);
-      } else {
-        WriteSnapshotFile(precompiled_snapshot_directory,
-                          kPrecompiledAssemblyName,
-                          false,
-                          assembly_buffer,
-                          assembly_size);
-      }
+    if (gen_snapshot_kind == kAppAOT) {
+      GeneratePrecompiledSnapshot();
     } else {
       if (Dart_IsNull(root_lib)) {
         ErrorExit(kErrorExitCode,
@@ -1499,11 +1444,18 @@
 
       // Keep handling messages until the last active receive port is closed.
       result = Dart_RunLoop();
-      // Generate a full snapshot after execution if specified.
-      if (generate_full_snapshot_after_run) {
+      // Generate an app snapshot after execution if specified.
+      if ((gen_snapshot_kind == kAppAfterRun) ||
+          (gen_snapshot_kind == kAppJITAfterRun)) {
         if (!Dart_IsCompilationError(result) &&
             !Dart_IsVMRestartRequest(result)) {
-          GenerateFullSnapshot();
+          if (gen_snapshot_kind == kAppAfterRun) {
+            GenerateFullSnapshot();
+          } else {
+            Dart_Handle prepare_result = Dart_PrecompileJIT();
+            CHECK_RESULT(prepare_result);
+            GeneratePrecompiledJITSnapshot();
+          }
         }
       }
       CHECK_RESULT(result);
@@ -1661,18 +1613,17 @@
     Platform::Exit(kErrorExitCode);
   }
 
-#if !defined(PRODUCT)
-  // Constant true in PRODUCT mode.
-  if (generate_script_snapshot ||
-      generate_full_snapshot_after_run ||
-      run_full_snapshot) {
+#if !defined(PRODUCT) && !defined(DART_PRECOMPILED_RUNTIME)
+  // Constant true if PRODUCT or DART_PRECOMPILED_RUNTIME.
+  if ((gen_snapshot_kind != kNone) || run_app_snapshot) {
     vm_options.AddArgument("--load_deferred_eagerly");
   }
 #endif
 
-#if defined(DART_PRECOMPILER) && !defined(DART_NO_SNAPSHOT)
-  // Always set --precompilation with dart_noopt.
-  ASSERT(!gen_precompiled_snapshot && !run_precompiled_snapshot);
+  if ((gen_snapshot_kind == kAppAOT) || is_noopt) {
+    vm_options.AddArgument("--precompilation");
+  }
+#if defined(DART_PRECOMPILED_RUNTIME)
   vm_options.AddArgument("--precompilation");
 #endif
 
@@ -1684,43 +1635,27 @@
 
   const uint8_t* instructions_snapshot = NULL;
   const uint8_t* data_snapshot = NULL;
-  if (run_precompiled_snapshot) {
-    ReadSnapshotFile(precompiled_snapshot_directory,
-                     kPrecompiledVmIsolateName,
+  if (run_app_snapshot) {
+    ReadSnapshotFile(snapshot_filename, kVMIsolateSuffix,
                      &vm_isolate_snapshot_buffer);
-    ReadSnapshotFile(precompiled_snapshot_directory,
-                     kPrecompiledIsolateName,
+    ReadSnapshotFile(snapshot_filename, kIsolateSuffix,
                      &isolate_snapshot_buffer);
     if (use_blobs) {
-      ReadExecutableSnapshotFile(precompiled_snapshot_directory,
-                                 kPrecompiledInstructionsBlobName,
+      ReadExecutableSnapshotFile(snapshot_filename,
+                                 kInstructionsSuffix,
                                  &instructions_snapshot);
-      ReadSnapshotFile(precompiled_snapshot_directory,
-                       kPrecompiledRodataBlobName,
+      ReadSnapshotFile(snapshot_filename, kRODataSuffix,
                        &data_snapshot);
     } else {
       instructions_snapshot = reinterpret_cast<const uint8_t*>(
-          LoadLibrarySymbol(precompiled_snapshot_directory,
+          LoadLibrarySymbol(snapshot_filename,
                             kPrecompiledLibraryName,
                             kPrecompiledInstructionsSymbolName));
       data_snapshot = reinterpret_cast<const uint8_t*>(
-          LoadLibrarySymbol(precompiled_snapshot_directory,
+          LoadLibrarySymbol(snapshot_filename,
                             kPrecompiledLibraryName,
                             kPrecompiledDataSymbolName));
     }
-  } else if (run_full_snapshot) {
-    char* vm_snapshot_fname;
-    char* isolate_snapshot_fname;
-
-    // Compute file names.
-    ComputeSnapshotFilenames(snapshot_filename,
-                             &vm_snapshot_fname,
-                             &isolate_snapshot_fname);
-
-    ReadSnapshotFile(NULL, vm_snapshot_fname, &vm_isolate_snapshot_buffer);
-    ReadSnapshotFile(NULL, isolate_snapshot_fname, &isolate_snapshot_buffer);
-    delete vm_snapshot_fname;
-    delete isolate_snapshot_fname;
   }
 
   // Initialize the Dart VM.
diff --git a/runtime/bin/platform.cc b/runtime/bin/platform.cc
index 2099ebb..3dccea7 100644
--- a/runtime/bin/platform.cc
+++ b/runtime/bin/platform.cc
@@ -40,7 +40,6 @@
 
 
 void FUNCTION_NAME(Platform_ExecutableName)(Dart_NativeArguments args) {
-  ASSERT(Platform::GetExecutableName() != NULL);
   if (Dart_IsRunningPrecompiledCode()) {
     // This is a work-around to be able to use most of the existing test suite
     // for precompilation. Many tests do something like Process.run(
@@ -51,8 +50,12 @@
         "Platform.executable not supported under precompilation"));
     UNREACHABLE();
   }
-  Dart_SetReturnValue(
-      args, Dart_NewStringFromCString(Platform::GetExecutableName()));
+  if (Platform::GetExecutableName() != NULL) {
+    Dart_SetReturnValue(
+        args, Dart_NewStringFromCString(Platform::GetExecutableName()));
+  } else {
+    Dart_SetReturnValue(args, Dart_Null());
+  }
 }
 
 
diff --git a/runtime/bin/platform.h b/runtime/bin/platform.h
index b4c10a2..1f52ef9 100644
--- a/runtime/bin/platform.h
+++ b/runtime/bin/platform.h
@@ -69,7 +69,10 @@
   static const char* GetResolvedExecutableName() {
     if (resolved_executable_name_ == NULL) {
       // Try to resolve the executable path using platform specific APIs.
-      resolved_executable_name_ = strdup(Platform::ResolveExecutablePath());
+      const char* resolved_name = Platform::ResolveExecutablePath();
+      if (resolved_name != NULL) {
+        resolved_executable_name_ = strdup(resolved_name);
+      }
     }
     return resolved_executable_name_;
   }
diff --git a/runtime/bin/platform_android.cc b/runtime/bin/platform_android.cc
index f713c9a..3d1a764 100644
--- a/runtime/bin/platform_android.cc
+++ b/runtime/bin/platform_android.cc
@@ -81,7 +81,7 @@
 
 
 const char* Platform::ResolveExecutablePath() {
-  return File::LinkTarget("/proc/self/exe");
+  return NULL;
 }
 
 
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 5835660..c7390e7 100755
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -2957,15 +2957,36 @@
     bool reset_fields);
 
 
+/**
+ *  Creates a precompiled snapshot.
+ *   - The VM must not have been started from a snapshot.
+ *   - A root library must have been loaded.
+ *   - Dart_Precompile must have been called.
+ *
+ *  Outputs a vm isolate snapshot, an isolate snapshot, and an assembly file
+ *  defining the symbols kInstructionsSnapshot and kDataSnapshot. The assembly
+ *  should be compiled as a static or shared library and linked or loaded by the
+ *  embedder.
+ *  Running this snapshot requires a VM compiled with DART_PRECOMPILED_SNAPSHOT.
+ *  The vm isolate snapshot, kInstructionsSnapshot and kDataSnapshot should be
+ *  passed as arguments to Dart_Initialize. The isolate snapshot should be
+ *  passed to Dart_CreateIsolate.
+ */
 DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotAssembly(
     uint8_t** vm_isolate_snapshot_buffer,
     intptr_t* vm_isolate_snapshot_size,
     uint8_t** isolate_snapshot_buffer,
     intptr_t* isolate_snapshot_size,
-    uint8_t** instructions_assembly_buffer,
-    intptr_t* instructions_assembly_size);
+    uint8_t** assembly_buffer,
+    intptr_t* assembly_size);
 
 
+/**
+ *  Same as Dart_CreatePrecompiledSnapshotAssembly, except the instruction and
+ *  data snapshot pieces are provided directly as bytes that the embedder can
+ *  load with mmap. The instructions piece must be loaded with read and
+ *  execute permissions; the rodata piece may be loaded as read-only.
+ */
 DART_EXPORT Dart_Handle Dart_CreatePrecompiledSnapshotBlob(
     uint8_t** vm_isolate_snapshot_buffer,
     intptr_t* vm_isolate_snapshot_size,
@@ -2977,6 +2998,35 @@
     intptr_t* rodata_blob_size);
 
 
+DART_EXPORT Dart_Handle Dart_PrecompileJIT();
+
+
+DART_EXPORT Dart_Handle Dart_CreatePrecompiledJITSnapshotBlob(
+    uint8_t** vm_isolate_snapshot_buffer,
+    intptr_t* vm_isolate_snapshot_size,
+    uint8_t** isolate_snapshot_buffer,
+    intptr_t* isolate_snapshot_size,
+    uint8_t** instructions_blob_buffer,
+    intptr_t* instructions_blob_size,
+    uint8_t** rodata_blob_buffer,
+    intptr_t* rodata_blob_size);
+
+
+/**
+ *  Returns whether the VM only supports running from precompiled snapshots and
+ *  not from any other kind of snapshot or no snapshot (that is, the VM was
+ *  compiled with DART_PRECOMPILED_RUNTIME).
+ */
+DART_EXPORT bool Dart_IsPrecompiledRuntime();
+
+
+/**
+ *  Returns whether the VM was initialized with a precompiled snapshot. Only
+ *  valid after Dart_Initialize.
+ *  DEPRECATED. This is currently used to disable Platform.executable and
+ *  Platform.resolvedExecutable under precompilation to prevent process
+ *  spawning tests from becoming fork-bombs.
+ */
 DART_EXPORT bool Dart_IsRunningPrecompiledCode();
 
 #endif  /* INCLUDE_DART_API_H_ */  /* NOLINT */
diff --git a/runtime/lib/errors_patch.dart b/runtime/lib/errors_patch.dart
index 29c14f5..98814f8 100644
--- a/runtime/lib/errors_patch.dart
+++ b/runtime/lib/errors_patch.dart
@@ -107,6 +107,12 @@
   final String _msg;
 }
 
+patch class UnsupportedError {
+  static _throwNew(String msg) {
+    throw new UnsupportedError(msg);
+  }
+}
+
 patch class CyclicInitializationError {
   static _throwNew(String variableName) {
     throw new CyclicInitializationError(variableName);
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index fb51c07..54a55ee 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -345,7 +345,7 @@
   GET_NATIVE_ARGUMENT(String, packageRoot, arguments->NativeArgAt(10));
   GET_NATIVE_ARGUMENT(String, packageConfig, arguments->NativeArgAt(11));
 
-  if (Dart::IsRunningPrecompiledCode()) {
+  if (Snapshot::IncludesCode(Dart::snapshot_kind())) {
     const Array& args = Array::Handle(Array::New(1));
     args.SetAt(0, String::Handle(String::New(
         "Isolate.spawnUri not supported under precompilation")));
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 33b61c6..1478f04 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -1980,7 +1980,7 @@
 
 DEFINE_NATIVE_ENTRY(DeclarationMirror_location, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Instance, reflectee, arguments->NativeArgAt(0));
-  Object& decl = Object::Handle();
+  Object& decl = Object::Handle(zone);
   if (reflectee.IsMirrorReference()) {
     const MirrorReference& decl_ref = MirrorReference::Cast(reflectee);
     decl = decl_ref.referent();
@@ -1990,7 +1990,7 @@
     UNREACHABLE();
   }
 
-  Script& script = Script::Handle();
+  Script& script = Script::Handle(zone);
   TokenPosition token_pos = TokenPosition::kNoSource;
 
   if (decl.IsFunction()) {
@@ -2018,7 +2018,7 @@
     token_pos = field.token_pos();
   } else if (decl.IsTypeParameter()) {
     const TypeParameter& type_var = TypeParameter::Cast(decl);
-    const Class& owner = Class::Handle(type_var.parameterized_class());
+    const Class& owner = Class::Handle(zone, type_var.parameterized_class());
     script = owner.script();
     token_pos = type_var.token_pos();
   } else if (decl.IsLibrary()) {
@@ -2026,20 +2026,20 @@
     if (lib.raw() == Library::NativeWrappersLibrary()) {
       return Instance::null();  // No source.
     }
-    const Array& scripts = Array::Handle(lib.LoadedScripts());
+    const Array& scripts = Array::Handle(zone, lib.LoadedScripts());
     for (intptr_t i = 0; i < scripts.Length(); i++) {
       script ^= scripts.At(i);
       if (script.kind() == RawScript::kLibraryTag) break;
     }
     ASSERT(!script.IsNull());
-    const String& libname = String::Handle(lib.name());
+    const String& libname = String::Handle(zone, lib.name());
     if (libname.Length() == 0) {
       // No library declaration.
-      const String& uri = String::Handle(script.url());
+      const String& uri = String::Handle(zone, script.url());
       return CreateSourceLocation(uri, 1, 1);
     }
-    const TokenStream& stream = TokenStream::Handle(script.tokens());
-    TokenStream::Iterator tkit(stream, TokenPosition::kMinSource);
+    const TokenStream& stream = TokenStream::Handle(zone, script.tokens());
+    TokenStream::Iterator tkit(zone, stream, TokenPosition::kMinSource);
     if (tkit.CurrentTokenKind() == Token::kSCRIPTTAG) tkit.Advance();
     token_pos = tkit.CurrentPosition();
   }
@@ -2047,7 +2047,7 @@
   ASSERT(!script.IsNull());
   ASSERT(token_pos != TokenPosition::kNoSource);
 
-  const String& uri = String::Handle(script.url());
+  const String& uri = String::Handle(zone, script.url());
   intptr_t from_line = 0;
   intptr_t from_col = 0;
   if (script.HasSource()) {
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index f7aa83c..4352245 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -230,7 +230,7 @@
 
   String operator [](int index) native "String_charAt";
 
-  int codeUnitAt(int index) native "String_codeUnitAt";
+  int codeUnitAt(int index);  // Implemented in the subclasses.
 
   int get length native "String_getLength";
 
@@ -937,6 +937,8 @@
 
   int get hashCode native "String_getHashCode";
 
+  int codeUnitAt(int index) native "String_codeUnitAt";
+
   bool _isWhitespace(int codeUnit) {
     return _StringBase._isOneByteWhitespace(codeUnit);
   }
@@ -1240,6 +1242,8 @@
     return _StringBase._isTwoByteWhitespace(codeUnit);
   }
 
+  int codeUnitAt(int index) native "String_codeUnitAt";
+
   bool operator ==(Object other) {
     return super == other;
   }
@@ -1256,6 +1260,8 @@
     return _StringBase._isOneByteWhitespace(codeUnit);
   }
 
+  int codeUnitAt(int index) native "String_codeUnitAt";
+
   bool operator ==(Object other) {
     return super == other;
   }
@@ -1274,6 +1280,8 @@
     return _StringBase._isTwoByteWhitespace(codeUnit);
   }
 
+  int codeUnitAt(int index) native "String_codeUnitAt";
+
   bool operator ==(Object other) {
     return super == other;
   }
diff --git a/runtime/lib/timeline.cc b/runtime/lib/timeline.cc
index df36a25..d8bef45 100644
--- a/runtime/lib/timeline.cc
+++ b/runtime/lib/timeline.cc
@@ -37,6 +37,11 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(Timeline_getThreadCpuClock, 0) {
+  return Integer::New(OS::GetCurrentThreadCPUMicros(), Heap::kNew);
+}
+
+
 DEFINE_NATIVE_ENTRY(Timeline_reportTaskEvent, 6) {
   if (!FLAG_support_timeline) {
     return Object::null();
@@ -108,7 +113,7 @@
     return Object::null();
   }
   GET_NON_NULL_NATIVE_ARGUMENT(Integer, start, arguments->NativeArgAt(0));
-  GET_NON_NULL_NATIVE_ARGUMENT(Integer, end, arguments->NativeArgAt(1));
+  GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_cpu, arguments->NativeArgAt(1));
   GET_NON_NULL_NATIVE_ARGUMENT(String, category, arguments->NativeArgAt(2));
   GET_NON_NULL_NATIVE_ARGUMENT(String, name, arguments->NativeArgAt(3));
   GET_NON_NULL_NATIVE_ARGUMENT(String, args, arguments->NativeArgAt(4));
@@ -124,24 +129,49 @@
     return Object::null();
   }
 
-  int64_t duration = end.AsInt64Value() - start.AsInt64Value();
+  const int64_t end = OS::GetCurrentMonotonicMicros();
+  const int64_t end_cpu = OS::GetCurrentThreadCPUMicros();
+  const int64_t duration = end - start.AsInt64Value();
+  const int64_t duration_cpu = end_cpu - start_cpu.AsInt64Value();
   int64_t pid = OS::ProcessId();
   OSThread* os_thread = thread->os_thread();
   ASSERT(os_thread != NULL);
   int64_t tid = OSThread::ThreadIdToIntPtr(os_thread->trace_id());
 
-  char* json = OS::SCreate(zone,
-      "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
-      "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ",\"args\":%s}",
-      name.ToCString(),
-      category.ToCString(),
-      tid,
-      pid,
-      start.AsInt64Value(),
-      duration,
-      args.ToCString());
+  char* json = NULL;
 
-  event->Duration("", start.AsInt64Value(), end.AsInt64Value());
+  if ((start_cpu.AsInt64Value() != -1) && (end_cpu != -1)) {
+    json = OS::SCreate(zone,
+        "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
+        "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ","
+        "\"tdur\":%" Pd64 ",\"args\":%s}",
+        name.ToCString(),
+        category.ToCString(),
+        tid,
+        pid,
+        start.AsInt64Value(),
+        duration,
+        duration_cpu,
+        args.ToCString());
+  } else {
+    json = OS::SCreate(zone,
+        "{\"name\":\"%s\",\"cat\":\"%s\",\"tid\":%" Pd64 ",\"pid\":%" Pd64 ","
+        "\"ts\":%" Pd64 ",\"ph\":\"X\",\"dur\":%" Pd64 ",\"args\":%s}",
+        name.ToCString(),
+        category.ToCString(),
+        tid,
+        pid,
+        start.AsInt64Value(),
+        duration,
+        args.ToCString());
+  }
+  ASSERT(json != NULL);
+
+  event->Duration("",
+                  start.AsInt64Value(),
+                  end,
+                  start_cpu.AsInt64Value(),
+                  end_cpu);
   // json was allocated in the zone and a copy will be stored in event.
   event->CompleteWithPreSerializedJSON(json);
 
diff --git a/runtime/lib/timeline.dart b/runtime/lib/timeline.dart
index 3a336e2..b4ecd44 100644
--- a/runtime/lib/timeline.dart
+++ b/runtime/lib/timeline.dart
@@ -6,6 +6,8 @@
 
 patch int _getTraceClock() native "Timeline_getTraceClock";
 
+patch int _getThreadCpuClock() native "Timeline_getThreadCpuClock";
+
 patch int _getNextAsyncId() native "Timeline_getNextAsyncId";
 
 patch int _getIsolateNum() native "Timeline_getIsolateNum";
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index c18b8ec..502f510 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -37,7 +37,7 @@
     const String& library_url = Symbols::DartVMService();
     ASSERT(!library_url.IsNull());
     const Library& library =
-        Library::Handle(Library::LookupLibrary(library_url));
+        Library::Handle(Library::LookupLibrary(thread, library_url));
     ASSERT(!library.IsNull());
     // Get function.
     const String& function_name =
diff --git a/runtime/observatory/lib/src/elements/script_inset.dart b/runtime/observatory/lib/src/elements/script_inset.dart
index 1b94f38..5776bc4 100644
--- a/runtime/observatory/lib/src/elements/script_inset.dart
+++ b/runtime/observatory/lib/src/elements/script_inset.dart
@@ -597,12 +597,15 @@
     for (var range in sourceReport['ranges']) {
       int startLine = script.tokenToLine(range['startPos']);
       int endLine = script.tokenToLine(range['endPos']);
-      for (var line = startLine; line <= endLine; line++) {
-        var rangeList = _rangeMap[line];
-        if (rangeList == null) {
-          _rangeMap[line] = [range];
-        } else {
-          rangeList.add(range);
+      // TODO(turnidge): Track down the root cause of null startLine/endLine.
+      if ((startLine != null) && (endLine != null)) {
+        for (var line = startLine; line <= endLine; line++) {
+          var rangeList = _rangeMap[line];
+          if (rangeList == null) {
+            _rangeMap[line] = [range];
+          } else {
+            rangeList.add(range);
+          }
         }
       }
       if (_includeProfile && range['profile'] != null) {
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 5bae881..9283031 100644
--- a/runtime/observatory/tests/service/get_version_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_version_rpc_test.dart
@@ -13,7 +13,7 @@
     var result = await vm.invokeRpcNoUpgrade('getVersion', {});
     expect(result['type'], equals('Version'));
     expect(result['major'], equals(3));
-    expect(result['minor'], equals(4));
+    expect(result['minor'], equals(5));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 8de2b3b..025a0f4 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -132,16 +132,14 @@
 cc/SourceReport_Coverage_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) DisassembleToJSONStream requires
-# DecodeLoadObjectFromPoolOrThread which is unimplemented.
-cc/Service_Code: Skip
-cc/PrintJSON: 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.
diff --git a/runtime/vm/aot_optimizer.cc b/runtime/vm/aot_optimizer.cc
index bc3bf8b..0318786 100644
--- a/runtime/vm/aot_optimizer.cc
+++ b/runtime/vm/aot_optimizer.cc
@@ -789,7 +789,7 @@
       return false;
     }
   } else {
-    return d->IsStringFromCharCode();
+    return d->IsOneByteStringFromCharCode();
   }
 }
 
@@ -823,9 +823,10 @@
       ConstantInstr* char_code_left = flow_graph()->GetConstant(
           Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0)))));
       left_val = new(Z) Value(char_code_left);
-    } else if (left->IsStringFromCharCode()) {
+    } else if (left->IsOneByteStringFromCharCode()) {
       // Use input of string-from-charcode as left value.
-      StringFromCharCodeInstr* instr = left->AsStringFromCharCode();
+      OneByteStringFromCharCodeInstr* instr =
+          left->AsOneByteStringFromCharCode();
       left_val = new(Z) Value(instr->char_code()->definition());
       to_remove_left = instr;
     } else {
@@ -835,9 +836,10 @@
 
     Definition* to_remove_right = NULL;
     Value* right_val = NULL;
-    if (right->IsStringFromCharCode()) {
+    if (right->IsOneByteStringFromCharCode()) {
       // Skip string-from-char-code, and use its input as right value.
-      StringFromCharCodeInstr* right_instr = right->AsStringFromCharCode();
+      OneByteStringFromCharCodeInstr* right_instr =
+          right->AsOneByteStringFromCharCode();
       right_val = new(Z) Value(right_instr->char_code()->definition());
       to_remove_right = right_instr;
     } else {
@@ -1787,11 +1789,24 @@
     return true;
   }
 
-  if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
-       (recognized_kind == MethodRecognizer::kStringBaseCharAt)) &&
-      (ic_data.NumberOfChecks() == 1) &&
-      ((class_ids[0] == kOneByteStringCid) ||
-       (class_ids[0] == kTwoByteStringCid))) {
+  if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) ||
+      (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) ||
+      (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
+      (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt)) {
+      ASSERT(ic_data.NumberOfChecks() == 1);
+      ASSERT((class_ids[0] == kOneByteStringCid) ||
+             (class_ids[0] == kTwoByteStringCid) ||
+             (class_ids[0] == kExternalOneByteStringCid) ||
+             (class_ids[0] == kExternalTwoByteStringCid));
+    return TryReplaceInstanceCallWithInline(call);
+  }
+
+  if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
+      (ic_data.NumberOfChecks() == 1)) {
+      ASSERT((class_ids[0] == kOneByteStringCid) ||
+             (class_ids[0] == kTwoByteStringCid) ||
+             (class_ids[0] == kExternalOneByteStringCid) ||
+             (class_ids[0] == kExternalTwoByteStringCid));
     return TryReplaceInstanceCallWithInline(call);
   }
 
diff --git a/runtime/vm/assembler_dbc_test.cc b/runtime/vm/assembler_dbc_test.cc
index 2941f20..11e579e 100644
--- a/runtime/vm/assembler_dbc_test.cc
+++ b/runtime/vm/assembler_dbc_test.cc
@@ -6,6 +6,7 @@
 #if defined(TARGET_ARCH_DBC)
 
 #include "vm/assembler.h"
+#include "vm/stack_frame.h"
 #include "vm/unit_test.h"
 
 namespace dart {
@@ -42,6 +43,18 @@
 }
 
 
+// Called from assembler_test.cc.
+// FP[-kParamEndSlotFromFp - 1]: growable array
+// FP[-kParamEndSlotFromFp - 2]: value
+ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
+  __ Frame(2);
+  __ Move(0, -kParamEndSlotFromFp - 1);
+  __ Move(1, -kParamEndSlotFromFp - 2);
+  __ StoreField(0, GrowableObjectArray::data_offset() / kWordSize, 1);
+  __ Return(0);
+}
+
+
 //  - AddTOS; SubTOS; MulTOS; BitOrTOS; BitAndTOS; EqualTOS; LessThanTOS;
 //    GreaterThanTOS;
 //
@@ -704,6 +717,317 @@
   EXPECT(EXECUTE_TEST_CODE_OBJECT(test->code()).IsError());
 }
 
+
+//  - Drop1; DropR n; Drop n
+//
+//    Drop 1 or n values from the stack, if instruction is DropR push the first
+//    dropped value to the stack;
+ASSEMBLER_TEST_GENERATE(Drop1, assembler) {
+  __ PushConstant(Smi::Handle(Smi::New(0)));
+  __ PushConstant(Smi::Handle(Smi::New(42)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ Drop1();
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(Drop1, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Drop, assembler) {
+  __ PushConstant(Smi::Handle(Smi::New(0)));
+  __ PushConstant(Smi::Handle(Smi::New(42)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ Drop(11);
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(Drop, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(DropR, assembler) {
+  __ PushConstant(Smi::Handle(Smi::New(0)));
+  __ PushConstant(Smi::Handle(Smi::New(1)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(37)));
+  __ PushConstant(Smi::Handle(Smi::New(41)));
+  __ DropR(11);
+  __ AddTOS();
+  __ PushConstant(Smi::Handle(Smi::New(0)));  // Should be skipped.
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(DropR, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+//  - Frame D
+//
+//    Reserve and initialize with null space for D local variables.
+ASSEMBLER_TEST_GENERATE(FrameInitialized1, assembler) {
+  __ Frame(1);
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(FrameInitialized1, test) {
+  EXPECT(EXECUTE_TEST_CODE_OBJECT(test->code()).IsNull());
+}
+
+
+ASSEMBLER_TEST_GENERATE(FrameInitialized, assembler) {
+  Label error;
+  __ PushConstant(Smi::Handle(Smi::New(42)));
+  __ Frame(4);
+  __ PushConstant(Object::null_object());
+  __ IfNeStrictTOS();
+  __ Jump(&error);
+  __ PushConstant(Object::null_object());
+  __ IfNeStrictTOS();
+  __ Jump(&error);
+  __ PushConstant(Object::null_object());
+  __ IfNeStrictTOS();
+  __ Jump(&error);
+  __ PushConstant(Object::null_object());
+  __ IfNeStrictTOS();
+  __ Jump(&error);
+  __ ReturnTOS();
+
+  // If a frame slot was not initialized to null.
+  __ Bind(&error);
+  __ PushConstant(Smi::Handle(Smi::New(0)));
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(FrameInitialized, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+//  - StoreLocal rX; PopLocal rX
+//
+//    Store top of the stack into FP[rX] and pop it if needed.
+//
+//  - Push rX
+//
+//    Push FP[rX] to the stack.
+ASSEMBLER_TEST_GENERATE(StoreLocalPush, assembler) {
+  __ Frame(1);
+  __ PushConstant(Smi::Handle(Smi::New(21)));
+  __ StoreLocal(0);
+  __ Push(0);
+  __ AddTOS();
+  __ PushConstant(Smi::Handle(Smi::New(0)));  // Should be skipped.
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(StoreLocalPush, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(PopLocalPush, assembler) {
+  __ Frame(1);
+  __ PushConstant(Smi::Handle(Smi::New(21)));
+  __ PopLocal(0);
+  __ Push(0);
+  __ Push(0);
+  __ AddTOS();
+  __ PushConstant(Smi::Handle(Smi::New(0)));  // Should be skipped.
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(PopLocalPush, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(LoadConstantPush, assembler) {
+  __ Frame(1);
+  __ LoadConstant(0, Smi::Handle(Smi::New(21)));
+  __ Push(0);
+  __ Push(0);
+  __ AddTOS();
+  __ PushConstant(Smi::Handle(Smi::New(0)));  // Should be skipped.
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(LoadConstantPush, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+//  - Move rA, rX
+//
+//    FP[rA] <- FP[rX]
+//    Note: rX is signed so it can be used to address parameters which are
+//    at negative indices with respect to FP.
+ASSEMBLER_TEST_GENERATE(MoveLocalLocal, assembler) {
+  __ Frame(2);
+  __ PushConstant(Smi::Handle(Smi::New(21)));
+  __ PopLocal(0);
+  __ Move(1, 0);
+  __ Push(0);
+  __ Push(1);
+  __ AddTOS();
+  __ PushConstant(Smi::Handle(Smi::New(0)));  // Should be skipped.
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(MoveLocalLocal, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+//  - Return R; ReturnTOS
+//
+//    Return to the caller using either a value from the given register or a
+//    value from the top-of-stack as a result.
+ASSEMBLER_TEST_GENERATE(Return1, assembler) {
+  __ Frame(1);
+  __ PushConstant(Smi::Handle(Smi::New(42)));
+  __ StoreLocal(0);
+  __ Return(0);
+}
+
+
+ASSEMBLER_TEST_RUN(Return1, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Return2, assembler) {
+  __ Frame(2);
+  __ PushConstant(Smi::Handle(Smi::New(42)));
+  __ StoreLocal(1);
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(Return2, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(Loop, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadConstant(1, Smi::Handle(Smi::New(0)));
+
+  Label loop_entry, error;
+  __ Bind(&loop_entry);
+  // Add 1 to FP[1].
+  __ PushConstant(Smi::Handle(Smi::New(1)));
+  __ Push(1);
+  __ AddTOS();
+  __ Jump(&error);
+  __ PopLocal(1);
+
+  // Subtract 1 from FP[0].
+  __ Push(0);
+  __ PushConstant(Smi::Handle(Smi::New(1)));
+  __ SubTOS();
+  __ Jump(&error);
+
+  // Jump to loop_entry if FP[0] != 0.
+  __ StoreLocal(0);
+  __ PushConstant(Smi::Handle(Smi::New(0)));
+  __ IfNeStrictNumTOS();
+  __ Jump(&loop_entry);
+
+  __ Return(1);
+
+  __ Bind(&error);
+  __ LoadConstant(1, Smi::Handle(Smi::New(-42)));
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(Loop, test) {
+  EXPECT_EQ(42, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+//  - LoadClassIdTOS, LoadClassId rA, D
+//
+//    LoadClassIdTOS loads the class id from the object at SP[0] and stores it
+//    to SP[0]. LoadClassId loads the class id from FP[rA] and stores it to
+//    FP[D].
+ASSEMBLER_TEST_GENERATE(LoadClassIdTOS, assembler) {
+  __ PushConstant(Smi::Handle(Smi::New(42)));
+  __ LoadClassIdTOS();
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(LoadClassIdTOS, test) {
+  EXPECT_EQ(kSmiCid, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+ASSEMBLER_TEST_GENERATE(LoadClassId, assembler) {
+  __ Frame(2);
+  __ LoadConstant(0, Smi::Handle(Smi::New(42)));
+  __ LoadClassId(1, 0);
+  __ Return(1);
+}
+
+
+ASSEMBLER_TEST_RUN(LoadClassId, test) {
+  EXPECT_EQ(kSmiCid, EXECUTE_TEST_CODE_INTPTR(test->code()));
+}
+
+
+//  - CreateArrayTOS
+//
+//    Allocate array of length SP[0] with type arguments SP[-1].
+ASSEMBLER_TEST_GENERATE(CreateArrayTOS, assembler) {
+  __ PushConstant(Object::null_object());
+  __ PushConstant(Smi::Handle(Smi::New(10)));
+  __ CreateArrayTOS();
+  __ ReturnTOS();
+}
+
+
+ASSEMBLER_TEST_RUN(CreateArrayTOS, test) {
+  const Object& obj = EXECUTE_TEST_CODE_OBJECT(test->code());
+  EXPECT(obj.IsArray());
+  Array& array = Array::Handle();
+  array ^= obj.raw();
+  EXPECT_EQ(10, array.Length());
+}
+
 }  // namespace dart
 
 #endif  // defined(TARGET_ARCH_DBC)
diff --git a/runtime/vm/assembler_test.cc b/runtime/vm/assembler_test.cc
index 88ff667..fbbd994 100644
--- a/runtime/vm/assembler_test.cc
+++ b/runtime/vm/assembler_test.cc
@@ -11,8 +11,6 @@
 
 namespace dart {
 
-// TODO(vegorov) assembler part of this test is not implemented.
-#if !defined(TARGET_ARCH_DBC)
 ASSEMBLER_TEST_EXTERN(StoreIntoObject);
 
 ASSEMBLER_TEST_RUN(StoreIntoObject, test) {
@@ -62,6 +60,5 @@
   EXPECT(old_array.raw() == grow_new_array.data());
   EXPECT(!thread->StoreBufferContains(grow_new_array.raw()));
 }
-#endif
 
 }  // namespace dart
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 13184af..790e94c 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -616,7 +616,7 @@
   DISALLOW_IMPLICIT_CONSTRUCTORS(PrimaryNode);
 };
 
-// In asynchronous code that gets suspeded and resumed, return nodes
+// In asynchronous code that gets suspended and resumed, return nodes
 // can be of different types:
 // * A regular return node that in the case of async functions
 //    gets replaced with appropriate completer calls. (kRegular)
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index 8e4975b..1d56af7 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -528,8 +528,7 @@
                             &vm_isolate_snapshot_buffer,
                             &isolate_snapshot_buffer,
                             &malloc_allocator,
-                            NULL, /* instructions_writer */
-                            true /* vm_isolate_is_symbolic */);
+                            NULL /* instructions_writer */);
   writer.WriteFullSnapshot();
   const Snapshot* snapshot = Snapshot::SetupFromBuffer(isolate_snapshot_buffer);
   ASSERT(snapshot->kind() == Snapshot::kCore);
@@ -565,8 +564,7 @@
                             &vm_isolate_snapshot_buffer,
                             &isolate_snapshot_buffer,
                             &malloc_allocator,
-                            NULL, /* instructions_writer */
-                            true /* vm_isolate_is_symbolic */);
+                            NULL /* instructions_writer */);
   writer.WriteFullSnapshot();
   const Snapshot* snapshot = Snapshot::SetupFromBuffer(isolate_snapshot_buffer);
   ASSERT(snapshot->kind() == Snapshot::kCore);
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 9bde826..ed97340 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -301,11 +301,11 @@
     }
 #endif  // !PRODUCT
     uri = Symbols::New(thread, bootstrap_libraries[i].uri_);
-    lib = Library::LookupLibrary(uri);
+    lib = Library::LookupLibrary(thread, uri);
     if (lib.IsNull()) {
       lib = Library::NewLibraryHelper(uri, false);
       lib.SetLoadRequested();
-      lib.Register();
+      lib.Register(thread);
     }
     isolate->object_store()->set_bootstrap_library(
         bootstrap_libraries[i].index_, lib);
@@ -321,7 +321,7 @@
     }
 #endif  // PRODUCT
     uri = Symbols::New(thread, bootstrap_libraries[i].uri_);
-    lib = Library::LookupLibrary(uri);
+    lib = Library::LookupLibrary(thread, uri);
     ASSERT(!lib.IsNull());
     source = GetLibrarySource(lib, uri, false);
     if (source.IsNull()) {
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 81d46ec..31b800c 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -161,6 +161,7 @@
   V(Timeline_getIsolateNum, 0)                                                 \
   V(Timeline_getNextAsyncId, 0)                                                \
   V(Timeline_getTraceClock, 0)                                                 \
+  V(Timeline_getThreadCpuClock, 0)                                             \
   V(Timeline_reportCompleteEvent, 5)                                           \
   V(Timeline_reportInstantEvent, 4)                                            \
   V(Timeline_reportTaskEvent, 6)                                               \
diff --git a/runtime/vm/cha_test.cc b/runtime/vm/cha_test.cc
index 0d0a1a4..7316da0 100644
--- a/runtime/vm/cha_test.cc
+++ b/runtime/vm/cha_test.cc
@@ -38,7 +38,7 @@
   TestCase::LoadTestScript(kScriptChars, NULL);
   EXPECT(ClassFinalizer::ProcessPendingClasses());
   const String& name = String::Handle(String::New(TestCase::url()));
-  const Library& lib = Library::Handle(Library::LookupLibrary(name));
+  const Library& lib = Library::Handle(Library::LookupLibrary(thread, name));
   EXPECT(!lib.IsNull());
 
   const Class& class_a = Class::Handle(
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 3cc1ef9..99b5b57 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -218,7 +218,7 @@
 
   EXPECT(ClassFinalizer::ProcessPendingClasses());
   const String& name = String::Handle(String::New(TestCase::url()));
-  const Library& lib = Library::Handle(Library::LookupLibrary(name));
+  const Library& lib = Library::Handle(Library::LookupLibrary(thread, name));
   EXPECT(!lib.IsNull());
   Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index 1d26af8..3f01605 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -449,9 +449,9 @@
   const SubtypeTestCache& cache =
       SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(3));
   ASSERT(type.IsFinalized());
-  ASSERT(!type.IsDynamicType());  // No need to check assignment.
   ASSERT(!type.IsMalformed());  // Already checked in code generator.
   ASSERT(!type.IsMalbounded());  // Already checked in code generator.
+  ASSERT(!type.IsDynamicType());  // No need to check assignment.
   Error& bound_error = Error::Handle(zone);
   const Bool& result =
       Bool::Get(instance.IsInstanceOf(type,
@@ -495,9 +495,9 @@
   const String& dst_name = String::CheckedHandle(zone, arguments.ArgAt(3));
   const SubtypeTestCache& cache =
       SubtypeTestCache::CheckedHandle(zone, arguments.ArgAt(4));
-  ASSERT(!dst_type.IsDynamicType());  // No need to check assignment.
   ASSERT(!dst_type.IsMalformed());  // Already checked in code generator.
   ASSERT(!dst_type.IsMalbounded());  // Already checked in code generator.
+  ASSERT(!dst_type.IsDynamicType());  // No need to check assignment.
   ASSERT(!src_instance.IsNull());  // Already checked in inlined code.
 
   Error& bound_error = Error::Handle(zone);
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index b532cf1..54a9174 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -213,14 +213,16 @@
 
 
 static Library& MakeTestLibrary(const char* url) {
-  const String& lib_url = String::ZoneHandle(Symbols::New(Thread::Current(),
-                                                          url));
-  Library& lib = Library::ZoneHandle(Library::New(lib_url));
-  lib.Register();
-  Library& core_lib = Library::Handle(Library::CoreLibrary());
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+
+  const String& lib_url = String::ZoneHandle(zone, Symbols::New(thread, url));
+  Library& lib = Library::ZoneHandle(zone, Library::New(lib_url));
+  lib.Register(thread);
+  Library& core_lib = Library::Handle(zone, Library::CoreLibrary());
   ASSERT(!core_lib.IsNull());
-  const Namespace& core_ns = Namespace::Handle(
-      Namespace::New(core_lib, Array::Handle(), Array::Handle()));
+  const Namespace& core_ns = Namespace::Handle(zone,
+      Namespace::New(core_lib, Array::Handle(zone), Array::Handle(zone)));
   lib.AddImport(core_ns);
   return lib;
 }
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 49796c1..e084f16 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -1341,10 +1341,7 @@
     } else if (FLAG_disassemble_optimized &&
                optimized &&
                FlowGraphPrinter::ShouldPrint(function)) {
-      // TODO(fschneider): Print unoptimized code along with the optimized code.
-      THR_Print("*** BEGIN CODE\n");
       Disassembler::DisassembleCode(function, true);
-      THR_Print("*** END CODE\n");
     }
     DEBUG_ONLY(CheckInliningIntervals(function));
     return Error::null();
@@ -1538,6 +1535,11 @@
     if (!func.HasCode() &&
         !func.is_abstract() &&
         !func.IsRedirectingFactory()) {
+      if ((cls.is_mixin_app_alias() || cls.IsMixinApplication()) &&
+          func.HasOptionalParameters()) {
+        // Skipping optional parameters in mixin application.
+        continue;
+      }
       error = CompileFunction(thread, func);
       if (!error.IsNull()) {
         return error.raw();
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index d23e6f0..d15df53 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -31,7 +31,8 @@
     }
     obj_ = raw_obj;
     if (obj_.GetClassId() == TokenStream::kClassId) {
-      TokenStream::Iterator tkit(TokenStream::Cast(obj_),
+      TokenStream::Iterator tkit(Thread::Current()->zone(),
+                                 TokenStream::Cast(obj_),
                                  TokenPosition::kMinSource,
                                  TokenStream::Iterator::kNoNewlines);
       Token::Kind kind = tkit.CurrentTokenKind();
diff --git a/runtime/vm/constant_propagator.cc b/runtime/vm/constant_propagator.cc
index 0b8d617..4409f3f 100644
--- a/runtime/vm/constant_propagator.cc
+++ b/runtime/vm/constant_propagator.cc
@@ -403,12 +403,6 @@
 }
 
 
-void ConstantPropagator::VisitPushTemp(PushTempInstr* instr) {
-  // Instruction is eliminated when translating to SSA.
-  UNREACHABLE();
-}
-
-
 void ConstantPropagator::VisitDropTemps(DropTempsInstr* instr) {
   // Instruction is eliminated when translating to SSA.
   UNREACHABLE();
@@ -610,8 +604,8 @@
 }
 
 
-void ConstantPropagator::VisitStringFromCharCode(
-    StringFromCharCodeInstr* instr) {
+void ConstantPropagator::VisitOneByteStringFromCharCode(
+    OneByteStringFromCharCodeInstr* instr) {
   const Object& o = instr->char_code()->definition()->constant_value();
   if (o.IsNull() || IsNonConstant(o)) {
     SetValue(instr, non_constant_);
diff --git a/runtime/vm/constants_dbc.h b/runtime/vm/constants_dbc.h
index f4144d6..54fc66b 100644
--- a/runtime/vm/constants_dbc.h
+++ b/runtime/vm/constants_dbc.h
@@ -302,6 +302,12 @@
 //    match patched call's argument count so that Return instructions continue
 //    to work.
 //
+//  - LoadClassIdTOS, LoadClassId rA, D
+//
+//    LoadClassIdTOS loads the class id from the object at SP[0] and stores it
+//    to SP[0]. LoadClassId loads the class id from FP[rA] and stores it to
+//    FP[D].
+//
 // TODO(vegorov) the way we replace calls with DebugBreak does not work
 //               with our smi fast paths because DebugBreak is simply skipped.
 //
@@ -462,6 +468,12 @@
 #endif
     return (call >> 8) & 0xFF;
   }
+
+  static Instr At(uword pc) { return *reinterpret_cast<Instr*>(pc); }
+
+ private:
+  DISALLOW_ALLOCATION();
+  DISALLOW_IMPLICIT_CONSTRUCTORS(Bytecode);
 };
 
 // Various dummy declarations to make shared code compile.
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index cd7dbde..0bc7a50 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -47,6 +47,7 @@
 ThreadPool* Dart::thread_pool_ = NULL;
 DebugInfo* Dart::pprof_symbol_generator_ = NULL;
 ReadOnlyHandles* Dart::predefined_handles_ = NULL;
+Snapshot::Kind Dart::snapshot_kind_ = Snapshot::kInvalid;
 const uint8_t* Dart::instructions_snapshot_buffer_ = NULL;
 const uint8_t* Dart::data_snapshot_buffer_ = NULL;
 Dart_ThreadExitCallback Dart::thread_exit_callback_ = NULL;
@@ -131,15 +132,6 @@
   if (vm_isolate_ != NULL || !Flags::Initialized()) {
     return "VM already initialized or flags not initialized.";
   }
-#if defined(DART_PRECOMPILED_RUNTIME)
-  if (instructions_snapshot == NULL) {
-    return "Precompiled runtime requires a precompiled snapshot";
-  }
-#else
-  if (instructions_snapshot != NULL) {
-    return "JIT runtime cannot run a precompiled snapshot";
-  }
-#endif
   set_thread_exit_callback(thread_exit);
   SetFileCallbacks(file_open, file_read, file_write, file_close);
   set_entropy_source_callback(entropy_source);
@@ -178,14 +170,12 @@
     ASSERT(vm_isolate_ == NULL);
     ASSERT(Flags::Initialized());
     const bool is_vm_isolate = true;
-    const bool precompiled = instructions_snapshot != NULL;
 
     // Setup default flags for the VM isolate.
     Dart_IsolateFlags api_flags;
     Isolate::FlagsInitialize(&api_flags);
     vm_isolate_ = Isolate::Init("vm-isolate", api_flags, is_vm_isolate);
     start_time_ = vm_isolate_->start_time();
-    vm_isolate_->set_compilation_allowed(!precompiled);
     // Verify assumptions about executing in the VM isolate.
     ASSERT(vm_isolate_ == Isolate::Current());
     ASSERT(vm_isolate_ == Thread::Current()->isolate());
@@ -200,24 +190,48 @@
     Object::InitOnce(vm_isolate_);
     ArgumentsDescriptor::InitOnce();
     ICData::InitOnce();
-    // When precompiled the stub code is initialized from the snapshot.
-    if (!precompiled) {
-      StubCode::InitOnce();
-    }
     if (vm_isolate_snapshot != NULL) {
       NOT_IN_PRODUCT(TimelineDurationScope tds(Timeline::GetVMStream(),
                                                "VMIsolateSnapshot"));
-      if (instructions_snapshot != NULL) {
-        vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot);
-      }
-      if (data_snapshot != NULL) {
-        vm_isolate_->SetupDataSnapshotPage(data_snapshot);
-      }
       const Snapshot* snapshot = Snapshot::SetupFromBuffer(vm_isolate_snapshot);
       if (snapshot == NULL) {
-        return "Invalid vm isolate snapshot seen.";
+        return "Invalid vm isolate snapshot seen";
       }
-      ASSERT(Snapshot::IsFull(snapshot->kind()));
+      snapshot_kind_ = snapshot->kind();
+      if (Snapshot::IncludesCode(snapshot_kind_)) {
+        if (snapshot_kind_ == Snapshot::kAppNoJIT) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+          vm_isolate_->set_compilation_allowed(false);
+          if (!FLAG_precompiled_runtime) {
+            return "Flag --precompilation was not specified";
+          }
+#else
+          return "JIT runtime cannot run a precompiled snapshot";
+#endif
+        }
+        if (instructions_snapshot == NULL) {
+          return "Missing instructions snapshot";
+        }
+        if (data_snapshot == NULL) {
+          return "Missing rodata snapshot";
+        }
+        vm_isolate_->SetupInstructionsSnapshotPage(instructions_snapshot);
+        vm_isolate_->SetupDataSnapshotPage(data_snapshot);
+      } else if (Snapshot::IsFull(snapshot_kind_)) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+        return "Precompiled runtime requires a precompiled snapshot";
+#else
+        if (instructions_snapshot != NULL) {
+          return "Unexpected instructions snapshot";
+        }
+        if (data_snapshot != NULL) {
+          return "Unexpected rodata snapshot";
+        }
+        StubCode::InitOnce();
+#endif
+      } else {
+        return "Invalid vm isolate snapshot seen";
+      }
       VmIsolateSnapshotReader reader(snapshot->kind(),
                                      snapshot->content(),
                                      snapshot->length(),
@@ -226,7 +240,7 @@
                                      T);
       const Error& error = Error::Handle(reader.ReadVmIsolateSnapshot());
       if (!error.IsNull()) {
-        return error.ToCString();
+        return error.ToErrorCString();
       }
       NOT_IN_PRODUCT(if (tds.enabled()) {
         tds.SetNumArguments(2);
@@ -247,7 +261,13 @@
         OS::Print("VM Isolate: Symbol table capacity : %" Pd "\n", capacity);
       }
     } else {
+#if defined(DART_PRECOMPILED_RUNTIME)
+      return "Precompiled runtime requires a precompiled snapshot";
+#else
+      snapshot_kind_ = Snapshot::kNone;
+      StubCode::InitOnce();
       Symbols::InitOnce(vm_isolate_);
+#endif
     }
     // We need to initialize the constants here for the vm isolate thread due to
     // bootstrapping issues.
@@ -487,6 +507,7 @@
       return ApiError::New(message);
     }
     ASSERT(Snapshot::IsFull(snapshot->kind()));
+    ASSERT(snapshot->kind() == snapshot_kind_);
     if (FLAG_trace_isolates) {
       OS::Print("Size of isolate snapshot = %" Pd "\n", snapshot->length());
     }
@@ -511,11 +532,7 @@
       MegamorphicCacheTable::PrintSizes(I);
     }
   } else {
-    // Populate the isolate's symbol table with all symbols from the
-    // VM isolate. We do this so that when we generate a full snapshot
-    // for the isolate we have a unified symbol table that we can then
-    // read into the VM isolate.
-    Symbols::AddPredefinedSymbolsToIsolate();
+    ASSERT(snapshot_kind_ == Snapshot::kNone);
   }
 
   Object::VerifyBuiltinVtables();
@@ -530,7 +547,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME)
   // When running precompiled, the megamorphic miss function/code comes from the
   // snapshot.
-  if (!Dart::IsRunningPrecompiledCode()) {
+  if (!Snapshot::IncludesCode(Dart::snapshot_kind())) {
     MegamorphicCacheTable::InitMissHandler(I);
   }
 #endif
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index afa2499..a21dab2 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -7,6 +7,7 @@
 
 #include "include/dart_api.h"
 #include "vm/allocation.h"
+#include "vm/snapshot.h"
 
 namespace dart {
 
@@ -60,16 +61,15 @@
   static uword AllocateReadOnlyHandle();
   static bool IsReadOnlyHandle(uword address);
 
+  static Snapshot::Kind snapshot_kind() {
+    return snapshot_kind_;
+  }
   static const uint8_t* instructions_snapshot_buffer() {
     return instructions_snapshot_buffer_;
   }
   static void set_instructions_snapshot_buffer(const uint8_t* buffer) {
     instructions_snapshot_buffer_ = buffer;
   }
-  static bool IsRunningPrecompiledCode() {
-    return instructions_snapshot_buffer_ != NULL;
-  }
-
   static const uint8_t* data_snapshot_buffer() {
     return data_snapshot_buffer_;
   }
@@ -121,6 +121,7 @@
   static ThreadPool* thread_pool_;
   static DebugInfo* pprof_symbol_generator_;
   static ReadOnlyHandles* predefined_handles_;
+  static Snapshot::Kind snapshot_kind_;
   static const uint8_t* instructions_snapshot_buffer_;
   static const uint8_t* data_snapshot_buffer_;
   static Dart_ThreadExitCallback thread_exit_callback_;
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 9dcaa4b..e980f09 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1148,9 +1148,6 @@
     Dart_FileCloseCallback file_close,
     Dart_EntropySource entropy_source,
     Dart_GetVMServiceAssetsArchive get_service_assets) {
-  if ((instructions_snapshot != NULL) && !FLAG_precompiled_runtime) {
-    return strdup("Flag --precompilation was not specified.");
-  }
   if (interrupt != NULL) {
     return strdup("Dart_Initialize: "
                   "Setting of interrupt callback is not supported.");
@@ -1485,20 +1482,19 @@
   if (::Dart_IsError(state)) {
     return state;
   }
-  I->heap()->CollectAllGarbage();
   I->StopBackgroundCompiler();
 
 #if defined(DEBUG)
+  I->heap()->CollectAllGarbage();
   FunctionVisitor check_canonical(T);
   I->heap()->IterateObjects(&check_canonical);
-#endif  // #if defined(DEBUG).
+#endif  // #if defined(DEBUG)
 
   FullSnapshotWriter writer(Snapshot::kCore,
                             vm_isolate_snapshot_buffer,
                             isolate_snapshot_buffer,
                             ApiReallocate,
-                            NULL, /* instructions_writer */
-                            true /* vm_isolate_is_symbolic */);
+                            NULL /* instructions_writer */);
   writer.WriteFullSnapshot();
   *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
   *isolate_snapshot_size = writer.IsolateSnapshotSize();
@@ -1528,11 +1524,13 @@
   } else {
     lib ^= Api::UnwrapHandle(library);
   }
-  I->heap()->CollectAllGarbage();
+
 #if defined(DEBUG)
+  I->heap()->CollectAllGarbage();
   FunctionVisitor check_canonical(T);
   I->heap()->IterateObjects(&check_canonical);
-#endif  // #if defined(DEBUG).
+#endif  // #if defined(DEBUG)
+
   ScriptSnapshotWriter writer(buffer, ApiReallocate);
   writer.WriteScriptSnapshot(lib);
   *size = writer.BytesWritten();
@@ -2841,8 +2839,8 @@
   // Lookup the class ArgumentError in dart:core.
   const String& lib_url = String::Handle(String::New("dart:core"));
   const String& class_name = String::Handle(String::New("ArgumentError"));
-  const Library& lib =
-      Library::Handle(zone, Library::LookupLibrary(lib_url));
+  const Library& lib = Library::Handle(zone,
+      Library::LookupLibrary(thread, lib_url));
   if (lib.IsNull()) {
     const String& message = String::Handle(
         String::NewFormatted("%s: library '%s' not found.",
@@ -3829,7 +3827,7 @@
   }
   if (constructor.IsGenerativeConstructor()) {
 #if defined(DEBUG)
-    if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+    if (!cls.is_allocated() && (Dart::snapshot_kind() == Snapshot::kAppNoJIT)) {
       return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
     }
 #endif
@@ -3924,7 +3922,7 @@
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
 #if defined(DEBUG)
-  if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+  if (!cls.is_allocated() && (Dart::snapshot_kind() == Snapshot::kAppNoJIT)) {
     return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
   }
 #endif
@@ -3954,7 +3952,7 @@
   }
   const Class& cls = Class::Handle(Z, type_obj.type_class());
 #if defined(DEBUG)
-  if (!cls.is_allocated() && Dart::IsRunningPrecompiledCode()) {
+  if (!cls.is_allocated() && (Dart::snapshot_kind() == Snapshot::kAppNoJIT)) {
     return Api::NewError("Precompilation dropped '%s'", cls.ToCString());
   }
 #endif
@@ -4122,6 +4120,15 @@
                            cls_name.ToCString(),
                            function_name.ToCString());
     }
+    NOT_IN_PRODUCT(if (tds.enabled()) {
+      const String& cls_name = String::Handle(Z, cls.Name());
+      tds.SetNumArguments(1);
+      tds.FormatArgument(0,
+                         "name",
+                         "%s.%s",
+                         cls_name.ToCString(),
+                         function_name.ToCString());
+    });
     // Setup args and check for malformed arguments in the arguments list.
     result = SetupArguments(T, number_of_arguments, arguments, 0, &args);
     if (!::Dart_IsError(result)) {
@@ -4157,6 +4164,17 @@
       }
       return result;
     }
+    NOT_IN_PRODUCT(if (tds.enabled()) {
+      const Class& cls = Class::Handle(Z, instance.clazz());
+      ASSERT(!cls.IsNull());
+      const String& cls_name = String::Handle(Z, cls.Name());
+      tds.SetNumArguments(1);
+      tds.FormatArgument(0,
+                         "name",
+                         "%s.%s",
+                         cls_name.ToCString(),
+                         function_name.ToCString());
+    });
     // Setup args and check for malformed arguments in the arguments list.
     result = SetupArguments(T, number_of_arguments, arguments, 1, &args);
     if (!::Dart_IsError(result)) {
@@ -4182,6 +4200,17 @@
                            CURRENT_FUNC,
                            function_name.ToCString());
     }
+
+    NOT_IN_PRODUCT(if (tds.enabled()) {
+      const String& lib_name = String::Handle(Z, lib.url());
+      tds.SetNumArguments(1);
+      tds.FormatArgument(0,
+                         "name",
+                         "%s.%s",
+                         lib_name.ToCString(),
+                         function_name.ToCString());
+    });
+
     // LookupFunctionAllowPrivate does not check argument arity, so we
     // do it here.
     String& error_message = String::Handle(Z);
@@ -4272,6 +4301,15 @@
       getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
     }
 
+    NOT_IN_PRODUCT(if (tds.enabled()) {
+      const String& cls_name = String::Handle(cls.Name());
+      tds.SetNumArguments(1);
+      tds.FormatArgument(0,
+                         "name",
+                         "%s.%s",
+                         cls_name.ToCString(), field_name.ToCString());
+    });
+
     if (!getter.IsNull()) {
       // Invoke the getter and return the result.
       return Api::NewHandle(
@@ -4298,6 +4336,15 @@
       cls = cls.SuperClass();
     }
 
+    NOT_IN_PRODUCT(if (tds.enabled()) {
+      const String& cls_name = String::Handle(cls.Name());
+      tds.SetNumArguments(1);
+      tds.FormatArgument(0,
+                         "name",
+                         "%s.%s",
+                         cls_name.ToCString(), field_name.ToCString());
+    });
+
     // Invoke the getter and return the result.
     const int kNumArgs = 1;
     const Array& args = Array::Handle(Z, Array::New(kNumArgs));
@@ -4337,6 +4384,15 @@
       getter = cls.LookupStaticFunctionAllowPrivate(getter_name);
     }
 
+    NOT_IN_PRODUCT(if (tds.enabled()) {
+      const String& lib_name = String::Handle(lib.url());
+      tds.SetNumArguments(1);
+      tds.FormatArgument(0,
+                         "name",
+                         "%s.%s",
+                         lib_name.ToCString(), field_name.ToCString());
+    });
+
     if (!getter.IsNull()) {
       // Invoke the getter and return the result.
       return Api::NewHandle(
@@ -4984,6 +5040,14 @@
       return Symbols::False().raw();
     }
 
+    if (name.Equals(Symbols::DartVMProduct())) {
+#ifdef PRODUCT
+      return Symbols::True().raw();
+#else
+      return Symbols::False().raw();
+#endif
+    }
+
     const String& prefix = Symbols::DartLibrary();
     if (name.StartsWith(prefix)) {
       const String& library_name =
@@ -4994,7 +5058,7 @@
         const String& dart_library_name =
             String::Handle(String::Concat(Symbols::DartScheme(), library_name));
         const Library& library =
-            Library::Handle(Library::LookupLibrary(dart_library_name));
+            Library::Handle(Library::LookupLibrary(thread, dart_library_name));
         if (!library.IsNull()) {
           return Symbols::True().raw();
         }
@@ -5147,7 +5211,7 @@
 
   library = Library::New(url_str);
   library.set_debuggable(true);
-  library.Register();
+  library.Register(T);
   I->object_store()->set_root_library(library);
 
   const Script& script = Script::Handle(Z,
@@ -5348,7 +5412,8 @@
   if (url_str.IsNull()) {
     RETURN_TYPE_ERROR(Z, url, String);
   }
-  const Library& library = Library::Handle(Z, Library::LookupLibrary(url_str));
+  const Library& library = Library::Handle(Z,
+      Library::LookupLibrary(T, url_str));
   if (library.IsNull()) {
     return Api::NewError("%s: library '%s' not found.",
                          CURRENT_FUNC, url_str.ToCString());
@@ -5414,10 +5479,10 @@
 
   NoHeapGrowthControlScope no_growth_control;
 
-  Library& library = Library::Handle(Z, Library::LookupLibrary(url_str));
+  Library& library = Library::Handle(Z, Library::LookupLibrary(T, url_str));
   if (library.IsNull()) {
     library = Library::New(url_str);
-    library.Register();
+    library.Register(T);
   } else if (library.LoadInProgress() ||
       library.Loaded() ||
       library.LoadFailed()) {
@@ -6117,14 +6182,15 @@
   if (assembly_size == NULL) {
     RETURN_NULL_ERROR(assembly_size);
   }
-  I->heap()->CollectAllGarbage();
   AssemblyInstructionsWriter instructions_writer(assembly_buffer,
                                                  ApiReallocate,
                                                  2 * MB /* initial_size */);
-  PrecompiledSnapshotWriter writer(vm_isolate_snapshot_buffer,
-                                   isolate_snapshot_buffer,
-                                   ApiReallocate,
-                                   &instructions_writer);
+  FullSnapshotWriter writer(Snapshot::kAppNoJIT,
+                            vm_isolate_snapshot_buffer,
+                            isolate_snapshot_buffer,
+                            ApiReallocate,
+                            &instructions_writer);
+
   writer.WriteFullSnapshot();
   *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
   *isolate_snapshot_size = writer.IsolateSnapshotSize();
@@ -6175,15 +6241,16 @@
   if (rodata_blob_size == NULL) {
     RETURN_NULL_ERROR(instructions_blob_size);
   }
-  I->heap()->CollectAllGarbage();
   BlobInstructionsWriter instructions_writer(instructions_blob_buffer,
                                              rodata_blob_buffer,
                                              ApiReallocate,
                                              2 * MB /* initial_size */);
-  PrecompiledSnapshotWriter writer(vm_isolate_snapshot_buffer,
-                                   isolate_snapshot_buffer,
-                                   ApiReallocate,
-                                   &instructions_writer);
+  FullSnapshotWriter writer(Snapshot::kAppNoJIT,
+                            vm_isolate_snapshot_buffer,
+                            isolate_snapshot_buffer,
+                            ApiReallocate,
+                            &instructions_writer);
+
   writer.WriteFullSnapshot();
   *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
   *isolate_snapshot_size = writer.IsolateSnapshotSize();
@@ -6195,8 +6262,112 @@
 #endif  // DART_PRECOMPILER
 
 
+DART_EXPORT Dart_Handle Dart_PrecompileJIT() {
+  API_TIMELINE_BEGIN_END;
+  DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
+  Dart_Handle result = Api::CheckAndFinalizePendingClasses(T);
+  if (::Dart_IsError(result)) {
+    return result;
+  }
+  CHECK_CALLBACK_STATE(T);
+  GrowableObjectArray& libraries =
+      GrowableObjectArray::Handle(Z, I->object_store()->libraries());
+  Library& lib = Library::Handle(Z);
+  Class& cls = Class::Handle(Z);
+  Error& error = Error::Handle(Z);
+  for (intptr_t i = 0; i < libraries.Length(); i++) {
+    lib ^= libraries.At(i);
+    ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
+    while (it.HasNext()) {
+      cls = it.GetNextClass();
+      if (cls.IsDynamicClass()) {
+        continue;  // class 'dynamic' is in the read-only VM isolate.
+      }
+      error = cls.EnsureIsFinalized(T);
+      if (!error.IsNull()) {
+        return Api::NewHandle(T, error.raw());
+      }
+    }
+  }
+  return Api::Success();
+}
+
+
+DART_EXPORT Dart_Handle Dart_CreatePrecompiledJITSnapshotBlob(
+    uint8_t** vm_isolate_snapshot_buffer,
+    intptr_t* vm_isolate_snapshot_size,
+    uint8_t** isolate_snapshot_buffer,
+    intptr_t* isolate_snapshot_size,
+    uint8_t** instructions_blob_buffer,
+    intptr_t* instructions_blob_size,
+    uint8_t** rodata_blob_buffer,
+    intptr_t* rodata_blob_size) {
+  ASSERT(FLAG_load_deferred_eagerly);
+  API_TIMELINE_DURATION;
+  DARTSCOPE(Thread::Current());
+  Isolate* I = T->isolate();
+  if (vm_isolate_snapshot_buffer == NULL) {
+    RETURN_NULL_ERROR(vm_isolate_snapshot_buffer);
+  }
+  if (vm_isolate_snapshot_size == NULL) {
+    RETURN_NULL_ERROR(vm_isolate_snapshot_size);
+  }
+  if (isolate_snapshot_buffer == NULL) {
+    RETURN_NULL_ERROR(isolate_snapshot_buffer);
+  }
+  if (isolate_snapshot_size == NULL) {
+    RETURN_NULL_ERROR(isolate_snapshot_size);
+  }
+  if (instructions_blob_buffer == NULL) {
+    RETURN_NULL_ERROR(instructions_blob_buffer);
+  }
+  if (instructions_blob_size == NULL) {
+    RETURN_NULL_ERROR(instructions_blob_size);
+  }
+  if (rodata_blob_buffer == NULL) {
+    RETURN_NULL_ERROR(instructions_blob_buffer);
+  }
+  if (rodata_blob_size == NULL) {
+    RETURN_NULL_ERROR(instructions_blob_size);
+  }
+  // Finalize all classes if needed.
+  Dart_Handle state = Api::CheckAndFinalizePendingClasses(T);
+  if (::Dart_IsError(state)) {
+    return state;
+  }
+  I->StopBackgroundCompiler();
+
+  BlobInstructionsWriter instructions_writer(instructions_blob_buffer,
+                                             rodata_blob_buffer,
+                                             ApiReallocate,
+                                             2 * MB /* initial_size */);
+  FullSnapshotWriter writer(Snapshot::kAppWithJIT,
+                            vm_isolate_snapshot_buffer,
+                            isolate_snapshot_buffer,
+                            ApiReallocate,
+                            &instructions_writer);
+  writer.WriteFullSnapshot();
+  *vm_isolate_snapshot_size = writer.VmIsolateSnapshotSize();
+  *isolate_snapshot_size = writer.IsolateSnapshotSize();
+  *instructions_blob_size = instructions_writer.InstructionsBlobSize();
+  *rodata_blob_size = instructions_writer.RodataBlobSize();
+
+  return Api::Success();
+}
+
+
 DART_EXPORT bool Dart_IsRunningPrecompiledCode() {
-  return Dart::IsRunningPrecompiledCode();
+  return Snapshot::IncludesCode(Dart::snapshot_kind());
+}
+
+
+DART_EXPORT bool Dart_IsPrecompiledRuntime() {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  return true;
+#else
+  return false;
+#endif
 }
 
 }  // namespace dart
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 02c28db..3b0f238 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -6799,7 +6799,7 @@
                             kPatchNoClassChars };
   const String& lib_url = String::Handle(String::New("theLibrary"));
 
-  const Library& lib = Library::Handle(Library::LookupLibrary(lib_url));
+  const Library& lib = Library::Handle(Library::LookupLibrary(thread, lib_url));
 
   for (int i = 0; i < 3; i++) {
     const String& patch_url = String::Handle(String::New(patchNames[i]));
diff --git a/runtime/vm/dart_api_message.cc b/runtime/vm/dart_api_message.cc
index 182fc7d..2d4e759 100644
--- a/runtime/vm/dart_api_message.cc
+++ b/runtime/vm/dart_api_message.cc
@@ -416,8 +416,8 @@
 }
 
 
-Dart_CObject* ApiMessageReader::ReadVMSymbol(intptr_t object_id) {
-  ASSERT(Symbols::IsVMSymbolId(object_id));
+Dart_CObject* ApiMessageReader::ReadPredefinedSymbol(intptr_t object_id) {
+  ASSERT(Symbols::IsPredefinedSymbolId(object_id));
   intptr_t symbol_id = object_id - kMaxPredefinedObjectIds;
   Dart_CObject* object;
   if (vm_symbol_references_ != NULL &&
@@ -433,7 +433,7 @@
     memset(vm_symbol_references_, 0, size);
   }
 
-  object = CreateDartCObjectString(Symbols::GetVMSymbol(object_id));
+  object = CreateDartCObjectString(Symbols::GetPredefinedSymbol(object_id));
   ASSERT(vm_symbol_references_[symbol_id] == NULL);
   vm_symbol_references_[symbol_id] = object;
   return object;
@@ -547,8 +547,8 @@
   if (object_id == kDoubleObject) {
     return AllocateDartCObjectDouble(ReadDouble());
   }
-  if (Symbols::IsVMSymbolId(object_id)) {
-    return ReadVMSymbol(object_id);
+  if (Symbols::IsPredefinedSymbolId(object_id)) {
+    return ReadPredefinedSymbol(object_id);
   }
   // No other VM isolate objects are supported.
   return AllocateDartCObjectNull();
diff --git a/runtime/vm/dart_api_message.h b/runtime/vm/dart_api_message.h
index f4675c4..bb1efa2 100644
--- a/runtime/vm/dart_api_message.h
+++ b/runtime/vm/dart_api_message.h
@@ -115,7 +115,7 @@
   Dart_CObject* ReadInlinedObject(intptr_t object_id);
   Dart_CObject* ReadObjectImpl();
   Dart_CObject* ReadIndexedObject(intptr_t object_id);
-  Dart_CObject* ReadVMSymbol(intptr_t object_id);
+  Dart_CObject* ReadPredefinedSymbol(intptr_t object_id);
   Dart_CObject* ReadObjectRef();
   Dart_CObject* ReadObject();
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 3cb92b2..6d11f18 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -766,8 +766,8 @@
         ASSERT(!type.IsNull());
         // Uninstantiated types are not added to ExceptionHandlers data.
         ASSERT(type.IsInstantiated());
-        if (type.IsDynamicType()) return frame;
         if (type.IsMalformed()) continue;
+        if (type.IsDynamicType()) return frame;
         if (exc_obj.IsInstanceOf(type, no_instantiator, NULL)) {
           return frame;
         }
@@ -1693,9 +1693,11 @@
 }
 
 
-static TokenPosition LastTokenOnLine(const TokenStream& tokens,
+static TokenPosition LastTokenOnLine(Zone* zone,
+                                     const TokenStream& tokens,
                                      TokenPosition pos) {
-  TokenStream::Iterator iter(tokens,
+  TokenStream::Iterator iter(zone,
+                             tokens,
                              pos,
                              TokenStream::Iterator::kAllTokens);
   ASSERT(iter.IsValid());
@@ -1780,10 +1782,11 @@
     last_token_pos = func.end_token_pos();
   }
 
-  Script& script = Script::Handle(func.script());
-  Code& code = Code::Handle(func.unoptimized_code());
+  Zone* zone = Thread::Current()->zone();
+  Script& script = Script::Handle(zone, func.script());
+  Code& code = Code::Handle(zone, func.unoptimized_code());
   ASSERT(!code.IsNull());
-  PcDescriptors& desc = PcDescriptors::Handle(code.pc_descriptors());
+  PcDescriptors& desc = PcDescriptors::Handle(zone, code.pc_descriptors());
 
   // First pass: find the safe point which is closest to the beginning
   // of the given token range.
@@ -1830,10 +1833,11 @@
   // the token on the line which is at the best fit column (if column
   // was specified) and has the lowest code address.
   if (best_fit_pos != TokenPosition::kMaxSource) {
-    const Script& script = Script::Handle(func.script());
-    const TokenStream& tokens = TokenStream::Handle(script.tokens());
+    const Script& script = Script::Handle(zone, func.script());
+    const TokenStream& tokens = TokenStream::Handle(zone, script.tokens());
     const TokenPosition begin_pos = best_fit_pos;
-    const TokenPosition end_of_line_pos = LastTokenOnLine(tokens, begin_pos);
+    const TokenPosition end_of_line_pos =
+        LastTokenOnLine(zone, tokens, begin_pos);
     uword lowest_pc_offset = kUwordMax;
     PcDescriptors::Iterator iter(desc, kSafepointKind);
     while (iter.MoveNext()) {
@@ -2662,13 +2666,15 @@
 
 
 bool Debugger::IsAtAsyncJump(ActivationFrame* top_frame) {
-  Object& closure_or_null = Object::Handle(top_frame->GetAsyncOperation());
+  Zone* zone = Thread::Current()->zone();
+  Object& closure_or_null =
+      Object::Handle(zone, top_frame->GetAsyncOperation());
   if (!closure_or_null.IsNull()) {
     ASSERT(closure_or_null.IsInstance());
     ASSERT(Instance::Cast(closure_or_null).IsClosure());
-    const Script& script = Script::Handle(top_frame->SourceScript());
-    const TokenStream& tokens = TokenStream::Handle(script.tokens());
-    TokenStream::Iterator iter(tokens, top_frame->TokenPos());
+    const Script& script = Script::Handle(zone, top_frame->SourceScript());
+    const TokenStream& tokens = TokenStream::Handle(zone, script.tokens());
+    TokenStream::Iterator iter(zone, tokens, top_frame->TokenPos());
     if ((iter.CurrentTokenKind() == Token::kIDENT) &&
         ((iter.CurrentLiteral() == Symbols::Await().raw()) ||
          (iter.CurrentLiteral() == Symbols::YieldKw().raw()))) {
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index f98b60a..4bfcae1 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -789,13 +789,14 @@
   UNWRAP_AND_CHECK_PARAM(String, library_url, library_url_in);
   UNWRAP_AND_CHECK_PARAM(String, script_url, script_url_in);
 
-  const Library& library = Library::Handle(Library::LookupLibrary(library_url));
+  const Library& library = Library::Handle(Z,
+      Library::LookupLibrary(T, library_url));
   if (library.IsNull()) {
     return Api::NewError("%s: library '%s' not found",
                          CURRENT_FUNC, library_url.ToCString());
   }
 
-  const Script& script = Script::Handle(library.LookupScript(script_url));
+  const Script& script = Script::Handle(Z, library.LookupScript(script_url));
   if (script.IsNull()) {
     return Api::NewError("%s: script '%s' not found in library '%s'",
                          CURRENT_FUNC, script_url.ToCString(),
@@ -810,17 +811,18 @@
   DARTSCOPE(Thread::Current());
   UNWRAP_AND_CHECK_PARAM(String, library_url, library_url_in);
 
-  const Library& library = Library::Handle(Library::LookupLibrary(library_url));
+  const Library& library = Library::Handle(Z,
+      Library::LookupLibrary(T, library_url));
   if (library.IsNull()) {
     return Api::NewError("%s: library '%s' not found",
                          CURRENT_FUNC, library_url.ToCString());
   }
-  const Array& loaded_scripts = Array::Handle(library.LoadedScripts());
+  const Array& loaded_scripts = Array::Handle(Z, library.LoadedScripts());
   ASSERT(!loaded_scripts.IsNull());
   intptr_t num_scripts = loaded_scripts.Length();
-  const Array& script_list = Array::Handle(Array::New(num_scripts));
-  Script& script = Script::Handle();
-  String& url = String::Handle();
+  const Array& script_list = Array::Handle(Z, Array::New(num_scripts));
+  Script& script = Script::Handle(Z);
+  String& url = String::Handle(Z);
   for (int i = 0; i < num_scripts; i++) {
     script ^= loaded_scripts.At(i);
     url = script.url();
diff --git a/runtime/vm/flow_graph.cc b/runtime/vm/flow_graph.cc
index 8c69bc7..bac0c4b 100644
--- a/runtime/vm/flow_graph.cc
+++ b/runtime/vm/flow_graph.cc
@@ -1080,8 +1080,8 @@
     // 2a. Handle uses:
     // Update the expression stack renaming environment for each use by
     // removing the renamed value.
-    // For each use of a LoadLocal, StoreLocal, or Constant: Replace it with
-    // the renamed value.
+    // For each use of a LoadLocal, StoreLocal, DropTemps or Constant: Replace
+    // it with the renamed value.
     for (intptr_t i = current->InputCount() - 1; i >= 0; --i) {
       Value* v = current->InputAt(i);
       // Update expression stack.
@@ -1089,13 +1089,11 @@
 
       Definition* reaching_defn = env->RemoveLast();
       Definition* input_defn = v->definition();
-      if (input_defn->IsLoadLocal() ||
-          input_defn->IsStoreLocal() ||
-          input_defn->IsPushTemp() ||
-          input_defn->IsDropTemps() ||
-          input_defn->IsConstant()) {
-        // Remove the load/store from the graph.
-        input_defn->RemoveFromGraph();
+      if (input_defn != reaching_defn) {
+        ASSERT(input_defn->IsLoadLocal() ||
+               input_defn->IsStoreLocal() ||
+               input_defn->IsDropTemps() ||
+               input_defn->IsConstant());
         // Assert we are not referencing nulls in the initial environment.
         ASSERT(reaching_defn->ssa_temp_index() != -1);
         v->set_definition(reaching_defn);
@@ -1109,17 +1107,15 @@
       env->RemoveLast();
     }
 
-    // 2b. Handle LoadLocal, StoreLocal, and Constant.
+    // 2b. Handle LoadLocal, StoreLocal, DropTemps and Constant.
     Definition* definition = current->AsDefinition();
     if (definition != NULL) {
       LoadLocalInstr* load = definition->AsLoadLocal();
       StoreLocalInstr* store = definition->AsStoreLocal();
-      PushTempInstr* push = definition->AsPushTemp();
       DropTempsInstr* drop = definition->AsDropTemps();
       ConstantInstr* constant = definition->AsConstant();
       if ((load != NULL) ||
           (store != NULL) ||
-          (push != NULL) ||
           (drop != NULL) ||
           (constant != NULL)) {
         Definition* result = NULL;
@@ -1158,12 +1154,6 @@
             intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
             captured_parameters_->Add(index);
           }
-
-        } else if (push != NULL) {
-          result = push->value()->definition();
-          env->Add(result);
-          it.RemoveCurrentFromGraph();
-          continue;
         } else if (drop != NULL) {
           // Drop temps from the environment.
           for (intptr_t j = 0; j < drop->num_temps(); j++) {
@@ -1181,13 +1171,10 @@
         if (definition->HasTemp()) {
           ASSERT(result != NULL);
           env->Add(result);
-          // We remove load/store/constant instructions when we find their
-          // use in 2a.
-        } else {
-          it.RemoveCurrentFromGraph();
         }
+        it.RemoveCurrentFromGraph();
       } else {
-        // Not a load, store, or constant.
+        // Not a load, store, drop or constant.
         if (definition->HasTemp()) {
           // Assign fresh SSA temporary and update expression stack.
           AllocateSSAIndexes(definition);
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index 0a78c7b..b968585 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -2247,9 +2247,6 @@
 
 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(
     Value* value, TokenPosition token_pos) {
-  Do(new(Z) PushTempInstr(value));
-  owner()->AllocateTemp();
-
   ASSERT(value->definition()->temp_index() == (owner()->temp_count() - 1));
   intptr_t index = GetCurrentTempLocalIndex();
   char name[64];
@@ -2278,12 +2275,9 @@
     ValueGraphVisitor for_value(owner());
     node->InitializerAt(i)->Visit(&for_value);
     Append(for_value);
-    Value* temp_val = for_value.value();
     ASSERT(!node->TempAt(i)->HasIndex() ||
            (node->TempAt(i)->index() == GetCurrentTempLocalIndex()));
     node->TempAt(i)->set_index(GetCurrentTempLocalIndex());
-    Do(new(Z) PushTempInstr(temp_val));
-    owner()->AllocateTemp();
   }
 }
 
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index 006053f..71fcec4 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -1400,7 +1400,7 @@
   }
 
   // Allocate all unallocated input locations.
-  const bool should_pop = !instr->IsPushArgument() && !instr->IsPushTemp();
+  const bool should_pop = !instr->IsPushArgument();
   for (intptr_t i = locs->input_count() - 1; i >= 0; i--) {
     Location loc = locs->in(i);
     Register reg = kNoRegister;
@@ -1932,7 +1932,6 @@
 
   switch (instr->tag()) {
     case Instruction::kPushArgument:
-    case Instruction::kPushTemp:
       // Do nothing.
       break;
 
diff --git a/runtime/vm/flow_graph_compiler_dbc.cc b/runtime/vm/flow_graph_compiler_dbc.cc
index 2f3ff8e..92ba799 100644
--- a/runtime/vm/flow_graph_compiler_dbc.cc
+++ b/runtime/vm/flow_graph_compiler_dbc.cc
@@ -132,7 +132,6 @@
         (defn->tag() != Instruction::kStoreLocal) &&
         (defn->tag() != Instruction::kStoreInstanceField) &&
         (defn->tag() != Instruction::kDropTemps) &&
-        (defn->tag() != Instruction::kPushTemp) &&
         !defn->HasTemp()) {
       __ Drop1();
     }
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 471c511..c360c98 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -2803,6 +2803,25 @@
                                 call->env(),
                                 FlowGraph::kEffect);
 
+  // For external strings: Load backing store.
+  if (cid == kExternalOneByteStringCid) {
+    str = new LoadUntaggedInstr(new Value(str),
+                                ExternalOneByteString::external_data_offset());
+    cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
+    str = new LoadUntaggedInstr(
+        new Value(str),
+        RawExternalOneByteString::ExternalData::data_offset());
+    cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
+  } else if (cid == kExternalTwoByteStringCid) {
+    str = new LoadUntaggedInstr(new Value(str),
+                                ExternalTwoByteString::external_data_offset());
+    cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
+    str = new LoadUntaggedInstr(
+        new Value(str),
+        RawExternalTwoByteString::ExternalData::data_offset());
+    cursor = flow_graph->AppendTo(cursor, str, NULL, FlowGraph::kValue);
+  }
+
   LoadIndexedInstr* load_indexed = new(Z) LoadIndexedInstr(
       new(Z) Value(str),
       new(Z) Value(index),
@@ -2823,8 +2842,7 @@
     intptr_t cid,
     TargetEntryInstr** entry,
     Definition** last) {
-  // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp.
-  if (RawObject::IsExternalStringClassId(cid) || cid != kOneByteStringCid) {
+  if ((cid != kOneByteStringCid) && (cid != kExternalOneByteStringCid)) {
     return false;
   }
   Definition* str = call->ArgumentAt(0);
@@ -2836,8 +2854,8 @@
 
   *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry);
 
-  StringFromCharCodeInstr* char_at = new(Z) StringFromCharCodeInstr(
-      new(Z) Value(*last), cid);
+  OneByteStringFromCharCodeInstr* char_at =
+      new(Z) OneByteStringFromCharCodeInstr(new(Z) Value(*last));
 
   flow_graph->AppendTo(*last, char_at, NULL, FlowGraph::kValue);
   *last = char_at;
@@ -2852,11 +2870,6 @@
     intptr_t cid,
     TargetEntryInstr** entry,
     Definition** last) {
-  // TODO(johnmccutchan): Handle external strings in PrepareInlineStringIndexOp.
-  if (RawObject::IsExternalStringClassId(cid)) {
-    return false;
-  }
-
   Definition* str = call->ArgumentAt(0);
   Definition* index = call->ArgumentAt(1);
 
@@ -3097,7 +3110,10 @@
                                       receiver_cid,
                                       kTypedDataInt32x4ArrayCid,
                                       entry, last);
-    case MethodRecognizer::kStringBaseCodeUnitAt:
+    case MethodRecognizer::kOneByteStringCodeUnitAt:
+    case MethodRecognizer::kTwoByteStringCodeUnitAt:
+    case MethodRecognizer::kExternalOneByteStringCodeUnitAt:
+    case MethodRecognizer::kExternalTwoByteStringCodeUnitAt:
       return InlineStringCodeUnitAt(
           flow_graph, call, receiver_cid, entry, last);
     case MethodRecognizer::kStringBaseCharAt:
diff --git a/runtime/vm/flow_graph_type_propagator.cc b/runtime/vm/flow_graph_type_propagator.cc
index b4a5f3b..d0391db 100644
--- a/runtime/vm/flow_graph_type_propagator.cc
+++ b/runtime/vm/flow_graph_type_propagator.cc
@@ -910,11 +910,6 @@
 }
 
 
-CompileType PushTempInstr::ComputeType() const {
-  return CompileType::Dynamic();
-}
-
-
 CompileType DropTempsInstr::ComputeType() const {
   return *value()->Type();
 }
@@ -926,8 +921,8 @@
 }
 
 
-CompileType StringFromCharCodeInstr::ComputeType() const {
-  return CompileType::FromCid(cid_);
+CompileType OneByteStringFromCharCodeInstr::ComputeType() const {
+  return CompileType::FromCid(kOneByteStringCid);
 }
 
 
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index ef4e14c..2c92b17 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -381,6 +381,7 @@
     UpdatePretenurePolicy();
     RecordAfterGC(kNew);
     PrintStats();
+    NOT_IN_PRODUCT(PrintStatsToTimeline(&tds));
     EndNewSpaceGC();
     if ((reason == kNewSpace) && old_space_.NeedsGarbageCollection()) {
       // Old collections should call the API callbacks.
@@ -403,6 +404,7 @@
     old_space_.MarkSweep(invoke_api_callbacks);
     RecordAfterGC(kOld);
     PrintStats();
+    NOT_IN_PRODUCT(PrintStatsToTimeline(&tds));
     EndOldSpaceGC();
   }
 }
@@ -834,6 +836,66 @@
 }
 
 
+void Heap::PrintStatsToTimeline(TimelineEventScope* event) {
+#if !defined(PRODUCT)
+  if ((event == NULL) || !event->enabled()) {
+    return;
+  }
+  event->SetNumArguments(12);
+  event->FormatArgument(0,
+                        "Before.New.Used (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.before_.new_.used_in_words));
+  event->FormatArgument(1,
+                        "After.New.Used (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.after_.new_.used_in_words));
+  event->FormatArgument(2,
+                        "Before.Old.Used (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.before_.old_.used_in_words));
+  event->FormatArgument(3,
+                        "After.Old.Used (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.after_.old_.used_in_words));
+
+  event->FormatArgument(4,
+                        "Before.New.Capacity (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.before_.new_.capacity_in_words));
+  event->FormatArgument(5,
+                        "After.New.Capacity (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.after_.new_.capacity_in_words));
+  event->FormatArgument(6,
+                        "Before.Old.Capacity (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.before_.old_.capacity_in_words));
+  event->FormatArgument(7,
+                        "After.Old.Capacity (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.after_.old_.capacity_in_words));
+
+  event->FormatArgument(8,
+                        "Before.New.External (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.before_.new_.external_in_words));
+  event->FormatArgument(9,
+                        "After.New.External (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.after_.new_.external_in_words));
+  event->FormatArgument(10,
+                        "Before.Old.External (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.before_.old_.external_in_words));
+  event->FormatArgument(11,
+                        "After.Old.External (kB)",
+                        "%" Pd "",
+                        RoundWordsToKB(stats_.after_.old_.external_in_words));
+#endif  // !defined(PRODUCT)
+}
+
+
 NoHeapGrowthControlScope::NoHeapGrowthControlScope()
     : StackResource(Thread::Current()) {
     Heap* heap = reinterpret_cast<Isolate*>(isolate())->heap();
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 1526424..c5a7693 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -22,6 +22,7 @@
 class ObjectPointerVisitor;
 class ObjectSet;
 class ServiceEvent;
+class TimelineEventScope;
 class VirtualMemory;
 
 class Heap {
@@ -327,6 +328,7 @@
   void PrintStats();
   void UpdateClassHeapStatsBeforeGC(Heap::Space space);
   void UpdatePretenurePolicy();
+  void PrintStatsToTimeline(TimelineEventScope* event);
 
   // Updates gc in progress flags.
   bool BeginNewSpaceGC(Thread* thread);
diff --git a/runtime/vm/instructions_dbc.cc b/runtime/vm/instructions_dbc.cc
index 38b69f4..ec7945f 100644
--- a/runtime/vm/instructions_dbc.cc
+++ b/runtime/vm/instructions_dbc.cc
@@ -109,10 +109,40 @@
 }
 
 
+static bool HasLoadFromPool(Instr instr) {
+  switch (Bytecode::DecodeOpcode(instr)) {
+    case Bytecode::kLoadConstant:
+    case Bytecode::kPushConstant:
+    case Bytecode::kStaticCall:
+    case Bytecode::kInstanceCall:
+    case Bytecode::kInstanceCall2:
+    case Bytecode::kInstanceCall3:
+    case Bytecode::kStoreStaticTOS:
+    case Bytecode::kPushStatic:
+    case Bytecode::kAllocate:
+    case Bytecode::kInstantiateType:
+    case Bytecode::kInstantiateTypeArgumentsTOS:
+    case Bytecode::kAssertAssignable:
+      return true;
+    default:
+      return false;
+  }
+}
+
+
 bool DecodeLoadObjectFromPoolOrThread(uword pc,
                                       const Code& code,
                                       Object* obj) {
-  UNIMPLEMENTED();
+  ASSERT(code.ContainsInstructionAt(pc));
+  Instr instr = Bytecode::At(pc);
+  if (HasLoadFromPool(instr)) {
+    uint16_t index = Bytecode::DecodeD(instr);
+    const ObjectPool& pool = ObjectPool::Handle(code.object_pool());
+    if (pool.InfoAt(index) == ObjectPool::kTaggedObject) {
+      *obj = pool.ObjectAt(index);
+      return true;
+    }
+  }
   return false;
 }
 
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 3869329..3950f3e 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -2969,21 +2969,6 @@
 }
 
 
-LocationSummary* PushTempInstr::MakeLocationSummary(Zone* zone,
-                                                    bool optimizing) const {
-  return LocationSummary::Make(zone,
-                               1,
-                               Location::NoLocation(),
-                               LocationSummary::kNoCall);
-}
-
-
-void PushTempInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
-  ASSERT(!compiler->is_optimizing());
-  // Nothing to do.
-}
-
-
 LocationSummary* DropTempsInstr::MakeLocationSummary(Zone* zone,
                                                      bool optimizing) const {
   return (InputCount() == 1)
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 1536cf4..a7f522d 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -454,7 +454,6 @@
   M(PolymorphicInstanceCall)                                                   \
   M(StaticCall)                                                                \
   M(LoadLocal)                                                                 \
-  M(PushTemp)                                                                  \
   M(DropTemps)                                                                 \
   M(StoreLocal)                                                                \
   M(StrictCompare)                                                             \
@@ -515,7 +514,7 @@
   M(CheckArrayBound)                                                           \
   M(Constraint)                                                                \
   M(StringToCharCode)                                                          \
-  M(StringFromCharCode)                                                        \
+  M(OneByteStringFromCharCode)                                                 \
   M(StringInterpolate)                                                         \
   M(InvokeMathCFunction)                                                       \
   M(MergedMath)                                                                \
@@ -3368,34 +3367,6 @@
 };
 
 
-class PushTempInstr : public TemplateDefinition<1, NoThrow> {
- public:
-  explicit PushTempInstr(Value* value) {
-    SetInputAt(0, value);
-  }
-
-  DECLARE_INSTRUCTION(PushTemp)
-
-  Value* value() const { return inputs_[0]; }
-
-  virtual CompileType ComputeType() const;
-
-  virtual bool CanDeoptimize() const { return false; }
-
-  virtual EffectSet Effects() const {
-    UNREACHABLE();  // Eliminated by SSA construction.
-    return EffectSet::None();
-  }
-
-  virtual TokenPosition token_pos() const {
-    return TokenPosition::kTempMove;
-  }
-
- private:
-  DISALLOW_COPY_AND_ASSIGN(PushTempInstr);
-};
-
-
 class DropTempsInstr : public Definition {
  public:
   DropTempsInstr(intptr_t num_temps, Value* value)
@@ -3958,17 +3929,14 @@
 };
 
 
-class StringFromCharCodeInstr : public TemplateDefinition<1, NoThrow, Pure> {
+class OneByteStringFromCharCodeInstr
+    : public TemplateDefinition<1, NoThrow, Pure> {
  public:
-  StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
-    ASSERT(char_code != NULL);
-    ASSERT(char_code->definition()->IsLoadIndexed());
-    ASSERT(char_code->definition()->AsLoadIndexed()->class_id() ==
-           kOneByteStringCid);
+  explicit OneByteStringFromCharCodeInstr(Value* char_code) {
     SetInputAt(0, char_code);
   }
 
-  DECLARE_INSTRUCTION(StringFromCharCode)
+  DECLARE_INSTRUCTION(OneByteStringFromCharCode)
   virtual CompileType ComputeType() const;
 
   Value* char_code() const { return inputs_[0]; }
@@ -3976,13 +3944,11 @@
   virtual bool CanDeoptimize() const { return false; }
 
   virtual bool AttributesEqual(Instruction* other) const {
-    return other->AsStringFromCharCode()->cid_ == cid_;
+    return true;
   }
 
  private:
-  const intptr_t cid_;
-
-  DISALLOW_COPY_AND_ASSIGN(StringFromCharCodeInstr);
+  DISALLOW_COPY_AND_ASSIGN(OneByteStringFromCharCodeInstr);
 };
 
 
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index 2c7d44e..4123a2a 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -968,8 +968,8 @@
 }
 
 
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
-                                                              bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+    Zone* zone, bool opt) const {
   const intptr_t kNumInputs = 1;
   // TODO(fschneider): Allow immediate operands for the char code.
   return LocationSummary::Make(zone,
@@ -979,7 +979,8 @@
 }
 
 
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+    FlowGraphCompiler* compiler) {
   ASSERT(compiler->is_optimizing());
   const Register char_code = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
@@ -1111,6 +1112,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return CompileType::FromCid(kSmiCid);
 
     case kTypedDataInt32ArrayCid:
@@ -1137,6 +1140,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return kTagged;
     case kTypedDataInt32ArrayCid:
       return kUnboxedInt32;
@@ -1314,6 +1319,7 @@
     case kExternalTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
+    case kExternalOneByteStringCid:
       ASSERT(index_scale() == 1);
       __ ldrb(result, element_address);
       __ SmiTag(result);
@@ -1324,6 +1330,7 @@
       break;
     case kTypedDataUint16ArrayCid:
     case kTwoByteStringCid:
+    case kExternalTwoByteStringCid:
       __ ldrh(result, element_address);
       __ SmiTag(result);
       break;
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index f627e6e..29eae7d 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -822,8 +822,8 @@
 }
 
 
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
-                                                              bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+    Zone* zone, bool opt) const {
   const intptr_t kNumInputs = 1;
   // TODO(fschneider): Allow immediate operands for the char code.
   return LocationSummary::Make(zone,
@@ -833,7 +833,8 @@
 }
 
 
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+    FlowGraphCompiler* compiler) {
   ASSERT(compiler->is_optimizing());
   const Register char_code = locs()->in(0).reg();
   const Register result = locs()->out(0).reg();
@@ -968,6 +969,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
     case kTypedDataInt32ArrayCid:
     case kTypedDataUint32ArrayCid:
       return CompileType::FromCid(kSmiCid);
@@ -992,6 +995,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return kTagged;
     case kTypedDataInt32ArrayCid:
       return kUnboxedInt32;
@@ -1125,6 +1130,7 @@
     case kExternalTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
+    case kExternalOneByteStringCid:
       ASSERT(index_scale() == 1);
       __ ldr(result, element_address, kUnsignedByte);
       __ SmiTag(result);
@@ -1135,6 +1141,7 @@
       break;
     case kTypedDataUint16ArrayCid:
     case kTwoByteStringCid:
+    case kExternalTwoByteStringCid:
       __ ldr(result, element_address, kUnsignedHalfword);
       __ SmiTag(result);
       break;
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 44d16ed..5a7d5ce 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -840,8 +840,8 @@
 }
 
 
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
-                                                              bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+    Zone* zone, bool opt) const {
   const intptr_t kNumInputs = 1;
   // TODO(fschneider): Allow immediate operands for the char code.
   return LocationSummary::Make(zone,
@@ -851,7 +851,8 @@
 }
 
 
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+    FlowGraphCompiler* compiler) {
   Register char_code = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
   __ movl(result,
@@ -1000,6 +1001,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return CompileType::FromCid(kSmiCid);
 
     case kTypedDataInt32ArrayCid:
@@ -1026,6 +1029,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return kTagged;
     case kTypedDataInt32ArrayCid:
       return kUnboxedInt32;
@@ -1159,6 +1164,7 @@
     case kExternalTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
+    case kExternalOneByteStringCid:
       ASSERT(index_scale() == 1);
       __ movzxb(result, element_address);
       __ SmiTag(result);
@@ -1169,6 +1175,7 @@
       break;
     case kTypedDataUint16ArrayCid:
     case kTwoByteStringCid:
+    case kExternalTwoByteStringCid:
       __ movzxw(result, element_address);
       __ SmiTag(result);
       break;
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index 7bbfb55..b1b078f 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -1019,8 +1019,8 @@
 }
 
 
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
-                                                              bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+    Zone* zone, bool opt) const {
   const intptr_t kNumInputs = 1;
   // TODO(fschneider): Allow immediate operands for the char code.
   return LocationSummary::Make(zone,
@@ -1030,13 +1030,12 @@
 }
 
 
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+    FlowGraphCompiler* compiler) {
   ASSERT(compiler->is_optimizing());
   Register char_code = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
 
-  __ Comment("StringFromCharCodeInstr");
-
   __ lw(result, Address(THR, Thread::predefined_symbols_address_offset()));
   __ AddImmediate(result, Symbols::kNullCharCodeSymbolOffset * kWordSize);
   __ sll(TMP, char_code, 1);  // Char code is a smi.
@@ -1169,6 +1168,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return CompileType::FromCid(kSmiCid);
 
     case kTypedDataInt32ArrayCid:
@@ -1195,6 +1196,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return kTagged;
     case kTypedDataInt32ArrayCid:
       return kUnboxedInt32;
@@ -1321,6 +1324,7 @@
     case kExternalTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
+    case kExternalOneByteStringCid:
       ASSERT(index_scale() == 1);
       __ lbu(result, element_address);
       __ SmiTag(result);
@@ -1331,6 +1335,7 @@
       break;
     case kTypedDataUint16ArrayCid:
     case kTwoByteStringCid:
+    case kExternalTwoByteStringCid:
       __ lhu(result, element_address);
       __ SmiTag(result);
       break;
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 87b1f2e..28159ed 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -812,8 +812,8 @@
 }
 
 
-LocationSummary* StringFromCharCodeInstr::MakeLocationSummary(Zone* zone,
-                                                              bool opt) const {
+LocationSummary* OneByteStringFromCharCodeInstr::MakeLocationSummary(
+    Zone* zone, bool opt) const {
   const intptr_t kNumInputs = 1;
   // TODO(fschneider): Allow immediate operands for the char code.
   return LocationSummary::Make(zone,
@@ -823,7 +823,8 @@
 }
 
 
-void StringFromCharCodeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+void OneByteStringFromCharCodeInstr::EmitNativeCode(
+    FlowGraphCompiler* compiler) {
   ASSERT(compiler->is_optimizing());
   Register char_code = locs()->in(0).reg();
   Register result = locs()->out(0).reg();
@@ -973,6 +974,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
     case kTypedDataInt32ArrayCid:
     case kTypedDataUint32ArrayCid:
       return CompileType::FromCid(kSmiCid);
@@ -1000,6 +1003,8 @@
     case kTypedDataUint16ArrayCid:
     case kOneByteStringCid:
     case kTwoByteStringCid:
+    case kExternalOneByteStringCid:
+    case kExternalTwoByteStringCid:
       return kTagged;
     case kTypedDataInt32ArrayCid:
       return kUnboxedInt32;
@@ -1135,6 +1140,7 @@
     case kExternalTypedDataUint8ArrayCid:
     case kExternalTypedDataUint8ClampedArrayCid:
     case kOneByteStringCid:
+    case kExternalOneByteStringCid:
       __ movzxb(result, element_address);
       __ SmiTag(result);
       break;
@@ -1144,6 +1150,7 @@
       break;
     case kTypedDataUint16ArrayCid:
     case kTwoByteStringCid:
+    case kExternalTwoByteStringCid:
       __ movzxw(result, element_address);
       __ SmiTag(result);
       break;
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 5615e58..27631b3 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -659,6 +659,68 @@
 }
 
 
+static bool BuildCodeUnitAt(FlowGraph* flow_graph, intptr_t cid) {
+  GraphEntryInstr* graph_entry = flow_graph->graph_entry();
+  TargetEntryInstr* normal_entry = graph_entry->normal_entry();
+  BlockBuilder builder(flow_graph, normal_entry);
+
+  Definition* index = builder.AddParameter(1);
+  Definition* str = builder.AddParameter(2);
+  PrepareIndexedOp(&builder, str, index, String::length_offset());
+
+  // For external strings: Load external data.
+  if (cid == kExternalOneByteStringCid) {
+    str = builder.AddDefinition(
+        new LoadUntaggedInstr(new Value(str),
+                              ExternalOneByteString::external_data_offset()));
+    str = builder.AddDefinition(
+        new LoadUntaggedInstr(
+            new Value(str),
+            RawExternalOneByteString::ExternalData::data_offset()));
+  } else if (cid == kExternalTwoByteStringCid) {
+    str = builder.AddDefinition(
+      new LoadUntaggedInstr(new Value(str),
+                            ExternalTwoByteString::external_data_offset()));
+    str = builder.AddDefinition(
+        new LoadUntaggedInstr(
+            new Value(str),
+            RawExternalTwoByteString::ExternalData::data_offset()));
+  }
+
+  Definition* result = builder.AddDefinition(
+      new LoadIndexedInstr(new Value(str),
+                           new Value(index),
+                           Instance::ElementSizeFor(cid),
+                           cid,
+                           Thread::kNoDeoptId,
+                           builder.TokenPos()));
+  builder.AddIntrinsicReturn(new Value(result));
+  return true;
+}
+
+
+bool Intrinsifier::Build_OneByteStringCodeUnitAt(FlowGraph* flow_graph) {
+  return BuildCodeUnitAt(flow_graph, kOneByteStringCid);
+}
+
+
+bool Intrinsifier::Build_TwoByteStringCodeUnitAt(FlowGraph* flow_graph) {
+  return BuildCodeUnitAt(flow_graph, kTwoByteStringCid);
+}
+
+
+bool Intrinsifier::Build_ExternalOneByteStringCodeUnitAt(
+    FlowGraph* flow_graph) {
+  return BuildCodeUnitAt(flow_graph, kExternalOneByteStringCid);
+}
+
+
+bool Intrinsifier::Build_ExternalTwoByteStringCodeUnitAt(
+    FlowGraph* flow_graph) {
+  return BuildCodeUnitAt(flow_graph, kExternalTwoByteStringCid);
+}
+
+
 static bool BuildBinaryFloat32x4Op(FlowGraph* flow_graph, Token::Kind kind) {
   if (!FlowGraphCompiler::SupportsUnboxedSimd128()) return false;
 
diff --git a/runtime/vm/intrinsifier_arm.cc b/runtime/vm/intrinsifier_arm.cc
index 78ab5db..e878d03 100644
--- a/runtime/vm/intrinsifier_arm.cc
+++ b/runtime/vm/intrinsifier_arm.cc
@@ -1574,38 +1574,6 @@
 }
 
 
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
-
-  __ ldr(R1, Address(SP, 0 * kWordSize));  // Index.
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // String.
-  __ tst(R1, Operand(kSmiTagMask));
-  __ b(&fall_through, NE);  // Index is not a Smi.
-  // Range check.
-  __ ldr(R2, FieldAddress(R0, String::length_offset()));
-  __ cmp(R1, Operand(R2));
-  __ b(&fall_through, CS);  // Runtime throws exception.
-  __ CompareClassId(R0, kOneByteStringCid, R3);
-  __ b(&try_two_byte_string, NE);
-  __ SmiUntag(R1);
-  __ AddImmediate(R0, OneByteString::data_offset() - kHeapObjectTag);
-  __ ldrb(R0, Address(R0, R1));
-  __ SmiTag(R0);
-  __ Ret();
-
-  __ Bind(&try_two_byte_string);
-  __ CompareClassId(R0, kTwoByteStringCid, R3);
-  __ b(&fall_through, NE);
-  ASSERT(kSmiTagShift == 1);
-  __ AddImmediate(R0, TwoByteString::data_offset() - kHeapObjectTag);
-  __ ldrh(R0, Address(R0, R1));
-  __ SmiTag(R0);
-  __ Ret();
-
-  __ Bind(&fall_through);
-}
-
-
 void GenerateSubstringMatchesSpecialization(Assembler* assembler,
                                             intptr_t receiver_cid,
                                             intptr_t other_cid,
diff --git a/runtime/vm/intrinsifier_arm64.cc b/runtime/vm/intrinsifier_arm64.cc
index ba2a6f1..88512e8 100644
--- a/runtime/vm/intrinsifier_arm64.cc
+++ b/runtime/vm/intrinsifier_arm64.cc
@@ -1655,38 +1655,6 @@
 }
 
 
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
-
-  __ ldr(R1, Address(SP, 0 * kWordSize));  // Index.
-  __ ldr(R0, Address(SP, 1 * kWordSize));  // String.
-  __ tsti(R1, Immediate(kSmiTagMask));
-  __ b(&fall_through, NE);  // Index is not a Smi.
-  // Range check.
-  __ ldr(R2, FieldAddress(R0, String::length_offset()));
-  __ cmp(R1, Operand(R2));
-  __ b(&fall_through, CS);  // Runtime throws exception.
-  __ CompareClassId(R0, kOneByteStringCid);
-  __ b(&try_two_byte_string, NE);
-  __ SmiUntag(R1);
-  __ AddImmediate(R0, R0, OneByteString::data_offset() - kHeapObjectTag);
-  __ ldr(R0, Address(R0, R1), kUnsignedByte);
-  __ SmiTag(R0);
-  __ ret();
-
-  __ Bind(&try_two_byte_string);
-  __ CompareClassId(R0, kTwoByteStringCid);
-  __ b(&fall_through, NE);
-  ASSERT(kSmiTagShift == 1);
-  __ AddImmediate(R0, R0, TwoByteString::data_offset() - kHeapObjectTag);
-  __ ldr(R0, Address(R0, R1), kUnsignedHalfword);
-  __ SmiTag(R0);
-  __ ret();
-
-  __ Bind(&fall_through);
-}
-
-
 void GenerateSubstringMatchesSpecialization(Assembler* assembler,
                                             intptr_t receiver_cid,
                                             intptr_t other_cid,
diff --git a/runtime/vm/intrinsifier_ia32.cc b/runtime/vm/intrinsifier_ia32.cc
index fd2bc9f..8dc9e99 100644
--- a/runtime/vm/intrinsifier_ia32.cc
+++ b/runtime/vm/intrinsifier_ia32.cc
@@ -1718,35 +1718,6 @@
 }
 
 
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
-  __ movl(EBX, Address(ESP, + 1 * kWordSize));  // Index.
-  __ movl(EAX, Address(ESP, + 2 * kWordSize));  // String.
-  __ testl(EBX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi index.
-  // Range check.
-  __ cmpl(EBX, FieldAddress(EAX, String::length_offset()));
-  // Runtime throws exception.
-  __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
-  __ CompareClassId(EAX, kOneByteStringCid, EDI);
-  __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
-  __ SmiUntag(EBX);
-  __ movzxb(EAX, FieldAddress(EAX, EBX, TIMES_1, OneByteString::data_offset()));
-  __ SmiTag(EAX);
-  __ ret();
-
-  __ Bind(&try_two_byte_string);
-  __ CompareClassId(EAX, kTwoByteStringCid, EDI);
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
-  ASSERT(kSmiTagShift == 1);
-  __ movzxw(EAX, FieldAddress(EAX, EBX, TIMES_1, TwoByteString::data_offset()));
-  __ SmiTag(EAX);
-  __ ret();
-
-  __ Bind(&fall_through);
-}
-
-
 // bool _substringMatches(int start, String other)
 void Intrinsifier::StringBaseSubstringMatches(Assembler* assembler) {
   // For precompilation, not implemented on IA32.
diff --git a/runtime/vm/intrinsifier_mips.cc b/runtime/vm/intrinsifier_mips.cc
index e98fc1d..2398a7b 100644
--- a/runtime/vm/intrinsifier_mips.cc
+++ b/runtime/vm/intrinsifier_mips.cc
@@ -1682,41 +1682,6 @@
 }
 
 
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
-
-  __ lw(T1, Address(SP, 0 * kWordSize));  // Index.
-  __ lw(T0, Address(SP, 1 * kWordSize));  // String.
-
-  // Checks.
-  __ andi(CMPRES1, T1, Immediate(kSmiTagMask));
-  __ bne(CMPRES1, ZR, &fall_through);  // Index is not a Smi.
-  __ lw(T2, FieldAddress(T0, String::length_offset()));  // Range check.
-  // Runtime throws exception.
-  __ BranchUnsignedGreaterEqual(T1, T2, &fall_through);
-  __ LoadClassId(CMPRES1, T0);  // Class ID check.
-  __ BranchNotEqual(
-      CMPRES1, Immediate(kOneByteStringCid), &try_two_byte_string);
-
-  // Grab byte and return.
-  __ SmiUntag(T1);
-  __ addu(T2, T0, T1);
-  __ lbu(V0, FieldAddress(T2, OneByteString::data_offset()));
-  __ Ret();
-  __ delay_slot()->SmiTag(V0);
-
-  __ Bind(&try_two_byte_string);
-  __ BranchNotEqual(CMPRES1, Immediate(kTwoByteStringCid), &fall_through);
-  ASSERT(kSmiTagShift == 1);
-  __ addu(T2, T0, T1);
-  __ lhu(V0, FieldAddress(T2, TwoByteString::data_offset()));
-  __ Ret();
-  __ delay_slot()->SmiTag(V0);
-
-  __ Bind(&fall_through);
-}
-
-
 void GenerateSubstringMatchesSpecialization(Assembler* assembler,
                                             intptr_t receiver_cid,
                                             intptr_t other_cid,
diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc
index ab2fa94..402613e 100644
--- a/runtime/vm/intrinsifier_x64.cc
+++ b/runtime/vm/intrinsifier_x64.cc
@@ -1573,35 +1573,6 @@
 }
 
 
-void Intrinsifier::StringBaseCodeUnitAt(Assembler* assembler) {
-  Label fall_through, try_two_byte_string;
-  __ movq(RCX, Address(RSP, + 1 * kWordSize));  // Index.
-  __ movq(RAX, Address(RSP, + 2 * kWordSize));  // String.
-  __ testq(RCX, Immediate(kSmiTagMask));
-  __ j(NOT_ZERO, &fall_through, Assembler::kNearJump);  // Non-smi index.
-  // Range check.
-  __ cmpq(RCX, FieldAddress(RAX, String::length_offset()));
-  // Runtime throws exception.
-  __ j(ABOVE_EQUAL, &fall_through, Assembler::kNearJump);
-  __ CompareClassId(RAX, kOneByteStringCid);
-  __ j(NOT_EQUAL, &try_two_byte_string, Assembler::kNearJump);
-  __ SmiUntag(RCX);
-  __ movzxb(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(&try_two_byte_string);
-  __ CompareClassId(RAX, kTwoByteStringCid);
-  __ j(NOT_EQUAL, &fall_through, Assembler::kNearJump);
-  ASSERT(kSmiTagShift == 1);
-  __ movzxw(RAX, FieldAddress(RAX, RCX, TIMES_1, OneByteString::data_offset()));
-  __ SmiTag(RAX);
-  __ ret();
-
-  __ Bind(&fall_through);
-}
-
-
 void GenerateSubstringMatchesSpecialization(Assembler* assembler,
                                             intptr_t receiver_cid,
                                             intptr_t other_cid,
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index 44127c5..57fb16a 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1403,11 +1403,6 @@
 
 
 void Isolate::AddClosureFunction(const Function& function) const {
-  // TODO(regis): remove once debugging complete.
-  if (Compiler::IsBackgroundCompilation()) {
-    NOT_IN_PRODUCT(Profiler::DumpStackTrace(true /*native*/));
-    UNREACHABLE();
-  }
   ASSERT(!Compiler::IsBackgroundCompilation());
   GrowableObjectArray& closures =
       GrowableObjectArray::Handle(object_store()->closure_functions());
@@ -2635,22 +2630,26 @@
 
 
 RawObject* IsolateSpawnState::ResolveFunction() {
-  const String& func_name = String::Handle(String::New(function_name()));
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+
+  const String& func_name = String::Handle(zone, String::New(function_name()));
 
   if (library_url() == NULL) {
     // Handle spawnUri lookup rules.
     // Check whether the root library defines a main function.
-    const Library& lib = Library::Handle(I->object_store()->root_library());
-    Function& func = Function::Handle(lib.LookupLocalFunction(func_name));
+    const Library& lib = Library::Handle(zone,
+                                         I->object_store()->root_library());
+    Function& func = Function::Handle(zone, lib.LookupLocalFunction(func_name));
     if (func.IsNull()) {
       // Check whether main is reexported from the root library.
-      const Object& obj = Object::Handle(lib.LookupReExport(func_name));
+      const Object& obj = Object::Handle(zone, lib.LookupReExport(func_name));
       if (obj.IsFunction()) {
         func ^= obj.raw();
       }
     }
     if (func.IsNull()) {
-      const String& msg = String::Handle(String::NewFormatted(
+      const String& msg = String::Handle(zone, String::NewFormatted(
           "Unable to resolve function '%s' in script '%s'.",
           function_name(), script_url()));
       return LanguageError::New(msg);
@@ -2660,19 +2659,21 @@
 
   // Lookup the to be spawned function for the Isolate.spawn implementation.
   // Resolve the library.
-  const String& lib_url = String::Handle(String::New(library_url()));
-  const Library& lib = Library::Handle(Library::LookupLibrary(lib_url));
+  const String& lib_url = String::Handle(zone, String::New(library_url()));
+  const Library& lib = Library::Handle(zone,
+                                       Library::LookupLibrary(thread, lib_url));
   if (lib.IsNull() || lib.IsError()) {
-    const String& msg = String::Handle(String::NewFormatted(
+    const String& msg = String::Handle(zone, String::NewFormatted(
         "Unable to find library '%s'.", library_url()));
     return LanguageError::New(msg);
   }
 
   // Resolve the function.
   if (class_name() == NULL) {
-    const Function& func = Function::Handle(lib.LookupLocalFunction(func_name));
+    const Function& func = Function::Handle(zone,
+                                            lib.LookupLocalFunction(func_name));
     if (func.IsNull()) {
-      const String& msg = String::Handle(String::NewFormatted(
+      const String& msg = String::Handle(zone, String::NewFormatted(
           "Unable to resolve function '%s' in library '%s'.",
           function_name(), library_url()));
       return LanguageError::New(msg);
@@ -2680,19 +2681,19 @@
     return func.raw();
   }
 
-  const String& cls_name = String::Handle(String::New(class_name()));
-  const Class& cls = Class::Handle(lib.LookupLocalClass(cls_name));
+  const String& cls_name = String::Handle(zone, String::New(class_name()));
+  const Class& cls = Class::Handle(zone, lib.LookupLocalClass(cls_name));
   if (cls.IsNull()) {
-    const String& msg = String::Handle(String::NewFormatted(
+    const String& msg = String::Handle(zone, String::NewFormatted(
           "Unable to resolve class '%s' in library '%s'.",
           class_name(),
           (library_url() != NULL ? library_url() : script_url())));
     return LanguageError::New(msg);
   }
   const Function& func =
-      Function::Handle(cls.LookupStaticFunctionAllowPrivate(func_name));
+      Function::Handle(zone, cls.LookupStaticFunctionAllowPrivate(func_name));
   if (func.IsNull()) {
-    const String& msg = String::Handle(String::NewFormatted(
+    const String& msg = String::Handle(zone, String::NewFormatted(
           "Unable to resolve static method '%s.%s' in library '%s'.",
           class_name(), function_name(),
           (library_url() != NULL ? library_url() : script_url())));
diff --git a/runtime/vm/jit_optimizer.cc b/runtime/vm/jit_optimizer.cc
index b0be614..f4d8757 100644
--- a/runtime/vm/jit_optimizer.cc
+++ b/runtime/vm/jit_optimizer.cc
@@ -755,7 +755,7 @@
       return false;
     }
   } else {
-    return d->IsStringFromCharCode();
+    return d->IsOneByteStringFromCharCode();
   }
 }
 
@@ -789,9 +789,10 @@
       ConstantInstr* char_code_left = flow_graph()->GetConstant(
           Smi::ZoneHandle(Z, Smi::New(static_cast<intptr_t>(str.CharAt(0)))));
       left_val = new(Z) Value(char_code_left);
-    } else if (left->IsStringFromCharCode()) {
+    } else if (left->IsOneByteStringFromCharCode()) {
       // Use input of string-from-charcode as left value.
-      StringFromCharCodeInstr* instr = left->AsStringFromCharCode();
+      OneByteStringFromCharCodeInstr* instr =
+          left->AsOneByteStringFromCharCode();
       left_val = new(Z) Value(instr->char_code()->definition());
       to_remove_left = instr;
     } else {
@@ -801,9 +802,10 @@
 
     Definition* to_remove_right = NULL;
     Value* right_val = NULL;
-    if (right->IsStringFromCharCode()) {
+    if (right->IsOneByteStringFromCharCode()) {
       // Skip string-from-char-code, and use its input as right value.
-      StringFromCharCodeInstr* right_instr = right->AsStringFromCharCode();
+      OneByteStringFromCharCodeInstr* right_instr =
+          right->AsOneByteStringFromCharCode();
       right_val = new(Z) Value(right_instr->char_code()->definition());
       to_remove_right = right_instr;
     } else {
@@ -1764,11 +1766,24 @@
     return true;
   }
 
-  if (((recognized_kind == MethodRecognizer::kStringBaseCodeUnitAt) ||
-       (recognized_kind == MethodRecognizer::kStringBaseCharAt)) &&
-      (ic_data.NumberOfChecks() == 1) &&
-      ((class_ids[0] == kOneByteStringCid) ||
-       (class_ids[0] == kTwoByteStringCid))) {
+  if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) ||
+      (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) ||
+      (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) ||
+      (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt)) {
+      ASSERT(ic_data.NumberOfChecks() == 1);
+      ASSERT((class_ids[0] == kOneByteStringCid) ||
+             (class_ids[0] == kTwoByteStringCid) ||
+             (class_ids[0] == kExternalOneByteStringCid) ||
+             (class_ids[0] == kExternalTwoByteStringCid));
+    return TryReplaceInstanceCallWithInline(call);
+  }
+
+  if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) &&
+      (ic_data.NumberOfChecks() == 1)) {
+      ASSERT((class_ids[0] == kOneByteStringCid) ||
+             (class_ids[0] == kTwoByteStringCid) ||
+             (class_ids[0] == kExternalOneByteStringCid) ||
+             (class_ids[0] == kExternalTwoByteStringCid));
     return TryReplaceInstanceCallWithInline(call);
   }
 
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index b793d35..3a55d5a 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -76,6 +76,8 @@
   function.set_is_debuggable(false);
   function.set_is_visible(false);
   function.AttachCode(code);
+  // For inclusion in Snapshot::kAppWithJIT.
+  function.set_unoptimized_code(code);
 
   isolate->object_store()->SetMegamorphicMissHandler(code, function);
 }
diff --git a/runtime/vm/method_recognizer.h b/runtime/vm/method_recognizer.h
index a3e0eda..9ed5848 100644
--- a/runtime/vm/method_recognizer.h
+++ b/runtime/vm/method_recognizer.h
@@ -16,38 +16,38 @@
   V(::, identical, ObjectIdentical, 317103244)                                 \
   V(ClassID, getID, ClassIDgetID, 1385157717)                                  \
   V(Object, Object., ObjectConstructor, 1746278398)                            \
-  V(_List, ., ObjectArrayAllocate, 184405219)                                  \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 187609847)                     \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1826086346)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1174755987)                  \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1936358273)                \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 1123951931)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 853172551)                 \
-  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 1115954619)                  \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 165422183)               \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1564825450)              \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1123952315)          \
-  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 831892409)               \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 2043203289)                    \
-  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1759261408)                  \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 267848339)                   \
-  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 350952121)                 \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1170619358)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1325523969)                \
-  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 935451230)                   \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 541136999)               \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 365317124)               \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1766802707)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 2075229300)              \
-  V(_StringBase, _interpolate, StringBaseInterpolate, 1597087225)              \
-  V(_IntegerImplementation, toDouble, IntegerToDouble, 150718448)              \
-  V(_Double, _add, DoubleAdd, 1190606283)                                      \
-  V(_Double, _sub, DoubleSub, 1086286468)                                      \
-  V(_Double, _mul, DoubleMul, 166332351)                                       \
-  V(_Double, _div, DoubleDiv, 821396195)                                       \
+  V(_List, ., ObjectArrayAllocate, 1661438741)                                 \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1508321565)                    \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 953411007)                   \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 433971756)                   \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1329446488)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 137212209)                   \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 499907480)                 \
+  V(_TypedList, _getInt64, ByteArrayBaseGetInt64, 1639388276)                  \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 1672834581)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 966634744)               \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1197581758)          \
+  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 810805548)               \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1317196265)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetUint8, 1328908284)                  \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1827614958)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetUint16, 1694054572)                \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 915652649)                   \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1958474336)                \
+  V(_TypedList, _setInt64, ByteArrayBaseSetInt64, 1970687707)                  \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1853026980)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1197862362)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 2093630771)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 1982971324)              \
+  V(_StringBase, _interpolate, StringBaseInterpolate, 1872292681)              \
+  V(_IntegerImplementation, toDouble, IntegerToDouble, 792762465)              \
+  V(_Double, _add, DoubleAdd, 2213216)                                         \
+  V(_Double, _sub, DoubleSub, 1100692582)                                      \
+  V(_Double, _mul, DoubleMul, 436784097)                                       \
+  V(_Double, _div, DoubleDiv, 953317135)                                       \
   V(::, min, MathMin, 1115051548)                                              \
   V(::, max, MathMax, 1410473322)                                              \
-  V(::, _doublePow, MathDoublePow, 562154128)                                  \
+  V(::, _doublePow, MathDoublePow, 1770960781)                                 \
   V(Float32x4, Float32x4., Float32x4Constructor, 93751705)                     \
   V(Float32x4, Float32x4.zero, Float32x4Zero, 1193954374)                      \
   V(Float32x4, Float32x4.splat, Float32x4Splat, 12296613)                      \
@@ -56,21 +56,21 @@
   V(Float32x4, shuffle, Float32x4Shuffle, 2015957023)                          \
   V(Float32x4, shuffleMix, Float32x4ShuffleMix, 1099087979)                    \
   V(Float32x4, get:signMask, Float32x4GetSignMask, 487049875)                  \
-  V(Float32x4, _cmpequal, Float32x4Equal, 1069901308)                          \
-  V(Float32x4, _cmpgt, Float32x4GreaterThan, 2112381651)                       \
-  V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 1088241265)               \
-  V(Float32x4, _cmplt, Float32x4LessThan, 2001171012)                          \
-  V(Float32x4, _cmplte, Float32x4LessThanOrEqual, 1568686387)                  \
-  V(Float32x4, _cmpnequal, Float32x4NotEqual, 1833412828)                      \
-  V(Float32x4, _min, Float32x4Min, 1194113943)                                 \
-  V(Float32x4, _max, Float32x4Max, 1876936155)                                 \
-  V(Float32x4, _scale, Float32x4Scale, 1176743640)                             \
-  V(Float32x4, _sqrt, Float32x4Sqrt, 526238610)                                \
-  V(Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, 860560177)            \
-  V(Float32x4, _reciprocal, Float32x4Reciprocal, 1703468100)                   \
-  V(Float32x4, _negate, Float32x4Negate, 1409902640)                           \
-  V(Float32x4, _abs, Float32x4Absolute, 2116840471)                            \
-  V(Float32x4, _clamp, Float32x4Clamp, 1789892357)                             \
+  V(Float32x4, _cmpequal, Float32x4Equal, 127403211)                           \
+  V(Float32x4, _cmpgt, Float32x4GreaterThan, 2118391173)                       \
+  V(Float32x4, _cmpgte, Float32x4GreaterThanOrEqual, 557807661)                \
+  V(Float32x4, _cmplt, Float32x4LessThan, 1061691185)                          \
+  V(Float32x4, _cmplte, Float32x4LessThanOrEqual, 102608993)                   \
+  V(Float32x4, _cmpnequal, Float32x4NotEqual, 1873649982)                      \
+  V(Float32x4, _min, Float32x4Min, 1158016632)                                 \
+  V(Float32x4, _max, Float32x4Max, 118915526)                                  \
+  V(Float32x4, _scale, Float32x4Scale, 415757469)                              \
+  V(Float32x4, _sqrt, Float32x4Sqrt, 1934518992)                               \
+  V(Float32x4, _reciprocalSqrt, Float32x4ReciprocalSqrt, 1586141174)           \
+  V(Float32x4, _reciprocal, Float32x4Reciprocal, 1651466502)                   \
+  V(Float32x4, _negate, Float32x4Negate, 2142478676)                           \
+  V(Float32x4, _abs, Float32x4Absolute, 337704007)                             \
+  V(Float32x4, _clamp, Float32x4Clamp, 1107305005)                             \
   V(Float32x4, withX, Float32x4WithX, 1311992575)                              \
   V(Float32x4, withY, Float32x4WithY, 175290640)                               \
   V(Float32x4, withZ, Float32x4WithZ, 837367384)                               \
@@ -81,7 +81,7 @@
   V(Float64x2, Float64x2.fromFloat32x4, Float64x2FromFloat32x4, 792974246)     \
   V(Float64x2, get:x, Float64x2GetX, 1488958362)                               \
   V(Float64x2, get:y, Float64x2GetY, 1022688506)                               \
-  V(Float64x2, _negate, Float64x2Negate, 960840275)                            \
+  V(Float64x2, _negate, Float64x2Negate, 1693416311)                           \
   V(Float64x2, abs, Float64x2Abs, 52403783)                                    \
   V(Float64x2, sqrt, Float64x2Sqrt, 2012680669)                                \
   V(Float64x2, get:signMask, Float64x2GetSignMask, 668856717)                  \
@@ -100,48 +100,48 @@
   V(Int32x4, get:signMask, Int32x4GetSignMask, 740215269)                      \
   V(Int32x4, shuffle, Int32x4Shuffle, 549194518)                               \
   V(Int32x4, shuffleMix, Int32x4ShuffleMix, 1550866145)                        \
-  V(Int32x4, select, Int32x4Select, 614943686)                                 \
+  V(Int32x4, select, Int32x4Select, 1368318775)                                \
   V(Int32x4, withFlagX, Int32x4WithFlagX, 250974159)                           \
   V(Int32x4, withFlagY, Int32x4WithFlagY, 1686481348)                          \
   V(Int32x4, withFlagZ, Int32x4WithFlagZ, 645582330)                           \
   V(Int32x4, withFlagW, Int32x4WithFlagW, 878364277)                           \
-  V(Float32List, [], Float32ArrayGetIndexed, 1002307136)                       \
-  V(Float32List, []=, Float32ArraySetIndexed, 279546769)                       \
-  V(Int8List, [], Int8ArrayGetIndexed, 1141846285)                             \
-  V(Int8List, []=, Int8ArraySetIndexed, 1486839324)                            \
-  V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 513704632)              \
-  V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 1015846567)            \
+  V(Float32List, [], Float32ArrayGetIndexed, 1451643535)                       \
+  V(Float32List, []=, Float32ArraySetIndexed, 453873887)                       \
+  V(Int8List, [], Int8ArrayGetIndexed, 110819507)                              \
+  V(Int8List, []=, Int8ArraySetIndexed, 865684695)                             \
+  V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 41288685)               \
+  V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 687206488)             \
   V(_ExternalUint8ClampedArray, [], ExternalUint8ClampedArrayGetIndexed,       \
-    513704632)                                                                 \
+    41288685)                                                                  \
   V(_ExternalUint8ClampedArray, []=, ExternalUint8ClampedArraySetIndexed,      \
-    1015846567)                                                                \
-  V(Int16List, [], Int16ArrayGetIndexed, 1826359619)                           \
-  V(Int16List, []=, Int16ArraySetIndexed, 1108689116)                          \
-  V(Uint16List, [], Uint16ArrayGetIndexed, 118958722)                          \
-  V(Uint16List, []=, Uint16ArraySetIndexed, 658824450)                         \
-  V(Int32List, [], Int32ArrayGetIndexed, 681203163)                            \
-  V(Int32List, []=, Int32ArraySetIndexed, 1786886245)                          \
-  V(Int64List, [], Int64ArrayGetIndexed, 1883155004)                           \
-  V(Int64List, []=, Int64ArraySetIndexed, 905815059)                           \
-  V(Float32x4List, [], Float32x4ArrayGetIndexed, 694822356)                    \
-  V(Float32x4List, []=, Float32x4ArraySetIndexed, 1166109127)                  \
-  V(Int32x4List, [], Int32x4ArrayGetIndexed, 668249259)                        \
-  V(Int32x4List, []=, Int32x4ArraySetIndexed, 654739449)                       \
-  V(Float64x2List, [], Float64x2ArrayGetIndexed, 196472005)                    \
-  V(Float64x2List, []=, Float64x2ArraySetIndexed, 1421858500)                  \
-  V(_Bigint, get:_neg, Bigint_getNeg, 1681019799)                              \
-  V(_Bigint, get:_used, Bigint_getUsed, 1439136438)                            \
-  V(_Bigint, get:_digits, Bigint_getDigits, 769722770)                         \
-  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2048715833)               \
-  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1882796480)               \
-  V(_HashVMBase, get:_data, LinkedHashMap_getData, 942992497)                  \
-  V(_HashVMBase, set:_data, LinkedHashMap_setData, 1410623019)                 \
-  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 1698421819)         \
-  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1858754514)         \
-  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 98745045)           \
-  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 340628211)          \
-  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 1340385546)   \
-  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 638315987)    \
+    687206488)                                                                 \
+  V(Int16List, [], Int16ArrayGetIndexed, 389863073)                            \
+  V(Int16List, []=, Int16ArraySetIndexed, 855133756)                           \
+  V(Uint16List, [], Uint16ArrayGetIndexed, 1053739567)                         \
+  V(Uint16List, []=, Uint16ArraySetIndexed, 1547307961)                        \
+  V(Int32List, [], Int32ArrayGetIndexed, 640610057)                            \
+  V(Int32List, []=, Int32ArraySetIndexed, 453358705)                           \
+  V(Int64List, [], Int64ArrayGetIndexed, 202150810)                            \
+  V(Int64List, []=, Int64ArraySetIndexed, 924110852)                           \
+  V(Float32x4List, [], Float32x4ArrayGetIndexed, 29819259)                     \
+  V(Float32x4List, []=, Float32x4ArraySetIndexed, 1458062250)                  \
+  V(Int32x4List, [], Int32x4ArrayGetIndexed, 137707405)                        \
+  V(Int32x4List, []=, Int32x4ArraySetIndexed, 496650149)                       \
+  V(Float64x2List, [], Float64x2ArrayGetIndexed, 1721439384)                   \
+  V(Float64x2List, []=, Float64x2ArraySetIndexed, 1994027006)                  \
+  V(_Bigint, get:_neg, Bigint_getNeg, 2079423063)                              \
+  V(_Bigint, get:_used, Bigint_getUsed, 1426329619)                            \
+  V(_Bigint, get:_digits, Bigint_getDigits, 1185333683)                        \
+  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2104211307)               \
+  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1273697266)               \
+  V(_HashVMBase, get:_data, LinkedHashMap_getData, 1274399923)                 \
+  V(_HashVMBase, set:_data, LinkedHashMap_setData, 1611093357)                 \
+  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 367462469)          \
+  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1049390812)         \
+  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 902147072)          \
+  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 1236137630)         \
+  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 812542585)    \
+  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 1072259010)   \
 
 
 // List of intrinsics:
@@ -149,94 +149,94 @@
 #define CORE_LIB_INTRINSIC_LIST(V)                                             \
   V(_Smi, ~, Smi_bitNegate, 1673522705)                                        \
   V(_Smi, get:bitLength, Smi_bitLength, 632480332)                             \
-  V(_Bigint, _lsh, Bigint_lsh, 834311957)                                      \
-  V(_Bigint, _rsh, Bigint_rsh, 333337658)                                      \
-  V(_Bigint, _absAdd, Bigint_absAdd, 473436659)                                \
-  V(_Bigint, _absSub, Bigint_absSub, 1018678324)                               \
-  V(_Bigint, _mulAdd, Bigint_mulAdd, 571005736)                                \
-  V(_Bigint, _sqrAdd, Bigint_sqrAdd, 372896038)                                \
-  V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 540033329)            \
-  V(_Montgomery, _mulMod, Montgomery_mulMod, 118781828)                        \
-  V(_Double, >, Double_greaterThan, 1413076759)                                \
+  V(_Bigint, _lsh, Bigint_lsh, 1557746963)                                     \
+  V(_Bigint, _rsh, Bigint_rsh, 761843937)                                      \
+  V(_Bigint, _absAdd, Bigint_absAdd, 1227835493)                               \
+  V(_Bigint, _absSub, Bigint_absSub, 390740532)                                \
+  V(_Bigint, _mulAdd, Bigint_mulAdd, 617534446)                                \
+  V(_Bigint, _sqrAdd, Bigint_sqrAdd, 1623635507)                               \
+  V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 797340802)            \
+  V(_Montgomery, _mulMod, Montgomery_mulMod, 1947987219)                       \
+  V(_Double, >, Double_greaterThan, 1453001345)                                \
   V(_Double, >=, Double_greaterEqualThan, 1815180096)                          \
   V(_Double, <, Double_lessThan, 652059836)                                    \
   V(_Double, <=, Double_lessEqualThan, 512138528)                              \
-  V(_Double, ==, Double_equal, 752327620)                                      \
-  V(_Double, +, Double_add, 854024064)                                         \
-  V(_Double, -, Double_sub, 685132889)                                         \
-  V(_Double, *, Double_mul, 542254390)                                         \
-  V(_Double, /, Double_div, 1145710768)                                        \
+  V(_Double, ==, Double_equal, 1468668497)                                     \
+  V(_Double, +, Double_add, 1269587413)                                        \
+  V(_Double, -, Double_sub, 1644506555)                                        \
+  V(_Double, *, Double_mul, 600860888)                                         \
+  V(_Double, /, Double_div, 1220198876)                                        \
   V(_Double, get:isNaN, Double_getIsNaN, 184085483)                            \
   V(_Double, get:isNegative, Double_getIsNegative, 978911030)                  \
-  V(_Double, _mulFromInteger, Double_mulFromInteger, 543831179)                \
-  V(_Double, .fromInteger, DoubleFromInteger, 1453449234)                      \
+  V(_Double, _mulFromInteger, Double_mulFromInteger, 1893886883)               \
+  V(_Double, .fromInteger, DoubleFromInteger, 2129942595)                      \
   V(_List, []=, ObjectArraySetIndexed, 886228780)                              \
-  V(_GrowableList, .withData, GrowableArray_Allocate, 131424500)               \
-  V(_GrowableList, add, GrowableArray_add, 242296201)                          \
-  V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 2077783530)                   \
+  V(_GrowableList, .withData, GrowableArray_Allocate, 631736030)               \
+  V(_GrowableList, add, GrowableArray_add, 219371757)                          \
+  V(_RegExp, _ExecuteMatch, RegExp_ExecuteMatch, 1614206970)                   \
   V(Object, ==, ObjectEquals, 291909336)                                       \
   V(Object, get:runtimeType, ObjectRuntimeType, 15188587)                      \
   V(_StringBase, get:hashCode, String_getHashCode, 2026040200)                 \
   V(_StringBase, get:isEmpty, StringBaseIsEmpty, 1958879178)                   \
-  V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1436590579)                 \
-  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 1548648995)    \
+  V(_StringBase, _substringMatches, StringBaseSubstringMatches, 797253099)     \
   V(_StringBase, [], StringBaseCharAt, 754527301)                              \
   V(_OneByteString, get:hashCode, OneByteString_getHashCode, 2026040200)       \
   V(_OneByteString, _substringUncheckedNative,                                 \
-    OneByteString_substringUnchecked, 2063670029)                              \
-  V(_OneByteString, _setAt, OneByteStringSetAt, 929822971)                     \
-  V(_OneByteString, _allocate, OneByteString_allocate, 1737851380)             \
+    OneByteString_substringUnchecked, 1670133538)                              \
+  V(_OneByteString, _setAt, OneByteStringSetAt, 1160066031)                    \
+  V(_OneByteString, _allocate, OneByteString_allocate, 1028631946)             \
   V(_OneByteString, ==, OneByteString_equality, 1062844160)                    \
   V(_TwoByteString, ==, TwoByteString_equality, 1062844160)                    \
 
 
 #define CORE_INTEGER_LIB_INTRINSIC_LIST(V)                                     \
-  V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger, 298045644)\
-  V(_IntegerImplementation, +, Integer_add, 364498398)                         \
-  V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 422157928)\
-  V(_IntegerImplementation, -, Integer_sub, 1682674911)                        \
+  V(_IntegerImplementation, _addFromInteger, Integer_addFromInteger,           \
+    2042488139)                                                                \
+  V(_IntegerImplementation, +, Integer_add, 239272130)                         \
+  V(_IntegerImplementation, _subFromInteger, Integer_subFromInteger, 957923759)\
+  V(_IntegerImplementation, -, Integer_sub, 216175811)                         \
   V(_IntegerImplementation, _mulFromInteger, Integer_mulFromInteger,           \
-    2074733333)                                                                \
-  V(_IntegerImplementation, *, Integer_mul, 1651115456)                        \
+    2032062140)                                                                \
+  V(_IntegerImplementation, *, Integer_mul, 1301152164)                        \
   V(_IntegerImplementation, _moduloFromInteger, Integer_moduloFromInteger,     \
-    2100319763)                                                                \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 108494012)                \
+    779285842)                                                                 \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 1018128256)               \
   V(_IntegerImplementation, unary-, Integer_negate, 1507648892)                \
   V(_IntegerImplementation, _bitAndFromInteger, Integer_bitAndFromInteger,     \
-    363854564)                                                                 \
-  V(_IntegerImplementation, &, Integer_bitAnd, 286231290)                      \
+    503046514)                                                                 \
+  V(_IntegerImplementation, &, Integer_bitAnd, 1500136766)                     \
   V(_IntegerImplementation, _bitOrFromInteger, Integer_bitOrFromInteger,       \
-    1623085924)                                                                \
-  V(_IntegerImplementation, |, Integer_bitOr, 1111108792)                      \
+    1031383580)                                                                \
+  V(_IntegerImplementation, |, Integer_bitOr, 119412028)                       \
   V(_IntegerImplementation, _bitXorFromInteger, Integer_bitXorFromInteger,     \
-    140783758)                                                                 \
-  V(_IntegerImplementation, ^, Integer_bitXor, 1884808537)                     \
+    1339506501)                                                                \
+  V(_IntegerImplementation, ^, Integer_bitXor, 210430781)                      \
   V(_IntegerImplementation, _greaterThanFromInteger,                           \
-    Integer_greaterThanFromInt, 814932166)                                     \
-  V(_IntegerImplementation, >, Integer_greaterThan, 293890061)                 \
-  V(_IntegerImplementation, ==, Integer_equal, 4489308)                        \
+    Integer_greaterThanFromInt, 780147656)                                     \
+  V(_IntegerImplementation, >, Integer_greaterThan, 673741711)                 \
+  V(_IntegerImplementation, ==, Integer_equal, 272474439)                      \
   V(_IntegerImplementation, _equalToInteger, Integer_equalToInteger,           \
-    1818326386)                                                                \
+    2004079901)                                                                \
   V(_IntegerImplementation, <, Integer_lessThan, 652059836)                    \
   V(_IntegerImplementation, <=, Integer_lessEqualThan, 512138528)              \
   V(_IntegerImplementation, >=, Integer_greaterEqualThan, 1815180096)          \
-  V(_IntegerImplementation, <<, Integer_shl, 293751452)                        \
-  V(_IntegerImplementation, >>, Integer_sar, 125091101)                        \
+  V(_IntegerImplementation, <<, Integer_shl, 1127538624)                       \
+  V(_IntegerImplementation, >>, Integer_sar, 1243972513)                       \
   V(_Double, toInt, DoubleToInteger, 653210699)
 
 
 #define MATH_LIB_INTRINSIC_LIST(V)                                             \
-  V(::, sqrt, MathSqrt, 1446681622)                                            \
-  V(_Random, _nextState, Random_nextState, 1241583299)                         \
+  V(::, sqrt, MathSqrt, 417912310)                                             \
+  V(_Random, _nextState, Random_nextState, 508231939)                          \
 
 #define GRAPH_MATH_LIB_INTRINSIC_LIST(V)                                       \
-  V(::, sin, MathSin, 939048573)                                               \
-  V(::, cos, MathCos, 1148850331)                                              \
-  V(::, tan, MathTan, 179725235)                                               \
-  V(::, asin, MathAsin, 848695059)                                             \
-  V(::, acos, MathAcos, 337299516)                                             \
-  V(::, atan, MathAtan, 866406810)                                             \
-  V(::, atan2, MathAtan2, 1901969510)                                          \
+  V(::, sin, MathSin, 65032)                                                   \
+  V(::, cos, MathCos, 2006233918)                                              \
+  V(::, tan, MathTan, 1276867325)                                              \
+  V(::, asin, MathAsin, 1678592173)                                            \
+  V(::, acos, MathAcos, 1121218433)                                            \
+  V(::, atan, MathAtan, 1109653625)                                            \
+  V(::, atan2, MathAtan2, 894696289)                                           \
 
 #define TYPED_DATA_LIB_INTRINSIC_LIST(V)                                       \
   V(Int8List, ., TypedData_Int8Array_factory, 779569635)                       \
@@ -255,22 +255,22 @@
   V(Float64x2List, ., TypedData_Float64x2Array_factory, 416019673)             \
 
 #define GRAPH_TYPED_DATA_INTRINSICS_LIST(V)                                    \
-  V(Uint8List, [], Uint8ArrayGetIndexed, 513704632)                            \
-  V(Uint8List, []=, Uint8ArraySetIndexed, 2123520783)                          \
-  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 513704632)          \
-  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 2123520783)        \
-  V(Uint32List, [], Uint32ArrayGetIndexed, 1179675338)                         \
-  V(Uint32List, []=, Uint32ArraySetIndexed, 1455695417)                        \
-  V(Float64List, []=, Float64ArraySetIndexed, 1929239576)                      \
-  V(Float64List, [], Float64ArrayGetIndexed, 816943529)                        \
+  V(Uint8List, [], Uint8ArrayGetIndexed, 41288685)                             \
+  V(Uint8List, []=, Uint8ArraySetIndexed, 101536342)                           \
+  V(_ExternalUint8Array, [], ExternalUint8ArrayGetIndexed, 41288685)           \
+  V(_ExternalUint8Array, []=, ExternalUint8ArraySetIndexed, 101536342)         \
+  V(Uint32List, [], Uint32ArrayGetIndexed, 1614870523)                         \
+  V(Uint32List, []=, Uint32ArraySetIndexed, 978194713)                         \
+  V(Float64List, []=, Float64ArraySetIndexed, 328934501)                       \
+  V(Float64List, [], Float64ArrayGetIndexed, 2049378701)                       \
   V(_TypedList, get:length, TypedDataLength, 546364442)                        \
   V(Float32x4, get:x, Float32x4ShuffleX, 1674625343)                           \
   V(Float32x4, get:y, Float32x4ShuffleY, 540293915)                            \
   V(Float32x4, get:z, Float32x4ShuffleZ, 320347578)                            \
   V(Float32x4, get:w, Float32x4ShuffleW, 1770606624)                           \
-  V(Float32x4, _mul, Float32x4Mul, 861549065)                                  \
-  V(Float32x4, _sub, Float32x4Sub, 460363214)                                  \
-  V(Float32x4, _add, Float32x4Add, 1487592255)                                 \
+  V(Float32x4, _mul, Float32x4Mul, 42807622)                                   \
+  V(Float32x4, _sub, Float32x4Sub, 103774455)                                  \
+  V(Float32x4, _add, Float32x4Add, 1352634374)                                 \
 
 #define GRAPH_CORE_INTRINSICS_LIST(V)                                          \
   V(_List, get:length, ObjectArrayLength, 630471378)                           \
@@ -278,18 +278,24 @@
   V(_ImmutableList, get:length, ImmutableArrayLength, 630471378)               \
   V(_ImmutableList, [], ImmutableArrayGetIndexed, 360400496)                   \
   V(_GrowableList, get:length, GrowableArrayLength, 417111542)                 \
-  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 193746510)            \
-  V(_GrowableList, _setData, GrowableArraySetData, 1496536873)                 \
-  V(_GrowableList, _setLength, GrowableArraySetLength, 32203572)               \
+  V(_GrowableList, get:_capacity, GrowableArrayCapacity, 41110914)             \
+  V(_GrowableList, _setData, GrowableArraySetData, 210059283)                  \
+  V(_GrowableList, _setLength, GrowableArraySetLength, 335652822)              \
   V(_GrowableList, [], GrowableArrayGetIndexed, 1957529650)                    \
   V(_GrowableList, []=, GrowableArraySetIndexed, 225246870)                    \
   V(_StringBase, get:length, StringBaseLength, 707533587)                      \
+  V(_OneByteString, codeUnitAt, OneByteStringCodeUnitAt, 1436590579)           \
+  V(_TwoByteString, codeUnitAt, TwoByteStringCodeUnitAt, 1436590579)           \
+  V(_ExternalOneByteString, codeUnitAt, ExternalOneByteStringCodeUnitAt,       \
+    1436590579)                                                                \
+  V(_ExternalTwoByteString, codeUnitAt, ExternalTwoByteStringCodeUnitAt,       \
+    1436590579)                                                                \
   V(_Double, unary-, DoubleFlipSignBit, 1783281169)                            \
   V(_Double, truncateToDouble, DoubleTruncate, 791143891)                      \
   V(_Double, roundToDouble, DoubleRound, 797558034)                            \
   V(_Double, floorToDouble, DoubleFloor, 1789426271)                           \
   V(_Double, ceilToDouble, DoubleCeil, 453271198)                              \
-  V(_Double, _modulo, DoubleMod, 1093862165)
+  V(_Double, _modulo, DoubleMod, 776062204)
 
 
 #define GRAPH_INTRINSICS_LIST(V)                                               \
@@ -299,8 +305,8 @@
 
 #define DEVELOPER_LIB_INTRINSIC_LIST(V)                                        \
   V(_UserTag, makeCurrent, UserTag_makeCurrent, 187721469)                     \
-  V(::, _getDefaultTag, UserTag_defaultTag, 1872263331)                        \
-  V(::, _getCurrentTag, Profiler_getCurrentTag, 692104531)                     \
+  V(::, _getDefaultTag, UserTag_defaultTag, 350077879)                         \
+  V(::, _getCurrentTag, Profiler_getCurrentTag, 1215225901)                    \
 
 #define ALL_INTRINSICS_NO_INTEGER_LIB_LIST(V)                                  \
   CORE_LIB_INTRINSIC_LIST(V)                                                   \
@@ -324,154 +330,153 @@
   V(_ImmutableList, get:length, ImmutableArrayLength, 630471378)               \
   V(_TypedList, get:length, TypedDataLength, 546364442)                        \
   V(_GrowableList, get:length, GrowableArrayLength, 417111542)                 \
-  V(_GrowableList, add, GrowableListAdd, 242296201)                            \
-  V(_GrowableList, removeLast, GrowableListRemoveLast, 1655383014)             \
+  V(_GrowableList, add, GrowableListAdd, 219371757)                            \
+  V(_GrowableList, removeLast, GrowableListRemoveLast, 324891524)              \
   V(_StringBase, get:length, StringBaseLength, 707533587)                      \
-  V(ListIterator, moveNext, ListIteratorMoveNext, 1467737539)                  \
-  V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 784200630)   \
+  V(ListIterator, moveNext, ListIteratorMoveNext, 1065954929)                  \
+  V(_FixedSizeArrayIterator, moveNext, FixedListIteratorMoveNext, 1451346178)  \
   V(_GrowableList, get:iterator, GrowableArrayIterator, 1840323187)            \
   V(_GrowableList, forEach, GrowableArrayForEach, 620771070)                   \
-  V(_List, ., ObjectArrayAllocate, 184405219)                                  \
+  V(_List, ., ObjectArrayAllocate, 1661438741)                                 \
   V(_List, [], ObjectArrayGetIndexed, 360400496)                               \
   V(_List, []=, ObjectArraySetIndexed, 886228780)                              \
   V(ListMixin, get:isEmpty, ListMixinIsEmpty, 2021497798)                      \
-  V(_List, get:iterator, ObjectArrayIterator, 1930956161)                      \
+  V(_List, get:iterator, ObjectArrayIterator, 295498778)                       \
   V(_List, forEach, ObjectArrayForEach, 180150673)                             \
-  V(_List, _slice, ObjectArraySlice, 1785552519)                               \
-  V(_ImmutableList, get:iterator, ImmutableArrayIterator, 1930956161)          \
+  V(_List, _slice, ObjectArraySlice, 840558357)                                \
+  V(_ImmutableList, get:iterator, ImmutableArrayIterator, 295498778)           \
   V(_ImmutableList, forEach, ImmutableArrayForEach, 180150673)                 \
   V(_ImmutableList, [], ImmutableArrayGetIndexed, 360400496)                   \
   V(_GrowableList, [], GrowableArrayGetIndexed, 1957529650)                    \
   V(_GrowableList, []=, GrowableArraySetIndexed, 225246870)                    \
-  V(Float32List, [], Float32ArrayGetIndexed, 1002307136)                       \
-  V(Float32List, []=, Float32ArraySetIndexed, 279546769)                       \
-  V(Float64List, [], Float64ArrayGetIndexed, 816943529)                        \
-  V(Float64List, []=, Float64ArraySetIndexed, 1929239576)                      \
-  V(Int8List, [], Int8ArrayGetIndexed, 1141846285)                             \
-  V(Int8List, []=, Int8ArraySetIndexed, 1486839324)                            \
-  V(Uint8List, [], Uint8ArrayGetIndexed, 513704632)                            \
-  V(Uint8List, []=, Uint8ArraySetIndexed, 2123520783)                          \
-  V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 513704632)              \
-  V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 1015846567)            \
-  V(Uint16List, [], Uint16ArrayGetIndexed, 118958722)                          \
-  V(Uint16List, []=, Uint16ArraySetIndexed, 658824450)                         \
-  V(Int16List, [], Int16ArrayGetIndexed, 1826359619)                           \
-  V(Int16List, []=, Int16ArraySetIndexed, 1108689116)                          \
-  V(Int32List, [], Int32ArrayGetIndexed, 681203163)                            \
-  V(Int32List, []=, Int32ArraySetIndexed, 1786886245)                          \
-  V(Int64List, [], Int64ArrayGetIndexed, 1883155004)                           \
-  V(Int64List, []=, Int64ArraySetIndexed, 905815059)                           \
-  V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 215420949)                  \
-  V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 1138146450)                \
-  V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 1003520035)                   \
-  V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 225448326)                   \
-  V(_ByteDataView, setInt8, ByteDataViewSetInt8, 1091734252)                   \
-  V(_ByteDataView, setUint8, ByteDataViewSetUint8, 549773093)                  \
-  V(_ByteDataView, setInt16, ByteDataViewSetInt16, 1580120352)                 \
-  V(_ByteDataView, setUint16, ByteDataViewSetUint16, 948267909)                \
-  V(_ByteDataView, setInt32, ByteDataViewSetInt32, 2088513508)                 \
-  V(_ByteDataView, setUint32, ByteDataViewSetUint32, 1125319)                  \
-  V(_ByteDataView, setInt64, ByteDataViewSetInt64, 192928709)                  \
-  V(_ByteDataView, setUint64, ByteDataViewSetUint64, 483118836)                \
-  V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 1241910514)             \
-  V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 1950485343)             \
-  V(_ByteDataView, getInt8, ByteDataViewGetInt8, 1939363561)                   \
-  V(_ByteDataView, getUint8, ByteDataViewGetUint8, 121087953)                  \
-  V(_ByteDataView, getInt16, ByteDataViewGetInt16, 591911343)                  \
-  V(_ByteDataView, getUint16, ByteDataViewGetUint16, 2114157459)               \
-  V(_ByteDataView, getInt32, ByteDataViewGetInt32, 712570242)                  \
-  V(_ByteDataView, getUint32, ByteDataViewGetUint32, 162058988)                \
-  V(_ByteDataView, getInt64, ByteDataViewGetInt64, 1566486016)                 \
-  V(_ByteDataView, getUint64, ByteDataViewGetUint64, 1397980812)               \
-  V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 1251636679)             \
-  V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 1940177769)             \
-  V(::, asin, MathASin, 848695059)                                             \
-  V(::, acos, MathACos, 337299516)                                             \
-  V(::, atan, MathATan, 866406810)                                             \
-  V(::, atan2, MathATan2, 1901969510)                                          \
-  V(::, cos, MathCos, 1148850331)                                              \
-  V(::, exp, MathExp, 1006863255)                                              \
-  V(::, log, MathLog, 817988874)                                               \
+  V(Float32List, [], Float32ArrayGetIndexed, 1451643535)                       \
+  V(Float32List, []=, Float32ArraySetIndexed, 453873887)                       \
+  V(Float64List, [], Float64ArrayGetIndexed, 2049378701)                       \
+  V(Float64List, []=, Float64ArraySetIndexed, 328934501)                       \
+  V(Int8List, [], Int8ArrayGetIndexed, 110819507)                              \
+  V(Int8List, []=, Int8ArraySetIndexed, 865684695)                             \
+  V(Uint8List, [], Uint8ArrayGetIndexed, 41288685)                             \
+  V(Uint8List, []=, Uint8ArraySetIndexed, 101536342)                           \
+  V(Uint8ClampedList, [], Uint8ClampedArrayGetIndexed, 41288685)               \
+  V(Uint8ClampedList, []=, Uint8ClampedArraySetIndexed, 687206488)             \
+  V(Uint16List, [], Uint16ArrayGetIndexed, 1053739567)                         \
+  V(Uint16List, []=, Uint16ArraySetIndexed, 1547307961)                        \
+  V(Int16List, [], Int16ArrayGetIndexed, 389863073)                            \
+  V(Int16List, []=, Int16ArraySetIndexed, 855133756)                           \
+  V(Int32List, [], Int32ArrayGetIndexed, 640610057)                            \
+  V(Int32List, []=, Int32ArraySetIndexed, 453358705)                           \
+  V(Int64List, [], Int64ArrayGetIndexed, 202150810)                            \
+  V(Int64List, []=, Int64ArraySetIndexed, 924110852)                           \
+  V(_Uint8ArrayView, [], Uint8ArrayViewGetIndexed, 1338422227)                 \
+  V(_Uint8ArrayView, []=, Uint8ArrayViewSetIndexed, 540212720)                 \
+  V(_Int8ArrayView, [], Int8ArrayViewGetIndexed, 302213458)                    \
+  V(_Int8ArrayView, []=, Int8ArrayViewSetIndexed, 1837635160)                  \
+  V(_ByteDataView, setInt8, ByteDataViewSetInt8, 660389322)                    \
+  V(_ByteDataView, setUint8, ByteDataViewSetUint8, 1651986039)                 \
+  V(_ByteDataView, setInt16, ByteDataViewSetInt16, 2051262146)                 \
+  V(_ByteDataView, setUint16, ByteDataViewSetUint16, 1692244111)               \
+  V(_ByteDataView, setInt32, ByteDataViewSetInt32, 862135882)                  \
+  V(_ByteDataView, setUint32, ByteDataViewSetUint32, 361732249)                \
+  V(_ByteDataView, setInt64, ByteDataViewSetInt64, 1208972197)                 \
+  V(_ByteDataView, setUint64, ByteDataViewSetUint64, 1545853836)               \
+  V(_ByteDataView, setFloat32, ByteDataViewSetFloat32, 1333183642)             \
+  V(_ByteDataView, setFloat64, ByteDataViewSetFloat64, 1579015503)             \
+  V(_ByteDataView, getInt8, ByteDataViewGetInt8, 29018237)                     \
+  V(_ByteDataView, getUint8, ByteDataViewGetUint8, 312322868)                  \
+  V(_ByteDataView, getInt16, ByteDataViewGetInt16, 1613243255)                 \
+  V(_ByteDataView, getUint16, ByteDataViewGetUint16, 284020105)                \
+  V(_ByteDataView, getInt32, ByteDataViewGetInt32, 2036535169)                 \
+  V(_ByteDataView, getUint32, ByteDataViewGetUint32, 571293096)                \
+  V(_ByteDataView, getInt64, ByteDataViewGetInt64, 1971181000)                 \
+  V(_ByteDataView, getUint64, ByteDataViewGetUint64, 799775022)                \
+  V(_ByteDataView, getFloat32, ByteDataViewGetFloat32, 947822534)              \
+  V(_ByteDataView, getFloat64, ByteDataViewGetFloat64, 1402356525)             \
+  V(::, asin, MathASin, 1678592173)                                            \
+  V(::, acos, MathACos, 1121218433)                                            \
+  V(::, atan, MathATan, 1109653625)                                            \
+  V(::, atan2, MathATan2, 894696289)                                           \
+  V(::, cos, MathCos, 2006233918)                                              \
+  V(::, exp, MathExp, 1500946333)                                              \
+  V(::, log, MathLog, 739403086)                                               \
   V(::, max, MathMax, 1410473322)                                              \
   V(::, min, MathMin, 1115051548)                                              \
-  V(::, pow, MathPow, 864430827)                                               \
-  V(::, sin, MathSin, 939048573)                                               \
-  V(::, sqrt, MathSqrt, 1446681622)                                            \
-  V(::, tan, MathTan, 179725235)                                               \
+  V(::, pow, MathPow, 2058759335)                                              \
+  V(::, sin, MathSin, 65032)                                                   \
+  V(::, sqrt, MathSqrt, 417912310)                                             \
+  V(::, tan, MathTan, 1276867325)                                              \
   V(Lists, copy, ListsCopy, 564237562)                                         \
-  V(_Bigint, get:_neg, Bigint_getNeg, 1681019799)                              \
-  V(_Bigint, get:_used, Bigint_getUsed, 1439136438)                            \
-  V(_Bigint, get:_digits, Bigint_getDigits, 769722770)                         \
-  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2048715833)               \
-  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1882796480)               \
-  V(_HashVMBase, get:_data, LinkedHashMap_getData, 942992497)                  \
-  V(_HashVMBase, set:_data, LinkedHashMap_setData, 1410623019)                 \
-  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 1698421819)         \
-  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1858754514)         \
-  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 98745045)           \
-  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 340628211)          \
-  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 1340385546)   \
-  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 638315987)    \
+  V(_Bigint, get:_neg, Bigint_getNeg, 2079423063)                              \
+  V(_Bigint, get:_used, Bigint_getUsed, 1426329619)                            \
+  V(_Bigint, get:_digits, Bigint_getDigits, 1185333683)                        \
+  V(_HashVMBase, get:_index, LinkedHashMap_getIndex, 2104211307)               \
+  V(_HashVMBase, set:_index, LinkedHashMap_setIndex, 1273697266)               \
+  V(_HashVMBase, get:_data, LinkedHashMap_getData, 1274399923)                 \
+  V(_HashVMBase, set:_data, LinkedHashMap_setData, 1611093357)                 \
+  V(_HashVMBase, get:_usedData, LinkedHashMap_getUsedData, 367462469)          \
+  V(_HashVMBase, set:_usedData, LinkedHashMap_setUsedData, 1049390812)         \
+  V(_HashVMBase, get:_hashMask, LinkedHashMap_getHashMask, 902147072)          \
+  V(_HashVMBase, set:_hashMask, LinkedHashMap_setHashMask, 1236137630)         \
+  V(_HashVMBase, get:_deletedKeys, LinkedHashMap_getDeletedKeys, 812542585)    \
+  V(_HashVMBase, set:_deletedKeys, LinkedHashMap_setDeletedKeys, 1072259010)   \
 
 // A list of core function that should never be inlined.
 #define INLINE_BLACK_LIST(V)                                                   \
-  V(_Bigint, _lsh, Bigint_lsh, 834311957)                                      \
-  V(_Bigint, _rsh, Bigint_rsh, 333337658)                                      \
-  V(_Bigint, _absAdd, Bigint_absAdd, 473436659)                                \
-  V(_Bigint, _absSub, Bigint_absSub, 1018678324)                               \
-  V(_Bigint, _mulAdd, Bigint_mulAdd, 571005736)                                \
-  V(_Bigint, _sqrAdd, Bigint_sqrAdd, 372896038)                                \
-  V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 540033329)            \
-  V(_Montgomery, _mulMod, Montgomery_mulMod, 118781828)                        \
-  V(_Double, >, Double_greaterThan, 1413076759)                                \
+  V(_Bigint, _lsh, Bigint_lsh, 1557746963)                                     \
+  V(_Bigint, _rsh, Bigint_rsh, 761843937)                                      \
+  V(_Bigint, _absAdd, Bigint_absAdd, 1227835493)                               \
+  V(_Bigint, _absSub, Bigint_absSub, 390740532)                                \
+  V(_Bigint, _mulAdd, Bigint_mulAdd, 617534446)                                \
+  V(_Bigint, _sqrAdd, Bigint_sqrAdd, 1623635507)                               \
+  V(_Bigint, _estQuotientDigit, Bigint_estQuotientDigit, 797340802)            \
+  V(_Montgomery, _mulMod, Montgomery_mulMod, 1947987219)                       \
+  V(_Double, >, Double_greaterThan, 1453001345)                                \
   V(_Double, >=, Double_greaterEqualThan, 1815180096)                          \
   V(_Double, <, Double_lessThan, 652059836)                                    \
   V(_Double, <=, Double_lessEqualThan, 512138528)                              \
-  V(_Double, ==, Double_equal, 752327620)                                      \
-  V(_Double, +, Double_add, 854024064)                                         \
-  V(_Double, -, Double_sub, 685132889)                                         \
-  V(_Double, *, Double_mul, 542254390)                                         \
-  V(_Double, /, Double_div, 1145710768)                                        \
-  V(_IntegerImplementation, +, Integer_add, 364498398)                         \
-  V(_IntegerImplementation, -, Integer_sub, 1682674911)                        \
-  V(_IntegerImplementation, *, Integer_mul, 1651115456)                        \
-  V(_IntegerImplementation, ~/, Integer_truncDivide, 108494012)                \
+  V(_Double, ==, Double_equal, 1468668497)                                     \
+  V(_Double, +, Double_add, 1269587413)                                        \
+  V(_Double, -, Double_sub, 1644506555)                                        \
+  V(_Double, *, Double_mul, 600860888)                                         \
+  V(_Double, /, Double_div, 1220198876)                                        \
+  V(_IntegerImplementation, +, Integer_add, 239272130)                         \
+  V(_IntegerImplementation, -, Integer_sub, 216175811)                         \
+  V(_IntegerImplementation, *, Integer_mul, 1301152164)                        \
+  V(_IntegerImplementation, ~/, Integer_truncDivide, 1018128256)               \
   V(_IntegerImplementation, unary-, Integer_negate, 1507648892)                \
-  V(_IntegerImplementation, &, Integer_bitAnd, 286231290)                      \
-  V(_IntegerImplementation, |, Integer_bitOr, 1111108792)                      \
-  V(_IntegerImplementation, ^, Integer_bitXor, 1884808537)                     \
-  V(_IntegerImplementation, >, Integer_greaterThan, 293890061)                 \
-  V(_IntegerImplementation, ==, Integer_equal, 4489308)                        \
+  V(_IntegerImplementation, &, Integer_bitAnd, 1500136766)                     \
+  V(_IntegerImplementation, |, Integer_bitOr, 119412028)                       \
+  V(_IntegerImplementation, ^, Integer_bitXor, 210430781)                      \
+  V(_IntegerImplementation, >, Integer_greaterThan, 673741711)                 \
+  V(_IntegerImplementation, ==, Integer_equal, 272474439)                      \
   V(_IntegerImplementation, <, Integer_lessThan, 652059836)                    \
   V(_IntegerImplementation, <=, Integer_lessEqualThan, 512138528)              \
   V(_IntegerImplementation, >=, Integer_greaterEqualThan, 1815180096)          \
-  V(_IntegerImplementation, <<, Integer_shl, 293751452)                        \
-  V(_IntegerImplementation, >>, Integer_sar, 125091101)                        \
+  V(_IntegerImplementation, <<, Integer_shl, 1127538624)                       \
+  V(_IntegerImplementation, >>, Integer_sar, 1243972513)                       \
 
 // A list of core functions that internally dispatch based on received id.
 #define POLYMORPHIC_TARGET_LIST(V)                                             \
   V(_StringBase, [], StringBaseCharAt, 754527301)                              \
-  V(_StringBase, codeUnitAt, StringBaseCodeUnitAt, 1436590579)                 \
-  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 187609847)                     \
-  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 1826086346)                  \
-  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 1174755987)                  \
-  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1936358273)                \
-  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 1123951931)                  \
-  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 853172551)                 \
-  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 165422183)               \
-  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 1564825450)              \
-  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1123952315)          \
-  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 831892409)               \
-  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 2043203289)                    \
-  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 1759261408)                   \
-  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 267848339)                   \
-  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 350952121)                  \
-  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 1170619358)                  \
-  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1325523969)                \
-  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 541136999)               \
-  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 365317124)               \
-  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 1766802707)          \
-  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 2075229300)              \
+  V(_TypedList, _getInt8, ByteArrayBaseGetInt8, 1508321565)                    \
+  V(_TypedList, _getUint8, ByteArrayBaseGetUint8, 953411007)                   \
+  V(_TypedList, _getInt16, ByteArrayBaseGetInt16, 433971756)                   \
+  V(_TypedList, _getUint16, ByteArrayBaseGetUint16, 1329446488)                \
+  V(_TypedList, _getInt32, ByteArrayBaseGetInt32, 137212209)                   \
+  V(_TypedList, _getUint32, ByteArrayBaseGetUint32, 499907480)                 \
+  V(_TypedList, _getFloat32, ByteArrayBaseGetFloat32, 1672834581)              \
+  V(_TypedList, _getFloat64, ByteArrayBaseGetFloat64, 966634744)               \
+  V(_TypedList, _getFloat32x4, ByteArrayBaseGetFloat32x4, 1197581758)          \
+  V(_TypedList, _getInt32x4, ByteArrayBaseGetInt32x4, 810805548)               \
+  V(_TypedList, _setInt8, ByteArrayBaseSetInt8, 1317196265)                    \
+  V(_TypedList, _setUint8, ByteArrayBaseSetInt8, 1328908284)                   \
+  V(_TypedList, _setInt16, ByteArrayBaseSetInt16, 1827614958)                  \
+  V(_TypedList, _setUint16, ByteArrayBaseSetInt16, 1694054572)                 \
+  V(_TypedList, _setInt32, ByteArrayBaseSetInt32, 915652649)                   \
+  V(_TypedList, _setUint32, ByteArrayBaseSetUint32, 1958474336)                \
+  V(_TypedList, _setFloat32, ByteArrayBaseSetFloat32, 1853026980)              \
+  V(_TypedList, _setFloat64, ByteArrayBaseSetFloat64, 1197862362)              \
+  V(_TypedList, _setFloat32x4, ByteArrayBaseSetFloat32x4, 2093630771)          \
+  V(_TypedList, _setInt32x4, ByteArrayBaseSetInt32x4, 1982971324)              \
 
 // Forward declarations.
 class Function;
@@ -511,9 +516,9 @@
 // List of recognized list factories:
 // (factory-name-symbol, result-cid, fingerprint).
 #define RECOGNIZED_LIST_FACTORY_LIST(V)                                        \
-  V(_ListFactory, kArrayCid, 184405219)                                        \
-  V(_GrowableListWithData, kGrowableObjectArrayCid, 131424500)                 \
-  V(_GrowableListFactory, kGrowableObjectArrayCid, 664918385)                  \
+  V(_ListFactory, kArrayCid, 1661438741)                                       \
+  V(_GrowableListWithData, kGrowableObjectArrayCid, 631736030)                 \
+  V(_GrowableListFactory, kGrowableObjectArrayCid, 1330464656)                 \
   V(_Int8ArrayFactory, kTypedDataInt8ArrayCid, 779569635)                      \
   V(_Uint8ArrayFactory, kTypedDataUint8ArrayCid, 1790399545)                   \
   V(_Uint8ClampedArrayFactory, kTypedDataUint8ClampedArrayCid, 405875159)      \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 6f48c92..46320b4 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1243,11 +1243,12 @@
   // Pre-register the isolate library so the native class implementations
   // can be hooked up before compiling it.
   Library& isolate_lib =
-      Library::Handle(zone, Library::LookupLibrary(Symbols::DartIsolate()));
+      Library::Handle(zone, Library::LookupLibrary(thread,
+                                                   Symbols::DartIsolate()));
   if (isolate_lib.IsNull()) {
     isolate_lib = Library::NewLibraryHelper(Symbols::DartIsolate(), true);
     isolate_lib.SetLoadRequested();
-    isolate_lib.Register();
+    isolate_lib.Register(thread);
     object_store->set_bootstrap_library(ObjectStore::kIsolate, isolate_lib);
   }
   ASSERT(!isolate_lib.IsNull());
@@ -1365,11 +1366,11 @@
   // Pre-register the mirrors library so we can place the vm class
   // MirrorReference there rather than the core library.
 NOT_IN_PRODUCT(
-  lib = Library::LookupLibrary(Symbols::DartMirrors());
+  lib = Library::LookupLibrary(thread, Symbols::DartMirrors());
   if (lib.IsNull()) {
     lib = Library::NewLibraryHelper(Symbols::DartMirrors(), true);
     lib.SetLoadRequested();
-    lib.Register();
+    lib.Register(thread);
     object_store->set_bootstrap_library(ObjectStore::kMirrors, lib);
   }
   ASSERT(!lib.IsNull());
@@ -1381,11 +1382,11 @@
 
   // Pre-register the collection library so we can place the vm class
   // LinkedHashMap there rather than the core library.
-  lib = Library::LookupLibrary(Symbols::DartCollection());
+  lib = Library::LookupLibrary(thread, Symbols::DartCollection());
   if (lib.IsNull()) {
     lib = Library::NewLibraryHelper(Symbols::DartCollection(), true);
     lib.SetLoadRequested();
-    lib.Register();
+    lib.Register(thread);
     object_store->set_bootstrap_library(ObjectStore::kCollection, lib);
   }
   ASSERT(!lib.IsNull());
@@ -1400,17 +1401,17 @@
 
   // Pre-register the developer library so we can place the vm class
   // UserTag there rather than the core library.
-  lib = Library::LookupLibrary(Symbols::DartDeveloper());
+  lib = Library::LookupLibrary(thread, Symbols::DartDeveloper());
   if (lib.IsNull()) {
     lib = Library::NewLibraryHelper(Symbols::DartDeveloper(), true);
     lib.SetLoadRequested();
-    lib.Register();
+    lib.Register(thread);
     object_store->set_bootstrap_library(ObjectStore::kDeveloper, lib);
   }
   ASSERT(!lib.IsNull());
   ASSERT(lib.raw() == Library::DeveloperLibrary());
 
-  lib = Library::LookupLibrary(Symbols::DartDeveloper());
+  lib = Library::LookupLibrary(thread, Symbols::DartDeveloper());
   ASSERT(!lib.IsNull());
   cls = Class::New<UserTag>();
   RegisterPrivateClass(cls, Symbols::_UserTag(), lib);
@@ -1423,11 +1424,11 @@
 
   // Pre-register the typed_data library so the native class implementations
   // can be hooked up before compiling it.
-  lib = Library::LookupLibrary(Symbols::DartTypedData());
+  lib = Library::LookupLibrary(thread, Symbols::DartTypedData());
   if (lib.IsNull()) {
     lib = Library::NewLibraryHelper(Symbols::DartTypedData(), true);
     lib.SetLoadRequested();
-    lib.Register();
+    lib.Register(thread);
     object_store->set_bootstrap_library(ObjectStore::kTypedData, lib);
   }
   ASSERT(!lib.IsNull());
@@ -1582,7 +1583,7 @@
   MethodRecognizer::InitializeState();
 
   // Adds static const fields (class ids) to the class 'ClassID');
-  lib = Library::LookupLibrary(Symbols::DartInternal());
+  lib = Library::LookupLibrary(thread, Symbols::DartInternal());
   ASSERT(!lib.IsNull());
   cls = lib.LookupClassAllowPrivate(Symbols::ClassID());
   ASSERT(!cls.IsNull());
@@ -3422,14 +3423,16 @@
   if (is_synthesized_class() || IsMixinApplication() || IsTopLevel()) {
     return token_pos();
   }
-  const Script& scr = Script::Handle(script());
+  Zone* zone = Thread::Current()->zone();
+  const Script& scr = Script::Handle(zone, script());
   ASSERT(!scr.IsNull());
-  const TokenStream& tkns = TokenStream::Handle(scr.tokens());
+  const TokenStream& tkns = TokenStream::Handle(zone, scr.tokens());
   if (tkns.IsNull()) {
-    ASSERT(Dart::IsRunningPrecompiledCode());
+    ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
     return TokenPosition::kNoSource;
   }
-  TokenStream::Iterator tkit(tkns,
+  TokenStream::Iterator tkit(zone,
+                             tkns,
                              token_pos(),
                              TokenStream::Iterator::kNoNewlines);
   intptr_t level = 0;
@@ -6432,45 +6435,6 @@
   }
   AbstractType& param_type =
       AbstractType::Handle(ParameterTypeAt(parameter_position));
-
-  // TODO(regis): Remove this debugging code.
-  if (param_type.IsNull()) {
-    THR_Print("*** null param_type ***\n");
-    THR_Print("parameter_position: %" Pd "\n", parameter_position);
-    THR_Print("other_parameter_position: %" Pd "\n", other_parameter_position);
-    String& str = String::Handle();
-    str = QualifiedScrubbedName();
-    THR_Print("function name: %s\n", str.ToCString());
-    str = other.QualifiedScrubbedName();
-    THR_Print("other function name: %s\n", str.ToCString());
-    Class& owner = Class::Handle();
-    owner = Owner();
-    THR_Print("function owner: %s\n", owner.ToCString());
-    owner = other.Owner();
-    THR_Print("other function owner: %s\n", owner.ToCString());
-    THR_Print("other_param_type: %s\n", other_param_type.ToCString());
-    AbstractType& type = AbstractType::Handle();
-    if (parameter_position > 0) {
-      type = ParameterTypeAt(0);
-      THR_Print("receiver type: %s\n",
-                type.IsNull()? "null" : type.ToCString());
-    }
-    THR_Print("has code: %s\n", HasCode() ? "yes" : "no");
-    str = Report::PrependSnippet(Report::kWarning,
-                                 Script::Handle(script()),
-                                 token_pos(),
-                                 Report::AtLocation,
-                                 Symbols::Empty());
-    THR_Print("function source: %s\n", str.ToCString());
-    for (intptr_t i = 0; i < NumParameters(); i++) {
-      THR_Print("function param %" Pd "\n", i);
-      str = ParameterNameAt(i);
-      THR_Print("  name: %s\n", str.IsNull() ? "null" : str.ToCString());
-      type = ParameterTypeAt(i);
-      THR_Print("  type: %s\n", type.IsNull() ? "null" : type.ToCString());
-    }
-  }
-
   if (!param_type.IsInstantiated()) {
     param_type = param_type.InstantiateFrom(type_arguments,
                                             bound_error,
@@ -7077,20 +7041,20 @@
 
 
 RawClass* Function::Owner() const {
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
-  if (obj.IsClass()) {
-    return Class::Cast(obj).raw();
+  if (raw_ptr()->owner_->IsClass()) {
+    return Class::RawCast(raw_ptr()->owner_);
   }
+  const Object& obj = Object::Handle(raw_ptr()->owner_);
   ASSERT(obj.IsPatchClass());
   return PatchClass::Cast(obj).patched_class();
 }
 
 
 RawClass* Function::origin() const {
-  const Object& obj = Object::Handle(raw_ptr()->owner_);
-  if (obj.IsClass()) {
-    return Class::Cast(obj).raw();
+  if (raw_ptr()->owner_->IsClass()) {
+    return Class::RawCast(raw_ptr()->owner_);
   }
+  const Object& obj = Object::Handle(raw_ptr()->owner_);
   ASSERT(obj.IsPatchClass());
   return PatchClass::Cast(obj).origin_class();
 }
@@ -7163,15 +7127,16 @@
     // constructor from the mixin to use.
     return String::null();
   }
-  const Script& func_script = Script::Handle(script());
-  const TokenStream& stream = TokenStream::Handle(func_script.tokens());
+  Zone* zone = Thread::Current()->zone();
+  const Script& func_script = Script::Handle(zone, script());
+  const TokenStream& stream = TokenStream::Handle(zone, func_script.tokens());
   if (!func_script.HasSource()) {
     // When source is not available, avoid printing the whole token stream and
     // doing expensive position calculations.
     return stream.GenerateSource(token_pos(), end_token_pos().Next());
   }
 
-  const TokenStream::Iterator tkit(stream, end_token_pos());
+  const TokenStream::Iterator tkit(zone, stream, end_token_pos());
   intptr_t from_line;
   intptr_t from_col;
   intptr_t to_line;
@@ -7188,10 +7153,10 @@
   if ((tkit.CurrentTokenKind() == Token::kCOMMA) ||                   // Case 1.
       (tkit.CurrentTokenKind() == Token::kRPAREN) ||                  // Case 2.
       (tkit.CurrentTokenKind() == Token::kSEMICOLON &&
-       String::Handle(name()).Equals("<anonymous closure>"))) {  // Case 3.
+       String::Handle(zone, name()).Equals("<anonymous closure>"))) {  // Cas 3.
     last_tok_len = 0;
   }
-  const String& result = String::Handle(func_script.GetSnippet(
+  const String& result = String::Handle(zone, func_script.GetSnippet(
       from_line, from_col, to_line, to_col + last_tok_len));
   ASSERT(!result.IsNull());
   return result.raw();
@@ -7202,10 +7167,13 @@
 // arguments.
 int32_t Function::SourceFingerprint() const {
   uint32_t result = 0;
-  TokenStream::Iterator tokens_iterator(TokenStream::Handle(
-      Script::Handle(script()).tokens()), token_pos());
-  Object& obj = Object::Handle();
-  String& literal = String::Handle();
+  Zone* zone = Thread::Current()->zone();
+  TokenStream::Iterator tokens_iterator(
+      zone,
+      TokenStream::Handle(zone, Script::Handle(zone, script()).tokens()),
+      token_pos());
+  Object& obj = Object::Handle(zone);
+  String& literal = String::Handle(zone);
   while (tokens_iterator.CurrentPosition() < end_token_pos()) {
     uint32_t val = 0;
     obj = tokens_iterator.CurrentToken();
@@ -8220,18 +8188,20 @@
 
 RawString* TokenStream::GenerateSource(TokenPosition start_pos,
                                        TokenPosition end_pos) const {
-  Iterator iterator(*this, start_pos, Iterator::kAllTokens);
-  const ExternalTypedData& data = ExternalTypedData::Handle(GetStream());
+  Zone* zone = Thread::Current()->zone();
+  Iterator iterator(zone, *this, start_pos, Iterator::kAllTokens);
+  const ExternalTypedData& data = ExternalTypedData::Handle(zone, GetStream());
   const GrowableObjectArray& literals =
-      GrowableObjectArray::Handle(GrowableObjectArray::New(data.Length()));
-  const String& private_key = String::Handle(PrivateKey());
+      GrowableObjectArray::Handle(zone,
+                                  GrowableObjectArray::New(data.Length()));
+  const String& private_key = String::Handle(zone, PrivateKey());
   intptr_t private_len = private_key.Length();
 
   Token::Kind curr = iterator.CurrentTokenKind();
   Token::Kind prev = Token::kILLEGAL;
   // Handles used in the loop.
-  Object& obj = Object::Handle();
-  String& literal = String::Handle();
+  Object& obj = Object::Handle(zone);
+  String& literal = String::Handle(zone);
   // Current indentation level.
   int indent = 0;
 
@@ -8405,7 +8375,11 @@
 
 TokenPosition TokenStream::ComputeSourcePosition(
     TokenPosition tok_pos) const {
-  Iterator iterator(*this, TokenPosition::kMinSource, Iterator::kAllTokens);
+  Zone* zone = Thread::Current()->zone();
+  Iterator iterator(zone,
+                    *this,
+                    TokenPosition::kMinSource,
+                    Iterator::kAllTokens);
   TokenPosition src_pos = TokenPosition::kMinSource;
   Token::Kind kind = iterator.CurrentTokenKind();
   while ((iterator.CurrentPosition() < tok_pos) && (kind != Token::kEOS)) {
@@ -8669,15 +8643,16 @@
 }
 
 
-TokenStream::Iterator::Iterator(const TokenStream& tokens,
+TokenStream::Iterator::Iterator(Zone* zone,
+                                const TokenStream& tokens,
                                 TokenPosition token_pos,
                                 Iterator::StreamType stream_type)
-    : tokens_(TokenStream::Handle(tokens.raw())),
-      data_(ExternalTypedData::Handle(tokens.GetStream())),
+    : tokens_(TokenStream::Handle(zone, tokens.raw())),
+      data_(ExternalTypedData::Handle(zone, tokens.GetStream())),
       stream_(reinterpret_cast<uint8_t*>(data_.DataAddr(0)), data_.Length()),
-      token_objects_(Array::Handle(
-          GrowableObjectArray::Handle(tokens.TokenObjects()).data())),
-      obj_(Object::Handle()),
+      token_objects_(Array::Handle(zone,
+         GrowableObjectArray::Handle(zone, tokens.TokenObjects()).data())),
+      obj_(Object::Handle(zone)),
       cur_token_pos_(token_pos.Pos()),
       cur_token_kind_(Token::kILLEGAL),
       cur_token_obj_index_(-1),
@@ -8822,7 +8797,7 @@
 RawString* Script::GenerateSource() const {
   const TokenStream& token_stream = TokenStream::Handle(tokens());
   if (token_stream.IsNull()) {
-    ASSERT(Dart::IsRunningPrecompiledCode());
+    ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
     return String::null();
   }
   return token_stream.GenerateSource();
@@ -8840,7 +8815,8 @@
   Smi& value = Smi::Handle(zone);
   String& tokenValue = String::Handle(zone);
   ASSERT(!tkns.IsNull());
-  TokenStream::Iterator tkit(tkns,
+  TokenStream::Iterator tkit(zone,
+                             tkns,
                              TokenPosition::kMinSource,
                              TokenStream::Iterator::kAllTokens);
   int current_line = -1;
@@ -8989,9 +8965,10 @@
                               intptr_t* column,
                               intptr_t* token_len) const {
   ASSERT(line != NULL);
-  const TokenStream& tkns = TokenStream::Handle(tokens());
+  Zone* zone = Thread::Current()->zone();
+  const TokenStream& tkns = TokenStream::Handle(zone, tokens());
   if (tkns.IsNull()) {
-    ASSERT(Dart::IsRunningPrecompiledCode());
+    ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
     *line = -1;
     if (column != NULL) {
       *column = -1;
@@ -9002,7 +8979,8 @@
     return;
   }
   if (column == NULL) {
-    TokenStream::Iterator tkit(tkns,
+    TokenStream::Iterator tkit(zone,
+                               tkns,
                                TokenPosition::kMinSource,
                                TokenStream::Iterator::kAllTokens);
     intptr_t cur_line = line_offset() + 1;
@@ -9015,7 +8993,7 @@
     }
     *line = cur_line;
   } else {
-    const String& src = String::Handle(Source());
+    const String& src = String::Handle(zone, Source());
     TokenPosition src_pos = tkns.ComputeSourcePosition(token_pos);
     Scanner scanner(src, Symbols::Empty());
     scanner.ScanTo(src_pos);
@@ -9042,12 +9020,14 @@
                               TokenPosition* last_token_index) const {
   ASSERT(first_token_index != NULL && last_token_index != NULL);
   ASSERT(line_number > 0);
+  Zone* zone = Thread::Current()->zone();
   *first_token_index = TokenPosition::kNoSource;
   *last_token_index = TokenPosition::kNoSource;
-  const TokenStream& tkns = TokenStream::Handle(tokens());
+  const TokenStream& tkns = TokenStream::Handle(zone, tokens());
   line_number -= line_offset();
   if (line_number < 1) line_number = 1;
-  TokenStream::Iterator tkit(tkns,
+  TokenStream::Iterator tkit(zone,
+                             tkns,
                              TokenPosition::kMinSource,
                              TokenStream::Iterator::kAllTokens);
   // Scan through the token stream to the required line.
@@ -9090,7 +9070,7 @@
 RawString* Script::GetLine(intptr_t line_number, Heap::Space space) const {
   const String& src = String::Handle(Source());
   if (src.IsNull()) {
-    ASSERT(Dart::IsRunningPrecompiledCode());
+    ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
     return Symbols::OptimizedOut().raw();
   }
   intptr_t relative_line_number = line_number - line_offset();
@@ -9132,7 +9112,7 @@
                               intptr_t to_column) const {
   const String& src = String::Handle(Source());
   if (src.IsNull()) {
-    ASSERT(Dart::IsRunningPrecompiledCode());
+    ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
     return Symbols::OptimizedOut().raw();
   }
   intptr_t length = src.Length();
@@ -10545,19 +10525,21 @@
 
 
 void Library::InitCoreLibrary(Isolate* isolate) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
   const String& core_lib_url = Symbols::DartCore();
   const Library& core_lib =
-      Library::Handle(Library::NewLibraryHelper(core_lib_url, false));
+      Library::Handle(zone, Library::NewLibraryHelper(core_lib_url, false));
   core_lib.SetLoadRequested();
-  core_lib.Register();
+  core_lib.Register(thread);
   isolate->object_store()->set_bootstrap_library(ObjectStore::kCore, core_lib);
   isolate->object_store()->set_root_library(Library::Handle());
 
   // Hook up predefined classes without setting their library pointers. These
   // classes are coming from the VM isolate, and are shared between multiple
   // isolates so setting their library pointers would be wrong.
-  const Class& cls = Class::Handle(Object::dynamic_class());
-  core_lib.AddObject(cls, String::Handle(cls.Name()));
+  const Class& cls = Class::Handle(zone, Object::dynamic_class());
+  core_lib.AddObject(cls, String::Handle(zone, cls.Name()));
 }
 
 
@@ -10583,7 +10565,7 @@
   const String& native_flds_lib_name = Symbols::DartNativeWrappersLibName();
   native_flds_lib.SetName(native_flds_lib_name);
   native_flds_lib.SetLoadRequested();
-  native_flds_lib.Register();
+  native_flds_lib.Register(thread);
   native_flds_lib.SetLoadInProgress();
   isolate->object_store()->set_native_wrappers_library(native_flds_lib);
   static const char* const kNativeWrappersClass = "NativeFieldWrapperClass";
@@ -10604,31 +10586,51 @@
 }
 
 
+// LibraryLookupSet maps URIs to libraries.
+class LibraryLookupTraits {
+ public:
+  static const char* Name() { return "LibraryLookupTraits"; }
+  static bool ReportStats() { return false; }
+
+  static bool IsMatch(const Object& a, const Object& b) {
+    const String& a_str = String::Cast(a);
+    const String& b_str = String::Cast(b);
+
+    ASSERT(a_str.HasHash() && b_str.HasHash());
+    return a_str.Equals(b_str);
+  }
+
+  static uword Hash(const Object& key) {
+    return String::Cast(key).Hash();
+  }
+
+  static RawObject* NewKey(const String& str) {
+    return str.raw();
+  }
+};
+typedef UnorderedHashMap<LibraryLookupTraits> LibraryLookupMap;
+
+
 // Returns library with given url in current isolate, or NULL.
-RawLibrary* Library::LookupLibrary(const String &url) {
-  Thread* thread = Thread::Current();
+RawLibrary* Library::LookupLibrary(Thread* thread, const String &url) {
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
-  Library& lib = Library::Handle(zone, Library::null());
-  String& lib_url = String::Handle(zone, String::null());
-  GrowableObjectArray& libs = GrowableObjectArray::Handle(
-      zone, isolate->object_store()->libraries());
+  ObjectStore* object_store = isolate->object_store();
 
   // Make sure the URL string has an associated hash code
   // to speed up the repeated equality checks.
   url.Hash();
 
-  intptr_t len = libs.Length();
-  for (intptr_t i = 0; i < len; i++) {
-    lib ^= libs.At(i);
-    lib_url ^= lib.url();
-
-    ASSERT(url.HasHash() && lib_url.HasHash());
-    if (lib_url.Equals(url)) {
-      return lib.raw();
-    }
+  // Use the libraries map to lookup the library by URL.
+  Library& lib = Library::Handle(zone);
+  if (object_store->libraries_map() == Array::null()) {
+    return Library::null();
+  } else {
+    LibraryLookupMap map(object_store->libraries_map());
+    lib ^= map.GetOrNull(url);
+    ASSERT(map.Release().raw() == object_store->libraries_map());
   }
-  return Library::null();
+  return lib.raw();
 }
 
 
@@ -10652,35 +10654,32 @@
 }
 
 
-bool Library::IsKeyUsed(intptr_t key) {
-  intptr_t lib_key;
-  const GrowableObjectArray& libs = GrowableObjectArray::Handle(
-      Isolate::Current()->object_store()->libraries());
-  Library& lib = Library::Handle();
-  String& lib_url = String::Handle();
-  for (int i = 0; i < libs.Length(); i++) {
-    lib ^= libs.At(i);
-    lib_url ^= lib.url();
-    lib_key = lib_url.Hash();
-    if (lib_key == key) {
-      return true;
-    }
-  }
-  return false;
-}
-
-
+// Create a private key for this library. It is based on the hash of the
+// library URI and the sequence number of the library to guarantee unique
+// private keys without having to verify.
 void Library::AllocatePrivateKey() const {
-  const String& url = String::Handle(this->url());
-  intptr_t key_value = url.Hash() & kIntptrMax;
-  while ((key_value == 0) || Library::IsKeyUsed(key_value)) {
-    key_value = (key_value + 1) & kIntptrMax;
-  }
-  ASSERT(key_value > 0);
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
+
+  // Format of the private key is: "@<sequence number><6 digits of hash>
+  const intptr_t hash_mask = 0x7FFFF;
+
+  const String& url = String::Handle(zone, this->url());
+  intptr_t hash_value = url.Hash() & hash_mask;
+
+  const GrowableObjectArray& libs = GrowableObjectArray::Handle(zone,
+      isolate->object_store()->libraries());
+  intptr_t sequence_value = libs.Length();
+
   char private_key[32];
   OS::SNPrint(private_key, sizeof(private_key),
-              "%c%" Pd "", kPrivateKeySeparator, key_value);
-  StorePointer(&raw_ptr()->private_key_, String::New(private_key, Heap::kOld));
+              "%c%" Pd "%06" Pd "",
+              kPrivateKeySeparator, sequence_value, hash_value);
+  const String& key = String::Handle(zone, String::New(private_key,
+                                                       Heap::kOld));
+  key.Hash();  // This string may end up in the VM isolate.
+  StorePointer(&raw_ptr()->private_key_, key.raw());
 }
 
 
@@ -10721,12 +10720,14 @@
 
 
 RawLibrary* Library::GetLibrary(intptr_t index) {
-  Isolate* isolate = Isolate::Current();
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
   const GrowableObjectArray& libs =
-      GrowableObjectArray::Handle(isolate->object_store()->libraries());
+      GrowableObjectArray::Handle(zone, isolate->object_store()->libraries());
   ASSERT(!libs.IsNull());
   if ((0 <= index) && (index < libs.Length())) {
-    Library& lib = Library::Handle();
+    Library& lib = Library::Handle(zone);
     lib ^= libs.At(index);
     return lib.raw();
   }
@@ -10734,15 +10735,53 @@
 }
 
 
-void Library::Register() const {
-  ASSERT(Library::LookupLibrary(String::Handle(url())) == Library::null());
-  ASSERT(String::Handle(url()).HasHash());
-  ObjectStore* object_store = Isolate::Current()->object_store();
-  GrowableObjectArray& libs =
-      GrowableObjectArray::Handle(object_store->libraries());
+void Library::Register(Thread* thread) const {
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
+  ObjectStore* object_store = isolate->object_store();
+
+  // A library is "registered" in two places:
+  // - A growable array mapping from index to library.
+  const String& lib_url = String::Handle(zone, url());
+  ASSERT(Library::LookupLibrary(thread, lib_url) == Library::null());
+  ASSERT(lib_url.HasHash());
+  GrowableObjectArray& libs = GrowableObjectArray::Handle(zone,
+      object_store->libraries());
   ASSERT(!libs.IsNull());
   set_index(libs.Length());
   libs.Add(*this);
+
+  // - A map from URL string to library.
+  if (object_store->libraries_map() == Array::null()) {
+    LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld));
+    object_store->set_libraries_map(map.Release());
+  }
+
+  LibraryLookupMap map(object_store->libraries_map());
+  bool present = map.UpdateOrInsert(lib_url, *this);
+  ASSERT(!present);
+  object_store->set_libraries_map(map.Release());
+}
+
+
+void Library::RegisterLibraries(Thread* thread,
+                                const GrowableObjectArray& libs) {
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
+  Library& lib = Library::Handle(zone);
+  String& lib_url = String::Handle(zone);
+
+  LibraryLookupMap map(HashTables::New<LibraryLookupMap>(16, Heap::kOld));
+
+  intptr_t len = libs.Length();
+  for (intptr_t i = 0; i < len; i++) {
+    lib ^= libs.At(i);
+    lib_url = lib.url();
+    map.InsertNewOrGetValue(lib_url, lib);
+  }
+  // Now rememeber these in the isolate's object store.
+  isolate->object_store()->set_libraries(libs);
+  isolate->object_store()->set_libraries_map(map.Release());
 }
 
 
@@ -10981,7 +11020,7 @@
   }
   ASSERT(is_deferred_load());
   ASSERT(num_imports() == 1);
-  if (Dart::IsRunningPrecompiledCode()) {
+  if (Dart::snapshot_kind() == Snapshot::kAppNoJIT) {
     // The library list was tree-shaken away.
     this->set_is_loaded();
     return true;
@@ -13550,7 +13589,7 @@
   uword code_entry = instrs.EntryPoint();
   const Array& table = Array::Handle(deopt_info_array());
   if (table.IsNull()) {
-    ASSERT(Dart::IsRunningPrecompiledCode());
+    ASSERT(Dart::snapshot_kind() == Snapshot::kAppNoJIT);
     return TypedData::null();
   }
   // Linear search for the PC offset matching the target PC.
@@ -15495,7 +15534,8 @@
 
 
 intptr_t Instance::DataOffsetFor(intptr_t cid) {
-  if (RawObject::IsExternalTypedDataClassId(cid)) {
+  if (RawObject::IsExternalTypedDataClassId(cid) ||
+      RawObject::IsExternalStringClassId(cid)) {
     // Elements start at offset 0 of the external data.
     return 0;
   }
@@ -15605,15 +15645,6 @@
 
 bool AbstractType::IsInstantiated(TrailPtr trail) const {
   // AbstractType is an abstract class.
-#if !defined(PRODUCT)
-  // TODO(srdjan) : Remove temporary code.
-NOT_IN_PRODUCT(
-  Profiler::DumpStackTrace(true);  // Only native stack trace.
-)
-  if (Compiler::IsBackgroundCompilation()) {
-    UNREACHABLE();
-  }
-#endif
   UNREACHABLE();
   return false;
 }
@@ -15967,6 +15998,19 @@
 }
 
 
+bool AbstractType::IsDynamicType() const {
+  if (IsCanonical()) {
+    return raw() == Object::dynamic_type().raw();
+  }
+  return HasResolvedTypeClass() && (type_class() == Object::dynamic_class());
+}
+
+
+bool AbstractType::IsVoidType() const {
+    return raw() == Object::void_type().raw();
+}
+
+
 bool AbstractType::IsNullType() const {
   return !IsFunctionType() &&
       HasResolvedTypeClass() &&
@@ -16352,10 +16396,11 @@
   if (raw_ptr()->sig_or_err_.error_ == LanguageError::null()) {
     return false;  // Valid type, but not a function type.
   }
-  const LanguageError& type_error = LanguageError::Handle(error());
-  if (type_error.IsNull()) {
+  if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) {
     return false;  // Valid function type.
   }
+  const LanguageError& type_error = LanguageError::Handle(error());
+  ASSERT(!type_error.IsNull());
   return type_error.kind() == Report::kMalformedType;
 }
 
@@ -16367,10 +16412,11 @@
   if (!Isolate::Current()->type_checks()) {
     return false;
   }
-  const LanguageError& type_error = LanguageError::Handle(error());
-  if (type_error.IsNull()) {
+  if (!raw_ptr()->sig_or_err_.error_->IsLanguageError()) {
     return false;  // Valid function type.
   }
+  const LanguageError& type_error = LanguageError::Handle(error());
+  ASSERT(!type_error.IsNull());
   return type_error.kind() == Report::kMalboundedType;
 }
 
@@ -16392,9 +16438,8 @@
 
 
 RawLanguageError* Type::error() const {
-  const Object& type_error = Object::Handle(raw_ptr()->sig_or_err_.error_);
-  if (type_error.IsLanguageError()) {
-    return LanguageError::RawCast(type_error.raw());
+  if (raw_ptr()->sig_or_err_.error_->IsLanguageError()) {
+    return LanguageError::RawCast(raw_ptr()->sig_or_err_.error_);
   }
   return LanguageError::null();
 }
@@ -16406,14 +16451,14 @@
 
 
 RawFunction* Type::signature() const {
-  if (raw_ptr()->sig_or_err_.signature_ == Function::null()) {
+  intptr_t cid = raw_ptr()->sig_or_err_.signature_->GetClassId();
+  if (cid == kNullCid) {
     return Function::null();
   }
-  const Object& obj = Object::Handle(raw_ptr()->sig_or_err_.signature_);
-  if (obj.IsFunction()) {
-    return Function::RawCast(obj.raw());
+  if (cid == kFunctionCid) {
+    return Function::RawCast(raw_ptr()->sig_or_err_.signature_);
   }
-  ASSERT(obj.IsLanguageError());  // Type is malformed or malbounded.
+  ASSERT(cid == kLanguageErrorCid);  // Type is malformed or malbounded.
   return Function::null();
 }
 
@@ -16778,9 +16823,29 @@
     const LanguageError& bound_error = LanguageError::Handle(zone, error());
     clone.set_error(bound_error);
   }
+  TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
+  bool type_args_cloned = false;
   // Clone the signature if this type represents a function type.
   const Function& fun = Function::Handle(zone, signature());
   if (!fun.IsNull()) {
+    // If the scope class is not a typedef and if it is generic, it must be the
+    // mixin class, set it to the new owner.
+    if (!type_cls.IsTypedefClass() && type_cls.IsGeneric()) {
+      clone.set_type_class(new_owner);
+      AbstractType& decl_type = AbstractType::Handle(zone);
+#ifdef DEBUG
+      decl_type = type_cls.DeclarationType();
+      ASSERT(decl_type.IsFinalized());
+      const TypeArguments& decl_type_args =
+          TypeArguments::Handle(zone, decl_type.arguments());
+      ASSERT(type_args.Equals(decl_type_args));
+#endif  // DEBUG
+      decl_type = new_owner.DeclarationType();
+      ASSERT(decl_type.IsFinalized());
+      type_args = decl_type.arguments();
+      clone.set_arguments(type_args);
+      type_args_cloned = true;
+    }
     Function& fun_clone = Function::Handle(zone,
         Function::NewSignatureFunction(new_owner, TokenPosition::kNoSource));
     AbstractType& type = AbstractType::Handle(zone, fun.result_type());
@@ -16800,13 +16865,14 @@
     fun_clone.set_parameter_names(Array::Handle(zone, fun.parameter_names()));
     clone.set_signature(fun_clone);
   }
-  TypeArguments& type_args = TypeArguments::Handle(zone, arguments());
-  // Upper bounds of uninstantiated type arguments may form a cycle.
-  if (type_args.IsRecursive() || !type_args.IsInstantiated()) {
-    AddOnlyBuddyToTrail(&trail, clone);
+  if (!type_args_cloned) {
+    // Upper bounds of uninstantiated type arguments may form a cycle.
+    if (type_args.IsRecursive() || !type_args.IsInstantiated()) {
+      AddOnlyBuddyToTrail(&trail, clone);
+    }
+    type_args = type_args.CloneUninstantiated(new_owner, trail);
+    clone.set_arguments(type_args);
   }
-  type_args = type_args.CloneUninstantiated(new_owner, trail);
-  clone.set_arguments(type_args);
   clone.SetIsFinalized();
   return clone.raw();
 }
@@ -16823,7 +16889,15 @@
   Isolate* isolate = thread->isolate();
   AbstractType& type = Type::Handle(zone);
   const Class& cls = Class::Handle(zone, type_class());
-  if (cls.raw() == Object::dynamic_class() && (isolate != Dart::vm_isolate())) {
+  // Since void is a keyword, we never have to canonicalize the void type after
+  // it is canonicalized once by the vm isolate. The parser does the mapping.
+  ASSERT((cls.raw() != Object::void_class()) ||
+         (isolate == Dart::vm_isolate()));
+  // Since dynamic is not a keyword, the parser builds a type that requires
+  // canonicalization.
+  if ((cls.raw() == Object::dynamic_class()) &&
+      (isolate != Dart::vm_isolate())) {
+    ASSERT(Object::dynamic_type().IsCanonical());
     return Object::dynamic_type().raw();
   }
   // Fast canonical lookup/registry for simple types.
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 564db72..a2f8d21 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -3307,7 +3307,8 @@
       kAllTokens
     };
 
-    Iterator(const TokenStream& tokens,
+    Iterator(Zone* zone,
+             const TokenStream& tokens,
              TokenPosition token_pos,
              Iterator::StreamType stream_type = kNoNewlines);
 
@@ -3632,7 +3633,9 @@
     StoreNonPointer(&raw_ptr()->index_, value);
   }
 
-  void Register() const;
+  void Register(Thread* thread) const;
+  static void RegisterLibraries(Thread* thread,
+                                const GrowableObjectArray& libs);
 
   bool IsDebuggable() const {
     return raw_ptr()->debuggable_;
@@ -3654,7 +3657,7 @@
 
   inline intptr_t UrlHash() const;
 
-  static RawLibrary* LookupLibrary(const String& url);
+  static RawLibrary* LookupLibrary(Thread* thread, const String& url);
   static RawLibrary* GetLibrary(intptr_t index);
 
   static void InitCoreLibrary(Isolate* isolate);
@@ -3738,7 +3741,6 @@
                                       bool import_core_lib);
   RawObject* LookupEntry(const String& name, intptr_t *index) const;
 
-  static bool IsKeyUsed(intptr_t key);
   void AllocatePrivateKey() const;
 
   RawString* MakeMetadataName(const Object& obj) const;
@@ -5472,23 +5474,17 @@
   // type.
   RawString* ClassName() const;
 
-  // Check if this type represents the 'dynamic' type.
-  bool IsDynamicType() const {
-    return !IsFunctionType() &&
-        HasResolvedTypeClass() &&
-        (type_class() == Object::dynamic_class());
-  }
+  // Check if this type represents the 'dynamic' type or if it is malformed,
+  // since a malformed type is mapped to 'dynamic'.
+  // Call IsMalformed() first, if distinction is required.
+  bool IsDynamicType() const;
+
+  // Check if this type represents the 'void' type.
+  bool IsVoidType() const;
 
   // Check if this type represents the 'Null' type.
   bool IsNullType() const;
 
-  // Check if this type represents the 'void' type.
-  bool IsVoidType() const {
-    return !IsFunctionType() &&
-        HasResolvedTypeClass() &&
-        (type_class() == Object::void_class());
-  }
-
   bool IsObjectType() const {
     return !IsFunctionType() &&
         HasResolvedTypeClass() &&
diff --git a/runtime/vm/object_dbc_test.cc b/runtime/vm/object_dbc_test.cc
new file mode 100644
index 0000000..464350d
--- /dev/null
+++ b/runtime/vm/object_dbc_test.cc
@@ -0,0 +1,51 @@
+// 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 "platform/assert.h"
+#include "vm/globals.h"
+#if defined(TARGET_ARCH_DBC)
+
+#include "vm/assembler.h"
+#include "vm/object.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+#define __ assembler->
+
+// Generate a simple dart code sequence.
+// This is used to test Code and Instruction object creation.
+void GenerateIncrement(Assembler* assembler) {
+  __ Frame(1);
+  __ LoadConstant(0, Smi::Handle(Smi::New(0)));
+  __ PushConstant(Smi::Handle(Smi::New(1)));
+  __ Push(0);
+  __ AddTOS();
+  __ Trap();
+  __ PopLocal(0);
+  __ Return(0);
+}
+
+
+// Generate a dart code sequence that embeds a string object in it.
+// This is used to test Embedded String objects in the instructions.
+void GenerateEmbedStringInCode(Assembler* assembler, const char* str) {
+  const String& string_object =
+      String::ZoneHandle(String::New(str, Heap::kOld));
+  __ PushConstant(string_object);
+  __ ReturnTOS();
+}
+
+
+// Generate a dart code sequence that embeds a smi object in it.
+// This is used to test Embedded Smi objects in the instructions.
+void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value) {
+  const Smi& smi_object = Smi::ZoneHandle(Smi::New(value));
+  __ PushConstant(smi_object);
+  __ ReturnTOS();
+}
+
+}  // namespace dart
+
+#endif  // defined TARGET_ARCH_DBC
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index 3cfc25b..41290fb 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -1038,7 +1038,6 @@
   GrowableArray<Class*> classes;
   Class& cls = Class::Handle(this->clazz());
   do {
-    cls.Print();
     classes.Add(&Class::Handle(cls.raw()));
     cls = cls.SuperClass();
   } while (!cls.IsNull());
diff --git a/runtime/vm/object_store.cc b/runtime/vm/object_store.cc
index a0feb38..95810d2 100644
--- a/runtime/vm/object_store.cc
+++ b/runtime/vm/object_store.cc
@@ -73,6 +73,7 @@
     typed_data_library_(Library::null()),
     vmservice_library_(Library::null()),
     libraries_(GrowableObjectArray::null()),
+    libraries_map_(Array::null()),
     closure_functions_(GrowableObjectArray::null()),
     pending_classes_(GrowableObjectArray::null()),
     pending_deferred_loads_(GrowableObjectArray::null()),
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 534e516..eb868fb 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -332,6 +332,11 @@
     libraries_ = value.raw();
   }
 
+  RawArray* libraries_map() const { return libraries_map_; }
+  void set_libraries_map(const Array& value) {
+    libraries_map_ = value.raw();
+  }
+
   RawGrowableObjectArray* closure_functions() const {
     return closure_functions_;
   }
@@ -548,6 +553,7 @@
   RawLibrary* typed_data_library_;
   RawLibrary* vmservice_library_;
   RawGrowableObjectArray* libraries_;
+  RawArray* libraries_map_;
   RawGrowableObjectArray* closure_functions_;
   RawGrowableObjectArray* pending_classes_;
   RawGrowableObjectArray* pending_deferred_loads_;
@@ -582,6 +588,8 @@
         return to();
       case Snapshot::kScript:
       case Snapshot::kMessage:
+      case Snapshot::kNone:
+      case Snapshot::kInvalid:
         break;
     }
     UNREACHABLE();
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index aa75ee9..7d9be08 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -162,15 +162,16 @@
 
 
 VM_TEST_CASE(TokenStream) {
-  String& source = String::Handle(String::New("= ( 9 , ."));
-  String& private_key = String::Handle(String::New(""));
+  Zone* zone = Thread::Current()->zone();
+  String& source = String::Handle(zone, String::New("= ( 9 , ."));
+  String& private_key = String::Handle(zone, String::New(""));
   Scanner scanner(source, private_key);
   const Scanner::GrowableTokenStream& ts = scanner.GetStream();
   EXPECT_EQ(6, ts.length());
   EXPECT_EQ(Token::kLPAREN, ts[1].kind);
   const TokenStream& token_stream = TokenStream::Handle(
-      TokenStream::New(ts, private_key, false));
-  TokenStream::Iterator iterator(token_stream, TokenPosition::kMinSource);
+      zone, TokenStream::New(ts, private_key, false));
+  TokenStream::Iterator iterator(zone, token_stream, TokenPosition::kMinSource);
   // EXPECT_EQ(6, token_stream.Length());
   iterator.Advance();  // Advance to '(' token.
   EXPECT_EQ(Token::kLPAREN, iterator.CurrentTokenKind());
@@ -2686,7 +2687,6 @@
 }
 
 
-#if !defined(TARGET_ARCH_DBC)
 static RawLibrary* CreateDummyLibrary(const String& library_name) {
   return Library::New(library_name);
 }
@@ -2968,7 +2968,6 @@
 
   EXPECT_EQ(false, iter.MoveNext());
 }
-#endif  // !defined(TARGET_ARCH_DBC)
 
 
 static RawClass* CreateTestClass(const char* name) {
@@ -4011,7 +4010,7 @@
   TestCase::LoadTestScript(kScriptChars, NULL);
   EXPECT(ClassFinalizer::ProcessPendingClasses());
   const String& name = String::Handle(String::New(TestCase::url()));
-  const Library& lib = Library::Handle(Library::LookupLibrary(name));
+  const Library& lib = Library::Handle(Library::LookupLibrary(thread, name));
   EXPECT(!lib.IsNull());
 
   const Class& class_a = Class::Handle(
@@ -4076,7 +4075,7 @@
 
   // With no breakpoint, function A.b is inlineable.
   const String& name = String::Handle(String::New(TestCase::url()));
-  const Library& vmlib = Library::Handle(Library::LookupLibrary(name));
+  const Library& vmlib = Library::Handle(Library::LookupLibrary(thread, name));
   EXPECT(!vmlib.IsNull());
   const Class& class_a = Class::Handle(
       vmlib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
diff --git a/runtime/vm/os.h b/runtime/vm/os.h
index cd570c4..9064322 100644
--- a/runtime/vm/os.h
+++ b/runtime/vm/os.h
@@ -56,6 +56,13 @@
   // Returns the frequency of the monotonic clock.
   static int64_t GetCurrentMonotonicFrequency();
 
+  // Returns the value of current thread's CPU usage clock in microseconds.
+  // NOTE: This clock will return different values depending on the calling
+  // thread. It is only expected to increase in value as the thread uses
+  // CPU time.
+  // NOTE: This function will return -1 on OSs that are not supported.
+  static int64_t GetCurrentThreadCPUMicros();
+
   // Returns a cleared aligned array of type T with n entries.
   // Alignment must be >= 16 and a power of two.
   template<typename T>
diff --git a/runtime/vm/os_android.cc b/runtime/vm/os_android.cc
index 3269b12..1c22b7c 100644
--- a/runtime/vm/os_android.cc
+++ b/runtime/vm/os_android.cc
@@ -168,6 +168,19 @@
 }
 
 
+int64_t OS::GetCurrentThreadCPUMicros() {
+  struct timespec ts;
+  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) {
+    UNREACHABLE();
+    return -1;
+  }
+  int64_t result = ts.tv_sec;
+  result *= kMicrosecondsPerSecond;
+  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+  return result;
+}
+
+
 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
   const int kMinimumAlignment = 16;
   ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/os_linux.cc b/runtime/vm/os_linux.cc
index 0fc90c7..7d7c7e0 100644
--- a/runtime/vm/os_linux.cc
+++ b/runtime/vm/os_linux.cc
@@ -175,6 +175,19 @@
 }
 
 
+int64_t OS::GetCurrentThreadCPUMicros() {
+  struct timespec ts;
+  if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) != 0) {
+    UNREACHABLE();
+    return -1;
+  }
+  int64_t result = ts.tv_sec;
+  result *= kMicrosecondsPerSecond;
+  result += (ts.tv_nsec / kNanosecondsPerMicrosecond);
+  return result;
+}
+
+
 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
   const int kMinimumAlignment = 16;
   ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/os_macos.cc b/runtime/vm/os_macos.cc
index d2d5576..6d2d02a 100644
--- a/runtime/vm/os_macos.cc
+++ b/runtime/vm/os_macos.cc
@@ -139,6 +139,27 @@
 }
 
 
+int64_t OS::GetCurrentThreadCPUMicros() {
+  mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
+  thread_basic_info_data_t info_data;
+  thread_basic_info_t info = &info_data;
+  mach_port_t thread_port = mach_thread_self();
+  if (thread_port == MACH_PORT_NULL) {
+    return -1;
+  }
+  kern_return_t r = thread_info(thread_port, THREAD_BASIC_INFO,
+                                (thread_info_t)info, &count);
+  mach_port_deallocate(mach_task_self(), thread_port);
+  ASSERT(r == KERN_SUCCESS);
+  int64_t thread_cpu_micros =
+      (info->system_time.seconds + info->user_time.seconds);
+  thread_cpu_micros *= kMicrosecondsPerSecond;
+  thread_cpu_micros += info->user_time.microseconds;
+  thread_cpu_micros += info->system_time.microseconds;
+  return thread_cpu_micros;
+}
+
+
 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
   const int kMinimumAlignment = 16;
   ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index e0b41ac..1bd2193 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -173,7 +173,6 @@
   static intptr_t ThreadIdToIntPtr(ThreadId id);
   static ThreadId ThreadIdFromIntPtr(intptr_t id);
   static bool Compare(ThreadId a, ThreadId b);
-  static void GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage);
 
   // Called at VM startup and shutdown.
   static void InitOnce();
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index 9b93cbe..b184f61 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -3,6 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "platform/globals.h"  // NOLINT
+
+
 #if defined(TARGET_OS_ANDROID)
 
 #include "vm/os_thread.h"
@@ -11,6 +13,7 @@
 #include <sys/time.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "platform/signal_blocker.h"
 #include "platform/utils.h"
 
 namespace dart {
@@ -83,6 +86,21 @@
 };
 
 
+// Spawned threads inherit their spawner's signal mask. We sometimes spawn
+// threads for running Dart code from a thread that is blocking SIGPROF.
+// This function explicitly unblocks SIGPROF so the profiler continues to
+// sample this thread.
+static void UnblockSIGPROF() {
+  sigset_t set;
+  sigemptyset(&set);
+  sigaddset(&set, SIGPROF);
+  int r = pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+  USE(r);
+  ASSERT(r == 0);
+  ASSERT(!CHECK_IS_BLOCKING(SIGPROF));
+}
+
+
 // Dispatch to the thread start function provided by the caller. This trampoline
 // is used to ensure that the thread is properly destroyed if the thread just
 // exits.
@@ -99,7 +117,7 @@
   if (thread != NULL) {
     OSThread::SetCurrent(thread);
     thread->set_name(name);
-
+    UnblockSIGPROF();
     // Call the supplied thread start function handing it its parameters.
     function(parameter);
   }
@@ -202,17 +220,6 @@
 }
 
 
-void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  ASSERT(thread_id == GetCurrentThreadId());
-  ASSERT(cpu_usage != NULL);
-  struct timespec ts;
-  int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
-  ASSERT(r == 0);
-  *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) /
-               kNanosecondsPerMicrosecond;
-}
-
-
 Mutex::Mutex() {
   pthread_mutexattr_t attr;
   int result = pthread_mutexattr_init(&attr);
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index a0e68f1..bd9bfaf 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "platform/globals.h"  // NOLINT
+
 #if defined(TARGET_OS_LINUX)
 
 #include "vm/os_thread.h"
@@ -13,6 +14,7 @@
 #include <sys/time.h>  // NOLINT
 
 #include "platform/assert.h"
+#include "platform/signal_blocker.h"
 #include "platform/utils.h"
 
 namespace dart {
@@ -85,6 +87,21 @@
 };
 
 
+// Spawned threads inherit their spawner's signal mask. We sometimes spawn
+// threads for running Dart code from a thread that is blocking SIGPROF.
+// This function explicitly unblocks SIGPROF so the profiler continues to
+// sample this thread.
+static void UnblockSIGPROF() {
+  sigset_t set;
+  sigemptyset(&set);
+  sigaddset(&set, SIGPROF);
+  int r = pthread_sigmask(SIG_UNBLOCK, &set, NULL);
+  USE(r);
+  ASSERT(r == 0);
+  ASSERT(!CHECK_IS_BLOCKING(SIGPROF));
+}
+
+
 // Dispatch to the thread start function provided by the caller. This trampoline
 // is used to ensure that the thread is properly destroyed if the thread just
 // exits.
@@ -101,7 +118,7 @@
   if (thread != NULL) {
     OSThread::SetCurrent(thread);
     thread->set_name(name);
-
+    UnblockSIGPROF();
     // Call the supplied thread start function handing it its parameters.
     function(parameter);
   }
@@ -204,17 +221,6 @@
 }
 
 
-void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  ASSERT(thread_id == GetCurrentThreadId());
-  ASSERT(cpu_usage != NULL);
-  struct timespec ts;
-  int r = clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts);
-  ASSERT(r == 0);
-  *cpu_usage = (ts.tv_sec * kNanosecondsPerSecond + ts.tv_nsec) /
-               kNanosecondsPerMicrosecond;
-}
-
-
 Mutex::Mutex() {
   pthread_mutexattr_t attr;
   int result = pthread_mutexattr_init(&attr);
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index 42dd360..4c7d094 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -195,30 +195,6 @@
 }
 
 
-void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  ASSERT(thread_id == GetCurrentThreadId());
-  ASSERT(cpu_usage != NULL);
-  // TODO(johnmccutchan): Enable this after fixing issue with macos directory
-  // watcher.
-  const bool get_cpu_usage = false;
-  if (get_cpu_usage) {
-    mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
-    thread_basic_info_data_t info_data;
-    thread_basic_info_t info = &info_data;
-    mach_port_t thread_port = mach_thread_self();
-    kern_return_t r = thread_info(thread_port, THREAD_BASIC_INFO,
-                                  (thread_info_t)info, &count);
-    mach_port_deallocate(mach_task_self(), thread_port);
-    if (r == KERN_SUCCESS) {
-      *cpu_usage = (info->user_time.seconds * kMicrosecondsPerSecond) +
-                   info->user_time.microseconds;
-      return;
-    }
-  }
-  *cpu_usage = 0;
-}
-
-
 Mutex::Mutex() {
   pthread_mutexattr_t attr;
   int result = pthread_mutexattr_init(&attr);
diff --git a/runtime/vm/os_thread_win.cc b/runtime/vm/os_thread_win.cc
index 9d282bc..e4083dc 100644
--- a/runtime/vm/os_thread_win.cc
+++ b/runtime/vm/os_thread_win.cc
@@ -173,38 +173,6 @@
 }
 
 
-void OSThread::GetThreadCpuUsage(ThreadId thread_id, int64_t* cpu_usage) {
-  static const int64_t kTimeEpoc = 116444736000000000LL;
-  static const int64_t kTimeScaler = 10;  // 100 ns to us.
-  // Although win32 uses 64-bit integers for representing timestamps,
-  // these are packed into a FILETIME structure. The FILETIME
-  // structure is just a struct representing a 64-bit integer. The
-  // TimeStamp union allows access to both a FILETIME and an integer
-  // representation of the timestamp. The Windows timestamp is in
-  // 100-nanosecond intervals since January 1, 1601.
-  union TimeStamp {
-    FILETIME ft_;
-    int64_t t_;
-  };
-  ASSERT(cpu_usage != NULL);
-  TimeStamp created;
-  TimeStamp exited;
-  TimeStamp kernel;
-  TimeStamp user;
-  HANDLE handle = OpenThread(THREAD_QUERY_INFORMATION, false, thread_id);
-  BOOL result = GetThreadTimes(handle,
-                               &created.ft_,
-                               &exited.ft_,
-                               &kernel.ft_,
-                               &user.ft_);
-  CloseHandle(handle);
-  if (!result) {
-    FATAL1("GetThreadCpuUsage failed %d\n", GetLastError());
-  }
-  *cpu_usage = (user.t_ - kTimeEpoc) / kTimeScaler;
-}
-
-
 void OSThread::SetThreadLocal(ThreadLocalKey key, uword value) {
   ASSERT(key != kUnsetThreadLocalKey);
   BOOL result = TlsSetValue(key, reinterpret_cast<void*>(value));
diff --git a/runtime/vm/os_win.cc b/runtime/vm/os_win.cc
index 2548a4c..bb2d634 100644
--- a/runtime/vm/os_win.cc
+++ b/runtime/vm/os_win.cc
@@ -160,6 +160,12 @@
 }
 
 
+int64_t OS::GetCurrentThreadCPUMicros() {
+  // TODO(johnmccutchan): Implement. See base/time_win.cc for details.
+  return -1;
+}
+
+
 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) {
   const int kMinimumAlignment = 16;
   ASSERT(Utils::IsPowerOfTwo(alignment));
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 05e01fb..64b1d5e 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -211,7 +211,7 @@
   } else {
     // Should not allocate executable pages when running from a precompiled
     // snapshot.
-    ASSERT(!Dart::IsRunningPrecompiledCode());
+    ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT);
 
     if (exec_pages_ == NULL) {
       exec_pages_ = page;
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 80c6021..0ace98b 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -364,10 +364,11 @@
 Parser::Parser(const Script& script,
                const Library& library,
                TokenPosition token_pos)
-    : isolate_(Thread::Current()->isolate()),
-      thread_(Thread::Current()),
+    : thread_(Thread::Current()),
+      isolate_(thread()->isolate()),
       script_(Script::Handle(zone(), script.raw())),
-      tokens_iterator_(TokenStream::Handle(zone(), script.tokens()),
+      tokens_iterator_(zone(),
+                       TokenStream::Handle(zone(), script.tokens()),
                        token_pos),
       token_kind_(Token::kILLEGAL),
       current_block_(NULL),
@@ -395,10 +396,11 @@
 Parser::Parser(const Script& script,
                ParsedFunction* parsed_function,
                TokenPosition token_pos)
-    : isolate_(Thread::Current()->isolate()),
-      thread_(Thread::Current()),
+    : thread_(Thread::Current()),
+      isolate_(thread()->isolate()),
       script_(Script::Handle(zone(), script.raw())),
-      tokens_iterator_(TokenStream::Handle(zone(), script.tokens()),
+      tokens_iterator_(zone(),
+                       TokenStream::Handle(zone(), script.tokens()),
                        token_pos),
       token_kind_(Token::kILLEGAL),
       current_block_(NULL),
@@ -1254,12 +1256,11 @@
                     field.token_pos()));
   initializer.set_result_type(AbstractType::Handle(zone, field.type()));
   // Static initializer functions are hidden from the user.
-  // Since they are only executed once, we avoid optimizing
-  // and inlining them. After the field is initialized, the
-  // compiler can eliminate the call to the static initializer.
+  // Since they are only executed once, we avoid inlining them.
+  // After the field is initialized, the compiler can eliminate
+  // the call to the static initializer.
   initializer.set_is_reflectable(false);
   initializer.set_is_debuggable(false);
-  initializer.SetIsOptimizable(false);
   initializer.set_is_inlinable(false);
 
   ParsedFunction* parsed_function = new ParsedFunction(thread, initializer);
@@ -2749,8 +2750,8 @@
       // no existing names.
       nsm_args->Add(new(Z) LiteralNode(init_pos, Object::null_array()));
 
-      AstNode* nsm_call =
-          MakeStaticCall(Symbols::NoSuchMethodError(),
+      AstNode* nsm_call = MakeStaticCall(
+          Symbols::NoSuchMethodError(),
           Library::PrivateCoreLibName(Symbols::ThrowNew()),
           nsm_args);
 
@@ -3297,7 +3298,9 @@
 
     // The number of parameters and their type are not yet set in local
     // functions, since they are not 'top-level' parsed.
-    if (func.IsLocalFunction()) {
+    // However, they are already set when the local function is compiled, since
+    // the local function was parsed when its parent was compiled.
+    if (func.parameter_types() == Object::empty_array().raw()) {
       AddFormalParamsToFunction(&params, func);
     }
     SetupDefaultsForOptionalParams(params);
@@ -5920,10 +5923,10 @@
       CallLibraryTagHandler(Dart_kCanonicalizeUrl, import_pos, url));
 
   // Create a new library if it does not exist yet.
-  Library& library = Library::Handle(Z, Library::LookupLibrary(canon_url));
+  Library& library = Library::Handle(Z, Library::LookupLibrary(T, canon_url));
   if (library.IsNull()) {
     library = Library::New(canon_url);
-    library.Register();
+    library.Register(T);
   }
 
   // If loading hasn't been requested yet, and if this is not a deferred
@@ -7287,6 +7290,8 @@
                                 params->has_optional_positional_parameters);
   const int num_parameters = params->parameters->length();
   ASSERT(num_parameters == func.NumParameters());
+  ASSERT(func.parameter_types() == Object::empty_array().raw());
+  ASSERT(func.parameter_names() == Object::empty_array().raw());
   func.set_parameter_types(Array::Handle(Array::New(num_parameters,
                                                     Heap::kOld)));
   func.set_parameter_names(Array::Handle(Array::New(num_parameters,
@@ -10022,6 +10027,56 @@
         ReportError(expr_pos, "generator functions may not return a value");
       }
       AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
+      if (I->type_checks() &&
+          current_function().IsAsyncClosure() &&
+          (current_block_->scope->function_level() == 0)) {
+        // In checked mode, when the declared result type is Future<T>, verify
+        // that the returned expression is of type T or Future<T> as follows:
+        // return temp = expr, temp is Future ? temp as Future<T> : temp as T;
+        // In case of a mismatch, we need a TypeError and not a CastError, so
+        // we do not actually implement an "as" test, but an "assignable" test.
+        const Function& async_func =
+            Function::Handle(Z, current_function().parent_function());
+        const AbstractType& result_type =
+            AbstractType::ZoneHandle(Z, async_func.result_type());
+        const Class& future_class =
+            Class::ZoneHandle(Z, I->object_store()->future_class());
+        ASSERT(!future_class.IsNull());
+        if (result_type.type_class() == future_class.raw()) {
+          const TypeArguments& result_type_args =
+              TypeArguments::ZoneHandle(Z, result_type.arguments());
+          if (!result_type_args.IsNull() && (result_type_args.Length() == 1)) {
+            const AbstractType& result_type_arg =
+                AbstractType::ZoneHandle(Z, result_type_args.TypeAt(0));
+            LetNode* checked_expr = new(Z) LetNode(expr_pos);
+            LocalVariable* temp = checked_expr->AddInitializer(expr);
+            temp->set_is_final();
+            const AbstractType& future_type =
+                AbstractType::ZoneHandle(Z, future_class.RareType());
+            AstNode* is_future = new(Z) LoadLocalNode(expr_pos, temp);
+            is_future = new(Z) ComparisonNode(expr_pos,
+                                              Token::kIS,
+                                              is_future,
+                                              new(Z) TypeNode(expr_pos,
+                                                              future_type));
+            AstNode* as_future_t = new(Z) LoadLocalNode(expr_pos, temp);
+            as_future_t = new(Z) AssignableNode(expr_pos,
+                                                as_future_t,
+                                                result_type,
+                                                Symbols::FunctionResult());
+            AstNode* as_t = new(Z) LoadLocalNode(expr_pos, temp);
+            as_t = new(Z) AssignableNode(expr_pos,
+                                         as_t,
+                                         result_type_arg,
+                                         Symbols::FunctionResult());
+            checked_expr->AddNode(new(Z) ConditionalExprNode(expr_pos,
+                                                             is_future,
+                                                             as_future_t,
+                                                             as_t));
+            expr = checked_expr;
+          }
+        }
+      }
       statement = new(Z) ReturnNode(statement_pos, expr);
     } else {
       if (current_function().IsSyncGenClosure() &&
@@ -11994,7 +12049,7 @@
     return HashValue(String::HashRawSymbol(key.script_url.raw()),
                      key.token_pos.value());
   }
-  // Used by CachConstantValue if a new constant is added to the map.
+  // Used by CacheConstantValue if a new constant is added to the map.
   static RawObject* NewKey(const ConstantPosKey& key) {
     const Array& key_obj = Array::Handle(Array::New(2));
     key_obj.SetAt(0, key.script_url);
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index dcd03a6..eb9f54a 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -850,8 +850,8 @@
   Isolate* isolate() const { return isolate_; }
   Zone* zone() const { return thread_->zone(); }
 
+  Thread* thread_;  // Cached current thread.
   Isolate* isolate_;  // Cached current isolate.
-  Thread* thread_;
 
   Script& script_;
   TokenStream::Iterator tokens_iterator_;
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 0bb6669..924d8a1 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -54,6 +54,7 @@
 DEFINE_FLAG(bool, trace_precompiler, false, "Trace precompiler.");
 DEFINE_FLAG(int, max_speculative_inlining_attempts, 1,
     "Max number of attempts with speculative inlining (precompilation only)");
+DEFINE_FLAG(int, precompiler_rounds, 1, "Number of precompiler iterations");
 
 DECLARE_FLAG(bool, allocation_sinking);
 DECLARE_FLAG(bool, common_subexpression_elimination);
@@ -168,8 +169,7 @@
     // because their class hasn't been finalized yet.
     FinalizeAllClasses();
 
-    const intptr_t kPrecompilerRounds = 1;
-    for (intptr_t round = 0; round < kPrecompilerRounds; round++) {
+    for (intptr_t round = 0; round < FLAG_precompiler_rounds; round++) {
       if (FLAG_trace_precompiler) {
         THR_Print("Precompiler round %" Pd "\n", round);
       }
@@ -229,16 +229,24 @@
     zone_ = NULL;
   }
 
-  intptr_t dropped_symbols_count = Symbols::Compact(I);
+  intptr_t symbols_before = -1;
+  intptr_t symbols_after = -1;
+  intptr_t capacity = -1;
+  if (FLAG_trace_precompiler) {
+    Symbols::GetStats(I, &symbols_before, &capacity);
+  }
+
+  Symbols::Compact(I);
 
   if (FLAG_trace_precompiler) {
+    Symbols::GetStats(I, &symbols_after, &capacity);
     THR_Print("Precompiled %" Pd " functions,", function_count_);
     THR_Print(" %" Pd " dynamic types,", class_count_);
     THR_Print(" %" Pd " dynamic selectors.\n", selector_count_);
 
     THR_Print("Dropped %" Pd " functions,", dropped_function_count_);
     THR_Print(" %" Pd " fields,", dropped_field_count_);
-    THR_Print(" %" Pd " symbols,", dropped_symbols_count);
+    THR_Print(" %" Pd " symbols,", symbols_before - symbols_after);
     THR_Print(" %" Pd " types,", dropped_type_count_);
     THR_Print(" %" Pd " type arguments,", dropped_typearg_count_);
     THR_Print(" %" Pd " classes,", dropped_class_count_);
@@ -354,7 +362,7 @@
     class_name = Symbols::New(thread(), entry_points[i].class_name);
     function_name = Symbols::New(thread(), entry_points[i].function_name);
 
-    lib = Library::LookupLibrary(library_uri);
+    lib = Library::LookupLibrary(T, library_uri);
     if (lib.IsNull()) {
       String& msg = String::Handle(Z, String::NewFormatted(
           "Cannot find entry point %s\n", entry_points[i].library_uri));
@@ -760,22 +768,18 @@
       const bool is_initialized = value.raw() != Object::sentinel().raw();
       if (is_initialized && !reset_fields_) return;
 
-      if (!field.HasPrecompiledInitializer()) {
+      if (!field.HasPrecompiledInitializer() ||
+          !Function::Handle(Z, field.PrecompiledInitializer()).HasCode()) {
         if (FLAG_trace_precompiler) {
           THR_Print("Precompiling initializer for %s\n", field.ToCString());
         }
-        ASSERT(!Dart::IsRunningPrecompiledCode());
-        field.SetStaticValue(Instance::Handle(field.SavedInitialStaticValue()));
+        ASSERT(Dart::snapshot_kind() != Snapshot::kAppNoJIT);
         const Function& initializer =
-            Function::Handle(CompileStaticInitializer(field));
-        if (!initializer.IsNull()) {
-          field.SetPrecompiledInitializer(initializer);
-        }
+            Function::Handle(Z, CompileStaticInitializer(field));
+        ASSERT(!initializer.IsNull());
+        field.SetPrecompiledInitializer(initializer);
+        AddCalleesOf(initializer);
       }
-
-      const Function& function =
-          Function::Handle(Z, field.PrecompiledInitializer());
-      AddCalleesOf(function);
     }
   }
 }
@@ -783,23 +787,24 @@
 
 RawFunction* Precompiler::CompileStaticInitializer(const Field& field) {
   ASSERT(field.is_static());
-  if (field.HasPrecompiledInitializer()) {
-    // TODO(rmacnak): Investigate why this happens for _enum_names.
-    THR_Print("Warning: Ignoring repeated request for initializer for %s\n",
-              field.ToCString());
-    return Function::null();
-  }
+  ASSERT(!field.HasPrecompiledInitializer());
   Thread* thread = Thread::Current();
   StackZone zone(thread);
 
   ParsedFunction* parsed_function = Parser::ParseStaticFieldInitializer(field);
 
   parsed_function->AllocateVariables();
-  // Non-optimized code generator.
   DartCompilationPipeline pipeline;
   PrecompileParsedFunctionHelper helper(parsed_function,
-                                        /* optimized = */ false);
-  helper.Compile(&pipeline);
+                                        /* optimized = */ true);
+  bool success = helper.Compile(&pipeline);
+  ASSERT(success);
+
+  if ((FLAG_disassemble || FLAG_disassemble_optimized) &&
+      FlowGraphPrinter::ShouldPrint(parsed_function->function())) {
+    Disassembler::DisassembleCode(parsed_function->function(),
+                                  /* optimized = */ true);
+  }
   return parsed_function->function().raw();
 }
 
@@ -818,8 +823,6 @@
     Function& initializer = Function::Handle();
     if (!field.HasPrecompiledInitializer()) {
       initializer = CompileStaticInitializer(field);
-      Code::Handle(initializer.unoptimized_code()).set_var_descriptors(
-          Object::empty_var_descriptors());
     } else {
       initializer ^= field.PrecompiledInitializer();
     }
@@ -1638,7 +1641,8 @@
 void Precompiler::DropLibraries() {
   const GrowableObjectArray& retained_libraries =
       GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
-  Library& root_lib = Library::Handle(Z, I->object_store()->root_library());
+  const Library& root_lib = Library::Handle(Z,
+      I->object_store()->root_library());
   Library& lib = Library::Handle(Z);
 
   for (intptr_t i = 0; i < libraries_.Length(); i++) {
@@ -1668,7 +1672,7 @@
     }
   }
 
-  I->object_store()->set_libraries(retained_libraries);
+  Library::RegisterLibraries(T, retained_libraries);
   libraries_ = retained_libraries.raw();
 }
 
@@ -1959,6 +1963,8 @@
   Library& lib = Library::Handle(Z);
   Class& cls = Class::Handle(Z);
   Array& functions = Array::Handle(Z);
+  Array& fields = Array::Handle(Z);
+  Field& field = Field::Handle(Z);
   Object& object = Object::Handle(Z);
   Function& function = Function::Handle(Z);
   GrowableObjectArray& closures = GrowableObjectArray::Handle(Z);
@@ -1990,6 +1996,14 @@
           visitor->VisitFunction(function);
         }
       }
+      fields = cls.fields();
+      for (intptr_t j = 0; j < fields.Length(); j++) {
+        field ^= fields.At(j);
+        if (field.is_static() && field.HasPrecompiledInitializer()) {
+          function ^= field.PrecompiledInitializer();
+          visitor->VisitFunction(function);
+        }
+      }
     }
   }
   closures = isolate()->object_store()->closure_functions();
@@ -2130,6 +2144,8 @@
   ASSERT(FLAG_precompiled_mode);
   const Function& function = parsed_function()->function();
   if (optimized() && !function.IsOptimizable()) {
+    // All functions compiled by precompiler must be optimizable.
+    UNREACHABLE();
     return false;
   }
   bool is_compiled = false;
@@ -2705,7 +2721,7 @@
 
     per_compile_timer.Stop();
 
-    if (trace_compiler && success) {
+    if (trace_compiler) {
       THR_Print("--> '%s' entry: %#" Px " size: %" Pd " time: %" Pd64 " us\n",
                 function.ToFullyQualifiedCString(),
                 Code::Handle(function.CurrentCode()).EntryPoint(),
@@ -2718,10 +2734,7 @@
     } else if (FLAG_disassemble_optimized &&
                optimized &&
                FlowGraphPrinter::ShouldPrint(function)) {
-      // TODO(fschneider): Print unoptimized code along with the optimized code.
-      THR_Print("*** BEGIN CODE\n");
       Disassembler::DisassembleCode(function, true);
-      THR_Print("*** END CODE\n");
     }
     return Error::null();
   } else {
diff --git a/runtime/vm/profiler_service.cc b/runtime/vm/profiler_service.cc
index c0ac69d..4d5c4a5 100644
--- a/runtime/vm/profiler_service.cc
+++ b/runtime/vm/profiler_service.cc
@@ -2544,12 +2544,13 @@
     // No function.
     return NULL;
   }
-  const Script& script = Script::Handle(function.script());
+  Zone* zone = Thread::Current()->zone();
+  const Script& script = Script::Handle(zone, function.script());
   if (script.IsNull()) {
     // No script.
     return NULL;
   }
-  const TokenStream& token_stream = TokenStream::Handle(script.tokens());
+  const TokenStream& token_stream = TokenStream::Handle(zone, script.tokens());
   if (token_stream.IsNull()) {
     // No token position.
     return NULL;
@@ -2567,8 +2568,8 @@
   if (token_pos.IsSynthetic()) {
     token_pos = token_pos.FromSynthetic();
   }
-  TokenStream::Iterator iterator(token_stream, token_pos);
-  const String& str = String::Handle(iterator.CurrentLiteral());
+  TokenStream::Iterator iterator(zone, token_stream, token_pos);
+  const String& str = String::Handle(zone, iterator.CurrentLiteral());
   if (str.IsNull()) {
     return NULL;
   }
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 12d5234..977ba55 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -432,38 +432,32 @@
     return TryAcquireTagBit<RememberedBit>();
   }
 
-  bool IsDartInstance() {
-    return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
+#define DEFINE_IS_CID(clazz)                                                   \
+  bool Is##clazz() const { return ((GetClassId() == k##clazz##Cid)); }
+CLASS_LIST(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+#define DEFINE_IS_CID(clazz)                                                   \
+  bool IsTypedData##clazz() const {                                            \
+    return ((GetClassId() == kTypedData##clazz##Cid));                         \
+  }                                                                            \
+  bool IsTypedDataView##clazz() const {                                        \
+    return ((GetClassId() == kTypedData##clazz##ViewCid));                     \
+  }                                                                            \
+  bool IsExternalTypedData##clazz() const {                                    \
+    return ((GetClassId() == kExternalTypedData##clazz##Cid));                 \
   }
-  bool IsFreeListElement() {
-    return ((GetClassId() == kFreeListElement));
-  }
-  bool IsScript() {
-    return ((GetClassId() == kScriptCid));
-  }
-  bool IsField() {
-    return ((GetClassId() == kFieldCid));
-  }
-  bool IsFunction() {
-    return ((GetClassId() == kFunctionCid));
-  }
-  bool IsInstructions() {
-    return ((GetClassId() == kInstructionsCid));
-  }
-  bool IsCode() {
-    return ((GetClassId() == kCodeCid));
-  }
-  bool IsString() {
+CLASS_LIST_TYPED_DATA(DEFINE_IS_CID)
+#undef DEFINE_IS_CID
+
+  bool IsStringInstance() const {
     return IsStringClassId(GetClassId());
   }
-  bool IsStackmap() {
-    return ((GetClassId() == kStackmapCid));
+  bool IsDartInstance() const {
+    return (!IsHeapObject() || (GetClassId() >= kInstanceCid));
   }
-  bool IsPcDescriptors() {
-    return ((GetClassId() == kPcDescriptorsCid));
-  }
-  bool IsOneByteString() {
-    return ((GetClassId() == kOneByteStringCid));
+  bool IsFreeListElement() const {
+    return ((GetClassId() == kFreeListElement));
   }
 
   intptr_t Size() const {
@@ -721,6 +715,8 @@
       case Snapshot::kAppNoJIT:
         return reinterpret_cast<RawObject**>(&ptr()->direct_subclasses_);
       case Snapshot::kMessage:
+      case Snapshot::kNone:
+      case Snapshot::kInvalid:
         break;
     }
     UNREACHABLE();
@@ -949,6 +945,8 @@
       case Snapshot::kAppNoJIT:
         return reinterpret_cast<RawObject**>(&ptr()->initializer_);
       case Snapshot::kMessage:
+      case Snapshot::kNone:
+      case Snapshot::kInvalid:
         break;
     }
     UNREACHABLE();
@@ -1029,6 +1027,8 @@
       case Snapshot::kScript:
         return reinterpret_cast<RawObject**>(&ptr()->tokens_);
       case Snapshot::kMessage:
+      case Snapshot::kNone:
+      case Snapshot::kInvalid:
         break;
     }
     UNREACHABLE();
@@ -1515,6 +1515,8 @@
       case Snapshot::kAppWithJIT:
         return to();
       case Snapshot::kMessage:
+      case Snapshot::kNone:
+      case Snapshot::kInvalid:
         break;
     }
     UNREACHABLE();
@@ -1646,6 +1648,8 @@
       case Snapshot::kAppNoJIT:
         return reinterpret_cast<RawObject**>(&ptr()->importer_);
       case Snapshot::kMessage:
+      case Snapshot::kNone:
+      case Snapshot::kInvalid:
         break;
     }
     UNREACHABLE();
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index eec2523..196e145 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -644,13 +644,12 @@
   // Context scope.
   if (ptr()->context_scope_ == Object::empty_context_scope().raw()) {
     writer->WriteVMIsolateObject(kEmptyContextScopeObject);
+  } else if (ptr()->context_scope_->ptr()->is_implicit_ ||
+             (kind == Snapshot::kAppWithJIT)) {
+    writer->WriteObjectImpl(ptr()->context_scope_, kAsInlinedObject);
   } else {
-    if (ptr()->context_scope_->ptr()->is_implicit_) {
-      writer->WriteObjectImpl(ptr()->context_scope_, kAsInlinedObject);
-    } else {
-      // We don't write non implicit context scopes in the snapshot.
-      writer->WriteVMIsolateObject(kNullObject);
-    }
+    // We don't write non implicit context scopes in the snapshot.
+    writer->WriteVMIsolateObject(kNullObject);
   }
 
   // Parent function.
@@ -730,7 +729,7 @@
     func.set_kind_tag(reader->Read<uint32_t>());
     func.set_token_pos(TokenPosition::SnapshotDecode(token_pos));
     func.set_end_token_pos(TokenPosition::SnapshotDecode(end_token_pos));
-    if (Snapshot::IncludesCode(kind)) {
+    if (kind == Snapshot::kAppNoJIT) {
       func.set_usage_counter(0);
       func.set_deoptimization_counter(0);
       func.set_optimized_instruction_count(0);
@@ -748,12 +747,23 @@
                        func.raw()->from(), func.raw()->to_snapshot(),
                        kAsReference);
     // Initialize all fields that are not part of the snapshot.
-    if (Snapshot::IncludesCode(kind)) {
+    if (kind == Snapshot::kAppNoJIT) {
+      // Read the code object and fixup entry point.
       func.ClearICDataArray();
       func.ClearCode();
-      // Read the code object and fixup entry point.
       (*reader->CodeHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
       func.SetInstructions(*reader->CodeHandle());
+    } else if (kind == Snapshot::kAppWithJIT) {
+      (*reader->ArrayHandle()) ^= reader->ReadObjectImpl(kAsReference);
+      func.set_ic_data_array(*reader->ArrayHandle());
+      (*reader->CodeHandle()) ^= reader->ReadObjectImpl(kAsInlinedObject);
+      func.set_unoptimized_code(*reader->CodeHandle());
+      if (!reader->CodeHandle()->IsNull()) {
+        func.SetInstructions(*reader->CodeHandle());
+        func.set_was_compiled(true);
+      } else {
+        func.ClearCode();
+      }
     } else {
       bool is_optimized = func.usage_counter() != 0;
       if (is_optimized) {
@@ -784,7 +794,7 @@
     intptr_t tags = writer->GetObjectTags(ptr()->owner_);
     intptr_t cid = ClassIdTag::decode(tags);
     owner_is_class = (cid == kClassCid);
-    is_in_fullsnapshot =  owner_is_class ?
+    is_in_fullsnapshot = owner_is_class ?
         Class::IsInFullSnapshot(reinterpret_cast<RawClass*>(ptr()->owner_)) :
         PatchClass::IsInFullSnapshot(
             reinterpret_cast<RawPatchClass*>(ptr()->owner_));
@@ -811,7 +821,7 @@
     writer->Write<int16_t>(ptr()->num_fixed_parameters_);
     writer->Write<int16_t>(ptr()->num_optional_parameters_);
     writer->Write<uint32_t>(ptr()->kind_tag_);
-    if (Snapshot::IncludesCode(kind)) {
+    if (kind == Snapshot::kAppNoJIT) {
       // Omit fields used to support de/reoptimization.
     } else {
       if (is_optimized) {
@@ -827,15 +837,16 @@
     // Write out all the object pointer fields.
     SnapshotWriterVisitor visitor(writer, kAsReference);
     visitor.VisitPointers(from(), to_snapshot());
-    if (Snapshot::IncludesCode(kind)) {
+    if (kind == Snapshot::kAppNoJIT) {
       ASSERT(ptr()->ic_data_array_ == Array::null());
       ASSERT((ptr()->code_ == ptr()->unoptimized_code_) ||
              (ptr()->unoptimized_code_ == Code::null()));
-      // Write out the code object as we are generating a precompiled snapshot.
       writer->WriteObjectImpl(ptr()->code_, kAsInlinedObject);
+    } else if (kind == Snapshot::kAppWithJIT) {
+      writer->WriteObjectImpl(ptr()->ic_data_array_, kAsReference);
+      writer->WriteObjectImpl(ptr()->unoptimized_code_, kAsInlinedObject);
     } else if (is_optimized) {
-      // Write out the ic data array as the function is optimized or
-      // we are generating a precompiled snapshot.
+      // Write out the ic data array as the function is optimized.
       writer->WriteObjectImpl(ptr()->ic_data_array_, kAsReference);
     }
   } else {
@@ -922,6 +933,9 @@
       // For precompiled static fields, the value was already reset and
       // initializer_ now contains a Function.
       writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
+    } else if (Field::ConstBit::decode(ptr()->kind_bits_)) {
+      // Do not reset const fields.
+      writer->WriteObjectImpl(ptr()->value_.static_value_, kAsReference);
     } else {
       // Otherwise, for static fields we write out the initial static value.
       writer->WriteObjectImpl(ptr()->initializer_.saved_value_, kAsReference);
@@ -1132,7 +1146,7 @@
   if ((kind == Snapshot::kScript) && is_in_fullsnapshot) {
     // Lookup the object as it should already exist in the heap.
     *reader->StringHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
-    library = Library::LookupLibrary(*reader->StringHandle());
+    library = Library::LookupLibrary(reader->thread(), *reader->StringHandle());
     ASSERT(library.is_in_fullsnapshot());
   } else {
     // Allocate library object.
@@ -1174,7 +1188,7 @@
     if (!Snapshot::IsFull(kind)) {
       // The cache of resolved names in library scope is not serialized.
       library.InitResolvedNamesCache(kInitialNameCacheSize);
-      library.Register();
+      library.Register(reader->thread());
     } else {
       library.InitResolvedNamesCache(kInitialNameCacheSize, reader);
     }
@@ -1436,9 +1450,21 @@
   intptr_t pointer_offsets_length =
       Code::PtrOffBits::decode(ptr()->state_bits_);
   if (pointer_offsets_length != 0) {
-    // Should only be IA32.
     FATAL("Cannot serialize code with embedded pointers");
   }
+  if (kind == Snapshot::kAppNoJIT) {
+    // No disabled code in precompilation.
+    ASSERT(ptr()->instructions_ == ptr()->active_instructions_);
+  } else {
+    ASSERT(kind == Snapshot::kAppWithJIT);
+    // We never include optimized code in JIT precompilation. Deoptimization
+    // requires code patching and we cannot patch code that is shared between
+    // isolates and should not mutate memory allocated by the embedder.
+    bool is_optimized = Code::PtrOffBits::decode(ptr()->state_bits_);
+    if (is_optimized) {
+      FATAL("Cannot include optimized code in a JIT snapshot");
+    }
+  }
 
   // Write out the serialization header value for this object.
   writer->WriteInlinedObjectHeader(object_id);
@@ -1450,9 +1476,6 @@
   // Write out all the non object fields.
   writer->Write<int32_t>(ptr()->state_bits_);
 
-  // No disabled code in precompilation.
-  ASSERT(ptr()->instructions_ == ptr()->active_instructions_);
-
   RawInstructions* instr = ptr()->instructions_;
   int32_t text_offset = writer->GetInstructionsId(instr, this);
   writer->Write<int32_t>(text_offset);
@@ -1912,7 +1935,7 @@
   // Allocate context object.
   bool is_implicit = reader->Read<bool>();
   if (is_implicit) {
-    ContextScope& context_scope = ContextScope::ZoneHandle();
+    ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
     if (Snapshot::IsFull(kind)) {
       context_scope = reader->NewContextScope(1);
       context_scope.set_is_implicit(true);
@@ -1932,6 +1955,19 @@
     context_scope.SetContextIndexAt(0, 0);
     context_scope.SetContextLevelAt(0, 0);
     return context_scope.raw();
+  } else if (kind == Snapshot::kAppWithJIT) {
+    int32_t num_vars = reader->Read<int32_t>();
+
+    ContextScope& context_scope = ContextScope::ZoneHandle(reader->zone());
+    context_scope = reader->NewContextScope(num_vars);
+    context_scope.set_is_implicit(false);
+    reader->AddBackRef(object_id, &context_scope, kIsDeserialized);
+
+    READ_OBJECT_FIELDS(context_scope,
+                       context_scope.raw()->from(),
+                       context_scope.raw()->to(num_vars),
+                       kAsInlinedObject);
+    return context_scope.raw();
   }
   UNREACHABLE();
   return NULL;
@@ -1962,6 +1998,23 @@
     writer->WriteObjectImpl(var->type, kAsInlinedObject);
 
     return;
+  } else if (kind == Snapshot::kAppWithJIT) {
+    // Write out the serialization header value for this object.
+    writer->WriteInlinedObjectHeader(object_id);
+
+    // Write out the class and tags information.
+    writer->WriteVMIsolateObject(kContextScopeCid);
+    writer->WriteTags(writer->GetObjectTags(this));
+
+    // Write out is_implicit flag for the context scope.
+    writer->Write<bool>(false);
+    int32_t num_vars = ptr()->num_variables_;
+    writer->Write<int32_t>(num_vars);
+
+    SnapshotWriterVisitor visitor(writer, kAsInlinedObject);
+    visitor.VisitPointers(from(), to(num_vars));
+
+    return;
   }
   UNREACHABLE();
 }
diff --git a/runtime/vm/resolver_test.cc b/runtime/vm/resolver_test.cc
index 52aa4b6..2252e23 100644
--- a/runtime/vm/resolver_test.cc
+++ b/runtime/vm/resolver_test.cc
@@ -19,6 +19,9 @@
                           const char* test_class_name,
                           const char* test_static_function_name,
                           bool is_static) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+
   // Setup a dart class and function.
   char script_chars[1024];
   OS::SNPrint(script_chars,
@@ -35,16 +38,16 @@
               is_static ? "static" : "",
               test_static_function_name);
 
-  String& url = String::Handle(is_static ?
-                               String::New("dart-test:DartStaticResolve") :
-                               String::New("dart-test:DartDynamicResolve"));
-  String& source = String::Handle(String::New(script_chars));
-  Script& script = Script::Handle(Script::New(url,
-                                              source,
-                                              RawScript::kScriptTag));
-  const String& lib_name = String::Handle(String::New(test_library_name));
-  Library& lib = Library::Handle(Library::New(lib_name));
-  lib.Register();
+  String& url = String::Handle(zone,
+      is_static ?
+          String::New("dart-test:DartStaticResolve") :
+          String::New("dart-test:DartDynamicResolve"));
+  String& source = String::Handle(zone, String::New(script_chars));
+  Script& script = Script::Handle(zone,
+      Script::New(url, source, RawScript::kScriptTag));
+  const String& lib_name = String::Handle(zone, String::New(test_library_name));
+  Library& lib = Library::Handle(zone, Library::New(lib_name));
+  lib.Register(thread);
   EXPECT(CompilerTest::TestCompileScript(lib, script));
   EXPECT(ClassFinalizer::ProcessPendingClasses());
 }
@@ -87,7 +90,7 @@
 
   const String& library_name = String::Handle(String::New(test_library_name));
   const Library& library =
-      Library::Handle(Library::LookupLibrary(library_name));
+      Library::Handle(Library::LookupLibrary(thread, library_name));
   const String& class_name = String::Handle(String::New(test_class_name));
   const String& static_function_name =
       String::Handle(String::New(test_static_function_name));
@@ -155,7 +158,8 @@
   // Now create an instance object of the class and try to
   // resolve a function in it.
   const String& lib_name = String::Handle(String::New(test_library_name));
-  const Library& lib = Library::Handle(Library::LookupLibrary(lib_name));
+  const Library& lib = Library::Handle(Library::LookupLibrary(thread,
+                                                              lib_name));
   ASSERT(!lib.IsNull());
   const Class& cls = Class::Handle(lib.LookupClass(
       String::Handle(Symbols::New(thread, test_class_name))));
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index efed3c0..197c77f 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -3597,7 +3597,7 @@
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "Version");
   jsobj.AddProperty("major", static_cast<intptr_t>(3));
-  jsobj.AddProperty("minor", static_cast<intptr_t>(4));
+  jsobj.AddProperty("minor", static_cast<intptr_t>(5));
   jsobj.AddProperty("_privateMajor", static_cast<intptr_t>(0));
   jsobj.AddProperty("_privateMinor", static_cast<intptr_t>(0));
   return true;
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 47e77f4..e37643c 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.4
+# Dart VM Service Protocol 3.5
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.4_ of the Dart VM Service Protocol. This
+This document describes of _version 3.5_ of the Dart VM Service Protocol. This
 protocol is used to communicate with a running Dart Virtual Machine.
 
 To use the Service Protocol, start the VM with the *--observe* flag.
@@ -120,7 +120,7 @@
   "result": {
     "type": "Version",
     "major": 3,
-    "minor": 0
+    "minor": 5
   }
   "id": "1"
 }
@@ -311,7 +311,7 @@
   "result": {
     "type": "Version",
     "major": 3,
-    "minor": 0
+    "minor": 5
   }
 ```
 
@@ -2317,6 +2317,10 @@
   // Has this range been compiled by the Dart VM?
   bool compiled;
 
+  // The error while attempting to compile this range, if this
+  // report was generated with forceCompile=true.
+  @Error error [optional];
+
   // Code coverage information for this range.  Provided only when the
   // Coverage report has been requested and the range has been
   // compiled.
@@ -2519,4 +2523,5 @@
 3.2 | Isolate objects now include the runnable bit and many debugger related RPCs will return an error if executed on an isolate before it is runnable.
 3.3 | Pause event now indicates if the isolate is paused at an await, yield, or yield* suspension point via the 'atAsyncSuspension' field. Resume command now supports the step parameter 'OverAsyncSuspension'. A Breakpoint added synthetically by an 'OverAsyncSuspension' resume command identifies itself as such via the 'isSyntheticAsyncContinuation' field.
 3.4 | Add the superType and mixin fields to Class. Added new pause event 'None'.
+3.5 | Add the error field to SourceReportRange.
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index cb14557..fa8cd95 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -336,6 +336,7 @@
       OS::PrintErr("vm-service: Isolate creation error: %s\n", error);
       ServiceIsolate::SetServiceIsolate(NULL);
       ServiceIsolate::FinishedInitializing();
+      ServiceIsolate::FinishedExiting();
       return;
     }
 
@@ -501,8 +502,9 @@
 
 
 void ServiceIsolate::BootVmServiceLibrary() {
+  Thread* thread = Thread::Current();
   const Library& vmservice_library =
-      Library::Handle(Library::LookupLibrary(Symbols::DartVMService()));
+      Library::Handle(Library::LookupLibrary(thread, Symbols::DartVMService()));
   ASSERT(!vmservice_library.IsNull());
   const String& boot_function_name = String::Handle(String::New("boot"));
   const Function& boot_function =
diff --git a/runtime/vm/simulator_dbc.cc b/runtime/vm/simulator_dbc.cc
index d9ff04e..e732409 100644
--- a/runtime/vm/simulator_dbc.cc
+++ b/runtime/vm/simulator_dbc.cc
@@ -1129,6 +1129,7 @@
 
   {
     BYTECODE(DebugBreak, A);
+#if !defined(PRODUCT)
     {
       const uint32_t original_bc =
           static_cast<uint32_t>(reinterpret_cast<uintptr_t>(
@@ -1141,6 +1142,10 @@
       INVOKE_RUNTIME(DRT_BreakpointRuntimeHandler, args)
       DISPATCH_OP(original_bc);
     }
+#else
+    // There should be no debug breaks in product mode.
+    UNREACHABLE();
+#endif
     DISPATCH();
   }
 
diff --git a/runtime/vm/snapshot.cc b/runtime/vm/snapshot.cc
index 2f2ca6a..33570ae 100644
--- a/runtime/vm/snapshot.cc
+++ b/runtime/vm/snapshot.cc
@@ -253,7 +253,7 @@
   AddBackRef(object_id, &cls, kIsDeserialized);
   // Read the library/class information and lookup the class.
   str_ ^= ReadObjectImpl(class_header, kAsInlinedObject, kInvalidPatchIndex, 0);
-  library_ = Library::LookupLibrary(str_);
+  library_ = Library::LookupLibrary(thread(), str_);
   if (library_.IsNull() || !library_.Loaded()) {
     SetReadException("Invalid object found in message.");
   }
@@ -280,7 +280,7 @@
   AddBackRef(object_id, &func, kIsDeserialized);
   // Read the library/class/function information and lookup the function.
   str_ ^= ReadObjectImpl(func_header, kAsInlinedObject, kInvalidPatchIndex, 0);
-  library_ = Library::LookupLibrary(str_);
+  library_ = Library::LookupLibrary(thread(), str_);
   if (library_.IsNull() || !library_.Loaded()) {
     SetReadException("Expected a library name, but found an invalid name.");
   }
@@ -316,7 +316,7 @@
 
   // Read the library/class/function information and lookup the function.
   str_ ^= ReadObjectImpl(kAsInlinedObject);
-  library_ = Library::LookupLibrary(str_);
+  library_ = Library::LookupLibrary(thread(), str_);
   if (library_.IsNull() || !library_.Loaded()) {
     SetReadException("Invalid Library object found in message.");
   }
@@ -625,7 +625,7 @@
       }
     }
 
-    if (Snapshot::IncludesCode(kind_)) {
+    if (kind_ == Snapshot::kAppNoJIT) {
       ICData& ic = ICData::Handle(thread->zone());
       Object& funcOrCode = Object::Handle(thread->zone());
       Code& code = Code::Handle(thread->zone());
@@ -1562,8 +1562,8 @@
     }
   }
 
-  ASSERT(Symbols::IsVMSymbolId(object_id));
-  return Symbols::GetVMSymbol(object_id);  // return VM symbol.
+  ASSERT(Symbols::IsPredefinedSymbolId(object_id));
+  return Symbols::GetPredefinedSymbol(object_id);  // return VM symbol.
 }
 
 
@@ -1764,7 +1764,7 @@
                      new ZoneGrowableArray<BackRefNode>(
                          kNumInitialReferencesInFullSnapshot),
                      thread) {
-  isolate()->set_compilation_allowed(instructions_buffer_ == NULL);
+  isolate()->set_compilation_allowed(kind != Snapshot::kAppNoJIT);
   ASSERT(Snapshot::IsFull(kind));
 }
 
@@ -1818,7 +1818,7 @@
                                ForwardList* forward_list,
                                InstructionsWriter* instructions_writer,
                                bool can_send_any_object,
-                               bool vm_isolate_is_symbolic)
+                               bool writing_vm_isolate)
     : BaseWriter(buffer, alloc, initial_size),
       thread_(thread),
       kind_(kind),
@@ -1830,7 +1830,7 @@
       exception_msg_(NULL),
       unmarked_objects_(false),
       can_send_any_object_(can_send_any_object),
-      vm_isolate_is_symbolic_(vm_isolate_is_symbolic) {
+      writing_vm_isolate_(writing_vm_isolate) {
   ASSERT(forward_list_ != NULL);
 }
 
@@ -1922,9 +1922,15 @@
     }
   }
 
+  if (writing_vm_isolate_) {
+    // When we are writing the VM isolate snapshot, write out the object
+    // itself instead of a VM object id.
+    return false;
+  }
+
   if (Snapshot::IsFull(kind())) {
     // Check it is a predefined symbol in the VM isolate.
-    id = Symbols::LookupVMSymbol(rawobj);
+    id = Symbols::LookupPredefinedSymbol(rawobj);
     if (id != kInvalidIndex) {
       WriteVMIsolateObject(id);
       return true;
@@ -1960,10 +1966,6 @@
     }
   }
 
-  if (!vm_isolate_is_symbolic()) {
-    return false;
-  }
-
   const Object& obj = Object::Handle(rawobj);
   FATAL1("Unexpected reference to object in VM isolate: %s\n", obj.ToCString());
   return false;
@@ -2011,8 +2013,7 @@
                                        uint8_t** vm_isolate_snapshot_buffer,
                                        uint8_t** isolate_snapshot_buffer,
                                        ReAlloc alloc,
-                                       InstructionsWriter* instructions_writer,
-                                       bool vm_isolate_is_symbolic)
+                                       InstructionsWriter* instructions_writer)
     : thread_(Thread::Current()),
       kind_(kind),
       vm_isolate_snapshot_buffer_(vm_isolate_snapshot_buffer),
@@ -2023,8 +2024,8 @@
       forward_list_(NULL),
       instructions_writer_(instructions_writer),
       scripts_(Array::Handle(zone())),
-      symbol_table_(Array::Handle(zone())),
-      vm_isolate_is_symbolic_(vm_isolate_is_symbolic) {
+      saved_symbol_table_(Array::Handle(zone())),
+      new_vm_symbol_table_(Array::Handle(zone())) {
   ASSERT(isolate_snapshot_buffer_ != NULL);
   ASSERT(alloc_ != NULL);
   ASSERT(isolate() != NULL);
@@ -2033,31 +2034,49 @@
   ASSERT(heap() != NULL);
   ObjectStore* object_store = isolate()->object_store();
   ASSERT(object_store != NULL);
-  // Ensure the class table is valid.
+
 #if defined(DEBUG)
+  // Ensure the class table is valid.
   isolate()->ValidateClassTable();
 #endif
+  // Can't have any mutation happening while we're serializing.
+  ASSERT(isolate()->background_compiler() == NULL);
 
-  // Collect all the script objects and their accompanying token stream objects
-  // into an array so that we can write it out as part of the VM isolate
-  // snapshot. We first count the number of script objects, allocate an array
-  // and then fill it up with the script objects.
-  ScriptVisitor scripts_counter(thread());
-  heap()->IterateOldObjects(&scripts_counter);
-  intptr_t count = scripts_counter.count();
-  scripts_ = Array::New(count, Heap::kOld);
-  ScriptVisitor script_visitor(thread(), &scripts_);
-  heap()->IterateOldObjects(&script_visitor);
-
+  intptr_t first_object_id = -1;
   if (vm_isolate_snapshot_buffer != NULL) {
-    // Stash the symbol table away for writing and reading into the vm isolate,
-    // and reset the symbol table for the regular isolate so that we do not
-    // write these symbols into the snapshot of a regular dart isolate.
-    symbol_table_ = object_store->symbol_table();
+    // Collect all the script objects and their accompanying token stream
+    // objects into an array so that we can write it out as part of the VM
+    // isolate snapshot. We first count the number of script objects, allocate
+    // an array and then fill it up with the script objects.
+    ScriptVisitor scripts_counter(thread());
+    heap()->IterateOldObjects(&scripts_counter);
+    Dart::vm_isolate()->heap()->IterateOldObjects(&scripts_counter);
+    intptr_t count = scripts_counter.count();
+    scripts_ = Array::New(count, Heap::kOld);
+    ScriptVisitor script_visitor(thread(), &scripts_);
+    heap()->IterateOldObjects(&script_visitor);
+    Dart::vm_isolate()->heap()->IterateOldObjects(&script_visitor);
+    ASSERT(script_visitor.count() == count);
+
+    // Tuck away the current symbol table.
+    saved_symbol_table_ = object_store->symbol_table();
+
+    // Create a unified symbol table that will be written as the vm isolate's
+    // symbol table.
+    new_vm_symbol_table_ = Symbols::UnifiedSymbolTable();
+
+    // Create an empty symbol table that will be written as the isolate's symbol
+    // table.
     Symbols::SetupSymbolTable(isolate());
+
+    first_object_id = kMaxPredefinedObjectIds;
+  } else {
+    intptr_t max_vm_isolate_object_id =
+        Object::vm_isolate_snapshot_object_table().Length();
+    first_object_id = kMaxPredefinedObjectIds + max_vm_isolate_object_id;
   }
 
-  forward_list_ = new ForwardList(thread(), SnapshotWriter::FirstObjectId());
+  forward_list_ = new ForwardList(thread(), first_object_id);
   ASSERT(forward_list_ != NULL);
 }
 
@@ -2065,10 +2084,11 @@
 FullSnapshotWriter::~FullSnapshotWriter() {
   delete forward_list_;
   // We may run Dart code afterwards, restore the symbol table if needed.
-  if (!symbol_table_.IsNull()) {
-    isolate()->object_store()->set_symbol_table(symbol_table_);
-    symbol_table_ = Array::null();
+  if (!saved_symbol_table_.IsNull()) {
+    isolate()->object_store()->set_symbol_table(saved_symbol_table_);
+    saved_symbol_table_ = Array::null();
   }
+  new_vm_symbol_table_ = Array::null();
   scripts_ = Array::null();
 }
 
@@ -2083,7 +2103,7 @@
                         forward_list_,
                         instructions_writer_,
                         true, /* can_send_any_object */
-                        vm_isolate_is_symbolic_);
+                        true /* writing_vm_isolate */);
   // Write full snapshot for the VM isolate.
   // Setup for long jump in case there is an exception while writing
   // the snapshot.
@@ -2099,10 +2119,10 @@
      * Now Write out the following
      * - the symbol table
      * - all the scripts and token streams for these scripts
-     *
+     * - the stub code (precompiled snapshots only)
      **/
     // Write out the symbol table.
-    writer.WriteObject(symbol_table_.raw());
+    writer.WriteObject(new_vm_symbol_table_.raw());
 
     // Write out all the script objects and the accompanying token streams
     // for the bootstrap libraries so that they are in the VM isolate
@@ -2110,11 +2130,9 @@
     writer.WriteObject(scripts_.raw());
 
     if (Snapshot::IncludesCode(kind_)) {
-      ASSERT(!vm_isolate_is_symbolic_);
       StubCode::WriteTo(&writer);
     }
 
-
     writer.FillHeader(writer.kind());
 
     vm_isolate_snapshot_size_ = writer.BytesWritten();
@@ -2133,7 +2151,7 @@
                         forward_list_,
                         instructions_writer_,
                         true, /* can_send_any_object */
-                        true /* vm_isolate_is_symbolic */);
+                        false /* writing_vm_isolate */);
   ObjectStore* object_store = isolate()->object_store();
   ASSERT(object_store != NULL);
 
@@ -2188,28 +2206,12 @@
 }
 
 
-PrecompiledSnapshotWriter::PrecompiledSnapshotWriter(
-    uint8_t** vm_isolate_snapshot_buffer,
-    uint8_t** isolate_snapshot_buffer,
-    ReAlloc alloc,
-    InstructionsWriter* instructions_writer)
-  : FullSnapshotWriter(Snapshot::kAppNoJIT,
-                       vm_isolate_snapshot_buffer,
-                       isolate_snapshot_buffer,
-                       alloc,
-                       instructions_writer,
-                       false /* vm_isolate_is_symbolic */) {
-}
-
-
-PrecompiledSnapshotWriter::~PrecompiledSnapshotWriter() {}
-
-
 ForwardList::ForwardList(Thread* thread, intptr_t first_object_id)
     : thread_(thread),
       first_object_id_(first_object_id),
       nodes_(),
       first_unprocessed_object_id_(first_object_id) {
+  ASSERT(first_object_id > 0);
 }
 
 
@@ -2228,7 +2230,6 @@
   Node* node = new Node(&obj, state);
   ASSERT(node != NULL);
   nodes_.Add(node);
-  ASSERT(SnapshotWriter::FirstObjectId() > 0);
   ASSERT(object_id != 0);
   heap()->SetObjectId(raw, object_id);
   return object_id;
@@ -2237,7 +2238,6 @@
 
 intptr_t ForwardList::FindObject(RawObject* raw) {
   NoSafepointScope no_safepoint;
-  ASSERT(SnapshotWriter::FirstObjectId() > 0);
   intptr_t id = heap()->GetObjectId(raw);
   ASSERT(id == 0 || NodeForObjectId(id)->obj()->raw() == raw);
   return (id == 0) ? static_cast<intptr_t>(kInvalidIndex) : id;
@@ -2696,13 +2696,6 @@
 }
 
 
-intptr_t SnapshotWriter::FirstObjectId() {
-  intptr_t max_vm_isolate_object_id =
-      Object::vm_isolate_snapshot_object_table().Length();
-  return kMaxPredefinedObjectIds + max_vm_isolate_object_id;
-}
-
-
 ScriptSnapshotWriter::ScriptSnapshotWriter(uint8_t** buffer,
                                            ReAlloc alloc)
     : SnapshotWriter(Thread::Current(),
@@ -2713,7 +2706,7 @@
                      &forward_list_,
                      NULL, /* instructions_writer */
                      true, /* can_send_any_object */
-                     true /* vm_isolate_is_symbolic */),
+                     false /* writing_vm_isolate */),
       forward_list_(thread(), kMaxPredefinedObjectIds) {
   ASSERT(buffer != NULL);
   ASSERT(alloc != NULL);
@@ -2769,7 +2762,7 @@
                      &forward_list_,
                      NULL, /* instructions_writer */
                      can_send_any_object,
-                     true /* vm_isolate_is_symbolic */),
+                     false /* writing_vm_isolate */),
       forward_list_(thread(), kMaxPredefinedObjectIds) {
   ASSERT(buffer != NULL);
   ASSERT(alloc != NULL);
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index 3dc6aae..1c0fddb 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -152,6 +152,8 @@
  public:
   enum Kind {
     kCore = 0,    // Full snapshot of core libraries. No root library, no code.
+    kScript,      // A partial snapshot of only the application script.
+    kMessage,     // A partial snapshot used only for isolate messaging.
     kAppWithJIT,  // Full snapshot of core libraries and application. Has some
                   // code, but may compile in the future because we haven't
                   // necessarily included code for every function or to
@@ -159,8 +161,8 @@
     kAppNoJIT,    // Full snapshot of core libraries and application. Has
                   // complete code for the application that never deopts. Will
                   // not compile in the future.
-    kScript,      // A partial snapshot of only the application script.
-    kMessage,     // A partial snapshot used only for isolate messaging.
+    kNone,        // dart_bootstrap/gen_snapshot
+    kInvalid
   };
 
   static const int kHeaderSize = 2 * sizeof(int64_t);
@@ -919,7 +921,8 @@
                              ReAlloc alloc,
                              intptr_t initial_size)
     : InstructionsWriter(),
-      assembly_stream_(assembly_buffer, alloc, initial_size) {
+      assembly_stream_(assembly_buffer, alloc, initial_size),
+      binary_size_(0) {
   }
 
   virtual void Write();
@@ -986,7 +989,7 @@
                  ForwardList* forward_list,
                  InstructionsWriter* instructions_writer,
                  bool can_send_any_object,
-                 bool vm_isolate_is_symbolic);
+                 bool writing_vm_isolate = false);
 
  public:
   // Snapshot kind.
@@ -1012,14 +1015,12 @@
     exception_msg_ = msg;
   }
   bool can_send_any_object() const { return can_send_any_object_; }
-  bool vm_isolate_is_symbolic() const { return vm_isolate_is_symbolic_; }
+  bool writing_vm_isolate() const { return writing_vm_isolate_; }
   void ThrowException(Exceptions::ExceptionType type, const char* msg);
 
   // Write a version string for the snapshot.
   void WriteVersion();
 
-  static intptr_t FirstObjectId();
-
   int32_t GetInstructionsId(RawInstructions* instructions, RawCode* code) {
     return instructions_writer_->GetOffsetFor(instructions, code);
   }
@@ -1065,15 +1066,6 @@
   bool AllowObjectsInDartLibrary(RawLibrary* library);
   intptr_t FindVmSnapshotObject(RawObject* rawobj);
 
-  void InitializeForwardList(ForwardList* forward_list) {
-    ASSERT(forward_list_ == NULL);
-    forward_list_ = forward_list;
-  }
-  void ResetForwardList() {
-    ASSERT(forward_list_ != NULL);
-    forward_list_ = NULL;
-  }
-
   ObjectStore* object_store() const { return object_store_; }
 
  private:
@@ -1087,7 +1079,7 @@
   const char* exception_msg_;  // Message associated with exception.
   bool unmarked_objects_;  // True if marked objects have been unmarked.
   bool can_send_any_object_;  // True if any Dart instance can be sent.
-  bool vm_isolate_is_symbolic_;
+  bool writing_vm_isolate_;
 
   friend class FullSnapshotWriter;
   friend class RawArray;
@@ -1128,8 +1120,7 @@
                      uint8_t** vm_isolate_snapshot_buffer,
                      uint8_t** isolate_snapshot_buffer,
                      ReAlloc alloc,
-                     InstructionsWriter* instructions_writer,
-                     bool vm_isolate_is_symbolic);
+                     InstructionsWriter* instructions_writer);
   ~FullSnapshotWriter();
 
   uint8_t** vm_isolate_snapshot_buffer() {
@@ -1172,23 +1163,13 @@
   ForwardList* forward_list_;
   InstructionsWriter* instructions_writer_;
   Array& scripts_;
-  Array& symbol_table_;
-  bool vm_isolate_is_symbolic_;
+  Array& saved_symbol_table_;
+  Array& new_vm_symbol_table_;
 
   DISALLOW_COPY_AND_ASSIGN(FullSnapshotWriter);
 };
 
 
-class PrecompiledSnapshotWriter : public FullSnapshotWriter {
- public:
-  PrecompiledSnapshotWriter(uint8_t** vm_isolate_snapshot_buffer,
-                            uint8_t** isolate_snapshot_buffer,
-                            ReAlloc alloc,
-                            InstructionsWriter* instructions_writer);
-  ~PrecompiledSnapshotWriter();
-};
-
-
 class ScriptSnapshotWriter : public SnapshotWriter {
  public:
   static const intptr_t kInitialSize = 64 * KB;
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index ef7a10c..52db512 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -835,8 +835,7 @@
                        kInitialSize,
                        &forward_list_,
                        NULL, /* test_writer */
-                       true, /* can_send_any_object */
-                       true /* vm_isolate_is_symbolic */),
+                       true /* can_send_any_object */),
         forward_list_(thread(), kMaxPredefinedObjectIds) {
     ASSERT(buffer != NULL);
     ASSERT(alloc != NULL);
@@ -859,27 +858,32 @@
   // Check if we are able to generate the source from the token stream.
   // Rescan this source and compare the token stream to see if they are
   // the same.
-  const TokenStream& expected_tokens = TokenStream::Handle(script.tokens());
+  Zone* zone = Thread::Current()->zone();
+  const TokenStream& expected_tokens =
+      TokenStream::Handle(zone, script.tokens());
   TokenStream::Iterator expected_iterator(
+      zone,
       expected_tokens,
       TokenPosition::kMinSource,
       TokenStream::Iterator::kAllTokens);
-  const String& str = String::Handle(expected_tokens.GenerateSource());
-  const String& private_key = String::Handle(expected_tokens.PrivateKey());
+  const String& str = String::Handle(zone, expected_tokens.GenerateSource());
+  const String& private_key =
+      String::Handle(zone, expected_tokens.PrivateKey());
   Scanner scanner(str, private_key);
   const TokenStream& reconstructed_tokens =
-      TokenStream::Handle(TokenStream::New(scanner.GetStream(),
-                                           private_key,
-                                           false));
+      TokenStream::Handle(zone, TokenStream::New(scanner.GetStream(),
+                                                 private_key,
+                                                 false));
   expected_iterator.SetCurrentPosition(TokenPosition::kMinSource);
   TokenStream::Iterator reconstructed_iterator(
+      zone,
       reconstructed_tokens,
       TokenPosition::kMinSource,
       TokenStream::Iterator::kAllTokens);
   Token::Kind expected_kind = expected_iterator.CurrentTokenKind();
   Token::Kind reconstructed_kind = reconstructed_iterator.CurrentTokenKind();
-  String& expected_literal = String::Handle();
-  String& actual_literal = String::Handle();
+  String& expected_literal = String::Handle(zone);
+  String& actual_literal = String::Handle(zone);
   while (expected_kind != Token::kEOS && reconstructed_kind != Token::kEOS) {
     EXPECT_EQ(expected_kind, reconstructed_kind);
     expected_literal ^= expected_iterator.CurrentLiteral();
@@ -937,14 +941,15 @@
       "  }\n"
       "}\n";
 
-  String& url = String::Handle(String::New("dart-test:SerializeScript"));
-  String& source = String::Handle(String::New(kScriptChars));
-  Script& script = Script::Handle(Script::New(url,
-                                              source,
-                                              RawScript::kScriptTag));
-  const String& lib_url = String::Handle(Symbols::New(thread, "TestLib"));
-  Library& lib = Library::Handle(Library::New(lib_url));
-  lib.Register();
+  Zone* zone = thread->zone();
+  String& url = String::Handle(zone, String::New("dart-test:SerializeScript"));
+  String& source = String::Handle(zone, String::New(kScriptChars));
+  Script& script = Script::Handle(zone, Script::New(url,
+                                                    source,
+                                                    RawScript::kScriptTag));
+  const String& lib_url = String::Handle(zone, Symbols::New(thread, "TestLib"));
+  Library& lib = Library::Handle(zone, Library::New(lib_url));
+  lib.Register(thread);
   EXPECT(CompilerTest::TestCompileScript(lib, script));
 
   // Write snapshot with script content.
@@ -954,27 +959,30 @@
 
   // Read object back from the snapshot.
   ScriptSnapshotReader reader(buffer, writer.BytesWritten(), thread);
-  Script& serialized_script = Script::Handle(thread->zone());
+  Script& serialized_script = Script::Handle(zone);
   serialized_script ^= reader.ReadObject();
 
   // Check if the serialized script object matches the original script.
-  String& expected_literal = String::Handle();
-  String& actual_literal = String::Handle();
-  String& str = String::Handle();
+  String& expected_literal = String::Handle(zone);
+  String& actual_literal = String::Handle(zone);
+  String& str = String::Handle(zone);
   str ^= serialized_script.url();
   EXPECT(url.Equals(str));
 
-  const TokenStream& expected_tokens = TokenStream::Handle(script.tokens());
+  const TokenStream& expected_tokens =
+      TokenStream::Handle(zone, script.tokens());
   const TokenStream& serialized_tokens =
-      TokenStream::Handle(serialized_script.tokens());
+      TokenStream::Handle(zone, serialized_script.tokens());
   const ExternalTypedData& expected_data =
-      ExternalTypedData::Handle(expected_tokens.GetStream());
+      ExternalTypedData::Handle(zone, expected_tokens.GetStream());
   const ExternalTypedData& serialized_data =
-      ExternalTypedData::Handle(serialized_tokens.GetStream());
+      ExternalTypedData::Handle(zone, serialized_tokens.GetStream());
   EXPECT_EQ(expected_data.Length(), serialized_data.Length());
-  TokenStream::Iterator expected_iterator(expected_tokens,
+  TokenStream::Iterator expected_iterator(zone,
+                                          expected_tokens,
                                           TokenPosition::kMinSource);
-  TokenStream::Iterator serialized_iterator(serialized_tokens,
+  TokenStream::Iterator serialized_iterator(zone,
+                                            serialized_tokens,
                                             TokenPosition::kMinSource);
   Token::Kind expected_kind = expected_iterator.CurrentTokenKind();
   Token::Kind serialized_kind = serialized_iterator.CurrentTokenKind();
@@ -1187,8 +1195,7 @@
                                 NULL,
                                 &isolate_snapshot_buffer,
                                 &malloc_allocator,
-                                NULL, /* instructions_writer */
-                                true);
+                                NULL /* instructions_writer */);
       writer.WriteFullSnapshot();
     }
   }
@@ -1248,8 +1255,7 @@
                                 NULL,
                                 &isolate_snapshot_buffer,
                                 &malloc_allocator,
-                                NULL, /* instructions_writer */
-                                true /* vm_isolate_is_symbolic */);
+                                NULL /* instructions_writer */);
       writer.WriteFullSnapshot();
     }
 
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 1d3e818..ee8858d6 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -145,8 +145,16 @@
       RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
   while (iter.MoveNext()) {
     HANDLESCOPE(thread());
+    // TODO(zra): Remove this bailout once DBC has reliable ICData.
+#if defined(TARGET_ARCH_DBC)
+    if (iter.DeoptId() >= ic_data_array->length()) {
+      continue;
+    }
+#else
+    ASSERT(iter.DeoptId() < ic_data_array->length());
+#endif
     const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
-    if (!ic_data->IsNull()) {
+    if (ic_data != NULL) {
       const TokenPosition token_pos = iter.TokenPos();
       if ((token_pos < begin_pos) || (token_pos > end_pos)) {
         // Does not correspond to a valid source position.
@@ -158,6 +166,7 @@
   }
 }
 
+
 void SourceReport::PrintCoverageData(JSONObject* jsobj,
                                      const Function& function,
                                      const Code& code) {
@@ -186,8 +195,16 @@
       RawPcDescriptors::kIcCall | RawPcDescriptors::kUnoptStaticCall);
   while (iter.MoveNext()) {
     HANDLESCOPE(thread());
+    // TODO(zra): Remove this bailout once DBC has reliable ICData.
+#if defined(TARGET_ARCH_DBC)
+    if (iter.DeoptId() >= ic_data_array->length()) {
+      continue;
+    }
+#else
+    ASSERT(iter.DeoptId() < ic_data_array->length());
+#endif
     const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
-    if (!ic_data->IsNull()) {
+    if (ic_data != NULL) {
       const TokenPosition token_pos = iter.TokenPos();
       if ((token_pos < begin_pos) || (token_pos > end_pos)) {
         // Does not correspond to a valid source position.
@@ -226,6 +243,7 @@
   }
 }
 
+
 void SourceReport::PrintPossibleBreakpointsData(JSONObject* jsobj,
                                                 const Function& func,
                                                 const Code& code) {
@@ -338,8 +356,16 @@
   Code& code = Code::Handle(zone(), func.unoptimized_code());
   if (code.IsNull()) {
     if (func.HasCode() || (compile_mode_ == kForceCompile)) {
-      if (Compiler::EnsureUnoptimizedCode(thread(), func) != Error::null()) {
-        // Ignore the error and this function entirely.
+      const Error& err =
+          Error::Handle(Compiler::EnsureUnoptimizedCode(thread(), func));
+      if (!err.IsNull()) {
+        // Emit an uncompiled range for this function with error information.
+        JSONObject range(jsarr);
+        range.AddProperty("scriptIndex", GetScriptIndex(script));
+        range.AddProperty("startPos", begin_pos);
+        range.AddProperty("endPos", end_pos);
+        range.AddProperty("compiled", false);
+        range.AddProperty("error", err);
         return;
       }
       code = func.unoptimized_code();
@@ -393,9 +419,36 @@
   Class& cls = Class::Handle(zone());
   Array& functions = Array::Handle(zone());
   Function& func = Function::Handle(zone());
+  Script& script = Script::Handle(zone());
   ClassDictionaryIterator it(lib, ClassDictionaryIterator::kIteratePrivate);
   while (it.HasNext()) {
     cls = it.GetNextClass();
+    if (!cls.is_finalized()) {
+      if (compile_mode_ == kForceCompile) {
+        const Error& err = Error::Handle(cls.EnsureIsFinalized(thread()));
+        if (!err.IsNull()) {
+          // Emit an uncompiled range for this class with error information.
+          JSONObject range(jsarr);
+          script = cls.script();
+          range.AddProperty("scriptIndex", GetScriptIndex(script));
+          range.AddProperty("startPos", cls.token_pos());
+          range.AddProperty("endPos", cls.ComputeEndTokenPos());
+          range.AddProperty("compiled", false);
+          range.AddProperty("error", err);
+          continue;
+        }
+      } else {
+        // Emit one range for the whole uncompiled class.
+        JSONObject range(jsarr);
+        script = cls.script();
+        range.AddProperty("scriptIndex", GetScriptIndex(script));
+        range.AddProperty("startPos", cls.token_pos());
+        range.AddProperty("endPos", cls.ComputeEndTokenPos());
+        range.AddProperty("compiled", false);
+        continue;
+      }
+    }
+
     functions = cls.functions();
     for (int i = 0; i < functions.Length(); i++) {
       func ^= functions.At(i);
@@ -451,5 +504,4 @@
   PrintScriptTable(&scripts);
 }
 
-
 }  // namespace dart
diff --git a/runtime/vm/source_report_test.cc b/runtime/vm/source_report_test.cc
index ca02001..ad00dec 100644
--- a/runtime/vm/source_report_test.cc
+++ b/runtime/vm/source_report_test.cc
@@ -143,6 +143,140 @@
 }
 
 
+TEST_CASE(SourceReport_Coverage_UnusedClass_NoForceCompile) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "class Unused {\n"
+      "  helper1() { helper0(); }\n"
+      "}\n"
+      "main() {\n"
+      "  helper0();\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCoverage);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // UnusedClass is not compiled.
+      "{\"scriptIndex\":0,\"startPos\":6,\"endPos\":20,\"compiled\":false},"
+
+      // helper0 is compiled.
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // One range with a hit (main).
+      "{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
+
+      // Only one script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_UnusedClass_ForceCompile) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "class Unused {\n"
+      "  helper1() { helper0(); }\n"
+      "}\n"
+      "main() {\n"
+      "  helper0();\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCoverage, SourceReport::kForceCompile);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // UnusedClass.helper1 is compiled.
+      "{\"scriptIndex\":0,\"startPos\":10,\"endPos\":18,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[14]}},"
+
+      // helper0 is compiled.
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // One range with a hit (main).
+      "{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
+
+      // Only one script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
+TEST_CASE(SourceReport_Coverage_UnusedClass_ForceCompileError) {
+  char buffer[1024];
+  const char* kScript =
+      "helper0() {}\n"
+      "class Unused {\n"
+      "  helper1() { helper0()+ }\n"  // syntax error
+      "}\n"
+      "main() {\n"
+      "  helper0();\n"
+      "}";
+
+  Library& lib = Library::Handle();
+  lib ^= ExecuteScript(kScript);
+  ASSERT(!lib.IsNull());
+  const Script& script = Script::Handle(lib.LookupScript(
+      String::Handle(String::New("test-lib"))));
+
+  SourceReport report(SourceReport::kCoverage, SourceReport::kForceCompile);
+  JSONStream js;
+  report.PrintJSON(&js, script);
+  ElideJSONSubstring("classes", js.ToCString(), buffer);
+  ElideJSONSubstring("libraries", buffer, buffer);
+  EXPECT_STREQ(
+      "{\"type\":\"SourceReport\",\"ranges\":["
+
+      // UnusedClass has a syntax error.
+      "{\"scriptIndex\":0,\"startPos\":10,\"endPos\":18,\"compiled\":false,"
+      "\"error\":{\"type\":\"@Error\",\"_vmType\":\"LanguageError\","
+      "\"kind\":\"LanguageError\",\"id\":\"objects\\/0\","
+      "\"message\":\"'test-lib': error: line 3 pos 26: unexpected token '}'\\n"
+      "  helper1() { helper0()+ }\\n                         ^\\n\"}},"
+
+      // helper0 is compiled.
+      "{\"scriptIndex\":0,\"startPos\":0,\"endPos\":4,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[],\"misses\":[]}},"
+
+      // One range with a hit (main).
+      "{\"scriptIndex\":0,\"startPos\":22,\"endPos\":32,\"compiled\":true,"
+      "\"coverage\":{\"hits\":[27],\"misses\":[]}}],"
+
+      // Only one script in the script table.
+      "\"scripts\":[{\"type\":\"@Script\",\"fixedId\":true,\"id\":\"\","
+      "\"uri\":\"test-lib\",\"_kind\":\"script\"}]}",
+      buffer);
+}
+
+
 TEST_CASE(SourceReport_Coverage_NestedFunctions) {
   char buffer[1024];
   const char* kScript =
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index 0a7644b..a2198aa 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -75,6 +75,9 @@
 
 
 void FUNCTION_NAME(StackFrame_validateFrame)(Dart_NativeArguments args) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+
   Dart_Handle index = Dart_GetNativeArgument(args, 0);
   Dart_Handle name = Dart_GetNativeArgument(args, 1);
   const Smi& frame_index_smi = Smi::CheckedHandle(Api::UnwrapHandle(index));
@@ -89,18 +92,18 @@
       // Find the function corresponding to this frame and check if it
       // matches the function name passed in.
       const Function& function =
-          Function::Handle(frame->LookupDartFunction());
+          Function::Handle(zone, frame->LookupDartFunction());
       if (function.IsNull()) {
         FATAL("StackFrame_validateFrame fails, invalid dart frame.\n");
       }
       const char* name = function.ToFullyQualifiedCString();
       // Currently all unit tests are loaded as being part of dart:core-lib.
-      String& url = String::Handle(String::New(TestCase::url()));
-      const Library& lib = Library::Handle(Library::LookupLibrary(url));
+      String& url = String::Handle(zone, String::New(TestCase::url()));
+      const Library& lib = Library::Handle(zone,
+                                           Library::LookupLibrary(thread, url));
       ASSERT(!lib.IsNull());
-      const char* lib_name = String::Handle(lib.url()).ToCString();
-      char* full_name = OS::SCreate(Thread::Current()->zone(),
-          "%s_%s", lib_name, expected_name);
+      const char* lib_name = String::Handle(zone, lib.url()).ToCString();
+      char* full_name = OS::SCreate(zone, "%s_%s", lib_name, expected_name);
       if (strcmp(full_name, name) != 0) {
         FATAL("StackFrame_validateFrame fails, incorrect frame.\n");
       }
diff --git a/runtime/vm/stub_code_dbc.cc b/runtime/vm/stub_code_dbc.cc
index 0042f2d..0f66414 100644
--- a/runtime/vm/stub_code_dbc.cc
+++ b/runtime/vm/stub_code_dbc.cc
@@ -26,9 +26,6 @@
 DEFINE_FLAG(bool, use_slow_path, false,
     "Set to true for debugging & verifying the slow paths.");
 DECLARE_FLAG(bool, trace_optimized_ic_calls);
-DECLARE_FLAG(int, optimization_counter_threshold);
-DECLARE_FLAG(bool, support_debugger);
-DECLARE_FLAG(bool, lazy_dispatchers);
 
 void StubCode::GenerateLazyCompileStub(Assembler* assembler) {
   __ Compile();
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index a138437..a0b6c83 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -307,41 +307,6 @@
 }
 
 
-void Symbols::AddPredefinedSymbolsToIsolate() {
-  // Should only be run by regular Dart isolates.
-  Thread* thread = Thread::Current();
-  Isolate* isolate = thread->isolate();
-  Zone* zone = thread->zone();
-  ASSERT(isolate != Dart::vm_isolate());
-  String& str = String::Handle(zone);
-
-  SymbolTable table(zone, isolate->object_store()->symbol_table());
-
-  // Set up all the predefined string symbols and create symbols for
-  // language keywords.
-  for (intptr_t i = 1; i < Symbols::kNullCharId; i++) {
-    str = OneByteString::New(names[i], Heap::kOld);
-    str.Hash();
-    str ^= table.InsertOrGet(str);
-    str.SetCanonical();  // Make canonical once entered.
-  }
-
-  // Add Latin1 characters as Symbols, so that Symbols::FromCharCode is fast.
-  for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) {
-    intptr_t idx = (kNullCharId + c);
-    ASSERT(idx < kMaxPredefinedId);
-    ASSERT(Utf::IsLatin1(c));
-    uint8_t ch = static_cast<uint8_t>(c);
-    str = OneByteString::New(&ch, 1, Heap::kOld);
-    str.Hash();
-    str ^= table.InsertOrGet(str);
-    str.SetCanonical();  // Make canonical once entered.
-  }
-
-  isolate->object_store()->set_symbol_table(table.Release());
-}
-
-
 void Symbols::SetupSymbolTable(Isolate* isolate) {
   ASSERT(isolate != NULL);
 
@@ -354,48 +319,54 @@
 }
 
 
-intptr_t Symbols::Compact(Isolate* isolate) {
-  ASSERT(isolate != Dart::vm_isolate());
+RawArray* Symbols::UnifiedSymbolTable() {
+  Thread* thread = Thread::Current();
+  Isolate* isolate = thread->isolate();
+  Zone* zone = thread->zone();
 
-  Zone* zone = Thread::Current()->zone();
-  intptr_t initial_size = -1;
-  intptr_t final_size = -1;
+  ASSERT(thread->IsMutatorThread());
+  ASSERT(isolate->background_compiler() == NULL);
 
-  // 1. Build a collection of all the predefined symbols so they are
-  // strongly referenced (the read only handles are not traced).
-  {
-    SymbolTable table(zone, isolate->object_store()->symbol_table());
-    initial_size = table.NumOccupied();
+  SymbolTable vm_table(zone,
+                       Dart::vm_isolate()->object_store()->symbol_table());
+  SymbolTable table(zone, isolate->object_store()->symbol_table());
+  intptr_t unified_size = vm_table.NumOccupied() + table.NumOccupied();
+  SymbolTable unified_table(zone, HashTables::New<SymbolTable>(unified_size,
+                                                               Heap::kOld));
+  String& symbol = String::Handle(zone);
 
-    if (Object::vm_isolate_snapshot_object_table().Length() == 0) {
-      GrowableObjectArray& predefined_symbols = GrowableObjectArray::Handle(
-          GrowableObjectArray::New(kMaxPredefinedId));
-      String& symbol = String::Handle();
-      for (intptr_t i = 1; i < Symbols::kNullCharId; i++) {
-        const unsigned char* name =
-          reinterpret_cast<const unsigned char*>(names[i]);
-        symbol ^= table.GetOrNull(Latin1Array(name, strlen(names[i])));
-        ASSERT(!symbol.IsNull());
-        predefined_symbols.Add(symbol);
-      }
-      for (intptr_t c = 0; c < kNumberOfOneCharCodeSymbols; c++) {
-        intptr_t idx = (kNullCharId + c);
-        ASSERT(idx < kMaxPredefinedId);
-        ASSERT(Utf::IsLatin1(c));
-        uint8_t ch = static_cast<uint8_t>(c);
-        symbol ^= table.GetOrNull(Latin1Array(&ch, 1));
-        ASSERT(!symbol.IsNull());
-        predefined_symbols.Add(symbol);
-      }
-    }
-    table.Release();
+  SymbolTable::Iterator vm_iter(&vm_table);
+  while (vm_iter.MoveNext()) {
+    symbol ^= vm_table.GetKey(vm_iter.Current());
+    ASSERT(!symbol.IsNull());
+    bool present = unified_table.Insert(symbol);
+    ASSERT(!present);
   }
+  vm_table.Release();
 
-  // 2. Knock out the symbol table and do a full garbage collection.
+  SymbolTable::Iterator iter(&table);
+  while (iter.MoveNext()) {
+    symbol ^= table.GetKey(iter.Current());
+    ASSERT(!symbol.IsNull());
+    bool present = unified_table.Insert(symbol);
+    ASSERT(!present);
+  }
+  table.Release();
+
+  return unified_table.Release().raw();
+}
+
+
+#if defined(DART_PRECOMPILER)
+void Symbols::Compact(Isolate* isolate) {
+  ASSERT(isolate != Dart::vm_isolate());
+  Zone* zone = Thread::Current()->zone();
+
+  // 1. Drop the symbol table and do a full garbage collection.
   isolate->object_store()->set_symbol_table(Object::empty_array());
   isolate->heap()->CollectAllGarbage();
 
-  // 3. Walk the heap and build a new table from surviving symbols.
+  // 2. Walk the heap to find surviving symbols.
   GrowableArray<String*> symbols;
   class SymbolCollector : public ObjectVisitor {
    public:
@@ -405,7 +376,7 @@
           zone_(thread->zone()) {}
 
     void VisitObject(RawObject* obj) {
-      if (obj->IsString() && obj->IsCanonical()) {
+      if (obj->IsCanonical() && obj->IsStringInstance()) {
         symbols_->Add(&String::ZoneHandle(zone_, String::RawCast(obj)));
       }
     }
@@ -418,24 +389,21 @@
   SymbolCollector visitor(Thread::Current(), &symbols);
   isolate->heap()->IterateObjects(&visitor);
 
-  {
-    Array& array =
-        Array::Handle(HashTables::New<SymbolTable>(symbols.length() * 4 / 3,
-                                                   Heap::kOld));
-    SymbolTable table(zone, array.raw());
-    for (intptr_t i = 0; i < symbols.length(); i++) {
-      String& symbol = *symbols[i];
-      ASSERT(symbol.IsString());
-      ASSERT(symbol.IsCanonical());
-      bool present = table.Insert(symbol);
-      ASSERT(!present);
-    }
-    final_size = table.NumOccupied();
-    isolate->object_store()->set_symbol_table(table.Release());
+  // 3. Build a new table from the surviving symbols.
+  Array& array =
+      Array::Handle(zone, HashTables::New<SymbolTable>(symbols.length() * 4 / 3,
+                                                       Heap::kOld));
+  SymbolTable table(zone, array.raw());
+  for (intptr_t i = 0; i < symbols.length(); i++) {
+    String& symbol = *symbols[i];
+    ASSERT(symbol.IsString());
+    ASSERT(symbol.IsCanonical());
+    bool present = table.Insert(symbol);
+    ASSERT(!present);
   }
-
-  return initial_size - final_size;
+  isolate->object_store()->set_symbol_table(table.Release());
 }
+#endif   // DART_PRECOMPILER
 
 
 void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) {
@@ -655,7 +623,6 @@
     symbol ^= table.GetOrNull(str);
     table.Release();
   }
-
   ASSERT(symbol.IsNull() || symbol.IsSymbol());
   ASSERT(symbol.IsNull() || symbol.HasHash());
   return symbol.raw();
@@ -758,7 +725,7 @@
 }
 
 
-intptr_t Symbols::LookupVMSymbol(RawObject* obj) {
+intptr_t Symbols::LookupPredefinedSymbol(RawObject* obj) {
   for (intptr_t i = 1; i < Symbols::kMaxPredefinedId; i++) {
     if (symbol_handles_[i]->raw() == obj) {
       return (i + kMaxPredefinedObjectIds);
@@ -768,8 +735,8 @@
 }
 
 
-RawObject* Symbols::GetVMSymbol(intptr_t object_id) {
-  ASSERT(IsVMSymbolId(object_id));
+RawObject* Symbols::GetPredefinedSymbol(intptr_t object_id) {
+  ASSERT(IsPredefinedSymbolId(object_id));
   intptr_t i = (object_id - kMaxPredefinedObjectIds);
   if ((i > kIllegal) && (i < Symbols::kMaxPredefinedId)) {
     return symbol_handles_[i]->raw();
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 83c7458..7057da2 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -332,6 +332,7 @@
   V(DartTypedData, "dart:typed_data")                                          \
   V(DartVMService, "dart:_vmservice")                                          \
   V(DartIOLibName, "dart.io")                                                  \
+  V(DartVMProduct, "dart.vm.product")                                          \
   V(EvalSourceUri, "evaluate:source")                                          \
   V(_Random, "_Random")                                                        \
   V(_state, "_state")                                                          \
@@ -555,19 +556,15 @@
   static void InitOnce(Isolate* isolate);
   static void InitOnceFromSnapshot(Isolate* isolate);
 
-  // Add all the symbols that were cached in the VM isolate to this isolate,
-  // we do this when an Isolate is not created from the snapshot so that
-  // we get a unified symbol table that can be be dumped into the VM isolate
-  // snapshot.
-  static void AddPredefinedSymbolsToIsolate();
-
   // Initialize and setup a symbol table for the isolate.
   static void SetupSymbolTable(Isolate* isolate);
 
-  // Treat the symbol table as weak and collect garbage. Answer the number of
-  // symbols deleted from the symbol table because they where not referenced
-  // from anywhere else.
-  static intptr_t Compact(Isolate* isolate);
+  static RawArray* UnifiedSymbolTable();
+
+#if defined(DART_PRECOMPILER)
+  // Treat the symbol table as weak and collect garbage.
+  static void Compact(Isolate* isolate);
+#endif
 
   // Creates a Symbol given a C string that is assumed to contain
   // UTF-8 encoded characters and '\0' is considered a termination character.
@@ -644,22 +641,22 @@
   static RawString* LookupFromSet(Thread* thread, const String& str);
   static RawString* LookupFromDot(Thread* thread, const String& str);
 
+  static void GetStats(Isolate* isolate,
+                       intptr_t* size,
+                       intptr_t* capacity);
+
  private:
   enum {
     kInitialVMIsolateSymtabSize = 1024,
     kInitialSymtabSize = 2048
   };
 
-  static void GetStats(Isolate* isolate,
-                       intptr_t* size,
-                       intptr_t* capacity);
-
   template<typename StringType>
   static RawString* NewSymbol(Thread* thread, const StringType& str);
 
-  static intptr_t LookupVMSymbol(RawObject* obj);
-  static RawObject* GetVMSymbol(intptr_t object_id);
-  static bool IsVMSymbolId(intptr_t object_id) {
+  static intptr_t LookupPredefinedSymbol(RawObject* obj);
+  static RawObject* GetPredefinedSymbol(intptr_t object_id);
+  static bool IsPredefinedSymbolId(intptr_t object_id) {
     return (object_id >= kMaxPredefinedObjectIds &&
             object_id < (kMaxPredefinedObjectIds + kMaxPredefinedId));
   }
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 0adf841..8b9eaf0 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -308,6 +308,8 @@
 TimelineEvent::TimelineEvent()
     : timestamp0_(0),
       timestamp1_(0),
+      thread_timestamp0_(-1),
+      thread_timestamp1_(-1),
       arguments_(NULL),
       arguments_length_(0),
       state_(0),
@@ -370,15 +372,19 @@
 
 
 void TimelineEvent::DurationBegin(const char* label,
-                                  int64_t micros) {
+                                  int64_t micros,
+                                  int64_t thread_micros) {
   Init(kDuration, label);
   set_timestamp0(micros);
+  set_thread_timestamp0(thread_micros);
 }
 
 
-void TimelineEvent::DurationEnd(int64_t micros) {
+void TimelineEvent::DurationEnd(int64_t micros,
+                                int64_t thread_micros) {
   ASSERT(timestamp1_ == 0);
   set_timestamp1(micros);
+  set_thread_timestamp1(thread_micros);
 }
 
 
@@ -391,24 +397,32 @@
 
 void TimelineEvent::Duration(const char* label,
                              int64_t start_micros,
-                             int64_t end_micros) {
+                             int64_t end_micros,
+                             int64_t thread_start_micros,
+                             int64_t thread_end_micros) {
   Init(kDuration, label);
   set_timestamp0(start_micros);
   set_timestamp1(end_micros);
+  set_thread_timestamp0(thread_start_micros);
+  set_thread_timestamp1(thread_end_micros);
 }
 
 
 void TimelineEvent::Begin(const char* label,
-                          int64_t micros) {
+                          int64_t micros,
+                          int64_t thread_micros) {
   Init(kBegin, label);
   set_timestamp0(micros);
+  set_thread_timestamp0(thread_micros);
 }
 
 
 void TimelineEvent::End(const char* label,
-                        int64_t micros) {
+                        int64_t micros,
+                        int64_t thread_micros) {
   Init(kEnd, label);
   set_timestamp0(micros);
+  set_thread_timestamp0(thread_micros);
 }
 
 
@@ -522,6 +536,8 @@
   state_ = 0;
   timestamp0_ = 0;
   timestamp1_ = 0;
+  thread_timestamp0_ = -1;
+  thread_timestamp1_ = -1;
   OSThread* os_thread = OSThread::Current();
   ASSERT(os_thread != NULL);
   thread_ = os_thread->trace_id();
@@ -588,7 +604,9 @@
   obj.AddProperty64("tid", tid);
   obj.AddProperty64("pid", pid);
   obj.AddPropertyTimeMicros("ts", TimeOrigin());
-
+  if (HasThreadCPUTime()) {
+    obj.AddPropertyTimeMicros("tts", ThreadCPUTimeOrigin());
+  }
   switch (event_type()) {
     case kBegin: {
       obj.AddProperty("ph", "B");
@@ -601,6 +619,9 @@
     case kDuration: {
       obj.AddProperty("ph", "X");
       obj.AddPropertyTimeMicros("dur", TimeDuration());
+      if (HasThreadCPUTime()) {
+        obj.AddPropertyTimeMicros("tdur", ThreadCPUTimeDuration());
+      }
     }
     break;
     case kInstant: {
@@ -668,6 +689,28 @@
 }
 
 
+bool TimelineEvent::HasThreadCPUTime() const {
+  return (thread_timestamp0_ != -1);
+}
+
+
+
+int64_t TimelineEvent::ThreadCPUTimeOrigin() const {
+  ASSERT(HasThreadCPUTime());
+  return thread_timestamp0_;
+}
+
+
+int64_t TimelineEvent::ThreadCPUTimeDuration() const {
+  ASSERT(HasThreadCPUTime());
+  if (thread_timestamp1_ == -1) {
+    // This duration is still open, use current time as end.
+    return OS::GetCurrentThreadCPUMicros() - thread_timestamp0_;
+  }
+  return thread_timestamp1_ - thread_timestamp0_;
+}
+
+
 TimelineStream::TimelineStream()
     : name_(NULL),
       enabled_(false),
@@ -831,6 +874,7 @@
     return;
   }
   timestamp_ = OS::GetCurrentMonotonicMicros();
+  thread_timestamp_ = OS::GetCurrentThreadCPUMicros();
 }
 
 
@@ -842,6 +886,7 @@
     return;
   }
   timestamp_ = OS::GetCurrentMonotonicMicros();
+  thread_timestamp_ = OS::GetCurrentThreadCPUMicros();
 }
 
 
@@ -859,7 +904,11 @@
   }
   ASSERT(event != NULL);
   // Emit a duration event.
-  event->Duration(label(), timestamp_, OS::GetCurrentMonotonicMicros());
+  event->Duration(label(),
+                  timestamp_,
+                  OS::GetCurrentMonotonicMicros(),
+                  thread_timestamp_,
+                  OS::GetCurrentThreadCPUMicros());
   StealArguments(event);
   event->Complete();
 }
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index f78b516..1646d99 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -156,20 +156,27 @@
                 int64_t micros = OS::GetCurrentMonotonicMicros());
 
   void DurationBegin(const char* label,
-                     int64_t micros = OS::GetCurrentMonotonicMicros());
-  void DurationEnd(int64_t micros = OS::GetCurrentMonotonicMicros());
+                     int64_t micros = OS::GetCurrentMonotonicMicros(),
+                     int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
+  void DurationEnd(int64_t micros = OS::GetCurrentMonotonicMicros(),
+                   int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
+
   void Instant(const char* label,
                int64_t micros = OS::GetCurrentMonotonicMicros());
 
   void Duration(const char* label,
                 int64_t start_micros,
-                int64_t end_micros);
+                int64_t end_micros,
+                int64_t thread_start_micros = -1,
+                int64_t thread_end_micros = -1);
 
   void Begin(const char* label,
-             int64_t micros = OS::GetCurrentMonotonicMicros());
+             int64_t micros = OS::GetCurrentMonotonicMicros(),
+             int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
 
   void End(const char* label,
-           int64_t micros = OS::GetCurrentMonotonicMicros());
+           int64_t micros = OS::GetCurrentMonotonicMicros(),
+           int64_t thread_micros = OS::GetCurrentThreadCPUMicros());
 
   void Counter(const char* label,
                int64_t micros = OS::GetCurrentMonotonicMicros());
@@ -204,6 +211,10 @@
     return (event_type() == kDuration) && (timestamp1_ > timestamp0_);
   }
 
+  bool HasThreadCPUTime() const;
+  int64_t ThreadCPUTimeDuration() const;
+  int64_t ThreadCPUTimeOrigin() const;
+
   int64_t TimeOrigin() const;
   int64_t AsyncId() const;
   int64_t TimeDuration() const;
@@ -311,6 +322,16 @@
     timestamp1_ = value;
   }
 
+  void set_thread_timestamp0(int64_t value) {
+    ASSERT(thread_timestamp0_ == -1);
+    thread_timestamp0_ = value;
+  }
+
+  void set_thread_timestamp1(int64_t value) {
+    ASSERT(thread_timestamp1_ == -1);
+    thread_timestamp1_ = value;
+  }
+
   bool pre_serialized_json() const {
     return PreSerializedJSON::decode(state_);
   }
@@ -337,6 +358,8 @@
 
   int64_t timestamp0_;
   int64_t timestamp1_;
+  int64_t thread_timestamp0_;
+  int64_t thread_timestamp1_;
   TimelineEventArgument* arguments_;
   intptr_t arguments_length_;
   uword state_;
@@ -486,6 +509,7 @@
 
  private:
   int64_t timestamp_;
+  int64_t thread_timestamp_;
 
   DISALLOW_COPY_AND_ASSIGN(TimelineDurationScope);
 };
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index 60f4057..a8224c5 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -430,6 +430,29 @@
         reinterpret_cast<intptr_t>(arg3),
         0, fp_return, fp_args);
   }
+#elif defined(USING_SIMULATOR) && defined(TARGET_ARCH_DBC)
+  template<typename ResultType,
+           typename Arg1Type,
+           typename Arg2Type,
+           typename Arg3Type>
+  ResultType Invoke(Arg1Type arg1, Arg2Type arg2, Arg3Type arg3) {
+    // TODO(fschneider): Support double arguments for simulator calls.
+    COMPILE_ASSERT(is_void<ResultType>::value);
+    COMPILE_ASSERT(!is_double<Arg1Type>::value);
+    COMPILE_ASSERT(!is_double<Arg2Type>::value);
+    COMPILE_ASSERT(!is_double<Arg3Type>::value);
+    const Object& arg1obj = Object::Handle(reinterpret_cast<RawObject*>(arg1));
+    const Object& arg2obj = Object::Handle(reinterpret_cast<RawObject*>(arg2));
+    const Array& argdesc = Array::Handle(ArgumentsDescriptor::New(2));
+    const Array& arguments = Array::Handle(Array::New(2));
+    arguments.SetAt(0, arg1obj);
+    arguments.SetAt(1, arg2obj);
+    Simulator::Current()->Call(
+        code(),
+        argdesc,
+        arguments,
+        reinterpret_cast<Thread*>(arg3));
+  }
 #else
   template<typename ResultType> ResultType InvokeWithCodeAndThread() {
     Thread* thread = Thread::Current();
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index d51185b..210cfcd 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -304,6 +304,7 @@
     'object.h',
     'object_arm_test.cc',
     'object_arm64_test.cc',
+    'object_dbc_test.cc',
     'object_graph.cc',
     'object_graph.h',
     'object_graph_test.cc',
diff --git a/runtime/vm/weak_table.h b/runtime/vm/weak_table.h
index aca86fc..01a607b 100644
--- a/runtime/vm/weak_table.h
+++ b/runtime/vm/weak_table.h
@@ -154,7 +154,7 @@
   void Rehash();
 
   static intptr_t Hash(RawObject* key) {
-    return reinterpret_cast<intptr_t>(key) >> kObjectAlignmentLog2;
+    return reinterpret_cast<intptr_t>(key) * 92821;
   }
 
   // data_ contains size_ tuples of key/value.
diff --git a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
index d56f946..7a2c5a6 100644
--- a/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/developer_patch.dart
@@ -59,8 +59,14 @@
 int _clockValue = 0;
 
 @patch
+int _getThreadCpuClock() {
+  return -1;
+}
+
+
+@patch
 void _reportCompleteEvent(int start,
-                          int end,
+                          int startCpu,
                           String category,
                           String name,
                           String argumentsAsJson) {
diff --git a/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
index 6041760..a7f13ab 100644
--- a/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/typed_data_patch.dart
@@ -3,13 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 
-import 'dart:_internal' show FixedLengthListMixin;
-import 'dart:_foreign_helper' show JS;
-import 'dart:math' as Math;
-import 'dart:_internal';
-import 'dart:_interceptors' show JSIndexable, JSUInt32, JSUInt31;
-import 'dart:_js_helper'
-    show Creates, JavaScriptIndexingBehavior, JSName, Returns, patch;
+import 'dart:_js_helper' show patch;
 import 'dart:_native_typed_data';
 
 @patch class ByteData {
diff --git a/sdk/lib/core/errors.dart b/sdk/lib/core/errors.dart
index a47838b..c11ea2e 100644
--- a/sdk/lib/core/errors.dart
+++ b/sdk/lib/core/errors.dart
@@ -454,7 +454,7 @@
    * The [namedArguments] is a map from [Symbol]s to the values of named
    * arguments that the method was called with.
    *
-   * The optional [exisitingArgumentNames] is the expected parameters of a
+   * The optional [existingArgumentNames] is the expected parameters of a
    * method with the same name on the receiver, if available. This is
    * the signature of the method that would have been called if the parameters
    * had matched.
diff --git a/sdk/lib/core/map.dart b/sdk/lib/core/map.dart
index 4f7fcf8..ac4581f 100644
--- a/sdk/lib/core/map.dart
+++ b/sdk/lib/core/map.dart
@@ -244,7 +244,7 @@
    * The values of [this].
    *
    * The values are iterated in the order of their corresponding keys.
-   * This means that iterating [keys] and [values] in parrallel will
+   * This means that iterating [keys] and [values] in parallel will
    * provided matching pairs of keys and values.
    *
    * The returned iterable has an efficient `length` method based on the
diff --git a/sdk/lib/developer/developer.dart b/sdk/lib/developer/developer.dart
index e66e13a..74c9d50 100644
--- a/sdk/lib/developer/developer.dart
+++ b/sdk/lib/developer/developer.dart
@@ -8,9 +8,9 @@
 /// as a result of developer feedback. This library is platform dependent and
 /// therefore it has implementations for both dart2js and the Dart VM. Both are
 /// under development and may not support all operations yet.
-/// 
+///
 /// To use this library in your code:
-/// 
+///
 ///     import 'dart:developer';
 ///
 library dart.developer;
diff --git a/sdk/lib/developer/timeline.dart b/sdk/lib/developer/timeline.dart
index 362832d..fbdad8b 100644
--- a/sdk/lib/developer/timeline.dart
+++ b/sdk/lib/developer/timeline.dart
@@ -4,6 +4,8 @@
 
 part of dart.developer;
 
+const bool _isProduct = const bool.fromEnvironment("dart.vm.product");
+
 typedef dynamic TimelineSyncFunction();
 typedef Future TimelineAsyncFunction();
 
@@ -13,12 +15,15 @@
   /// a [Map] of [arguments]. This operation must be finished before
   /// returning to the event queue.
   static void startSync(String name, {Map arguments}) {
+    if (_isProduct) {
+      return;
+    }
     if (name is! String) {
       throw new ArgumentError.value(name,
                                     'name',
                                     'Must be a String');
     }
-    var block = new _SyncBlock._(name, _getTraceClock());
+    var block = new _SyncBlock._(name, _getTraceClock(), _getThreadCpuClock());
     if (arguments is Map) {
       block._appendArguments(arguments);
     }
@@ -27,6 +32,9 @@
 
   /// Finish the last synchronous operation that was started.
   static void finishSync() {
+    if (_isProduct) {
+      return;
+    }
     if (_stack.length == 0) {
       throw new StateError(
           'Uneven calls to startSync and finishSync');
@@ -39,6 +47,9 @@
 
   /// Emit an instant event.
   static void instantSync(String name, {Map arguments}) {
+    if (_isProduct) {
+      return;
+    }
     if (name is! String) {
       throw new ArgumentError.value(name,
                                     'name',
@@ -101,6 +112,9 @@
   /// Start a synchronous operation within this task named [name].
   /// Optionally takes a [Map] of [arguments].
   void start(String name, {Map arguments}) {
+    if (_isProduct) {
+      return;
+    }
     if (name is! String) {
       throw new ArgumentError.value(name,
                                     'name',
@@ -116,6 +130,9 @@
 
   /// Emit an instant event for this task.
   void instant(String name, {Map arguments}) {
+    if (_isProduct) {
+      return;
+    }
     if (name is! String) {
       throw new ArgumentError.value(name,
                                     'name',
@@ -135,6 +152,9 @@
 
   /// Finish the last synchronous operation that was started.
   void finish() {
+    if (_isProduct) {
+      return;
+    }
     if (_stack.length == 0) {
       throw new StateError(
           'Uneven calls to start and finish');
@@ -215,16 +235,19 @@
   Map _arguments;
   // The start time stamp.
   final int _start;
+  // The start time stamp of the thread cpu clock.
+  final int _startCpu;
 
   _SyncBlock._(this.name,
-               this._start);
+               this._start,
+               this._startCpu);
 
   /// Finish this block of time. At this point, this block can no longer be
   /// used.
   void finish() {
     // Report event to runtime.
     _reportCompleteEvent(_start,
-                         _getTraceClock(),
+                         _startCpu,
                          category,
                          name,
                          _argumentsAsJson(_arguments));
@@ -261,6 +284,9 @@
 /// Returns the current value from the trace clock.
 external int _getTraceClock();
 
+/// Returns the current value from the thread CPU usage clock.
+external int _getThreadCpuClock();
+
 /// Returns the isolate's main port number.
 external int _getIsolateNum();
 
@@ -274,7 +300,7 @@
 
 /// Reports a complete synchronous event.
 external void _reportCompleteEvent(int start,
-                                   int end,
+                                   int startCpu,
                                    String category,
                                    String name,
                                    String argumentsAsJson);
diff --git a/sdk/lib/io/bytes_builder.dart b/sdk/lib/io/bytes_builder.dart
index 2882402..a4b611f 100644
--- a/sdk/lib/io/bytes_builder.dart
+++ b/sdk/lib/io/bytes_builder.dart
@@ -153,7 +153,7 @@
 
 class _BytesBuilder implements BytesBuilder {
   int _length = 0;
-  final List _chunks = [];
+  final _chunks = <List<int>>[];
 
   void add(List<int> bytes) {
     if (bytes is! Uint8List) {
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index 0972e84..ec1320a 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -58,7 +58,8 @@
  * will lead to undefined behaviour.
  */
 // TODO(ajohnsen): make this transformer reusable?
-class _WebSocketProtocolTransformer implements StreamTransformer, EventSink {
+class _WebSocketProtocolTransformer
+    implements StreamTransformer<List<int>, dynamic>, EventSink<List<int>> {
   static const int START = 0;
   static const int LEN_FIRST = 1;
   static const int LEN_REST = 2;
@@ -114,7 +115,8 @@
   /**
    * Process data received from the underlying communication channel.
    */
-  void add(Uint8List buffer) {
+  void add(List<int> bytes) {
+    var buffer = bytes is Uint8List ? bytes : new Uint8List.fromList(bytes);
     int index = 0;
     int lastIndex = buffer.length;
     if (_state == CLOSED) {
@@ -626,9 +628,10 @@
 }
 
 // TODO(ajohnsen): Make this transformer reusable.
-class _WebSocketOutgoingTransformer implements StreamTransformer, EventSink {
+class _WebSocketOutgoingTransformer
+    implements StreamTransformer<dynamic, List<int>>, EventSink {
   final _WebSocketImpl webSocket;
-  EventSink _eventSink;
+  EventSink<List<int>> _eventSink;
 
   _WebSocketPerMessageDeflate _deflateHelper;
 
@@ -636,8 +639,8 @@
     _deflateHelper = webSocket._deflate;
   }
 
-  Stream bind(Stream stream) {
-    return new Stream.eventTransformed(stream, (EventSink eventSink) {
+  Stream<List<int>> bind(Stream stream) {
+    return new Stream.eventTransformed(stream, (eventSink) {
       if (_eventSink != null) {
         throw new StateError("WebSocket transformer already used");
       }
@@ -662,11 +665,12 @@
         opcode = _WebSocketOpcode.TEXT;
         data = UTF8.encode(message);
       } else {
-        if (message is! List<int>) {
+        if (message is List<int>) {
+          data = message;
+          opcode = _WebSocketOpcode.BINARY;
+        } else {
           throw new ArgumentError(message);
         }
-        opcode = _WebSocketOpcode.BINARY;
-        data = message;
       }
 
       if (_deflateHelper != null) {
@@ -708,7 +712,7 @@
         _eventSink.add(e);
       });
 
-  static Iterable createFrame(
+  static Iterable<List<int>> createFrame(
       int opcode, List<int> data, bool serverSide, bool compressed) {
     bool mask = !serverSide; // Masking not implemented for server.
     int dataLength = data == null ? 0 : data.length;
@@ -1218,7 +1222,7 @@
 
   Map _toJSON(bool ref) {
     var name = '${_socket.address.host}:${_socket.port}';
-    var r = {
+    var r = <String, dynamic>{
       'id': _servicePath,
       'type': _serviceType(ref),
       'name': name,
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index fa1267b..aa0daa9 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -31,6 +31,8 @@
 # co19 issue #615: Expect import missing
 LibTest/collection/LinkedList/LinkedList_A01_t01: Fail, OK
 
+Language/Generics/syntax_t04: StaticWarning # co19 issue #56
+
 LibTest/isolate/IsolateStream/any_A01_t01: Fail # co19-roll r706: Please triage this failure.
 LibTest/isolate/IsolateStream/asBroadcastStream_A01_t01: Fail # co19-roll r706: Please triage this failure.
 LibTest/isolate/IsolateStream/contains_A01_t01: Fail # co19-roll r706: Please triage this failure.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index f8105cc..d12cbfc 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -658,40 +658,18 @@
 LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Pass, Timeout # Please triage this failure
 LayoutTests/fast/canvas/webgl/css-webkit-canvas-repaint_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/css-webkit-canvas_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgb565_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba4444_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-rgba5551_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-input-validation_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/texture-transparent-pixels-initialized_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/uniform-location_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/uninitialized-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-depth-texture_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-large-texture_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/webgl-layer-update_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/css/background-clip-text_t01: RuntimeError # Issue 54
 LayoutTests/fast/css-generated-content/hit-test-generated-content_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css-generated-content/malformed-url_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/css-generated-content/pseudo-animation-before-onload_t01: Pass, RuntimeError # Please triage this failure
@@ -919,6 +897,7 @@
 LayoutTests/fast/dom/SelectorAPI/dumpNodeList_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/StyleSheet/css-medialist-item_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/StyleSheet/detached-parent-rule-without-wrapper_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/StyleSheet/detached-stylesheet-without-wrapper_t01: RuntimeError # Issue 55
 LayoutTests/fast/dom/TreeWalker/TreeWalker-basic_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Window/getMatchedCSSRules-nested-rules_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Window/getMatchedCSSRules-with-pseudo-elements-complex_t01: RuntimeError # Please triage this failure
@@ -949,6 +928,7 @@
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl-doesnt-fire-onscroll_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-in-rtl_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/horizontal-scrollbar-when-dir-change_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/icon-size-property_t01: RuntimeError # https://github.com/dart-lang/sdk/issues/26422
 LayoutTests/fast/dom/location-hash_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # API not supported.
 LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
@@ -1607,6 +1587,9 @@
 LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/drawingbuffer-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/error-reporting_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-bindings-unaffected-on-resize_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-object-attachment_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/framebuffer-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/functions-returning-strings_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/get-active-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-bind-attrib-location-test_t01: RuntimeError # Please triage this failure
@@ -1615,8 +1598,11 @@
 LayoutTests/fast/canvas/webgl/gl-get-calls_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-getshadersource_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-getstring_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/invalid-passed-params_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/object-deletion-behaviour_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-object-get-calls_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-pixelstorei_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/gl-teximage_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-uniformmatrix4fv_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-vertex-attrib-zero-issues_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/gl-vertex-attrib_t01: RuntimeError # Please triage this failure
@@ -1642,9 +1628,26 @@
 LayoutTests/fast/canvas/webgl/renderbuffer-initialization_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/renderer-and-vendor-strings_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/shader-precision-format_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-array-buffer-view_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-canvas_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-image-data_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgb565_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba4444_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video-rgba5551_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-image-and-sub-image-2d-with-video_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-and-uniform-binding-bugs_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/tex-image-webgl_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d-bad-args_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-2d_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/tex-sub-image-cube-maps_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/texImage2DImageDataTest_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/texImageTest_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/texture-active-bind_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/texture-bindings-uneffected-on-resize_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/texture-color-profile_t01: RuntimeError # Please triage this failure
diff --git a/tests/compiler/dart2js/analyze_only_test.dart b/tests/compiler/dart2js/analyze_only_test.dart
index 2d771fb..e0a9948 100644
--- a/tests/compiler/dart2js/analyze_only_test.dart
+++ b/tests/compiler/dart2js/analyze_only_test.dart
@@ -12,8 +12,8 @@
 import '../../utils/dummy_compiler_test.dart' as dummy;
 import 'package:compiler/compiler.dart';
 import 'package:compiler/src/commandline_options.dart';
-import 'package:compiler/src/diagnostics/messages.dart' show
-    MessageKind, MessageTemplate;
+import 'package:compiler/src/diagnostics/messages.dart'
+    show MessageKind, MessageTemplate;
 
 import 'output_collector.dart';
 
@@ -175,12 +175,31 @@
     });
 
   // --analyze-signatures-only implies --analyze-only
+  runCompiler("", [Flags.analyzeSignaturesOnly, Flags.analyzeAll],
+      (String code, List errors, List warnings) {
+    Expect.isNull(code);
+    Expect.isTrue(errors.isEmpty);
+    Expect.isTrue(warnings.isEmpty);
+  });
+
+  // Test that --allow-native-extensions works.
   runCompiler(
-    "",
-    [Flags.analyzeSignaturesOnly, Flags.analyzeAll],
-    (String code, List errors, List warnings) {
-      Expect.isNull(code);
-      Expect.isTrue(errors.isEmpty);
-      Expect.isTrue(warnings.isEmpty);
-    });
+      """main() {}
+      foo() native 'foo';""",
+      [Flags.analyzeOnly, Flags.allowNativeExtensions],
+      (String code, List errors, List warnings) {
+    Expect.isNull(code);
+    Expect.isTrue(errors.isEmpty);
+    Expect.isTrue(warnings.isEmpty);
+  });
+  runCompiler(
+      """main() {}
+      foo() native 'foo';""",
+      [Flags.analyzeOnly],
+      (String code, List errors, List warnings) {
+    Expect.isNull(code);
+    Expect.isTrue(
+        errors.single.startsWith("'native' modifier is not supported."));
+    Expect.isTrue(warnings.isEmpty);
+  });
 }
diff --git a/tests/compiler/dart2js/error_token_test.dart b/tests/compiler/dart2js/error_token_test.dart
new file mode 100644
index 0000000..2000f1a
--- /dev/null
+++ b/tests/compiler/dart2js/error_token_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// Test that we don't report invalid modifier on error tokens.
+
+library dart2js.test.error_token;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import "package:compiler/src/diagnostics/messages.dart";
+import 'package:expect/expect.dart';
+import 'memory_compiler.dart';
+
+Future runTest(String code, {MessageKind error}) async {
+  DiagnosticCollector diagnostics = new DiagnosticCollector();
+  OutputCollector output = new OutputCollector();
+  await runCompiler(
+      entryPoint: Uri.parse('memory:main.dart'),
+      memorySourceFiles: {'main.dart': code},
+      diagnosticHandler: diagnostics,
+      outputProvider: output);
+
+  Expect.equals(error != null ? 1 : 0, diagnostics.errors.length);
+  if (error != null) {
+    Expect.equals(error, diagnostics.errors.first.message.kind);
+  }
+  Expect.equals(0, diagnostics.warnings.length);
+  Expect.equals(0, diagnostics.hints.length);
+  Expect.equals(0, diagnostics.infos.length);
+}
+
+void main() {
+  asyncTest(() async {
+    await runTest('''
+main() {}
+class Foo {
+	static void bar() {
+		baz());
+	}
+}
+''', error: MessageKind.UNMATCHED_TOKEN);
+
+    await runTest('''
+main() {}
+class C {
+  C(v) {
+    throw '');
+  }
+}''', error: MessageKind.UNMATCHED_TOKEN);
+  });
+}
diff --git a/tests/compiler/dart2js/generic_method_type_usage_test.dart b/tests/compiler/dart2js/generic_method_type_usage_test.dart
new file mode 100644
index 0000000..9ec4fbe
--- /dev/null
+++ b/tests/compiler/dart2js/generic_method_type_usage_test.dart
@@ -0,0 +1,115 @@
+// 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.
+
+/// Dart test verifying that method type variables are considered to denote
+/// the type `dynamic`.
+///
+/// NB: This test is intended to succeed with a `dart2js` with the option
+/// '--generic-method-syntax', but it should fail with a full implementation
+/// of generic method support, and it should fail with every other tool than
+/// `dart2js`.
+
+library dart2js.test.generic_method_type_usage;
+
+import 'dart:async';
+import 'package:async_helper/async_helper.dart';
+import "package:compiler/src/diagnostics/messages.dart";
+import 'package:expect/expect.dart';
+import 'memory_compiler.dart';
+
+const MEMORY_SOURCE_FILES = const {
+  'type_variable_is_dynamic.dart': '''
+class C {
+  bool aMethod<X>(X x) {
+    // `dynamic` is assignable to both `int` and `String`: no warnings.
+    int i = x;
+    String s = x;
+    try {
+      // Only `dynamic` allows unknown member lookup without a warning.
+      var y = x.undefinedMember;
+    } on NoSuchMethodError catch (_) {
+      return true;
+    }
+    return false;
+  }
+}
+
+bool aFunction<X>(X x) {
+  // `dynamic` is assignable to both `int` and `String`: no warnings.
+  int i = x;
+  String s = x;
+  try {
+    // Only `dynamic` allows unknown member lookup without a warning.
+    var y = x.undefinedMember;
+  } on NoSuchMethodError catch (_) {
+    return true;
+  }
+  return false;
+}
+
+main() {
+  print(new C().aMethod<Set>(null));
+  print(aFunction<Set>(null));
+}
+''',
+
+  'cannot_new_method_type_variable.dart': '''
+class C {
+  X aMethod<X>() => new X();
+}
+
+main() {
+  new C().aMethod<Set>();
+}
+''',
+
+  'cannot_new_function_type_variable.dart': '''
+X aFunction<X>() => new X(42);
+
+main() {
+  aFunction<Set>();
+}
+''',
+};
+
+
+Future runTest(Uri main, {MessageKind warning, MessageKind info}) async {
+  print("----\nentry-point: $main\n");
+
+  DiagnosticCollector diagnostics = new DiagnosticCollector();
+  OutputCollector output = new OutputCollector();
+  await runCompiler(
+      entryPoint: main,
+      options: const <String>["--generic-method-syntax"],
+      memorySourceFiles: MEMORY_SOURCE_FILES,
+      diagnosticHandler: diagnostics,
+      outputProvider: output);
+
+  Expect.isFalse(output.hasExtraOutput);
+  Expect.equals(0, diagnostics.errors.length);
+  Expect.equals(warning != null ? 1 : 0, diagnostics.warnings.length);
+  if (warning != null) {
+    Expect.equals(warning, diagnostics.warnings.first.message.kind);
+  }
+  Expect.equals(info != null ? 1 : 0, diagnostics.infos.length);
+  if (info != null) {
+    Expect.equals(info, diagnostics.infos.first.message.kind);
+  }
+  Expect.equals(0, diagnostics.hints.length);
+}
+
+void main() {
+  asyncTest(() async {
+    await runTest(
+        Uri.parse('memory:type_variable_is_dynamic.dart'));
+
+    await runTest(
+        Uri.parse('memory:cannot_new_method_type_variable.dart'),
+        warning: MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE);
+
+    await runTest(
+        Uri.parse('memory:cannot_new_function_type_variable.dart'),
+        warning: MessageKind.CANNOT_INSTANTIATE_TYPE_VARIABLE);
+  });
+}
diff --git a/tests/compiler/dart2js/serialization/helper.dart b/tests/compiler/dart2js/serialization/helper.dart
index c7719b3..095915b 100644
--- a/tests/compiler/dart2js/serialization/helper.dart
+++ b/tests/compiler/dart2js/serialization/helper.dart
@@ -103,11 +103,14 @@
   assert(compiler.serialization.supportSerialization);
 
   Serializer serializer = new Serializer();
-  serializer.plugins.add(compiler.backend.serialization.serializer);
-  serializer.plugins.add(new ResolutionImpactSerializer(compiler.resolution));
+  SerializerPlugin backendSerializer =
+      compiler.backend.serialization.serializer;
+  serializer.plugins.add(backendSerializer);
+  serializer.plugins.add(new ResolutionImpactSerializer(
+      compiler.resolution, backendSerializer));
   if (serializeResolvedAst) {
-    serializer.plugins.add(
-        new ResolvedAstSerializerPlugin(compiler.resolution, compiler.backend));
+    serializer.plugins.add(new ResolvedAstSerializerPlugin(
+        compiler.resolution, backendSerializer));
   }
 
   for (LibraryElement library in libraries) {
@@ -137,28 +140,34 @@
 
 class ResolutionImpactSerializer extends SerializerPlugin {
   final Resolution resolution;
+  final SerializerPlugin nativeDataSerializer;
 
-  ResolutionImpactSerializer(this.resolution);
+  ResolutionImpactSerializer(this.resolution, this.nativeDataSerializer);
 
   @override
   void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
     if (resolution.hasBeenResolved(element)) {
       ResolutionImpact impact = resolution.getResolutionImpact(element);
       ObjectEncoder encoder = createEncoder(WORLD_IMPACT_TAG);
-      new ImpactSerializer(element, encoder).serialize(impact);
+      new ImpactSerializer(element, encoder, nativeDataSerializer)
+          .serialize(impact);
     }
   }
 }
 
 class ResolutionImpactDeserializer extends DeserializerPlugin {
   Map<Element, ResolutionImpact> impactMap = <Element, ResolutionImpact>{};
+  final DeserializerPlugin nativeDataDeserializer;
+
+  ResolutionImpactDeserializer(this.nativeDataDeserializer);
 
   @override
   void onElement(Element element, ObjectDecoder getDecoder(String tag)) {
     ObjectDecoder decoder = getDecoder(WORLD_IMPACT_TAG);
     if (decoder != null) {
       impactMap[element] =
-          ImpactDeserializer.deserializeImpact(element, decoder);
+          ImpactDeserializer.deserializeImpact(
+              element, decoder, nativeDataDeserializer);
     }
   }
 }
@@ -167,34 +176,53 @@
   final Compiler _compiler;
   final Deserializer _deserializer;
   final List<LibraryElement> deserializedLibraries = <LibraryElement>[];
-  final ResolutionImpactDeserializer _resolutionImpactDeserializer =
-      new ResolutionImpactDeserializer();
+  final ResolutionImpactDeserializer _resolutionImpactDeserializer;
   final ResolvedAstDeserializerPlugin _resolvedAstDeserializer;
   final ImpactTransformer _impactTransformer;
-  final bool _deserializeResolvedAst;
+  final bool deserializeResolvedAst;
 
-  _DeserializerSystem(
+  factory _DeserializerSystem(
       Compiler compiler,
+      Deserializer deserializer,
+      ImpactTransformer impactTransformer,
+      {bool deserializeResolvedAst: false}) {
+    List<DeserializerPlugin> plugins = <DeserializerPlugin>[];
+    DeserializerPlugin backendDeserializer =
+        compiler.backend.serialization.deserializer;
+    deserializer.plugins.add(backendDeserializer);
+    ResolutionImpactDeserializer resolutionImpactDeserializer =
+        new ResolutionImpactDeserializer(backendDeserializer);
+    deserializer.plugins.add(resolutionImpactDeserializer);
+    ResolvedAstDeserializerPlugin resolvedAstDeserializer;
+    if (deserializeResolvedAst) {
+      resolvedAstDeserializer = new ResolvedAstDeserializerPlugin(
+          compiler.parsingContext, backendDeserializer);
+      deserializer.plugins.add(resolvedAstDeserializer);
+    }
+    return new _DeserializerSystem._(
+        compiler,
+        deserializer,
+        impactTransformer,
+        resolutionImpactDeserializer,
+        resolvedAstDeserializer,
+        deserializeResolvedAst: deserializeResolvedAst);
+  }
+
+  _DeserializerSystem._(
+      this._compiler,
       this._deserializer,
       this._impactTransformer,
-      {bool deserializeResolvedAst: false})
-      : this._compiler = compiler,
-        this._deserializeResolvedAst = deserializeResolvedAst,
-        this._resolvedAstDeserializer = deserializeResolvedAst
-           ? new ResolvedAstDeserializerPlugin(
-               compiler.parsingContext, compiler.backend) : null {
-    _deserializer.plugins.add(_resolutionImpactDeserializer);
-    if (_deserializeResolvedAst) {
-      _deserializer.plugins.add(_resolvedAstDeserializer);
-    }
-  }
+      this._resolutionImpactDeserializer,
+      this._resolvedAstDeserializer,
+      {this.deserializeResolvedAst: false});
+
 
   @override
   Future<LibraryElement> readLibrary(Uri resolvedUri) {
     LibraryElement library = _deserializer.lookupLibrary(resolvedUri);
     if (library != null) {
       deserializedLibraries.add(library);
-      if (_deserializeResolvedAst) {
+      if (deserializeResolvedAst) {
         return Future.forEach(library.compilationUnits,
             (CompilationUnitElement compilationUnit) {
           ScriptZ script = compilationUnit.script;
@@ -274,9 +302,9 @@
 
 class ResolvedAstSerializerPlugin extends SerializerPlugin {
   final Resolution resolution;
-  final Backend backend;
+  final SerializerPlugin nativeDataSerializer;
 
-  ResolvedAstSerializerPlugin(this.resolution, this.backend);
+  ResolvedAstSerializerPlugin(this.resolution, this.nativeDataSerializer);
 
   @override
   void onElement(Element element, ObjectEncoder createEncoder(String tag)) {
@@ -290,14 +318,14 @@
       new ResolvedAstSerializer(
           objectEncoder,
           resolvedAst,
-          backend.serialization.serializer).serialize();
+          nativeDataSerializer).serialize();
     }
   }
 }
 
 class ResolvedAstDeserializerPlugin extends DeserializerPlugin {
   final ParsingContext parsingContext;
-  final Backend backend;
+  final DeserializerPlugin nativeDataDeserializer;
   final Map<Uri, SourceFile> sourceFiles = <Uri, SourceFile>{};
 
   Map<ExecutableElement, ResolvedAst> _resolvedAstMap =
@@ -306,7 +334,8 @@
       <MemberElement, ObjectDecoder>{};
   Map<Uri, Token> beginTokenMap = <Uri, Token>{};
 
-  ResolvedAstDeserializerPlugin(this.parsingContext, this.backend);
+  ResolvedAstDeserializerPlugin(
+      this.parsingContext, this.nativeDataDeserializer);
 
   bool hasResolvedAst(ExecutableElement element) {
     return _resolvedAstMap.containsKey(element) ||
@@ -320,7 +349,7 @@
       if (decoder != null) {
          ResolvedAstDeserializer.deserialize(
              element.memberContext, decoder, parsingContext, findToken,
-             backend.serialization.deserializer,
+             nativeDataDeserializer,
              _resolvedAstMap);
         _decoderMap.remove(element);
         resolvedAst = _resolvedAstMap[element];
diff --git a/tests/compiler/dart2js/serialization/model_test.dart b/tests/compiler/dart2js/serialization/model_test.dart
index 66ac6c5..0229b02 100644
--- a/tests/compiler/dart2js/serialization/model_test.dart
+++ b/tests/compiler/dart2js/serialization/model_test.dart
@@ -95,8 +95,6 @@
       compilerDeserialized.resolverWorld.instantiatedTypes,
       "Instantiated types mismatch",
       areTypesEquivalent,
-      // TODO(johnniwinther): Ensure that all instantiated types are tracked.
-      failOnUnfound: false,
       verbose: verbose);
 
   checkSets(
diff --git a/tests/compiler/dart2js/serialization/test_helper.dart b/tests/compiler/dart2js/serialization/test_helper.dart
index 1a05c98..d753b53 100644
--- a/tests/compiler/dart2js/serialization/test_helper.dart
+++ b/tests/compiler/dart2js/serialization/test_helper.dart
@@ -21,7 +21,7 @@
 import 'package:compiler/src/serialization/equivalence.dart';
 import 'package:compiler/src/serialization/json_serializer.dart';
 import 'package:compiler/src/serialization/serialization.dart';
-
+import 'package:compiler/src/tree/nodes.dart';
 
 /// Strategy for checking equivalence.
 ///
@@ -97,6 +97,13 @@
       List<ConstantExpression> list2) {
     return checkConstantLists(object1, object2, property, list1, list2);
   }
+
+  @override
+  bool testNodes(Object object1, Object object2, String property,
+      Node node1, Node node2) {
+    return new NodeEquivalenceVisitor(this).testNodes(
+        object1, object2, property, node1, node2);
+  }
 }
 
 /// Check that the values [property] of [object1] and [object2], [value1] and
diff --git a/tests/compiler/dart2js_extra/dart2js_extra.status b/tests/compiler/dart2js_extra/dart2js_extra.status
index bde5681..897d5b3 100644
--- a/tests/compiler/dart2js_extra/dart2js_extra.status
+++ b/tests/compiler/dart2js_extra/dart2js_extra.status
@@ -53,7 +53,7 @@
 bailout8_test: Fail, OK # Mismatch in thrown exception.
 
 [ $compiler == dart2js && $runtime == d8 && $system == windows ]
-deferred/*: Skip # Issue 17458
+deferred/*: Pass,RuntimeError # Issue 17458
 
 [ $compiler == dart2js && $csp ]
 deferred_fail_and_retry_test: SkipByDesign # Uses eval to simulate failed loading.
diff --git a/tests/compiler/dart2js_extra/deferred/deferred_constant_dependency_evaluation_test.dart b/tests/compiler/dart2js_extra/deferred/deferred_constant_dependency_evaluation_test.dart
new file mode 100644
index 0000000..49d9558
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred/deferred_constant_dependency_evaluation_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// This is a regression test for dartbug.com/26406. We test that the deferred
+// loader analyzer doesn't trip over constant expression evaluation.
+//
+// Today the task uses constant values to calculate dependencies, and only uses
+// those values that were previously computed by resolution. A change to compute
+// the value on-demmand made the deferred task evaluate more expressions,
+// including expressions with free variables (which can't be evaluated). See the
+// dartbug.com/26406 for details on how we plan to make the task more robust.
+
+// import is only used to trigger the deferred task
+import 'deferred_class_library.dart' deferred as lib;
+
+class A {
+  final int x;
+
+  const A(bool foo)
+      // The deferred task would crash trying to compute the value here, where
+      // [foo] is a free variable.
+      : x = foo ? 1 : 0;
+}
+
+main() => const A(true);
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 60a6bc5..62f45da 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -139,7 +139,7 @@
 from_environment_const_type_undefined_test/16: CompileTimeError
 
 [ $compiler == dart2analyzer ]
-int_parse_radix_test: fail
+int_parse_radix_bad_handler_test: fail
 list_insert_test: fail
 list_removeat_test: fail
 hash_set_type_check_test: StaticWarning, OK # Tests failing type tests.
diff --git a/tests/corelib/int_parse_radix_bad_handler_test.dart b/tests/corelib/int_parse_radix_bad_handler_test.dart
new file mode 100644
index 0000000..58009fa
--- /dev/null
+++ b/tests/corelib/int_parse_radix_bad_handler_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2012, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import "package:expect/expect.dart";
+
+void main() {
+  // If handleError isn't an unary function, and it's called, it also throws
+  // (either TypeError in checked mode, or some failure in unchecked mode).
+
+  // These are compile time errors for strong mode.
+  Expect.throws(() => int.parse("9", radix: 8, onError: "not a function"));
+  Expect.throws(() => int.parse("9", radix: 8, onError: () => 42));
+  Expect.throws(() => int.parse("9", radix: 8, onError: (v1, v2) => 42));
+}
diff --git a/tests/corelib/int_parse_radix_test.dart b/tests/corelib/int_parse_radix_test.dart
index fbe9205..03af528 100644
--- a/tests/corelib/int_parse_radix_test.dart
+++ b/tests/corelib/int_parse_radix_test.dart
@@ -7,7 +7,7 @@
 
 void main() {
   bool checkedMode = false;
-  assert(checkedMode = true);
+  assert((checkedMode = true));
   const String oneByteWhiteSpace = "\x09\x0a\x0b\x0c\x0d\x20"
     "\x85"    /// 01: ok
     "\xa0";
@@ -116,7 +116,7 @@
     }
     // In checked mode, it's always a TypeError.
     Expect.throws(() => int.parse(source, radix: radix, onError: (s) => 0),
-                  (e) => e is TypeError);
+                  (e) => e is TypeError || e is CastError);
   }
 
   testBadTypes(9, 10);
@@ -135,11 +135,7 @@
   testBadArguments("0", 1);
   testBadArguments("0", 37);
 
-  // If handleError isn't an unary function, and it's called, it also throws
-  // (either TypeError in checked mode, or some failure in unchecked mode).
-  Expect.throws(() => int.parse("9", radix: 8, onError: "not a function"));
-  Expect.throws(() => int.parse("9", radix: 8, onError: () => 42));
-  Expect.throws(() => int.parse("9", radix: 8, onError: (v1, v2) => 42));
+  // See also int_parse_radix_bad_handler_test.dart
 }
 
 bool isFail(e) => e == "FAIL";
diff --git a/tests/corelib/string_operations_with_null_test.dart b/tests/corelib/string_operations_with_null_test.dart
index 7288001..cac0c7c 100644
--- a/tests/corelib/string_operations_with_null_test.dart
+++ b/tests/corelib/string_operations_with_null_test.dart
@@ -3,11 +3,10 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import "package:expect/expect.dart";
-import "../language/compiler_annotations.dart";
 
-@DontInline()
+@NoInline()
+@AssumeDynamic()
 returnStringOrNull() {
-  () => 42;
   return new DateTime.now().millisecondsSinceEpoch == 0 ? 'foo' : null;
 }
 
diff --git a/tests/language/async_return_types_test.dart b/tests/language/async_return_types_test.dart
index 1134e25..f8d194d 100644
--- a/tests/language/async_return_types_test.dart
+++ b/tests/language/async_return_types_test.dart
@@ -14,7 +14,7 @@
   return 3;
 }
 
-Future<int> /// wrongTypeParameter: static type warning
+Future<int> /// wrongTypeParameter: static type warning, dynamic type error
 foo3() async {
   return "String";
 }
@@ -35,7 +35,7 @@
   return new Future<int>.value(3);
 }
 
-Future<Future<int>> /// nestedFuture: static type warning
+Future<Future<int>> /// nestedFuture: static type warning, dynamic type error
 foo7() async {
   return new Future<int>.value(3);
 }
diff --git a/tests/language/generic_functions_test.dart b/tests/language/generic_functions_test.dart
index 814163a..e3f6caf 100644
--- a/tests/language/generic_functions_test.dart
+++ b/tests/language/generic_functions_test.dart
@@ -55,19 +55,16 @@
   }
 }
 
-// Use fresh type variables.
 BinaryTreeNode<K2, V2> insertOpt<K2 extends Comparable<K2>, V2>(
     BinaryTreeNode<K2, V2> t, K2 key, V2 value) {
   return (t == null) ? new BinaryTreeNode(key, value) : t.insert(key, value);
 }
 
-// Reuse type variables [K], [V] to test shadowing.
 BinaryTreeNode<K, U> mapOpt<K extends Comparable<K>, V, U>(
     BinaryTreeNode<K, V> t, U f(V x)) {
   return (t == null) ? null : t.map<U>(f);
 }
 
-// Use fresh [K2], shadowing [V].
 S foldPreOpt<K2 extends Comparable<K2>, V, S>(
     BinaryTreeNode<K2, V> t, S init, S f(V t, S s)) {
   return (t == null) ? init : t.foldPre<S>(init, f);
diff --git a/tests/language/language.status b/tests/language/language.status
index ca50f91..5eacbfa 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -49,6 +49,7 @@
 generic_functions_test: CompiletimeError # Issue 25869
 generic_local_functions_test: CompiletimeError # Issue 25869
 generic_sends_test: CompiletimeError # Issue 25869
+generic_method_type_usage_test: CompiletimeError # Tests --generic-method-syntax, plus issue 25869
 
 [ ($compiler == none || $compiler == precompiler || $compiler == dart2app) && ($runtime == vm || $runtime == dart_precompiled || $runtime == dart_product) ]
 
@@ -94,6 +95,7 @@
 generic_functions_test: RuntimeError # Issue 25869
 generic_local_functions_test: RuntimeError # Issue 25869
 generic_sends_test: RuntimeError # Issue 25869
+generic_method_type_usage_test: CompiletimeError # Tests --generic-method-syntax, plus issue 25869
 config_import_test: Skip  # Issue 26250
 
 [ $compiler == none && $runtime == dartium && $system == linux && $arch != x64 ]
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index a588be3..9cc27c9 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -491,23 +491,6 @@
 mixin_supertype_subclass4_test/04: MissingStaticWarning # Issue 25614
 mixin_supertype_subclass4_test/05: MissingStaticWarning # Issue 25614
 
-mixin_of_mixin_test/01: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/02: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/04: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/05: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/06: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/08: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/09: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/10: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/12: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/13: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/15: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/16: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/17: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/19: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/20: MissingStaticWarning # Issue 25605
-mixin_of_mixin_test/21: MissingStaticWarning # Issue 25605
-
 accessor_conflict_export2_test: StaticWarning # Issue 25624
 accessor_conflict_export_test: StaticWarning # Issue 25624
 accessor_conflict_import2_test: StaticWarning # Issue 25624
@@ -523,3 +506,4 @@
 generic_local_functions_test: CompileTimeError # Issue 25868
 generic_methods_test: CompileTimeError # Issue 25868
 generic_sends_test: CompileTimeError # Issue 25868
+generic_method_type_usage_test: CompiletimeError # Tests --generic-method-syntax, plus issue 25868
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index 4a95853..025d91a 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -40,6 +40,7 @@
 generic_local_functions_test: CompileTimeError # Issue 25835
 generic_methods_test: CompileTimeError # Issue 25835
 generic_sends_test: CompileTimeError # Issue 25835
+generic_method_type_usage_test: CompiletimeError # Tests --generic-method-syntax, plus issue 25835
 
 [ $compiler == dart2js && $runtime == jsshell ]
 await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
@@ -112,6 +113,9 @@
 multiline_newline_test/none: RuntimeError # Issue 23888
 
 [ $compiler == dart2js && $checked ]
+async_return_types_test/nestedFuture: Fail # Issue 26429
+async_return_types_test/wrongTypeParameter: Fail # Issue 26429
+regress_26133_test: RuntimeError # Issue 26429
 type_variable_bounds_test/02: Fail # Issue 12702
 type_variable_bounds2_test/01: Fail # Issue 12702
 type_variable_bounds2_test/04: Fail # Issue 12702
diff --git a/tests/language/mixin_of_mixin_test.dart b/tests/language/mixin_of_mixin_test.dart
index 005f959..a15b20c 100644
--- a/tests/language/mixin_of_mixin_test.dart
+++ b/tests/language/mixin_of_mixin_test.dart
@@ -34,26 +34,27 @@
 class T6 extends D with M3 {} // extends a class which declares m3()
 
 main() {
+  /// none: static type warning, ok
   new T1().a();  /// 01: static type warning, runtime error
   new T1().b();  /// 02: static type warning, runtime error
-  new T1().c();  /// 03: ok
+  new T1().c();  /// 03: static type warning, ok
   new T2().a();  /// 04: static type warning, runtime error
   new T2().b();  /// 05: static type warning, runtime error
   new T2().c();  /// 06: static type warning, runtime error
-  new T2().m2(); /// 07: ok
+  new T2().m2(); /// 07: static type warning, ok
   new T3().a();  /// 08: static type warning, runtime error
   new T3().b();  /// 09: static type warning, runtime error
   new T3().c();  /// 10: static type warning, runtime error
-  new T3().m3(); /// 11: ok
+  new T3().m3(); /// 11: static type warning, ok
   new T4().a();  /// 12: static type warning, runtime error
   new T4().b();  /// 13: static type warning, runtime error
-  new T4().c();  /// 14: ok
+  new T4().c();  /// 14: static type warning, ok
   new T5().a();  /// 15: static type warning, runtime error
   new T5().b();  /// 16: static type warning, runtime error
   new T5().c();  /// 17: static type warning, runtime error
-  new T5().m2(); /// 18: ok
+  new T5().m2(); /// 18: static type warning, ok
   new T6().a();  /// 19: static type warning, runtime error
   new T6().b();  /// 20: static type warning, runtime error
   new T6().c();  /// 21: static type warning, runtime error
-  new T6().m3(); /// 22: ok
+  new T6().m3(); /// 22: static type warning, ok
 }
diff --git a/tests/language/regress_26133_test.dart b/tests/language/regress_26133_test.dart
new file mode 100644
index 0000000..9c6bbb5
--- /dev/null
+++ b/tests/language/regress_26133_test.dart
@@ -0,0 +1,34 @@
+// 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:async';
+import 'package:expect/expect.dart';
+
+isCheckedMode() {
+  try {
+    var i = 1;
+    String s = i;
+    return false;
+  } on TypeError {
+    return true;
+  }
+}
+
+var x = 'a';
+
+Future<int> foo() async {
+  return x;
+}
+
+main() {
+  foo().then(
+    (_) {
+      Expect.isFalse(isCheckedMode());
+    },
+    onError: (e) {
+      Expect.isTrue(isCheckedMode() && (e is TypeError));
+    }
+  );
+}
+
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index c0a201e..ec94cf6 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -294,8 +294,8 @@
 mirrors/regress_16321_test/01: MissingCompileTimeError # Issue 16391
 
 [ $compiler == dart2js && $runtime == d8 && $system == windows ]
-async/*deferred*: Skip # Issue 17458
-mirrors/*deferred*: Skip # Issue 17458
+async/*deferred*: Pass,RuntimeError # Issue 17458
+mirrors/*deferred*: Pass,RuntimeError # Issue 17458
 
 [ $compiler == dart2js && $mode == debug ]
 mirrors/native_class_test: Pass, Slow
diff --git a/tests/standalone/io/code_collection_test.dart b/tests/standalone/io/code_collection_test.dart
index 696be6e..3747399 100644
--- a/tests/standalone/io/code_collection_test.dart
+++ b/tests/standalone/io/code_collection_test.dart
@@ -11,6 +11,9 @@
 
 int foo(int x) {
   x = x + 1;
+  // Print marker message while foo is on the stack so the code cannot be
+  // collected.
+  print("foo=$x");
   return x;
 }
 
@@ -25,18 +28,18 @@
 doTest() {
   var i = 0;
   var ret = foo(1);  // Initial call to compile.
-  print("foo=$ret");
   // Time passes, GC runs, foo's code is dropped.
   var ms = const Duration(milliseconds: 100);
   var t = new Timer.periodic(ms, (timer) {
     i++;
+    // Calling bar will trigger GC without foo being on the stack. This way
+    // the method can be collected.
     bar();
     if (i > 1) {
       timer.cancel();
       // foo is called again to make sure we can still run it even after
       // its code has been detached.
       var ret = foo(2);
-      print("foo=$ret");
     }
   });
 }
@@ -48,7 +51,8 @@
   } else {
     // Run the test and capture stdout.
     var pr = Process.runSync(Platform.executable,
-        ["--collect-code",
+        ["--verbose-gc",
+         "--collect-code",
          "--code-collection-interval-in-us=0",
          "--old_gen_growth_rate=10",
          "--log-code-drop",
@@ -61,6 +65,7 @@
 
     // Code drops are logged with --log-code-drop. Look through stdout for the
     // message that foo's code was dropped.
+    print(pr.stdout);
     var count = 0;
     pr.stdout.split("\n").forEach((line) {
       if (line.contains("foo=2")) {
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index adb3a7d..30a1101 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -114,6 +114,7 @@
 
 [ ($runtime == vm || $runtime == dart_product) && ($arch == arm || $arch == arm64) ]
 io/file_stream_test: Skip # Issue 26109
+io/file_typed_data_test: Skip # Issue 26109
 
 [ $compiler == dart2js && $jscl ]
 assert_test: RuntimeError, OK # Assumes unspecified fields on the AssertionError.
diff --git a/tools/VERSION b/tools/VERSION
index ec6b498..ea11638 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 17
 PATCH 0
-PRERELEASE 2
+PRERELEASE 3
 PRERELEASE_PATCH 0
diff --git a/tools/build.py b/tools/build.py
index 4b9df2a..518a015 100755
--- a/tools/build.py
+++ b/tools/build.py
@@ -56,7 +56,7 @@
   result.add_option("-a", "--arch",
       help='Target architectures (comma-separated).',
       metavar='[all,ia32,x64,simarm,arm,simarmv6,armv6,simarmv5te,armv5te,'
-              'simmips,mips,simarm64,arm64,simdbc,]',
+              'simmips,mips,simarm64,arm64,simdbc,armsimdbc]',
       default=utils.GuessArchitecture())
   result.add_option("--os",
     help='Target OSs (comma-separated).',
@@ -88,7 +88,7 @@
 
 def ProcessOptions(options, args):
   if options.arch == 'all':
-    options.arch = 'ia32,x64,simarm,simmips,simarm64'
+    options.arch = 'ia32,x64,simarm,simarm64,simmips,simdbc'
   if options.mode == 'all':
     options.mode = 'debug,release,product'
   if options.os == 'all':
@@ -103,7 +103,7 @@
   for arch in options.arch:
     archs = ['ia32', 'x64', 'simarm', 'arm', 'simarmv6', 'armv6',
              'simarmv5te', 'armv5te', 'simmips', 'mips', 'simarm64', 'arm64',
-             'simdbc', 'simdbc64']
+             'simdbc', 'simdbc64', 'armsimdbc']
     if not arch in archs:
       print "Unknown arch %s" % arch
       return False
@@ -154,7 +154,7 @@
                     'supported on Linux.')
 
   # For ARM Linux, by default use the Linux distribution's cross-compiler.
-  if arch == 'arm':
+  if arch == 'arm' or arch == 'armsimdbc':
     # To use a non-hf compiler, specify on the command line with --toolchain.
     return (DEFAULT_ARM_CROSS_COMPILER_PATH + "/arm-linux-gnueabihf")
   if arch == 'arm64':
diff --git a/tools/deps/dartium.deps/DEPS b/tools/deps/dartium.deps/DEPS
index b7500f2..960cf72 100644
--- a/tools/deps/dartium.deps/DEPS
+++ b/tools/deps/dartium.deps/DEPS
@@ -8,7 +8,7 @@
 # Now we need to override some settings and add some new ones.
 
 vars.update({
-  "dartium_chromium_commit": "18554681ff1dfb53a553375c1b0c641fb3d63a1a",
+  "dartium_chromium_commit": "81ac1404ddd8fde55b9eb28a97c8a6d8b75e264f",
   "dartium_webkit_commit": "ef30dc04127c86283c1f5c5c6b0094d73b1e29df",
   "chromium_base_revision": "338390",
 
diff --git a/tools/gyp/configurations.gypi b/tools/gyp/configurations.gypi
index e5ab11a..29f457e 100644
--- a/tools/gyp/configurations.gypi
+++ b/tools/gyp/configurations.gypi
@@ -387,6 +387,15 @@
         ],
       },
 
+      'ProductSIMDBC': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_simdbc_Base', 'Dart_Product',
+          'Dart_<(dart_target_os)_Base',
+          'Dart_<(dart_target_os)_simdbc_Base',
+          'Dart_<(dart_target_os)_Product',
+        ],
+      },
+
       'DebugSIMDBC64': {
         'inherit_from': [
           'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
@@ -408,6 +417,47 @@
         ],
       },
 
+      'ProductSIMDBC64': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_simdbc_Base', 'Dart_Product',
+          'Dart_<(dart_target_os)_Base',
+          'Dart_<(dart_target_os)_simdbc64_Base',
+          'Dart_<(dart_target_os)_Product',
+        ],
+      },
+
+      # Special Linux-only targets to enable SIMDBC cross compilation for
+      # non-Android ARM devices.
+      'DebugXARMSIMDBC': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_simdbc_Base', 'Dart_Debug',
+          'Dart_Linux_Base',
+          'Dart_Linux_xarm_Base',
+          'Dart_Linux_Debug',
+        ],
+        'defines': [
+          'DEBUG',
+        ],
+      },
+
+      'ReleaseXARMSIMDBC': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_simdbc_Base', 'Dart_Release',
+          'Dart_Linux_Base',
+          'Dart_Linux_xarm_Base',
+          'Dart_Linux_Release',
+        ],
+      },
+
+      'ProductXARMSIMDBC': {
+        'inherit_from': [
+          'Dart_Base', 'Dart_simdbc_Base', 'Dart_Product',
+          'Dart_Linux_Base',
+          'Dart_Linux_xarm_Base',
+          'Dart_Linux_Product',
+        ],
+      },
+
       # ARM and MIPS hardware configurations are only for Linux and Android.
       'DebugXARM': {
         'inherit_from': [
diff --git a/tools/testing/dart/android.dart b/tools/testing/dart/android.dart
index bf83128..615d5b0 100644
--- a/tools/testing/dart/android.dart
+++ b/tools/testing/dart/android.dart
@@ -333,7 +333,10 @@
       if (index >= 0) {
         exitCode = int.parse(
             lines.last.substring(index + MARKER.length).trim());
-        exitCode = exitCode.toSigned(8);
+        if (exitCode > 128 && exitCode <= 128 + 31) {
+          // Return negative exit codes for signals 1..31 (128+N for signal N)
+          exitCode = 128 - exitCode;
+        }
       } else {
         // In case of timeouts, for example, we won't get the exitcode marker.
         assert(result.exitCode != 0);
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 7c0945e..5781e83 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -342,9 +342,10 @@
       Map<String, String> environmentOverrides) {
     var exec = "$buildDir/dart_bootstrap";
     var args = new List();
-    args.add("--gen-precompiled-snapshot=$tempDir");
+    args.add("--snapshot=$tempDir");
+    args.add("--snapshot-kind=app-aot");
     if (useBlobs) {
-      args.add("--use_blobs");
+      args.add("--use-blobs");
     }
     if (isAndroid && arch == 'arm') {
       args.add('--no-sim-use-hardfp');
@@ -375,7 +376,7 @@
       throw "Platform not supported: ${Platform.operatingSystem}";
     }
     if (isAndroid) {
-      // TODO: If we're not using "--use_blobs" we need to use the arm cross
+      // TODO: If we're not using "--use-blobs" we need to use the arm cross
       // compiler instead of just 'gcc' for .
     }
 
@@ -403,7 +404,7 @@
     args.addAll([
       '-o',
       '$tempDir/$libname',
-      '$tempDir/precompiled.S'
+      '$tempDir/snapshot.S'
     ]);
 
     return commandBuilder.getCompilationCommand('assemble', tempDir, !useSdk,
@@ -419,7 +420,7 @@
       List arguments,
       Map<String, String> environmentOverrides) {
     var exec = 'rm';
-    var args = ['$tempDir/precompiled.S'];
+    var args = ['$tempDir/snapshot.S'];
 
     return commandBuilder.getCompilationCommand(
         'remove_assembly',
@@ -490,32 +491,27 @@
       CommandBuilder commandBuilder,
       List arguments,
       Map<String, String> environmentOverrides) {
-    String outputName = computeOutputName(tempDir);
     return new CommandArtifact(<Command>[
-      this.computeCompilationCommand(outputName, buildDir,
+      this.computeCompilationCommand(tempDir, buildDir,
           CommandBuilder.instance, arguments, environmentOverrides)
-    ], outputName, 'application/dart-snapshot');
-  }
-
-  String computeOutputName(String tempDir) {
-    var randName = TestUtils.getRandomNumber().toString();
-    return '$tempDir/test.$randName';
+    ], tempDir, 'application/dart-snapshot');
   }
 
   CompilationCommand computeCompilationCommand(
-      String outputName,
+      String tempDir,
       String buildDir,
       CommandBuilder commandBuilder,
       List arguments,
       Map<String, String> environmentOverrides) {
     var exec = "$buildDir/dart_bootstrap";
     var args = new List();
-    args.add("--full-snapshot-after-run=$outputName");
+    args.add("--snapshot=$tempDir");
+    args.add("--snapshot-kind=app-after-run");
     args.addAll(arguments);
 
     return commandBuilder.getCompilationCommand(
         'dart2snapshot',
-        outputName,
+        tempDir,
         !useSdk,
         bootstrapDependencies(buildDir),
         exec,
diff --git a/tools/testing/dart/runtime_configuration.dart b/tools/testing/dart/runtime_configuration.dart
index b8e9e3d7..67a739a 100644
--- a/tools/testing/dart/runtime_configuration.dart
+++ b/tools/testing/dart/runtime_configuration.dart
@@ -238,7 +238,7 @@
     }
 
     var augmentedArgs = new List();
-    augmentedArgs.add("--run-full-snapshot=${artifact.filename}");
+    augmentedArgs.add("--run-app-snapshot=${artifact.filename}");
     augmentedArgs.addAll(arguments);
 
     return <Command>[
@@ -265,9 +265,9 @@
     }
 
     var augmentedArgs = new List();
-    augmentedArgs.add("--run-precompiled-snapshot=${artifact.filename}");
+    augmentedArgs.add("--run-app-snapshot=${artifact.filename}");
     if (useBlobs) {
-      augmentedArgs.add("--use_blobs");
+      augmentedArgs.add("--use-blobs");
     }
     augmentedArgs.addAll(arguments);
 
diff --git a/tools/testing/dart/test_options.dart b/tools/testing/dart/test_options.dart
index bc83dc0..dfca779 100644
--- a/tools/testing/dart/test_options.dart
+++ b/tools/testing/dart/test_options.dart
@@ -693,7 +693,7 @@
   List<Map> _expandConfigurations(Map configuration) {
     // Expand the pseudo-values such as 'all'.
     if (configuration['arch'] == 'all') {
-      configuration['arch'] = 'ia32,x64,simarm,simarm64,simmips';
+      configuration['arch'] = 'ia32,x64,simarm,simarm64,simmips,simdbc';
     }
     if (configuration['mode'] == 'all') {
       configuration['mode'] = 'debug,release,product';
diff --git a/tools/testing/dart/test_runner.dart b/tools/testing/dart/test_runner.dart
index 8d189ae..d862db5 100644
--- a/tools/testing/dart/test_runner.dart
+++ b/tools/testing/dart/test_runner.dart
@@ -2543,9 +2543,9 @@
     // pushhing it for every single test (this is bad for SSD cycle time, test
     // timing).
     steps.add(() => device.runAdbCommand(
-          ['push', runner, '$devicedir/runner']));
+          ['push', runner, '$devicedir/dart_precompiled_runtime']));
     steps.add(() => device.runAdbShellCommand(
-          ['chmod', '777', '$devicedir/runner']));
+          ['chmod', '777', '$devicedir/dart_precompiled_runtime']));
 
     for (var file in files) {
       steps.add(() => device.runAdbCommand(
@@ -2554,12 +2554,16 @@
 
     if (command.useBlobs) {
       steps.add(() => device.runAdbShellCommand(
-            ['$devicedir/runner', '--run-precompiled-snapshot=$deviceTestDir',
-             '--use_blobs', 'ignored.dart'], timeout: timeoutDuration));
+            ['$devicedir/dart_precompiled_runtime',
+             '--run-app-snapshot=$deviceTestDir',
+             '--use-blobs', 'ignored.dart'],
+            timeout: timeoutDuration));
     } else {
       steps.add(() => device.runAdbShellCommand(
-            ['$devicedir/runner', '--run-precompiled-snapshot=$deviceTestDir',
-             'ignored.dart'], timeout: timeoutDuration));
+            ['$devicedir/dart_precompiled_runtime',
+             '--run-app-snapshot=$deviceTestDir',
+             'ignored.dart'],
+            timeout: timeoutDuration));
     }
 
     var stopwatch = new Stopwatch()..start();
diff --git a/tools/utils.py b/tools/utils.py
index 02fe8ef..c4be5af 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -242,6 +242,7 @@
   'simarm64': 'ia32',
   'simdbc': 'ia32',
   'simdbc64': 'ia32',
+  'armsimdbc': 'arm',
 }
 
 ARCH_GUESS = GuessArchitecture()