Version 1.15.0-dev.1.0

Merge commit '4f392df85ea116029c0c8aecbb68997e4d3c5a5c' into dev
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7702384..045ba6a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,7 +4,7 @@
   * Added `Uri.queryParametersAll` to handle multiple query parameters with
     the same name.
 
-## 1.14.0
+## 1.14.0 - 2016-01-28
 
 ### Core library changes
 * `dart:async`
@@ -49,7 +49,7 @@
     * Added named arguments `packageConfig` and `automaticPackageResolution` to
     the `Isolate.spawnUri` constructor.
 
-[Package Resolution Configuration File]: https://github.com/dart-lang/dart_enhancement_proposals/blob/master/Accepted/0005%20-%20Package%20Specification/DEP-pkgspec.md
+[Package Resolution Configuration]: https://github.com/dart-lang/dart_enhancement_proposals/blob/master/Accepted/0005%20-%20Package%20Specification/DEP-pkgspec.md
 
 ### Tool changes
 
diff --git a/pkg/analysis_server/lib/src/analysis_server.dart b/pkg/analysis_server/lib/src/analysis_server.dart
index f0d7931..73bc612 100644
--- a/pkg/analysis_server/lib/src/analysis_server.dart
+++ b/pkg/analysis_server/lib/src/analysis_server.dart
@@ -9,7 +9,6 @@
 import 'dart:core' hide Resource;
 import 'dart:math' show max;
 
-import 'package:analysis_server/plugin/analysis/resolver_provider.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart' hide Element;
 import 'package:analysis_server/src/analysis_logger.dart';
 import 'package:analysis_server/src/channel/channel.dart';
@@ -24,6 +23,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/ast.dart';
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index d0862f0..2140f7c 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -9,11 +9,11 @@
 import 'dart:convert';
 import 'dart:core' hide Resource;
 
-import 'package:analysis_server/plugin/analysis/resolver_provider.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
 import 'package:analyzer/plugin/options.dart';
+import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/package_map_provider.dart';
diff --git a/pkg/analysis_server/lib/src/server/driver.dart b/pkg/analysis_server/lib/src/server/driver.dart
index 664ab74..62e284e 100644
--- a/pkg/analysis_server/lib/src/server/driver.dart
+++ b/pkg/analysis_server/lib/src/server/driver.dart
@@ -8,7 +8,6 @@
 import 'dart:io';
 import 'dart:math';
 
-import 'package:analysis_server/plugin/analysis/resolver_provider.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/plugin/linter_plugin.dart';
 import 'package:analysis_server/src/plugin/server_plugin.dart';
@@ -20,6 +19,7 @@
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/file_instrumentation.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/incremental_logger.dart';
 import 'package:analyzer/src/generated/java_io.dart';
diff --git a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
index fa16435..c04bd75 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -149,6 +149,9 @@
         CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE) {
       _addFix_replaceWithConstInstanceCreation();
     }
+    if (errorCode == CompileTimeErrorCode.ASYNC_FOR_IN_WRONG_CONTEXT) {
+      _addFix_addAsync_asyncFor();
+    }
     if (errorCode == CompileTimeErrorCode.INVALID_ANNOTATION) {
       if (node is Annotation) {
         Annotation annotation = node;
@@ -387,6 +390,7 @@
       FunctionBody body = node.getAncestor((n) => n is FunctionBody);
       if (body != null && body.keyword == null) {
         _addReplaceEdit(rf.rangeStartLength(body, 0), 'async ');
+        _replaceReturnTypeWithFuture(body);
         _addFix(DartFixKind.ADD_ASYNC, []);
         return true;
       }
@@ -394,6 +398,15 @@
     return false;
   }
 
+  void _addFix_addAsync_asyncFor() {
+    FunctionBody body = node.getAncestor((n) => n is FunctionBody);
+    if (body != null && body.keyword == null) {
+      _addReplaceEdit(rf.rangeStartLength(body, 0), 'async ');
+      _replaceReturnTypeWithFuture(body);
+      _addFix(DartFixKind.ADD_ASYNC, []);
+    }
+  }
+
   void _addFix_addMissingParameter() {
     if (node is ArgumentList && node.parent is MethodInvocation) {
       ArgumentList argumentList = node;
@@ -1346,19 +1359,9 @@
   }
 
   void _addFix_illegalAsyncReturnType() {
-    InterfaceType futureType = context.typeProvider.futureType;
-    String futureTypeCode = utils.getTypeSource(futureType, librariesToImport);
     // prepare the existing type
     TypeName typeName = node.getAncestor((n) => n is TypeName);
-    String nodeCode = utils.getNodeText(typeName);
-    // wrap the existing type with Future
-    String returnTypeCode;
-    if (nodeCode == 'void') {
-      returnTypeCode = futureTypeCode;
-    } else {
-      returnTypeCode = '$futureTypeCode<$nodeCode>';
-    }
-    _addReplaceEdit(rf.rangeNode(typeName), returnTypeCode);
+    _replaceTypeWithFuture(typeName);
     // add proposal
     _addFix(DartFixKind.REPLACE_RETURN_TYPE_FUTURE, []);
   }
@@ -2776,6 +2779,40 @@
     }
   }
 
+  void _replaceReturnTypeWithFuture(AstNode node) {
+    for (; node != null; node = node.parent) {
+      if (node is FunctionDeclaration) {
+        _replaceTypeWithFuture(node.returnType);
+        return;
+      } else if (node is MethodDeclaration) {
+        _replaceTypeWithFuture(node.returnType);
+        return;
+      }
+    }
+  }
+
+  void _replaceTypeWithFuture(TypeName typeName) {
+    InterfaceType futureType = context.typeProvider.futureType;
+    // validate the type
+    DartType type = typeName?.type;
+    if (type == null ||
+        type.isDynamic ||
+        type is InterfaceType && type.element == futureType.element) {
+      return;
+    }
+    // prepare code for the types
+    String futureTypeCode = utils.getTypeSource(futureType, librariesToImport);
+    String nodeCode = utils.getNodeText(typeName);
+    // wrap the existing type with Future
+    String returnTypeCode;
+    if (nodeCode == 'void') {
+      returnTypeCode = futureTypeCode;
+    } else {
+      returnTypeCode = '$futureTypeCode<$nodeCode>';
+    }
+    _addReplaceEdit(rf.rangeNode(typeName), returnTypeCode);
+  }
+
   void _updateFinderWithClassMembers(
       _ClosestElementFinder finder, ClassElement clazz) {
     if (clazz != null) {
diff --git a/pkg/analysis_server/lib/src/socket_server.dart b/pkg/analysis_server/lib/src/socket_server.dart
index f3e1c5c..1efbfd9 100644
--- a/pkg/analysis_server/lib/src/socket_server.dart
+++ b/pkg/analysis_server/lib/src/socket_server.dart
@@ -4,7 +4,6 @@
 
 library socket.server;
 
-import 'package:analysis_server/plugin/analysis/resolver_provider.dart';
 import 'package:analysis_server/plugin/protocol/protocol.dart';
 import 'package:analysis_server/src/analysis_server.dart';
 import 'package:analysis_server/src/channel/channel.dart';
@@ -13,6 +12,7 @@
 import 'package:analysis_server/src/services/index/local_file_index.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:analyzer/source/pub_package_map_provider.dart';
 import 'package:analyzer/src/generated/sdk_io.dart';
 import 'package:plugin/plugin.dart';
diff --git a/pkg/analysis_server/lib/src/status/get_handler.dart b/pkg/analysis_server/lib/src/status/get_handler.dart
index b20d642..0887d07 100644
--- a/pkg/analysis_server/lib/src/status/get_handler.dart
+++ b/pkg/analysis_server/lib/src/status/get_handler.dart
@@ -1666,6 +1666,9 @@
           buffer.write('<p>Status: Analyzing</p>');
         }
       }
+      buffer.write('<p>Using package resolver provider: ');
+      buffer.write(_server.packageResolverProvider != null);
+      buffer.write('</p>');
       buffer.write('<p>');
       buffer.write(makeLink(OVERLAYS_PATH, {}, 'All overlay information'));
       buffer.write('</p>');
diff --git a/pkg/analysis_server/lib/starter.dart b/pkg/analysis_server/lib/starter.dart
index ad5b19d..42c9861 100644
--- a/pkg/analysis_server/lib/starter.dart
+++ b/pkg/analysis_server/lib/starter.dart
@@ -4,9 +4,9 @@
 
 library analysis_server.starter;
 
-import 'package:analysis_server/plugin/analysis/resolver_provider.dart';
 import 'package:analysis_server/src/server/driver.dart';
 import 'package:analyzer/instrumentation/instrumentation.dart';
+import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:plugin/plugin.dart';
 
 /**
diff --git a/pkg/analysis_server/test/context_manager_test.dart b/pkg/analysis_server/test/context_manager_test.dart
index c332aa9..0d59bdf 100644
--- a/pkg/analysis_server/test/context_manager_test.dart
+++ b/pkg/analysis_server/test/context_manager_test.dart
@@ -147,7 +147,7 @@
     newFile(
         [projPath, AnalysisEngine.ANALYSIS_OPTIONS_FILE],
         r'''
-embedder_libs:
+embedded_libs:
   "dart:foobar": "../sdk_ext/entry.dart"
 analyzer:
   language:
@@ -290,7 +290,7 @@
     newFile(
         [libPath, '_embedder.yaml'],
         r'''
-embedder_libs:
+embedded_libs:
   "dart:foobar": "../sdk_ext/entry.dart"
 analyzer:
   strong-mode: true
@@ -384,7 +384,7 @@
     newFile(
         [libPath, '_embedder.yaml'],
         r'''
-embedder_libs:
+embedded_libs:
   "dart:foobar": "../sdk_ext/entry.dart"
   "dart:typed_data": "../sdk_ext/src/part"
   ''');
@@ -408,10 +408,10 @@
     expect(source.fullName,
         '/my/proj/sdk_ext/entry.dart'.replaceAll('/', JavaFile.separator));
     // We can't find dart:core because we didn't list it in our
-    // embedder_libs map.
+    // embedded_libs map.
     expect(context.sourceFactory.forUri('dart:core'), isNull);
     // We can find dart:typed_data because we listed it in our
-    // embedder_libs map.
+    // embedded_libs map.
     expect(context.sourceFactory.forUri('dart:typed_data'), isNotNull);
   }
 
diff --git a/pkg/analysis_server/test/services/correction/fix_test.dart b/pkg/analysis_server/test/services/correction/fix_test.dart
index 7ce9b90..2b0db03 100644
--- a/pkg/analysis_server/test/services/correction/fix_test.dart
+++ b/pkg/analysis_server/test/services/correction/fix_test.dart
@@ -349,6 +349,27 @@
 ''');
   }
 
+  test_addSync_asyncFor() async {
+    resolveTestUnit('''
+import 'dart:async';
+void main(Stream<String> names) {
+  await for (String name in names) {
+    print(name);
+  }
+}
+''');
+    await assertHasFix(
+        DartFixKind.ADD_ASYNC,
+        '''
+import 'dart:async';
+Future main(Stream<String> names) async {
+  await for (String name in names) {
+    print(name);
+  }
+}
+''');
+  }
+
   test_addSync_BAD_nullFunctionBody() async {
     resolveTestUnit('''
 var F = await;
@@ -412,6 +433,98 @@
 ''');
   }
 
+  test_addSync_returnFuture() async {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+    };
+    resolveTestUnit('''
+foo() {}
+int main() {
+  await foo();
+  return 42;
+}
+''');
+    await assertHasFix(
+        DartFixKind.ADD_ASYNC,
+        '''
+import 'dart:async';
+
+foo() {}
+Future<int> main() async {
+  await foo();
+  return 42;
+}
+''');
+  }
+
+  test_addSync_returnFuture_alreadyFuture() async {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+    };
+    resolveTestUnit('''
+import 'dart:async';
+foo() {}
+Future<int> main() {
+  await foo();
+  return 42;
+}
+''');
+    await assertHasFix(
+        DartFixKind.ADD_ASYNC,
+        '''
+import 'dart:async';
+foo() {}
+Future<int> main() async {
+  await foo();
+  return 42;
+}
+''');
+  }
+
+  test_addSync_returnFuture_dynamic() async {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+    };
+    resolveTestUnit('''
+foo() {}
+dynamic main() {
+  await foo();
+  return 42;
+}
+''');
+    await assertHasFix(
+        DartFixKind.ADD_ASYNC,
+        '''
+foo() {}
+dynamic main() async {
+  await foo();
+  return 42;
+}
+''');
+  }
+
+  test_addSync_returnFuture_noType() async {
+    errorFilter = (AnalysisError error) {
+      return error.errorCode == StaticWarningCode.UNDEFINED_IDENTIFIER;
+    };
+    resolveTestUnit('''
+foo() {}
+main() {
+  await foo();
+  return 42;
+}
+''');
+    await assertHasFix(
+        DartFixKind.ADD_ASYNC,
+        '''
+foo() {}
+main() async {
+  await foo();
+  return 42;
+}
+''');
+  }
+
   test_boolean() async {
     resolveTestUnit('''
 main() {
diff --git a/pkg/analyzer/lib/dart/element/type.dart b/pkg/analyzer/lib/dart/element/type.dart
index 5b92819..9f079a9 100644
--- a/pkg/analyzer/lib/dart/element/type.dart
+++ b/pkg/analyzer/lib/dart/element/type.dart
@@ -173,6 +173,12 @@
   List<DartType> get normalParameterTypes;
 
   /**
+   * The names of the required positional parameters of this type of function,
+   * in the order that the parameters appear.
+   */
+  List<String> get normalParameterNames;
+
+  /**
    * Return a map from the names of optional (positional) parameters to the
    * types of the optional parameters of this type of function. The entries in
    * the map will be iterated in the same order as the order in which the
@@ -182,6 +188,12 @@
   List<DartType> get optionalParameterTypes;
 
   /**
+   * The names of the optional positional parameters of this type of function,
+   * in the order that the parameters appear.
+   */
+  List<String> get optionalParameterNames;
+
+  /**
    * Return a list containing the parameters elements of this type of function.
    * The parameter types are in the same order as they appear in the declaration
    * of the function.
diff --git a/pkg/analyzer/lib/file_system/memory_file_system.dart b/pkg/analyzer/lib/file_system/memory_file_system.dart
index dc676bb..a8aca38 100644
--- a/pkg/analyzer/lib/file_system/memory_file_system.dart
+++ b/pkg/analyzer/lib/file_system/memory_file_system.dart
@@ -28,11 +28,15 @@
       new HashMap<String, List<StreamController<WatchEvent>>>();
   int nextStamp = 0;
 
-  final AbsolutePathContext absolutePathContext =
-      new AbsolutePathContext(false);
+  final Context _pathContext;
+  final AbsolutePathContext absolutePathContext;
+
+  MemoryResourceProvider({bool isWindows: false})
+      : _pathContext = isWindows ? windows : posix,
+        absolutePathContext = new AbsolutePathContext(isWindows);
 
   @override
-  Context get pathContext => posix;
+  Context get pathContext => _pathContext;
 
   /**
    * Delete the file with the given path.
@@ -127,9 +131,8 @@
 
   Folder newFolder(String path) {
     path = pathContext.normalize(path);
-    if (!path.startsWith(pathContext.separator)) {
-      throw new ArgumentError(
-          "Path must start with '${pathContext.separator}' : $path");
+    if (!pathContext.isAbsolute(path)) {
+      throw new ArgumentError("Path must be absolute : $path");
     }
     _MemoryResource resource = _pathToResource[path];
     if (resource == null) {
diff --git a/pkg/analysis_server/lib/plugin/analysis/resolver_provider.dart b/pkg/analyzer/lib/plugin/resolver_provider.dart
similarity index 72%
rename from pkg/analysis_server/lib/plugin/analysis/resolver_provider.dart
rename to pkg/analyzer/lib/plugin/resolver_provider.dart
index ab6926c..1172372 100644
--- a/pkg/analysis_server/lib/plugin/analysis/resolver_provider.dart
+++ b/pkg/analyzer/lib/plugin/resolver_provider.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-library analysis_server.plugin.analysis.resolver_provider;
+library analyzer.plugin.resolver_provider;
 
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -10,7 +10,5 @@
 /**
  * A function that will return a [UriResolver] that can be used to resolve a
  * specific kind of URI within the analysis context rooted at the given folder.
- * This is currently being used to provide a package URI resolver that will be
- * used by the server (see [ServerStarter.packageResolverProvider]).
  */
 typedef UriResolver ResolverProvider(Folder folder);
diff --git a/pkg/analyzer/lib/source/embedder.dart b/pkg/analyzer/lib/source/embedder.dart
index f77ff7c..af30e76 100644
--- a/pkg/analyzer/lib/source/embedder.dart
+++ b/pkg/analyzer/lib/source/embedder.dart
@@ -99,12 +99,12 @@
 }
 
 /// Given the [embedderYamls] from [EmbedderYamlLocator] check each one for the
-/// top level key 'embedder_libs'. Under the 'embedder_libs' key are key value
+/// top level key 'embedded_libs'. Under the 'embedded_libs' key are key value
 /// pairs. Each key is a 'dart:' library uri and each value is a path
 /// (relative to the directory containing `_embedder.yaml`) to a dart script
 /// for the given library. For example:
 ///
-/// embedder_libs:
+/// embedded_libs:
 ///   'dart:io': '../../sdk/io/io.dart'
 ///
 /// If a key doesn't begin with `dart:` it is ignored.
@@ -124,19 +124,19 @@
   }
 
   void _processEmbedderYaml(Folder libDir, YamlMap map) {
-    YamlNode embedder_libs = map['embedder_libs'];
-    if (embedder_libs == null) {
+    YamlNode embedded_libs = map['embedded_libs'];
+    if (embedded_libs == null) {
       return;
     }
-    if (embedder_libs is! YamlMap) {
+    if (embedded_libs is! YamlMap) {
       return;
     }
-    (embedder_libs as YamlMap)
-        .forEach((k, v) => _processEmbedderLibs(k, v, libDir));
+    (embedded_libs as YamlMap)
+        .forEach((k, v) => _processEmbeddedLibs(k, v, libDir));
   }
 
   /// Install the mapping from [name] to [libDir]/[file].
-  void _processEmbedderLibs(String name, String file, Folder libDir) {
+  void _processEmbeddedLibs(String name, String file, Folder libDir) {
     if (!name.startsWith(_DART_COLON_PREFIX)) {
       // SDK libraries must begin with 'dart:'.
       // TODO(pquitslund): Notify developer that something is wrong with the
@@ -151,12 +151,16 @@
     (dartSdk as EmbedderSdk)._librariesMap.setLibrary(name, library);
   }
 
-  /// Number of embedder libraries.
+  /// Number of embedded libraries.
   int get length => _urlMappings.length;
 
   @override
   Uri restoreAbsolute(Source source) {
-    Source sdkSource = dartSdk.fromFileUri(Uri.parse(source.fullName));
+    String path = source.fullName;
+    if (path.length > 3 && path[1] == ':' && path[2] == '\\') {
+      path = '/${path[0]}:${path.substring(2).replaceAll('\\', '/')}';
+    }
+    Source sdkSource = dartSdk.fromFileUri(Uri.parse('file://$path'));
     return sdkSource?.uri;
   }
 }
diff --git a/pkg/analyzer/lib/src/context/source.dart b/pkg/analyzer/lib/src/context/source.dart
new file mode 100644
index 0000000..faf8eaa
--- /dev/null
+++ b/pkg/analyzer/lib/src/context/source.dart
@@ -0,0 +1,311 @@
+// Copyright (c) 2015, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.context.source;
+
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/file_system/physical_file_system.dart';
+import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
+import 'package:package_config/packages.dart';
+
+/**
+ * Instances of the class `SourceFactory` resolve possibly relative URI's
+ * against an existing [Source].
+ */
+class SourceFactoryImpl implements SourceFactory {
+  /**
+   * The analysis context that this source factory is associated with.
+   */
+  AnalysisContext context;
+
+  /**
+   * URI processor used to find mappings for `package:` URIs found in a
+   * `.packages` config file.
+   */
+  final Packages _packages;
+
+  /**
+   * Resource provider used in working with package maps.
+   */
+  final ResourceProvider _resourceProvider;
+
+  /**
+   * The resolvers used to resolve absolute URI's.
+   */
+  final List<UriResolver> resolvers;
+
+  /**
+   * The predicate to determine is [Source] is local.
+   */
+  LocalSourcePredicate _localSourcePredicate = LocalSourcePredicate.NOT_SDK;
+
+  /**
+   * Initialize a newly created source factory with the given absolute URI
+   * [resolvers] and optional [packages] resolution helper.
+   */
+  SourceFactoryImpl(this.resolvers,
+      [this._packages, ResourceProvider resourceProvider])
+      : _resourceProvider = resourceProvider != null
+            ? resourceProvider
+            : PhysicalResourceProvider.INSTANCE;
+
+  /**
+   * Return the [DartSdk] associated with this [SourceFactory], or `null` if
+   * there is no such SDK.
+   *
+   * @return the [DartSdk] associated with this [SourceFactory], or `null` if
+   *         there is no such SDK
+   */
+  DartSdk get dartSdk {
+    for (UriResolver resolver in resolvers) {
+      if (resolver is DartUriResolver) {
+        DartUriResolver dartUriResolver = resolver;
+        return dartUriResolver.dartSdk;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Sets the [LocalSourcePredicate].
+   *
+   * @param localSourcePredicate the predicate to determine is [Source] is local
+   */
+  void set localSourcePredicate(LocalSourcePredicate localSourcePredicate) {
+    this._localSourcePredicate = localSourcePredicate;
+  }
+
+  /// A table mapping package names to paths of directories containing
+  /// the package (or [null] if there is no registered package URI resolver).
+  Map<String, List<Folder>> get packageMap {
+    // Start by looking in .packages.
+    if (_packages != null) {
+      Map<String, List<Folder>> packageMap = <String, List<Folder>>{};
+      _packages.asMap().forEach((String name, Uri uri) {
+        if (uri.scheme == 'file' || uri.scheme == '' /* unspecified */) {
+          packageMap[name] = <Folder>[
+            _resourceProvider.getFolder(uri.toFilePath())
+          ];
+        }
+      });
+      return packageMap;
+    }
+
+    // Default to the PackageMapUriResolver.
+    PackageMapUriResolver resolver = resolvers
+        .firstWhere((r) => r is PackageMapUriResolver, orElse: () => null);
+    return resolver != null ? resolver.packageMap : null;
+  }
+
+  /**
+   * Return a source factory that will resolve URI's in the same way that this
+   * source factory does.
+   */
+  SourceFactory clone() {
+    SourceFactory factory =
+        new SourceFactory(resolvers, _packages, _resourceProvider);
+    factory.localSourcePredicate = _localSourcePredicate;
+    return factory;
+  }
+
+  /**
+   * Return a source object representing the given absolute URI, or `null` if
+   * the URI is not a valid URI or if it is not an absolute URI.
+   *
+   * @param absoluteUri the absolute URI to be resolved
+   * @return a source object representing the absolute URI
+   */
+  Source forUri(String absoluteUri) {
+    try {
+      Uri uri = parseUriWithException(absoluteUri);
+      if (uri.isAbsolute) {
+        return _internalResolveUri(null, uri);
+      }
+    } catch (exception, stackTrace) {
+      AnalysisEngine.instance.logger.logError(
+          "Could not resolve URI: $absoluteUri",
+          new CaughtException(exception, stackTrace));
+    }
+    return null;
+  }
+
+  /**
+   * Return a source object representing the given absolute URI, or `null` if
+   * the URI is not an absolute URI.
+   *
+   * @param absoluteUri the absolute URI to be resolved
+   * @return a source object representing the absolute URI
+   */
+  Source forUri2(Uri absoluteUri) {
+    if (absoluteUri.isAbsolute) {
+      try {
+        return _internalResolveUri(null, absoluteUri);
+      } on AnalysisException catch (exception, stackTrace) {
+        AnalysisEngine.instance.logger.logError(
+            "Could not resolve URI: $absoluteUri",
+            new CaughtException(exception, stackTrace));
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Return a source object that is equal to the source object used to obtain
+   * the given encoding.
+   *
+   * @param encoding the encoding of a source object
+   * @return a source object that is described by the given encoding
+   * @throws IllegalArgumentException if the argument is not a valid encoding
+   * See [Source.encoding].
+   */
+  Source fromEncoding(String encoding) {
+    Source source = forUri(encoding);
+    if (source == null) {
+      throw new IllegalArgumentException(
+          "Invalid source encoding: '$encoding'");
+    }
+    return source;
+  }
+
+  /**
+   * Determines if the given [Source] is local.
+   *
+   * @param source the [Source] to analyze
+   * @return `true` if the given [Source] is local
+   */
+  bool isLocalSource(Source source) => _localSourcePredicate.isLocal(source);
+
+  /**
+   * Return a source representing the URI that results from resolving the given
+   * (possibly relative) [containedUri] against the URI associated with the
+   * [containingSource], whether or not the resulting source exists, or `null`
+   * if either the [containedUri] is invalid or if it cannot be resolved against
+   * the [containingSource]'s URI.
+   */
+  Source resolveUri(Source containingSource, String containedUri) {
+    if (containedUri == null || containedUri.isEmpty) {
+      return null;
+    }
+    try {
+      // Force the creation of an escaped URI to deal with spaces, etc.
+      return _internalResolveUri(
+          containingSource, parseUriWithException(containedUri));
+    } on URISyntaxException {
+      return null;
+    } catch (exception, stackTrace) {
+      String containingFullName =
+          containingSource != null ? containingSource.fullName : '<null>';
+      AnalysisEngine.instance.logger.logInformation(
+          "Could not resolve URI ($containedUri) "
+          "relative to source ($containingFullName)",
+          new CaughtException(exception, stackTrace));
+      return null;
+    }
+  }
+
+  /**
+   * Return an absolute URI that represents the given source, or `null` if a
+   * valid URI cannot be computed.
+   *
+   * @param source the source to get URI for
+   * @return the absolute URI representing the given source
+   */
+  Uri restoreUri(Source source) {
+    // First see if a resolver can restore the URI.
+    for (UriResolver resolver in resolvers) {
+      Uri uri = resolver.restoreAbsolute(source);
+      if (uri != null) {
+        // Now see if there's a package mapping.
+        Uri packageMappedUri = _getPackageMapping(uri);
+        if (packageMappedUri != null) {
+          return packageMappedUri;
+        }
+        // Fall back to the resolver's computed URI.
+        return uri;
+      }
+    }
+
+    return null;
+  }
+
+  Uri _getPackageMapping(Uri sourceUri) {
+    if (_packages == null) {
+      return null;
+    }
+    if (sourceUri.scheme != 'file') {
+      //TODO(pquitslund): verify this works for non-file URIs.
+      return null;
+    }
+
+    Uri packageUri;
+    _packages.asMap().forEach((String name, Uri uri) {
+      if (packageUri == null) {
+        if (utils.startsWith(sourceUri, uri)) {
+          packageUri = Uri.parse(
+              'package:$name/${sourceUri.path.substring(uri.path.length)}');
+        }
+      }
+    });
+    return packageUri;
+  }
+
+  /**
+   * Return a source object representing the URI that results from resolving
+   * the given (possibly relative) contained URI against the URI associated
+   * with an existing source object, or `null` if the URI could not be resolved.
+   *
+   * @param containingSource the source containing the given URI
+   * @param containedUri the (possibly relative) URI to be resolved against the
+   *        containing source
+   * @return the source representing the contained URI
+   * @throws AnalysisException if either the contained URI is invalid or if it
+   *         cannot be resolved against the source object's URI
+   */
+  Source _internalResolveUri(Source containingSource, Uri containedUri) {
+    if (!containedUri.isAbsolute) {
+      if (containingSource == null) {
+        throw new AnalysisException(
+            "Cannot resolve a relative URI without a containing source: "
+            "$containedUri");
+      }
+      containedUri = containingSource.resolveRelativeUri(containedUri);
+    }
+
+    Uri actualUri = containedUri;
+
+    // Check .packages and update target and actual URIs as appropriate.
+    if (_packages != null && containedUri.scheme == 'package') {
+      Uri packageUri = null;
+      try {
+        packageUri =
+            _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
+      } on ArgumentError {
+        // Fall through to try resolvers.
+      }
+
+      if (packageUri != null) {
+        // Ensure scheme is set.
+        if (packageUri.scheme == '') {
+          packageUri = packageUri.replace(scheme: 'file');
+        }
+        containedUri = packageUri;
+      }
+    }
+
+    for (UriResolver resolver in resolvers) {
+      Source result = resolver.resolveAbsolute(containedUri, actualUri);
+      if (result != null) {
+        return result;
+      }
+    }
+
+    return null;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/builder.dart b/pkg/analyzer/lib/src/dart/element/builder.dart
new file mode 100644
index 0000000..df8f470
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/builder.dart
@@ -0,0 +1,1350 @@
+// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer.src.dart.element.builder;
+
+import 'dart:collection';
+
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_engine.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
+import 'package:analyzer/src/generated/sdk.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
+
+/**
+ * A `CompilationUnitBuilder` builds an element model for a single compilation
+ * unit.
+ */
+class CompilationUnitBuilder {
+  /**
+   * Build the compilation unit element for the given [source] based on the
+   * compilation [unit] associated with the source. Throw an AnalysisException
+   * if the element could not be built.  [librarySource] is the source for the
+   * containing library.
+   */
+  CompilationUnitElementImpl buildCompilationUnit(
+      Source source, CompilationUnit unit, Source librarySource) {
+    return PerformanceStatistics.resolve.makeCurrentWhile(() {
+      if (unit == null) {
+        return null;
+      }
+      ElementHolder holder = new ElementHolder();
+      ElementBuilder builder = new ElementBuilder(holder);
+      unit.accept(builder);
+      CompilationUnitElementImpl element =
+          new CompilationUnitElementImpl(source.shortName);
+      element.accessors = holder.accessors;
+      element.enums = holder.enums;
+      element.functions = holder.functions;
+      element.source = source;
+      element.librarySource = librarySource;
+      element.typeAliases = holder.typeAliases;
+      element.types = holder.types;
+      element.topLevelVariables = holder.topLevelVariables;
+      unit.element = element;
+      holder.validate();
+      return element;
+    });
+  }
+}
+
+/**
+ * Instances of the class `DirectiveElementBuilder` build elements for top
+ * level library directives.
+ */
+class DirectiveElementBuilder extends SimpleAstVisitor<Object> {
+  /**
+   * The analysis context within which directive elements are being built.
+   */
+  final AnalysisContext context;
+
+  /**
+   * The library element for which directive elements are being built.
+   */
+  final LibraryElementImpl libraryElement;
+
+  /**
+   * Map from sources imported by this library to their corresponding library
+   * elements.
+   */
+  final Map<Source, LibraryElement> importLibraryMap;
+
+  /**
+   * Map from sources imported by this library to their corresponding source
+   * kinds.
+   */
+  final Map<Source, SourceKind> importSourceKindMap;
+
+  /**
+   * Map from sources exported by this library to their corresponding library
+   * elements.
+   */
+  final Map<Source, LibraryElement> exportLibraryMap;
+
+  /**
+   * Map from sources exported by this library to their corresponding source
+   * kinds.
+   */
+  final Map<Source, SourceKind> exportSourceKindMap;
+
+  /**
+   * The [ImportElement]s created so far.
+   */
+  final List<ImportElement> imports = <ImportElement>[];
+
+  /**
+   * The [ExportElement]s created so far.
+   */
+  final List<ExportElement> exports = <ExportElement>[];
+
+  /**
+   * The errors found while building directive elements.
+   */
+  final List<AnalysisError> errors = <AnalysisError>[];
+
+  /**
+   * Map from prefix names to their corresponding elements.
+   */
+  final HashMap<String, PrefixElementImpl> nameToPrefixMap =
+      new HashMap<String, PrefixElementImpl>();
+
+  /**
+   * Indicates whether an explicit import of `dart:core` has been found.
+   */
+  bool explicitlyImportsCore = false;
+
+  DirectiveElementBuilder(
+      this.context,
+      this.libraryElement,
+      this.importLibraryMap,
+      this.importSourceKindMap,
+      this.exportLibraryMap,
+      this.exportSourceKindMap);
+
+  @override
+  Object visitCompilationUnit(CompilationUnit node) {
+    //
+    // Resolve directives.
+    //
+    for (Directive directive in node.directives) {
+      directive.accept(this);
+    }
+    //
+    // Ensure "dart:core" import.
+    //
+    Source librarySource = libraryElement.source;
+    Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
+    if (!explicitlyImportsCore && coreLibrarySource != librarySource) {
+      ImportElementImpl importElement = new ImportElementImpl(-1);
+      importElement.importedLibrary = importLibraryMap[coreLibrarySource];
+      importElement.synthetic = true;
+      imports.add(importElement);
+    }
+    //
+    // Populate the library element.
+    //
+    libraryElement.imports = imports;
+    libraryElement.exports = exports;
+    return null;
+  }
+
+  @override
+  Object visitExportDirective(ExportDirective node) {
+    Source exportedSource = node.source;
+    if (exportedSource != null && context.exists(exportedSource)) {
+      // The exported source will be null if the URI in the export
+      // directive was invalid.
+      LibraryElement exportedLibrary = exportLibraryMap[exportedSource];
+      if (exportedLibrary != null) {
+        ExportElementImpl exportElement = new ExportElementImpl(node.offset);
+        StringLiteral uriLiteral = node.uri;
+        if (uriLiteral != null) {
+          exportElement.uriOffset = uriLiteral.offset;
+          exportElement.uriEnd = uriLiteral.end;
+        }
+        exportElement.uri = node.uriContent;
+        exportElement.combinators = _buildCombinators(node);
+        exportElement.exportedLibrary = exportedLibrary;
+        _setDoc(exportElement, node);
+        node.element = exportElement;
+        exports.add(exportElement);
+        if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
+          errors.add(new AnalysisError(
+              exportedSource,
+              uriLiteral.offset,
+              uriLiteral.length,
+              CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
+              [uriLiteral.toSource()]));
+        }
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitImportDirective(ImportDirective node) {
+    String uriContent = node.uriContent;
+    if (DartUriResolver.isDartExtUri(uriContent)) {
+      libraryElement.hasExtUri = true;
+    }
+    Source importedSource = node.source;
+    if (importedSource != null && context.exists(importedSource)) {
+      // The imported source will be null if the URI in the import
+      // directive was invalid.
+      LibraryElement importedLibrary = importLibraryMap[importedSource];
+      if (importedLibrary != null) {
+        if (importedLibrary.isDartCore) {
+          explicitlyImportsCore = true;
+        }
+        ImportElementImpl importElement = new ImportElementImpl(node.offset);
+        StringLiteral uriLiteral = node.uri;
+        if (uriLiteral != null) {
+          importElement.uriOffset = uriLiteral.offset;
+          importElement.uriEnd = uriLiteral.end;
+        }
+        importElement.uri = uriContent;
+        importElement.deferred = node.deferredKeyword != null;
+        importElement.combinators = _buildCombinators(node);
+        importElement.importedLibrary = importedLibrary;
+        _setDoc(importElement, node);
+        SimpleIdentifier prefixNode = node.prefix;
+        if (prefixNode != null) {
+          importElement.prefixOffset = prefixNode.offset;
+          String prefixName = prefixNode.name;
+          PrefixElementImpl prefix = nameToPrefixMap[prefixName];
+          if (prefix == null) {
+            prefix = new PrefixElementImpl.forNode(prefixNode);
+            nameToPrefixMap[prefixName] = prefix;
+          }
+          importElement.prefix = prefix;
+          prefixNode.staticElement = prefix;
+        }
+        node.element = importElement;
+        imports.add(importElement);
+        if (importSourceKindMap[importedSource] != SourceKind.LIBRARY) {
+          ErrorCode errorCode = (importElement.isDeferred
+              ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
+              : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
+          errors.add(new AnalysisError(importedSource, uriLiteral.offset,
+              uriLiteral.length, errorCode, [uriLiteral.toSource()]));
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * If the given [node] has a documentation comment, remember its content
+   * and range into the given [element].
+   */
+  void _setDoc(ElementImpl element, AnnotatedNode node) {
+    Comment comment = node.documentationComment;
+    if (comment != null && comment.isDocumentation) {
+      element.documentationComment =
+          comment.tokens.map((Token t) => t.lexeme).join('\n');
+      element.setDocRange(comment.offset, comment.length);
+    }
+  }
+
+  /**
+   * Build the element model representing the combinators declared by
+   * the given [directive].
+   */
+  static List<NamespaceCombinator> _buildCombinators(
+      NamespaceDirective directive) {
+    _NamespaceCombinatorBuilder namespaceCombinatorBuilder =
+        new _NamespaceCombinatorBuilder();
+    for (Combinator combinator in directive.combinators) {
+      combinator.accept(namespaceCombinatorBuilder);
+    }
+    return namespaceCombinatorBuilder.combinators;
+  }
+}
+
+/**
+ * Instances of the class `ElementBuilder` traverse an AST structure and build the element
+ * model representing the AST structure.
+ */
+class ElementBuilder extends RecursiveAstVisitor<Object> {
+  /**
+   * The element holder associated with the element that is currently being built.
+   */
+  ElementHolder _currentHolder;
+
+  /**
+   * A flag indicating whether a variable declaration is in the context of a field declaration.
+   */
+  bool _inFieldContext = false;
+
+  /**
+   * A flag indicating whether a variable declaration is within the body of a method or function.
+   */
+  bool _inFunction = false;
+
+  /**
+   * A collection holding the elements defined in a class that need to have
+   * their function type fixed to take into account type parameters of the
+   * enclosing class, or `null` if we are not currently processing nodes within
+   * a class.
+   */
+  List<ExecutableElementImpl> _functionTypesToFix = null;
+
+  /**
+   * A table mapping field names to field elements for the fields defined in the current class, or
+   * `null` if we are not in the scope of a class.
+   */
+  HashMap<String, FieldElement> _fieldMap;
+
+  /**
+   * Initialize a newly created element builder to build the elements for a compilation unit.
+   *
+   * @param initialHolder the element holder associated with the compilation unit being built
+   */
+  ElementBuilder(ElementHolder initialHolder) {
+    _currentHolder = initialHolder;
+  }
+
+  @override
+  Object visitBlock(Block node) {
+    bool wasInField = _inFieldContext;
+    _inFieldContext = false;
+    try {
+      node.visitChildren(this);
+    } finally {
+      _inFieldContext = wasInField;
+    }
+    return null;
+  }
+
+  @override
+  Object visitCatchClause(CatchClause node) {
+    SimpleIdentifier exceptionParameter = node.exceptionParameter;
+    if (exceptionParameter != null) {
+      // exception
+      LocalVariableElementImpl exception =
+          new LocalVariableElementImpl.forNode(exceptionParameter);
+      if (node.exceptionType == null) {
+        exception.hasImplicitType = true;
+      }
+      _currentHolder.addLocalVariable(exception);
+      exceptionParameter.staticElement = exception;
+      // stack trace
+      SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
+      if (stackTraceParameter != null) {
+        LocalVariableElementImpl stackTrace =
+            new LocalVariableElementImpl.forNode(stackTraceParameter);
+        _currentHolder.addLocalVariable(stackTrace);
+        stackTraceParameter.staticElement = stackTrace;
+      }
+    }
+    return super.visitCatchClause(node);
+  }
+
+  @override
+  Object visitClassDeclaration(ClassDeclaration node) {
+    ElementHolder holder = new ElementHolder();
+    _functionTypesToFix = new List<ExecutableElementImpl>();
+    //
+    // Process field declarations before constructors and methods so that field
+    // formal parameters can be correctly resolved to their fields.
+    //
+    ElementHolder previousHolder = _currentHolder;
+    _currentHolder = holder;
+    try {
+      List<ClassMember> nonFields = new List<ClassMember>();
+      node.visitChildren(
+          new _ElementBuilder_visitClassDeclaration(this, nonFields));
+      _buildFieldMap(holder.fieldsWithoutFlushing);
+      int count = nonFields.length;
+      for (int i = 0; i < count; i++) {
+        nonFields[i].accept(this);
+      }
+    } finally {
+      _currentHolder = previousHolder;
+    }
+    SimpleIdentifier className = node.name;
+    ClassElementImpl element = new ClassElementImpl.forNode(className);
+    List<TypeParameterElement> typeParameters = holder.typeParameters;
+    List<DartType> typeArguments = _createTypeParameterTypes(typeParameters);
+    InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
+    interfaceType.typeArguments = typeArguments;
+    element.type = interfaceType;
+    element.typeParameters = typeParameters;
+    _setDoc(element, node);
+    element.abstract = node.isAbstract;
+    element.accessors = holder.accessors;
+    List<ConstructorElement> constructors = holder.constructors;
+    if (constructors.isEmpty) {
+      constructors = _createDefaultConstructors(element);
+    }
+    element.constructors = constructors;
+    element.fields = holder.fields;
+    element.methods = holder.methods;
+    // Function types must be initialized after the enclosing element has been
+    // set, for them to pick up the type parameters.
+    for (ExecutableElementImpl e in _functionTypesToFix) {
+      e.type = new FunctionTypeImpl(e);
+    }
+    _functionTypesToFix = null;
+    _currentHolder.addType(element);
+    className.staticElement = element;
+    _fieldMap = null;
+    holder.validate();
+    return null;
+  }
+
+  /**
+   * Implementation of this method should be synchronized with
+   * [visitClassDeclaration].
+   */
+  void visitClassDeclarationIncrementally(ClassDeclaration node) {
+    //
+    // Process field declarations before constructors and methods so that field
+    // formal parameters can be correctly resolved to their fields.
+    //
+    ClassElement classElement = node.element;
+    _buildFieldMap(classElement.fields);
+  }
+
+  @override
+  Object visitClassTypeAlias(ClassTypeAlias node) {
+    ElementHolder holder = new ElementHolder();
+    _visitChildren(holder, node);
+    SimpleIdentifier className = node.name;
+    ClassElementImpl element = new ClassElementImpl.forNode(className);
+    element.abstract = node.abstractKeyword != null;
+    element.mixinApplication = true;
+    List<TypeParameterElement> typeParameters = holder.typeParameters;
+    element.typeParameters = typeParameters;
+    List<DartType> typeArguments = _createTypeParameterTypes(typeParameters);
+    InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
+    interfaceType.typeArguments = typeArguments;
+    element.type = interfaceType;
+    _setDoc(element, node);
+    _currentHolder.addType(element);
+    className.staticElement = element;
+    holder.validate();
+    return null;
+  }
+
+  @override
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    ElementHolder holder = new ElementHolder();
+    bool wasInFunction = _inFunction;
+    _inFunction = true;
+    try {
+      _visitChildren(holder, node);
+    } finally {
+      _inFunction = wasInFunction;
+    }
+    FunctionBody body = node.body;
+    SimpleIdentifier constructorName = node.name;
+    ConstructorElementImpl element =
+        new ConstructorElementImpl.forNode(constructorName);
+    _setDoc(element, node);
+    if (node.externalKeyword != null) {
+      element.external = true;
+    }
+    if (node.factoryKeyword != null) {
+      element.factory = true;
+    }
+    element.functions = holder.functions;
+    element.labels = holder.labels;
+    element.localVariables = holder.localVariables;
+    element.parameters = holder.parameters;
+    element.const2 = node.constKeyword != null;
+    if (body.isAsynchronous) {
+      element.asynchronous = true;
+    }
+    if (body.isGenerator) {
+      element.generator = true;
+    }
+    _currentHolder.addConstructor(element);
+    node.element = element;
+    if (constructorName == null) {
+      Identifier returnType = node.returnType;
+      if (returnType != null) {
+        element.nameOffset = returnType.offset;
+        element.nameEnd = returnType.end;
+      }
+    } else {
+      constructorName.staticElement = element;
+      element.periodOffset = node.period.offset;
+      element.nameEnd = constructorName.end;
+    }
+    holder.validate();
+    return null;
+  }
+
+  @override
+  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
+    SimpleIdentifier variableName = node.identifier;
+    LocalVariableElementImpl element =
+        new LocalVariableElementImpl.forNode(variableName);
+    ForEachStatement statement = node.parent as ForEachStatement;
+    int declarationEnd = node.offset + node.length;
+    int statementEnd = statement.offset + statement.length;
+    element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1);
+    element.const3 = node.isConst;
+    element.final2 = node.isFinal;
+    if (node.type == null) {
+      element.hasImplicitType = true;
+    }
+    _currentHolder.addLocalVariable(element);
+    variableName.staticElement = element;
+    return super.visitDeclaredIdentifier(node);
+  }
+
+  @override
+  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
+    ElementHolder holder = new ElementHolder();
+    NormalFormalParameter normalParameter = node.parameter;
+    SimpleIdentifier parameterName = normalParameter.identifier;
+    ParameterElementImpl parameter;
+    if (normalParameter is FieldFormalParameter) {
+      parameter = new DefaultFieldFormalParameterElementImpl(parameterName);
+      FieldElement field =
+          _fieldMap == null ? null : _fieldMap[parameterName.name];
+      if (field != null) {
+        (parameter as DefaultFieldFormalParameterElementImpl).field = field;
+      }
+    } else {
+      parameter = new DefaultParameterElementImpl(parameterName);
+    }
+    parameter.const3 = node.isConst;
+    parameter.final2 = node.isFinal;
+    parameter.parameterKind = node.kind;
+    // set initializer, default value range
+    Expression defaultValue = node.defaultValue;
+    if (defaultValue != null) {
+      _visit(holder, defaultValue);
+      FunctionElementImpl initializer =
+          new FunctionElementImpl.forOffset(defaultValue.beginToken.offset);
+      initializer.functions = holder.functions;
+      initializer.labels = holder.labels;
+      initializer.localVariables = holder.localVariables;
+      initializer.parameters = holder.parameters;
+      initializer.synthetic = true;
+      parameter.initializer = initializer;
+      parameter.defaultValueCode = defaultValue.toSource();
+    }
+    // visible range
+    _setParameterVisibleRange(node, parameter);
+    if (normalParameter is SimpleFormalParameter &&
+        normalParameter.type == null) {
+      parameter.hasImplicitType = true;
+    }
+    _currentHolder.addParameter(parameter);
+    parameterName.staticElement = parameter;
+    normalParameter.accept(this);
+    holder.validate();
+    return null;
+  }
+
+  @override
+  Object visitEnumDeclaration(EnumDeclaration node) {
+    SimpleIdentifier enumName = node.name;
+    ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName);
+    enumElement.enum2 = true;
+    _setDoc(enumElement, node);
+    InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement);
+    enumElement.type = enumType;
+    // The equivalent code for enums in the spec shows a single constructor,
+    // but that constructor is not callable (since it is a compile-time error
+    // to subclass, mix-in, implement, or explicitly instantiate an enum).  So
+    // we represent this as having no constructors.
+    enumElement.constructors = ConstructorElement.EMPTY_LIST;
+    _currentHolder.addEnum(enumElement);
+    enumName.staticElement = enumElement;
+    return super.visitEnumDeclaration(node);
+  }
+
+  @override
+  Object visitFieldDeclaration(FieldDeclaration node) {
+    bool wasInField = _inFieldContext;
+    _inFieldContext = true;
+    try {
+      node.visitChildren(this);
+    } finally {
+      _inFieldContext = wasInField;
+    }
+    return null;
+  }
+
+  @override
+  Object visitFieldFormalParameter(FieldFormalParameter node) {
+    if (node.parent is! DefaultFormalParameter) {
+      SimpleIdentifier parameterName = node.identifier;
+      FieldElement field =
+          _fieldMap == null ? null : _fieldMap[parameterName.name];
+      FieldFormalParameterElementImpl parameter =
+          new FieldFormalParameterElementImpl(parameterName);
+      parameter.const3 = node.isConst;
+      parameter.final2 = node.isFinal;
+      parameter.parameterKind = node.kind;
+      if (field != null) {
+        parameter.field = field;
+      }
+      _currentHolder.addParameter(parameter);
+      parameterName.staticElement = parameter;
+    }
+    //
+    // The children of this parameter include any parameters defined on the type
+    // of this parameter.
+    //
+    ElementHolder holder = new ElementHolder();
+    _visitChildren(holder, node);
+    ParameterElementImpl element = node.element;
+    element.parameters = holder.parameters;
+    element.typeParameters = holder.typeParameters;
+    holder.validate();
+    return null;
+  }
+
+  @override
+  Object visitFunctionDeclaration(FunctionDeclaration node) {
+    FunctionExpression expression = node.functionExpression;
+    if (expression != null) {
+      ElementHolder holder = new ElementHolder();
+      bool wasInFunction = _inFunction;
+      _inFunction = true;
+      try {
+        _visitChildren(holder, node);
+      } finally {
+        _inFunction = wasInFunction;
+      }
+      FunctionBody body = expression.body;
+      Token property = node.propertyKeyword;
+      if (property == null || _inFunction) {
+        SimpleIdentifier functionName = node.name;
+        FunctionElementImpl element =
+            new FunctionElementImpl.forNode(functionName);
+        _setDoc(element, node);
+        if (node.externalKeyword != null) {
+          element.external = true;
+        }
+        element.functions = holder.functions;
+        element.labels = holder.labels;
+        element.localVariables = holder.localVariables;
+        element.parameters = holder.parameters;
+        element.typeParameters = holder.typeParameters;
+        if (body.isAsynchronous) {
+          element.asynchronous = true;
+        }
+        if (body.isGenerator) {
+          element.generator = true;
+        }
+        if (_inFunction) {
+          Block enclosingBlock = node.getAncestor((node) => node is Block);
+          if (enclosingBlock != null) {
+            int functionEnd = node.offset + node.length;
+            int blockEnd = enclosingBlock.offset + enclosingBlock.length;
+            element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
+          }
+        }
+        if (node.returnType == null) {
+          element.hasImplicitReturnType = true;
+        }
+        _currentHolder.addFunction(element);
+        expression.element = element;
+        functionName.staticElement = element;
+      } else {
+        SimpleIdentifier propertyNameNode = node.name;
+        if (propertyNameNode == null) {
+          // TODO(brianwilkerson) Report this internal error.
+          return null;
+        }
+        String propertyName = propertyNameNode.name;
+        TopLevelVariableElementImpl variable = _currentHolder
+            .getTopLevelVariable(propertyName) as TopLevelVariableElementImpl;
+        if (variable == null) {
+          variable = new TopLevelVariableElementImpl(node.name.name, -1);
+          variable.final2 = true;
+          variable.synthetic = true;
+          _currentHolder.addTopLevelVariable(variable);
+        }
+        if (node.isGetter) {
+          PropertyAccessorElementImpl getter =
+              new PropertyAccessorElementImpl.forNode(propertyNameNode);
+          _setDoc(getter, node);
+          if (node.externalKeyword != null) {
+            getter.external = true;
+          }
+          getter.functions = holder.functions;
+          getter.labels = holder.labels;
+          getter.localVariables = holder.localVariables;
+          if (body.isAsynchronous) {
+            getter.asynchronous = true;
+          }
+          if (body.isGenerator) {
+            getter.generator = true;
+          }
+          getter.variable = variable;
+          getter.getter = true;
+          getter.static = true;
+          variable.getter = getter;
+          if (node.returnType == null) {
+            getter.hasImplicitReturnType = true;
+          }
+          _currentHolder.addAccessor(getter);
+          expression.element = getter;
+          propertyNameNode.staticElement = getter;
+        } else {
+          PropertyAccessorElementImpl setter =
+              new PropertyAccessorElementImpl.forNode(propertyNameNode);
+          _setDoc(setter, node);
+          if (node.externalKeyword != null) {
+            setter.external = true;
+          }
+          setter.functions = holder.functions;
+          setter.labels = holder.labels;
+          setter.localVariables = holder.localVariables;
+          setter.parameters = holder.parameters;
+          if (body.isAsynchronous) {
+            setter.asynchronous = true;
+          }
+          if (body.isGenerator) {
+            setter.generator = true;
+          }
+          setter.variable = variable;
+          setter.setter = true;
+          setter.static = true;
+          if (node.returnType == null) {
+            setter.hasImplicitReturnType = true;
+          }
+          variable.setter = setter;
+          variable.final2 = false;
+          _currentHolder.addAccessor(setter);
+          expression.element = setter;
+          propertyNameNode.staticElement = setter;
+        }
+      }
+      holder.validate();
+    }
+    return null;
+  }
+
+  @override
+  Object visitFunctionExpression(FunctionExpression node) {
+    if (node.parent is FunctionDeclaration) {
+      // visitFunctionDeclaration has already created the element for the
+      // declaration.  We just need to visit children.
+      return super.visitFunctionExpression(node);
+    }
+    ElementHolder holder = new ElementHolder();
+    bool wasInFunction = _inFunction;
+    _inFunction = true;
+    try {
+      _visitChildren(holder, node);
+    } finally {
+      _inFunction = wasInFunction;
+    }
+    FunctionBody body = node.body;
+    FunctionElementImpl element =
+        new FunctionElementImpl.forOffset(node.beginToken.offset);
+    element.functions = holder.functions;
+    element.labels = holder.labels;
+    element.localVariables = holder.localVariables;
+    element.parameters = holder.parameters;
+    element.typeParameters = holder.typeParameters;
+    if (body.isAsynchronous) {
+      element.asynchronous = true;
+    }
+    if (body.isGenerator) {
+      element.generator = true;
+    }
+    if (_inFunction) {
+      Block enclosingBlock = node.getAncestor((node) => node is Block);
+      if (enclosingBlock != null) {
+        int functionEnd = node.offset + node.length;
+        int blockEnd = enclosingBlock.offset + enclosingBlock.length;
+        element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
+      }
+    }
+    if (_functionTypesToFix != null) {
+      _functionTypesToFix.add(element);
+    } else {
+      element.type = new FunctionTypeImpl(element);
+    }
+    element.hasImplicitReturnType = true;
+    _currentHolder.addFunction(element);
+    node.element = element;
+    holder.validate();
+    return null;
+  }
+
+  @override
+  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
+    ElementHolder holder = new ElementHolder();
+    _visitChildren(holder, node);
+    SimpleIdentifier aliasName = node.name;
+    List<ParameterElement> parameters = holder.parameters;
+    List<TypeParameterElement> typeParameters = holder.typeParameters;
+    FunctionTypeAliasElementImpl element =
+        new FunctionTypeAliasElementImpl.forNode(aliasName);
+    _setDoc(element, node);
+    element.parameters = parameters;
+    element.typeParameters = typeParameters;
+    _createTypeParameterTypes(typeParameters);
+    element.type = new FunctionTypeImpl.forTypedef(element);
+    _currentHolder.addTypeAlias(element);
+    aliasName.staticElement = element;
+    holder.validate();
+    return null;
+  }
+
+  @override
+  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    if (node.parent is! DefaultFormalParameter) {
+      SimpleIdentifier parameterName = node.identifier;
+      ParameterElementImpl parameter =
+          new ParameterElementImpl.forNode(parameterName);
+      parameter.parameterKind = node.kind;
+      _setParameterVisibleRange(node, parameter);
+      _currentHolder.addParameter(parameter);
+      parameterName.staticElement = parameter;
+    }
+    //
+    // The children of this parameter include any parameters defined on the type
+    //of this parameter.
+    //
+    ElementHolder holder = new ElementHolder();
+    _visitChildren(holder, node);
+    ParameterElementImpl element = node.element;
+    element.parameters = holder.parameters;
+    element.typeParameters = holder.typeParameters;
+    holder.validate();
+    return null;
+  }
+
+  @override
+  Object visitLabeledStatement(LabeledStatement node) {
+    bool onSwitchStatement = node.statement is SwitchStatement;
+    for (Label label in node.labels) {
+      SimpleIdentifier labelName = label.label;
+      LabelElementImpl element =
+          new LabelElementImpl(labelName, onSwitchStatement, false);
+      _currentHolder.addLabel(element);
+      labelName.staticElement = element;
+    }
+    return super.visitLabeledStatement(node);
+  }
+
+  @override
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    try {
+      ElementHolder holder = new ElementHolder();
+      bool wasInFunction = _inFunction;
+      _inFunction = true;
+      try {
+        _visitChildren(holder, node);
+      } finally {
+        _inFunction = wasInFunction;
+      }
+      bool isStatic = node.isStatic;
+      Token property = node.propertyKeyword;
+      FunctionBody body = node.body;
+      if (property == null) {
+        SimpleIdentifier methodName = node.name;
+        String nameOfMethod = methodName.name;
+        if (nameOfMethod == TokenType.MINUS.lexeme &&
+            node.parameters.parameters.length == 0) {
+          nameOfMethod = "unary-";
+        }
+        MethodElementImpl element =
+            new MethodElementImpl(nameOfMethod, methodName.offset);
+        _setDoc(element, node);
+        element.abstract = node.isAbstract;
+        if (node.externalKeyword != null) {
+          element.external = true;
+        }
+        element.functions = holder.functions;
+        element.labels = holder.labels;
+        element.localVariables = holder.localVariables;
+        element.parameters = holder.parameters;
+        element.static = isStatic;
+        element.typeParameters = holder.typeParameters;
+        if (body.isAsynchronous) {
+          element.asynchronous = true;
+        }
+        if (body.isGenerator) {
+          element.generator = true;
+        }
+        if (node.returnType == null) {
+          element.hasImplicitReturnType = true;
+        }
+        _currentHolder.addMethod(element);
+        methodName.staticElement = element;
+      } else {
+        SimpleIdentifier propertyNameNode = node.name;
+        String propertyName = propertyNameNode.name;
+        FieldElementImpl field =
+            _currentHolder.getField(propertyName) as FieldElementImpl;
+        if (field == null) {
+          field = new FieldElementImpl(node.name.name, -1);
+          field.final2 = true;
+          field.static = isStatic;
+          field.synthetic = true;
+          _currentHolder.addField(field);
+        }
+        if (node.isGetter) {
+          PropertyAccessorElementImpl getter =
+              new PropertyAccessorElementImpl.forNode(propertyNameNode);
+          _setDoc(getter, node);
+          if (node.externalKeyword != null) {
+            getter.external = true;
+          }
+          getter.functions = holder.functions;
+          getter.labels = holder.labels;
+          getter.localVariables = holder.localVariables;
+          if (body.isAsynchronous) {
+            getter.asynchronous = true;
+          }
+          if (body.isGenerator) {
+            getter.generator = true;
+          }
+          getter.variable = field;
+          getter.abstract = node.isAbstract;
+          getter.getter = true;
+          getter.static = isStatic;
+          field.getter = getter;
+          if (node.returnType == null) {
+            getter.hasImplicitReturnType = true;
+          }
+          _currentHolder.addAccessor(getter);
+          propertyNameNode.staticElement = getter;
+        } else {
+          PropertyAccessorElementImpl setter =
+              new PropertyAccessorElementImpl.forNode(propertyNameNode);
+          _setDoc(setter, node);
+          if (node.externalKeyword != null) {
+            setter.external = true;
+          }
+          setter.functions = holder.functions;
+          setter.labels = holder.labels;
+          setter.localVariables = holder.localVariables;
+          setter.parameters = holder.parameters;
+          if (body.isAsynchronous) {
+            setter.asynchronous = true;
+          }
+          if (body.isGenerator) {
+            setter.generator = true;
+          }
+          setter.variable = field;
+          setter.abstract = node.isAbstract;
+          setter.setter = true;
+          setter.static = isStatic;
+          if (node.returnType == null) {
+            setter.hasImplicitReturnType = true;
+          }
+          field.setter = setter;
+          field.final2 = false;
+          _currentHolder.addAccessor(setter);
+          propertyNameNode.staticElement = setter;
+        }
+      }
+      holder.validate();
+    } catch (exception, stackTrace) {
+      if (node.name.staticElement == null) {
+        ClassDeclaration classNode =
+            node.getAncestor((node) => node is ClassDeclaration);
+        StringBuffer buffer = new StringBuffer();
+        buffer.write("The element for the method ");
+        buffer.write(node.name);
+        buffer.write(" in ");
+        buffer.write(classNode.name);
+        buffer.write(" was not set while trying to build the element model.");
+        AnalysisEngine.instance.logger.logError(
+            buffer.toString(), new CaughtException(exception, stackTrace));
+      } else {
+        String message =
+            "Exception caught in ElementBuilder.visitMethodDeclaration()";
+        AnalysisEngine.instance.logger
+            .logError(message, new CaughtException(exception, stackTrace));
+      }
+    } finally {
+      if (node.name.staticElement == null) {
+        ClassDeclaration classNode =
+            node.getAncestor((node) => node is ClassDeclaration);
+        StringBuffer buffer = new StringBuffer();
+        buffer.write("The element for the method ");
+        buffer.write(node.name);
+        buffer.write(" in ");
+        buffer.write(classNode.name);
+        buffer.write(" was not set while trying to resolve types.");
+        AnalysisEngine.instance.logger.logError(
+            buffer.toString(),
+            new CaughtException(
+                new AnalysisException(buffer.toString()), null));
+      }
+    }
+    return null;
+  }
+
+  @override
+  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
+    if (node.parent is! DefaultFormalParameter) {
+      SimpleIdentifier parameterName = node.identifier;
+      ParameterElementImpl parameter =
+          new ParameterElementImpl.forNode(parameterName);
+      parameter.const3 = node.isConst;
+      parameter.final2 = node.isFinal;
+      parameter.parameterKind = node.kind;
+      _setParameterVisibleRange(node, parameter);
+      if (node.type == null) {
+        parameter.hasImplicitType = true;
+      }
+      _currentHolder.addParameter(parameter);
+      parameterName.staticElement = parameter;
+    }
+    return super.visitSimpleFormalParameter(node);
+  }
+
+  @override
+  Object visitSwitchCase(SwitchCase node) {
+    for (Label label in node.labels) {
+      SimpleIdentifier labelName = label.label;
+      LabelElementImpl element = new LabelElementImpl(labelName, false, true);
+      _currentHolder.addLabel(element);
+      labelName.staticElement = element;
+    }
+    return super.visitSwitchCase(node);
+  }
+
+  @override
+  Object visitSwitchDefault(SwitchDefault node) {
+    for (Label label in node.labels) {
+      SimpleIdentifier labelName = label.label;
+      LabelElementImpl element = new LabelElementImpl(labelName, false, true);
+      _currentHolder.addLabel(element);
+      labelName.staticElement = element;
+    }
+    return super.visitSwitchDefault(node);
+  }
+
+  @override
+  Object visitTypeParameter(TypeParameter node) {
+    SimpleIdentifier parameterName = node.name;
+    TypeParameterElementImpl typeParameter =
+        new TypeParameterElementImpl.forNode(parameterName);
+    TypeParameterTypeImpl typeParameterType =
+        new TypeParameterTypeImpl(typeParameter);
+    typeParameter.type = typeParameterType;
+    _currentHolder.addTypeParameter(typeParameter);
+    parameterName.staticElement = typeParameter;
+    return super.visitTypeParameter(node);
+  }
+
+  @override
+  Object visitVariableDeclaration(VariableDeclaration node) {
+    bool isConst = node.isConst;
+    bool isFinal = node.isFinal;
+    bool hasInitializer = node.initializer != null;
+    VariableElementImpl element;
+    if (_inFieldContext) {
+      SimpleIdentifier fieldName = node.name;
+      FieldElementImpl field;
+      if ((isConst || isFinal) && hasInitializer) {
+        field = new ConstFieldElementImpl.forNode(fieldName);
+      } else {
+        field = new FieldElementImpl.forNode(fieldName);
+      }
+      element = field;
+      if (node.parent.parent is FieldDeclaration) {
+        _setDoc(element, node.parent.parent);
+      }
+      if ((node.parent as VariableDeclarationList).type == null) {
+        field.hasImplicitType = true;
+      }
+      _currentHolder.addField(field);
+      fieldName.staticElement = field;
+    } else if (_inFunction) {
+      SimpleIdentifier variableName = node.name;
+      LocalVariableElementImpl variable;
+      if (isConst && hasInitializer) {
+        variable = new ConstLocalVariableElementImpl.forNode(variableName);
+      } else {
+        variable = new LocalVariableElementImpl.forNode(variableName);
+      }
+      element = variable;
+      Block enclosingBlock = node.getAncestor((node) => node is Block);
+      // TODO(brianwilkerson) This isn't right for variables declared in a for
+      // loop.
+      variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
+      if ((node.parent as VariableDeclarationList).type == null) {
+        variable.hasImplicitType = true;
+      }
+      _currentHolder.addLocalVariable(variable);
+      variableName.staticElement = element;
+    } else {
+      SimpleIdentifier variableName = node.name;
+      TopLevelVariableElementImpl variable;
+      if (isConst && hasInitializer) {
+        variable = new ConstTopLevelVariableElementImpl.forNode(variableName);
+      } else {
+        variable = new TopLevelVariableElementImpl.forNode(variableName);
+      }
+      element = variable;
+      if (node.parent.parent is TopLevelVariableDeclaration) {
+        _setDoc(element, node.parent.parent);
+      }
+      if ((node.parent as VariableDeclarationList).type == null) {
+        variable.hasImplicitType = true;
+      }
+      _currentHolder.addTopLevelVariable(variable);
+      variableName.staticElement = element;
+    }
+    element.const3 = isConst;
+    element.final2 = isFinal;
+    if (hasInitializer) {
+      ElementHolder holder = new ElementHolder();
+      bool wasInFieldContext = _inFieldContext;
+      _inFieldContext = false;
+      try {
+        _visit(holder, node.initializer);
+      } finally {
+        _inFieldContext = wasInFieldContext;
+      }
+      FunctionElementImpl initializer =
+          new FunctionElementImpl.forOffset(node.initializer.beginToken.offset);
+      initializer.functions = holder.functions;
+      initializer.labels = holder.labels;
+      initializer.localVariables = holder.localVariables;
+      initializer.synthetic = true;
+      element.initializer = initializer;
+      holder.validate();
+    }
+    if (element is PropertyInducingElementImpl) {
+      if (_inFieldContext) {
+        (element as FieldElementImpl).static =
+            (node.parent.parent as FieldDeclaration).isStatic;
+      }
+      PropertyAccessorElementImpl getter =
+          new PropertyAccessorElementImpl.forVariable(element);
+      getter.getter = true;
+      if (element.hasImplicitType) {
+        getter.hasImplicitReturnType = true;
+      }
+      _currentHolder.addAccessor(getter);
+      element.getter = getter;
+      if (!isConst && !isFinal) {
+        PropertyAccessorElementImpl setter =
+            new PropertyAccessorElementImpl.forVariable(element);
+        setter.setter = true;
+        ParameterElementImpl parameter =
+            new ParameterElementImpl("_${element.name}", element.nameOffset);
+        parameter.synthetic = true;
+        parameter.parameterKind = ParameterKind.REQUIRED;
+        setter.parameters = <ParameterElement>[parameter];
+        _currentHolder.addAccessor(setter);
+        element.setter = setter;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Build the table mapping field names to field elements for the fields defined in the current
+   * class.
+   *
+   * @param fields the field elements defined in the current class
+   */
+  void _buildFieldMap(List<FieldElement> fields) {
+    _fieldMap = new HashMap<String, FieldElement>();
+    int count = fields.length;
+    for (int i = 0; i < count; i++) {
+      FieldElement field = fields[i];
+      _fieldMap[field.name] = field;
+    }
+  }
+
+  /**
+   * Creates the [ConstructorElement]s array with the single default constructor element.
+   *
+   * @param interfaceType the interface type for which to create a default constructor
+   * @return the [ConstructorElement]s array with the single default constructor element
+   */
+  List<ConstructorElement> _createDefaultConstructors(
+      ClassElementImpl definingClass) {
+    ConstructorElementImpl constructor =
+        new ConstructorElementImpl.forNode(null);
+    constructor.synthetic = true;
+    constructor.returnType = definingClass.type;
+    constructor.enclosingElement = definingClass;
+    constructor.type = new FunctionTypeImpl(constructor);
+    return <ConstructorElement>[constructor];
+  }
+
+  /**
+   * Create the types associated with the given type parameters, setting the type of each type
+   * parameter, and return an array of types corresponding to the given parameters.
+   *
+   * @param typeParameters the type parameters for which types are to be created
+   * @return an array of types corresponding to the given parameters
+   */
+  List<DartType> _createTypeParameterTypes(
+      List<TypeParameterElement> typeParameters) {
+    int typeParameterCount = typeParameters.length;
+    List<DartType> typeArguments = new List<DartType>(typeParameterCount);
+    for (int i = 0; i < typeParameterCount; i++) {
+      TypeParameterElementImpl typeParameter =
+          typeParameters[i] as TypeParameterElementImpl;
+      TypeParameterTypeImpl typeParameterType =
+          new TypeParameterTypeImpl(typeParameter);
+      typeParameter.type = typeParameterType;
+      typeArguments[i] = typeParameterType;
+    }
+    return typeArguments;
+  }
+
+  /**
+   * Return the body of the function that contains the given parameter, or `null` if no
+   * function body could be found.
+   *
+   * @param node the parameter contained in the function whose body is to be returned
+   * @return the body of the function that contains the given parameter
+   */
+  FunctionBody _getFunctionBody(FormalParameter node) {
+    AstNode parent = node.parent;
+    while (parent != null) {
+      if (parent is ConstructorDeclaration) {
+        return parent.body;
+      } else if (parent is FunctionExpression) {
+        return parent.body;
+      } else if (parent is MethodDeclaration) {
+        return parent.body;
+      }
+      parent = parent.parent;
+    }
+    return null;
+  }
+
+  /**
+   * If the given [node] has a documentation comment, remember its content
+   * and range into the given [element].
+   */
+  void _setDoc(ElementImpl element, AnnotatedNode node) {
+    Comment comment = node.documentationComment;
+    if (comment != null && comment.isDocumentation) {
+      element.documentationComment =
+          comment.tokens.map((Token t) => t.lexeme).join('\n');
+      element.setDocRange(comment.offset, comment.length);
+    }
+  }
+
+  /**
+   * Sets the visible source range for formal parameter.
+   */
+  void _setParameterVisibleRange(
+      FormalParameter node, ParameterElementImpl element) {
+    FunctionBody body = _getFunctionBody(node);
+    if (body != null) {
+      element.setVisibleRange(body.offset, body.length);
+    }
+  }
+
+  /**
+   * Make the given holder be the current holder while visiting the given node.
+   *
+   * @param holder the holder that will gather elements that are built while visiting the children
+   * @param node the node to be visited
+   */
+  void _visit(ElementHolder holder, AstNode node) {
+    if (node != null) {
+      ElementHolder previousHolder = _currentHolder;
+      _currentHolder = holder;
+      try {
+        node.accept(this);
+      } finally {
+        _currentHolder = previousHolder;
+      }
+    }
+  }
+
+  /**
+   * Make the given holder be the current holder while visiting the children of the given node.
+   *
+   * @param holder the holder that will gather elements that are built while visiting the children
+   * @param node the node whose children are to be visited
+   */
+  void _visitChildren(ElementHolder holder, AstNode node) {
+    if (node != null) {
+      ElementHolder previousHolder = _currentHolder;
+      _currentHolder = holder;
+      try {
+        node.visitChildren(this);
+      } finally {
+        _currentHolder = previousHolder;
+      }
+    }
+  }
+}
+
+class _ElementBuilder_visitClassDeclaration extends UnifyingAstVisitor<Object> {
+  final ElementBuilder builder;
+
+  List<ClassMember> nonFields;
+
+  _ElementBuilder_visitClassDeclaration(this.builder, this.nonFields) : super();
+
+  @override
+  Object visitConstructorDeclaration(ConstructorDeclaration node) {
+    nonFields.add(node);
+    return null;
+  }
+
+  @override
+  Object visitMethodDeclaration(MethodDeclaration node) {
+    nonFields.add(node);
+    return null;
+  }
+
+  @override
+  Object visitNode(AstNode node) => node.accept(builder);
+}
+
+/**
+ * Instances of the class [_NamespaceCombinatorBuilder] can be used to visit
+ * [Combinator] AST nodes and generate [NamespaceCombinator] elements.
+ */
+class _NamespaceCombinatorBuilder extends SimpleAstVisitor<Object> {
+  /**
+   * Elements generated so far.
+   */
+  final List<NamespaceCombinator> combinators = <NamespaceCombinator>[];
+
+  @override
+  Object visitHideCombinator(HideCombinator node) {
+    HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
+    hide.hiddenNames = _getIdentifiers(node.hiddenNames);
+    combinators.add(hide);
+    return null;
+  }
+
+  @override
+  Object visitShowCombinator(ShowCombinator node) {
+    ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
+    show.offset = node.offset;
+    show.end = node.end;
+    show.shownNames = _getIdentifiers(node.shownNames);
+    combinators.add(show);
+    return null;
+  }
+
+  /**
+   * Return the lexical identifiers associated with the given [identifiers].
+   */
+  static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) {
+    return identifiers.map((identifier) => identifier.name).toList();
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index e319acf..1ae2e9d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -1400,10 +1400,18 @@
   EvaluationResultImpl _result;
 
   /**
+   * Initialize a newly created synthetic top-level variable element to have the
+   * given [name] and [offset].
+   */
+  ConstTopLevelVariableElementImpl(String name, int offset)
+      : super(name, offset);
+
+  /**
    * Initialize a newly created top-level variable element to have the given
    * [name].
    */
-  ConstTopLevelVariableElementImpl(Identifier name) : super.forNode(name);
+  ConstTopLevelVariableElementImpl.forNode(Identifier name)
+      : super.forNode(name);
 
   @override
   DartObject get constantValue => _result.value;
@@ -4096,6 +4104,18 @@
    */
   ParameterElementImpl.forNode(Identifier name) : super.forNode(name);
 
+  /**
+   * Creates a synthetic parameter with [name], [type] and [kind].
+   */
+  factory ParameterElementImpl.synthetic(String name, DartType type,
+      ParameterKind kind) {
+    ParameterElementImpl element = new ParameterElementImpl(name, -1);
+    element.type = type;
+    element.synthetic = true;
+    element.parameterKind = kind;
+    return element;
+  }
+
   @override
   String get defaultValueCode => _defaultValueCode;
 
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 0f8ec27..0383846 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -18,6 +18,11 @@
 import 'package:analyzer/src/generated/utilities_dart.dart';
 
 /**
+ * Type of callbacks used by [DeferredFunctionTypeImpl].
+ */
+typedef FunctionTypedElement FunctionTypedElementComputer();
+
+/**
  * A [Type] that represents the type 'bottom'.
  */
 class BottomTypeImpl extends TypeImpl {
@@ -90,6 +95,41 @@
 }
 
 /**
+ * The type of a function, method, constructor, getter, or setter that has been
+ * resynthesized from a summary.  The actual underlying element won't be
+ * constructed until it's needed.
+ */
+class DeferredFunctionTypeImpl extends FunctionTypeImpl {
+  /**
+   * Callback which should be invoked when the element associated with this
+   * function type is needed.
+   *
+   * Once the callback has been invoked, it is set to `null` to reduce GC
+   * pressure.
+   */
+  FunctionTypedElementComputer _computeElement;
+
+  /**
+   * If [_computeElement] has been called, the value it returned.  Otherwise
+   * `null`.
+   */
+  FunctionTypedElement _computedElement;
+
+  DeferredFunctionTypeImpl(this._computeElement, String name,
+      List<DartType> typeArguments, bool isInstantiated)
+      : super._(null, name, null, typeArguments, isInstantiated);
+
+  @override
+  FunctionTypedElement get element {
+    if (_computeElement != null) {
+      _computedElement = _computeElement();
+      _computeElement = null;
+    }
+    return _computedElement;
+  }
+}
+
+/**
  * The [Type] representing the type `dynamic`.
  */
 class DynamicTypeImpl extends TypeImpl {
@@ -409,6 +449,14 @@
   }
 
   @override
+  List<String> get normalParameterNames {
+    return baseParameters
+        .where((parameter) => parameter.parameterKind == ParameterKind.REQUIRED)
+        .map((parameter) => parameter.name)
+        .toList();
+  }
+
+  @override
   List<DartType> get optionalParameterTypes {
     List<ParameterElement> parameters = baseParameters;
     if (parameters.length == 0) {
@@ -434,6 +482,15 @@
   }
 
   @override
+  List<String> get optionalParameterNames {
+    return baseParameters
+        .where(
+            (parameter) => parameter.parameterKind == ParameterKind.POSITIONAL)
+        .map((parameter) => parameter.name)
+        .toList();
+  }
+
+  @override
   List<ParameterElement> get parameters {
     List<ParameterElement> baseParameters = this.baseParameters;
     // no parameters, quick return
@@ -1029,19 +1086,6 @@
   }
 
   /**
-   * Compute the least upper bound of types [f] and [g], both of which are
-   * known to be function types.
-   *
-   * In the event that f and g have different numbers of required parameters,
-   * `null` is returned, in which case the least upper bound is the interface
-   * type `Function`.
-   */
-  static FunctionType computeLeastUpperBound(FunctionType f, FunctionType g) {
-    // TODO(paulberry): implement this.
-    return null;
-  }
-
-  /**
    * Return `true` if all of the name/type pairs in the first map ([firstTypes])
    * are equal to the corresponding name/type pairs in the second map
    * ([secondTypes]). The maps are expected to iterate over their entries in the
@@ -1941,7 +1985,8 @@
    * If there is a single type which is at least as specific as all of the
    * types in [types], return it.  Otherwise return `null`.
    */
-  static DartType _findMostSpecificType(List<DartType> types, TypeSystem typeSystem) {
+  static DartType _findMostSpecificType(
+      List<DartType> types, TypeSystem typeSystem) {
     // The << relation ("more specific than") is a partial ordering on types,
     // so to find the most specific type of a set, we keep a bucket of the most
     // specific types seen so far such that no type in the bucket is more
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index efb81e3..1f5635c 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -1799,8 +1799,8 @@
       return null;
     }
     bool errorOccurred = false;
-    HashMap<DartObjectImpl, DartObjectImpl> map =
-        new HashMap<DartObjectImpl, DartObjectImpl>();
+    LinkedHashMap<DartObjectImpl, DartObjectImpl> map =
+        new LinkedHashMap<DartObjectImpl, DartObjectImpl>();
     for (MapLiteralEntry entry in node.entries) {
       DartObjectImpl keyResult = entry.key.accept(this);
       DartObjectImpl valueResult = entry.value.accept(this);
diff --git a/pkg/analyzer/lib/src/generated/error.dart b/pkg/analyzer/lib/src/generated/error.dart
index 777e5bc..fe21b9d 100644
--- a/pkg/analyzer/lib/src/generated/error.dart
+++ b/pkg/analyzer/lib/src/generated/error.dart
@@ -19,8 +19,6 @@
 import 'package:analyzer/task/model.dart';
 import 'package:source_span/source_span.dart';
 
-import 'generated/shared_messages.dart' as shared_messages;
-
 /**
  * The descriptor used to associate error processors with analysis contexts in
  * configuration data.
@@ -1660,25 +1658,6 @@
           "Map literals must be prefixed with 'const' when used as a constant expression");
 
   /**
-   * Enum proposal: It is a static warning if all of the following conditions
-   * hold:
-   * * The switch statement does not have a 'default' clause.
-   * * The static type of <i>e</i> is an enumerated typed with elements
-   *   <i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>.
-   * * The sets {<i>e<sub>1</sub></i>, &hellip;, <i>e<sub>k</sub></i>} and
-   *   {<i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>} are not the
-   *   same.
-   *
-   * Parameters:
-   * 0: the name of the constant that is missing
-   */
-  static const CompileTimeErrorCode MISSING_ENUM_CONSTANT_IN_SWITCH =
-      const CompileTimeErrorCode(
-          'MISSING_ENUM_CONSTANT_IN_SWITCH',
-          "Missing case clause for '{0}'",
-          "Add a case clause for the missing constant or add a default clause.");
-
-  /**
    * 9 Mixins: It is a compile-time error if a declared or derived mixin
    * explicitly declares a constructor.
    *
@@ -2615,7 +2594,6 @@
     CompileTimeErrorCode.METHOD_AND_GETTER_WITH_SAME_NAME,
     CompileTimeErrorCode.MISSING_CONST_IN_LIST_LITERAL,
     CompileTimeErrorCode.MISSING_CONST_IN_MAP_LITERAL,
-    CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
     CompileTimeErrorCode.MIXIN_DECLARES_CONSTRUCTOR,
     CompileTimeErrorCode.MIXIN_DEFERRED_CLASS,
     CompileTimeErrorCode.MIXIN_HAS_NO_CONSTRUCTORS,
@@ -2850,6 +2828,7 @@
     StaticWarningCode.UNDEFINED_SUPER_GETTER,
     StaticWarningCode.UNDEFINED_SUPER_SETTER,
     StaticWarningCode.VOID_RETURN_FOR_GETTER,
+    StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
     TodoCode.TODO,
 
     //
@@ -5648,6 +5627,24 @@
           "The return type of the getter must not be 'void'");
 
   /**
+   * 17.9 Switch: It is a static warning if all of the following conditions
+   * hold:
+   * * The switch statement does not have a 'default' clause.
+   * * The static type of <i>e</i> is an enumerated typed with elements
+   *   <i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>.
+   * * The sets {<i>e<sub>1</sub></i>, &hellip;, <i>e<sub>k</sub></i>} and
+   *   {<i>id<sub>1</sub></i>, &hellip;, <i>id<sub>n</sub></i>} are not the
+   *   same.
+   *
+   * Parameters:
+   * 0: the name of the constant that is missing
+   */
+  static const StaticWarningCode MISSING_ENUM_CONSTANT_IN_SWITCH =
+      const StaticWarningCode('MISSING_ENUM_CONSTANT_IN_SWITCH',
+          "Missing case clause for '{0}'",
+          "Add a case clause for the missing constant or add a default clause.");
+
+  /**
    * Initialize a newly created error code to have the given [name]. The message
    * associated with the error will be created from the given [message]
    * template. The correction associated with the error will be created from the
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index 20462bb..ac73a8a 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -4280,7 +4280,7 @@
       int offset = statement.offset;
       int end = statement.rightParenthesis.end;
       _errorReporter.reportErrorForOffset(
-          CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
+          StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
           offset,
           end - offset,
           [constantNames[i]]);
diff --git a/pkg/analyzer/lib/src/generated/incremental_resolver.dart b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
index 542e721..d810b92 100644
--- a/pkg/analyzer/lib/src/generated/incremental_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/incremental_resolver.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 4ed3deb..612912d 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -1022,43 +1022,6 @@
 }
 
 /**
- * A `CompilationUnitBuilder` builds an element model for a single compilation
- * unit.
- */
-class CompilationUnitBuilder {
-  /**
-   * Build the compilation unit element for the given [source] based on the
-   * compilation [unit] associated with the source. Throw an AnalysisException
-   * if the element could not be built.  [librarySource] is the source for the
-   * containing library.
-   */
-  CompilationUnitElementImpl buildCompilationUnit(
-      Source source, CompilationUnit unit, Source librarySource) {
-    return PerformanceStatistics.resolve.makeCurrentWhile(() {
-      if (unit == null) {
-        return null;
-      }
-      ElementHolder holder = new ElementHolder();
-      ElementBuilder builder = new ElementBuilder(holder);
-      unit.accept(builder);
-      CompilationUnitElementImpl element =
-          new CompilationUnitElementImpl(source.shortName);
-      element.accessors = holder.accessors;
-      element.enums = holder.enums;
-      element.functions = holder.functions;
-      element.source = source;
-      element.librarySource = librarySource;
-      element.typeAliases = holder.typeAliases;
-      element.types = holder.types;
-      element.topLevelVariables = holder.topLevelVariables;
-      unit.element = element;
-      holder.validate();
-      return element;
-    });
-  }
-}
-
-/**
  * Instances of the class `ConstantVerifier` traverse an AST structure looking for additional
  * errors and warnings not covered by the parser and resolver. In particular, it looks for errors
  * and warnings related to constant expressions.
@@ -2651,1025 +2614,6 @@
 }
 
 /**
- * Instances of the class `ElementBuilder` traverse an AST structure and build the element
- * model representing the AST structure.
- */
-class ElementBuilder extends RecursiveAstVisitor<Object> {
-  /**
-   * The element holder associated with the element that is currently being built.
-   */
-  ElementHolder _currentHolder;
-
-  /**
-   * A flag indicating whether a variable declaration is in the context of a field declaration.
-   */
-  bool _inFieldContext = false;
-
-  /**
-   * A flag indicating whether a variable declaration is within the body of a method or function.
-   */
-  bool _inFunction = false;
-
-  /**
-   * A collection holding the elements defined in a class that need to have
-   * their function type fixed to take into account type parameters of the
-   * enclosing class, or `null` if we are not currently processing nodes within
-   * a class.
-   */
-  List<ExecutableElementImpl> _functionTypesToFix = null;
-
-  /**
-   * A table mapping field names to field elements for the fields defined in the current class, or
-   * `null` if we are not in the scope of a class.
-   */
-  HashMap<String, FieldElement> _fieldMap;
-
-  /**
-   * Initialize a newly created element builder to build the elements for a compilation unit.
-   *
-   * @param initialHolder the element holder associated with the compilation unit being built
-   */
-  ElementBuilder(ElementHolder initialHolder) {
-    _currentHolder = initialHolder;
-  }
-
-  @override
-  Object visitBlock(Block node) {
-    bool wasInField = _inFieldContext;
-    _inFieldContext = false;
-    try {
-      node.visitChildren(this);
-    } finally {
-      _inFieldContext = wasInField;
-    }
-    return null;
-  }
-
-  @override
-  Object visitCatchClause(CatchClause node) {
-    SimpleIdentifier exceptionParameter = node.exceptionParameter;
-    if (exceptionParameter != null) {
-      // exception
-      LocalVariableElementImpl exception =
-          new LocalVariableElementImpl.forNode(exceptionParameter);
-      if (node.exceptionType == null) {
-        exception.hasImplicitType = true;
-      }
-      _currentHolder.addLocalVariable(exception);
-      exceptionParameter.staticElement = exception;
-      // stack trace
-      SimpleIdentifier stackTraceParameter = node.stackTraceParameter;
-      if (stackTraceParameter != null) {
-        LocalVariableElementImpl stackTrace =
-            new LocalVariableElementImpl.forNode(stackTraceParameter);
-        _currentHolder.addLocalVariable(stackTrace);
-        stackTraceParameter.staticElement = stackTrace;
-      }
-    }
-    return super.visitCatchClause(node);
-  }
-
-  @override
-  Object visitClassDeclaration(ClassDeclaration node) {
-    ElementHolder holder = new ElementHolder();
-    _functionTypesToFix = new List<ExecutableElementImpl>();
-    //
-    // Process field declarations before constructors and methods so that field
-    // formal parameters can be correctly resolved to their fields.
-    //
-    ElementHolder previousHolder = _currentHolder;
-    _currentHolder = holder;
-    try {
-      List<ClassMember> nonFields = new List<ClassMember>();
-      node.visitChildren(
-          new _ElementBuilder_visitClassDeclaration(this, nonFields));
-      _buildFieldMap(holder.fieldsWithoutFlushing);
-      int count = nonFields.length;
-      for (int i = 0; i < count; i++) {
-        nonFields[i].accept(this);
-      }
-    } finally {
-      _currentHolder = previousHolder;
-    }
-    SimpleIdentifier className = node.name;
-    ClassElementImpl element = new ClassElementImpl.forNode(className);
-    List<TypeParameterElement> typeParameters = holder.typeParameters;
-    List<DartType> typeArguments = _createTypeParameterTypes(typeParameters);
-    InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
-    interfaceType.typeArguments = typeArguments;
-    element.type = interfaceType;
-    element.typeParameters = typeParameters;
-    _setDoc(element, node);
-    element.abstract = node.isAbstract;
-    element.accessors = holder.accessors;
-    List<ConstructorElement> constructors = holder.constructors;
-    if (constructors.isEmpty) {
-      constructors = _createDefaultConstructors(element);
-    }
-    element.constructors = constructors;
-    element.fields = holder.fields;
-    element.methods = holder.methods;
-    // Function types must be initialized after the enclosing element has been
-    // set, for them to pick up the type parameters.
-    for (ExecutableElementImpl e in _functionTypesToFix) {
-      e.type = new FunctionTypeImpl(e);
-    }
-    _functionTypesToFix = null;
-    _currentHolder.addType(element);
-    className.staticElement = element;
-    _fieldMap = null;
-    holder.validate();
-    return null;
-  }
-
-  /**
-   * Implementation of this method should be synchronized with
-   * [visitClassDeclaration].
-   */
-  void visitClassDeclarationIncrementally(ClassDeclaration node) {
-    //
-    // Process field declarations before constructors and methods so that field
-    // formal parameters can be correctly resolved to their fields.
-    //
-    ClassElement classElement = node.element;
-    _buildFieldMap(classElement.fields);
-  }
-
-  @override
-  Object visitClassTypeAlias(ClassTypeAlias node) {
-    ElementHolder holder = new ElementHolder();
-    _visitChildren(holder, node);
-    SimpleIdentifier className = node.name;
-    ClassElementImpl element = new ClassElementImpl.forNode(className);
-    element.abstract = node.abstractKeyword != null;
-    element.mixinApplication = true;
-    List<TypeParameterElement> typeParameters = holder.typeParameters;
-    element.typeParameters = typeParameters;
-    List<DartType> typeArguments = _createTypeParameterTypes(typeParameters);
-    InterfaceTypeImpl interfaceType = new InterfaceTypeImpl(element);
-    interfaceType.typeArguments = typeArguments;
-    element.type = interfaceType;
-    _setDoc(element, node);
-    _currentHolder.addType(element);
-    className.staticElement = element;
-    holder.validate();
-    return null;
-  }
-
-  @override
-  Object visitConstructorDeclaration(ConstructorDeclaration node) {
-    ElementHolder holder = new ElementHolder();
-    bool wasInFunction = _inFunction;
-    _inFunction = true;
-    try {
-      _visitChildren(holder, node);
-    } finally {
-      _inFunction = wasInFunction;
-    }
-    FunctionBody body = node.body;
-    SimpleIdentifier constructorName = node.name;
-    ConstructorElementImpl element =
-        new ConstructorElementImpl.forNode(constructorName);
-    _setDoc(element, node);
-    if (node.externalKeyword != null) {
-      element.external = true;
-    }
-    if (node.factoryKeyword != null) {
-      element.factory = true;
-    }
-    element.functions = holder.functions;
-    element.labels = holder.labels;
-    element.localVariables = holder.localVariables;
-    element.parameters = holder.parameters;
-    element.const2 = node.constKeyword != null;
-    if (body.isAsynchronous) {
-      element.asynchronous = true;
-    }
-    if (body.isGenerator) {
-      element.generator = true;
-    }
-    _currentHolder.addConstructor(element);
-    node.element = element;
-    if (constructorName == null) {
-      Identifier returnType = node.returnType;
-      if (returnType != null) {
-        element.nameOffset = returnType.offset;
-        element.nameEnd = returnType.end;
-      }
-    } else {
-      constructorName.staticElement = element;
-      element.periodOffset = node.period.offset;
-      element.nameEnd = constructorName.end;
-    }
-    holder.validate();
-    return null;
-  }
-
-  @override
-  Object visitDeclaredIdentifier(DeclaredIdentifier node) {
-    SimpleIdentifier variableName = node.identifier;
-    LocalVariableElementImpl element =
-        new LocalVariableElementImpl.forNode(variableName);
-    ForEachStatement statement = node.parent as ForEachStatement;
-    int declarationEnd = node.offset + node.length;
-    int statementEnd = statement.offset + statement.length;
-    element.setVisibleRange(declarationEnd, statementEnd - declarationEnd - 1);
-    element.const3 = node.isConst;
-    element.final2 = node.isFinal;
-    if (node.type == null) {
-      element.hasImplicitType = true;
-    }
-    _currentHolder.addLocalVariable(element);
-    variableName.staticElement = element;
-    return super.visitDeclaredIdentifier(node);
-  }
-
-  @override
-  Object visitDefaultFormalParameter(DefaultFormalParameter node) {
-    ElementHolder holder = new ElementHolder();
-    NormalFormalParameter normalParameter = node.parameter;
-    SimpleIdentifier parameterName = normalParameter.identifier;
-    ParameterElementImpl parameter;
-    if (normalParameter is FieldFormalParameter) {
-      parameter = new DefaultFieldFormalParameterElementImpl(parameterName);
-      FieldElement field =
-          _fieldMap == null ? null : _fieldMap[parameterName.name];
-      if (field != null) {
-        (parameter as DefaultFieldFormalParameterElementImpl).field = field;
-      }
-    } else {
-      parameter = new DefaultParameterElementImpl(parameterName);
-    }
-    parameter.const3 = node.isConst;
-    parameter.final2 = node.isFinal;
-    parameter.parameterKind = node.kind;
-    // set initializer, default value range
-    Expression defaultValue = node.defaultValue;
-    if (defaultValue != null) {
-      _visit(holder, defaultValue);
-      FunctionElementImpl initializer =
-          new FunctionElementImpl.forOffset(defaultValue.beginToken.offset);
-      initializer.functions = holder.functions;
-      initializer.labels = holder.labels;
-      initializer.localVariables = holder.localVariables;
-      initializer.parameters = holder.parameters;
-      initializer.synthetic = true;
-      parameter.initializer = initializer;
-      parameter.defaultValueCode = defaultValue.toSource();
-    }
-    // visible range
-    _setParameterVisibleRange(node, parameter);
-    if (normalParameter is SimpleFormalParameter &&
-        normalParameter.type == null) {
-      parameter.hasImplicitType = true;
-    }
-    _currentHolder.addParameter(parameter);
-    parameterName.staticElement = parameter;
-    normalParameter.accept(this);
-    holder.validate();
-    return null;
-  }
-
-  @override
-  Object visitEnumDeclaration(EnumDeclaration node) {
-    SimpleIdentifier enumName = node.name;
-    ClassElementImpl enumElement = new ClassElementImpl.forNode(enumName);
-    enumElement.enum2 = true;
-    _setDoc(enumElement, node);
-    InterfaceTypeImpl enumType = new InterfaceTypeImpl(enumElement);
-    enumElement.type = enumType;
-    // The equivalent code for enums in the spec shows a single constructor,
-    // but that constructor is not callable (since it is a compile-time error
-    // to subclass, mix-in, implement, or explicitly instantiate an enum).  So
-    // we represent this as having no constructors.
-    enumElement.constructors = ConstructorElement.EMPTY_LIST;
-    _currentHolder.addEnum(enumElement);
-    enumName.staticElement = enumElement;
-    return super.visitEnumDeclaration(node);
-  }
-
-  @override
-  Object visitFieldDeclaration(FieldDeclaration node) {
-    bool wasInField = _inFieldContext;
-    _inFieldContext = true;
-    try {
-      node.visitChildren(this);
-    } finally {
-      _inFieldContext = wasInField;
-    }
-    return null;
-  }
-
-  @override
-  Object visitFieldFormalParameter(FieldFormalParameter node) {
-    if (node.parent is! DefaultFormalParameter) {
-      SimpleIdentifier parameterName = node.identifier;
-      FieldElement field =
-          _fieldMap == null ? null : _fieldMap[parameterName.name];
-      FieldFormalParameterElementImpl parameter =
-          new FieldFormalParameterElementImpl(parameterName);
-      parameter.const3 = node.isConst;
-      parameter.final2 = node.isFinal;
-      parameter.parameterKind = node.kind;
-      if (field != null) {
-        parameter.field = field;
-      }
-      _currentHolder.addParameter(parameter);
-      parameterName.staticElement = parameter;
-    }
-    //
-    // The children of this parameter include any parameters defined on the type
-    // of this parameter.
-    //
-    ElementHolder holder = new ElementHolder();
-    _visitChildren(holder, node);
-    ParameterElementImpl element = node.element;
-    element.parameters = holder.parameters;
-    element.typeParameters = holder.typeParameters;
-    holder.validate();
-    return null;
-  }
-
-  @override
-  Object visitFunctionDeclaration(FunctionDeclaration node) {
-    FunctionExpression expression = node.functionExpression;
-    if (expression != null) {
-      ElementHolder holder = new ElementHolder();
-      bool wasInFunction = _inFunction;
-      _inFunction = true;
-      try {
-        _visitChildren(holder, node);
-      } finally {
-        _inFunction = wasInFunction;
-      }
-      FunctionBody body = expression.body;
-      Token property = node.propertyKeyword;
-      if (property == null || _inFunction) {
-        SimpleIdentifier functionName = node.name;
-        FunctionElementImpl element =
-            new FunctionElementImpl.forNode(functionName);
-        _setDoc(element, node);
-        if (node.externalKeyword != null) {
-          element.external = true;
-        }
-        element.functions = holder.functions;
-        element.labels = holder.labels;
-        element.localVariables = holder.localVariables;
-        element.parameters = holder.parameters;
-        element.typeParameters = holder.typeParameters;
-        if (body.isAsynchronous) {
-          element.asynchronous = true;
-        }
-        if (body.isGenerator) {
-          element.generator = true;
-        }
-        if (_inFunction) {
-          Block enclosingBlock = node.getAncestor((node) => node is Block);
-          if (enclosingBlock != null) {
-            int functionEnd = node.offset + node.length;
-            int blockEnd = enclosingBlock.offset + enclosingBlock.length;
-            element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
-          }
-        }
-        if (node.returnType == null) {
-          element.hasImplicitReturnType = true;
-        }
-        _currentHolder.addFunction(element);
-        expression.element = element;
-        functionName.staticElement = element;
-      } else {
-        SimpleIdentifier propertyNameNode = node.name;
-        if (propertyNameNode == null) {
-          // TODO(brianwilkerson) Report this internal error.
-          return null;
-        }
-        String propertyName = propertyNameNode.name;
-        TopLevelVariableElementImpl variable = _currentHolder
-            .getTopLevelVariable(propertyName) as TopLevelVariableElementImpl;
-        if (variable == null) {
-          variable = new TopLevelVariableElementImpl(node.name.name, -1);
-          variable.final2 = true;
-          variable.synthetic = true;
-          _currentHolder.addTopLevelVariable(variable);
-        }
-        if (node.isGetter) {
-          PropertyAccessorElementImpl getter =
-              new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDoc(getter, node);
-          if (node.externalKeyword != null) {
-            getter.external = true;
-          }
-          getter.functions = holder.functions;
-          getter.labels = holder.labels;
-          getter.localVariables = holder.localVariables;
-          if (body.isAsynchronous) {
-            getter.asynchronous = true;
-          }
-          if (body.isGenerator) {
-            getter.generator = true;
-          }
-          getter.variable = variable;
-          getter.getter = true;
-          getter.static = true;
-          variable.getter = getter;
-          if (node.returnType == null) {
-            getter.hasImplicitReturnType = true;
-          }
-          _currentHolder.addAccessor(getter);
-          expression.element = getter;
-          propertyNameNode.staticElement = getter;
-        } else {
-          PropertyAccessorElementImpl setter =
-              new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDoc(setter, node);
-          if (node.externalKeyword != null) {
-            setter.external = true;
-          }
-          setter.functions = holder.functions;
-          setter.labels = holder.labels;
-          setter.localVariables = holder.localVariables;
-          setter.parameters = holder.parameters;
-          if (body.isAsynchronous) {
-            setter.asynchronous = true;
-          }
-          if (body.isGenerator) {
-            setter.generator = true;
-          }
-          setter.variable = variable;
-          setter.setter = true;
-          setter.static = true;
-          if (node.returnType == null) {
-            setter.hasImplicitReturnType = true;
-          }
-          variable.setter = setter;
-          variable.final2 = false;
-          _currentHolder.addAccessor(setter);
-          expression.element = setter;
-          propertyNameNode.staticElement = setter;
-        }
-      }
-      holder.validate();
-    }
-    return null;
-  }
-
-  @override
-  Object visitFunctionExpression(FunctionExpression node) {
-    if (node.parent is FunctionDeclaration) {
-      // visitFunctionDeclaration has already created the element for the
-      // declaration.  We just need to visit children.
-      return super.visitFunctionExpression(node);
-    }
-    ElementHolder holder = new ElementHolder();
-    bool wasInFunction = _inFunction;
-    _inFunction = true;
-    try {
-      _visitChildren(holder, node);
-    } finally {
-      _inFunction = wasInFunction;
-    }
-    FunctionBody body = node.body;
-    FunctionElementImpl element =
-        new FunctionElementImpl.forOffset(node.beginToken.offset);
-    element.functions = holder.functions;
-    element.labels = holder.labels;
-    element.localVariables = holder.localVariables;
-    element.parameters = holder.parameters;
-    element.typeParameters = holder.typeParameters;
-    if (body.isAsynchronous) {
-      element.asynchronous = true;
-    }
-    if (body.isGenerator) {
-      element.generator = true;
-    }
-    if (_inFunction) {
-      Block enclosingBlock = node.getAncestor((node) => node is Block);
-      if (enclosingBlock != null) {
-        int functionEnd = node.offset + node.length;
-        int blockEnd = enclosingBlock.offset + enclosingBlock.length;
-        element.setVisibleRange(functionEnd, blockEnd - functionEnd - 1);
-      }
-    }
-    if (_functionTypesToFix != null) {
-      _functionTypesToFix.add(element);
-    } else {
-      element.type = new FunctionTypeImpl(element);
-    }
-    element.hasImplicitReturnType = true;
-    _currentHolder.addFunction(element);
-    node.element = element;
-    holder.validate();
-    return null;
-  }
-
-  @override
-  Object visitFunctionTypeAlias(FunctionTypeAlias node) {
-    ElementHolder holder = new ElementHolder();
-    _visitChildren(holder, node);
-    SimpleIdentifier aliasName = node.name;
-    List<ParameterElement> parameters = holder.parameters;
-    List<TypeParameterElement> typeParameters = holder.typeParameters;
-    FunctionTypeAliasElementImpl element =
-        new FunctionTypeAliasElementImpl.forNode(aliasName);
-    _setDoc(element, node);
-    element.parameters = parameters;
-    element.typeParameters = typeParameters;
-    _createTypeParameterTypes(typeParameters);
-    element.type = new FunctionTypeImpl.forTypedef(element);
-    _currentHolder.addTypeAlias(element);
-    aliasName.staticElement = element;
-    holder.validate();
-    return null;
-  }
-
-  @override
-  Object visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
-    if (node.parent is! DefaultFormalParameter) {
-      SimpleIdentifier parameterName = node.identifier;
-      ParameterElementImpl parameter =
-          new ParameterElementImpl.forNode(parameterName);
-      parameter.parameterKind = node.kind;
-      _setParameterVisibleRange(node, parameter);
-      _currentHolder.addParameter(parameter);
-      parameterName.staticElement = parameter;
-    }
-    //
-    // The children of this parameter include any parameters defined on the type
-    //of this parameter.
-    //
-    ElementHolder holder = new ElementHolder();
-    _visitChildren(holder, node);
-    ParameterElementImpl element = node.element;
-    element.parameters = holder.parameters;
-    element.typeParameters = holder.typeParameters;
-    holder.validate();
-    return null;
-  }
-
-  @override
-  Object visitLabeledStatement(LabeledStatement node) {
-    bool onSwitchStatement = node.statement is SwitchStatement;
-    for (Label label in node.labels) {
-      SimpleIdentifier labelName = label.label;
-      LabelElementImpl element =
-          new LabelElementImpl(labelName, onSwitchStatement, false);
-      _currentHolder.addLabel(element);
-      labelName.staticElement = element;
-    }
-    return super.visitLabeledStatement(node);
-  }
-
-  @override
-  Object visitMethodDeclaration(MethodDeclaration node) {
-    try {
-      ElementHolder holder = new ElementHolder();
-      bool wasInFunction = _inFunction;
-      _inFunction = true;
-      try {
-        _visitChildren(holder, node);
-      } finally {
-        _inFunction = wasInFunction;
-      }
-      bool isStatic = node.isStatic;
-      Token property = node.propertyKeyword;
-      FunctionBody body = node.body;
-      if (property == null) {
-        SimpleIdentifier methodName = node.name;
-        String nameOfMethod = methodName.name;
-        if (nameOfMethod == TokenType.MINUS.lexeme &&
-            node.parameters.parameters.length == 0) {
-          nameOfMethod = "unary-";
-        }
-        MethodElementImpl element =
-            new MethodElementImpl(nameOfMethod, methodName.offset);
-        _setDoc(element, node);
-        element.abstract = node.isAbstract;
-        if (node.externalKeyword != null) {
-          element.external = true;
-        }
-        element.functions = holder.functions;
-        element.labels = holder.labels;
-        element.localVariables = holder.localVariables;
-        element.parameters = holder.parameters;
-        element.static = isStatic;
-        element.typeParameters = holder.typeParameters;
-        if (body.isAsynchronous) {
-          element.asynchronous = true;
-        }
-        if (body.isGenerator) {
-          element.generator = true;
-        }
-        if (node.returnType == null) {
-          element.hasImplicitReturnType = true;
-        }
-        _currentHolder.addMethod(element);
-        methodName.staticElement = element;
-      } else {
-        SimpleIdentifier propertyNameNode = node.name;
-        String propertyName = propertyNameNode.name;
-        FieldElementImpl field =
-            _currentHolder.getField(propertyName) as FieldElementImpl;
-        if (field == null) {
-          field = new FieldElementImpl(node.name.name, -1);
-          field.final2 = true;
-          field.static = isStatic;
-          field.synthetic = true;
-          _currentHolder.addField(field);
-        }
-        if (node.isGetter) {
-          PropertyAccessorElementImpl getter =
-              new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDoc(getter, node);
-          if (node.externalKeyword != null) {
-            getter.external = true;
-          }
-          getter.functions = holder.functions;
-          getter.labels = holder.labels;
-          getter.localVariables = holder.localVariables;
-          if (body.isAsynchronous) {
-            getter.asynchronous = true;
-          }
-          if (body.isGenerator) {
-            getter.generator = true;
-          }
-          getter.variable = field;
-          getter.abstract = node.isAbstract;
-          getter.getter = true;
-          getter.static = isStatic;
-          field.getter = getter;
-          if (node.returnType == null) {
-            getter.hasImplicitReturnType = true;
-          }
-          _currentHolder.addAccessor(getter);
-          propertyNameNode.staticElement = getter;
-        } else {
-          PropertyAccessorElementImpl setter =
-              new PropertyAccessorElementImpl.forNode(propertyNameNode);
-          _setDoc(setter, node);
-          if (node.externalKeyword != null) {
-            setter.external = true;
-          }
-          setter.functions = holder.functions;
-          setter.labels = holder.labels;
-          setter.localVariables = holder.localVariables;
-          setter.parameters = holder.parameters;
-          if (body.isAsynchronous) {
-            setter.asynchronous = true;
-          }
-          if (body.isGenerator) {
-            setter.generator = true;
-          }
-          setter.variable = field;
-          setter.abstract = node.isAbstract;
-          setter.setter = true;
-          setter.static = isStatic;
-          if (node.returnType == null) {
-            setter.hasImplicitReturnType = true;
-          }
-          field.setter = setter;
-          field.final2 = false;
-          _currentHolder.addAccessor(setter);
-          propertyNameNode.staticElement = setter;
-        }
-      }
-      holder.validate();
-    } catch (exception, stackTrace) {
-      if (node.name.staticElement == null) {
-        ClassDeclaration classNode =
-            node.getAncestor((node) => node is ClassDeclaration);
-        StringBuffer buffer = new StringBuffer();
-        buffer.write("The element for the method ");
-        buffer.write(node.name);
-        buffer.write(" in ");
-        buffer.write(classNode.name);
-        buffer.write(" was not set while trying to build the element model.");
-        AnalysisEngine.instance.logger.logError(
-            buffer.toString(), new CaughtException(exception, stackTrace));
-      } else {
-        String message =
-            "Exception caught in ElementBuilder.visitMethodDeclaration()";
-        AnalysisEngine.instance.logger
-            .logError(message, new CaughtException(exception, stackTrace));
-      }
-    } finally {
-      if (node.name.staticElement == null) {
-        ClassDeclaration classNode =
-            node.getAncestor((node) => node is ClassDeclaration);
-        StringBuffer buffer = new StringBuffer();
-        buffer.write("The element for the method ");
-        buffer.write(node.name);
-        buffer.write(" in ");
-        buffer.write(classNode.name);
-        buffer.write(" was not set while trying to resolve types.");
-        AnalysisEngine.instance.logger.logError(
-            buffer.toString(),
-            new CaughtException(
-                new AnalysisException(buffer.toString()), null));
-      }
-    }
-    return null;
-  }
-
-  @override
-  Object visitSimpleFormalParameter(SimpleFormalParameter node) {
-    if (node.parent is! DefaultFormalParameter) {
-      SimpleIdentifier parameterName = node.identifier;
-      ParameterElementImpl parameter =
-          new ParameterElementImpl.forNode(parameterName);
-      parameter.const3 = node.isConst;
-      parameter.final2 = node.isFinal;
-      parameter.parameterKind = node.kind;
-      _setParameterVisibleRange(node, parameter);
-      if (node.type == null) {
-        parameter.hasImplicitType = true;
-      }
-      _currentHolder.addParameter(parameter);
-      parameterName.staticElement = parameter;
-    }
-    return super.visitSimpleFormalParameter(node);
-  }
-
-  @override
-  Object visitSwitchCase(SwitchCase node) {
-    for (Label label in node.labels) {
-      SimpleIdentifier labelName = label.label;
-      LabelElementImpl element = new LabelElementImpl(labelName, false, true);
-      _currentHolder.addLabel(element);
-      labelName.staticElement = element;
-    }
-    return super.visitSwitchCase(node);
-  }
-
-  @override
-  Object visitSwitchDefault(SwitchDefault node) {
-    for (Label label in node.labels) {
-      SimpleIdentifier labelName = label.label;
-      LabelElementImpl element = new LabelElementImpl(labelName, false, true);
-      _currentHolder.addLabel(element);
-      labelName.staticElement = element;
-    }
-    return super.visitSwitchDefault(node);
-  }
-
-  @override
-  Object visitTypeParameter(TypeParameter node) {
-    SimpleIdentifier parameterName = node.name;
-    TypeParameterElementImpl typeParameter =
-        new TypeParameterElementImpl.forNode(parameterName);
-    TypeParameterTypeImpl typeParameterType =
-        new TypeParameterTypeImpl(typeParameter);
-    typeParameter.type = typeParameterType;
-    _currentHolder.addTypeParameter(typeParameter);
-    parameterName.staticElement = typeParameter;
-    return super.visitTypeParameter(node);
-  }
-
-  @override
-  Object visitVariableDeclaration(VariableDeclaration node) {
-    bool isConst = node.isConst;
-    bool isFinal = node.isFinal;
-    bool hasInitializer = node.initializer != null;
-    VariableElementImpl element;
-    if (_inFieldContext) {
-      SimpleIdentifier fieldName = node.name;
-      FieldElementImpl field;
-      if ((isConst || isFinal) && hasInitializer) {
-        field = new ConstFieldElementImpl.forNode(fieldName);
-      } else {
-        field = new FieldElementImpl.forNode(fieldName);
-      }
-      element = field;
-      if (node.parent.parent is FieldDeclaration) {
-        _setDoc(element, node.parent.parent);
-      }
-      if ((node.parent as VariableDeclarationList).type == null) {
-        field.hasImplicitType = true;
-      }
-      _currentHolder.addField(field);
-      fieldName.staticElement = field;
-    } else if (_inFunction) {
-      SimpleIdentifier variableName = node.name;
-      LocalVariableElementImpl variable;
-      if (isConst && hasInitializer) {
-        variable = new ConstLocalVariableElementImpl.forNode(variableName);
-      } else {
-        variable = new LocalVariableElementImpl.forNode(variableName);
-      }
-      element = variable;
-      Block enclosingBlock = node.getAncestor((node) => node is Block);
-      // TODO(brianwilkerson) This isn't right for variables declared in a for
-      // loop.
-      variable.setVisibleRange(enclosingBlock.offset, enclosingBlock.length);
-      if ((node.parent as VariableDeclarationList).type == null) {
-        variable.hasImplicitType = true;
-      }
-      _currentHolder.addLocalVariable(variable);
-      variableName.staticElement = element;
-    } else {
-      SimpleIdentifier variableName = node.name;
-      TopLevelVariableElementImpl variable;
-      if (isConst && hasInitializer) {
-        variable = new ConstTopLevelVariableElementImpl(variableName);
-      } else {
-        variable = new TopLevelVariableElementImpl.forNode(variableName);
-      }
-      element = variable;
-      if (node.parent.parent is TopLevelVariableDeclaration) {
-        _setDoc(element, node.parent.parent);
-      }
-      if ((node.parent as VariableDeclarationList).type == null) {
-        variable.hasImplicitType = true;
-      }
-      _currentHolder.addTopLevelVariable(variable);
-      variableName.staticElement = element;
-    }
-    element.const3 = isConst;
-    element.final2 = isFinal;
-    if (hasInitializer) {
-      ElementHolder holder = new ElementHolder();
-      bool wasInFieldContext = _inFieldContext;
-      _inFieldContext = false;
-      try {
-        _visit(holder, node.initializer);
-      } finally {
-        _inFieldContext = wasInFieldContext;
-      }
-      FunctionElementImpl initializer =
-          new FunctionElementImpl.forOffset(node.initializer.beginToken.offset);
-      initializer.functions = holder.functions;
-      initializer.labels = holder.labels;
-      initializer.localVariables = holder.localVariables;
-      initializer.synthetic = true;
-      element.initializer = initializer;
-      holder.validate();
-    }
-    if (element is PropertyInducingElementImpl) {
-      if (_inFieldContext) {
-        (element as FieldElementImpl).static =
-            (node.parent.parent as FieldDeclaration).isStatic;
-      }
-      PropertyAccessorElementImpl getter =
-          new PropertyAccessorElementImpl.forVariable(element);
-      getter.getter = true;
-      if (element.hasImplicitType) {
-        getter.hasImplicitReturnType = true;
-      }
-      _currentHolder.addAccessor(getter);
-      element.getter = getter;
-      if (!isConst && !isFinal) {
-        PropertyAccessorElementImpl setter =
-            new PropertyAccessorElementImpl.forVariable(element);
-        setter.setter = true;
-        ParameterElementImpl parameter =
-            new ParameterElementImpl("_${element.name}", element.nameOffset);
-        parameter.synthetic = true;
-        parameter.parameterKind = ParameterKind.REQUIRED;
-        setter.parameters = <ParameterElement>[parameter];
-        _currentHolder.addAccessor(setter);
-        element.setter = setter;
-      }
-    }
-    return null;
-  }
-
-  /**
-   * Build the table mapping field names to field elements for the fields defined in the current
-   * class.
-   *
-   * @param fields the field elements defined in the current class
-   */
-  void _buildFieldMap(List<FieldElement> fields) {
-    _fieldMap = new HashMap<String, FieldElement>();
-    int count = fields.length;
-    for (int i = 0; i < count; i++) {
-      FieldElement field = fields[i];
-      _fieldMap[field.name] = field;
-    }
-  }
-
-  /**
-   * Creates the [ConstructorElement]s array with the single default constructor element.
-   *
-   * @param interfaceType the interface type for which to create a default constructor
-   * @return the [ConstructorElement]s array with the single default constructor element
-   */
-  List<ConstructorElement> _createDefaultConstructors(
-      ClassElementImpl definingClass) {
-    ConstructorElementImpl constructor =
-        new ConstructorElementImpl.forNode(null);
-    constructor.synthetic = true;
-    constructor.returnType = definingClass.type;
-    constructor.enclosingElement = definingClass;
-    constructor.type = new FunctionTypeImpl(constructor);
-    return <ConstructorElement>[constructor];
-  }
-
-  /**
-   * Create the types associated with the given type parameters, setting the type of each type
-   * parameter, and return an array of types corresponding to the given parameters.
-   *
-   * @param typeParameters the type parameters for which types are to be created
-   * @return an array of types corresponding to the given parameters
-   */
-  List<DartType> _createTypeParameterTypes(
-      List<TypeParameterElement> typeParameters) {
-    int typeParameterCount = typeParameters.length;
-    List<DartType> typeArguments = new List<DartType>(typeParameterCount);
-    for (int i = 0; i < typeParameterCount; i++) {
-      TypeParameterElementImpl typeParameter =
-          typeParameters[i] as TypeParameterElementImpl;
-      TypeParameterTypeImpl typeParameterType =
-          new TypeParameterTypeImpl(typeParameter);
-      typeParameter.type = typeParameterType;
-      typeArguments[i] = typeParameterType;
-    }
-    return typeArguments;
-  }
-
-  /**
-   * Return the body of the function that contains the given parameter, or `null` if no
-   * function body could be found.
-   *
-   * @param node the parameter contained in the function whose body is to be returned
-   * @return the body of the function that contains the given parameter
-   */
-  FunctionBody _getFunctionBody(FormalParameter node) {
-    AstNode parent = node.parent;
-    while (parent != null) {
-      if (parent is ConstructorDeclaration) {
-        return parent.body;
-      } else if (parent is FunctionExpression) {
-        return parent.body;
-      } else if (parent is MethodDeclaration) {
-        return parent.body;
-      }
-      parent = parent.parent;
-    }
-    return null;
-  }
-
-  /**
-   * If the given [node] has a documentation comment, remember its content
-   * and range into the given [element].
-   */
-  void _setDoc(ElementImpl element, AnnotatedNode node) {
-    Comment comment = node.documentationComment;
-    if (comment != null && comment.isDocumentation) {
-      element.documentationComment =
-          comment.tokens.map((Token t) => t.lexeme).join('\n');
-      element.setDocRange(comment.offset, comment.length);
-    }
-  }
-
-  /**
-   * Sets the visible source range for formal parameter.
-   */
-  void _setParameterVisibleRange(
-      FormalParameter node, ParameterElementImpl element) {
-    FunctionBody body = _getFunctionBody(node);
-    if (body != null) {
-      element.setVisibleRange(body.offset, body.length);
-    }
-  }
-
-  /**
-   * Make the given holder be the current holder while visiting the given node.
-   *
-   * @param holder the holder that will gather elements that are built while visiting the children
-   * @param node the node to be visited
-   */
-  void _visit(ElementHolder holder, AstNode node) {
-    if (node != null) {
-      ElementHolder previousHolder = _currentHolder;
-      _currentHolder = holder;
-      try {
-        node.accept(this);
-      } finally {
-        _currentHolder = previousHolder;
-      }
-    }
-  }
-
-  /**
-   * Make the given holder be the current holder while visiting the children of the given node.
-   *
-   * @param holder the holder that will gather elements that are built while visiting the children
-   * @param node the node whose children are to be visited
-   */
-  void _visitChildren(ElementHolder holder, AstNode node) {
-    if (node != null) {
-      ElementHolder previousHolder = _currentHolder;
-      _currentHolder = holder;
-      try {
-        node.visitChildren(this);
-      } finally {
-        _currentHolder = previousHolder;
-      }
-    }
-  }
-}
-
-/**
  * Instances of the class `ElementHolder` hold on to elements created while traversing an AST
  * structure so that they can be accessed when creating their enclosing element.
  */
@@ -7677,7 +6621,7 @@
    */
   void _addPropagableVariables(List<VariableDeclaration> variables) {
     for (VariableDeclaration variable in variables) {
-      if (variable.initializer != null) {
+      if (variable.name.name.isNotEmpty && variable.initializer != null) {
         VariableElement element = variable.element;
         if (element.isConst || element.isFinal) {
           propagableVariables.add(element);
@@ -7695,7 +6639,7 @@
    */
   void _addStaticVariables(List<VariableDeclaration> variables) {
     for (VariableDeclaration variable in variables) {
-      if (variable.initializer != null) {
+      if (variable.name.name.isNotEmpty && variable.initializer != null) {
         staticVariables.add(variable.element);
       }
     }
@@ -13480,29 +12424,6 @@
   }
 }
 
-class _ElementBuilder_visitClassDeclaration extends UnifyingAstVisitor<Object> {
-  final ElementBuilder builder;
-
-  List<ClassMember> nonFields;
-
-  _ElementBuilder_visitClassDeclaration(this.builder, this.nonFields) : super();
-
-  @override
-  Object visitConstructorDeclaration(ConstructorDeclaration node) {
-    nonFields.add(node);
-    return null;
-  }
-
-  @override
-  Object visitMethodDeclaration(MethodDeclaration node) {
-    nonFields.add(node);
-    return null;
-  }
-
-  @override
-  Object visitNode(AstNode node) => node.accept(builder);
-}
-
 class _ResolverVisitor_isVariableAccessedInClosure
     extends RecursiveAstVisitor<Object> {
   final Element variable;
diff --git a/pkg/analyzer/lib/src/generated/source.dart b/pkg/analyzer/lib/src/generated/source.dart
index a3662f9..c9d1b45 100644
--- a/pkg/analyzer/lib/src/generated/source.dart
+++ b/pkg/analyzer/lib/src/generated/source.dart
@@ -8,15 +8,13 @@
 import "dart:math" as math;
 
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/file_system/physical_file_system.dart';
-import 'package:analyzer/source/package_map_resolver.dart';
+import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/java_engine.dart';
 import 'package:analyzer/src/generated/java_io.dart' show JavaFile;
 import 'package:analyzer/src/generated/sdk.dart' show DartSdk;
 import 'package:analyzer/src/generated/source_io.dart' show FileBasedSource;
-import 'package:analyzer/src/generated/utilities_dart.dart' as utils;
 import 'package:analyzer/task/model.dart';
 import 'package:package_config/packages.dart';
 import 'package:path/path.dart' as pathos;
@@ -603,159 +601,74 @@
  * Instances of the class `SourceFactory` resolve possibly relative URI's against an existing
  * [Source].
  */
-class SourceFactory {
+abstract class SourceFactory {
   /**
    * The analysis context that this source factory is associated with.
    */
   AnalysisContext context;
 
   /**
-   * URI processor used to find mappings for `package:` URIs found in a `.packages` config
-   * file.
+   * Initialize a newly created source factory with the given absolute URI
+   * [resolvers] and optional [packages] resolution helper.
    */
-  final Packages _packages;
+  factory SourceFactory(List<UriResolver> resolvers,
+      [Packages packages,
+      ResourceProvider resourceProvider]) = SourceFactoryImpl;
 
   /**
-   * Resource provider used in working with package maps.
-   */
-  final ResourceProvider _resourceProvider;
-
-  /**
-   * The resolvers used to resolve absolute URI's.
-   */
-  final List<UriResolver> _resolvers;
-
-  /**
-   * The predicate to determine is [Source] is local.
-   */
-  LocalSourcePredicate _localSourcePredicate = LocalSourcePredicate.NOT_SDK;
-
-  /**
-   * Initialize a newly created source factory with the given absolute URI [resolvers] and
-   * optional [packages] resolution helper.
-   */
-  SourceFactory(this._resolvers,
-      [this._packages, ResourceProvider resourceProvider])
-      : _resourceProvider = resourceProvider != null
-            ? resourceProvider
-            : PhysicalResourceProvider.INSTANCE;
-
-  /**
-   * Return the [DartSdk] associated with this [SourceFactory], or `null` if there
-   * is no such SDK.
+   * Return the [DartSdk] associated with this [SourceFactory], or `null` if
+   * there is no such SDK.
    *
    * @return the [DartSdk] associated with this [SourceFactory], or `null` if
    *         there is no such SDK
    */
-  DartSdk get dartSdk {
-    for (UriResolver resolver in _resolvers) {
-      if (resolver is DartUriResolver) {
-        DartUriResolver dartUriResolver = resolver;
-        return dartUriResolver.dartSdk;
-      }
-    }
-    return null;
-  }
+  DartSdk get dartSdk;
 
   /**
    * Sets the [LocalSourcePredicate].
    *
    * @param localSourcePredicate the predicate to determine is [Source] is local
    */
-  void set localSourcePredicate(LocalSourcePredicate localSourcePredicate) {
-    this._localSourcePredicate = localSourcePredicate;
-  }
+  void set localSourcePredicate(LocalSourcePredicate localSourcePredicate);
 
   /// A table mapping package names to paths of directories containing
   /// the package (or [null] if there is no registered package URI resolver).
-  Map<String, List<Folder>> get packageMap {
-    // Start by looking in .packages.
-    if (_packages != null) {
-      Map<String, List<Folder>> packageMap = <String, List<Folder>>{};
-      _packages.asMap().forEach((String name, Uri uri) {
-        if (uri.scheme == 'file' || uri.scheme == '' /* unspecified */) {
-          packageMap[name] = <Folder>[
-            _resourceProvider.getFolder(uri.toFilePath())
-          ];
-        }
-      });
-      return packageMap;
-    }
-
-    // Default to the PackageMapUriResolver.
-    PackageMapUriResolver resolver = _resolvers
-        .firstWhere((r) => r is PackageMapUriResolver, orElse: () => null);
-    return resolver != null ? resolver.packageMap : null;
-  }
+  Map<String, List<Folder>> get packageMap;
 
   /**
    * Return a source factory that will resolve URI's in the same way that this
    * source factory does.
    */
-  SourceFactory clone() {
-    SourceFactory factory =
-        new SourceFactory(_resolvers, _packages, _resourceProvider);
-    factory.localSourcePredicate = _localSourcePredicate;
-    return factory;
-  }
+  SourceFactory clone();
 
   /**
-   * Return a source object representing the given absolute URI, or `null` if the URI is not a
-   * valid URI or if it is not an absolute URI.
+   * Return a source object representing the given absolute URI, or `null` if
+   * the URI is not a valid URI or if it is not an absolute URI.
    *
    * @param absoluteUri the absolute URI to be resolved
    * @return a source object representing the absolute URI
    */
-  Source forUri(String absoluteUri) {
-    try {
-      Uri uri = parseUriWithException(absoluteUri);
-      if (uri.isAbsolute) {
-        return _internalResolveUri(null, uri);
-      }
-    } catch (exception, stackTrace) {
-      AnalysisEngine.instance.logger.logError(
-          "Could not resolve URI: $absoluteUri",
-          new CaughtException(exception, stackTrace));
-    }
-    return null;
-  }
+  Source forUri(String absoluteUri);
 
   /**
-   * Return a source object representing the given absolute URI, or `null` if the URI is not
-   * an absolute URI.
+   * Return a source object representing the given absolute URI, or `null` if
+   * the URI is not an absolute URI.
    *
    * @param absoluteUri the absolute URI to be resolved
    * @return a source object representing the absolute URI
    */
-  Source forUri2(Uri absoluteUri) {
-    if (absoluteUri.isAbsolute) {
-      try {
-        return _internalResolveUri(null, absoluteUri);
-      } on AnalysisException catch (exception, stackTrace) {
-        AnalysisEngine.instance.logger.logError(
-            "Could not resolve URI: $absoluteUri",
-            new CaughtException(exception, stackTrace));
-      }
-    }
-    return null;
-  }
+  Source forUri2(Uri absoluteUri);
 
   /**
-   * Return a source object that is equal to the source object used to obtain the given encoding.
+   * Return a source object that is equal to the source object used to obtain
+   * the given encoding.
    *
    * @param encoding the encoding of a source object
    * @return a source object that is described by the given encoding
    * @throws IllegalArgumentException if the argument is not a valid encoding
    * See [Source.encoding].
    */
-  Source fromEncoding(String encoding) {
-    Source source = forUri(encoding);
-    if (source == null) {
-      throw new IllegalArgumentException(
-          "Invalid source encoding: '$encoding'");
-    }
-    return source;
-  }
+  Source fromEncoding(String encoding);
 
   /**
    * Determines if the given [Source] is local.
@@ -763,7 +676,7 @@
    * @param source the [Source] to analyze
    * @return `true` if the given [Source] is local
    */
-  bool isLocalSource(Source source) => _localSourcePredicate.isLocal(source);
+  bool isLocalSource(Source source);
 
   /**
    * Return a source representing the URI that results from resolving the given
@@ -772,127 +685,21 @@
    * if either the [containedUri] is invalid or if it cannot be resolved against
    * the [containingSource]'s URI.
    */
-  Source resolveUri(Source containingSource, String containedUri) {
-    if (containedUri == null || containedUri.isEmpty) {
-      return null;
-    }
-    try {
-      // Force the creation of an escaped URI to deal with spaces, etc.
-      return _internalResolveUri(
-          containingSource, parseUriWithException(containedUri));
-    } on URISyntaxException {
-      return null;
-    } catch (exception, stackTrace) {
-      String containingFullName =
-          containingSource != null ? containingSource.fullName : '<null>';
-      AnalysisEngine.instance.logger.logInformation(
-          "Could not resolve URI ($containedUri) relative to source ($containingFullName)",
-          new CaughtException(exception, stackTrace));
-      return null;
-    }
-  }
+  Source resolveUri(Source containingSource, String containedUri);
 
   /**
-   * Return an absolute URI that represents the given source, or `null` if a valid URI cannot
-   * be computed.
+   * Return an absolute URI that represents the given source, or `null` if a
+   * valid URI cannot be computed.
    *
    * @param source the source to get URI for
    * @return the absolute URI representing the given source
    */
-  Uri restoreUri(Source source) {
-    // First see if a resolver can restore the URI.
-    for (UriResolver resolver in _resolvers) {
-      Uri uri = resolver.restoreAbsolute(source);
-      if (uri != null) {
-        // Now see if there's a package mapping.
-        Uri packageMappedUri = _getPackageMapping(uri);
-        if (packageMappedUri != null) {
-          return packageMappedUri;
-        }
-        // Fall back to the resolver's computed URI.
-        return uri;
-      }
-    }
-
-    return null;
-  }
-
-  Uri _getPackageMapping(Uri sourceUri) {
-    if (_packages == null) {
-      return null;
-    }
-    if (sourceUri.scheme != 'file') {
-      //TODO(pquitslund): verify this works for non-file URIs.
-      return null;
-    }
-
-    Uri packageUri;
-    _packages.asMap().forEach((String name, Uri uri) {
-      if (packageUri == null) {
-        if (utils.startsWith(sourceUri, uri)) {
-          packageUri = Uri.parse(
-              'package:$name/${sourceUri.path.substring(uri.path.length)}');
-        }
-      }
-    });
-    return packageUri;
-  }
-
-  /**
-   * Return a source object representing the URI that results from resolving the given (possibly
-   * relative) contained URI against the URI associated with an existing source object, or
-   * `null` if the URI could not be resolved.
-   *
-   * @param containingSource the source containing the given URI
-   * @param containedUri the (possibly relative) URI to be resolved against the containing source
-   * @return the source representing the contained URI
-   * @throws AnalysisException if either the contained URI is invalid or if it cannot be resolved
-   *           against the source object's URI
-   */
-  Source _internalResolveUri(Source containingSource, Uri containedUri) {
-    if (!containedUri.isAbsolute) {
-      if (containingSource == null) {
-        throw new AnalysisException(
-            "Cannot resolve a relative URI without a containing source: $containedUri");
-      }
-      containedUri = containingSource.resolveRelativeUri(containedUri);
-    }
-
-    Uri actualUri = containedUri;
-
-    // Check .packages and update target and actual URIs as appropriate.
-    if (_packages != null && containedUri.scheme == 'package') {
-      Uri packageUri = null;
-      try {
-        packageUri =
-            _packages.resolve(containedUri, notFound: (Uri packageUri) => null);
-      } on ArgumentError {
-        // Fall through to try resolvers.
-      }
-
-      if (packageUri != null) {
-        // Ensure scheme is set.
-        if (packageUri.scheme == '') {
-          packageUri = packageUri.replace(scheme: 'file');
-        }
-        containedUri = packageUri;
-      }
-    }
-
-    for (UriResolver resolver in _resolvers) {
-      Source result = resolver.resolveAbsolute(containedUri, actualUri);
-      if (result != null) {
-        return result;
-      }
-    }
-
-    return null;
-  }
+  Uri restoreUri(Source source);
 }
 
 /**
- * The enumeration `SourceKind` defines the different kinds of sources that are known to the
- * analysis engine.
+ * The enumeration `SourceKind` defines the different kinds of sources that are
+ * known to the analysis engine.
  */
 class SourceKind extends Enum<SourceKind> {
   /**
@@ -901,20 +708,22 @@
   static const SourceKind HTML = const SourceKind('HTML', 0);
 
   /**
-   * A Dart compilation unit that is not a part of another library. Libraries might or might not
-   * contain any directives, including a library directive.
+   * A Dart compilation unit that is not a part of another library. Libraries
+   * might or might not contain any directives, including a library directive.
    */
   static const SourceKind LIBRARY = const SourceKind('LIBRARY', 1);
 
   /**
-   * A Dart compilation unit that is part of another library. Parts contain a part-of directive.
+   * A Dart compilation unit that is part of another library. Parts contain a
+   * part-of directive.
    */
   static const SourceKind PART = const SourceKind('PART', 2);
 
   /**
-   * An unknown kind of source. Used both when it is not possible to identify the kind of a source
-   * and also when the kind of a source is not known without performing a computation and the client
-   * does not want to spend the time to identify the kind.
+   * An unknown kind of source. Used both when it is not possible to identify
+   * the kind of a source and also when the kind of a source is not known
+   * without performing a computation and the client does not want to spend the
+   * time to identify the kind.
    */
   static const SourceKind UNKNOWN = const SourceKind('UNKNOWN', 3);
 
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index e67d096..fa2bf1c 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -466,10 +466,19 @@
         node.element as ExecutableElementImpl;
     DartType computedType = _computeStaticReturnTypeOfFunctionExpression(node);
     if (_strongMode) {
+      // In strong mode, we don't want to allow the function's return type to
+      // be bottom. If the surrounding context has a more precise type, we
+      // will push it down with inference, below. If not we want to use dynamic.
+      // TODO(jmesserly): should we  do this for the `null` literal always in
+      // strong mode, instead of handling it here?
+      if (computedType.isBottom) {
+        computedType = DynamicTypeImpl.instance;
+      }
+
       DartType functionType = InferenceContext.getType(node);
       if (functionType is FunctionType) {
         DartType returnType = functionType.returnType;
-        if ((computedType.isDynamic || computedType.isBottom) &&
+        if (computedType.isDynamic &&
             !(returnType.isDynamic || returnType.isBottom)) {
           computedType = returnType;
           _resolver.inferenceContext.recordInference(node, functionType);
@@ -718,7 +727,7 @@
     SimpleIdentifier methodNameNode = node.methodName;
     Element staticMethodElement = methodNameNode.staticElement;
     if (_strongMode) {
-      _inferMethodInvocation(node);
+      _inferMethodInvocationGeneric(node);
     }
     // Record types of the variable invoked as a function.
     if (staticMethodElement is VariableElement) {
@@ -726,8 +735,16 @@
       _resolver.recordPropagatedTypeIfBetter(methodNameNode, propagatedType);
     }
     // Record static return type of the static element.
-    DartType staticStaticType = _computeInvokeReturnType(node.staticInvokeType);
-    _recordStaticType(node, staticStaticType);
+    bool inferredStaticType = _strongMode &&
+        (_inferMethodInvocationObject(node) ||
+            _inferMethodInvocationInlineJS(node));
+
+    if (!inferredStaticType) {
+      DartType staticStaticType =
+          _computeInvokeReturnType(node.staticInvokeType);
+      _recordStaticType(node, staticStaticType);
+    }
+
     // Record propagated return type of the static element.
     DartType staticPropagatedType =
         _computePropagatedReturnType(staticMethodElement);
@@ -998,6 +1015,10 @@
     } else if (staticElement is VariableElement) {
       staticType = staticElement.type;
     }
+    if (_strongMode) {
+      staticType = _inferGenericInstantiationFromContext(
+          InferenceContext.getType(node), staticType);
+    }
     if (!(_strongMode &&
         _inferObjectAccess(node, staticType, prefixedIdentifier))) {
       _recordStaticType(prefixedIdentifier, staticType);
@@ -1127,6 +1148,10 @@
     } else {
       // TODO(brianwilkerson) Report this internal error.
     }
+    if (_strongMode) {
+      staticType = _inferGenericInstantiationFromContext(
+          InferenceContext.getType(node), staticType);
+    }
     if (!(_strongMode && _inferObjectAccess(node, staticType, propertyName))) {
       _recordStaticType(propertyName, staticType);
       _recordStaticType(node, staticType);
@@ -1227,6 +1252,10 @@
     } else {
       staticType = _dynamicType;
     }
+    if (_strongMode) {
+      staticType = _inferGenericInstantiationFromContext(
+          InferenceContext.getType(node), staticType);
+    }
     _recordStaticType(node, staticType);
     // TODO(brianwilkerson) I think we want to repeat the logic above using the
     // propagated element to get another candidate for the propagated type.
@@ -1845,16 +1874,6 @@
   }
 
   /**
-   * Given a method invocation [node], attempt to infer a better
-   * type for the result.
-   */
-  bool _inferMethodInvocation(MethodInvocation node) {
-    return _inferMethodInvocationObject(node) ||
-        _inferMethodInvocationGeneric(node) ||
-        _inferMethodInvocationInlineJS(node);
-  }
-
-  /**
    * Given a generic method invocation [node], attempt to infer the method's
    * type variables, using the actual types of the arguments.
    */
@@ -1876,9 +1895,27 @@
   }
 
   /**
+   * Given an uninstantiated generic type, try to infer the instantiated generic
+   * type from the surrounding context.
+   */
+  DartType _inferGenericInstantiationFromContext(
+      DartType context, DartType type) {
+    TypeSystem ts = _typeSystem;
+    if (context is FunctionType &&
+        type is FunctionType &&
+        ts is StrongTypeSystemImpl) {
+      return ts.inferFunctionTypeInstantiation(_typeProvider, context, type);
+    }
+    return type;
+  }
+
+  /**
    * Given a method invocation [node], attempt to infer a better
    * type for the result if it is an inline JS invocation
    */
+  // TODO(jmesserly): we should remove this, and infer type from context, rather
+  // than try to understand the dart2js type grammar.
+  // (At the very least, we should lookup type name in the correct scope.)
   bool _inferMethodInvocationInlineJS(MethodInvocation node) {
     Element e = node.methodName.staticElement;
     if (e is FunctionElement &&
@@ -1905,6 +1942,10 @@
    * type for the result if the target is dynamic and the method
    * being called is one of the object methods.
    */
+  // TODO(jmesserly): we should move this logic to ElementResolver.
+  // If we do it here, we won't have correct parameter elements set on the
+  // node's argumentList. (This likely affects only explicit calls to
+  // `Object.noSuchMethod`.)
   bool _inferMethodInvocationObject(MethodInvocation node) {
     // If we have a call like `toString()` or `libraryPrefix.toString()` don't
     // infer it.
diff --git a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
index c77192c..a2f01f1 100644
--- a/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/ast_factory.dart
@@ -800,6 +800,10 @@
       new MapLiteralEntry(
           string2(key), TokenFactory.tokenFromType(TokenType.COLON), value);
 
+  static MapLiteralEntry mapLiteralEntry2(Expression key, Expression value) =>
+      new MapLiteralEntry(
+          key, TokenFactory.tokenFromType(TokenType.COLON), value);
+
   static MethodDeclaration methodDeclaration(
           Keyword modifier,
           TypeName returnType,
diff --git a/pkg/analyzer/lib/src/generated/testing/element_factory.dart b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
index 38c322e..282b52e 100644
--- a/pkg/analyzer/lib/src/generated/testing/element_factory.dart
+++ b/pkg/analyzer/lib/src/generated/testing/element_factory.dart
@@ -560,9 +560,11 @@
     TopLevelVariableElementImpl variable;
     if (isConst) {
       ConstTopLevelVariableElementImpl constant =
-          new ConstTopLevelVariableElementImpl(AstFactory.identifier3(name));
-      InstanceCreationExpression initializer = AstFactory.instanceCreationExpression2(
-          Keyword.CONST, AstFactory.typeName(type.element));
+          new ConstTopLevelVariableElementImpl.forNode(
+              AstFactory.identifier3(name));
+      InstanceCreationExpression initializer =
+          AstFactory.instanceCreationExpression2(
+              Keyword.CONST, AstFactory.typeName(type.element));
       if (type is InterfaceType) {
         ConstructorElement element = type.element.unnamedConstructor;
         initializer.staticElement = element;
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index b85205c..fb48bbe 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -5,6 +5,7 @@
 library analyzer.src.generated.type_system;
 
 import 'dart:collection';
+import 'dart:math' as math;
 
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
@@ -12,6 +13,7 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/engine.dart' show AnalysisContext;
 import 'package:analyzer/src/generated/resolver.dart' show TypeProvider;
+import 'package:analyzer/src/generated/utilities_dart.dart';
 
 typedef bool _GuardedSubtypeChecker<T>(T t1, T t2, Set<Element> visited);
 typedef bool _SubtypeChecker<T>(T t1, T t2);
@@ -32,9 +34,6 @@
   @override
   bool canPromoteToType(DartType to, DartType from) => isSubtypeOf(to, from);
 
-  @override
-  bool isMoreSpecificThan(DartType t1, DartType t2) => isSubtypeOf(t1, t2);
-
   /**
    * Given a type t, if t is an interface type with a call method
    * defined, return the function type for the call method, otherwise
@@ -72,22 +71,19 @@
   /// L is the lower bound of that type parameter.
   FunctionType inferCallFromArguments(
       TypeProvider typeProvider,
-      FunctionTypeImpl fnType,
+      FunctionType fnType,
       List<DartType> correspondingParameterTypes,
       List<DartType> argumentTypes) {
     if (fnType.typeFormals.isEmpty) {
       return fnType;
     }
 
-    List<TypeParameterType> fnTypeParams =
-        TypeParameterTypeImpl.getTypes(fnType.typeFormals);
-
     // Create a TypeSystem that will allow certain type parameters to be
     // inferred. It will optimistically assume these type parameters can be
     // subtypes (or supertypes) as necessary, and track the constraints that
     // are implied by this.
     var inferringTypeSystem =
-        new _StrongInferenceTypeSystem(typeProvider, fnTypeParams);
+        new _StrongInferenceTypeSystem(typeProvider, fnType.typeFormals);
 
     for (int i = 0; i < argumentTypes.length; i++) {
       // Try to pass each argument to each parameter, recording any type
@@ -96,61 +92,88 @@
           argumentTypes[i], correspondingParameterTypes[i]);
     }
 
-    var inferredTypes = new List<DartType>.from(fnTypeParams, growable: false);
-    for (int i = 0; i < fnTypeParams.length; i++) {
-      TypeParameterType typeParam = fnTypeParams[i];
-      _TypeParameterBound bound = inferringTypeSystem._bounds[typeParam];
+    return inferringTypeSystem._infer(fnType);
+  }
 
-      // Now we've computed lower and upper bounds for each type parameter.
-      //
-      // To decide on which type to assign, we look at the return type and see
-      // if the type parameter occurs in covariant or contravariant positions.
-      //
-      // If the type is "passed in" at all, or if our lower bound was bottom,
-      // we choose the upper bound as being the most useful.
-      //
-      // Otherwise we choose the more precise lower bound.
-      _TypeParameterVariance variance =
-          new _TypeParameterVariance.from(typeParam, fnType.returnType);
-
-      inferredTypes[i] =
-          variance.passedIn || bound.lower.isBottom ? bound.upper : bound.lower;
-
-      // Assumption: if the current type parameter has an "extends" clause
-      // that refers to another type variable we are inferring, it will appear
-      // before us or in this list position. For example:
-      //
-      //     <TFrom, TTo extends TFrom>
-      //
-      // We may infer TTo is TFrom. In that case, we already know what TFrom
-      // is inferred as, so we can substitute it now. This also handles more
-      // complex cases such as:
-      //
-      //     <TFrom, TTo extends Iterable<TFrom>>
-      //
-      // Or if the type parameter's bound depends on itself such as:
-      //
-      //     <T extends Clonable<T>>
-      inferredTypes[i] =
-          inferredTypes[i].substitute2(inferredTypes, fnTypeParams);
-
-      // See if this actually worked.
-      // If not, fall back to the known upper bound (if any) or `dynamic`.
-      if (inferredTypes[i].isBottom ||
-          !isSubtypeOf(inferredTypes[i],
-              bound.upper.substitute2(inferredTypes, fnTypeParams)) ||
-          !isSubtypeOf(bound.lower.substitute2(inferredTypes, fnTypeParams),
-              inferredTypes[i])) {
-        inferredTypes[i] = DynamicTypeImpl.instance;
-        if (typeParam.element.bound != null) {
-          inferredTypes[i] =
-              typeParam.element.bound.substitute2(inferredTypes, fnTypeParams);
-        }
-      }
+  /**
+   * Given a generic function type `F<T0, T1, ... Tn>` and a context type C,
+   * infer an instantiation of F, such that `F<S0, S1, ..., Sn>` <: C.
+   *
+   * This is similar to [inferCallFromArguments], but the return type is also
+   * considered as part of the solution.
+   *
+   * If this function is called with a [contextType] that is also
+   * uninstantiated, or a [fnType] that is already instantiated, it will have
+   * no effect and return [fnType].
+   */
+  FunctionType inferFunctionTypeInstantiation(TypeProvider typeProvider,
+      FunctionType contextType, FunctionType fnType) {
+    if (contextType.typeFormals.isNotEmpty || fnType.typeFormals.isEmpty) {
+      return fnType;
     }
 
-    // Return the instantiated type.
-    return fnType.instantiate(inferredTypes);
+    // Create a TypeSystem that will allow certain type parameters to be
+    // inferred. It will optimistically assume these type parameters can be
+    // subtypes (or supertypes) as necessary, and track the constraints that
+    // are implied by this.
+    var inferringTypeSystem =
+        new _StrongInferenceTypeSystem(typeProvider, fnType.typeFormals);
+
+    // Add constraints for each corresponding pair of parameters.
+    var fRequired = fnType.normalParameterTypes;
+    var cRequired = contextType.normalParameterTypes;
+    if (cRequired.length != fRequired.length) {
+      // If the number of required parameters differs, we can't infer from this
+      // type (this will be a static type error).
+      return fnType;
+    }
+    for (int i = 0; i < fRequired.length; i++) {
+      inferringTypeSystem.isSubtypeOf(cRequired[i], fRequired[i]);
+    }
+
+    var fOptional = fnType.optionalParameterTypes;
+    var cOptional = contextType.optionalParameterTypes;
+    if (cOptional.length > fOptional.length) {
+      // If we have more optional parameters that can be passed, we can't infer
+      // from this type (this will be a static type error).
+      return fnType;
+    }
+    // Ignore any extra optional arguments in F. We only need to pass arguments
+    // that could be passed to C.
+    for (int i = 0; i < cOptional.length; i++) {
+      inferringTypeSystem.isSubtypeOf(cOptional[i], fOptional[i]);
+    }
+
+    var fNamed = fnType.namedParameterTypes;
+    var cNamed = contextType.namedParameterTypes;
+    for (var name in cNamed.keys) {
+      DartType fNamedType = fNamed[name];
+      if (fNamedType == null) {
+        // If F does not have a named parameter needed for C, then we can't
+        // infer from this type (this will be a static type error).
+        return fnType;
+      }
+      DartType cNamedType = cNamed[name];
+      inferringTypeSystem.isSubtypeOf(cNamedType, fNamedType);
+    }
+
+    // Infer from the return type. F must return a subtype of what C returns.
+    inferringTypeSystem.isSubtypeOf(fnType.returnType, contextType.returnType);
+
+    // Instantiate the resulting type.
+    var resultType = inferringTypeSystem._infer(fnType);
+
+    // If the instantiation is not a subtype of our context (because some
+    // constraints could not be solved), return the original type, so the error
+    // is in terms of it.
+    //
+    // TODO(jmesserly): for performance, we could refactor this so the _infer
+    // call above bails out sooner, and then we can avoid this extra check.
+    if (isSubtypeOf(resultType, contextType)) {
+      return resultType;
+    } else {
+      return fnType;
+    }
   }
 
   /**
@@ -248,6 +271,9 @@
   }
 
   @override
+  bool isMoreSpecificThan(DartType t1, DartType t2) => isSubtypeOf(t1, t2);
+
+  @override
   bool isSubtypeOf(DartType leftType, DartType rightType) {
     return _isSubtypeOf(leftType, rightType, null);
   }
@@ -580,14 +606,6 @@
   bool canPromoteToType(DartType to, DartType from);
 
   /**
-   * Return `true` if the [leftType] is more specific than the [rightType]
-   * (that is, if leftType << rightType), as defined in the Dart language spec.
-   *
-   * In strong mode, this is equivalent to [isSubtypeOf].
-   */
-  bool isMoreSpecificThan(DartType leftType, DartType rightType);
-
-  /**
    * Compute the least upper bound of two types.
    */
   DartType getLeastUpperBound(
@@ -609,6 +627,14 @@
   bool isAssignableTo(DartType leftType, DartType rightType);
 
   /**
+   * Return `true` if the [leftType] is more specific than the [rightType]
+   * (that is, if leftType << rightType), as defined in the Dart language spec.
+   *
+   * In strong mode, this is equivalent to [isSubtypeOf].
+   */
+  bool isMoreSpecificThan(DartType leftType, DartType rightType);
+
+  /**
    * Return `true` if the [leftType] is a subtype of the [rightType] (that is,
    * if leftType <: rightType).
    */
@@ -631,10 +657,6 @@
   TypeSystemImpl();
 
   @override
-  bool isMoreSpecificThan(DartType t1, DartType t2) =>
-      t1.isMoreSpecificThan(t2);
-
-  @override
   bool canPromoteToType(DartType to, DartType from) {
     // Declared type should not be "dynamic".
     // Promoted type should not be "dynamic".
@@ -709,12 +731,7 @@
       }
       return result;
     } else if (type1 is FunctionType && type2 is FunctionType) {
-      FunctionType result =
-          FunctionTypeImpl.computeLeastUpperBound(type1, type2);
-      if (result == null) {
-        return typeProvider.functionType;
-      }
-      return result;
+      return _functionLeastUpperBound(typeProvider, type1, type2);
     } else {
       // Should never happen.  As a defensive measure, return the dynamic type.
       assert(false);
@@ -740,9 +757,91 @@
   }
 
   @override
+  bool isMoreSpecificThan(DartType t1, DartType t2) =>
+      t1.isMoreSpecificThan(t2);
+
+  @override
   bool isSubtypeOf(DartType leftType, DartType rightType) {
     return leftType.isSubtypeOf(rightType);
   }
+
+  /**
+   * Compute the least upper bound of function types [f] and [g].
+   *
+   * The spec rules for LUB on function types, informally, are pretty simple
+   * (though unsound):
+   *
+   * - If the functions don't have the same number of required parameters,
+   *   always return `Function`.
+   *
+   * - Discard any optional named or positional parameters the two types do not
+   *   have in common.
+   *
+   * - Compute the LUB of each corresponding pair of parameter and return types.
+   *   Return a function type with those types.
+   */
+  DartType _functionLeastUpperBound(
+      TypeProvider provider, FunctionType f, FunctionType g) {
+    // TODO(rnystrom): Right now, this assumes f and g do not have any type
+    // parameters. Revisit that in the presence of generic methods.
+    List<DartType> fRequired = f.normalParameterTypes;
+    List<DartType> gRequired = g.normalParameterTypes;
+
+    // We need some parameter names for in the synthesized function type, so
+    // arbitrarily use f's.
+    List<String> fRequiredNames = f.normalParameterNames;
+    List<String> fPositionalNames = f.optionalParameterNames;
+
+    // If F and G differ in their number of required parameters, then the
+    // least upper bound of F and G is Function.
+    if (fRequired.length != gRequired.length) {
+      return provider.functionType;
+    }
+
+    // Calculate the LUB of each corresponding pair of parameters.
+    List<ParameterElement> parameters = [];
+
+    for (int i = 0; i < fRequired.length; i++) {
+      parameters.add(new ParameterElementImpl.synthetic(
+          fRequiredNames[i],
+          getLeastUpperBound(provider, fRequired[i], gRequired[i]),
+          ParameterKind.REQUIRED));
+    }
+
+    List<DartType> fPositional = f.optionalParameterTypes;
+    List<DartType> gPositional = g.optionalParameterTypes;
+
+    // Ignore any extra optional positional parameters if one has more than the
+    // other.
+    int length = math.min(fPositional.length, gPositional.length);
+    for (int i = 0; i < length; i++) {
+      parameters.add(new ParameterElementImpl.synthetic(
+          fPositionalNames[i],
+          getLeastUpperBound(provider, fPositional[i], gPositional[i]),
+          ParameterKind.POSITIONAL));
+    }
+
+    Map<String, DartType> fNamed = f.namedParameterTypes;
+    Map<String, DartType> gNamed = g.namedParameterTypes;
+    for (String name in fNamed.keys.toSet()..retainAll(gNamed.keys)) {
+      parameters.add(new ParameterElementImpl.synthetic(
+          name,
+          getLeastUpperBound(provider, fNamed[name], gNamed[name]),
+          ParameterKind.NAMED));
+    }
+
+    // Calculate the LUB of the return type.
+    DartType returnType =
+        getLeastUpperBound(provider, f.returnType, g.returnType);
+
+    FunctionElementImpl function = new FunctionElementImpl("", -1);
+    function.synthetic = true;
+    function.returnType = returnType;
+    function.parameters = parameters;
+
+    function.type = new FunctionTypeImpl(function);
+    return function.type;
+  }
 }
 
 /// Tracks upper and lower type bounds for a set of type parameters.
@@ -751,13 +850,77 @@
   final Map<TypeParameterType, _TypeParameterBound> _bounds;
 
   _StrongInferenceTypeSystem(
-      this._typeProvider, Iterable<TypeParameterType> typeParams)
-      : _bounds = new Map.fromIterable(typeParams, value: (t) {
+      this._typeProvider, Iterable<TypeParameterElement> typeFormals)
+      : _bounds =
+            new Map.fromIterable(typeFormals, key: (t) => t.type, value: (t) {
           _TypeParameterBound bound = new _TypeParameterBound();
-          if (t.element.bound != null) bound.upper = t.element.bound;
+          if (t.bound != null) bound.upper = t.bound;
           return bound;
         });
 
+  /// Given the constraints that were given by calling [isSubtypeOf], find the
+  /// instantiation of the generic function that satisfies these constraints.
+  FunctionType _infer(FunctionType fnType) {
+    List<TypeParameterType> fnTypeParams =
+        TypeParameterTypeImpl.getTypes(fnType.typeFormals);
+
+    var inferredTypes = new List<DartType>.from(fnTypeParams, growable: false);
+    for (int i = 0; i < fnTypeParams.length; i++) {
+      TypeParameterType typeParam = fnTypeParams[i];
+      _TypeParameterBound bound = _bounds[typeParam];
+
+      // Now we've computed lower and upper bounds for each type parameter.
+      //
+      // To decide on which type to assign, we look at the return type and see
+      // if the type parameter occurs in covariant or contravariant positions.
+      //
+      // If the type is "passed in" at all, or if our lower bound was bottom,
+      // we choose the upper bound as being the most useful.
+      //
+      // Otherwise we choose the more precise lower bound.
+      _TypeParameterVariance variance =
+          new _TypeParameterVariance.from(typeParam, fnType.returnType);
+
+      inferredTypes[i] =
+          variance.passedIn || bound.lower.isBottom ? bound.upper : bound.lower;
+
+      // Assumption: if the current type parameter has an "extends" clause
+      // that refers to another type variable we are inferring, it will appear
+      // before us or in this list position. For example:
+      //
+      //     <TFrom, TTo extends TFrom>
+      //
+      // We may infer TTo is TFrom. In that case, we already know what TFrom
+      // is inferred as, so we can substitute it now. This also handles more
+      // complex cases such as:
+      //
+      //     <TFrom, TTo extends Iterable<TFrom>>
+      //
+      // Or if the type parameter's bound depends on itself such as:
+      //
+      //     <T extends Clonable<T>>
+      inferredTypes[i] =
+          inferredTypes[i].substitute2(inferredTypes, fnTypeParams);
+
+      // See if this actually worked.
+      // If not, fall back to the known upper bound (if any) or `dynamic`.
+      if (inferredTypes[i].isBottom ||
+          !isSubtypeOf(inferredTypes[i],
+              bound.upper.substitute2(inferredTypes, fnTypeParams)) ||
+          !isSubtypeOf(bound.lower.substitute2(inferredTypes, fnTypeParams),
+              inferredTypes[i])) {
+        inferredTypes[i] = DynamicTypeImpl.instance;
+        if (typeParam.element.bound != null) {
+          inferredTypes[i] =
+              typeParam.element.bound.substitute2(inferredTypes, fnTypeParams);
+        }
+      }
+    }
+
+    // Return the instantiated type.
+    return fnType.instantiate(inferredTypes);
+  }
+
   @override
   bool _inferTypeParameterSubtypeOf(
       DartType t1, DartType t2, Set<Element> visited) {
diff --git a/pkg/analyzer/lib/src/string_source.dart b/pkg/analyzer/lib/src/string_source.dart
index 0c99e69..b742db9 100644
--- a/pkg/analyzer/lib/src/string_source.dart
+++ b/pkg/analyzer/lib/src/string_source.dart
@@ -7,25 +7,39 @@
 import 'package:analyzer/src/generated/engine.dart' show TimestampedData;
 import 'package:analyzer/src/generated/source.dart';
 
-/// An implementation of [Source] that's based on an in-memory Dart string.
+/**
+ * An implementation of [Source] that's based on an in-memory Dart string.
+ */
 class StringSource extends Source {
+  /**
+   * The content of the source.
+   */
   final String _contents;
+
+  @override
   final String fullName;
+
+  @override
   final int modificationStamp;
 
   StringSource(this._contents, this.fullName)
       : modificationStamp = new DateTime.now().millisecondsSinceEpoch;
 
+  @override
   TimestampedData<String> get contents =>
       new TimestampedData(modificationStamp, _contents);
 
+  @override
   String get encoding =>
-      throw new UnsupportedError("StringSource doesn't support " "encoding.");
+      throw new UnsupportedError("StringSource doesn't support encoding.");
 
+  @override
   int get hashCode => _contents.hashCode ^ fullName.hashCode;
 
+  @override
   bool get isInSystemLibrary => false;
 
+  @override
   String get shortName => fullName;
 
   @override
@@ -33,18 +47,25 @@
       throw new UnsupportedError("StringSource doesn't support uri.");
 
   UriKind get uriKind =>
-      throw new UnsupportedError("StringSource doesn't support " "uriKind.");
+      throw new UnsupportedError("StringSource doesn't support uriKind.");
 
+  /**
+   * Return `true` if the given [object] is a string source that is equal to
+   * this source.
+   */
   bool operator ==(Object object) {
-    if (object is StringSource) {
-      StringSource ssObject = object;
-      return ssObject._contents == _contents && ssObject.fullName == fullName;
-    }
-    return false;
+    return object is StringSource &&
+        object._contents == _contents &&
+        object.fullName == fullName;
   }
 
+  @override
   bool exists() => true;
 
+  @override
   Uri resolveRelativeUri(Uri relativeUri) => throw new UnsupportedError(
       "StringSource doesn't support resolveRelative.");
+
+  @override
+  String toString() => 'StringSource ($fullName)';
 }
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 4a0424b..46ef9fa 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -26,14 +26,16 @@
   constructor,
 
   /**
-   * The entity is a static const field.
+   * The entity is a getter or setter inside a class.  Note: this is used in
+   * the case where a constant refers to a static const declared inside a
+   * class.
    */
-  constField,
+  propertyAccessor,
 
   /**
-   * The entity is a static method.
+   * The entity is a method.
    */
-  staticMethod,
+  method,
 
   /**
    * The `length` property access.
@@ -86,27 +88,21 @@
  */
 enum UnlinkedConstOperation {
   /**
-   * Push the value of the n-th constructor argument (where n is obtained from
-   * [UnlinkedConst.ints]) onto the stack.
-   */
-  pushArgument,
-
-  /**
    * Push the next value from [UnlinkedConst.ints] (a 32-bit unsigned integer)
    * onto the stack.
    *
    * Note that Dart supports integers larger than 32 bits; these are
-   * represented by composing 32 bit values using the [shiftOr] operation.
+   * represented by composing 32-bit values using the [pushLongInt] operation.
    */
   pushInt,
 
   /**
-   * Pop the top value off the stack, which should be an integer.  Multiply it
-   * by 2^32, "or" in the next value from [UnlinkedConst.ints] (which is
-   * interpreted as a 32-bit unsigned integer), and push the result back onto
-   * the stack.
+   * Get the number of components from [UnlinkedConst.ints], then do this number
+   * of times the following operations: multiple the current value by 2^32, "or"
+   * it with the next value in [UnlinkedConst.ints]. The initial value is zero.
+   * Push the result into the stack.
    */
-  shiftOr,
+  pushLongInt,
 
   /**
    * Push the next value from [UnlinkedConst.doubles] (a double precision
@@ -140,8 +136,8 @@
   concatenate,
 
   /**
-   * Pop the top value from the stack which should be string, convert it to
-   * a symbol, and push it back onto the stack.
+   * Get the next value from [UnlinkedConst.strings], convert it to a symbol,
+   * and push it onto the stack.
    */
   makeSymbol,
 
@@ -227,12 +223,16 @@
   /**
    * Pop the top 2 values from the stack, evaluate `v1 == v2`, and push the
    * result back onto the stack.
-   *
-   * This is also used to represent `v1 != v2`, by composition with [not].
    */
   equal,
 
   /**
+   * Pop the top 2 values from the stack, evaluate `v1 != v2`, and push the
+   * result back onto the stack.
+   */
+  notEqual,
+
+  /**
    * Pop the top value from the stack, compute its boolean negation, and push
    * the result back onto the stack.
    */
@@ -455,6 +455,7 @@
   int _slot;
   int _reference;
   int _paramReference;
+  List<int> _implicitFunctionTypeIndices;
   List<EntityRefBuilder> _typeArguments;
 
   @override
@@ -515,6 +516,37 @@
   }
 
   @override
+  List<int> get implicitFunctionTypeIndices => _implicitFunctionTypeIndices ??= <int>[];
+
+  /**
+   * If this is a reference to a function type implicitly defined by a
+   * function-typed parameter, a list of zero-based indices indicating the path
+   * from the entity referred to by [reference] to the appropriate type
+   * parameter.  Otherwise the empty list.
+   *
+   * If there are N indices in this list, then the entity being referred to is
+   * the function type implicitly defined by a function-typed parameter of a
+   * function-typed parameter, to N levels of nesting.  The first index in the
+   * list refers to the outermost level of nesting; for example if [reference]
+   * refers to the entity defined by:
+   *
+   *     void f(x, void g(y, z, int h(String w))) { ... }
+   *
+   * Then to refer to the function type implicitly defined by parameter `h`
+   * (which is parameter 2 of parameter 1 of `f`), then
+   * [implicitFunctionTypeIndices] should be [1, 2].
+   *
+   * Note that if the entity being referred to is a generic method inside a
+   * generic class, then the type arguments in [typeArguments] are applied
+   * first to the class and then to the method.
+   */
+  void set implicitFunctionTypeIndices(List<int> _value) {
+    assert(!_finished);
+    assert(_value == null || _value.every((e) => e >= 0));
+    _implicitFunctionTypeIndices = _value;
+  }
+
+  @override
   List<EntityRefBuilder> get typeArguments => _typeArguments ??= <EntityRefBuilder>[];
 
   /**
@@ -527,16 +559,21 @@
     _typeArguments = _value;
   }
 
-  EntityRefBuilder({int slot, int reference, int paramReference, List<EntityRefBuilder> typeArguments})
+  EntityRefBuilder({int slot, int reference, int paramReference, List<int> implicitFunctionTypeIndices, List<EntityRefBuilder> typeArguments})
     : _slot = slot,
       _reference = reference,
       _paramReference = paramReference,
+      _implicitFunctionTypeIndices = implicitFunctionTypeIndices,
       _typeArguments = typeArguments;
 
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
     _finished = true;
+    fb.Offset offset_implicitFunctionTypeIndices;
     fb.Offset offset_typeArguments;
+    if (!(_implicitFunctionTypeIndices == null || _implicitFunctionTypeIndices.isEmpty)) {
+      offset_implicitFunctionTypeIndices = fbBuilder.writeListUint32(_implicitFunctionTypeIndices);
+    }
     if (!(_typeArguments == null || _typeArguments.isEmpty)) {
       offset_typeArguments = fbBuilder.writeList(_typeArguments.map((b) => b.finish(fbBuilder)).toList());
     }
@@ -550,8 +587,11 @@
     if (_paramReference != null && _paramReference != 0) {
       fbBuilder.addUint32(2, _paramReference);
     }
+    if (offset_implicitFunctionTypeIndices != null) {
+      fbBuilder.addOffset(3, offset_implicitFunctionTypeIndices);
+    }
     if (offset_typeArguments != null) {
-      fbBuilder.addOffset(3, offset_typeArguments);
+      fbBuilder.addOffset(4, offset_typeArguments);
     }
     return fbBuilder.endTable();
   }
@@ -600,6 +640,30 @@
   int get paramReference;
 
   /**
+   * If this is a reference to a function type implicitly defined by a
+   * function-typed parameter, a list of zero-based indices indicating the path
+   * from the entity referred to by [reference] to the appropriate type
+   * parameter.  Otherwise the empty list.
+   *
+   * If there are N indices in this list, then the entity being referred to is
+   * the function type implicitly defined by a function-typed parameter of a
+   * function-typed parameter, to N levels of nesting.  The first index in the
+   * list refers to the outermost level of nesting; for example if [reference]
+   * refers to the entity defined by:
+   *
+   *     void f(x, void g(y, z, int h(String w))) { ... }
+   *
+   * Then to refer to the function type implicitly defined by parameter `h`
+   * (which is parameter 2 of parameter 1 of `f`), then
+   * [implicitFunctionTypeIndices] should be [1, 2].
+   *
+   * Note that if the entity being referred to is a generic method inside a
+   * generic class, then the type arguments in [typeArguments] are applied
+   * first to the class and then to the method.
+   */
+  List<int> get implicitFunctionTypeIndices;
+
+  /**
    * 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.
@@ -622,6 +686,7 @@
   int _slot;
   int _reference;
   int _paramReference;
+  List<int> _implicitFunctionTypeIndices;
   List<EntityRef> _typeArguments;
 
   @override
@@ -643,8 +708,14 @@
   }
 
   @override
+  List<int> get implicitFunctionTypeIndices {
+    _implicitFunctionTypeIndices ??= const fb.ListReader<int>(const fb.Uint32Reader()).vTableGet(_bp, 3, const <int>[]);
+    return _implicitFunctionTypeIndices;
+  }
+
+  @override
   List<EntityRef> get typeArguments {
-    _typeArguments ??= const fb.ListReader<EntityRef>(const _EntityRefReader()).vTableGet(_bp, 3, const <EntityRef>[]);
+    _typeArguments ??= const fb.ListReader<EntityRef>(const _EntityRefReader()).vTableGet(_bp, 4, const <EntityRef>[]);
     return _typeArguments;
   }
 }
@@ -655,6 +726,7 @@
     "slot": slot,
     "reference": reference,
     "paramReference": paramReference,
+    "implicitFunctionTypeIndices": implicitFunctionTypeIndices,
     "typeArguments": typeArguments,
   };
 }
@@ -788,8 +860,8 @@
   String get name => _name ??= '';
 
   /**
-   * Name of the exported entity.  TODO(paulberry): do we include the trailing
-   * '=' for a setter?
+   * Name of the exported entity.  For an exported setter, this name includes
+   * the trailing '='.
    */
   void set name(String _value) {
     assert(!_finished);
@@ -872,8 +944,8 @@
 abstract class LinkedExportName extends base.SummaryClass {
 
   /**
-   * Name of the exported entity.  TODO(paulberry): do we include the trailing
-   * '=' for a setter?
+   * Name of the exported entity.  For an exported setter, this name includes
+   * the trailing '='.
    */
   String get name;
 
@@ -1215,6 +1287,7 @@
   int _unit;
   int _numTypeParameters;
   String _name;
+  int _containingReference;
 
   @override
   int get dependency => _dependency ??= 0;
@@ -1222,6 +1295,9 @@
   /**
    * Index into [LinkedLibrary.dependencies] indicating which imported library
    * declares the entity being referred to.
+   *
+   * Zero if this entity is contained within another entity (e.g. a class
+   * member).
    */
   void set dependency(int _value) {
     assert(!_finished);
@@ -1249,6 +1325,9 @@
    * definition of the entity.  As with indices into [LinkedLibrary.units],
    * zero represents the defining compilation unit, and nonzero values
    * represent parts in the order of the corresponding `part` declarations.
+   *
+   * Zero if this entity is contained within another entity (e.g. a class
+   * member).
    */
   void set unit(int _value) {
     assert(!_finished);
@@ -1282,12 +1361,33 @@
     _name = _value;
   }
 
-  LinkedReferenceBuilder({int dependency, ReferenceKind kind, int unit, int numTypeParameters, String name})
+  @override
+  int get containingReference => _containingReference ??= 0;
+
+  /**
+   * If this [LinkedReference] doesn't have an associated [UnlinkedReference],
+   * and the entity being referred to is contained within another entity, index
+   * of the containing entity.  This behaves similarly to
+   * [UnlinkedReference.prefixReference], however it is only used for class
+   * members, not for prefixed imports.
+   *
+   * Containing references must always point backward; that is, for all i, if
+   * LinkedUnit.references[i].containingReference != 0, then
+   * LinkedUnit.references[i].containingReference < i.
+   */
+  void set containingReference(int _value) {
+    assert(!_finished);
+    assert(_value == null || _value >= 0);
+    _containingReference = _value;
+  }
+
+  LinkedReferenceBuilder({int dependency, ReferenceKind kind, int unit, int numTypeParameters, String name, int containingReference})
     : _dependency = dependency,
       _kind = kind,
       _unit = unit,
       _numTypeParameters = numTypeParameters,
-      _name = name;
+      _name = name,
+      _containingReference = containingReference;
 
   fb.Offset finish(fb.Builder fbBuilder) {
     assert(!_finished);
@@ -1312,6 +1412,9 @@
     if (offset_name != null) {
       fbBuilder.addOffset(4, offset_name);
     }
+    if (_containingReference != null && _containingReference != 0) {
+      fbBuilder.addUint32(5, _containingReference);
+    }
     return fbBuilder.endTable();
   }
 }
@@ -1324,6 +1427,9 @@
   /**
    * Index into [LinkedLibrary.dependencies] indicating which imported library
    * declares the entity being referred to.
+   *
+   * Zero if this entity is contained within another entity (e.g. a class
+   * member).
    */
   int get dependency;
 
@@ -1338,6 +1444,9 @@
    * definition of the entity.  As with indices into [LinkedLibrary.units],
    * zero represents the defining compilation unit, and nonzero values
    * represent parts in the order of the corresponding `part` declarations.
+   *
+   * Zero if this entity is contained within another entity (e.g. a class
+   * member).
    */
   int get unit;
 
@@ -1353,6 +1462,19 @@
    * string is "dynamic".  For the pseudo-type `void`, the string is "void".
    */
   String get name;
+
+  /**
+   * If this [LinkedReference] doesn't have an associated [UnlinkedReference],
+   * and the entity being referred to is contained within another entity, index
+   * of the containing entity.  This behaves similarly to
+   * [UnlinkedReference.prefixReference], however it is only used for class
+   * members, not for prefixed imports.
+   *
+   * Containing references must always point backward; that is, for all i, if
+   * LinkedUnit.references[i].containingReference != 0, then
+   * LinkedUnit.references[i].containingReference < i.
+   */
+  int get containingReference;
 }
 
 class _LinkedReferenceReader extends fb.TableReader<_LinkedReferenceImpl> {
@@ -1372,6 +1494,7 @@
   int _unit;
   int _numTypeParameters;
   String _name;
+  int _containingReference;
 
   @override
   int get dependency {
@@ -1402,6 +1525,12 @@
     _name ??= const fb.StringReader().vTableGet(_bp, 4, '');
     return _name;
   }
+
+  @override
+  int get containingReference {
+    _containingReference ??= const fb.Uint32Reader().vTableGet(_bp, 5, 0);
+    return _containingReference;
+  }
 }
 
 abstract class _LinkedReferenceMixin implements LinkedReference {
@@ -1412,6 +1541,7 @@
     "unit": unit,
     "numTypeParameters": numTypeParameters,
     "name": name,
+    "containingReference": containingReference,
   };
 }
 
diff --git a/pkg/analyzer/lib/src/summary/prelink.dart b/pkg/analyzer/lib/src/summary/prelink.dart
index 1e3caad..b885a7b 100644
--- a/pkg/analyzer/lib/src/summary/prelink.dart
+++ b/pkg/analyzer/lib/src/summary/prelink.dart
@@ -261,7 +261,7 @@
         cls.fields.forEach((field) {
           if (field.isStatic && field.isConst) {
             namespace[field.name] =
-                new _Meaning(unitNum, ReferenceKind.constField, 0, 0);
+                new _Meaning(unitNum, ReferenceKind.propertyAccessor, 0, 0);
           }
         });
         cls.executables.forEach((executable) {
@@ -272,7 +272,7 @@
           } else if (executable.kind ==
                   UnlinkedExecutableKind.functionOrMethod &&
               executable.isStatic) {
-            kind = ReferenceKind.staticMethod;
+            kind = ReferenceKind.method;
           }
           if (kind != null) {
             namespace[executable.name] = new _Meaning(
@@ -417,7 +417,7 @@
         if (namespace == null && reference.name == 'length') {
           ReferenceKind prefixKind = references[reference.prefixReference].kind;
           if (prefixKind == ReferenceKind.topLevelPropertyAccessor ||
-              prefixKind == ReferenceKind.constField) {
+              prefixKind == ReferenceKind.propertyAccessor) {
             references
                 .add(new LinkedReferenceBuilder(kind: ReferenceKind.length));
             continue;
diff --git a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
index 1f24248..75d142e 100644
--- a/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
+++ b/pkg/analyzer/lib/src/summary/public_namespace_computer.dart
@@ -72,7 +72,7 @@
             if (isPublic(name)) {
               cls.constMembers.add(new UnlinkedPublicNameBuilder(
                   name: name,
-                  kind: ReferenceKind.constField,
+                  kind: ReferenceKind.propertyAccessor,
                   numTypeParameters: 0));
             }
           }
@@ -86,7 +86,7 @@
           if (isPublic(name)) {
             cls.constMembers.add(new UnlinkedPublicNameBuilder(
                 name: name,
-                kind: ReferenceKind.staticMethod,
+                kind: ReferenceKind.method,
                 numTypeParameters:
                     member.typeParameters?.typeParameters?.length ?? 0));
           }
diff --git a/pkg/analyzer/lib/src/summary/resynthesize.dart b/pkg/analyzer/lib/src/summary/resynthesize.dart
index d70d392..4a182ed 100644
--- a/pkg/analyzer/lib/src/summary/resynthesize.dart
+++ b/pkg/analyzer/lib/src/summary/resynthesize.dart
@@ -6,6 +6,7 @@
 
 import 'dart:collection';
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -13,7 +14,10 @@
 import 'package:analyzer/src/generated/element_handle.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source_io.dart';
+import 'package:analyzer/src/generated/testing/ast_factory.dart';
+import 'package:analyzer/src/generated/testing/token_factory.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/format.dart';
 
@@ -240,6 +244,338 @@
 }
 
 /**
+ * Builder of [Expression]s from [UnlinkedConst]s.
+ */
+class _ConstExprBuilder {
+  final _LibraryResynthesizer resynthesizer;
+  final UnlinkedConst uc;
+
+  int intPtr = 0;
+  int doublePtr = 0;
+  int stringPtr = 0;
+  int refPtr = 0;
+  final List<Expression> stack = <Expression>[];
+
+  _ConstExprBuilder(this.resynthesizer, this.uc);
+
+  Expression get expr => stack.single;
+
+  Expression build() {
+    // TODO(scheglov) complete implementation
+    for (UnlinkedConstOperation operation in uc.operations) {
+      switch (operation) {
+        case UnlinkedConstOperation.pushNull:
+          _push(AstFactory.nullLiteral());
+          break;
+        // bool
+        case UnlinkedConstOperation.pushFalse:
+          _push(AstFactory.booleanLiteral(false));
+          break;
+        case UnlinkedConstOperation.pushTrue:
+          _push(AstFactory.booleanLiteral(true));
+          break;
+        // literals
+        case UnlinkedConstOperation.pushInt:
+          int value = uc.ints[intPtr++];
+          _push(AstFactory.integer(value));
+          break;
+        case UnlinkedConstOperation.pushLongInt:
+          int value = 0;
+          int count = uc.ints[intPtr++];
+          for (int i = 0; i < count; i++) {
+            int next = uc.ints[intPtr++];
+            value = value << 32 | next;
+          }
+          _push(AstFactory.integer(value));
+          break;
+        case UnlinkedConstOperation.pushDouble:
+          double value = uc.doubles[doublePtr++];
+          _push(AstFactory.doubleLiteral(value));
+          break;
+        case UnlinkedConstOperation.makeSymbol:
+          String component = uc.strings[stringPtr++];
+          _push(AstFactory.symbolLiteral([component]));
+          break;
+        // String
+        case UnlinkedConstOperation.pushString:
+          String value = uc.strings[stringPtr++];
+          _push(AstFactory.string2(value));
+          break;
+        case UnlinkedConstOperation.concatenate:
+          int count = uc.ints[intPtr++];
+          List<InterpolationElement> elements = <InterpolationElement>[];
+          for (int i = 0; i < count; i++) {
+            Expression expr = _pop();
+            InterpolationElement element = _newInterpolationElement(expr);
+            elements.insert(0, element);
+          }
+          _push(AstFactory.string(elements));
+          break;
+        // binary
+        case UnlinkedConstOperation.equal:
+          _pushBinary(TokenType.EQ_EQ);
+          break;
+        case UnlinkedConstOperation.notEqual:
+          _pushBinary(TokenType.BANG_EQ);
+          break;
+        case UnlinkedConstOperation.and:
+          _pushBinary(TokenType.AMPERSAND_AMPERSAND);
+          break;
+        case UnlinkedConstOperation.or:
+          _pushBinary(TokenType.BAR_BAR);
+          break;
+        case UnlinkedConstOperation.bitXor:
+          _pushBinary(TokenType.CARET);
+          break;
+        case UnlinkedConstOperation.bitAnd:
+          _pushBinary(TokenType.AMPERSAND);
+          break;
+        case UnlinkedConstOperation.bitOr:
+          _pushBinary(TokenType.BAR);
+          break;
+        case UnlinkedConstOperation.bitShiftLeft:
+          _pushBinary(TokenType.LT_LT);
+          break;
+        case UnlinkedConstOperation.bitShiftRight:
+          _pushBinary(TokenType.GT_GT);
+          break;
+        case UnlinkedConstOperation.add:
+          _pushBinary(TokenType.PLUS);
+          break;
+        case UnlinkedConstOperation.subtract:
+          _pushBinary(TokenType.MINUS);
+          break;
+        case UnlinkedConstOperation.multiply:
+          _pushBinary(TokenType.STAR);
+          break;
+        case UnlinkedConstOperation.divide:
+          _pushBinary(TokenType.SLASH);
+          break;
+        case UnlinkedConstOperation.floorDivide:
+          _pushBinary(TokenType.TILDE_SLASH);
+          break;
+        case UnlinkedConstOperation.modulo:
+          _pushBinary(TokenType.PERCENT);
+          break;
+        case UnlinkedConstOperation.greater:
+          _pushBinary(TokenType.GT);
+          break;
+        case UnlinkedConstOperation.greaterEqual:
+          _pushBinary(TokenType.GT_EQ);
+          break;
+        case UnlinkedConstOperation.less:
+          _pushBinary(TokenType.LT);
+          break;
+        case UnlinkedConstOperation.lessEqual:
+          _pushBinary(TokenType.LT_EQ);
+          break;
+        // prefix
+        case UnlinkedConstOperation.complement:
+          _pushPrefix(TokenType.TILDE);
+          break;
+        case UnlinkedConstOperation.negate:
+          _pushPrefix(TokenType.MINUS);
+          break;
+        case UnlinkedConstOperation.not:
+          _pushPrefix(TokenType.BANG);
+          break;
+        // conditional
+        case UnlinkedConstOperation.conditional:
+          Expression elseExpr = _pop();
+          Expression thenExpr = _pop();
+          Expression condition = _pop();
+          _push(
+              AstFactory.conditionalExpression(condition, thenExpr, elseExpr));
+          break;
+        // identical
+        case UnlinkedConstOperation.identical:
+          Expression second = _pop();
+          Expression first = _pop();
+          _push(AstFactory.methodInvocation(
+              null, 'identical', <Expression>[first, second]));
+          break;
+        // containers
+        case UnlinkedConstOperation.makeUntypedList:
+          _pushList(null);
+          break;
+        case UnlinkedConstOperation.makeTypedList:
+          TypeName itemType = _newTypeName();
+          _pushList(AstFactory.typeArgumentList(<TypeName>[itemType]));
+          break;
+        case UnlinkedConstOperation.makeUntypedMap:
+          _pushMap(null);
+          break;
+        case UnlinkedConstOperation.makeTypedMap:
+          TypeName keyType = _newTypeName();
+          TypeName valueType = _newTypeName();
+          _pushMap(AstFactory.typeArgumentList(<TypeName>[keyType, valueType]));
+          break;
+        case UnlinkedConstOperation.pushReference:
+          EntityRef ref = uc.references[refPtr++];
+          _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
+          if (info.element != null) {
+            SimpleIdentifier node = AstFactory.identifier3(info.name);
+            node.staticElement = info.element;
+            _push(node);
+          } else {
+            throw new StateError('Unsupported reference ${ref.toMap()}');
+          }
+          break;
+        case UnlinkedConstOperation.invokeConstructor:
+          _pushInstanceCreation();
+          break;
+        case UnlinkedConstOperation.length:
+          return AstFactory.nullLiteral();
+//          throw new StateError('Unsupported constant operation $operation');
+      }
+    }
+    return stack.single;
+  }
+
+  TypeName _buildTypeAst(DartType type) {
+    if (type is DynamicTypeImpl) {
+      TypeName node = AstFactory.typeName4('dynamic');
+      node.type = type;
+      (node.name as SimpleIdentifier).staticElement = type.element;
+      return node;
+    } else if (type is InterfaceType) {
+      List<TypeName> argumentNodes =
+          type.typeArguments.map(_buildTypeAst).toList();
+      TypeName node = AstFactory.typeName4(type.name, argumentNodes);
+      node.type = type;
+      (node.name as SimpleIdentifier).staticElement = type.element;
+      return node;
+    }
+    throw new StateError('Unsupported type $type');
+  }
+
+  InterpolationElement _newInterpolationElement(Expression expr) {
+    if (expr is SimpleStringLiteral) {
+      return new InterpolationString(expr.literal, expr.value);
+    } else {
+      return new InterpolationExpression(
+          TokenFactory.tokenFromType(TokenType.STRING_INTERPOLATION_EXPRESSION),
+          expr,
+          TokenFactory.tokenFromType(TokenType.CLOSE_CURLY_BRACKET));
+    }
+  }
+
+  /**
+   * Convert the next reference to the [DartType] and return the AST
+   * corresponding to this type.
+   */
+  TypeName _newTypeName() {
+    EntityRef typeRef = uc.references[refPtr++];
+    DartType type = resynthesizer.buildType(typeRef);
+    return _buildTypeAst(type);
+  }
+
+  Expression _pop() => stack.removeLast();
+
+  void _push(Expression expr) {
+    stack.add(expr);
+  }
+
+  void _pushBinary(TokenType operator) {
+    Expression right = _pop();
+    Expression left = _pop();
+    _push(AstFactory.binaryExpression(left, operator, right));
+  }
+
+  void _pushInstanceCreation() {
+    EntityRef ref = uc.references[refPtr++];
+    _ReferenceInfo info = resynthesizer.referenceInfos[ref.reference];
+    // prepare ClassElement / ConstructorElement
+    String className;
+    ClassElement classElement;
+    String constructorName;
+    ConstructorElement constructorElement;
+    if (info.element is ConstructorElement) {
+      constructorName = info.name;
+      constructorElement = info.element;
+      className = info.enclosing.name;
+      classElement = info.enclosing.element as ClassElement;
+    } else if (info.element is ClassElement) {
+      className = info.name;
+      classElement = info.element;
+      constructorName = null;
+      constructorElement = new ConstructorElementHandle(
+          resynthesizer.summaryResynthesizer,
+          new ElementLocationImpl.con3(
+              classElement.location.components.toList()..add('')));
+    } else {
+      throw new StateError('Unsupported element for invokeConstructor '
+          '${info.element?.runtimeType}');
+    }
+    // prepare arguments
+    List<Expression> arguments;
+    {
+      int numNamedArgs = uc.ints[intPtr++];
+      int numPositionalArgs = uc.ints[intPtr++];
+      int numArgs = numNamedArgs + numPositionalArgs;
+      arguments = _removeTopItems(numArgs);
+      // add names to the named arguments
+      for (int i = 0; i < numNamedArgs; i++) {
+        String name = uc.strings[stringPtr++];
+        int index = numPositionalArgs + i;
+        arguments[index] = AstFactory.namedExpression2(name, arguments[index]);
+      }
+    }
+    // create TypeName
+    SimpleIdentifier typeNameNode = AstFactory.identifier3(className);
+    typeNameNode.staticElement = classElement;
+    TypeName typeNode = AstFactory.typeName3(typeNameNode);
+    // create ConstructorName
+    ConstructorName constructorNode;
+    if (constructorName != null) {
+      constructorNode = AstFactory.constructorName(typeNode, info.name);
+      constructorNode.name.staticElement = constructorElement;
+    } else {
+      constructorNode = AstFactory.constructorName(typeNode, null);
+    }
+    constructorNode.staticElement = constructorElement;
+    // create InstanceCreationExpression
+    InstanceCreationExpression instanceCreation = AstFactory
+        .instanceCreationExpression(Keyword.CONST, constructorNode, arguments);
+    instanceCreation.staticElement = constructorElement;
+    _push(instanceCreation);
+  }
+
+  void _pushList(TypeArgumentList typeArguments) {
+    int count = uc.ints[intPtr++];
+    List<Expression> elements = <Expression>[];
+    for (int i = 0; i < count; i++) {
+      elements.insert(0, _pop());
+    }
+    _push(AstFactory.listLiteral2(Keyword.CONST, typeArguments, elements));
+  }
+
+  void _pushMap(TypeArgumentList typeArguments) {
+    int count = uc.ints[intPtr++];
+    List<MapLiteralEntry> entries = <MapLiteralEntry>[];
+    for (int i = 0; i < count; i++) {
+      Expression value = _pop();
+      Expression key = _pop();
+      entries.insert(0, AstFactory.mapLiteralEntry2(key, value));
+    }
+    _push(AstFactory.mapLiteral(Keyword.CONST, typeArguments, entries));
+  }
+
+  void _pushPrefix(TokenType operator) {
+    Expression operand = _pop();
+    _push(AstFactory.prefixExpression(operator, operand));
+  }
+
+  List<Expression> _removeTopItems(int count) {
+    int start = stack.length - count;
+    int end = stack.length;
+    List<Expression> items = stack.getRange(start, end).toList();
+    stack.removeRange(start, end);
+    return items;
+  }
+}
+
+/**
  * An instance of [_LibraryResynthesizer] is responsible for resynthesizing the
  * elements in a single library from that library's summary.
  */
@@ -324,6 +660,12 @@
    */
   Map<String, FieldElementImpl> fields;
 
+  /**
+   * List of [_ReferenceInfo] objects describing the references in the current
+   * compilation unit.
+   */
+  List<_ReferenceInfo> referenceInfos;
+
   _LibraryResynthesizer(this.summaryResynthesizer, this.linkedLibrary,
       this.unlinkedUnits, this.librarySource) {
     isCoreLibrary = librarySource.uri.toString() == 'dart:core';
@@ -651,10 +993,9 @@
         !name.endsWith('=')) {
       name += '?';
     }
-    ElementLocationImpl location = getReferencedLocation(
-        linkedLibrary.dependencies[exportName.dependency],
-        exportName.unit,
-        name);
+    ElementLocationImpl location = new ElementLocationImpl.con3(
+        getReferencedLocationComponents(
+            exportName.dependency, exportName.unit, name));
     switch (exportName.kind) {
       case ReferenceKind.classOrEnum:
         return new ClassElementHandle(summaryResynthesizer, location);
@@ -667,8 +1008,8 @@
         return new PropertyAccessorElementHandle(
             summaryResynthesizer, location);
       case ReferenceKind.constructor:
-      case ReferenceKind.constField:
-      case ReferenceKind.staticMethod:
+      case ReferenceKind.propertyAccessor:
+      case ReferenceKind.method:
       case ReferenceKind.length:
       case ReferenceKind.prefix:
       case ReferenceKind.unresolved:
@@ -1005,72 +1346,19 @@
     if (type.paramReference != 0) {
       // TODO(paulberry): make this work for generic methods.
       return currentTypeParameters[
-          currentTypeParameters.length - type.paramReference].type;
+              currentTypeParameters.length - type.paramReference]
+          .type;
     } else {
-      LinkedReference referenceResolution =
-          linkedUnit.references[type.reference];
-      String name;
-      if (type.reference < unlinkedUnit.references.length) {
-        name = unlinkedUnit.references[type.reference].name;
-      } else {
-        name = referenceResolution.name;
-      }
-      ElementLocationImpl location;
-      if (referenceResolution.dependency != 0) {
-        location = getReferencedLocation(
-            linkedLibrary.dependencies[referenceResolution.dependency],
-            referenceResolution.unit,
-            name);
-      } else if (referenceResolution.kind == ReferenceKind.unresolved) {
-        return summaryResynthesizer.typeProvider.undefinedType;
-      } else if (name == 'dynamic') {
-        return summaryResynthesizer.typeProvider.dynamicType;
-      } else if (name == 'void') {
-        return VoidTypeImpl.instance;
-      } else {
-        String referencedLibraryUri = librarySource.uri.toString();
-        String partUri;
-        if (referenceResolution.unit != 0) {
-          String uri = unlinkedUnits[0].publicNamespace.parts[
-              referenceResolution.unit - 1];
-          Source partSource =
-              summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
-          partUri = partSource.uri.toString();
+      DartType getTypeArgument(int i) {
+        if (i < type.typeArguments.length) {
+          return buildType(type.typeArguments[i]);
         } else {
-          partUri = referencedLibraryUri;
-        }
-        location = new ElementLocationImpl.con3(
-            <String>[referencedLibraryUri, partUri, name]);
-      }
-      List<DartType> typeArguments = const <DartType>[];
-      if (referenceResolution.numTypeParameters != 0) {
-        typeArguments = <DartType>[];
-        for (int i = 0; i < referenceResolution.numTypeParameters; i++) {
-          if (i < type.typeArguments.length) {
-            typeArguments.add(buildType(type.typeArguments[i]));
-          } else {
-            typeArguments.add(summaryResynthesizer.typeProvider.dynamicType);
-          }
+          return summaryResynthesizer.typeProvider.dynamicType;
         }
       }
-      switch (referenceResolution.kind) {
-        case ReferenceKind.classOrEnum:
-          return new InterfaceTypeImpl.elementWithNameAndArgs(
-              new ClassElementHandle(summaryResynthesizer, location),
-              name,
-              typeArguments);
-        case ReferenceKind.typedef:
-          return new FunctionTypeImpl.elementWithNameAndArgs(
-              new FunctionTypeAliasElementHandle(
-                  summaryResynthesizer, location),
-              name,
-              typeArguments,
-              typeArguments.isNotEmpty);
-        default:
-          // TODO(paulberry): figure out how to handle this case (which should
-          // only occur in the event of erroneous code).
-          throw new UnimplementedError();
-      }
+      _ReferenceInfo referenceInfo = referenceInfos[type.reference];
+      return referenceInfo.buildType(
+          getTypeArgument, type.implicitFunctionTypeIndices);
     }
   }
 
@@ -1127,8 +1415,20 @@
   void buildVariable(UnlinkedVariable serializedVariable,
       [ElementHolder holder]) {
     if (holder == null) {
-      TopLevelVariableElementImpl element = new TopLevelVariableElementImpl(
-          serializedVariable.name, serializedVariable.nameOffset);
+      TopLevelVariableElementImpl element;
+      if (serializedVariable.constExpr != null) {
+        ConstTopLevelVariableElementImpl constElement =
+            new ConstTopLevelVariableElementImpl(
+                serializedVariable.name, serializedVariable.nameOffset);
+        element = constElement;
+        // TODO(scheglov) share const builder?
+        _ConstExprBuilder builder =
+            new _ConstExprBuilder(this, serializedVariable.constExpr);
+        constElement.constantInitializer = builder.build();
+      } else {
+        element = new TopLevelVariableElementImpl(
+            serializedVariable.name, serializedVariable.nameOffset);
+      }
       buildVariableCommonParts(element, serializedVariable);
       unitHolder.addTopLevelVariable(element);
       buildImplicitAccessors(element, unitHolder);
@@ -1169,31 +1469,124 @@
   }
 
   /**
-   * Build an [ElementLocationImpl] for the entity in the given [unit] of the
-   * given [dependency], having the given [name].
+   * Build the components of an [ElementLocationImpl] for the entity in the
+   * given [unit] of the dependency located at [dependencyIndex], and having
+   * the given [name].
    */
-  ElementLocationImpl getReferencedLocation(
-      LinkedDependency dependency, int unit, String name) {
+  List<String> getReferencedLocationComponents(
+      int dependencyIndex, int unit, String name) {
+    if (dependencyIndex == 0) {
+      String referencedLibraryUri = librarySource.uri.toString();
+      String partUri;
+      if (unit != 0) {
+        String uri = unlinkedUnits[0].publicNamespace.parts[unit - 1];
+        Source partSource =
+            summaryResynthesizer.sourceFactory.resolveUri(librarySource, uri);
+        partUri = partSource.uri.toString();
+      } else {
+        partUri = referencedLibraryUri;
+      }
+      return <String>[referencedLibraryUri, partUri, name];
+    }
+    LinkedDependency dependency = linkedLibrary.dependencies[dependencyIndex];
     Source referencedLibrarySource = summaryResynthesizer.sourceFactory
         .resolveUri(librarySource, dependency.uri);
     String referencedLibraryUri = referencedLibrarySource.uri.toString();
-    // TODO(paulberry): consider changing Location format so that this is
-    // not necessary (2nd string in location should just be the unit
-    // number).
     String partUri;
     if (unit != 0) {
-      UnlinkedUnit referencedLibraryDefiningUnit =
-          summaryResynthesizer._getUnlinkedSummaryOrThrow(referencedLibraryUri);
-      String uri =
-          referencedLibraryDefiningUnit.publicNamespace.parts[unit - 1];
+      String uri = dependency.parts[unit - 1];
       Source partSource = summaryResynthesizer.sourceFactory
           .resolveUri(referencedLibrarySource, uri);
       partUri = partSource.uri.toString();
     } else {
       partUri = referencedLibraryUri;
     }
-    return new ElementLocationImpl.con3(
-        <String>[referencedLibraryUri, partUri, name]);
+    return <String>[referencedLibraryUri, partUri, name];
+  }
+
+  /**
+   * Populate [referenceInfos] with the correct information for the current
+   * compilation unit.
+   */
+  void populateReferenceInfos() {
+    int numLinkedReferences = linkedUnit.references.length;
+    int numUnlinkedReferences = unlinkedUnit.references.length;
+    referenceInfos = new List<_ReferenceInfo>(numLinkedReferences);
+    for (int i = 0; i < numLinkedReferences; i++) {
+      LinkedReference linkedReference = linkedUnit.references[i];
+      _ReferenceInfo enclosingInfo = null;
+      String name;
+      int containingReference;
+      if (i < numUnlinkedReferences) {
+        name = unlinkedUnit.references[i].name;
+        containingReference = unlinkedUnit.references[i].prefixReference;
+      } else {
+        name = linkedUnit.references[i].name;
+        containingReference = linkedUnit.references[i].containingReference;
+      }
+      Element element;
+      DartType type;
+      if (linkedReference.kind == ReferenceKind.unresolved) {
+        type = summaryResynthesizer.typeProvider.undefinedType;
+        element = type.element;
+      } else if (name == 'dynamic') {
+        type = summaryResynthesizer.typeProvider.dynamicType;
+        element = type.element;
+      } else if (name == 'void') {
+        type = VoidTypeImpl.instance;
+        element = type.element;
+      } else {
+        List<String> locationComponents;
+        if (containingReference != 0 &&
+            referenceInfos[containingReference].element is ClassElement) {
+          String identifier = _getElementIdentifier(name, linkedReference.kind);
+          enclosingInfo = referenceInfos[containingReference];
+          locationComponents =
+              enclosingInfo.element.location.components.toList();
+          locationComponents.add(identifier);
+        } else {
+          String identifier = _getElementIdentifier(name, linkedReference.kind);
+          locationComponents = getReferencedLocationComponents(
+              linkedReference.dependency, linkedReference.unit, identifier);
+        }
+        ElementLocation location =
+            new ElementLocationImpl.con3(locationComponents);
+        switch (linkedReference.kind) {
+          case ReferenceKind.classOrEnum:
+            element = new ClassElementHandle(summaryResynthesizer, location);
+            break;
+          case ReferenceKind.typedef:
+            element = new FunctionTypeAliasElementHandle(
+                summaryResynthesizer, location);
+            break;
+          case ReferenceKind.topLevelPropertyAccessor:
+            element = new PropertyAccessorElementHandle(
+                summaryResynthesizer, location);
+            break;
+          case ReferenceKind.constructor:
+            assert(location.components.length == 4);
+            element =
+                new ConstructorElementHandle(summaryResynthesizer, location);
+            break;
+          case ReferenceKind.propertyAccessor:
+            assert(location.components.length == 4);
+            element = new PropertyAccessorElementHandle(
+                summaryResynthesizer, location);
+            break;
+          case ReferenceKind.method:
+            assert(location.components.length == 4);
+            element = new MethodElementHandle(summaryResynthesizer, location);
+            break;
+          default:
+            // This is an element that doesn't (yet) need to be referred to
+            // directly, so don't bother populating an element for it.
+            // TODO(paulberry): add support for more kinds, as needed.
+            break;
+        }
+      }
+      referenceInfos[i] = new _ReferenceInfo(enclosingInfo, name, element, type,
+          linkedReference.numTypeParameters);
+    }
   }
 
   /**
@@ -1207,6 +1600,7 @@
     for (EntityRef t in linkedUnit.types) {
       linkedTypeMap[t.slot] = t;
     }
+    populateReferenceInfos();
     unitHolder = new ElementHolder();
     unlinkedUnit.classes.forEach(buildClass);
     unlinkedUnit.enums.forEach(buildEnum);
@@ -1247,5 +1641,147 @@
     linkedUnit = null;
     unlinkedUnit = null;
     linkedTypeMap = null;
+    referenceInfos = null;
+  }
+
+  /**
+   * If the given [kind] is a top-level or class member property accessor, and
+   * the given [name] does not end with `=`, i.e. does not denote a setter,
+   * return the getter identifier by appending `?`.
+   */
+  static String _getElementIdentifier(String name, ReferenceKind kind) {
+    if (kind == ReferenceKind.topLevelPropertyAccessor ||
+        kind == ReferenceKind.propertyAccessor) {
+      if (!name.endsWith('=')) {
+        return name + '?';
+      }
+    }
+    return name;
+  }
+}
+
+/**
+ * Data structure used during resynthesis to record all the information that is
+ * known about how to resynthesize a single entry in [LinkedUnit.references]
+ * (and its associated entry in [UnlinkedUnit.references], if it exists).
+ */
+class _ReferenceInfo {
+  /**
+   * The enclosing [_ReferenceInfo], or `null` for top-level elements.
+   */
+  final _ReferenceInfo enclosing;
+
+  /**
+   * The name of the entity referred to by this reference.
+   */
+  final String name;
+
+  /**
+   * The element referred to by this reference, or `null` if there is no
+   * associated element (e.g. because it is a reference to an undefined
+   * entity).
+   */
+  final Element element;
+
+  /**
+   * If this reference refers to a non-generic type, the type it refers to.
+   * Otherwise `null`.
+   */
+  DartType type;
+
+  /**
+   * The number of type parameters accepted by the entity referred to by this
+   * reference, or zero if it doesn't accept any type parameters.
+   */
+  final int numTypeParameters;
+
+  /**
+   * Create a new [_ReferenceInfo] object referring to an element called [name]
+   * via the element handle [element], and having [numTypeParameters] type
+   * parameters.
+   *
+   * For the special types `dynamic` and `void`, [specialType] should point to
+   * 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) {
+    if (specialType != null) {
+      type = specialType;
+    } else {
+      type = _buildType((_) => DynamicTypeImpl.instance, null);
+    }
+  }
+
+  /**
+   * Build a [DartType] corresponding to the result of applying some type
+   * arguments to the entity referred to by this [_ReferenceInfo].  The type
+   * arguments are retrieved by calling [getTypeArgument].
+   *
+   * If [implicitFunctionTypeIndices] is not empty, 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].
+   *
+   * If the entity referred to by this [_ReferenceInfo] is not a type, `null`
+   * is returned.
+   */
+  DartType buildType(
+      DartType getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
+    DartType result =
+        (numTypeParameters == 0 && implicitFunctionTypeIndices.isEmpty)
+            ? type
+            : _buildType(getTypeArgument, implicitFunctionTypeIndices);
+    if (result == null) {
+      // TODO(paulberry): figure out how to handle this case (which should
+      // only occur in the event of erroneous code).
+      throw new UnimplementedError();
+    }
+    return result;
+  }
+
+  /**
+   * If this reference refers to a type, build a [DartType] which instantiates
+   * it with type arguments returned by [getTypeArgument].  Otherwise return
+   * `null`.
+   *
+   * 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 getTypeArgument(int i), List<int> implicitFunctionTypeIndices) {
+    List<DartType> typeArguments = const <DartType>[];
+    if (numTypeParameters != 0) {
+      typeArguments = <DartType>[];
+      for (int i = 0; i < numTypeParameters; i++) {
+        typeArguments.add(getTypeArgument(i));
+      }
+    }
+    ElementHandle element = this.element; // To allow type promotion
+    if (element is ClassElementHandle) {
+      return new InterfaceTypeImpl.elementWithNameAndArgs(
+          element, name, typeArguments);
+    } else if (element is FunctionTypeAliasElementHandle) {
+      return new FunctionTypeImpl.elementWithNameAndArgs(
+          element, name, typeArguments, typeArguments.isNotEmpty);
+    } else if (element is FunctionTypedElement) {
+      FunctionTypedElementComputer computer =
+          implicitFunctionTypeIndices != null
+              ? () {
+                  FunctionTypedElement element = this.element;
+                  for (int index in implicitFunctionTypeIndices) {
+                    element = element.parameters[index].type.element;
+                  }
+                  return element;
+                }
+              : () => this.element;
+      // TODO(paulberry): Is it a bug that we have to pass `false` for
+      // isInstantiated?
+      return new DeferredFunctionTypeImpl(computer, null, typeArguments, false);
+    } else {
+      return null;
+    }
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/summarize_ast.dart b/pkg/analyzer/lib/src/summary/summarize_ast.dart
index c43a9b9..20d646d 100644
--- a/pkg/analyzer/lib/src/summary/summarize_ast.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_ast.dart
@@ -36,7 +36,8 @@
     } else {
       String name = constructor.name.name;
       int nameRef = visitor.serializeReference(typeBuilder.reference, name);
-      return new EntityRefBuilder(reference: nameRef);
+      return new EntityRefBuilder(
+          reference: nameRef, typeArguments: typeBuilder.typeArguments);
     }
   }
 
diff --git a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
index f6dea26..8d4f97b 100644
--- a/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_const_expr.dart
@@ -57,7 +57,6 @@
       _serializeString(expr);
     } else if (expr is SymbolLiteral) {
       strings.add(expr.components.map((token) => token.lexeme).join('.'));
-      operations.add(UnlinkedConstOperation.pushString);
       operations.add(UnlinkedConstOperation.makeSymbol);
     } else if (expr is NullLiteral) {
       operations.add(UnlinkedConstOperation.pushNull);
@@ -144,9 +143,18 @@
   void _pushInt(int value) {
     assert(value >= 0);
     if (value >= (1 << 32)) {
-      _pushInt(value >> 32);
-      operations.add(UnlinkedConstOperation.shiftOr);
-      ints.add(value & 0xFFFFFFFF);
+      int numOfComponents = 0;
+      ints.add(numOfComponents);
+      void pushComponents(int value) {
+        if (value >= (1 << 32)) {
+          pushComponents(value >> 32);
+        }
+        numOfComponents++;
+        ints.add(value & 0xFFFFFFFF);
+      }
+      pushComponents(value);
+      ints[ints.length - 1 - numOfComponents] = numOfComponents;
+      operations.add(UnlinkedConstOperation.pushLongInt);
     } else {
       operations.add(UnlinkedConstOperation.pushInt);
       ints.add(value);
@@ -160,8 +168,7 @@
     if (operator == TokenType.EQ_EQ) {
       operations.add(UnlinkedConstOperation.equal);
     } else if (operator == TokenType.BANG_EQ) {
-      operations.add(UnlinkedConstOperation.equal);
-      operations.add(UnlinkedConstOperation.not);
+      operations.add(UnlinkedConstOperation.notEqual);
     } else if (operator == TokenType.AMPERSAND_AMPERSAND) {
       operations.add(UnlinkedConstOperation.and);
     } else if (operator == TokenType.BAR_BAR) {
diff --git a/pkg/analyzer/lib/src/summary/summarize_elements.dart b/pkg/analyzer/lib/src/summary/summarize_elements.dart
index 66f31ecc..4d90318 100644
--- a/pkg/analyzer/lib/src/summary/summarize_elements.dart
+++ b/pkg/analyzer/lib/src/summary/summarize_elements.dart
@@ -40,11 +40,11 @@
     return ReferenceKind.typedef;
   } else if (element is PropertyAccessorElement) {
     if (element.enclosingElement is ClassElement) {
-      return ReferenceKind.constField;
+      return ReferenceKind.propertyAccessor;
     }
     return ReferenceKind.topLevelPropertyAccessor;
   } else if (element is MethodElement) {
-    return ReferenceKind.staticMethod;
+    return ReferenceKind.method;
   } else {
     throw new Exception('Unexpected element kind: ${element.runtimeType}');
   }
@@ -388,22 +388,25 @@
       List<UnlinkedPublicNameBuilder> bs = <UnlinkedPublicNameBuilder>[];
       for (FieldElement field in cls.fields) {
         if (field.isStatic && field.isConst && field.isPublic) {
+          // TODO(paulberry): should numTypeParameters include class params?
           bs.add(new UnlinkedPublicNameBuilder(
               name: field.name,
-              kind: ReferenceKind.constField,
+              kind: ReferenceKind.propertyAccessor,
               numTypeParameters: 0));
         }
       }
       for (MethodElement method in cls.methods) {
         if (method.isStatic && method.isPublic) {
+          // TODO(paulberry): should numTypeParameters include class params?
           bs.add(new UnlinkedPublicNameBuilder(
               name: method.name,
-              kind: ReferenceKind.staticMethod,
+              kind: ReferenceKind.method,
               numTypeParameters: method.typeParameters.length));
         }
       }
       for (ConstructorElement constructor in cls.constructors) {
         if (constructor.isConst && constructor.isPublic) {
+          // TODO(paulberry): should numTypeParameters include class params?
           bs.add(new UnlinkedPublicNameBuilder(
               name: constructor.name,
               kind: ReferenceKind.constructor,
@@ -675,7 +678,7 @@
    * Serialize the given [type] into a [EntityRef].  If [slot] is provided,
    * it should be included in the [EntityRef].  If [linked] is true, any
    * references that are created will be populated into [linkedReferences] but
-   * [not [unlinkedReferences].
+   * not [unlinkedReferences].
    *
    * [context] is the element within which the [EntityRef] will be
    * interpreted; this is used to serialize type parameters.
@@ -686,7 +689,36 @@
     if (type is TypeParameterType) {
       b.paramReference = findTypeParameterIndex(type, context);
     } else {
-      b.reference = serializeReferenceForType(type, linked);
+      if (type is FunctionType &&
+          type.element.enclosingElement is ParameterElement) {
+        // Code cannot refer to function types implicitly defined by parameters
+        // directly, so if we get here, we must be serializing a linked
+        // reference from type inference.
+        assert(linked);
+        ParameterElement parameterElement = type.element.enclosingElement;
+        while (true) {
+          Element parent = parameterElement.enclosingElement;
+          if (parent is ExecutableElement) {
+            Element grandParent = parent.enclosingElement;
+            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, linked: linked);
+              break;
+            }
+          } else {
+            throw new StateError(
+                'Unexpected element enclosing parameter: ${parent.runtimeType}');
+          }
+        }
+      } else {
+        b.reference = serializeReferenceForType(type, linked);
+      }
       List<DartType> typeArguments = getTypeArguments(type);
       if (typeArguments != null) {
         // Trailing type arguments of type 'dynamic' should be omitted.
@@ -798,19 +830,6 @@
 
   int _getElementReferenceId(Element element, {bool linked: false}) {
     return referenceMap.putIfAbsent(element, () {
-      if (element is ConstructorElement && element.displayName.isEmpty) {
-        return _getElementReferenceId(element.enclosingElement, linked: linked);
-      }
-      if (element is MethodElement && !element.isStatic) {
-        throw new StateError('Only static methods can be serialized.');
-      }
-      if (element is PropertyAccessorElement) {
-        Element enclosing = element.enclosingElement;
-        if (!(enclosing is CompilationUnitElement || element.isStatic)) {
-          throw new StateError(
-              'Only top-level or static property accessors can be serialized.');
-        }
-      }
       LibraryElement dependentLibrary = element?.library;
       int unit;
       if (dependentLibrary == null) {
@@ -824,18 +843,22 @@
         unit = dependentLibrary.units.indexOf(unitElement);
         assert(unit != -1);
       }
-      int numTypeParameters = 0;
-      if (element is TypeParameterizedElement) {
-        numTypeParameters = element.typeParameters.length;
-      }
       LinkedReferenceBuilder linkedReference = new LinkedReferenceBuilder(
           dependency: librarySerializer.serializeDependency(dependentLibrary),
           kind: _getReferenceKind(element),
-          unit: unit,
-          numTypeParameters: numTypeParameters);
+          unit: unit);
+      if (element is TypeParameterizedElement) {
+        linkedReference.numTypeParameters = element.typeParameters.length;
+      }
       String name = element == null ? 'void' : element.name;
       if (linked) {
         linkedReference.name = name;
+        Element enclosing = element?.enclosingElement;
+        if (enclosing is ClassElement) {
+          linkedReference.containingReference =
+              _getElementReferenceId(enclosing, linked: linked);
+          linkedReference.numTypeParameters += enclosing.typeParameters.length;
+        }
       } else {
         assert(unlinkedReferences.length == linkedReferences.length);
         int prefixReference = 0;
@@ -885,10 +908,23 @@
 
   @override
   EntityRefBuilder serializeConstructorName(ConstructorName constructor) {
-    ConstructorElement element = constructor.staticElement;
-    assert(element != null);
-    int referenceId = serializer._getElementReferenceId(element);
-    return new EntityRefBuilder(reference: referenceId);
+    DartType type = constructor.type.type;
+    EntityRefBuilder typeRef = serializer.serializeTypeRef(type, null);
+    if (constructor.name == null) {
+      return typeRef;
+    } else {
+      int typeId = typeRef.reference;
+      LinkedReference typeLinkedRef = serializer.linkedReferences[typeId];
+      serializer.unlinkedReferences.add(new UnlinkedReferenceBuilder(
+          name: constructor.name.name, prefixReference: typeId));
+      int refId = serializer.linkedReferences.length;
+      serializer.linkedReferences.add(new LinkedReferenceBuilder(
+          kind: ReferenceKind.constructor,
+          dependency: typeLinkedRef.dependency,
+          unit: typeLinkedRef.unit));
+      return new EntityRefBuilder(
+          reference: refId, typeArguments: typeRef.typeArguments);
+    }
   }
 
   EntityRefBuilder serializeIdentifier(Identifier identifier) {
diff --git a/pkg/analyzer/lib/src/task/dart.dart b/pkg/analyzer/lib/src/task/dart.dart
index 2c99cd2..bafe917 100644
--- a/pkg/analyzer/lib/src/task/dart.dart
+++ b/pkg/analyzer/lib/src/task/dart.dart
@@ -13,6 +13,7 @@
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -983,7 +984,6 @@
 
   @override
   void internalPerform() {
-    List<AnalysisError> errors = <AnalysisError>[];
     //
     // Prepare inputs.
     //
@@ -997,114 +997,17 @@
         getRequiredInput(IMPORTS_SOURCE_KIND_INPUT_NAME);
     Map<Source, SourceKind> exportSourceKindMap =
         getRequiredInput(EXPORTS_SOURCE_KIND_INPUT_NAME);
-    Source librarySource = libraryElement.source;
     //
-    // Resolve directives.
+    // Build elements.
     //
-    HashMap<String, PrefixElementImpl> nameToPrefixMap =
-        new HashMap<String, PrefixElementImpl>();
-    List<ImportElement> imports = <ImportElement>[];
-    List<ExportElement> exports = <ExportElement>[];
-    bool explicitlyImportsCore = false;
-    for (Directive directive in libraryUnit.directives) {
-      if (directive is ImportDirective) {
-        ImportDirective importDirective = directive;
-        String uriContent = importDirective.uriContent;
-        if (DartUriResolver.isDartExtUri(uriContent)) {
-          libraryElement.hasExtUri = true;
-        }
-        Source importedSource = importDirective.source;
-        if (importedSource != null && context.exists(importedSource)) {
-          // The imported source will be null if the URI in the import
-          // directive was invalid.
-          LibraryElement importedLibrary = importLibraryMap[importedSource];
-          if (importedLibrary != null) {
-            if (importedLibrary.isDartCore) {
-              explicitlyImportsCore = true;
-            }
-            ImportElementImpl importElement =
-                new ImportElementImpl(directive.offset);
-            StringLiteral uriLiteral = importDirective.uri;
-            if (uriLiteral != null) {
-              importElement.uriOffset = uriLiteral.offset;
-              importElement.uriEnd = uriLiteral.end;
-            }
-            importElement.uri = uriContent;
-            importElement.deferred = importDirective.deferredKeyword != null;
-            importElement.combinators = _buildCombinators(importDirective);
-            importElement.importedLibrary = importedLibrary;
-            _setDoc(importElement, importDirective);
-            SimpleIdentifier prefixNode = directive.prefix;
-            if (prefixNode != null) {
-              importElement.prefixOffset = prefixNode.offset;
-              String prefixName = prefixNode.name;
-              PrefixElementImpl prefix = nameToPrefixMap[prefixName];
-              if (prefix == null) {
-                prefix = new PrefixElementImpl.forNode(prefixNode);
-                nameToPrefixMap[prefixName] = prefix;
-              }
-              importElement.prefix = prefix;
-              prefixNode.staticElement = prefix;
-            }
-            directive.element = importElement;
-            imports.add(importElement);
-            if (importSourceKindMap[importedSource] != SourceKind.LIBRARY) {
-              ErrorCode errorCode = (importElement.isDeferred
-                  ? StaticWarningCode.IMPORT_OF_NON_LIBRARY
-                  : CompileTimeErrorCode.IMPORT_OF_NON_LIBRARY);
-              errors.add(new AnalysisError(importedSource, uriLiteral.offset,
-                  uriLiteral.length, errorCode, [uriLiteral.toSource()]));
-            }
-          }
-        }
-      } else if (directive is ExportDirective) {
-        ExportDirective exportDirective = directive;
-        Source exportedSource = exportDirective.source;
-        if (exportedSource != null && context.exists(exportedSource)) {
-          // The exported source will be null if the URI in the export
-          // directive was invalid.
-          LibraryElement exportedLibrary = exportLibraryMap[exportedSource];
-          if (exportedLibrary != null) {
-            ExportElementImpl exportElement =
-                new ExportElementImpl(directive.offset);
-            StringLiteral uriLiteral = exportDirective.uri;
-            if (uriLiteral != null) {
-              exportElement.uriOffset = uriLiteral.offset;
-              exportElement.uriEnd = uriLiteral.end;
-            }
-            exportElement.uri = exportDirective.uriContent;
-            exportElement.combinators = _buildCombinators(exportDirective);
-            exportElement.exportedLibrary = exportedLibrary;
-            _setDoc(exportElement, exportDirective);
-            directive.element = exportElement;
-            exports.add(exportElement);
-            if (exportSourceKindMap[exportedSource] != SourceKind.LIBRARY) {
-              errors.add(new AnalysisError(
-                  exportedSource,
-                  uriLiteral.offset,
-                  uriLiteral.length,
-                  CompileTimeErrorCode.EXPORT_OF_NON_LIBRARY,
-                  [uriLiteral.toSource()]));
-            }
-          }
-        }
-      }
-    }
-    //
-    // Ensure "dart:core" import.
-    //
-    Source coreLibrarySource = context.sourceFactory.forUri(DartSdk.DART_CORE);
-    if (!explicitlyImportsCore && coreLibrarySource != librarySource) {
-      ImportElementImpl importElement = new ImportElementImpl(-1);
-      importElement.importedLibrary = importLibraryMap[coreLibrarySource];
-      importElement.synthetic = true;
-      imports.add(importElement);
-    }
-    //
-    // Populate the library element.
-    //
-    libraryElement.imports = imports;
-    libraryElement.exports = exports;
+    DirectiveElementBuilder builder = new DirectiveElementBuilder(
+        context,
+        libraryElement,
+        importLibraryMap,
+        importSourceKindMap,
+        exportLibraryMap,
+        exportSourceKindMap);
+    libraryUnit.accept(builder);
     // See commentary in the computation of the LIBRARY_CYCLE result
     // for details on library cycle invalidation.
     libraryElement.invalidateLibraryCycles();
@@ -1112,20 +1015,7 @@
     // Record outputs.
     //
     outputs[LIBRARY_ELEMENT2] = libraryElement;
-    outputs[BUILD_DIRECTIVES_ERRORS] = errors;
-  }
-
-  /**
-   * If the given [node] has a documentation comment, remember its content
-   * and range into the given [element].
-   */
-  void _setDoc(ElementImpl element, AnnotatedNode node) {
-    Comment comment = node.documentationComment;
-    if (comment != null && comment.isDocumentation) {
-      element.documentationComment =
-          comment.tokens.map((Token t) => t.lexeme).join('\n');
-      element.setDocRange(comment.offset, comment.length);
-    }
+    outputs[BUILD_DIRECTIVES_ERRORS] = builder.errors;
   }
 
   /**
@@ -1158,36 +1048,6 @@
       AnalysisContext context, AnalysisTarget target) {
     return new BuildDirectiveElementsTask(context, target);
   }
-
-  /**
-   * Build the element model representing the combinators declared by
-   * the given [directive].
-   */
-  static List<NamespaceCombinator> _buildCombinators(
-      NamespaceDirective directive) {
-    List<NamespaceCombinator> combinators = <NamespaceCombinator>[];
-    for (Combinator combinator in directive.combinators) {
-      if (combinator is ShowCombinator) {
-        ShowElementCombinatorImpl show = new ShowElementCombinatorImpl();
-        show.offset = combinator.offset;
-        show.end = combinator.end;
-        show.shownNames = _getIdentifiers(combinator.shownNames);
-        combinators.add(show);
-      } else if (combinator is HideCombinator) {
-        HideElementCombinatorImpl hide = new HideElementCombinatorImpl();
-        hide.hiddenNames = _getIdentifiers(combinator.hiddenNames);
-        combinators.add(hide);
-      }
-    }
-    return combinators;
-  }
-
-  /**
-   * Return the lexical identifiers associated with the given [identifiers].
-   */
-  static List<String> _getIdentifiers(NodeList<SimpleIdentifier> identifiers) {
-    return identifiers.map((identifier) => identifier.name).toList();
-  }
 }
 
 /**
diff --git a/pkg/analyzer/lib/src/task/incremental_element_builder.dart b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
index 05029d3..4f674ef 100644
--- a/pkg/analyzer/lib/src/task/incremental_element_builder.dart
+++ b/pkg/analyzer/lib/src/task/incremental_element_builder.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/visitor.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index 01abc35..893b888 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.27.2-alpha.0
+version: 0.27.2-alpha.1
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: http://www.dartlang.org
diff --git a/pkg/analyzer/test/generated/all_the_rest_test.dart b/pkg/analyzer/test/generated/all_the_rest_test.dart
index 34b9797..ee26679 100644
--- a/pkg/analyzer/test/generated/all_the_rest_test.dart
+++ b/pkg/analyzer/test/generated/all_the_rest_test.dart
@@ -9,8 +9,8 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart' hide ConstantEvaluator;
+import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
-import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
 import 'package:analyzer/src/generated/java_core.dart';
@@ -41,9 +41,7 @@
   initializeTestEnvironment();
   runReflectiveTests(ContentCacheTest);
   runReflectiveTests(CustomUriResolverTest);
-  runReflectiveTests(DartObjectImplTest);
   runReflectiveTests(DartUriResolverTest);
-  runReflectiveTests(DeclaredVariablesTest);
   runReflectiveTests(DirectoryBasedDartSdkTest);
   runReflectiveTests(DirectoryBasedSourceContainerTest);
   runReflectiveTests(ElementBuilderTest);
@@ -104,2130 +102,6 @@
 }
 
 @reflectiveTest
-class DartObjectImplTest extends EngineTestCase {
-  TypeProvider _typeProvider = new TestTypeProvider();
-
-  void test_add_knownDouble_knownDouble() {
-    _assertAdd(_doubleValue(3.0), _doubleValue(1.0), _doubleValue(2.0));
-  }
-
-  void test_add_knownDouble_knownInt() {
-    _assertAdd(_doubleValue(3.0), _doubleValue(1.0), _intValue(2));
-  }
-
-  void test_add_knownDouble_unknownDouble() {
-    _assertAdd(_doubleValue(null), _doubleValue(1.0), _doubleValue(null));
-  }
-
-  void test_add_knownDouble_unknownInt() {
-    _assertAdd(_doubleValue(null), _doubleValue(1.0), _intValue(null));
-  }
-
-  void test_add_knownInt_knownInt() {
-    _assertAdd(_intValue(3), _intValue(1), _intValue(2));
-  }
-
-  void test_add_knownInt_knownString() {
-    _assertAdd(null, _intValue(1), _stringValue("2"));
-  }
-
-  void test_add_knownInt_unknownDouble() {
-    _assertAdd(_doubleValue(null), _intValue(1), _doubleValue(null));
-  }
-
-  void test_add_knownInt_unknownInt() {
-    _assertAdd(_intValue(null), _intValue(1), _intValue(null));
-  }
-
-  void test_add_knownString_knownInt() {
-    _assertAdd(null, _stringValue("1"), _intValue(2));
-  }
-
-  void test_add_knownString_knownString() {
-    _assertAdd(_stringValue("ab"), _stringValue("a"), _stringValue("b"));
-  }
-
-  void test_add_knownString_unknownString() {
-    _assertAdd(_stringValue(null), _stringValue("a"), _stringValue(null));
-  }
-
-  void test_add_unknownDouble_knownDouble() {
-    _assertAdd(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
-  }
-
-  void test_add_unknownDouble_knownInt() {
-    _assertAdd(_doubleValue(null), _doubleValue(null), _intValue(2));
-  }
-
-  void test_add_unknownInt_knownDouble() {
-    _assertAdd(_doubleValue(null), _intValue(null), _doubleValue(2.0));
-  }
-
-  void test_add_unknownInt_knownInt() {
-    _assertAdd(_intValue(null), _intValue(null), _intValue(2));
-  }
-
-  void test_add_unknownString_knownString() {
-    _assertAdd(_stringValue(null), _stringValue(null), _stringValue("b"));
-  }
-
-  void test_add_unknownString_unknownString() {
-    _assertAdd(_stringValue(null), _stringValue(null), _stringValue(null));
-  }
-
-  void test_bitAnd_knownInt_knownInt() {
-    _assertBitAnd(_intValue(2), _intValue(6), _intValue(3));
-  }
-
-  void test_bitAnd_knownInt_knownString() {
-    _assertBitAnd(null, _intValue(6), _stringValue("3"));
-  }
-
-  void test_bitAnd_knownInt_unknownInt() {
-    _assertBitAnd(_intValue(null), _intValue(6), _intValue(null));
-  }
-
-  void test_bitAnd_knownString_knownInt() {
-    _assertBitAnd(null, _stringValue("6"), _intValue(3));
-  }
-
-  void test_bitAnd_unknownInt_knownInt() {
-    _assertBitAnd(_intValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_bitAnd_unknownInt_unknownInt() {
-    _assertBitAnd(_intValue(null), _intValue(null), _intValue(null));
-  }
-
-  void test_bitNot_knownInt() {
-    _assertBitNot(_intValue(-4), _intValue(3));
-  }
-
-  void test_bitNot_knownString() {
-    _assertBitNot(null, _stringValue("6"));
-  }
-
-  void test_bitNot_unknownInt() {
-    _assertBitNot(_intValue(null), _intValue(null));
-  }
-
-  void test_bitOr_knownInt_knownInt() {
-    _assertBitOr(_intValue(7), _intValue(6), _intValue(3));
-  }
-
-  void test_bitOr_knownInt_knownString() {
-    _assertBitOr(null, _intValue(6), _stringValue("3"));
-  }
-
-  void test_bitOr_knownInt_unknownInt() {
-    _assertBitOr(_intValue(null), _intValue(6), _intValue(null));
-  }
-
-  void test_bitOr_knownString_knownInt() {
-    _assertBitOr(null, _stringValue("6"), _intValue(3));
-  }
-
-  void test_bitOr_unknownInt_knownInt() {
-    _assertBitOr(_intValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_bitOr_unknownInt_unknownInt() {
-    _assertBitOr(_intValue(null), _intValue(null), _intValue(null));
-  }
-
-  void test_bitXor_knownInt_knownInt() {
-    _assertBitXor(_intValue(5), _intValue(6), _intValue(3));
-  }
-
-  void test_bitXor_knownInt_knownString() {
-    _assertBitXor(null, _intValue(6), _stringValue("3"));
-  }
-
-  void test_bitXor_knownInt_unknownInt() {
-    _assertBitXor(_intValue(null), _intValue(6), _intValue(null));
-  }
-
-  void test_bitXor_knownString_knownInt() {
-    _assertBitXor(null, _stringValue("6"), _intValue(3));
-  }
-
-  void test_bitXor_unknownInt_knownInt() {
-    _assertBitXor(_intValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_bitXor_unknownInt_unknownInt() {
-    _assertBitXor(_intValue(null), _intValue(null), _intValue(null));
-  }
-
-  void test_concatenate_knownInt_knownString() {
-    _assertConcatenate(null, _intValue(2), _stringValue("def"));
-  }
-
-  void test_concatenate_knownString_knownInt() {
-    _assertConcatenate(null, _stringValue("abc"), _intValue(3));
-  }
-
-  void test_concatenate_knownString_knownString() {
-    _assertConcatenate(
-        _stringValue("abcdef"), _stringValue("abc"), _stringValue("def"));
-  }
-
-  void test_concatenate_knownString_unknownString() {
-    _assertConcatenate(
-        _stringValue(null), _stringValue("abc"), _stringValue(null));
-  }
-
-  void test_concatenate_unknownString_knownString() {
-    _assertConcatenate(
-        _stringValue(null), _stringValue(null), _stringValue("def"));
-  }
-
-  void test_divide_knownDouble_knownDouble() {
-    _assertDivide(_doubleValue(3.0), _doubleValue(6.0), _doubleValue(2.0));
-  }
-
-  void test_divide_knownDouble_knownInt() {
-    _assertDivide(_doubleValue(3.0), _doubleValue(6.0), _intValue(2));
-  }
-
-  void test_divide_knownDouble_unknownDouble() {
-    _assertDivide(_doubleValue(null), _doubleValue(6.0), _doubleValue(null));
-  }
-
-  void test_divide_knownDouble_unknownInt() {
-    _assertDivide(_doubleValue(null), _doubleValue(6.0), _intValue(null));
-  }
-
-  void test_divide_knownInt_knownInt() {
-    _assertDivide(_doubleValue(3.0), _intValue(6), _intValue(2));
-  }
-
-  void test_divide_knownInt_knownString() {
-    _assertDivide(null, _intValue(6), _stringValue("2"));
-  }
-
-  void test_divide_knownInt_unknownDouble() {
-    _assertDivide(_doubleValue(null), _intValue(6), _doubleValue(null));
-  }
-
-  void test_divide_knownInt_unknownInt() {
-    _assertDivide(_doubleValue(null), _intValue(6), _intValue(null));
-  }
-
-  void test_divide_knownString_knownInt() {
-    _assertDivide(null, _stringValue("6"), _intValue(2));
-  }
-
-  void test_divide_unknownDouble_knownDouble() {
-    _assertDivide(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
-  }
-
-  void test_divide_unknownDouble_knownInt() {
-    _assertDivide(_doubleValue(null), _doubleValue(null), _intValue(2));
-  }
-
-  void test_divide_unknownInt_knownDouble() {
-    _assertDivide(_doubleValue(null), _intValue(null), _doubleValue(2.0));
-  }
-
-  void test_divide_unknownInt_knownInt() {
-    _assertDivide(_doubleValue(null), _intValue(null), _intValue(2));
-  }
-
-  void test_equalEqual_bool_false() {
-    _assertEqualEqual(_boolValue(false), _boolValue(false), _boolValue(true));
-  }
-
-  void test_equalEqual_bool_true() {
-    _assertEqualEqual(_boolValue(true), _boolValue(true), _boolValue(true));
-  }
-
-  void test_equalEqual_bool_unknown() {
-    _assertEqualEqual(_boolValue(null), _boolValue(null), _boolValue(false));
-  }
-
-  void test_equalEqual_double_false() {
-    _assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
-  }
-
-  void test_equalEqual_double_true() {
-    _assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
-  }
-
-  void test_equalEqual_double_unknown() {
-    _assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
-  }
-
-  void test_equalEqual_int_false() {
-    _assertEqualEqual(_boolValue(false), _intValue(-5), _intValue(5));
-  }
-
-  void test_equalEqual_int_true() {
-    _assertEqualEqual(_boolValue(true), _intValue(5), _intValue(5));
-  }
-
-  void test_equalEqual_int_unknown() {
-    _assertEqualEqual(_boolValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_equalEqual_list_empty() {
-    _assertEqualEqual(null, _listValue(), _listValue());
-  }
-
-  void test_equalEqual_list_false() {
-    _assertEqualEqual(null, _listValue(), _listValue());
-  }
-
-  void test_equalEqual_map_empty() {
-    _assertEqualEqual(null, _mapValue(), _mapValue());
-  }
-
-  void test_equalEqual_map_false() {
-    _assertEqualEqual(null, _mapValue(), _mapValue());
-  }
-
-  void test_equalEqual_null() {
-    _assertEqualEqual(_boolValue(true), _nullValue(), _nullValue());
-  }
-
-  void test_equalEqual_string_false() {
-    _assertEqualEqual(
-        _boolValue(false), _stringValue("abc"), _stringValue("def"));
-  }
-
-  void test_equalEqual_string_true() {
-    _assertEqualEqual(
-        _boolValue(true), _stringValue("abc"), _stringValue("abc"));
-  }
-
-  void test_equalEqual_string_unknown() {
-    _assertEqualEqual(
-        _boolValue(null), _stringValue(null), _stringValue("def"));
-  }
-
-  void test_equals_list_false_differentSizes() {
-    expect(
-        _listValue([_boolValue(true)]) ==
-            _listValue([_boolValue(true), _boolValue(false)]),
-        isFalse);
-  }
-
-  void test_equals_list_false_sameSize() {
-    expect(_listValue([_boolValue(true)]) == _listValue([_boolValue(false)]),
-        isFalse);
-  }
-
-  void test_equals_list_true_empty() {
-    expect(_listValue(), _listValue());
-  }
-
-  void test_equals_list_true_nonEmpty() {
-    expect(_listValue([_boolValue(true)]), _listValue([_boolValue(true)]));
-  }
-
-  void test_equals_map_true_empty() {
-    expect(_mapValue(), _mapValue());
-  }
-
-  void test_equals_symbol_false() {
-    expect(_symbolValue("a") == _symbolValue("b"), isFalse);
-  }
-
-  void test_equals_symbol_true() {
-    expect(_symbolValue("a"), _symbolValue("a"));
-  }
-
-  void test_getValue_bool_false() {
-    expect(_boolValue(false).toBoolValue(), false);
-  }
-
-  void test_getValue_bool_true() {
-    expect(_boolValue(true).toBoolValue(), true);
-  }
-
-  void test_getValue_bool_unknown() {
-    expect(_boolValue(null).toBoolValue(), isNull);
-  }
-
-  void test_getValue_double_known() {
-    double value = 2.3;
-    expect(_doubleValue(value).toDoubleValue(), value);
-  }
-
-  void test_getValue_double_unknown() {
-    expect(_doubleValue(null).toDoubleValue(), isNull);
-  }
-
-  void test_getValue_int_known() {
-    int value = 23;
-    expect(_intValue(value).toIntValue(), value);
-  }
-
-  void test_getValue_int_unknown() {
-    expect(_intValue(null).toIntValue(), isNull);
-  }
-
-  void test_getValue_list_empty() {
-    Object result = _listValue().toListValue();
-    _assertInstanceOfObjectArray(result);
-    List<Object> array = result as List<Object>;
-    expect(array, hasLength(0));
-  }
-
-  void test_getValue_list_valid() {
-    Object result = _listValue([_intValue(23)]).toListValue();
-    _assertInstanceOfObjectArray(result);
-    List<Object> array = result as List<Object>;
-    expect(array, hasLength(1));
-  }
-
-  void test_getValue_map_empty() {
-    Object result = _mapValue().toMapValue();
-    EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
-    Map map = result as Map;
-    expect(map, hasLength(0));
-  }
-
-  void test_getValue_map_valid() {
-    Object result =
-        _mapValue([_stringValue("key"), _stringValue("value")]).toMapValue();
-    EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
-    Map map = result as Map;
-    expect(map, hasLength(1));
-  }
-
-  void test_getValue_null() {
-    expect(_nullValue().isNull, isTrue);
-  }
-
-  void test_getValue_string_known() {
-    String value = "twenty-three";
-    expect(_stringValue(value).toStringValue(), value);
-  }
-
-  void test_getValue_string_unknown() {
-    expect(_stringValue(null).toStringValue(), isNull);
-  }
-
-  void test_greaterThan_knownDouble_knownDouble_false() {
-    _assertGreaterThan(_boolValue(false), _doubleValue(1.0), _doubleValue(2.0));
-  }
-
-  void test_greaterThan_knownDouble_knownDouble_true() {
-    _assertGreaterThan(_boolValue(true), _doubleValue(2.0), _doubleValue(1.0));
-  }
-
-  void test_greaterThan_knownDouble_knownInt_false() {
-    _assertGreaterThan(_boolValue(false), _doubleValue(1.0), _intValue(2));
-  }
-
-  void test_greaterThan_knownDouble_knownInt_true() {
-    _assertGreaterThan(_boolValue(true), _doubleValue(2.0), _intValue(1));
-  }
-
-  void test_greaterThan_knownDouble_unknownDouble() {
-    _assertGreaterThan(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
-  }
-
-  void test_greaterThan_knownDouble_unknownInt() {
-    _assertGreaterThan(_boolValue(null), _doubleValue(1.0), _intValue(null));
-  }
-
-  void test_greaterThan_knownInt_knownInt_false() {
-    _assertGreaterThan(_boolValue(false), _intValue(1), _intValue(2));
-  }
-
-  void test_greaterThan_knownInt_knownInt_true() {
-    _assertGreaterThan(_boolValue(true), _intValue(2), _intValue(1));
-  }
-
-  void test_greaterThan_knownInt_knownString() {
-    _assertGreaterThan(null, _intValue(1), _stringValue("2"));
-  }
-
-  void test_greaterThan_knownInt_unknownDouble() {
-    _assertGreaterThan(_boolValue(null), _intValue(1), _doubleValue(null));
-  }
-
-  void test_greaterThan_knownInt_unknownInt() {
-    _assertGreaterThan(_boolValue(null), _intValue(1), _intValue(null));
-  }
-
-  void test_greaterThan_knownString_knownInt() {
-    _assertGreaterThan(null, _stringValue("1"), _intValue(2));
-  }
-
-  void test_greaterThan_unknownDouble_knownDouble() {
-    _assertGreaterThan(_boolValue(null), _doubleValue(null), _doubleValue(2.0));
-  }
-
-  void test_greaterThan_unknownDouble_knownInt() {
-    _assertGreaterThan(_boolValue(null), _doubleValue(null), _intValue(2));
-  }
-
-  void test_greaterThan_unknownInt_knownDouble() {
-    _assertGreaterThan(_boolValue(null), _intValue(null), _doubleValue(2.0));
-  }
-
-  void test_greaterThan_unknownInt_knownInt() {
-    _assertGreaterThan(_boolValue(null), _intValue(null), _intValue(2));
-  }
-
-  void test_greaterThanOrEqual_knownDouble_knownDouble_false() {
-    _assertGreaterThanOrEqual(
-        _boolValue(false), _doubleValue(1.0), _doubleValue(2.0));
-  }
-
-  void test_greaterThanOrEqual_knownDouble_knownDouble_true() {
-    _assertGreaterThanOrEqual(
-        _boolValue(true), _doubleValue(2.0), _doubleValue(1.0));
-  }
-
-  void test_greaterThanOrEqual_knownDouble_knownInt_false() {
-    _assertGreaterThanOrEqual(
-        _boolValue(false), _doubleValue(1.0), _intValue(2));
-  }
-
-  void test_greaterThanOrEqual_knownDouble_knownInt_true() {
-    _assertGreaterThanOrEqual(
-        _boolValue(true), _doubleValue(2.0), _intValue(1));
-  }
-
-  void test_greaterThanOrEqual_knownDouble_unknownDouble() {
-    _assertGreaterThanOrEqual(
-        _boolValue(null), _doubleValue(1.0), _doubleValue(null));
-  }
-
-  void test_greaterThanOrEqual_knownDouble_unknownInt() {
-    _assertGreaterThanOrEqual(
-        _boolValue(null), _doubleValue(1.0), _intValue(null));
-  }
-
-  void test_greaterThanOrEqual_knownInt_knownInt_false() {
-    _assertGreaterThanOrEqual(_boolValue(false), _intValue(1), _intValue(2));
-  }
-
-  void test_greaterThanOrEqual_knownInt_knownInt_true() {
-    _assertGreaterThanOrEqual(_boolValue(true), _intValue(2), _intValue(2));
-  }
-
-  void test_greaterThanOrEqual_knownInt_knownString() {
-    _assertGreaterThanOrEqual(null, _intValue(1), _stringValue("2"));
-  }
-
-  void test_greaterThanOrEqual_knownInt_unknownDouble() {
-    _assertGreaterThanOrEqual(
-        _boolValue(null), _intValue(1), _doubleValue(null));
-  }
-
-  void test_greaterThanOrEqual_knownInt_unknownInt() {
-    _assertGreaterThanOrEqual(_boolValue(null), _intValue(1), _intValue(null));
-  }
-
-  void test_greaterThanOrEqual_knownString_knownInt() {
-    _assertGreaterThanOrEqual(null, _stringValue("1"), _intValue(2));
-  }
-
-  void test_greaterThanOrEqual_unknownDouble_knownDouble() {
-    _assertGreaterThanOrEqual(
-        _boolValue(null), _doubleValue(null), _doubleValue(2.0));
-  }
-
-  void test_greaterThanOrEqual_unknownDouble_knownInt() {
-    _assertGreaterThanOrEqual(
-        _boolValue(null), _doubleValue(null), _intValue(2));
-  }
-
-  void test_greaterThanOrEqual_unknownInt_knownDouble() {
-    _assertGreaterThanOrEqual(
-        _boolValue(null), _intValue(null), _doubleValue(2.0));
-  }
-
-  void test_greaterThanOrEqual_unknownInt_knownInt() {
-    _assertGreaterThanOrEqual(_boolValue(null), _intValue(null), _intValue(2));
-  }
-
-  void test_hasKnownValue_bool_false() {
-    expect(_boolValue(false).hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_bool_true() {
-    expect(_boolValue(true).hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_bool_unknown() {
-    expect(_boolValue(null).hasKnownValue, isFalse);
-  }
-
-  void test_hasKnownValue_double_known() {
-    expect(_doubleValue(2.3).hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_double_unknown() {
-    expect(_doubleValue(null).hasKnownValue, isFalse);
-  }
-
-  void test_hasKnownValue_dynamic() {
-    expect(_dynamicValue().hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_int_known() {
-    expect(_intValue(23).hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_int_unknown() {
-    expect(_intValue(null).hasKnownValue, isFalse);
-  }
-
-  void test_hasKnownValue_list_empty() {
-    expect(_listValue().hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_list_invalidElement() {
-    expect(_listValue([_dynamicValue]).hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_list_valid() {
-    expect(_listValue([_intValue(23)]).hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_map_empty() {
-    expect(_mapValue().hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_map_invalidKey() {
-    expect(_mapValue([_dynamicValue(), _stringValue("value")]).hasKnownValue,
-        isTrue);
-  }
-
-  void test_hasKnownValue_map_invalidValue() {
-    expect(_mapValue([_stringValue("key"), _dynamicValue()]).hasKnownValue,
-        isTrue);
-  }
-
-  void test_hasKnownValue_map_valid() {
-    expect(
-        _mapValue([_stringValue("key"), _stringValue("value")]).hasKnownValue,
-        isTrue);
-  }
-
-  void test_hasKnownValue_null() {
-    expect(_nullValue().hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_num() {
-    expect(_numValue().hasKnownValue, isFalse);
-  }
-
-  void test_hasKnownValue_string_known() {
-    expect(_stringValue("twenty-three").hasKnownValue, isTrue);
-  }
-
-  void test_hasKnownValue_string_unknown() {
-    expect(_stringValue(null).hasKnownValue, isFalse);
-  }
-
-  void test_identical_bool_false() {
-    _assertIdentical(_boolValue(false), _boolValue(false), _boolValue(true));
-  }
-
-  void test_identical_bool_true() {
-    _assertIdentical(_boolValue(true), _boolValue(true), _boolValue(true));
-  }
-
-  void test_identical_bool_unknown() {
-    _assertIdentical(_boolValue(null), _boolValue(null), _boolValue(false));
-  }
-
-  void test_identical_double_false() {
-    _assertIdentical(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
-  }
-
-  void test_identical_double_true() {
-    _assertIdentical(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
-  }
-
-  void test_identical_double_unknown() {
-    _assertIdentical(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
-  }
-
-  void test_identical_int_false() {
-    _assertIdentical(_boolValue(false), _intValue(-5), _intValue(5));
-  }
-
-  void test_identical_int_true() {
-    _assertIdentical(_boolValue(true), _intValue(5), _intValue(5));
-  }
-
-  void test_identical_int_unknown() {
-    _assertIdentical(_boolValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_identical_list_empty() {
-    _assertIdentical(_boolValue(true), _listValue(), _listValue());
-  }
-
-  void test_identical_list_false() {
-    _assertIdentical(
-        _boolValue(false), _listValue(), _listValue([_intValue(3)]));
-  }
-
-  void test_identical_map_empty() {
-    _assertIdentical(_boolValue(true), _mapValue(), _mapValue());
-  }
-
-  void test_identical_map_false() {
-    _assertIdentical(_boolValue(false), _mapValue(),
-        _mapValue([_intValue(1), _intValue(2)]));
-  }
-
-  void test_identical_null() {
-    _assertIdentical(_boolValue(true), _nullValue(), _nullValue());
-  }
-
-  void test_identical_string_false() {
-    _assertIdentical(
-        _boolValue(false), _stringValue("abc"), _stringValue("def"));
-  }
-
-  void test_identical_string_true() {
-    _assertIdentical(
-        _boolValue(true), _stringValue("abc"), _stringValue("abc"));
-  }
-
-  void test_identical_string_unknown() {
-    _assertIdentical(_boolValue(null), _stringValue(null), _stringValue("def"));
-  }
-
-  void test_integerDivide_knownDouble_knownDouble() {
-    _assertIntegerDivide(_intValue(3), _doubleValue(6.0), _doubleValue(2.0));
-  }
-
-  void test_integerDivide_knownDouble_knownInt() {
-    _assertIntegerDivide(_intValue(3), _doubleValue(6.0), _intValue(2));
-  }
-
-  void test_integerDivide_knownDouble_unknownDouble() {
-    _assertIntegerDivide(
-        _intValue(null), _doubleValue(6.0), _doubleValue(null));
-  }
-
-  void test_integerDivide_knownDouble_unknownInt() {
-    _assertIntegerDivide(_intValue(null), _doubleValue(6.0), _intValue(null));
-  }
-
-  void test_integerDivide_knownInt_knownInt() {
-    _assertIntegerDivide(_intValue(3), _intValue(6), _intValue(2));
-  }
-
-  void test_integerDivide_knownInt_knownString() {
-    _assertIntegerDivide(null, _intValue(6), _stringValue("2"));
-  }
-
-  void test_integerDivide_knownInt_unknownDouble() {
-    _assertIntegerDivide(_intValue(null), _intValue(6), _doubleValue(null));
-  }
-
-  void test_integerDivide_knownInt_unknownInt() {
-    _assertIntegerDivide(_intValue(null), _intValue(6), _intValue(null));
-  }
-
-  void test_integerDivide_knownString_knownInt() {
-    _assertIntegerDivide(null, _stringValue("6"), _intValue(2));
-  }
-
-  void test_integerDivide_unknownDouble_knownDouble() {
-    _assertIntegerDivide(
-        _intValue(null), _doubleValue(null), _doubleValue(2.0));
-  }
-
-  void test_integerDivide_unknownDouble_knownInt() {
-    _assertIntegerDivide(_intValue(null), _doubleValue(null), _intValue(2));
-  }
-
-  void test_integerDivide_unknownInt_knownDouble() {
-    _assertIntegerDivide(_intValue(null), _intValue(null), _doubleValue(2.0));
-  }
-
-  void test_integerDivide_unknownInt_knownInt() {
-    _assertIntegerDivide(_intValue(null), _intValue(null), _intValue(2));
-  }
-
-  void test_isBoolNumStringOrNull_bool_false() {
-    expect(_boolValue(false).isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_bool_true() {
-    expect(_boolValue(true).isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_bool_unknown() {
-    expect(_boolValue(null).isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_double_known() {
-    expect(_doubleValue(2.3).isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_double_unknown() {
-    expect(_doubleValue(null).isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_dynamic() {
-    expect(_dynamicValue().isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_int_known() {
-    expect(_intValue(23).isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_int_unknown() {
-    expect(_intValue(null).isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_list() {
-    expect(_listValue().isBoolNumStringOrNull, isFalse);
-  }
-
-  void test_isBoolNumStringOrNull_null() {
-    expect(_nullValue().isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_num() {
-    expect(_numValue().isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_string_known() {
-    expect(_stringValue("twenty-three").isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_isBoolNumStringOrNull_string_unknown() {
-    expect(_stringValue(null).isBoolNumStringOrNull, isTrue);
-  }
-
-  void test_lessThan_knownDouble_knownDouble_false() {
-    _assertLessThan(_boolValue(false), _doubleValue(2.0), _doubleValue(1.0));
-  }
-
-  void test_lessThan_knownDouble_knownDouble_true() {
-    _assertLessThan(_boolValue(true), _doubleValue(1.0), _doubleValue(2.0));
-  }
-
-  void test_lessThan_knownDouble_knownInt_false() {
-    _assertLessThan(_boolValue(false), _doubleValue(2.0), _intValue(1));
-  }
-
-  void test_lessThan_knownDouble_knownInt_true() {
-    _assertLessThan(_boolValue(true), _doubleValue(1.0), _intValue(2));
-  }
-
-  void test_lessThan_knownDouble_unknownDouble() {
-    _assertLessThan(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
-  }
-
-  void test_lessThan_knownDouble_unknownInt() {
-    _assertLessThan(_boolValue(null), _doubleValue(1.0), _intValue(null));
-  }
-
-  void test_lessThan_knownInt_knownInt_false() {
-    _assertLessThan(_boolValue(false), _intValue(2), _intValue(1));
-  }
-
-  void test_lessThan_knownInt_knownInt_true() {
-    _assertLessThan(_boolValue(true), _intValue(1), _intValue(2));
-  }
-
-  void test_lessThan_knownInt_knownString() {
-    _assertLessThan(null, _intValue(1), _stringValue("2"));
-  }
-
-  void test_lessThan_knownInt_unknownDouble() {
-    _assertLessThan(_boolValue(null), _intValue(1), _doubleValue(null));
-  }
-
-  void test_lessThan_knownInt_unknownInt() {
-    _assertLessThan(_boolValue(null), _intValue(1), _intValue(null));
-  }
-
-  void test_lessThan_knownString_knownInt() {
-    _assertLessThan(null, _stringValue("1"), _intValue(2));
-  }
-
-  void test_lessThan_unknownDouble_knownDouble() {
-    _assertLessThan(_boolValue(null), _doubleValue(null), _doubleValue(2.0));
-  }
-
-  void test_lessThan_unknownDouble_knownInt() {
-    _assertLessThan(_boolValue(null), _doubleValue(null), _intValue(2));
-  }
-
-  void test_lessThan_unknownInt_knownDouble() {
-    _assertLessThan(_boolValue(null), _intValue(null), _doubleValue(2.0));
-  }
-
-  void test_lessThan_unknownInt_knownInt() {
-    _assertLessThan(_boolValue(null), _intValue(null), _intValue(2));
-  }
-
-  void test_lessThanOrEqual_knownDouble_knownDouble_false() {
-    _assertLessThanOrEqual(
-        _boolValue(false), _doubleValue(2.0), _doubleValue(1.0));
-  }
-
-  void test_lessThanOrEqual_knownDouble_knownDouble_true() {
-    _assertLessThanOrEqual(
-        _boolValue(true), _doubleValue(1.0), _doubleValue(2.0));
-  }
-
-  void test_lessThanOrEqual_knownDouble_knownInt_false() {
-    _assertLessThanOrEqual(_boolValue(false), _doubleValue(2.0), _intValue(1));
-  }
-
-  void test_lessThanOrEqual_knownDouble_knownInt_true() {
-    _assertLessThanOrEqual(_boolValue(true), _doubleValue(1.0), _intValue(2));
-  }
-
-  void test_lessThanOrEqual_knownDouble_unknownDouble() {
-    _assertLessThanOrEqual(
-        _boolValue(null), _doubleValue(1.0), _doubleValue(null));
-  }
-
-  void test_lessThanOrEqual_knownDouble_unknownInt() {
-    _assertLessThanOrEqual(
-        _boolValue(null), _doubleValue(1.0), _intValue(null));
-  }
-
-  void test_lessThanOrEqual_knownInt_knownInt_false() {
-    _assertLessThanOrEqual(_boolValue(false), _intValue(2), _intValue(1));
-  }
-
-  void test_lessThanOrEqual_knownInt_knownInt_true() {
-    _assertLessThanOrEqual(_boolValue(true), _intValue(1), _intValue(2));
-  }
-
-  void test_lessThanOrEqual_knownInt_knownString() {
-    _assertLessThanOrEqual(null, _intValue(1), _stringValue("2"));
-  }
-
-  void test_lessThanOrEqual_knownInt_unknownDouble() {
-    _assertLessThanOrEqual(_boolValue(null), _intValue(1), _doubleValue(null));
-  }
-
-  void test_lessThanOrEqual_knownInt_unknownInt() {
-    _assertLessThanOrEqual(_boolValue(null), _intValue(1), _intValue(null));
-  }
-
-  void test_lessThanOrEqual_knownString_knownInt() {
-    _assertLessThanOrEqual(null, _stringValue("1"), _intValue(2));
-  }
-
-  void test_lessThanOrEqual_unknownDouble_knownDouble() {
-    _assertLessThanOrEqual(
-        _boolValue(null), _doubleValue(null), _doubleValue(2.0));
-  }
-
-  void test_lessThanOrEqual_unknownDouble_knownInt() {
-    _assertLessThanOrEqual(_boolValue(null), _doubleValue(null), _intValue(2));
-  }
-
-  void test_lessThanOrEqual_unknownInt_knownDouble() {
-    _assertLessThanOrEqual(
-        _boolValue(null), _intValue(null), _doubleValue(2.0));
-  }
-
-  void test_lessThanOrEqual_unknownInt_knownInt() {
-    _assertLessThanOrEqual(_boolValue(null), _intValue(null), _intValue(2));
-  }
-
-  void test_logicalAnd_false_false() {
-    _assertLogicalAnd(_boolValue(false), _boolValue(false), _boolValue(false));
-  }
-
-  void test_logicalAnd_false_null() {
-    try {
-      _assertLogicalAnd(_boolValue(false), _boolValue(false), _nullValue());
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalAnd_false_string() {
-    try {
-      _assertLogicalAnd(
-          _boolValue(false), _boolValue(false), _stringValue("false"));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalAnd_false_true() {
-    _assertLogicalAnd(_boolValue(false), _boolValue(false), _boolValue(true));
-  }
-
-  void test_logicalAnd_null_false() {
-    try {
-      _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(false));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalAnd_null_true() {
-    try {
-      _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(true));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalAnd_string_false() {
-    try {
-      _assertLogicalAnd(
-          _boolValue(false), _stringValue("true"), _boolValue(false));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalAnd_string_true() {
-    try {
-      _assertLogicalAnd(
-          _boolValue(false), _stringValue("false"), _boolValue(true));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalAnd_true_false() {
-    _assertLogicalAnd(_boolValue(false), _boolValue(true), _boolValue(false));
-  }
-
-  void test_logicalAnd_true_null() {
-    _assertLogicalAnd(null, _boolValue(true), _nullValue());
-  }
-
-  void test_logicalAnd_true_string() {
-    try {
-      _assertLogicalAnd(
-          _boolValue(false), _boolValue(true), _stringValue("true"));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalAnd_true_true() {
-    _assertLogicalAnd(_boolValue(true), _boolValue(true), _boolValue(true));
-  }
-
-  void test_logicalNot_false() {
-    _assertLogicalNot(_boolValue(true), _boolValue(false));
-  }
-
-  void test_logicalNot_null() {
-    _assertLogicalNot(null, _nullValue());
-  }
-
-  void test_logicalNot_string() {
-    try {
-      _assertLogicalNot(_boolValue(true), _stringValue(null));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalNot_true() {
-    _assertLogicalNot(_boolValue(false), _boolValue(true));
-  }
-
-  void test_logicalNot_unknown() {
-    _assertLogicalNot(_boolValue(null), _boolValue(null));
-  }
-
-  void test_logicalOr_false_false() {
-    _assertLogicalOr(_boolValue(false), _boolValue(false), _boolValue(false));
-  }
-
-  void test_logicalOr_false_null() {
-    _assertLogicalOr(null, _boolValue(false), _nullValue());
-  }
-
-  void test_logicalOr_false_string() {
-    try {
-      _assertLogicalOr(
-          _boolValue(false), _boolValue(false), _stringValue("false"));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalOr_false_true() {
-    _assertLogicalOr(_boolValue(true), _boolValue(false), _boolValue(true));
-  }
-
-  void test_logicalOr_null_false() {
-    try {
-      _assertLogicalOr(_boolValue(false), _nullValue(), _boolValue(false));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalOr_null_true() {
-    try {
-      _assertLogicalOr(_boolValue(true), _nullValue(), _boolValue(true));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalOr_string_false() {
-    try {
-      _assertLogicalOr(
-          _boolValue(false), _stringValue("true"), _boolValue(false));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalOr_string_true() {
-    try {
-      _assertLogicalOr(
-          _boolValue(true), _stringValue("false"), _boolValue(true));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalOr_true_false() {
-    _assertLogicalOr(_boolValue(true), _boolValue(true), _boolValue(false));
-  }
-
-  void test_logicalOr_true_null() {
-    try {
-      _assertLogicalOr(_boolValue(true), _boolValue(true), _nullValue());
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalOr_true_string() {
-    try {
-      _assertLogicalOr(
-          _boolValue(true), _boolValue(true), _stringValue("true"));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_logicalOr_true_true() {
-    _assertLogicalOr(_boolValue(true), _boolValue(true), _boolValue(true));
-  }
-
-  void test_minus_knownDouble_knownDouble() {
-    _assertMinus(_doubleValue(1.0), _doubleValue(4.0), _doubleValue(3.0));
-  }
-
-  void test_minus_knownDouble_knownInt() {
-    _assertMinus(_doubleValue(1.0), _doubleValue(4.0), _intValue(3));
-  }
-
-  void test_minus_knownDouble_unknownDouble() {
-    _assertMinus(_doubleValue(null), _doubleValue(4.0), _doubleValue(null));
-  }
-
-  void test_minus_knownDouble_unknownInt() {
-    _assertMinus(_doubleValue(null), _doubleValue(4.0), _intValue(null));
-  }
-
-  void test_minus_knownInt_knownInt() {
-    _assertMinus(_intValue(1), _intValue(4), _intValue(3));
-  }
-
-  void test_minus_knownInt_knownString() {
-    _assertMinus(null, _intValue(4), _stringValue("3"));
-  }
-
-  void test_minus_knownInt_unknownDouble() {
-    _assertMinus(_doubleValue(null), _intValue(4), _doubleValue(null));
-  }
-
-  void test_minus_knownInt_unknownInt() {
-    _assertMinus(_intValue(null), _intValue(4), _intValue(null));
-  }
-
-  void test_minus_knownString_knownInt() {
-    _assertMinus(null, _stringValue("4"), _intValue(3));
-  }
-
-  void test_minus_unknownDouble_knownDouble() {
-    _assertMinus(_doubleValue(null), _doubleValue(null), _doubleValue(3.0));
-  }
-
-  void test_minus_unknownDouble_knownInt() {
-    _assertMinus(_doubleValue(null), _doubleValue(null), _intValue(3));
-  }
-
-  void test_minus_unknownInt_knownDouble() {
-    _assertMinus(_doubleValue(null), _intValue(null), _doubleValue(3.0));
-  }
-
-  void test_minus_unknownInt_knownInt() {
-    _assertMinus(_intValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_negated_double_known() {
-    _assertNegated(_doubleValue(2.0), _doubleValue(-2.0));
-  }
-
-  void test_negated_double_unknown() {
-    _assertNegated(_doubleValue(null), _doubleValue(null));
-  }
-
-  void test_negated_int_known() {
-    _assertNegated(_intValue(-3), _intValue(3));
-  }
-
-  void test_negated_int_unknown() {
-    _assertNegated(_intValue(null), _intValue(null));
-  }
-
-  void test_negated_string() {
-    _assertNegated(null, _stringValue(null));
-  }
-
-  void test_notEqual_bool_false() {
-    _assertNotEqual(_boolValue(false), _boolValue(true), _boolValue(true));
-  }
-
-  void test_notEqual_bool_true() {
-    _assertNotEqual(_boolValue(true), _boolValue(false), _boolValue(true));
-  }
-
-  void test_notEqual_bool_unknown() {
-    _assertNotEqual(_boolValue(null), _boolValue(null), _boolValue(false));
-  }
-
-  void test_notEqual_double_false() {
-    _assertNotEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(2.0));
-  }
-
-  void test_notEqual_double_true() {
-    _assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0));
-  }
-
-  void test_notEqual_double_unknown() {
-    _assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
-  }
-
-  void test_notEqual_int_false() {
-    _assertNotEqual(_boolValue(false), _intValue(5), _intValue(5));
-  }
-
-  void test_notEqual_int_true() {
-    _assertNotEqual(_boolValue(true), _intValue(-5), _intValue(5));
-  }
-
-  void test_notEqual_int_unknown() {
-    _assertNotEqual(_boolValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_notEqual_null() {
-    _assertNotEqual(_boolValue(false), _nullValue(), _nullValue());
-  }
-
-  void test_notEqual_string_false() {
-    _assertNotEqual(
-        _boolValue(false), _stringValue("abc"), _stringValue("abc"));
-  }
-
-  void test_notEqual_string_true() {
-    _assertNotEqual(_boolValue(true), _stringValue("abc"), _stringValue("def"));
-  }
-
-  void test_notEqual_string_unknown() {
-    _assertNotEqual(_boolValue(null), _stringValue(null), _stringValue("def"));
-  }
-
-  void test_performToString_bool_false() {
-    _assertPerformToString(_stringValue("false"), _boolValue(false));
-  }
-
-  void test_performToString_bool_true() {
-    _assertPerformToString(_stringValue("true"), _boolValue(true));
-  }
-
-  void test_performToString_bool_unknown() {
-    _assertPerformToString(_stringValue(null), _boolValue(null));
-  }
-
-  void test_performToString_double_known() {
-    _assertPerformToString(_stringValue("2.0"), _doubleValue(2.0));
-  }
-
-  void test_performToString_double_unknown() {
-    _assertPerformToString(_stringValue(null), _doubleValue(null));
-  }
-
-  void test_performToString_int_known() {
-    _assertPerformToString(_stringValue("5"), _intValue(5));
-  }
-
-  void test_performToString_int_unknown() {
-    _assertPerformToString(_stringValue(null), _intValue(null));
-  }
-
-  void test_performToString_null() {
-    _assertPerformToString(_stringValue("null"), _nullValue());
-  }
-
-  void test_performToString_string_known() {
-    _assertPerformToString(_stringValue("abc"), _stringValue("abc"));
-  }
-
-  void test_performToString_string_unknown() {
-    _assertPerformToString(_stringValue(null), _stringValue(null));
-  }
-
-  void test_remainder_knownDouble_knownDouble() {
-    _assertRemainder(_doubleValue(1.0), _doubleValue(7.0), _doubleValue(2.0));
-  }
-
-  void test_remainder_knownDouble_knownInt() {
-    _assertRemainder(_doubleValue(1.0), _doubleValue(7.0), _intValue(2));
-  }
-
-  void test_remainder_knownDouble_unknownDouble() {
-    _assertRemainder(_doubleValue(null), _doubleValue(7.0), _doubleValue(null));
-  }
-
-  void test_remainder_knownDouble_unknownInt() {
-    _assertRemainder(_doubleValue(null), _doubleValue(6.0), _intValue(null));
-  }
-
-  void test_remainder_knownInt_knownInt() {
-    _assertRemainder(_intValue(1), _intValue(7), _intValue(2));
-  }
-
-  void test_remainder_knownInt_knownString() {
-    _assertRemainder(null, _intValue(7), _stringValue("2"));
-  }
-
-  void test_remainder_knownInt_unknownDouble() {
-    _assertRemainder(_doubleValue(null), _intValue(7), _doubleValue(null));
-  }
-
-  void test_remainder_knownInt_unknownInt() {
-    _assertRemainder(_intValue(null), _intValue(7), _intValue(null));
-  }
-
-  void test_remainder_knownString_knownInt() {
-    _assertRemainder(null, _stringValue("7"), _intValue(2));
-  }
-
-  void test_remainder_unknownDouble_knownDouble() {
-    _assertRemainder(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
-  }
-
-  void test_remainder_unknownDouble_knownInt() {
-    _assertRemainder(_doubleValue(null), _doubleValue(null), _intValue(2));
-  }
-
-  void test_remainder_unknownInt_knownDouble() {
-    _assertRemainder(_doubleValue(null), _intValue(null), _doubleValue(2.0));
-  }
-
-  void test_remainder_unknownInt_knownInt() {
-    _assertRemainder(_intValue(null), _intValue(null), _intValue(2));
-  }
-
-  void test_shiftLeft_knownInt_knownInt() {
-    _assertShiftLeft(_intValue(48), _intValue(6), _intValue(3));
-  }
-
-  void test_shiftLeft_knownInt_knownString() {
-    _assertShiftLeft(null, _intValue(6), _stringValue(null));
-  }
-
-  void test_shiftLeft_knownInt_tooLarge() {
-    _assertShiftLeft(
-        _intValue(null),
-        _intValue(6),
-        new DartObjectImpl(
-            _typeProvider.intType, new IntState(LONG_MAX_VALUE)));
-  }
-
-  void test_shiftLeft_knownInt_unknownInt() {
-    _assertShiftLeft(_intValue(null), _intValue(6), _intValue(null));
-  }
-
-  void test_shiftLeft_knownString_knownInt() {
-    _assertShiftLeft(null, _stringValue(null), _intValue(3));
-  }
-
-  void test_shiftLeft_unknownInt_knownInt() {
-    _assertShiftLeft(_intValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_shiftLeft_unknownInt_unknownInt() {
-    _assertShiftLeft(_intValue(null), _intValue(null), _intValue(null));
-  }
-
-  void test_shiftRight_knownInt_knownInt() {
-    _assertShiftRight(_intValue(6), _intValue(48), _intValue(3));
-  }
-
-  void test_shiftRight_knownInt_knownString() {
-    _assertShiftRight(null, _intValue(48), _stringValue(null));
-  }
-
-  void test_shiftRight_knownInt_tooLarge() {
-    _assertShiftRight(
-        _intValue(null),
-        _intValue(48),
-        new DartObjectImpl(
-            _typeProvider.intType, new IntState(LONG_MAX_VALUE)));
-  }
-
-  void test_shiftRight_knownInt_unknownInt() {
-    _assertShiftRight(_intValue(null), _intValue(48), _intValue(null));
-  }
-
-  void test_shiftRight_knownString_knownInt() {
-    _assertShiftRight(null, _stringValue(null), _intValue(3));
-  }
-
-  void test_shiftRight_unknownInt_knownInt() {
-    _assertShiftRight(_intValue(null), _intValue(null), _intValue(3));
-  }
-
-  void test_shiftRight_unknownInt_unknownInt() {
-    _assertShiftRight(_intValue(null), _intValue(null), _intValue(null));
-  }
-
-  void test_stringLength_int() {
-    try {
-      _assertStringLength(_intValue(null), _intValue(0));
-      fail("Expected EvaluationException");
-    } on EvaluationException {}
-  }
-
-  void test_stringLength_knownString() {
-    _assertStringLength(_intValue(3), _stringValue("abc"));
-  }
-
-  void test_stringLength_unknownString() {
-    _assertStringLength(_intValue(null), _stringValue(null));
-  }
-
-  void test_times_knownDouble_knownDouble() {
-    _assertTimes(_doubleValue(6.0), _doubleValue(2.0), _doubleValue(3.0));
-  }
-
-  void test_times_knownDouble_knownInt() {
-    _assertTimes(_doubleValue(6.0), _doubleValue(2.0), _intValue(3));
-  }
-
-  void test_times_knownDouble_unknownDouble() {
-    _assertTimes(_doubleValue(null), _doubleValue(2.0), _doubleValue(null));
-  }
-
-  void test_times_knownDouble_unknownInt() {
-    _assertTimes(_doubleValue(null), _doubleValue(2.0), _intValue(null));
-  }
-
-  void test_times_knownInt_knownInt() {
-    _assertTimes(_intValue(6), _intValue(2), _intValue(3));
-  }
-
-  void test_times_knownInt_knownString() {
-    _assertTimes(null, _intValue(2), _stringValue("3"));
-  }
-
-  void test_times_knownInt_unknownDouble() {
-    _assertTimes(_doubleValue(null), _intValue(2), _doubleValue(null));
-  }
-
-  void test_times_knownInt_unknownInt() {
-    _assertTimes(_intValue(null), _intValue(2), _intValue(null));
-  }
-
-  void test_times_knownString_knownInt() {
-    _assertTimes(null, _stringValue("2"), _intValue(3));
-  }
-
-  void test_times_unknownDouble_knownDouble() {
-    _assertTimes(_doubleValue(null), _doubleValue(null), _doubleValue(3.0));
-  }
-
-  void test_times_unknownDouble_knownInt() {
-    _assertTimes(_doubleValue(null), _doubleValue(null), _intValue(3));
-  }
-
-  void test_times_unknownInt_knownDouble() {
-    _assertTimes(_doubleValue(null), _intValue(null), _doubleValue(3.0));
-  }
-
-  void test_times_unknownInt_knownInt() {
-    _assertTimes(_intValue(null), _intValue(null), _intValue(3));
-  }
-
-  /**
-   * Assert that the result of adding the left and right operands is the expected value, or that the
-   * operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertAdd(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.add(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.add(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of bit-anding the left and right operands is the expected value, or that
-   * the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertBitAnd(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.bitAnd(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.bitAnd(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the bit-not of the operand is the expected value, or that the operation throws an
-   * exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param operand the operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertBitNot(DartObjectImpl expected, DartObjectImpl operand) {
-    if (expected == null) {
-      try {
-        operand.bitNot(_typeProvider);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = operand.bitNot(_typeProvider);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of bit-oring the left and right operands is the expected value, or that
-   * the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertBitOr(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.bitOr(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.bitOr(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of bit-xoring the left and right operands is the expected value, or that
-   * the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertBitXor(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.bitXor(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.bitXor(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of concatenating the left and right operands is the expected value, or
-   * that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertConcatenate(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.concatenate(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.concatenate(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of dividing the left and right operands is the expected value, or that
-   * the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertDivide(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.divide(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.divide(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of comparing the left and right operands for equality is the expected
-   * value, or that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertEqualEqual(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.equalEqual(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.equalEqual(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of comparing the left and right operands is the expected value, or that
-   * the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertGreaterThan(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.greaterThan(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.greaterThan(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of comparing the left and right operands is the expected value, or that
-   * the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertGreaterThanOrEqual(DartObjectImpl expected,
-      DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of comparing the left and right operands using
-   * identical() is the expected value.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   */
-  void _assertIdentical(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    DartObjectImpl result =
-        leftOperand.isIdentical(_typeProvider, rightOperand);
-    expect(result, isNotNull);
-    expect(result, expected);
-  }
-
-  void _assertInstanceOfObjectArray(Object result) {
-    // TODO(scheglov) implement
-  }
-
-  /**
-   * Assert that the result of dividing the left and right operands as integers is the expected
-   * value, or that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertIntegerDivide(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.integerDivide(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.integerDivide(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of comparing the left and right operands is the expected value, or that
-   * the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertLessThan(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.lessThan(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.lessThan(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of comparing the left and right operands is the expected value, or that
-   * the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertLessThanOrEqual(DartObjectImpl expected,
-      DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of logical-anding the left and right operands is the expected value, or
-   * that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertLogicalAnd(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.logicalAnd(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.logicalAnd(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the logical-not of the operand is the expected value, or that the operation throws
-   * an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param operand the operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertLogicalNot(DartObjectImpl expected, DartObjectImpl operand) {
-    if (expected == null) {
-      try {
-        operand.logicalNot(_typeProvider);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = operand.logicalNot(_typeProvider);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of logical-oring the left and right operands is the expected value, or
-   * that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertLogicalOr(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.logicalOr(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.logicalOr(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of subtracting the left and right operands is the expected value, or
-   * that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertMinus(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.minus(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.minus(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the negation of the operand is the expected value, or that the operation throws an
-   * exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param operand the operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertNegated(DartObjectImpl expected, DartObjectImpl operand) {
-    if (expected == null) {
-      try {
-        operand.negated(_typeProvider);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = operand.negated(_typeProvider);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of comparing the left and right operands for inequality is the expected
-   * value, or that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertNotEqual(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.notEqual(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.notEqual(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that converting the operand to a string is the expected value, or that the operation
-   * throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param operand the operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertPerformToString(DartObjectImpl expected, DartObjectImpl operand) {
-    if (expected == null) {
-      try {
-        operand.performToString(_typeProvider);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = operand.performToString(_typeProvider);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of taking the remainder of the left and right operands is the expected
-   * value, or that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertRemainder(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.remainder(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.remainder(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of multiplying the left and right operands is the expected value, or
-   * that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertShiftLeft(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.shiftLeft(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.shiftLeft(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of multiplying the left and right operands is the expected value, or
-   * that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertShiftRight(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.shiftRight(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result =
-          leftOperand.shiftRight(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the length of the operand is the expected value, or that the operation throws an
-   * exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param operand the operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertStringLength(DartObjectImpl expected, DartObjectImpl operand) {
-    if (expected == null) {
-      try {
-        operand.stringLength(_typeProvider);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = operand.stringLength(_typeProvider);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  /**
-   * Assert that the result of multiplying the left and right operands is the expected value, or
-   * that the operation throws an exception if the expected value is `null`.
-   *
-   * @param expected the expected result of the operation
-   * @param leftOperand the left operand to the operation
-   * @param rightOperand the left operand to the operation
-   * @throws EvaluationException if the result is an exception when it should not be
-   */
-  void _assertTimes(DartObjectImpl expected, DartObjectImpl leftOperand,
-      DartObjectImpl rightOperand) {
-    if (expected == null) {
-      try {
-        leftOperand.times(_typeProvider, rightOperand);
-        fail("Expected an EvaluationException");
-      } on EvaluationException {}
-    } else {
-      DartObjectImpl result = leftOperand.times(_typeProvider, rightOperand);
-      expect(result, isNotNull);
-      expect(result, expected);
-    }
-  }
-
-  DartObjectImpl _boolValue(bool value) {
-    if (value == null) {
-      return new DartObjectImpl(
-          _typeProvider.boolType, BoolState.UNKNOWN_VALUE);
-    } else if (identical(value, false)) {
-      return new DartObjectImpl(_typeProvider.boolType, BoolState.FALSE_STATE);
-    } else if (identical(value, true)) {
-      return new DartObjectImpl(_typeProvider.boolType, BoolState.TRUE_STATE);
-    }
-    fail("Invalid boolean value used in test");
-    return null;
-  }
-
-  DartObjectImpl _doubleValue(double value) {
-    if (value == null) {
-      return new DartObjectImpl(
-          _typeProvider.doubleType, DoubleState.UNKNOWN_VALUE);
-    } else {
-      return new DartObjectImpl(
-          _typeProvider.doubleType, new DoubleState(value));
-    }
-  }
-
-  DartObjectImpl _dynamicValue() {
-    return new DartObjectImpl(
-        _typeProvider.nullType, DynamicState.DYNAMIC_STATE);
-  }
-
-  DartObjectImpl _intValue(int value) {
-    if (value == null) {
-      return new DartObjectImpl(_typeProvider.intType, IntState.UNKNOWN_VALUE);
-    } else {
-      return new DartObjectImpl(_typeProvider.intType, new IntState(value));
-    }
-  }
-
-  DartObjectImpl _listValue(
-      [List<DartObjectImpl> elements = DartObjectImpl.EMPTY_LIST]) {
-    return new DartObjectImpl(_typeProvider.listType, new ListState(elements));
-  }
-
-  DartObjectImpl _mapValue(
-      [List<DartObjectImpl> keyElementPairs = DartObjectImpl.EMPTY_LIST]) {
-    Map<DartObjectImpl, DartObjectImpl> map =
-        new Map<DartObjectImpl, DartObjectImpl>();
-    int count = keyElementPairs.length;
-    for (int i = 0; i < count;) {
-      map[keyElementPairs[i++]] = keyElementPairs[i++];
-    }
-    return new DartObjectImpl(_typeProvider.mapType, new MapState(map));
-  }
-
-  DartObjectImpl _nullValue() {
-    return new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
-  }
-
-  DartObjectImpl _numValue() {
-    return new DartObjectImpl(_typeProvider.nullType, NumState.UNKNOWN_VALUE);
-  }
-
-  DartObjectImpl _stringValue(String value) {
-    if (value == null) {
-      return new DartObjectImpl(
-          _typeProvider.stringType, StringState.UNKNOWN_VALUE);
-    } else {
-      return new DartObjectImpl(
-          _typeProvider.stringType, new StringState(value));
-    }
-  }
-
-  DartObjectImpl _symbolValue(String value) {
-    return new DartObjectImpl(_typeProvider.symbolType, new SymbolState(value));
-  }
-}
-
-@reflectiveTest
 class DartUriResolverTest {
   void test_creation() {
     JavaFile sdkDirectory = DirectoryBasedDartSdk.defaultSdkDirectory;
@@ -2273,102 +147,6 @@
 }
 
 @reflectiveTest
-class DeclaredVariablesTest extends EngineTestCase {
-  void test_getBool_false() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    DeclaredVariables variables = new DeclaredVariables();
-    variables.define(variableName, "false");
-    DartObject object = variables.getBool(typeProvider, variableName);
-    expect(object, isNotNull);
-    expect(object.toBoolValue(), false);
-  }
-
-  void test_getBool_invalid() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    DeclaredVariables variables = new DeclaredVariables();
-    variables.define(variableName, "not true");
-    _assertNullDartObject(
-        typeProvider, variables.getBool(typeProvider, variableName));
-  }
-
-  void test_getBool_true() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    DeclaredVariables variables = new DeclaredVariables();
-    variables.define(variableName, "true");
-    DartObject object = variables.getBool(typeProvider, variableName);
-    expect(object, isNotNull);
-    expect(object.toBoolValue(), true);
-  }
-
-  void test_getBool_undefined() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    DeclaredVariables variables = new DeclaredVariables();
-    _assertUnknownDartObject(
-        typeProvider.boolType, variables.getBool(typeProvider, variableName));
-  }
-
-  void test_getInt_invalid() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    DeclaredVariables variables = new DeclaredVariables();
-    variables.define(variableName, "four score and seven years");
-    _assertNullDartObject(
-        typeProvider, variables.getInt(typeProvider, variableName));
-  }
-
-  void test_getInt_undefined() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    DeclaredVariables variables = new DeclaredVariables();
-    _assertUnknownDartObject(
-        typeProvider.intType, variables.getInt(typeProvider, variableName));
-  }
-
-  void test_getInt_valid() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    DeclaredVariables variables = new DeclaredVariables();
-    variables.define(variableName, "23");
-    DartObject object = variables.getInt(typeProvider, variableName);
-    expect(object, isNotNull);
-    expect(object.toIntValue(), 23);
-  }
-
-  void test_getString_defined() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    String value = "value";
-    DeclaredVariables variables = new DeclaredVariables();
-    variables.define(variableName, value);
-    DartObject object = variables.getString(typeProvider, variableName);
-    expect(object, isNotNull);
-    expect(object.toStringValue(), value);
-  }
-
-  void test_getString_undefined() {
-    TestTypeProvider typeProvider = new TestTypeProvider();
-    String variableName = "var";
-    DeclaredVariables variables = new DeclaredVariables();
-    _assertUnknownDartObject(typeProvider.stringType,
-        variables.getString(typeProvider, variableName));
-  }
-
-  void _assertNullDartObject(TestTypeProvider typeProvider, DartObject result) {
-    expect(result.type, typeProvider.nullType);
-  }
-
-  void _assertUnknownDartObject(
-      ParameterizedType expectedType, DartObject result) {
-    expect((result as DartObjectImpl).isUnknown, isTrue);
-    expect(result.type, expectedType);
-  }
-}
-
-@reflectiveTest
 class DirectoryBasedDartSdkTest {
   void fail_getDocFileFor() {
     DirectoryBasedDartSdk sdk = _createDartSdk();
@@ -3078,7 +856,7 @@
     expect(parameter.parameters, hasLength(0));
   }
 
-  void test_visitFieldFormalParameter_funtionTyped() {
+  void test_visitFieldFormalParameter_functionTyped() {
     ElementHolder holder = new ElementHolder();
     ElementBuilder builder = new ElementBuilder(holder);
     String parameterName = "p";
@@ -4436,7 +2214,7 @@
         (obj) => obj is FieldElement, FieldElement, element);
   }
 
-  void test_locate_Identifier_propertAccess() {
+  void test_locate_Identifier_propertyAccess() {
     AstNode id = _findNodeIn(
         "length",
         r'''
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 15ef8ad..9c4f87c 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -3547,24 +3547,6 @@
     verify([source]);
   }
 
-  void test_missingEnumConstantInSwitch() {
-    Source source = addSource(r'''
-enum E { ONE, TWO, THREE, FOUR }
-bool odd(E e) {
-  switch (e) {
-    case E.ONE:
-    case E.THREE: return true;
-  }
-  return false;
-}''');
-    computeLibrarySourceErrors(source);
-    assertErrors(source, [
-      CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
-      CompileTimeErrorCode.MISSING_ENUM_CONSTANT_IN_SWITCH
-    ]);
-    verify([source]);
-  }
-
   void test_mixinDeclaresConstructor_classDeclaration() {
     Source source = addSource(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/constant_test.dart b/pkg/analyzer/test/generated/constant_test.dart
index 04592ff..f82c31e 100644
--- a/pkg/analyzer/test/generated/constant_test.dart
+++ b/pkg/analyzer/test/generated/constant_test.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
+import 'package:analyzer/src/generated/java_core.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/scanner.dart';
 import 'package:analyzer/src/generated/source.dart';
@@ -35,6 +36,8 @@
   runReflectiveTests(ConstantFinderTest);
   runReflectiveTests(ConstantValueComputerTest);
   runReflectiveTests(ConstantVisitorTest);
+  runReflectiveTests(DartObjectImplTest);
+  runReflectiveTests(DeclaredVariablesTest);
   runReflectiveTests(ReferenceFinderTest);
 }
 
@@ -281,6 +284,8 @@
     EvaluationResult result =
         _getExpressionValue("const {'a' : 'm', 'b' : 'n', 'c' : 'o'}");
     expect(result.isValid, isTrue);
+    Map<DartObject, DartObject> map = result.value.toMapValue();
+    expect(map.keys.map((k) => k.toStringValue()), ['a', 'b', 'c']);
   }
 
   void test_literal_null() {
@@ -831,7 +836,7 @@
     _evaluateAnnotation(compilationUnit, "C", "f");
   }
 
-  void test_annotation_toplevelVariable() {
+  void test_annotation_topLevelVariable() {
     CompilationUnit compilationUnit = resolveSource(r'''
 const int i = 5;
 class C {
@@ -844,8 +849,8 @@
     expect(_assertValidInt(result), 5);
   }
 
-  void test_annotation_toplevelVariable_args() {
-    // Applying arguments to an annotation that is a toplevel variable is
+  void test_annotation_topLevelVariable_args() {
+    // Applying arguments to an annotation that is a top-level variable is
     // illegal, but shouldn't crash analysis.
     CompilationUnit compilationUnit = resolveSource(r'''
 const int i = 5;
@@ -1374,7 +1379,7 @@
     _assertIntField(fields, "k", 7);
   }
 
-  void test_instanceCreationExpression_computedField_usesToplevelConst() {
+  void test_instanceCreationExpression_computedField_usesTopLevelConst() {
     CompilationUnit compilationUnit = resolveSource(r'''
 const foo = const A(3);
 const bar = 4;
@@ -1582,7 +1587,7 @@
     _assertValidUnknown(_evaluateTopLevelVariable(compilationUnit, "foo"));
   }
 
-  void test_instanceCreationExpression_redirect_extern() {
+  void test_instanceCreationExpression_redirect_external() {
     CompilationUnit compilationUnit = resolveSource(r'''
 const foo = const A();
 class A {
@@ -2198,6 +2203,2226 @@
 }
 
 @reflectiveTest
+class DartObjectImplTest extends EngineTestCase {
+  TypeProvider _typeProvider = new TestTypeProvider();
+
+  void test_add_knownDouble_knownDouble() {
+    _assertAdd(_doubleValue(3.0), _doubleValue(1.0), _doubleValue(2.0));
+  }
+
+  void test_add_knownDouble_knownInt() {
+    _assertAdd(_doubleValue(3.0), _doubleValue(1.0), _intValue(2));
+  }
+
+  void test_add_knownDouble_unknownDouble() {
+    _assertAdd(_doubleValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_add_knownDouble_unknownInt() {
+    _assertAdd(_doubleValue(null), _doubleValue(1.0), _intValue(null));
+  }
+
+  void test_add_knownInt_knownInt() {
+    _assertAdd(_intValue(3), _intValue(1), _intValue(2));
+  }
+
+  void test_add_knownInt_knownString() {
+    _assertAdd(null, _intValue(1), _stringValue("2"));
+  }
+
+  void test_add_knownInt_unknownDouble() {
+    _assertAdd(_doubleValue(null), _intValue(1), _doubleValue(null));
+  }
+
+  void test_add_knownInt_unknownInt() {
+    _assertAdd(_intValue(null), _intValue(1), _intValue(null));
+  }
+
+  void test_add_knownString_knownInt() {
+    _assertAdd(null, _stringValue("1"), _intValue(2));
+  }
+
+  void test_add_knownString_knownString() {
+    _assertAdd(_stringValue("ab"), _stringValue("a"), _stringValue("b"));
+  }
+
+  void test_add_knownString_unknownString() {
+    _assertAdd(_stringValue(null), _stringValue("a"), _stringValue(null));
+  }
+
+  void test_add_unknownDouble_knownDouble() {
+    _assertAdd(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
+  }
+
+  void test_add_unknownDouble_knownInt() {
+    _assertAdd(_doubleValue(null), _doubleValue(null), _intValue(2));
+  }
+
+  void test_add_unknownInt_knownDouble() {
+    _assertAdd(_doubleValue(null), _intValue(null), _doubleValue(2.0));
+  }
+
+  void test_add_unknownInt_knownInt() {
+    _assertAdd(_intValue(null), _intValue(null), _intValue(2));
+  }
+
+  void test_add_unknownString_knownString() {
+    _assertAdd(_stringValue(null), _stringValue(null), _stringValue("b"));
+  }
+
+  void test_add_unknownString_unknownString() {
+    _assertAdd(_stringValue(null), _stringValue(null), _stringValue(null));
+  }
+
+  void test_bitAnd_knownInt_knownInt() {
+    _assertBitAnd(_intValue(2), _intValue(6), _intValue(3));
+  }
+
+  void test_bitAnd_knownInt_knownString() {
+    _assertBitAnd(null, _intValue(6), _stringValue("3"));
+  }
+
+  void test_bitAnd_knownInt_unknownInt() {
+    _assertBitAnd(_intValue(null), _intValue(6), _intValue(null));
+  }
+
+  void test_bitAnd_knownString_knownInt() {
+    _assertBitAnd(null, _stringValue("6"), _intValue(3));
+  }
+
+  void test_bitAnd_unknownInt_knownInt() {
+    _assertBitAnd(_intValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_bitAnd_unknownInt_unknownInt() {
+    _assertBitAnd(_intValue(null), _intValue(null), _intValue(null));
+  }
+
+  void test_bitNot_knownInt() {
+    _assertBitNot(_intValue(-4), _intValue(3));
+  }
+
+  void test_bitNot_knownString() {
+    _assertBitNot(null, _stringValue("6"));
+  }
+
+  void test_bitNot_unknownInt() {
+    _assertBitNot(_intValue(null), _intValue(null));
+  }
+
+  void test_bitOr_knownInt_knownInt() {
+    _assertBitOr(_intValue(7), _intValue(6), _intValue(3));
+  }
+
+  void test_bitOr_knownInt_knownString() {
+    _assertBitOr(null, _intValue(6), _stringValue("3"));
+  }
+
+  void test_bitOr_knownInt_unknownInt() {
+    _assertBitOr(_intValue(null), _intValue(6), _intValue(null));
+  }
+
+  void test_bitOr_knownString_knownInt() {
+    _assertBitOr(null, _stringValue("6"), _intValue(3));
+  }
+
+  void test_bitOr_unknownInt_knownInt() {
+    _assertBitOr(_intValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_bitOr_unknownInt_unknownInt() {
+    _assertBitOr(_intValue(null), _intValue(null), _intValue(null));
+  }
+
+  void test_bitXor_knownInt_knownInt() {
+    _assertBitXor(_intValue(5), _intValue(6), _intValue(3));
+  }
+
+  void test_bitXor_knownInt_knownString() {
+    _assertBitXor(null, _intValue(6), _stringValue("3"));
+  }
+
+  void test_bitXor_knownInt_unknownInt() {
+    _assertBitXor(_intValue(null), _intValue(6), _intValue(null));
+  }
+
+  void test_bitXor_knownString_knownInt() {
+    _assertBitXor(null, _stringValue("6"), _intValue(3));
+  }
+
+  void test_bitXor_unknownInt_knownInt() {
+    _assertBitXor(_intValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_bitXor_unknownInt_unknownInt() {
+    _assertBitXor(_intValue(null), _intValue(null), _intValue(null));
+  }
+
+  void test_concatenate_knownInt_knownString() {
+    _assertConcatenate(null, _intValue(2), _stringValue("def"));
+  }
+
+  void test_concatenate_knownString_knownInt() {
+    _assertConcatenate(null, _stringValue("abc"), _intValue(3));
+  }
+
+  void test_concatenate_knownString_knownString() {
+    _assertConcatenate(
+        _stringValue("abcdef"), _stringValue("abc"), _stringValue("def"));
+  }
+
+  void test_concatenate_knownString_unknownString() {
+    _assertConcatenate(
+        _stringValue(null), _stringValue("abc"), _stringValue(null));
+  }
+
+  void test_concatenate_unknownString_knownString() {
+    _assertConcatenate(
+        _stringValue(null), _stringValue(null), _stringValue("def"));
+  }
+
+  void test_divide_knownDouble_knownDouble() {
+    _assertDivide(_doubleValue(3.0), _doubleValue(6.0), _doubleValue(2.0));
+  }
+
+  void test_divide_knownDouble_knownInt() {
+    _assertDivide(_doubleValue(3.0), _doubleValue(6.0), _intValue(2));
+  }
+
+  void test_divide_knownDouble_unknownDouble() {
+    _assertDivide(_doubleValue(null), _doubleValue(6.0), _doubleValue(null));
+  }
+
+  void test_divide_knownDouble_unknownInt() {
+    _assertDivide(_doubleValue(null), _doubleValue(6.0), _intValue(null));
+  }
+
+  void test_divide_knownInt_knownInt() {
+    _assertDivide(_doubleValue(3.0), _intValue(6), _intValue(2));
+  }
+
+  void test_divide_knownInt_knownString() {
+    _assertDivide(null, _intValue(6), _stringValue("2"));
+  }
+
+  void test_divide_knownInt_unknownDouble() {
+    _assertDivide(_doubleValue(null), _intValue(6), _doubleValue(null));
+  }
+
+  void test_divide_knownInt_unknownInt() {
+    _assertDivide(_doubleValue(null), _intValue(6), _intValue(null));
+  }
+
+  void test_divide_knownString_knownInt() {
+    _assertDivide(null, _stringValue("6"), _intValue(2));
+  }
+
+  void test_divide_unknownDouble_knownDouble() {
+    _assertDivide(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
+  }
+
+  void test_divide_unknownDouble_knownInt() {
+    _assertDivide(_doubleValue(null), _doubleValue(null), _intValue(2));
+  }
+
+  void test_divide_unknownInt_knownDouble() {
+    _assertDivide(_doubleValue(null), _intValue(null), _doubleValue(2.0));
+  }
+
+  void test_divide_unknownInt_knownInt() {
+    _assertDivide(_doubleValue(null), _intValue(null), _intValue(2));
+  }
+
+  void test_equalEqual_bool_false() {
+    _assertEqualEqual(_boolValue(false), _boolValue(false), _boolValue(true));
+  }
+
+  void test_equalEqual_bool_true() {
+    _assertEqualEqual(_boolValue(true), _boolValue(true), _boolValue(true));
+  }
+
+  void test_equalEqual_bool_unknown() {
+    _assertEqualEqual(_boolValue(null), _boolValue(null), _boolValue(false));
+  }
+
+  void test_equalEqual_double_false() {
+    _assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
+  }
+
+  void test_equalEqual_double_true() {
+    _assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
+  }
+
+  void test_equalEqual_double_unknown() {
+    _assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_equalEqual_int_false() {
+    _assertEqualEqual(_boolValue(false), _intValue(-5), _intValue(5));
+  }
+
+  void test_equalEqual_int_true() {
+    _assertEqualEqual(_boolValue(true), _intValue(5), _intValue(5));
+  }
+
+  void test_equalEqual_int_unknown() {
+    _assertEqualEqual(_boolValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_equalEqual_list_empty() {
+    _assertEqualEqual(null, _listValue(), _listValue());
+  }
+
+  void test_equalEqual_list_false() {
+    _assertEqualEqual(null, _listValue(), _listValue());
+  }
+
+  void test_equalEqual_map_empty() {
+    _assertEqualEqual(null, _mapValue(), _mapValue());
+  }
+
+  void test_equalEqual_map_false() {
+    _assertEqualEqual(null, _mapValue(), _mapValue());
+  }
+
+  void test_equalEqual_null() {
+    _assertEqualEqual(_boolValue(true), _nullValue(), _nullValue());
+  }
+
+  void test_equalEqual_string_false() {
+    _assertEqualEqual(
+        _boolValue(false), _stringValue("abc"), _stringValue("def"));
+  }
+
+  void test_equalEqual_string_true() {
+    _assertEqualEqual(
+        _boolValue(true), _stringValue("abc"), _stringValue("abc"));
+  }
+
+  void test_equalEqual_string_unknown() {
+    _assertEqualEqual(
+        _boolValue(null), _stringValue(null), _stringValue("def"));
+  }
+
+  void test_equals_list_false_differentSizes() {
+    expect(
+        _listValue([_boolValue(true)]) ==
+            _listValue([_boolValue(true), _boolValue(false)]),
+        isFalse);
+  }
+
+  void test_equals_list_false_sameSize() {
+    expect(_listValue([_boolValue(true)]) == _listValue([_boolValue(false)]),
+        isFalse);
+  }
+
+  void test_equals_list_true_empty() {
+    expect(_listValue(), _listValue());
+  }
+
+  void test_equals_list_true_nonEmpty() {
+    expect(_listValue([_boolValue(true)]), _listValue([_boolValue(true)]));
+  }
+
+  void test_equals_map_true_empty() {
+    expect(_mapValue(), _mapValue());
+  }
+
+  void test_equals_symbol_false() {
+    expect(_symbolValue("a") == _symbolValue("b"), isFalse);
+  }
+
+  void test_equals_symbol_true() {
+    expect(_symbolValue("a"), _symbolValue("a"));
+  }
+
+  void test_getValue_bool_false() {
+    expect(_boolValue(false).toBoolValue(), false);
+  }
+
+  void test_getValue_bool_true() {
+    expect(_boolValue(true).toBoolValue(), true);
+  }
+
+  void test_getValue_bool_unknown() {
+    expect(_boolValue(null).toBoolValue(), isNull);
+  }
+
+  void test_getValue_double_known() {
+    double value = 2.3;
+    expect(_doubleValue(value).toDoubleValue(), value);
+  }
+
+  void test_getValue_double_unknown() {
+    expect(_doubleValue(null).toDoubleValue(), isNull);
+  }
+
+  void test_getValue_int_known() {
+    int value = 23;
+    expect(_intValue(value).toIntValue(), value);
+  }
+
+  void test_getValue_int_unknown() {
+    expect(_intValue(null).toIntValue(), isNull);
+  }
+
+  void test_getValue_list_empty() {
+    Object result = _listValue().toListValue();
+    _assertInstanceOfObjectArray(result);
+    List<Object> array = result as List<Object>;
+    expect(array, hasLength(0));
+  }
+
+  void test_getValue_list_valid() {
+    Object result = _listValue([_intValue(23)]).toListValue();
+    _assertInstanceOfObjectArray(result);
+    List<Object> array = result as List<Object>;
+    expect(array, hasLength(1));
+  }
+
+  void test_getValue_map_empty() {
+    Object result = _mapValue().toMapValue();
+    EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
+    Map map = result as Map;
+    expect(map, hasLength(0));
+  }
+
+  void test_getValue_map_valid() {
+    Object result =
+        _mapValue([_stringValue("key"), _stringValue("value")]).toMapValue();
+    EngineTestCase.assertInstanceOf((obj) => obj is Map, Map, result);
+    Map map = result as Map;
+    expect(map, hasLength(1));
+  }
+
+  void test_getValue_null() {
+    expect(_nullValue().isNull, isTrue);
+  }
+
+  void test_getValue_string_known() {
+    String value = "twenty-three";
+    expect(_stringValue(value).toStringValue(), value);
+  }
+
+  void test_getValue_string_unknown() {
+    expect(_stringValue(null).toStringValue(), isNull);
+  }
+
+  void test_greaterThan_knownDouble_knownDouble_false() {
+    _assertGreaterThan(_boolValue(false), _doubleValue(1.0), _doubleValue(2.0));
+  }
+
+  void test_greaterThan_knownDouble_knownDouble_true() {
+    _assertGreaterThan(_boolValue(true), _doubleValue(2.0), _doubleValue(1.0));
+  }
+
+  void test_greaterThan_knownDouble_knownInt_false() {
+    _assertGreaterThan(_boolValue(false), _doubleValue(1.0), _intValue(2));
+  }
+
+  void test_greaterThan_knownDouble_knownInt_true() {
+    _assertGreaterThan(_boolValue(true), _doubleValue(2.0), _intValue(1));
+  }
+
+  void test_greaterThan_knownDouble_unknownDouble() {
+    _assertGreaterThan(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_greaterThan_knownDouble_unknownInt() {
+    _assertGreaterThan(_boolValue(null), _doubleValue(1.0), _intValue(null));
+  }
+
+  void test_greaterThan_knownInt_knownInt_false() {
+    _assertGreaterThan(_boolValue(false), _intValue(1), _intValue(2));
+  }
+
+  void test_greaterThan_knownInt_knownInt_true() {
+    _assertGreaterThan(_boolValue(true), _intValue(2), _intValue(1));
+  }
+
+  void test_greaterThan_knownInt_knownString() {
+    _assertGreaterThan(null, _intValue(1), _stringValue("2"));
+  }
+
+  void test_greaterThan_knownInt_unknownDouble() {
+    _assertGreaterThan(_boolValue(null), _intValue(1), _doubleValue(null));
+  }
+
+  void test_greaterThan_knownInt_unknownInt() {
+    _assertGreaterThan(_boolValue(null), _intValue(1), _intValue(null));
+  }
+
+  void test_greaterThan_knownString_knownInt() {
+    _assertGreaterThan(null, _stringValue("1"), _intValue(2));
+  }
+
+  void test_greaterThan_unknownDouble_knownDouble() {
+    _assertGreaterThan(_boolValue(null), _doubleValue(null), _doubleValue(2.0));
+  }
+
+  void test_greaterThan_unknownDouble_knownInt() {
+    _assertGreaterThan(_boolValue(null), _doubleValue(null), _intValue(2));
+  }
+
+  void test_greaterThan_unknownInt_knownDouble() {
+    _assertGreaterThan(_boolValue(null), _intValue(null), _doubleValue(2.0));
+  }
+
+  void test_greaterThan_unknownInt_knownInt() {
+    _assertGreaterThan(_boolValue(null), _intValue(null), _intValue(2));
+  }
+
+  void test_greaterThanOrEqual_knownDouble_knownDouble_false() {
+    _assertGreaterThanOrEqual(
+        _boolValue(false), _doubleValue(1.0), _doubleValue(2.0));
+  }
+
+  void test_greaterThanOrEqual_knownDouble_knownDouble_true() {
+    _assertGreaterThanOrEqual(
+        _boolValue(true), _doubleValue(2.0), _doubleValue(1.0));
+  }
+
+  void test_greaterThanOrEqual_knownDouble_knownInt_false() {
+    _assertGreaterThanOrEqual(
+        _boolValue(false), _doubleValue(1.0), _intValue(2));
+  }
+
+  void test_greaterThanOrEqual_knownDouble_knownInt_true() {
+    _assertGreaterThanOrEqual(
+        _boolValue(true), _doubleValue(2.0), _intValue(1));
+  }
+
+  void test_greaterThanOrEqual_knownDouble_unknownDouble() {
+    _assertGreaterThanOrEqual(
+        _boolValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_greaterThanOrEqual_knownDouble_unknownInt() {
+    _assertGreaterThanOrEqual(
+        _boolValue(null), _doubleValue(1.0), _intValue(null));
+  }
+
+  void test_greaterThanOrEqual_knownInt_knownInt_false() {
+    _assertGreaterThanOrEqual(_boolValue(false), _intValue(1), _intValue(2));
+  }
+
+  void test_greaterThanOrEqual_knownInt_knownInt_true() {
+    _assertGreaterThanOrEqual(_boolValue(true), _intValue(2), _intValue(2));
+  }
+
+  void test_greaterThanOrEqual_knownInt_knownString() {
+    _assertGreaterThanOrEqual(null, _intValue(1), _stringValue("2"));
+  }
+
+  void test_greaterThanOrEqual_knownInt_unknownDouble() {
+    _assertGreaterThanOrEqual(
+        _boolValue(null), _intValue(1), _doubleValue(null));
+  }
+
+  void test_greaterThanOrEqual_knownInt_unknownInt() {
+    _assertGreaterThanOrEqual(_boolValue(null), _intValue(1), _intValue(null));
+  }
+
+  void test_greaterThanOrEqual_knownString_knownInt() {
+    _assertGreaterThanOrEqual(null, _stringValue("1"), _intValue(2));
+  }
+
+  void test_greaterThanOrEqual_unknownDouble_knownDouble() {
+    _assertGreaterThanOrEqual(
+        _boolValue(null), _doubleValue(null), _doubleValue(2.0));
+  }
+
+  void test_greaterThanOrEqual_unknownDouble_knownInt() {
+    _assertGreaterThanOrEqual(
+        _boolValue(null), _doubleValue(null), _intValue(2));
+  }
+
+  void test_greaterThanOrEqual_unknownInt_knownDouble() {
+    _assertGreaterThanOrEqual(
+        _boolValue(null), _intValue(null), _doubleValue(2.0));
+  }
+
+  void test_greaterThanOrEqual_unknownInt_knownInt() {
+    _assertGreaterThanOrEqual(_boolValue(null), _intValue(null), _intValue(2));
+  }
+
+  void test_hasKnownValue_bool_false() {
+    expect(_boolValue(false).hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_bool_true() {
+    expect(_boolValue(true).hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_bool_unknown() {
+    expect(_boolValue(null).hasKnownValue, isFalse);
+  }
+
+  void test_hasKnownValue_double_known() {
+    expect(_doubleValue(2.3).hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_double_unknown() {
+    expect(_doubleValue(null).hasKnownValue, isFalse);
+  }
+
+  void test_hasKnownValue_dynamic() {
+    expect(_dynamicValue().hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_int_known() {
+    expect(_intValue(23).hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_int_unknown() {
+    expect(_intValue(null).hasKnownValue, isFalse);
+  }
+
+  void test_hasKnownValue_list_empty() {
+    expect(_listValue().hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_list_invalidElement() {
+    expect(_listValue([_dynamicValue]).hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_list_valid() {
+    expect(_listValue([_intValue(23)]).hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_map_empty() {
+    expect(_mapValue().hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_map_invalidKey() {
+    expect(_mapValue([_dynamicValue(), _stringValue("value")]).hasKnownValue,
+        isTrue);
+  }
+
+  void test_hasKnownValue_map_invalidValue() {
+    expect(_mapValue([_stringValue("key"), _dynamicValue()]).hasKnownValue,
+        isTrue);
+  }
+
+  void test_hasKnownValue_map_valid() {
+    expect(
+        _mapValue([_stringValue("key"), _stringValue("value")]).hasKnownValue,
+        isTrue);
+  }
+
+  void test_hasKnownValue_null() {
+    expect(_nullValue().hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_num() {
+    expect(_numValue().hasKnownValue, isFalse);
+  }
+
+  void test_hasKnownValue_string_known() {
+    expect(_stringValue("twenty-three").hasKnownValue, isTrue);
+  }
+
+  void test_hasKnownValue_string_unknown() {
+    expect(_stringValue(null).hasKnownValue, isFalse);
+  }
+
+  void test_identical_bool_false() {
+    _assertIdentical(_boolValue(false), _boolValue(false), _boolValue(true));
+  }
+
+  void test_identical_bool_true() {
+    _assertIdentical(_boolValue(true), _boolValue(true), _boolValue(true));
+  }
+
+  void test_identical_bool_unknown() {
+    _assertIdentical(_boolValue(null), _boolValue(null), _boolValue(false));
+  }
+
+  void test_identical_double_false() {
+    _assertIdentical(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
+  }
+
+  void test_identical_double_true() {
+    _assertIdentical(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
+  }
+
+  void test_identical_double_unknown() {
+    _assertIdentical(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_identical_int_false() {
+    _assertIdentical(_boolValue(false), _intValue(-5), _intValue(5));
+  }
+
+  void test_identical_int_true() {
+    _assertIdentical(_boolValue(true), _intValue(5), _intValue(5));
+  }
+
+  void test_identical_int_unknown() {
+    _assertIdentical(_boolValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_identical_list_empty() {
+    _assertIdentical(_boolValue(true), _listValue(), _listValue());
+  }
+
+  void test_identical_list_false() {
+    _assertIdentical(
+        _boolValue(false), _listValue(), _listValue([_intValue(3)]));
+  }
+
+  void test_identical_map_empty() {
+    _assertIdentical(_boolValue(true), _mapValue(), _mapValue());
+  }
+
+  void test_identical_map_false() {
+    _assertIdentical(_boolValue(false), _mapValue(),
+        _mapValue([_intValue(1), _intValue(2)]));
+  }
+
+  void test_identical_null() {
+    _assertIdentical(_boolValue(true), _nullValue(), _nullValue());
+  }
+
+  void test_identical_string_false() {
+    _assertIdentical(
+        _boolValue(false), _stringValue("abc"), _stringValue("def"));
+  }
+
+  void test_identical_string_true() {
+    _assertIdentical(
+        _boolValue(true), _stringValue("abc"), _stringValue("abc"));
+  }
+
+  void test_identical_string_unknown() {
+    _assertIdentical(_boolValue(null), _stringValue(null), _stringValue("def"));
+  }
+
+  void test_integerDivide_knownDouble_knownDouble() {
+    _assertIntegerDivide(_intValue(3), _doubleValue(6.0), _doubleValue(2.0));
+  }
+
+  void test_integerDivide_knownDouble_knownInt() {
+    _assertIntegerDivide(_intValue(3), _doubleValue(6.0), _intValue(2));
+  }
+
+  void test_integerDivide_knownDouble_unknownDouble() {
+    _assertIntegerDivide(
+        _intValue(null), _doubleValue(6.0), _doubleValue(null));
+  }
+
+  void test_integerDivide_knownDouble_unknownInt() {
+    _assertIntegerDivide(_intValue(null), _doubleValue(6.0), _intValue(null));
+  }
+
+  void test_integerDivide_knownInt_knownInt() {
+    _assertIntegerDivide(_intValue(3), _intValue(6), _intValue(2));
+  }
+
+  void test_integerDivide_knownInt_knownString() {
+    _assertIntegerDivide(null, _intValue(6), _stringValue("2"));
+  }
+
+  void test_integerDivide_knownInt_unknownDouble() {
+    _assertIntegerDivide(_intValue(null), _intValue(6), _doubleValue(null));
+  }
+
+  void test_integerDivide_knownInt_unknownInt() {
+    _assertIntegerDivide(_intValue(null), _intValue(6), _intValue(null));
+  }
+
+  void test_integerDivide_knownString_knownInt() {
+    _assertIntegerDivide(null, _stringValue("6"), _intValue(2));
+  }
+
+  void test_integerDivide_unknownDouble_knownDouble() {
+    _assertIntegerDivide(
+        _intValue(null), _doubleValue(null), _doubleValue(2.0));
+  }
+
+  void test_integerDivide_unknownDouble_knownInt() {
+    _assertIntegerDivide(_intValue(null), _doubleValue(null), _intValue(2));
+  }
+
+  void test_integerDivide_unknownInt_knownDouble() {
+    _assertIntegerDivide(_intValue(null), _intValue(null), _doubleValue(2.0));
+  }
+
+  void test_integerDivide_unknownInt_knownInt() {
+    _assertIntegerDivide(_intValue(null), _intValue(null), _intValue(2));
+  }
+
+  void test_isBoolNumStringOrNull_bool_false() {
+    expect(_boolValue(false).isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_bool_true() {
+    expect(_boolValue(true).isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_bool_unknown() {
+    expect(_boolValue(null).isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_double_known() {
+    expect(_doubleValue(2.3).isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_double_unknown() {
+    expect(_doubleValue(null).isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_dynamic() {
+    expect(_dynamicValue().isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_int_known() {
+    expect(_intValue(23).isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_int_unknown() {
+    expect(_intValue(null).isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_list() {
+    expect(_listValue().isBoolNumStringOrNull, isFalse);
+  }
+
+  void test_isBoolNumStringOrNull_null() {
+    expect(_nullValue().isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_num() {
+    expect(_numValue().isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_string_known() {
+    expect(_stringValue("twenty-three").isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_isBoolNumStringOrNull_string_unknown() {
+    expect(_stringValue(null).isBoolNumStringOrNull, isTrue);
+  }
+
+  void test_lessThan_knownDouble_knownDouble_false() {
+    _assertLessThan(_boolValue(false), _doubleValue(2.0), _doubleValue(1.0));
+  }
+
+  void test_lessThan_knownDouble_knownDouble_true() {
+    _assertLessThan(_boolValue(true), _doubleValue(1.0), _doubleValue(2.0));
+  }
+
+  void test_lessThan_knownDouble_knownInt_false() {
+    _assertLessThan(_boolValue(false), _doubleValue(2.0), _intValue(1));
+  }
+
+  void test_lessThan_knownDouble_knownInt_true() {
+    _assertLessThan(_boolValue(true), _doubleValue(1.0), _intValue(2));
+  }
+
+  void test_lessThan_knownDouble_unknownDouble() {
+    _assertLessThan(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_lessThan_knownDouble_unknownInt() {
+    _assertLessThan(_boolValue(null), _doubleValue(1.0), _intValue(null));
+  }
+
+  void test_lessThan_knownInt_knownInt_false() {
+    _assertLessThan(_boolValue(false), _intValue(2), _intValue(1));
+  }
+
+  void test_lessThan_knownInt_knownInt_true() {
+    _assertLessThan(_boolValue(true), _intValue(1), _intValue(2));
+  }
+
+  void test_lessThan_knownInt_knownString() {
+    _assertLessThan(null, _intValue(1), _stringValue("2"));
+  }
+
+  void test_lessThan_knownInt_unknownDouble() {
+    _assertLessThan(_boolValue(null), _intValue(1), _doubleValue(null));
+  }
+
+  void test_lessThan_knownInt_unknownInt() {
+    _assertLessThan(_boolValue(null), _intValue(1), _intValue(null));
+  }
+
+  void test_lessThan_knownString_knownInt() {
+    _assertLessThan(null, _stringValue("1"), _intValue(2));
+  }
+
+  void test_lessThan_unknownDouble_knownDouble() {
+    _assertLessThan(_boolValue(null), _doubleValue(null), _doubleValue(2.0));
+  }
+
+  void test_lessThan_unknownDouble_knownInt() {
+    _assertLessThan(_boolValue(null), _doubleValue(null), _intValue(2));
+  }
+
+  void test_lessThan_unknownInt_knownDouble() {
+    _assertLessThan(_boolValue(null), _intValue(null), _doubleValue(2.0));
+  }
+
+  void test_lessThan_unknownInt_knownInt() {
+    _assertLessThan(_boolValue(null), _intValue(null), _intValue(2));
+  }
+
+  void test_lessThanOrEqual_knownDouble_knownDouble_false() {
+    _assertLessThanOrEqual(
+        _boolValue(false), _doubleValue(2.0), _doubleValue(1.0));
+  }
+
+  void test_lessThanOrEqual_knownDouble_knownDouble_true() {
+    _assertLessThanOrEqual(
+        _boolValue(true), _doubleValue(1.0), _doubleValue(2.0));
+  }
+
+  void test_lessThanOrEqual_knownDouble_knownInt_false() {
+    _assertLessThanOrEqual(_boolValue(false), _doubleValue(2.0), _intValue(1));
+  }
+
+  void test_lessThanOrEqual_knownDouble_knownInt_true() {
+    _assertLessThanOrEqual(_boolValue(true), _doubleValue(1.0), _intValue(2));
+  }
+
+  void test_lessThanOrEqual_knownDouble_unknownDouble() {
+    _assertLessThanOrEqual(
+        _boolValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_lessThanOrEqual_knownDouble_unknownInt() {
+    _assertLessThanOrEqual(
+        _boolValue(null), _doubleValue(1.0), _intValue(null));
+  }
+
+  void test_lessThanOrEqual_knownInt_knownInt_false() {
+    _assertLessThanOrEqual(_boolValue(false), _intValue(2), _intValue(1));
+  }
+
+  void test_lessThanOrEqual_knownInt_knownInt_true() {
+    _assertLessThanOrEqual(_boolValue(true), _intValue(1), _intValue(2));
+  }
+
+  void test_lessThanOrEqual_knownInt_knownString() {
+    _assertLessThanOrEqual(null, _intValue(1), _stringValue("2"));
+  }
+
+  void test_lessThanOrEqual_knownInt_unknownDouble() {
+    _assertLessThanOrEqual(_boolValue(null), _intValue(1), _doubleValue(null));
+  }
+
+  void test_lessThanOrEqual_knownInt_unknownInt() {
+    _assertLessThanOrEqual(_boolValue(null), _intValue(1), _intValue(null));
+  }
+
+  void test_lessThanOrEqual_knownString_knownInt() {
+    _assertLessThanOrEqual(null, _stringValue("1"), _intValue(2));
+  }
+
+  void test_lessThanOrEqual_unknownDouble_knownDouble() {
+    _assertLessThanOrEqual(
+        _boolValue(null), _doubleValue(null), _doubleValue(2.0));
+  }
+
+  void test_lessThanOrEqual_unknownDouble_knownInt() {
+    _assertLessThanOrEqual(_boolValue(null), _doubleValue(null), _intValue(2));
+  }
+
+  void test_lessThanOrEqual_unknownInt_knownDouble() {
+    _assertLessThanOrEqual(
+        _boolValue(null), _intValue(null), _doubleValue(2.0));
+  }
+
+  void test_lessThanOrEqual_unknownInt_knownInt() {
+    _assertLessThanOrEqual(_boolValue(null), _intValue(null), _intValue(2));
+  }
+
+  void test_logicalAnd_false_false() {
+    _assertLogicalAnd(_boolValue(false), _boolValue(false), _boolValue(false));
+  }
+
+  void test_logicalAnd_false_null() {
+    try {
+      _assertLogicalAnd(_boolValue(false), _boolValue(false), _nullValue());
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalAnd_false_string() {
+    try {
+      _assertLogicalAnd(
+          _boolValue(false), _boolValue(false), _stringValue("false"));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalAnd_false_true() {
+    _assertLogicalAnd(_boolValue(false), _boolValue(false), _boolValue(true));
+  }
+
+  void test_logicalAnd_null_false() {
+    try {
+      _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(false));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalAnd_null_true() {
+    try {
+      _assertLogicalAnd(_boolValue(false), _nullValue(), _boolValue(true));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalAnd_string_false() {
+    try {
+      _assertLogicalAnd(
+          _boolValue(false), _stringValue("true"), _boolValue(false));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalAnd_string_true() {
+    try {
+      _assertLogicalAnd(
+          _boolValue(false), _stringValue("false"), _boolValue(true));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalAnd_true_false() {
+    _assertLogicalAnd(_boolValue(false), _boolValue(true), _boolValue(false));
+  }
+
+  void test_logicalAnd_true_null() {
+    _assertLogicalAnd(null, _boolValue(true), _nullValue());
+  }
+
+  void test_logicalAnd_true_string() {
+    try {
+      _assertLogicalAnd(
+          _boolValue(false), _boolValue(true), _stringValue("true"));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalAnd_true_true() {
+    _assertLogicalAnd(_boolValue(true), _boolValue(true), _boolValue(true));
+  }
+
+  void test_logicalNot_false() {
+    _assertLogicalNot(_boolValue(true), _boolValue(false));
+  }
+
+  void test_logicalNot_null() {
+    _assertLogicalNot(null, _nullValue());
+  }
+
+  void test_logicalNot_string() {
+    try {
+      _assertLogicalNot(_boolValue(true), _stringValue(null));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalNot_true() {
+    _assertLogicalNot(_boolValue(false), _boolValue(true));
+  }
+
+  void test_logicalNot_unknown() {
+    _assertLogicalNot(_boolValue(null), _boolValue(null));
+  }
+
+  void test_logicalOr_false_false() {
+    _assertLogicalOr(_boolValue(false), _boolValue(false), _boolValue(false));
+  }
+
+  void test_logicalOr_false_null() {
+    _assertLogicalOr(null, _boolValue(false), _nullValue());
+  }
+
+  void test_logicalOr_false_string() {
+    try {
+      _assertLogicalOr(
+          _boolValue(false), _boolValue(false), _stringValue("false"));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalOr_false_true() {
+    _assertLogicalOr(_boolValue(true), _boolValue(false), _boolValue(true));
+  }
+
+  void test_logicalOr_null_false() {
+    try {
+      _assertLogicalOr(_boolValue(false), _nullValue(), _boolValue(false));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalOr_null_true() {
+    try {
+      _assertLogicalOr(_boolValue(true), _nullValue(), _boolValue(true));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalOr_string_false() {
+    try {
+      _assertLogicalOr(
+          _boolValue(false), _stringValue("true"), _boolValue(false));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalOr_string_true() {
+    try {
+      _assertLogicalOr(
+          _boolValue(true), _stringValue("false"), _boolValue(true));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalOr_true_false() {
+    _assertLogicalOr(_boolValue(true), _boolValue(true), _boolValue(false));
+  }
+
+  void test_logicalOr_true_null() {
+    try {
+      _assertLogicalOr(_boolValue(true), _boolValue(true), _nullValue());
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalOr_true_string() {
+    try {
+      _assertLogicalOr(
+          _boolValue(true), _boolValue(true), _stringValue("true"));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_logicalOr_true_true() {
+    _assertLogicalOr(_boolValue(true), _boolValue(true), _boolValue(true));
+  }
+
+  void test_minus_knownDouble_knownDouble() {
+    _assertMinus(_doubleValue(1.0), _doubleValue(4.0), _doubleValue(3.0));
+  }
+
+  void test_minus_knownDouble_knownInt() {
+    _assertMinus(_doubleValue(1.0), _doubleValue(4.0), _intValue(3));
+  }
+
+  void test_minus_knownDouble_unknownDouble() {
+    _assertMinus(_doubleValue(null), _doubleValue(4.0), _doubleValue(null));
+  }
+
+  void test_minus_knownDouble_unknownInt() {
+    _assertMinus(_doubleValue(null), _doubleValue(4.0), _intValue(null));
+  }
+
+  void test_minus_knownInt_knownInt() {
+    _assertMinus(_intValue(1), _intValue(4), _intValue(3));
+  }
+
+  void test_minus_knownInt_knownString() {
+    _assertMinus(null, _intValue(4), _stringValue("3"));
+  }
+
+  void test_minus_knownInt_unknownDouble() {
+    _assertMinus(_doubleValue(null), _intValue(4), _doubleValue(null));
+  }
+
+  void test_minus_knownInt_unknownInt() {
+    _assertMinus(_intValue(null), _intValue(4), _intValue(null));
+  }
+
+  void test_minus_knownString_knownInt() {
+    _assertMinus(null, _stringValue("4"), _intValue(3));
+  }
+
+  void test_minus_unknownDouble_knownDouble() {
+    _assertMinus(_doubleValue(null), _doubleValue(null), _doubleValue(3.0));
+  }
+
+  void test_minus_unknownDouble_knownInt() {
+    _assertMinus(_doubleValue(null), _doubleValue(null), _intValue(3));
+  }
+
+  void test_minus_unknownInt_knownDouble() {
+    _assertMinus(_doubleValue(null), _intValue(null), _doubleValue(3.0));
+  }
+
+  void test_minus_unknownInt_knownInt() {
+    _assertMinus(_intValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_negated_double_known() {
+    _assertNegated(_doubleValue(2.0), _doubleValue(-2.0));
+  }
+
+  void test_negated_double_unknown() {
+    _assertNegated(_doubleValue(null), _doubleValue(null));
+  }
+
+  void test_negated_int_known() {
+    _assertNegated(_intValue(-3), _intValue(3));
+  }
+
+  void test_negated_int_unknown() {
+    _assertNegated(_intValue(null), _intValue(null));
+  }
+
+  void test_negated_string() {
+    _assertNegated(null, _stringValue(null));
+  }
+
+  void test_notEqual_bool_false() {
+    _assertNotEqual(_boolValue(false), _boolValue(true), _boolValue(true));
+  }
+
+  void test_notEqual_bool_true() {
+    _assertNotEqual(_boolValue(true), _boolValue(false), _boolValue(true));
+  }
+
+  void test_notEqual_bool_unknown() {
+    _assertNotEqual(_boolValue(null), _boolValue(null), _boolValue(false));
+  }
+
+  void test_notEqual_double_false() {
+    _assertNotEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(2.0));
+  }
+
+  void test_notEqual_double_true() {
+    _assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0));
+  }
+
+  void test_notEqual_double_unknown() {
+    _assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
+  }
+
+  void test_notEqual_int_false() {
+    _assertNotEqual(_boolValue(false), _intValue(5), _intValue(5));
+  }
+
+  void test_notEqual_int_true() {
+    _assertNotEqual(_boolValue(true), _intValue(-5), _intValue(5));
+  }
+
+  void test_notEqual_int_unknown() {
+    _assertNotEqual(_boolValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_notEqual_null() {
+    _assertNotEqual(_boolValue(false), _nullValue(), _nullValue());
+  }
+
+  void test_notEqual_string_false() {
+    _assertNotEqual(
+        _boolValue(false), _stringValue("abc"), _stringValue("abc"));
+  }
+
+  void test_notEqual_string_true() {
+    _assertNotEqual(_boolValue(true), _stringValue("abc"), _stringValue("def"));
+  }
+
+  void test_notEqual_string_unknown() {
+    _assertNotEqual(_boolValue(null), _stringValue(null), _stringValue("def"));
+  }
+
+  void test_performToString_bool_false() {
+    _assertPerformToString(_stringValue("false"), _boolValue(false));
+  }
+
+  void test_performToString_bool_true() {
+    _assertPerformToString(_stringValue("true"), _boolValue(true));
+  }
+
+  void test_performToString_bool_unknown() {
+    _assertPerformToString(_stringValue(null), _boolValue(null));
+  }
+
+  void test_performToString_double_known() {
+    _assertPerformToString(_stringValue("2.0"), _doubleValue(2.0));
+  }
+
+  void test_performToString_double_unknown() {
+    _assertPerformToString(_stringValue(null), _doubleValue(null));
+  }
+
+  void test_performToString_int_known() {
+    _assertPerformToString(_stringValue("5"), _intValue(5));
+  }
+
+  void test_performToString_int_unknown() {
+    _assertPerformToString(_stringValue(null), _intValue(null));
+  }
+
+  void test_performToString_null() {
+    _assertPerformToString(_stringValue("null"), _nullValue());
+  }
+
+  void test_performToString_string_known() {
+    _assertPerformToString(_stringValue("abc"), _stringValue("abc"));
+  }
+
+  void test_performToString_string_unknown() {
+    _assertPerformToString(_stringValue(null), _stringValue(null));
+  }
+
+  void test_remainder_knownDouble_knownDouble() {
+    _assertRemainder(_doubleValue(1.0), _doubleValue(7.0), _doubleValue(2.0));
+  }
+
+  void test_remainder_knownDouble_knownInt() {
+    _assertRemainder(_doubleValue(1.0), _doubleValue(7.0), _intValue(2));
+  }
+
+  void test_remainder_knownDouble_unknownDouble() {
+    _assertRemainder(_doubleValue(null), _doubleValue(7.0), _doubleValue(null));
+  }
+
+  void test_remainder_knownDouble_unknownInt() {
+    _assertRemainder(_doubleValue(null), _doubleValue(6.0), _intValue(null));
+  }
+
+  void test_remainder_knownInt_knownInt() {
+    _assertRemainder(_intValue(1), _intValue(7), _intValue(2));
+  }
+
+  void test_remainder_knownInt_knownString() {
+    _assertRemainder(null, _intValue(7), _stringValue("2"));
+  }
+
+  void test_remainder_knownInt_unknownDouble() {
+    _assertRemainder(_doubleValue(null), _intValue(7), _doubleValue(null));
+  }
+
+  void test_remainder_knownInt_unknownInt() {
+    _assertRemainder(_intValue(null), _intValue(7), _intValue(null));
+  }
+
+  void test_remainder_knownString_knownInt() {
+    _assertRemainder(null, _stringValue("7"), _intValue(2));
+  }
+
+  void test_remainder_unknownDouble_knownDouble() {
+    _assertRemainder(_doubleValue(null), _doubleValue(null), _doubleValue(2.0));
+  }
+
+  void test_remainder_unknownDouble_knownInt() {
+    _assertRemainder(_doubleValue(null), _doubleValue(null), _intValue(2));
+  }
+
+  void test_remainder_unknownInt_knownDouble() {
+    _assertRemainder(_doubleValue(null), _intValue(null), _doubleValue(2.0));
+  }
+
+  void test_remainder_unknownInt_knownInt() {
+    _assertRemainder(_intValue(null), _intValue(null), _intValue(2));
+  }
+
+  void test_shiftLeft_knownInt_knownInt() {
+    _assertShiftLeft(_intValue(48), _intValue(6), _intValue(3));
+  }
+
+  void test_shiftLeft_knownInt_knownString() {
+    _assertShiftLeft(null, _intValue(6), _stringValue(null));
+  }
+
+  void test_shiftLeft_knownInt_tooLarge() {
+    _assertShiftLeft(
+        _intValue(null),
+        _intValue(6),
+        new DartObjectImpl(
+            _typeProvider.intType, new IntState(LONG_MAX_VALUE)));
+  }
+
+  void test_shiftLeft_knownInt_unknownInt() {
+    _assertShiftLeft(_intValue(null), _intValue(6), _intValue(null));
+  }
+
+  void test_shiftLeft_knownString_knownInt() {
+    _assertShiftLeft(null, _stringValue(null), _intValue(3));
+  }
+
+  void test_shiftLeft_unknownInt_knownInt() {
+    _assertShiftLeft(_intValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_shiftLeft_unknownInt_unknownInt() {
+    _assertShiftLeft(_intValue(null), _intValue(null), _intValue(null));
+  }
+
+  void test_shiftRight_knownInt_knownInt() {
+    _assertShiftRight(_intValue(6), _intValue(48), _intValue(3));
+  }
+
+  void test_shiftRight_knownInt_knownString() {
+    _assertShiftRight(null, _intValue(48), _stringValue(null));
+  }
+
+  void test_shiftRight_knownInt_tooLarge() {
+    _assertShiftRight(
+        _intValue(null),
+        _intValue(48),
+        new DartObjectImpl(
+            _typeProvider.intType, new IntState(LONG_MAX_VALUE)));
+  }
+
+  void test_shiftRight_knownInt_unknownInt() {
+    _assertShiftRight(_intValue(null), _intValue(48), _intValue(null));
+  }
+
+  void test_shiftRight_knownString_knownInt() {
+    _assertShiftRight(null, _stringValue(null), _intValue(3));
+  }
+
+  void test_shiftRight_unknownInt_knownInt() {
+    _assertShiftRight(_intValue(null), _intValue(null), _intValue(3));
+  }
+
+  void test_shiftRight_unknownInt_unknownInt() {
+    _assertShiftRight(_intValue(null), _intValue(null), _intValue(null));
+  }
+
+  void test_stringLength_int() {
+    try {
+      _assertStringLength(_intValue(null), _intValue(0));
+      fail("Expected EvaluationException");
+    } on EvaluationException {}
+  }
+
+  void test_stringLength_knownString() {
+    _assertStringLength(_intValue(3), _stringValue("abc"));
+  }
+
+  void test_stringLength_unknownString() {
+    _assertStringLength(_intValue(null), _stringValue(null));
+  }
+
+  void test_times_knownDouble_knownDouble() {
+    _assertTimes(_doubleValue(6.0), _doubleValue(2.0), _doubleValue(3.0));
+  }
+
+  void test_times_knownDouble_knownInt() {
+    _assertTimes(_doubleValue(6.0), _doubleValue(2.0), _intValue(3));
+  }
+
+  void test_times_knownDouble_unknownDouble() {
+    _assertTimes(_doubleValue(null), _doubleValue(2.0), _doubleValue(null));
+  }
+
+  void test_times_knownDouble_unknownInt() {
+    _assertTimes(_doubleValue(null), _doubleValue(2.0), _intValue(null));
+  }
+
+  void test_times_knownInt_knownInt() {
+    _assertTimes(_intValue(6), _intValue(2), _intValue(3));
+  }
+
+  void test_times_knownInt_knownString() {
+    _assertTimes(null, _intValue(2), _stringValue("3"));
+  }
+
+  void test_times_knownInt_unknownDouble() {
+    _assertTimes(_doubleValue(null), _intValue(2), _doubleValue(null));
+  }
+
+  void test_times_knownInt_unknownInt() {
+    _assertTimes(_intValue(null), _intValue(2), _intValue(null));
+  }
+
+  void test_times_knownString_knownInt() {
+    _assertTimes(null, _stringValue("2"), _intValue(3));
+  }
+
+  void test_times_unknownDouble_knownDouble() {
+    _assertTimes(_doubleValue(null), _doubleValue(null), _doubleValue(3.0));
+  }
+
+  void test_times_unknownDouble_knownInt() {
+    _assertTimes(_doubleValue(null), _doubleValue(null), _intValue(3));
+  }
+
+  void test_times_unknownInt_knownDouble() {
+    _assertTimes(_doubleValue(null), _intValue(null), _doubleValue(3.0));
+  }
+
+  void test_times_unknownInt_knownInt() {
+    _assertTimes(_intValue(null), _intValue(null), _intValue(3));
+  }
+
+  /**
+   * Assert that the result of adding the left and right operands is the expected value, or that the
+   * operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertAdd(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.add(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.add(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of bit-anding the left and right operands is the expected value, or that
+   * the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertBitAnd(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.bitAnd(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.bitAnd(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the bit-not of the operand is the expected value, or that the operation throws an
+   * exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param operand the operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertBitNot(DartObjectImpl expected, DartObjectImpl operand) {
+    if (expected == null) {
+      try {
+        operand.bitNot(_typeProvider);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = operand.bitNot(_typeProvider);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of bit-oring the left and right operands is the expected value, or that
+   * the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertBitOr(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.bitOr(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.bitOr(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of bit-xoring the left and right operands is the expected value, or that
+   * the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertBitXor(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.bitXor(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.bitXor(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of concatenating the left and right operands is the expected value, or
+   * that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertConcatenate(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.concatenate(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.concatenate(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of dividing the left and right operands is the expected value, or that
+   * the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertDivide(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.divide(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.divide(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of comparing the left and right operands for equality is the expected
+   * value, or that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertEqualEqual(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.equalEqual(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.equalEqual(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of comparing the left and right operands is the expected value, or that
+   * the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertGreaterThan(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.greaterThan(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.greaterThan(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of comparing the left and right operands is the expected value, or that
+   * the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertGreaterThanOrEqual(DartObjectImpl expected,
+      DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.greaterThanOrEqual(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of comparing the left and right operands using
+   * identical() is the expected value.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   */
+  void _assertIdentical(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    DartObjectImpl result =
+        leftOperand.isIdentical(_typeProvider, rightOperand);
+    expect(result, isNotNull);
+    expect(result, expected);
+  }
+
+  void _assertInstanceOfObjectArray(Object result) {
+    // TODO(scheglov) implement
+  }
+
+  /**
+   * Assert that the result of dividing the left and right operands as integers is the expected
+   * value, or that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertIntegerDivide(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.integerDivide(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.integerDivide(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of comparing the left and right operands is the expected value, or that
+   * the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertLessThan(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.lessThan(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.lessThan(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of comparing the left and right operands is the expected value, or that
+   * the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertLessThanOrEqual(DartObjectImpl expected,
+      DartObjectImpl leftOperand, DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.lessThanOrEqual(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of logical-anding the left and right operands is the expected value, or
+   * that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertLogicalAnd(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.logicalAnd(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.logicalAnd(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the logical-not of the operand is the expected value, or that the operation throws
+   * an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param operand the operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertLogicalNot(DartObjectImpl expected, DartObjectImpl operand) {
+    if (expected == null) {
+      try {
+        operand.logicalNot(_typeProvider);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = operand.logicalNot(_typeProvider);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of logical-oring the left and right operands is the expected value, or
+   * that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertLogicalOr(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.logicalOr(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.logicalOr(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of subtracting the left and right operands is the expected value, or
+   * that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertMinus(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.minus(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.minus(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the negation of the operand is the expected value, or that the operation throws an
+   * exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param operand the operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertNegated(DartObjectImpl expected, DartObjectImpl operand) {
+    if (expected == null) {
+      try {
+        operand.negated(_typeProvider);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = operand.negated(_typeProvider);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of comparing the left and right operands for inequality is the expected
+   * value, or that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertNotEqual(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.notEqual(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.notEqual(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that converting the operand to a string is the expected value, or that the operation
+   * throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param operand the operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertPerformToString(DartObjectImpl expected, DartObjectImpl operand) {
+    if (expected == null) {
+      try {
+        operand.performToString(_typeProvider);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = operand.performToString(_typeProvider);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of taking the remainder of the left and right operands is the expected
+   * value, or that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertRemainder(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.remainder(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.remainder(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of multiplying the left and right operands is the expected value, or
+   * that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertShiftLeft(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.shiftLeft(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.shiftLeft(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of multiplying the left and right operands is the expected value, or
+   * that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertShiftRight(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.shiftRight(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result =
+          leftOperand.shiftRight(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the length of the operand is the expected value, or that the operation throws an
+   * exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param operand the operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertStringLength(DartObjectImpl expected, DartObjectImpl operand) {
+    if (expected == null) {
+      try {
+        operand.stringLength(_typeProvider);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = operand.stringLength(_typeProvider);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  /**
+   * Assert that the result of multiplying the left and right operands is the expected value, or
+   * that the operation throws an exception if the expected value is `null`.
+   *
+   * @param expected the expected result of the operation
+   * @param leftOperand the left operand to the operation
+   * @param rightOperand the left operand to the operation
+   * @throws EvaluationException if the result is an exception when it should not be
+   */
+  void _assertTimes(DartObjectImpl expected, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (expected == null) {
+      try {
+        leftOperand.times(_typeProvider, rightOperand);
+        fail("Expected an EvaluationException");
+      } on EvaluationException {}
+    } else {
+      DartObjectImpl result = leftOperand.times(_typeProvider, rightOperand);
+      expect(result, isNotNull);
+      expect(result, expected);
+    }
+  }
+
+  DartObjectImpl _boolValue(bool value) {
+    if (value == null) {
+      return new DartObjectImpl(
+          _typeProvider.boolType, BoolState.UNKNOWN_VALUE);
+    } else if (identical(value, false)) {
+      return new DartObjectImpl(_typeProvider.boolType, BoolState.FALSE_STATE);
+    } else if (identical(value, true)) {
+      return new DartObjectImpl(_typeProvider.boolType, BoolState.TRUE_STATE);
+    }
+    fail("Invalid boolean value used in test");
+    return null;
+  }
+
+  DartObjectImpl _doubleValue(double value) {
+    if (value == null) {
+      return new DartObjectImpl(
+          _typeProvider.doubleType, DoubleState.UNKNOWN_VALUE);
+    } else {
+      return new DartObjectImpl(
+          _typeProvider.doubleType, new DoubleState(value));
+    }
+  }
+
+  DartObjectImpl _dynamicValue() {
+    return new DartObjectImpl(
+        _typeProvider.nullType, DynamicState.DYNAMIC_STATE);
+  }
+
+  DartObjectImpl _intValue(int value) {
+    if (value == null) {
+      return new DartObjectImpl(_typeProvider.intType, IntState.UNKNOWN_VALUE);
+    } else {
+      return new DartObjectImpl(_typeProvider.intType, new IntState(value));
+    }
+  }
+
+  DartObjectImpl _listValue(
+      [List<DartObjectImpl> elements = DartObjectImpl.EMPTY_LIST]) {
+    return new DartObjectImpl(_typeProvider.listType, new ListState(elements));
+  }
+
+  DartObjectImpl _mapValue(
+      [List<DartObjectImpl> keyElementPairs = DartObjectImpl.EMPTY_LIST]) {
+    Map<DartObjectImpl, DartObjectImpl> map =
+        new Map<DartObjectImpl, DartObjectImpl>();
+    int count = keyElementPairs.length;
+    for (int i = 0; i < count;) {
+      map[keyElementPairs[i++]] = keyElementPairs[i++];
+    }
+    return new DartObjectImpl(_typeProvider.mapType, new MapState(map));
+  }
+
+  DartObjectImpl _nullValue() {
+    return new DartObjectImpl(_typeProvider.nullType, NullState.NULL_STATE);
+  }
+
+  DartObjectImpl _numValue() {
+    return new DartObjectImpl(_typeProvider.nullType, NumState.UNKNOWN_VALUE);
+  }
+
+  DartObjectImpl _stringValue(String value) {
+    if (value == null) {
+      return new DartObjectImpl(
+          _typeProvider.stringType, StringState.UNKNOWN_VALUE);
+    } else {
+      return new DartObjectImpl(
+          _typeProvider.stringType, new StringState(value));
+    }
+  }
+
+  DartObjectImpl _symbolValue(String value) {
+    return new DartObjectImpl(_typeProvider.symbolType, new SymbolState(value));
+  }
+}
+
+@reflectiveTest
+class DeclaredVariablesTest extends EngineTestCase {
+  void test_getBool_false() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    DeclaredVariables variables = new DeclaredVariables();
+    variables.define(variableName, "false");
+    DartObject object = variables.getBool(typeProvider, variableName);
+    expect(object, isNotNull);
+    expect(object.toBoolValue(), false);
+  }
+
+  void test_getBool_invalid() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    DeclaredVariables variables = new DeclaredVariables();
+    variables.define(variableName, "not true");
+    _assertNullDartObject(
+        typeProvider, variables.getBool(typeProvider, variableName));
+  }
+
+  void test_getBool_true() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    DeclaredVariables variables = new DeclaredVariables();
+    variables.define(variableName, "true");
+    DartObject object = variables.getBool(typeProvider, variableName);
+    expect(object, isNotNull);
+    expect(object.toBoolValue(), true);
+  }
+
+  void test_getBool_undefined() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    DeclaredVariables variables = new DeclaredVariables();
+    _assertUnknownDartObject(
+        typeProvider.boolType, variables.getBool(typeProvider, variableName));
+  }
+
+  void test_getInt_invalid() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    DeclaredVariables variables = new DeclaredVariables();
+    variables.define(variableName, "four score and seven years");
+    _assertNullDartObject(
+        typeProvider, variables.getInt(typeProvider, variableName));
+  }
+
+  void test_getInt_undefined() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    DeclaredVariables variables = new DeclaredVariables();
+    _assertUnknownDartObject(
+        typeProvider.intType, variables.getInt(typeProvider, variableName));
+  }
+
+  void test_getInt_valid() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    DeclaredVariables variables = new DeclaredVariables();
+    variables.define(variableName, "23");
+    DartObject object = variables.getInt(typeProvider, variableName);
+    expect(object, isNotNull);
+    expect(object.toIntValue(), 23);
+  }
+
+  void test_getString_defined() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    String value = "value";
+    DeclaredVariables variables = new DeclaredVariables();
+    variables.define(variableName, value);
+    DartObject object = variables.getString(typeProvider, variableName);
+    expect(object, isNotNull);
+    expect(object.toStringValue(), value);
+  }
+
+  void test_getString_undefined() {
+    TestTypeProvider typeProvider = new TestTypeProvider();
+    String variableName = "var";
+    DeclaredVariables variables = new DeclaredVariables();
+    _assertUnknownDartObject(typeProvider.stringType,
+        variables.getString(typeProvider, variableName));
+  }
+
+  void _assertNullDartObject(TestTypeProvider typeProvider, DartObject result) {
+    expect(result.type, typeProvider.nullType);
+  }
+
+  void _assertUnknownDartObject(
+      ParameterizedType expectedType, DartObject result) {
+    expect((result as DartObjectImpl).isUnknown, isTrue);
+    expect(result.type, expectedType);
+  }
+}
+
+@reflectiveTest
 class ReferenceFinderTest {
   DirectedGraph<ConstantEvaluationTarget> _referenceGraph;
   VariableElement _head;
diff --git a/pkg/analyzer/test/generated/engine_test.dart b/pkg/analyzer/test/generated/engine_test.dart
index ce630b1..f15ece1 100644
--- a/pkg/analyzer/test/generated/engine_test.dart
+++ b/pkg/analyzer/test/generated/engine_test.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/context/context.dart';
+import 'package:analyzer/src/context/source.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
@@ -75,7 +76,7 @@
 
 class CompilationUnitMock extends TypedMock implements CompilationUnit {}
 
-class MockSourceFactory extends SourceFactory {
+class MockSourceFactory extends SourceFactoryImpl {
   MockSourceFactory() : super([]);
   Source resolveUri(Source containingSource, String containedUri) {
     throw new JavaIOException();
diff --git a/pkg/analyzer/test/generated/incremental_resolver_test.dart b/pkg/analyzer/test/generated/incremental_resolver_test.dart
index 3f3390b..6b321b0 100644
--- a/pkg/analyzer/test/generated/incremental_resolver_test.dart
+++ b/pkg/analyzer/test/generated/incremental_resolver_test.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/context/cache.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
+import 'package:analyzer/src/dart/element/builder.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/error.dart';
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index fe755ed8..c05f4fd 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -44,30 +44,30 @@
   initializeTestEnvironment();
   runReflectiveTests(AnalysisDeltaTest);
   runReflectiveTests(ChangeSetTest);
-  runReflectiveTests(DisableAsyncTestCase);
-  runReflectiveTests(EnclosedScopeTest);
-  runReflectiveTests(LibraryImportScopeTest);
-  runReflectiveTests(LibraryScopeTest);
-  runReflectiveTests(ScopeTest);
-  runReflectiveTests(ElementResolverTest);
-  runReflectiveTests(InheritanceManagerTest);
-  runReflectiveTests(StaticTypeAnalyzerTest);
-  runReflectiveTests(StaticTypeAnalyzer2Test);
-  runReflectiveTests(SubtypeManagerTest);
-  runReflectiveTests(TypeOverrideManagerTest);
-  runReflectiveTests(TypeProviderImplTest);
-  runReflectiveTests(TypeResolverVisitorTest);
   runReflectiveTests(CheckedModeCompileTimeErrorCodeTest);
+  runReflectiveTests(DisableAsyncTestCase);
+  runReflectiveTests(ElementResolverTest);
+  runReflectiveTests(EnclosedScopeTest);
   runReflectiveTests(ErrorResolverTest);
   runReflectiveTests(HintCodeTest);
+  runReflectiveTests(InheritanceManagerTest);
+  runReflectiveTests(LibraryImportScopeTest);
+  runReflectiveTests(LibraryScopeTest);
   runReflectiveTests(MemberMapTest);
   runReflectiveTests(NonHintCodeTest);
+  runReflectiveTests(ScopeTest);
   runReflectiveTests(SimpleResolverTest);
+  runReflectiveTests(StaticTypeAnalyzerTest);
+  runReflectiveTests(StaticTypeAnalyzer2Test);
   runReflectiveTests(StrictModeTest);
-  runReflectiveTests(TypePropagationTest);
   runReflectiveTests(StrongModeDownwardsInferenceTest);
   runReflectiveTests(StrongModeStaticTypeAnalyzer2Test);
   runReflectiveTests(StrongModeTypePropagationTest);
+  runReflectiveTests(SubtypeManagerTest);
+  runReflectiveTests(TypeOverrideManagerTest);
+  runReflectiveTests(TypePropagationTest);
+  runReflectiveTests(TypeProviderImplTest);
+  runReflectiveTests(TypeResolverVisitorTest);
 }
 
 /**
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 2c1e2d2..cfab206 100644
--- a/pkg/analyzer/test/generated/static_type_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_type_warning_code_test.dart
@@ -27,6 +27,79 @@
     verify([source]);
   }
 
+  void fail_method_lookup_mixin_of_extends() {
+    // See dartbug.com/25605
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource('''
+class A { a() => null; }
+class B {}
+abstract class M extends A {}
+class T = B with M; // Warning: B does not extend A
+main() {
+  new T().a(); // Warning: The method 'a' is not defined for the class 'T'
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      // TODO(paulberry): when dartbug.com/25614 is fixed, add static warning
+      // code for "B does not extend A".
+      StaticTypeWarningCode.UNDEFINED_METHOD
+    ]);
+  }
+
+  void fail_method_lookup_mixin_of_implements() {
+    // See dartbug.com/25605
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource('''
+class A { a() => null; }
+class B {}
+abstract class M implements A {}
+class T = B with M; // Warning: Missing concrete implementation of 'A.a'
+main() {
+  new T().a(); // Warning: The method 'a' is not defined for the class 'T'
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticWarningCode.NON_ABSTRACT_CLASS_INHERITS_ABSTRACT_MEMBER_ONE,
+      StaticTypeWarningCode.UNDEFINED_METHOD
+    ]);
+  }
+
+  void fail_method_lookup_mixin_of_mixin() {
+    // See dartbug.com/25605
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource('''
+class A {}
+class B { b() => null; }
+class C {}
+class M extends A with B {}
+class T = C with M;
+main() {
+  new T().b();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
+  void fail_method_lookup_mixin_of_mixin_application() {
+    // See dartbug.com/25605
+    resetWithOptions(new AnalysisOptionsImpl()..enableSuperMixins = true);
+    Source source = addSource('''
+class A { a() => null; }
+class B {}
+class C {}
+class M = A with B;
+class T = C with M;
+main() {
+  new T().a();
+}
+''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [StaticTypeWarningCode.UNDEFINED_METHOD]);
+  }
+
   void fail_undefinedEnumConstant() {
     // We need a way to set the parseEnum flag in the parser to true.
     Source source = addSource(r'''
diff --git a/pkg/analyzer/test/generated/static_warning_code_test.dart b/pkg/analyzer/test/generated/static_warning_code_test.dart
index eb6aa8b..02c44b8 100644
--- a/pkg/analyzer/test/generated/static_warning_code_test.dart
+++ b/pkg/analyzer/test/generated/static_warning_code_test.dart
@@ -3616,4 +3616,22 @@
     computeLibrarySourceErrors(source);
     assertErrors(source, [StaticWarningCode.VOID_RETURN_FOR_GETTER]);
   }
+
+  void test_missingEnumConstantInSwitch() {
+    Source source = addSource(r'''
+enum E { ONE, TWO, THREE, FOUR }
+bool odd(E e) {
+  switch (e) {
+    case E.ONE:
+    case E.THREE: return true;
+  }
+  return false;
+}''');
+    computeLibrarySourceErrors(source);
+    assertErrors(source, [
+      StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH,
+      StaticWarningCode.MISSING_ENUM_CONSTANT_IN_SWITCH
+    ]);
+    verify([source]);
+  }
 }
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 6486b63..f9bca44 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -20,10 +20,10 @@
 
 main() {
   initializeTestEnvironment();
-  runReflectiveTests(TypeSystemTest);
-  runReflectiveTests(StrongSubtypingTest);
   runReflectiveTests(StrongAssignabilityTest);
+  runReflectiveTests(StrongSubtypingTest);
   runReflectiveTests(StrongGenericFunctionInferenceTest);
+  runReflectiveTests(LeastUpperBoundTest);
 }
 
 @reflectiveTest
@@ -903,7 +903,7 @@
 }
 
 @reflectiveTest
-class TypeSystemTest {
+class LeastUpperBoundTest {
   TypeProvider typeProvider;
   TypeSystem typeSystem;
   FunctionType simpleFunctionType;
@@ -929,21 +929,21 @@
     simpleFunctionType = typeAlias.type;
   }
 
-  void test_getLeastUpperBound_bottom_function() {
+  void test_bottom_function() {
     _checkLeastUpperBound(bottomType, simpleFunctionType, simpleFunctionType);
   }
 
-  void test_getLeastUpperBound_bottom_interface() {
+  void test_bottom_interface() {
     DartType interfaceType = ElementFactory.classElement2('A', []).type;
     _checkLeastUpperBound(bottomType, interfaceType, interfaceType);
   }
 
-  void test_getLeastUpperBound_bottom_typeParam() {
+  void test_bottom_typeParam() {
     DartType typeParam = ElementFactory.typeParameterElement('T').type;
     _checkLeastUpperBound(bottomType, typeParam, typeParam);
   }
 
-  void test_getLeastUpperBound_directInterfaceCase() {
+  void test_directInterfaceCase() {
     //
     // class A
     // class B implements A
@@ -960,7 +960,7 @@
     _checkLeastUpperBound(typeB, typeC, typeB);
   }
 
-  void test_getLeastUpperBound_directSubclassCase() {
+  void test_directSubclassCase() {
     //
     // class A
     // class B extends A
@@ -974,34 +974,34 @@
     _checkLeastUpperBound(typeB, typeC, typeB);
   }
 
-  void test_getLeastUpperBound_dynamic_bottom() {
+  void test_dynamic_bottom() {
     _checkLeastUpperBound(dynamicType, bottomType, dynamicType);
   }
 
-  void test_getLeastUpperBound_dynamic_function() {
+  void test_dynamic_function() {
     _checkLeastUpperBound(dynamicType, simpleFunctionType, dynamicType);
   }
 
-  void test_getLeastUpperBound_dynamic_interface() {
+  void test_dynamic_interface() {
     DartType interfaceType = ElementFactory.classElement2('A', []).type;
     _checkLeastUpperBound(dynamicType, interfaceType, dynamicType);
   }
 
-  void test_getLeastUpperBound_dynamic_typeParam() {
+  void test_dynamic_typeParam() {
     DartType typeParam = ElementFactory.typeParameterElement('T').type;
     _checkLeastUpperBound(dynamicType, typeParam, dynamicType);
   }
 
-  void test_getLeastUpperBound_dynamic_void() {
+  void test_dynamic_void() {
     _checkLeastUpperBound(dynamicType, voidType, dynamicType);
   }
 
-  void test_getLeastUpperBound_interface_function() {
+  void test_interface_function() {
     DartType interfaceType = ElementFactory.classElement2('A', []).type;
     _checkLeastUpperBound(interfaceType, simpleFunctionType, objectType);
   }
 
-  void test_getLeastUpperBound_mixinCase() {
+  void test_mixinCase() {
     //
     // class A
     // class B extends A
@@ -1024,7 +1024,7 @@
     _checkLeastUpperBound(typeD, typeC, typeA);
   }
 
-  void test_getLeastUpperBound_object() {
+  void test_object() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement2("B");
     InterfaceType typeA = classA.type;
@@ -1038,29 +1038,25 @@
     _checkLeastUpperBound(typeA, typeB, typeObject);
   }
 
-  void test_getLeastUpperBound_self() {
+  void test_self() {
     DartType typeParam = ElementFactory.typeParameterElement('T').type;
     DartType interfaceType = ElementFactory.classElement2('A', []).type;
-    expect(
-        typeSystem.getLeastUpperBound(typeProvider, dynamicType, dynamicType),
-        dynamicType);
-    expect(typeSystem.getLeastUpperBound(typeProvider, voidType, voidType),
-        voidType);
-    expect(typeSystem.getLeastUpperBound(typeProvider, bottomType, bottomType),
-        bottomType);
-    expect(typeSystem.getLeastUpperBound(typeProvider, typeParam, typeParam),
-        typeParam);
-    expect(
-        typeSystem.getLeastUpperBound(
-            typeProvider, interfaceType, interfaceType),
-        interfaceType);
-    expect(
-        typeSystem.getLeastUpperBound(
-            typeProvider, simpleFunctionType, simpleFunctionType),
-        simpleFunctionType);
+
+    List<DartType> types = [
+      dynamicType,
+      voidType,
+      bottomType,
+      typeParam,
+      interfaceType,
+      simpleFunctionType
+    ];
+
+    for (DartType type in types) {
+      _checkLeastUpperBound(type, type, type);
+    }
   }
 
-  void test_getLeastUpperBound_sharedSuperclass1() {
+  void test_sharedSuperclass1() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
     ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
@@ -1070,7 +1066,7 @@
     _checkLeastUpperBound(typeB, typeC, typeA);
   }
 
-  void test_getLeastUpperBound_sharedSuperclass2() {
+  void test_sharedSuperclass2() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
     ClassElementImpl classC = ElementFactory.classElement("C", classA.type);
@@ -1081,7 +1077,7 @@
     _checkLeastUpperBound(typeB, typeD, typeA);
   }
 
-  void test_getLeastUpperBound_sharedSuperclass3() {
+  void test_sharedSuperclass3() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement("B", classA.type);
     ClassElementImpl classC = ElementFactory.classElement("C", classB.type);
@@ -1092,7 +1088,7 @@
     _checkLeastUpperBound(typeC, typeD, typeB);
   }
 
-  void test_getLeastUpperBound_sharedSuperclass4() {
+  void test_sharedSuperclass4() {
     ClassElement classA = ElementFactory.classElement2("A");
     ClassElement classA2 = ElementFactory.classElement2("A2");
     ClassElement classA3 = ElementFactory.classElement2("A3");
@@ -1108,7 +1104,7 @@
     _checkLeastUpperBound(typeB, typeC, typeA);
   }
 
-  void test_getLeastUpperBound_sharedSuperinterface1() {
+  void test_sharedSuperinterface1() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement2("B");
     ClassElementImpl classC = ElementFactory.classElement2("C");
@@ -1120,7 +1116,7 @@
     _checkLeastUpperBound(typeB, typeC, typeA);
   }
 
-  void test_getLeastUpperBound_sharedSuperinterface2() {
+  void test_sharedSuperinterface2() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement2("B");
     ClassElementImpl classC = ElementFactory.classElement2("C");
@@ -1135,7 +1131,7 @@
     _checkLeastUpperBound(typeB, typeD, typeA);
   }
 
-  void test_getLeastUpperBound_sharedSuperinterface3() {
+  void test_sharedSuperinterface3() {
     ClassElementImpl classA = ElementFactory.classElement2("A");
     ClassElementImpl classB = ElementFactory.classElement2("B");
     ClassElementImpl classC = ElementFactory.classElement2("C");
@@ -1150,7 +1146,7 @@
     _checkLeastUpperBound(typeC, typeD, typeB);
   }
 
-  void test_getLeastUpperBound_sharedSuperinterface4() {
+  void test_sharedSuperinterface4() {
     ClassElement classA = ElementFactory.classElement2("A");
     ClassElement classA2 = ElementFactory.classElement2("A2");
     ClassElement classA3 = ElementFactory.classElement2("A3");
@@ -1166,11 +1162,11 @@
     _checkLeastUpperBound(typeB, typeC, typeA);
   }
 
-  void test_getLeastUpperBound_twoComparables() {
+  void test_twoComparables() {
     _checkLeastUpperBound(stringType, numType, objectType);
   }
 
-  void test_getLeastUpperBound_typeParam_function_bounded() {
+  void test_typeParam_function_bounded() {
     DartType typeA = ElementFactory.classElement('A', functionType).type;
     TypeParameterElementImpl typeParamElement =
         ElementFactory.typeParameterElement('T');
@@ -1179,12 +1175,12 @@
     _checkLeastUpperBound(typeParam, simpleFunctionType, functionType);
   }
 
-  void test_getLeastUpperBound_typeParam_function_noBound() {
+  void test_typeParam_function_noBound() {
     DartType typeParam = ElementFactory.typeParameterElement('T').type;
     _checkLeastUpperBound(typeParam, simpleFunctionType, objectType);
   }
 
-  void test_getLeastUpperBound_typeParam_interface_bounded() {
+  void test_typeParam_interface_bounded() {
     DartType typeA = ElementFactory.classElement2('A', []).type;
     DartType typeB = ElementFactory.classElement('B', typeA).type;
     DartType typeC = ElementFactory.classElement('C', typeA).type;
@@ -1195,13 +1191,13 @@
     _checkLeastUpperBound(typeParam, typeC, typeA);
   }
 
-  void test_getLeastUpperBound_typeParam_interface_noBound() {
+  void test_typeParam_interface_noBound() {
     DartType typeParam = ElementFactory.typeParameterElement('T').type;
     DartType interfaceType = ElementFactory.classElement2('A', []).type;
     _checkLeastUpperBound(typeParam, interfaceType, objectType);
   }
 
-  void test_getLeastUpperBound_typeParameters_different() {
+  void test_typeParameters_different() {
     //
     // class List<int>
     // class List<double>
@@ -1212,7 +1208,7 @@
     _checkLeastUpperBound(listOfIntType, listOfDoubleType, objectType);
   }
 
-  void test_getLeastUpperBound_typeParameters_same() {
+  void test_typeParameters_same() {
     //
     // List<int>
     // List<int>
@@ -1224,24 +1220,106 @@
         listOfIntType);
   }
 
-  void test_getLeastUpperBound_void_bottom() {
+  void test_void_bottom() {
     _checkLeastUpperBound(voidType, bottomType, voidType);
   }
 
-  void test_getLeastUpperBound_void_function() {
+  void test_void_function() {
     _checkLeastUpperBound(voidType, simpleFunctionType, voidType);
   }
 
-  void test_getLeastUpperBound_void_interface() {
+  void test_void_interface() {
     DartType interfaceType = ElementFactory.classElement2('A', []).type;
     _checkLeastUpperBound(voidType, interfaceType, voidType);
   }
 
-  void test_getLeastUpperBound_void_typeParam() {
+  void test_void_typeParam() {
     DartType typeParam = ElementFactory.typeParameterElement('T').type;
     _checkLeastUpperBound(voidType, typeParam, voidType);
   }
 
+  void test_functionsSameType() {
+    FunctionType type1 = _functionType([stringType, intType, numType],
+        optional: [doubleType], named: {'n': numType}, returns: intType);
+    FunctionType type2 = _functionType([stringType, intType, numType],
+        optional: [doubleType], named: {'n': numType}, returns: intType);
+    FunctionType expected = _functionType([stringType, intType, numType],
+        optional: [doubleType], named: {'n': numType}, returns: intType);
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_functionsDifferentRequiredArity() {
+    FunctionType type1 = _functionType([intType, intType]);
+    FunctionType type2 = _functionType([intType, intType, intType]);
+    _checkLeastUpperBound(type1, type2, functionType);
+  }
+
+  void test_functionsLubRequiredParams() {
+    FunctionType type1 = _functionType([stringType, intType, intType]);
+    FunctionType type2 = _functionType([intType, doubleType, numType]);
+    FunctionType expected = _functionType([objectType, numType, numType]);
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_functionsLubPositionalParams() {
+    FunctionType type1 = _functionType([], optional: [stringType, intType]);
+    FunctionType type2 = _functionType([], optional: [intType, doubleType]);
+    FunctionType expected = _functionType([], optional: [objectType, numType]);
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_functionsIgnoreExtraPositionalParams() {
+    FunctionType type1 =
+        _functionType([], optional: [intType, intType, stringType]);
+    FunctionType type2 = _functionType([], optional: [doubleType]);
+    FunctionType expected = _functionType([], optional: [numType]);
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_functionsLubNamedParams() {
+    FunctionType type1 =
+        _functionType([], named: {'a': stringType, 'b': intType});
+    FunctionType type2 =
+        _functionType([], named: {'a': intType, 'b': doubleType});
+    FunctionType expected =
+        _functionType([], named: {'a': objectType, 'b': numType});
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_functionsIgnoreExtraNamedParams() {
+    FunctionType type1 = _functionType([], named: {'a': intType, 'b': intType});
+    FunctionType type2 =
+        _functionType([], named: {'a': doubleType, 'c': doubleType});
+    FunctionType expected = _functionType([], named: {'a': numType});
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_functionsLubReturnType() {
+    FunctionType type1 = _functionType([], returns: intType);
+    FunctionType type2 = _functionType([], returns: doubleType);
+
+    FunctionType expected = _functionType([], returns: numType);
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  /**
+   * Creates a function type with the given parameter and return types.
+   *
+   * The return type defaults to `void` if omitted.
+   */
+  FunctionType _functionType(List<DartType> required,
+      {List<DartType> optional,
+      Map<String, DartType> named,
+      DartType returns}) {
+    if (returns == null) {
+      returns = voidType;
+    }
+    
+    return ElementFactory
+        .functionElement8(required, returns, optional: optional, named: named)
+        .type;
+  }
+
   void _checkLeastUpperBound(
       DartType type1, DartType type2, DartType expectedResult) {
     expect(typeSystem.getLeastUpperBound(typeProvider, type1, type2),
diff --git a/pkg/analyzer/test/source/embedder_test.dart b/pkg/analyzer/test/source/embedder_test.dart
index cf96040..eecb818 100644
--- a/pkg/analyzer/test/source/embedder_test.dart
+++ b/pkg/analyzer/test/source/embedder_test.dart
@@ -4,21 +4,26 @@
 
 library analyzer.test.source.embedder_test;
 
+import 'dart:core' hide Resource;
+
+import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/embedder.dart';
-import 'package:analyzer/src/generated/java_io.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/util/absolute_path.dart';
+import 'package:path/path.dart' as path;
 import 'package:unittest/unittest.dart';
 
 import '../utils.dart';
 
 main() {
-  initializeTestEnvironment();
   group('EmbedderUriResolverTest', () {
     setUp(() {
+      initializeTestEnvironment(path.context);
       buildResourceProvider();
     });
     tearDown(() {
+      initializeTestEnvironment();
       clearResourceProvider();
     });
     test('test_NullEmbedderYamls', () {
@@ -27,20 +32,20 @@
     });
     test('test_NoEmbedderYamls', () {
       var locator = new EmbedderYamlLocator({
-        'fox': [resourceProvider.getResource('/empty')]
+        'fox': [pathTranslator.getResource('/empty')]
       });
       expect(locator.embedderYamls.length, equals(0));
     });
     test('test_EmbedderYaml', () {
       var locator = new EmbedderYamlLocator({
-        'fox': [resourceProvider.getResource('/tmp')]
+        'fox': [pathTranslator.getResource('/tmp')]
       });
       var resolver = new EmbedderUriResolver(locator.embedderYamls);
 
-      expectResolved(dartUri, filePath) {
+      expectResolved(dartUri, posixPath) {
         Source source = resolver.resolveAbsolute(Uri.parse(dartUri));
         expect(source, isNotNull, reason: dartUri);
-        expect(source.fullName, filePath.replaceAll('/', JavaFile.separator));
+        expect(source.fullName, posixToOSPath(posixPath));
       }
 
       // We have four mappings.
@@ -58,12 +63,13 @@
     });
     test('test_restoreAbsolute', () {
       var locator = new EmbedderYamlLocator({
-        'fox': [resourceProvider.getResource('/tmp')]
+        'fox': [pathTranslator.getResource('/tmp')]
       });
       var resolver = new EmbedderUriResolver(locator.embedderYamls);
 
       expectRestore(String dartUri, [String expected]) {
-        var source = resolver.resolveAbsolute(Uri.parse(dartUri));
+        var parsedUri = Uri.parse(dartUri);
+        var source = resolver.resolveAbsolute(parsedUri);
         expect(source, isNotNull);
         // Restore source's uri.
         var restoreUri = resolver.restoreAbsolute(source);
@@ -75,72 +81,54 @@
         expect(restoreUri.path, equals(split[1]));
       }
 
-      try {
-        expectRestore('dart:deep');
-        expectRestore('dart:deep/file.dart', 'dart:deep');
-        expectRestore('dart:deep/part.dart');
-        expectRestore('dart:deep/deep/file.dart');
-        if (JavaFile.separator == '\\') {
-          // See https://github.com/dart-lang/sdk/issues/25498
-          fail('expected to fail on Windows');
-        }
-      } catch (_) {
-        // Test is broken on Windows, but should run elsewhere
-        if (JavaFile.separator != '\\') {
-          rethrow;
-        }
-      }
+      expectRestore('dart:deep');
+      expectRestore('dart:deep/file.dart', 'dart:deep');
+      expectRestore('dart:deep/part.dart');
+      expectRestore('dart:deep/deep/file.dart');
     });
 
     test('test_EmbedderSdk_fromFileUri', () {
       var locator = new EmbedderYamlLocator({
-        'fox': [resourceProvider.getResource('/tmp')]
+        'fox': [pathTranslator.getResource('/tmp')]
       });
       var resolver = new EmbedderUriResolver(locator.embedderYamls);
       var sdk = resolver.dartSdk;
 
-      expectSource(String filePath, String dartUri) {
-        var uri = Uri.parse(filePath);
+      expectSource(String posixPath, String dartUri) {
+        var uri = Uri.parse(posixToOSFileUri(posixPath));
         var source = sdk.fromFileUri(uri);
-        expect(source, isNotNull, reason: filePath);
+        expect(source, isNotNull, reason: posixPath);
         expect(source.uri.toString(), dartUri);
-        expect(source.fullName, filePath.replaceAll('/', JavaFile.separator));
+        expect(source.fullName, posixToOSPath(posixPath));
       }
 
-      //TODO(danrubel) fix embedder on Windows
-      isWindows() => JavaFile.separator == '\\';
-      try {
-        expectSource('/tmp/slippy.dart', 'dart:fox');
-        expectSource('/tmp/deep/directory/file.dart', 'dart:deep');
-        expectSource('/tmp/deep/directory/part.dart', 'dart:deep/part.dart');
-        if (isWindows()) fail('expected to fail on windows');
-      } catch (e) {
-        if (!isWindows()) rethrow;
-      }
+      expectSource('/tmp/slippy.dart', 'dart:fox');
+      expectSource('/tmp/deep/directory/file.dart', 'dart:deep');
+      expectSource('/tmp/deep/directory/part.dart', 'dart:deep/part.dart');
     });
     test('test_EmbedderSdk_getSdkLibrary', () {
       var locator = new EmbedderYamlLocator({
-        'fox': [resourceProvider.getResource('/tmp')]
+        'fox': [pathTranslator.getResource('/tmp')]
       });
       var resolver = new EmbedderUriResolver(locator.embedderYamls);
       var sdk = resolver.dartSdk;
       var lib = sdk.getSdkLibrary('dart:fox');
       expect(lib, isNotNull);
-      expect(lib.path, '/tmp/slippy.dart');
+      expect(lib.path, posixToOSPath('/tmp/slippy.dart'));
       expect(lib.shortName, 'fox');
     });
     test('test_EmbedderSdk_mapDartUri', () {
       var locator = new EmbedderYamlLocator({
-        'fox': [resourceProvider.getResource('/tmp')]
+        'fox': [pathTranslator.getResource('/tmp')]
       });
       var resolver = new EmbedderUriResolver(locator.embedderYamls);
       var sdk = resolver.dartSdk;
 
-      expectSource(String dartUri, String filePath) {
+      expectSource(String dartUri, String posixPath) {
         var source = sdk.mapDartUri(dartUri);
-        expect(source, isNotNull, reason: filePath);
+        expect(source, isNotNull, reason: posixPath);
         expect(source.uri.toString(), dartUri);
-        expect(source.fullName, filePath.replaceAll('/', JavaFile.separator));
+        expect(source.fullName, posixToOSPath(posixPath));
       }
 
       expectSource('dart:fox', '/tmp/slippy.dart');
@@ -150,16 +138,19 @@
   });
 }
 
-MemoryResourceProvider resourceProvider;
+ResourceProvider resourceProvider;
+TestPathTranslator pathTranslator;
 
 buildResourceProvider() {
-  resourceProvider = new MemoryResourceProvider();
-  resourceProvider.newFolder('/empty');
-  resourceProvider.newFolder('/tmp');
-  resourceProvider.newFile(
-      '/tmp/_embedder.yaml',
-      r'''
-embedder_libs:
+  var rawProvider = new MemoryResourceProvider(isWindows: isWindows);
+  resourceProvider = new TestResourceProvider(rawProvider);
+  pathTranslator = new TestPathTranslator(rawProvider)
+    ..newFolder('/empty')
+    ..newFolder('/tmp')
+    ..newFile(
+        '/tmp/_embedder.yaml',
+        r'''
+embedded_libs:
   "dart:fox": "slippy.dart"
   "dart:bear": "grizzly.dart"
   "dart:relative": "../relative.dart"
@@ -170,4 +161,117 @@
 
 clearResourceProvider() {
   resourceProvider = null;
+  pathTranslator = null;
+}
+
+// TODO(danrubel) if this approach works well for running tests
+// in a platform specific way, then move all of the following functionality
+// into a separate test utility library.
+
+bool get isWindows => path.Style.platform == path.Style.windows;
+
+/**
+ * Assert that the given path is posix.
+ */
+void expectAbsolutePosixPath(String posixPath) {
+  expect(posixPath, startsWith('/'),
+      reason: 'Expected absolute posix path, but found $posixPath');
+}
+
+/**
+ * Translate the given posixPath to a path appropriate for the
+ * platform on which the tests are executing.
+ */
+String posixToOSPath(String posixPath) {
+  expectAbsolutePosixPath(posixPath);
+  if (isWindows) {
+    String windowsPath = posixPath.replaceAll('/', '\\');
+    if (posixPath.startsWith('/')) {
+      return 'C:$windowsPath';
+    }
+    return windowsPath;
+  }
+  return posixPath;
+}
+
+/**
+ * Translate the given posixPath to a file URI appropriate for the
+ * platform on which the tests are executing.
+ */
+String posixToOSFileUri(String posixPath) {
+  expectAbsolutePosixPath(posixPath);
+  return isWindows ? 'file:///C:$posixPath' : 'file://$posixPath';
+}
+
+/**
+ * A convenience utility for setting up a test [MemoryResourceProvider].
+ * All supplied paths are assumed to be in [path.posix] format
+ * and are automatically translated to [path.context].
+ *
+ * This class intentionally does not implement [ResourceProvider]
+ * directly or indirectly so that it cannot be used as a resource provider.
+ * We do not want functionality under test to interact with a resource provider
+ * that automatically translates paths.
+ */
+class TestPathTranslator {
+  final MemoryResourceProvider _provider;
+
+  TestPathTranslator(this._provider);
+
+  Resource getResource(String posixPath) =>
+      _provider.getResource(posixToOSPath(posixPath));
+
+  File newFile(String posixPath, String content) =>
+      _provider.newFile(posixToOSPath(posixPath), content);
+
+  Folder newFolder(String posixPath) =>
+      _provider.newFolder(posixToOSPath(posixPath));
+}
+
+/**
+ * A resource provider for testing that asserts that any supplied paths
+ * are appropriate for the OS platform on which the tests are running.
+ */
+class TestResourceProvider implements ResourceProvider {
+  final ResourceProvider _provider;
+
+  TestResourceProvider(this._provider) {
+    expect(_provider.absolutePathContext.separator, isWindows ? '\\' : '/');
+  }
+
+  @override
+  AbsolutePathContext get absolutePathContext => _provider.absolutePathContext;
+
+  @override
+  File getFile(String path) => _provider.getFile(_assertPath(path));
+
+  @override
+  Folder getFolder(String path) => _provider.getFolder(_assertPath(path));
+
+  @override
+  Resource getResource(String path) => _provider.getResource(_assertPath(path));
+
+  @override
+  Folder getStateLocation(String pluginId) =>
+      _provider.getStateLocation(pluginId);
+
+  @override
+  path.Context get pathContext => _provider.pathContext;
+
+  /**
+   * Assert that the given path is valid for the OS platform on which the
+   * tests are running.
+   */
+  String _assertPath(String path) {
+    if (isWindows) {
+      if (path.contains('/')) {
+        fail('Expected windows path, but found: $path');
+      }
+    } else {
+      if (path.contains('\\')) {
+        fail('Expected posix path, but found: $path');
+      }
+    }
+    return path;
+  }
 }
diff --git a/pkg/analyzer/test/src/context/context_test.dart b/pkg/analyzer/test/src/context/context_test.dart
index d37179a..326e6a2 100644
--- a/pkg/analyzer/test/src/context/context_test.dart
+++ b/pkg/analyzer/test/src/context/context_test.dart
@@ -490,6 +490,13 @@
     expect(context.computeDocumentationComment(null), isNull);
   }
 
+  void test_computeErrors_dart_malformedCode() {
+    Source source = addSource("/lib.dart", "final int , = 42;");
+    List<AnalysisError> errors = context.computeErrors(source);
+    expect(errors, isNotNull);
+    expect(errors.length > 0, isTrue);
+  }
+
   void test_computeErrors_dart_none() {
     Source source = addSource("/lib.dart", "library lib;");
     List<AnalysisError> errors = context.computeErrors(source);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_test.dart b/pkg/analyzer/test/src/summary/resynthesize_test.dart
index c4692fc..ce262d3 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_test.dart
@@ -4,6 +4,7 @@
 
 library test.src.serialization.elements_test;
 
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
@@ -29,6 +30,7 @@
 @reflectiveTest
 class ResynthTest extends ResolverTestCase {
   Set<Source> otherLibrarySources = new Set<Source>();
+  bool shouldCompareConstValues = false;
 
   /**
    * Determine the analysis options that should be used for this test.
@@ -49,7 +51,8 @@
     LibraryElementImpl original = resolve2(source);
     LibraryElementImpl resynthesized = resynthesizeLibraryElement(
         encodeLibrary(original, allowErrors: allowErrors),
-        source.uri.toString());
+        source.uri.toString(),
+        original);
     checkLibraryElements(original, resynthesized);
   }
 
@@ -99,6 +102,29 @@
     // TODO(paulberry): test metadata.
   }
 
+  /**
+   * Verify that the [resynthesizer] didn't do any unnecessary work when
+   * resynthesizing [library].
+   */
+  void checkMinimalResynthesisWork(
+      _TestSummaryResynthesizer resynthesizer, LibraryElement library) {
+    // Check that no other summaries needed to be resynthesized to resynthesize
+    // the library element.
+    expect(resynthesizer.resynthesisCount, 1);
+    // Check that the only linked summary consulted was that for [uri].
+    expect(resynthesizer.linkedSummariesRequested, hasLength(1));
+    expect(resynthesizer.linkedSummariesRequested.first,
+        library.source.uri.toString());
+    // Check that the only unlinked summaries consulted were those for the
+    // library in question.
+    Set<String> expectedCompilationUnitUris = library.units
+        .map((CompilationUnitElement unit) => unit.source.uri.toString())
+        .toSet();
+    for (String requestedUri in resynthesizer.unlinkedSummariesRequested) {
+      expect(expectedCompilationUnitUris, contains(requestedUri));
+    }
+  }
+
   void compareClassElements(
       ClassElementImpl resynthesized, ClassElementImpl original, String desc) {
     compareElements(resynthesized, original, desc);
@@ -201,6 +227,120 @@
     // TODO(paulberry): test metadata and offsetToElementMap.
   }
 
+  void compareConstantExpressions(Expression r, Expression o, String desc) {
+    void compareLists(List<Object> rItems, List<Object> oItems) {
+      if (rItems == null && oItems == null) {
+        return;
+      }
+      expect(rItems != null && oItems != null, isTrue);
+      expect(rItems, hasLength(oItems.length));
+      for (int i = 0; i < oItems.length; i++) {
+        Object rItem = rItems[i];
+        Object oItem = oItems[i];
+        if (rItem is Expression && oItem is Expression) {
+          compareConstantExpressions(rItem, oItem, desc);
+        } else if (rItem is TypeName && oItem is TypeName) {
+          compareConstantExpressions(rItem.name, oItem.name, desc);
+        } else if (rItem is InterpolationString &&
+            oItem is InterpolationString) {
+          expect(rItem.value, oItem.value);
+        } else if (rItem is InterpolationExpression &&
+            oItem is InterpolationExpression) {
+          compareConstantExpressions(rItem.expression, oItem.expression, desc);
+        } else if (rItem is MapLiteralEntry && oItem is MapLiteralEntry) {
+          compareConstantExpressions(rItem.key, oItem.key, desc);
+          compareConstantExpressions(rItem.value, oItem.value, desc);
+        } else {
+          fail('$desc Incompatible item types: '
+              '${rItem.runtimeType} vs. ${oItem.runtimeType}');
+        }
+      }
+    }
+    if (o == null) {
+      expect(r, isNull, reason: desc);
+    } else {
+      expect(r, isNotNull, reason: desc);
+      // ConstantAstCloner does not copy static types, and constant values
+      // computer does not use static types. So, we don't set them during
+      // resynthesis and should not check them here.
+      if (o is ParenthesizedExpression) {
+        // We don't resynthesize parenthesis, so just ignore it.
+        compareConstantExpressions(r, o.expression, desc);
+      } else if (o is SimpleIdentifier && r is SimpleIdentifier) {
+        expect(r.name, o.name);
+        compareElements(r.staticElement, o.staticElement, desc);
+      } else if (o is PrefixedIdentifier && r is SimpleIdentifier) {
+        // We don't resynthesize prefixed identifiers.
+        // We use simple identifiers with correct elements.
+        compareConstantExpressions(r, o.identifier, desc);
+      } else if (o is PropertyAccess && r is SimpleIdentifier) {
+        // We don't resynthesize property access.
+        // We use simple identifiers with correct elements.
+        compareConstantExpressions(r, o.propertyName, desc);
+      } else if (o is NullLiteral) {
+        expect(r, new isInstanceOf<NullLiteral>(), reason: desc);
+      } else if (o is BooleanLiteral && r is BooleanLiteral) {
+        expect(r.value, o.value, reason: desc);
+      } else if (o is IntegerLiteral && r is IntegerLiteral) {
+        expect(r.value, o.value, reason: desc);
+      } else if (o is DoubleLiteral && r is DoubleLiteral) {
+        expect(r.value, o.value, reason: desc);
+      } else if (o is StringInterpolation && r is StringInterpolation) {
+        compareLists(r.elements, o.elements);
+      } else if (o is StringLiteral && r is StringLiteral) {
+        // We don't keep all the tokens of AdjacentStrings.
+        // So, we can compare only their values.
+        expect(r.stringValue, o.stringValue, reason: desc);
+      } else if (o is SymbolLiteral && r is SymbolLiteral) {
+        // We don't keep all the tokens of symbol literals.
+        // So, we can compare only their values.
+        expect(r.components.map((t) => t.lexeme).join('.'),
+            o.components.map((t) => t.lexeme).join('.'),
+            reason: desc);
+      } else if (o is NamedExpression && r is NamedExpression) {
+        expect(r.name.label.name, o.name.label.name, reason: desc);
+        compareConstantExpressions(r.expression, o.expression, desc);
+      } else if (o is BinaryExpression && r is BinaryExpression) {
+        expect(r.operator.lexeme, o.operator.lexeme, reason: desc);
+        compareConstantExpressions(r.leftOperand, o.leftOperand, desc);
+        compareConstantExpressions(r.rightOperand, o.rightOperand, desc);
+      } else if (o is PrefixExpression && r is PrefixExpression) {
+        expect(r.operator.lexeme, o.operator.lexeme, reason: desc);
+        compareConstantExpressions(r.operand, o.operand, desc);
+      } else if (o is ConditionalExpression && r is ConditionalExpression) {
+        compareConstantExpressions(r.condition, o.condition, desc);
+        compareConstantExpressions(r.thenExpression, o.thenExpression, desc);
+        compareConstantExpressions(r.elseExpression, o.elseExpression, desc);
+      } else if (o is ListLiteral && r is ListLiteral) {
+        compareLists(r.typeArguments?.arguments, o.typeArguments?.arguments);
+        compareLists(r.elements, o.elements);
+      } else if (o is MapLiteral && r is MapLiteral) {
+        compareLists(r.typeArguments?.arguments, o.typeArguments?.arguments);
+        compareLists(r.entries, o.entries);
+      } else if (o is InstanceCreationExpression &&
+          r is InstanceCreationExpression) {
+        compareElements(r.staticElement, o.staticElement, desc);
+        ConstructorName oConstructor = o.constructorName;
+        ConstructorName rConstructor = r.constructorName;
+        expect(oConstructor, isNotNull, reason: desc);
+        expect(rConstructor, isNotNull, reason: desc);
+        compareElements(
+            rConstructor.staticElement, oConstructor.staticElement, desc);
+        TypeName oType = oConstructor.type;
+        TypeName rType = rConstructor.type;
+        expect(oType, isNotNull, reason: desc);
+        expect(rType, isNotNull, reason: desc);
+        compareConstantExpressions(rType.name, oType.name, desc);
+        compareConstantExpressions(rConstructor.name, oConstructor.name, desc);
+        compareLists(r.argumentList.arguments, o.argumentList.arguments);
+      } else if (o is ConstructorName && r is ConstructorName) {
+        fail('Not implemented for ${r.runtimeType} vs. ${o.runtimeType}');
+      } else {
+        fail('Not implemented for ${r.runtimeType} vs. ${o.runtimeType}');
+      }
+    }
+  }
+
   void compareConstructorElements(ConstructorElementImpl resynthesized,
       ConstructorElementImpl original, String desc) {
     compareExecutableElements(resynthesized, original, desc);
@@ -241,6 +381,13 @@
     compareTypes(
         resynthesized.returnType, original.returnType, '$desc return type');
     compareTypes(resynthesized.type, original.type, desc);
+    expect(resynthesized.typeParameters.length, original.typeParameters.length);
+    for (int i = 0; i < resynthesized.typeParameters.length; i++) {
+      compareTypeParameterElements(
+          resynthesized.typeParameters[i],
+          original.typeParameters[i],
+          '$desc type parameter ${original.typeParameters[i].name}');
+    }
   }
 
   void compareExportElements(ExportElementImpl resynthesized,
@@ -313,7 +460,6 @@
       MethodElementImpl original, String desc) {
     // TODO(paulberry): do we need to deal with
     // MultiplyInheritedMethodElementImpl?
-    // TODO(paulberry): compare type parameters for generic methods.
     compareExecutableElements(resynthesized, original, desc);
   }
 
@@ -509,6 +655,12 @@
       VariableElementImpl original, String desc) {
     compareElements(resynthesized, original, desc);
     compareTypes(resynthesized.type, original.type, desc);
+    // TODO(scheglov) implement and validate other constant variable types
+    if (shouldCompareConstValues &&
+        original is ConstTopLevelVariableElementImpl) {
+      compareConstantExpressions(resynthesized.constantInitializer,
+          original.constantInitializer, desc);
+    }
     // TODO(paulberry): test initializer
   }
 
@@ -583,14 +735,15 @@
   /**
    * Resynthesize the library element associated with [uri] using
    * [resynthesizer], and verify that it only had to consult one summary in
-   * order to do so.
+   * order to do so.  [original] is consulted merely to verify that no
+   * unnecessary resynthesis work was performed.
    */
   LibraryElementImpl resynthesizeLibraryElement(
-      _TestSummaryResynthesizer resynthesizer, String uri) {
+      _TestSummaryResynthesizer resynthesizer,
+      String uri,
+      LibraryElement original) {
     LibraryElementImpl resynthesized = resynthesizer.getLibraryElement(uri);
-    // Check that no other summaries needed to be resynthesized to resynthesize
-    // the library element.
-    expect(resynthesizer.resynthesisCount, 1);
+    checkMinimalResynthesisWork(resynthesizer, original);
     return resynthesized;
   }
 
@@ -912,6 +1065,369 @@
     checkLibrary('class C {} class D {}');
   }
 
+  test_const_invokeConstructor_named() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+class C {
+  const C.named(bool a, int b, int c, {String d, double e});
+}
+const V = const C.named(true, 1, 2, d: 'ccc', e: 3.4);
+''');
+  }
+
+  test_const_invokeConstructor_named_imported() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {
+  const C.named();
+}
+''');
+    checkLibrary(r'''
+import 'a.dart';
+const V = const C.named();
+''');
+  }
+
+  test_const_invokeConstructor_named_imported_withPrefix() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {
+  const C.named();
+}
+''');
+    checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C.named();
+''');
+  }
+
+  test_const_invokeConstructor_unnamed() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+class C {
+  const C();
+}
+const V = const C();
+''');
+  }
+
+  test_const_invokeConstructor_unnamed_imported() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {
+  const C();
+}
+''');
+    checkLibrary(r'''
+import 'a.dart';
+const V = const C();
+''');
+  }
+
+  test_const_invokeConstructor_unnamed_imported_withPrefix() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {
+  const C();
+}
+''');
+    checkLibrary(r'''
+import 'a.dart' as p;
+const V = const p.C();
+''');
+  }
+
+  test_const_reference_staticField() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+class C {
+  static const int F = 42;
+}
+const V = C.F;
+''');
+  }
+
+  test_const_reference_staticField_imported() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {
+  static const int F = 42;
+}
+''');
+    checkLibrary(r'''
+import 'a.dart';
+const V = C.F;
+''');
+  }
+
+  test_const_reference_staticField_imported_withPrefix() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {
+  static const int F = 42;
+}
+''');
+    checkLibrary(r'''
+import 'a.dart' as p;
+const V = p.C.F;
+''');
+  }
+
+  test_const_reference_staticMethod() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+class C {
+  static int m(int a, String b) => 42;
+}
+const V = C.m;
+''');
+  }
+
+  test_const_reference_staticMethod_imported() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {
+  static int m(int a, String b) => 42;
+}
+''');
+    checkLibrary(r'''
+import 'a.dart';
+const V = C.m;
+''');
+  }
+
+  test_const_reference_staticMethod_imported_withPrefix() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {
+  static int m(int a, String b) => 42;
+}
+''');
+    checkLibrary(r'''
+import 'a.dart' as p;
+const V = p.C.m;
+''');
+  }
+
+  test_const_reference_topLevelVariable() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const A = 1;
+const B = A + 2;
+''');
+  }
+
+  test_const_reference_topLevelVariable_imported() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+const A = 1;
+''');
+    checkLibrary(r'''
+import 'a.dart';
+const B = A + 2;
+''');
+  }
+
+  test_const_reference_topLevelVariable_imported_withPrefix() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+const A = 1;
+''');
+    checkLibrary(r'''
+import 'a.dart' as p;
+const B = p.A + 2;
+''');
+  }
+
+  test_const_reference_type() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+class C {}
+class D<T> {}
+enum E {a, b, c}
+typedef F(int a, String b);
+const vDynamic = dynamic;
+const vNull = Null;
+const vObject = Object;
+const vClass = C;
+const vGenericClass = D;
+const vEnum = E;
+const vFunctionTypeAlias = F;
+''');
+  }
+
+  test_const_reference_type_imported() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {}
+enum E {a, b, c}
+typedef F(int a, String b);
+''');
+    checkLibrary(r'''
+import 'a.dart';
+const vClass = C;
+const vEnum = E;
+const vFunctionTypeAlias = F;
+''');
+  }
+
+  test_const_reference_type_imported_withPrefix() {
+    shouldCompareConstValues = true;
+    addLibrarySource(
+        '/a.dart',
+        r'''
+class C {}
+enum E {a, b, c}
+typedef F(int a, String b);
+''');
+    checkLibrary(r'''
+import 'a.dart' as p;
+const vClass = p.C;
+const vEnum = p.E;
+const vFunctionTypeAlias = p.F;
+''');
+  }
+
+  test_const_topLevel_binary() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const vEqual = 1 == 2;
+const vAnd = true && false;
+const vOr = false || true;
+const vBitXor = 1 ^ 2;
+const vBitAnd = 1 & 2;
+const vBitOr = 1 | 2;
+const vBitShiftLeft = 1 << 2;
+const vBitShiftRight = 1 >> 2;
+const vAdd = 1 + 2;
+const vSubtract = 1 - 2;
+const vMiltiply = 1 * 2;
+const vDivide = 1 / 2;
+const vFloorDivide = 1 ~/ 2;
+const vModulo = 1 % 2;
+const vGreater = 1 > 2;
+const vGreaterEqual = 1 >= 2;
+const vLess = 1 < 2;
+const vLessEqual = 1 <= 2;
+''');
+  }
+
+  test_const_topLevel_conditional() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const vConditional = (1 == 2) ? 11 : 22;
+''');
+  }
+
+  test_const_topLevel_identical() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const vIdentical = (1 == 2) ? 11 : 22;
+''');
+  }
+
+  test_const_topLevel_literal() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const vNull = null;
+const vBoolFalse = false;
+const vBoolTrue = true;
+const vInt = 1;
+const vIntLong = 0x9876543210987654321;
+const vDouble = 2.3;
+const vString = 'abc';
+const vStringConcat = 'aaa' 'bbb';
+const vStringInterpolation = 'aaa ${true} ${42} bbb';
+const vSymbol = #aaa.bbb.ccc;
+''');
+  }
+
+  test_const_topLevel_prefix() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const vNotEqual = 1 != 2;
+const vNot = !true;
+const vNegate = -1;
+const vComplement = ~1;
+''');
+  }
+
+  test_const_topLevel_typedList() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const vNull = const <Null>[];
+const vDynamic = const <dynamic>[1, 2, 3];
+const vInterfaceNoTypeParameters = const <int>[1, 2, 3];
+const vInterfaceNoTypeArguments = const <List>[];
+const vInterfaceWithTypeArguments = const <List<String>>[];
+const vInterfaceWithTypeArguments2 = const <Map<int, List<String>>>[];
+''');
+  }
+
+  test_const_topLevel_typedList_imported() {
+    shouldCompareConstValues = true;
+    addLibrarySource('/a.dart', 'class C {}');
+    checkLibrary(r'''
+import 'a.dart';
+const v = const <C>[];
+''');
+  }
+
+  test_const_topLevel_typedList_importedWithPrefix() {
+    shouldCompareConstValues = true;
+    addLibrarySource('/a.dart', 'class C {}');
+    checkLibrary(r'''
+import 'a.dart' as p;
+const v = const <p.C>[];
+''');
+  }
+
+  test_const_topLevel_typedMap() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const vDynamic1 = const <dynamic, int>{};
+const vDynamic2 = const <int, dynamic>{};
+const vInterface = const <int, String>{};
+const vInterfaceWithTypeArguments = const <int, List<String>>{};
+''');
+  }
+
+  test_const_topLevel_untypedList() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const v = const [1, 2, 3];
+''');
+  }
+
+  test_const_topLevel_untypedMap() {
+    shouldCompareConstValues = true;
+    checkLibrary(r'''
+const v = const {0: 'aaa', 1: 'bbb', 2: 'ccc'};
+''');
+  }
+
   test_constructor_documented() {
     checkLibrary('''
 class C {
@@ -926,8 +1442,8 @@
     String uri = 'dart:core';
     LibraryElementImpl original =
         resolve2(analysisContext2.sourceFactory.forUri(uri));
-    LibraryElementImpl resynthesized =
-        resynthesizeLibraryElement(encodeLibraryElement(original), uri);
+    LibraryElementImpl resynthesized = resynthesizeLibraryElement(
+        encodeLibraryElement(original), uri, original);
     checkLibraryElements(original, resynthesized);
   }
 
@@ -1324,13 +1840,27 @@
         ' abstract class D<U, V> { Map<V, U> get v; }');
   }
 
-  test_inferred_type_via_function_typed_param() {
-    if (options.strongMode) {
-      // TODO(paulberry): get this test to pass.
-      return;
-    }
-    checkLibrary('class C extends D { f(g) {} }'
-        ' abstract class D { void f(int g(String)); }');
+  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)); }');
+  }
+
+  test_inferred_type_refers_to_function_typed_parameter_type_other_lib() {
+    addLibrarySource(
+        '/a.dart', 'import "b.dart"; abstract class D extends E {}');
+    addLibrarySource(
+        '/b.dart', 'abstract class E { void f(int x, int g(String s)); }');
+    checkLibrary('import "a.dart"; class C extends D { void f(int x, g) {} }');
+  }
+
+  test_inferred_type_refers_to_method_function_typed_parameter_type() {
+    checkLibrary('class C extends D { void f(int x, g) {} }'
+        ' abstract class D { void f(int x, int g(String s)); }');
+  }
+
+  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)); }');
   }
 
   test_library() {
@@ -1814,6 +2344,7 @@
     _TestSummaryResynthesizer resynthesizer = encodeLibrary(original.library);
     ElementLocationImpl location = original.location;
     Element result = resynthesizer.getElement(location);
+    checkMinimalResynthesisWork(resynthesizer, original.library);
     // Check that no other summaries needed to be resynthesized to resynthesize
     // the library element.
     expect(resynthesizer.resynthesisCount, 1);
@@ -1826,6 +2357,18 @@
   final Map<String, UnlinkedUnit> unlinkedSummaries;
   final Map<String, LinkedLibrary> linkedSummaries;
 
+  /**
+   * The set of uris for which unlinked summaries have been requested using
+   * [getUnlinkedSummary].
+   */
+  final Set<String> unlinkedSummariesRequested = new Set<String>();
+
+  /**
+   * The set of uris for which linked summaries have been requested using
+   * [getLinkedSummary].
+   */
+  final Set<String> linkedSummariesRequested = new Set<String>();
+
   _TestSummaryResynthesizer(
       SummaryResynthesizer parent,
       AnalysisContext context,
@@ -1838,6 +2381,7 @@
 
   @override
   LinkedLibrary getLinkedSummary(String uri) {
+    linkedSummariesRequested.add(uri);
     LinkedLibrary serializedLibrary = linkedSummaries[uri];
     if (serializedLibrary == null) {
       fail('Unexpectedly tried to get linked summary for $uri');
@@ -1847,6 +2391,7 @@
 
   @override
   UnlinkedUnit getUnlinkedSummary(String uri) {
+    unlinkedSummariesRequested.add(uri);
     UnlinkedUnit serializedUnit = unlinkedSummaries[uri];
     if (serializedUnit == null) {
       fail('Unexpectedly tried to get unlinked summary for $uri');
diff --git a/pkg/analyzer/test/src/summary/summary_common.dart b/pkg/analyzer/test/src/summary/summary_common.dart
index 2122771..868fab4 100644
--- a/pkg/analyzer/test/src/summary/summary_common.dart
+++ b/pkg/analyzer/test/src/summary/summary_common.dart
@@ -375,16 +375,12 @@
     if (!allowTypeParameters) {
       expect(typeRef.typeArguments, isEmpty);
     }
-    checkTypeRefCommonElements(
-        index,
-        absoluteUri,
-        relativeUri,
-        expectedName,
-        expectedKind,
-        expectedTargetUnit,
-        linkedSourceUnit,
-        unlinkedSourceUnit,
-        numTypeParameters);
+    checkReferenceIndex(index, absoluteUri, relativeUri, expectedName,
+        expectedKind: expectedKind,
+        expectedTargetUnit: expectedTargetUnit,
+        linkedSourceUnit: linkedSourceUnit,
+        unlinkedSourceUnit: unlinkedSourceUnit,
+        numTypeParameters: numTypeParameters);
   }
 
   /**
@@ -452,95 +448,20 @@
   }
 
   /**
-   * 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
-   * 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.
-   * [expectedTargetUnit] is the index of the compilation unit in which the
-   * target of the [typeRef] is expected to appear; if not specified it is
-   * assumed to be the defining compilation unit.  [numTypeParameters] is the
-   * number of type parameters of the thing being referred to.
+   * Check the data structures that are reachable from an index in the
+   * references table..  If the reference in question is an explicit
+   * reference, return the [UnlinkedReference] that is used to make the
+   * explicit reference.  If the type reference in question is an implicit
+   * reference, return `null`.
    */
-  void checkTypeRef(EntityRef typeRef, String absoluteUri, String relativeUri,
-      String expectedName,
-      {String expectedPrefix,
-      List<_PrefixExpectation> prefixExpectations,
-      bool allowTypeParameters: false,
-      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
+  UnlinkedReference checkReferenceIndex(int referenceIndex, String absoluteUri,
+      String relativeUri, String expectedName,
+      {ReferenceKind expectedKind: ReferenceKind.classOrEnum,
       int expectedTargetUnit: 0,
       LinkedUnit linkedSourceUnit,
       UnlinkedUnit unlinkedSourceUnit,
       int numTypeParameters: 0}) {
     linkedSourceUnit ??= definingUnit;
-    expect(typeRef, new isInstanceOf<EntityRef>());
-    expect(typeRef.paramReference, 0);
-    int index = typeRef.reference;
-    if (!allowTypeParameters) {
-      expect(typeRef.typeArguments, isEmpty);
-    }
-    UnlinkedReference reference = checkTypeRefCommonElements(
-        index,
-        absoluteUri,
-        relativeUri,
-        expectedName,
-        expectedKind,
-        expectedTargetUnit,
-        linkedSourceUnit,
-        unlinkedSourceUnit,
-        numTypeParameters);
-    expect(reference, isNotNull,
-        reason: 'Unlinked type refs must refer to an explicit reference');
-    if (expectedKind == ReferenceKind.unresolved && !checkAstDerivedData) {
-      // summarize_elements.dart isn't yet able to record the prefix of
-      // unresolved references.  TODO(paulberry): fix this.
-      expect(reference.prefixReference, 0);
-    } else if (expectedPrefix != null) {
-      checkPrefix(reference.prefixReference, expectedPrefix);
-    } else if (prefixExpectations != null) {
-      for (_PrefixExpectation expectation in prefixExpectations) {
-        expect(reference.prefixReference, isNot(0));
-        reference = checkTypeRefCommonElements(
-            reference.prefixReference,
-            expectation.inLibraryDefiningUnit
-                ? null
-                : expectation.absoluteUri ?? absoluteUri,
-            expectation.inLibraryDefiningUnit
-                ? null
-                : expectation.relativeUri ?? relativeUri,
-            expectation.name,
-            expectation.kind,
-            expectedTargetUnit,
-            linkedSourceUnit,
-            unlinkedSourceUnit,
-            expectation.numTypeParameters);
-      }
-      expect(reference.prefixReference, 0);
-    } else {
-      expect(reference.prefixReference, 0);
-    }
-  }
-
-  /**
-   * Check the data structures that are common between [checkTypeRef] and
-   * [checkLinkedTypeRef].  If the type reference in question is an explicit
-   * reference, return the [UnlinkedReference] that is used to make the
-   * explicit reference.  If the type reference in question is an implicit
-   * reference, return `null`.
-   */
-  UnlinkedReference checkTypeRefCommonElements(
-      int referenceIndex,
-      String absoluteUri,
-      String relativeUri,
-      String expectedName,
-      ReferenceKind expectedKind,
-      int expectedTargetUnit,
-      LinkedUnit linkedSourceUnit,
-      UnlinkedUnit unlinkedSourceUnit,
-      int numTypeParameters) {
     unlinkedSourceUnit ??= unlinkedUnits[0];
     LinkedReference referenceResolution =
         linkedSourceUnit.references[referenceIndex];
@@ -587,6 +508,76 @@
   }
 
   /**
+   * 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
+   * 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.
+   * [expectedTargetUnit] is the index of the compilation unit in which the
+   * target of the [typeRef] is expected to appear; if not specified it is
+   * assumed to be the defining compilation unit.  [numTypeParameters] is the
+   * number of type parameters of the thing being referred to.
+   */
+  void checkTypeRef(EntityRef typeRef, String absoluteUri, String relativeUri,
+      String expectedName,
+      {String expectedPrefix,
+      List<_PrefixExpectation> prefixExpectations,
+      bool allowTypeParameters: false,
+      ReferenceKind expectedKind: ReferenceKind.classOrEnum,
+      int expectedTargetUnit: 0,
+      LinkedUnit linkedSourceUnit,
+      UnlinkedUnit unlinkedSourceUnit,
+      int numTypeParameters: 0}) {
+    linkedSourceUnit ??= definingUnit;
+    expect(typeRef, new isInstanceOf<EntityRef>());
+    expect(typeRef.paramReference, 0);
+    int index = typeRef.reference;
+    if (!allowTypeParameters) {
+      expect(typeRef.typeArguments, isEmpty);
+    }
+    UnlinkedReference reference = checkReferenceIndex(
+        index, absoluteUri, relativeUri, expectedName,
+        expectedKind: expectedKind,
+        expectedTargetUnit: expectedTargetUnit,
+        linkedSourceUnit: linkedSourceUnit,
+        unlinkedSourceUnit: unlinkedSourceUnit,
+        numTypeParameters: numTypeParameters);
+    expect(reference, isNotNull,
+        reason: 'Unlinked type refs must refer to an explicit reference');
+    if (expectedKind == ReferenceKind.unresolved && !checkAstDerivedData) {
+      // summarize_elements.dart isn't yet able to record the prefix of
+      // unresolved references.  TODO(paulberry): fix this.
+      expect(reference.prefixReference, 0);
+    } else if (expectedPrefix != null) {
+      checkPrefix(reference.prefixReference, expectedPrefix);
+    } else if (prefixExpectations != null) {
+      for (_PrefixExpectation expectation in prefixExpectations) {
+        expect(reference.prefixReference, isNot(0));
+        reference = checkReferenceIndex(
+            reference.prefixReference,
+            expectation.inLibraryDefiningUnit
+                ? null
+                : expectation.absoluteUri ?? absoluteUri,
+            expectation.inLibraryDefiningUnit
+                ? null
+                : expectation.relativeUri ?? relativeUri,
+            expectation.name,
+            expectedKind: expectation.kind,
+            expectedTargetUnit: expectedTargetUnit,
+            linkedSourceUnit: linkedSourceUnit,
+            unlinkedSourceUnit: unlinkedSourceUnit,
+            numTypeParameters: expectation.numTypeParameters);
+      }
+      expect(reference.prefixReference, 0);
+    } else {
+      expect(reference.prefixReference, 0);
+    }
+  }
+
+  /**
    * Verify that the given [typeRef] represents a reference to an unresolved
    * type.
    */
@@ -1098,12 +1089,12 @@
     expect(executablesMap, hasLength(2));
     {
       UnlinkedPublicName executable = executablesMap['fieldStaticConst'];
-      expect(executable.kind, ReferenceKind.constField);
+      expect(executable.kind, ReferenceKind.propertyAccessor);
       expect(executable.constMembers, isEmpty);
     }
     {
       UnlinkedPublicName executable = executablesMap['methodStaticPublic'];
-      expect(executable.kind, ReferenceKind.staticMethod);
+      expect(executable.kind, ReferenceKind.method);
       expect(executable.constMembers, isEmpty);
     }
   }
@@ -1422,8 +1413,7 @@
     _assertUnlinkedConst(variable.constExpr, operators: [
       UnlinkedConstOperation.pushInt,
       UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.equal,
-      UnlinkedConstOperation.not
+      UnlinkedConstOperation.notEqual
     ], ints: [
       1,
       2
@@ -1562,6 +1552,185 @@
     ]);
   }
 
+  test_constExpr_invokeConstructor_generic_named() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C<K, V> {
+  const C.named();
+}
+const v = const C<int, String>.named();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) {
+        checkTypeRef(r, null, null, 'named',
+            expectedKind: ReferenceKind.constructor,
+            prefixExpectations: [
+              new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+                  numTypeParameters: 2)
+            ],
+            allowTypeParameters: true);
+        checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
+        checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
+      }
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_generic_named_imported() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C<K, V> {
+  const C.named();
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = const C<int, String>.named();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) {
+        checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'named',
+            expectedKind: ReferenceKind.constructor,
+            prefixExpectations: [
+              new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+                  numTypeParameters: 2)
+            ],
+            allowTypeParameters: true);
+        checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
+        checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
+      }
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_generic_named_imported_withPrefix() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C<K, V> {
+  const C.named();
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = const p.C<int, String>.named();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) {
+        checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'named',
+            expectedKind: ReferenceKind.constructor,
+            prefixExpectations: [
+              new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
+                  numTypeParameters: 2),
+              new _PrefixExpectation(ReferenceKind.prefix, 'p',
+                  inLibraryDefiningUnit: true)
+            ],
+            allowTypeParameters: true);
+        checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
+        checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
+      }
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_generic_unnamed() {
+    UnlinkedVariable variable = serializeVariableText('''
+class C<K, V> {
+  const C();
+}
+const v = const C<int, String>();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) {
+        checkTypeRef(r, null, null, 'C',
+            expectedKind: ReferenceKind.classOrEnum,
+            numTypeParameters: 2,
+            allowTypeParameters: true);
+        checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
+        checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
+      }
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_generic_unnamed_imported() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C<K, V> {
+  const C();
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart';
+const v = const C<int, String>();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) {
+        checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
+            expectedKind: ReferenceKind.classOrEnum,
+            numTypeParameters: 2,
+            allowTypeParameters: true);
+        checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
+        checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
+      }
+    ]);
+  }
+
+  test_constExpr_invokeConstructor_generic_unnamed_imported_withPrefix() {
+    addNamedSource(
+        '/a.dart',
+        '''
+class C<K, V> {
+  const C();
+}
+''');
+    UnlinkedVariable variable = serializeVariableText('''
+import 'a.dart' as p;
+const v = const p.C<int, String>();
+''');
+    _assertUnlinkedConst(variable.constExpr, operators: [
+      UnlinkedConstOperation.invokeConstructor,
+    ], ints: [
+      0,
+      0
+    ], referenceValidators: [
+      (EntityRef r) {
+        checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'C',
+            expectedKind: ReferenceKind.classOrEnum,
+            numTypeParameters: 2,
+            allowTypeParameters: true,
+            prefixExpectations: [
+              new _PrefixExpectation(ReferenceKind.prefix, 'p',
+                  inLibraryDefiningUnit: true)
+            ]);
+        checkTypeRef(r.typeArguments[0], 'dart:core', 'dart:core', 'int');
+        checkTypeRef(r.typeArguments[1], 'dart:core', 'dart:core', 'String');
+      }
+    ]);
+  }
+
   test_constExpr_invokeConstructor_named() {
     UnlinkedVariable variable = serializeVariableText('''
 class C {
@@ -1739,7 +1908,7 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
-              expectedKind: ReferenceKind.constField,
+              expectedKind: ReferenceKind.propertyAccessor,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
               ])
@@ -1762,7 +1931,7 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'length',
-              expectedKind: ReferenceKind.constField,
+              expectedKind: ReferenceKind.propertyAccessor,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C',
                     absoluteUri: absUri('/a.dart'), relativeUri: 'a.dart'),
@@ -1802,7 +1971,7 @@
       (EntityRef r) => checkTypeRef(r, null, null, 'length',
               expectedKind: ReferenceKind.length,
               prefixExpectations: [
-                new _PrefixExpectation(ReferenceKind.constField, 'F'),
+                new _PrefixExpectation(ReferenceKind.propertyAccessor, 'F'),
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
               ])
     ]);
@@ -1894,12 +2063,8 @@
 
   test_constExpr_makeSymbol() {
     UnlinkedVariable variable = serializeVariableText('const v = #a.bb.ccc;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
-      UnlinkedConstOperation.pushString,
-      UnlinkedConstOperation.makeSymbol
-    ], strings: [
-      'a.bb.ccc'
-    ]);
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.makeSymbol], strings: ['a.bb.ccc']);
   }
 
   test_constExpr_makeTypedList() {
@@ -2109,45 +2274,25 @@
     ]);
   }
 
-  test_constExpr_pushInt_shiftOr_long() {
+  test_constExpr_pushLongInt() {
     UnlinkedVariable variable =
         serializeVariableText('const v = 0xA123456789ABCDEF012345678;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.shiftOr,
-      UnlinkedConstOperation.shiftOr,
-      UnlinkedConstOperation.shiftOr
-    ], ints: [
-      0xA,
-      0x12345678,
-      0x9ABCDEF0,
-      0x12345678
-    ]);
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushLongInt],
+        ints: [4, 0xA, 0x12345678, 0x9ABCDEF0, 0x12345678]);
   }
 
-  test_constExpr_pushInt_shiftOr_min() {
+  test_constExpr_pushLongInt_min2() {
     UnlinkedVariable variable = serializeVariableText('const v = 0x100000000;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.shiftOr,
-    ], ints: [
-      1,
-      0,
-    ]);
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushLongInt], ints: [2, 1, 0,]);
   }
 
-  test_constExpr_pushInt_shiftOr_min2() {
+  test_constExpr_pushLongInt_min3() {
     UnlinkedVariable variable =
         serializeVariableText('const v = 0x10000000000000000;');
-    _assertUnlinkedConst(variable.constExpr, operators: [
-      UnlinkedConstOperation.pushInt,
-      UnlinkedConstOperation.shiftOr,
-      UnlinkedConstOperation.shiftOr,
-    ], ints: [
-      1,
-      0,
-      0,
-    ]);
+    _assertUnlinkedConst(variable.constExpr,
+        operators: [UnlinkedConstOperation.pushLongInt], ints: [3, 1, 0, 0,]);
   }
 
   test_constExpr_pushNull() {
@@ -2193,7 +2338,7 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'F',
-              expectedKind: ReferenceKind.constField,
+              expectedKind: ReferenceKind.propertyAccessor,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
               ])
@@ -2216,7 +2361,7 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'F',
-              expectedKind: ReferenceKind.constField,
+              expectedKind: ReferenceKind.propertyAccessor,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
               ])
@@ -2239,7 +2384,7 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'F',
-              expectedKind: ReferenceKind.constField,
+              expectedKind: ReferenceKind.propertyAccessor,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
                 new _PrefixExpectation(ReferenceKind.prefix, 'p',
@@ -2259,7 +2404,7 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, null, null, 'm',
-              expectedKind: ReferenceKind.staticMethod,
+              expectedKind: ReferenceKind.method,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
               ])
@@ -2282,7 +2427,7 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'm',
-              expectedKind: ReferenceKind.staticMethod,
+              expectedKind: ReferenceKind.method,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C')
               ])
@@ -2305,7 +2450,7 @@
       UnlinkedConstOperation.pushReference
     ], referenceValidators: [
       (EntityRef r) => checkTypeRef(r, absUri('/a.dart'), 'a.dart', 'm',
-              expectedKind: ReferenceKind.staticMethod,
+              expectedKind: ReferenceKind.method,
               prefixExpectations: [
                 new _PrefixExpectation(ReferenceKind.classOrEnum, 'C'),
                 new _PrefixExpectation(ReferenceKind.prefix, 'p',
@@ -4025,6 +4170,129 @@
     checkLinkedTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int');
   }
 
+  test_inferred_type_refers_to_function_typed_parameter_type_generic_class() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedClass cls = serializeClassText(
+        '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)); }',
+        className: 'C');
+    EntityRef type =
+        getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot);
+    // Check that parameter g's inferred type is the type implied by D.f's 1st
+    // (zero-based) parameter.
+    expect(type.implicitFunctionTypeIndices, [1]);
+    expect(type.paramReference, 0);
+    expect(type.typeArguments, hasLength(2));
+    checkParamTypeRef(type.typeArguments[0], 1);
+    checkTypeRef(type.typeArguments[1], 'dart:core', 'dart:core', 'int');
+    expect(type.reference,
+        greaterThanOrEqualTo(unlinkedUnits[0].references.length));
+    LinkedReference linkedReference =
+        linked.units[0].references[type.reference];
+    expect(linkedReference.dependency, 0);
+    expect(linkedReference.kind, ReferenceKind.method);
+    expect(linkedReference.name, 'f');
+    expect(linkedReference.numTypeParameters, 2);
+    expect(linkedReference.unit, 0);
+    expect(linkedReference.containingReference, isNot(0));
+    expect(linkedReference.containingReference, lessThan(type.reference));
+    checkReferenceIndex(linkedReference.containingReference, null, null, 'D',
+        numTypeParameters: 2);
+  }
+
+  test_inferred_type_refers_to_function_typed_parameter_type_other_lib() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    addNamedSource('/a.dart', 'import "b.dart"; abstract class D extends E {}');
+    addNamedSource(
+        '/b.dart', 'abstract class E { void f(int x, int g(String s)); }');
+    UnlinkedClass cls = serializeClassText(
+        'import "a.dart"; class C extends D { void f(int x, g) {} }');
+    EntityRef type =
+        getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot);
+    // Check that parameter g's inferred type is the type implied by D.f's 1st
+    // (zero-based) parameter.
+    expect(type.implicitFunctionTypeIndices, [1]);
+    expect(type.paramReference, 0);
+    expect(type.typeArguments, isEmpty);
+    expect(type.reference,
+        greaterThanOrEqualTo(unlinkedUnits[0].references.length));
+    LinkedReference linkedReference =
+        linked.units[0].references[type.reference];
+    int expectedDep =
+        checkHasDependency(absUri('/b.dart'), 'b.dart', fullyLinked: true);
+    expect(linkedReference.dependency, expectedDep);
+    expect(linkedReference.kind, ReferenceKind.method);
+    expect(linkedReference.name, 'f');
+    expect(linkedReference.numTypeParameters, 0);
+    expect(linkedReference.unit, 0);
+    expect(linkedReference.containingReference, isNot(0));
+    expect(linkedReference.containingReference, lessThan(type.reference));
+    checkReferenceIndex(
+        linkedReference.containingReference, absUri('/b.dart'), 'b.dart', 'E');
+  }
+
+  test_inferred_type_refers_to_method_function_typed_parameter_type() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedClass cls = serializeClassText(
+        'class C extends D { void f(int x, g) {} }'
+        ' abstract class D { void f(int x, int g(String s)); }',
+        className: 'C');
+    EntityRef type =
+        getTypeRefForSlot(cls.executables[0].parameters[1].inferredTypeSlot);
+    // Check that parameter g's inferred type is the type implied by D.f's 1st
+    // (zero-based) parameter.
+    expect(type.implicitFunctionTypeIndices, [1]);
+    expect(type.paramReference, 0);
+    expect(type.typeArguments, isEmpty);
+    expect(type.reference,
+        greaterThanOrEqualTo(unlinkedUnits[0].references.length));
+    LinkedReference linkedReference =
+        linked.units[0].references[type.reference];
+    expect(linkedReference.dependency, 0);
+    expect(linkedReference.kind, ReferenceKind.method);
+    expect(linkedReference.name, 'f');
+    expect(linkedReference.numTypeParameters, 0);
+    expect(linkedReference.unit, 0);
+    expect(linkedReference.containingReference, isNot(0));
+    expect(linkedReference.containingReference, lessThan(type.reference));
+    checkReferenceIndex(linkedReference.containingReference, null, null, 'D');
+  }
+
+  test_inferred_type_refers_to_setter_function_typed_parameter_type() {
+    if (!strongMode || skipFullyLinkedData) {
+      return;
+    }
+    UnlinkedClass cls = serializeClassText(
+        'class C extends D { void set f(g) {} }'
+        ' abstract class D { void set f(int g(String s)); }',
+        className: 'C');
+    EntityRef type =
+        getTypeRefForSlot(cls.executables[0].parameters[0].inferredTypeSlot);
+    // Check that parameter g's inferred type is the type implied by D.f's 1st
+    // (zero-based) parameter.
+    expect(type.implicitFunctionTypeIndices, [0]);
+    expect(type.paramReference, 0);
+    expect(type.typeArguments, isEmpty);
+    expect(type.reference,
+        greaterThanOrEqualTo(unlinkedUnits[0].references.length));
+    LinkedReference linkedReference =
+        linked.units[0].references[type.reference];
+    expect(linkedReference.dependency, 0);
+    expect(linkedReference.kind, ReferenceKind.propertyAccessor);
+    expect(linkedReference.name, 'f=');
+    expect(linkedReference.numTypeParameters, 0);
+    expect(linkedReference.unit, 0);
+    expect(linkedReference.containingReference, isNot(0));
+    expect(linkedReference.containingReference, lessThan(type.reference));
+    checkReferenceIndex(linkedReference.containingReference, null, null, 'D');
+  }
+
   test_invalid_prefix_dynamic() {
     if (checkAstDerivedData) {
       // TODO(paulberry): get this to work properly.
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index bb8216a..65de58d 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -26,21 +26,19 @@
           Comparator<K> _comparator;
           _Predicate _validKey;
 
-          // Initializing _comparator needs a cast, since K may not always be
-          // Comparable.
-          // Initializing _validKey shouldn't need a cast.  Currently
-          // it requires inference to work because of dartbug.com/23381
+          // TODO(rnystrom): Initializing _comparator should have a cast, since
+          // K may not always be Comparable. It doesn't currently get one
+          // because we're using the spec's LUB on function types, which isn't
+          // sound.
           SplayTreeMap([int compare(K key1, K key2),
                         bool isValidKey(potentialKey)]) {
-            : _comparator = /*warning:DOWN_CAST_COMPOSITE*/(compare == null)
-                           ? Comparable.compare : compare,
-              _validKey = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
-                         ? isValidKey : ((v) => true);
-             _Predicate<Object> _v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
-                                    ? isValidKey : (/*info:INFERRED_TYPE_CLOSURE*/(v) => true);
-        // TODO(leafp): Fix unimplemented LUB in analyzer
-        _v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
-             ? _v : (/*info:INFERRED_TYPE_CLOSURE*/(v) => true);
+            : _comparator = (compare == null) ? Comparable.compare : compare,
+              _validKey = (isValidKey != null) ? isValidKey : ((v) => true);
+             _Predicate<Object> v = /*warning:DOWN_CAST_COMPOSITE*/(isValidKey != null)
+                                    ? isValidKey : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
+
+            v = (isValidKey != null)
+                 ? v : (/*info:INFERRED_TYPE_CLOSURE*/(_) => true);
           }
         }
         void main() {
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 d823b20..eccb4f2 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -1151,7 +1151,8 @@
       ''';
     testChecker('infer downwards', {'/main.dart': code});
 
-    testChecker('infer if value types match context', {'/main.dart': r'''
+    testChecker('infer if value types match context', {
+      '/main.dart': r'''
 class DartType {}
 typedef void Asserter<T>(T type);
 typedef Asserter<T> AsserterBuilder<S, T>(S arg);
@@ -1206,7 +1207,8 @@
   g.assertAOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
   g.assertDOf(/*info:INFERRED_TYPE_LITERAL*/[_isInt, _isString]);
 }
-    '''});
+    '''
+    });
   });
 
   group('downwards inference on function arguments', () {
@@ -1578,10 +1580,116 @@
         main() {
           Iterable<Future<int>> list = <int>[1, 2, 3].map(make);
           Future<List<int>> results = Future.wait(list);
-          Future<String> results2 = results.then((List<int> list) 
+          Future<String> results2 = results.then((List<int> list)
             => list.fold('', (String x, int y) => x + y.toString()));
         }
     '''
     });
+
+    // TODO(jmesserly): we should change how this inference works.
+    // For now this test will cover what we use.
+    testChecker('infer JS builtin', {
+      '/main.dart': '''
+import 'dart:math' as math;
+import 'dart:math' show min;
+
+class C {
+  /*=T*/ m/*<T extends num>*/(/*=T*/ x, /*=T*/ y) => null;
+}
+
+main() {
+  takeIII(math.max);
+  takeDDD(math.max);
+  takeNNN(math.max);
+  takeIDN(math.max);
+  takeDIN(math.max);
+  takeIIN(math.max);
+  takeDDN(math.max);
+  takeIIO(math.max);
+  takeDDO(math.max);
+
+  takeOOI(/*severe:STATIC_TYPE_ERROR*/math.max);
+  takeIDI(/*severe:STATIC_TYPE_ERROR*/math.max);
+  takeDID(/*severe:STATIC_TYPE_ERROR*/math.max);
+
+  takeOON(/*warning:DOWN_CAST_COMPOSITE*/math.max);
+  takeOOO(/*warning:DOWN_CAST_COMPOSITE*/math.max);
+
+  // Also test SimpleIdentifier
+  takeIII(min);
+  takeDDD(min);
+  takeNNN(min);
+  takeIDN(min);
+  takeDIN(min);
+  takeIIN(min);
+  takeDDN(min);
+  takeIIO(min);
+  takeDDO(min);
+
+  takeOOI(/*severe:STATIC_TYPE_ERROR*/min);
+  takeIDI(/*severe:STATIC_TYPE_ERROR*/min);
+  takeDID(/*severe:STATIC_TYPE_ERROR*/min);
+
+  takeOON(/*warning:DOWN_CAST_COMPOSITE*/min);
+  takeOOO(/*warning:DOWN_CAST_COMPOSITE*/min);
+  
+  // Also PropertyAccess
+  takeIII(new C().m);
+  takeDDD(new C().m);
+  takeNNN(new C().m);
+  takeIDN(new C().m);
+  takeDIN(new C().m);
+  takeIIN(new C().m);
+  takeDDN(new C().m);
+  takeIIO(new C().m);
+  takeDDO(new C().m);
+
+  takeOOI(/*severe:STATIC_TYPE_ERROR*/new C().m);
+  takeIDI(/*severe:STATIC_TYPE_ERROR*/new C().m);
+  takeDID(/*severe:STATIC_TYPE_ERROR*/new C().m);
+
+  takeOON(/*warning:DOWN_CAST_COMPOSITE*/new C().m);
+  takeOOO(/*warning:DOWN_CAST_COMPOSITE*/new C().m);
+}
+
+void takeIII(int fn(int a, int b)) {}
+void takeDDD(double fn(double a, double b)) {}
+void takeIDI(int fn(double a, int b)) {}
+void takeDID(double fn(int a, double b)) {}
+void takeIDN(num fn(double a, int b)) {}
+void takeDIN(num fn(int a, double b)) {}
+void takeIIN(num fn(int a, int b)) {}
+void takeDDN(num fn(double a, double b)) {}
+void takeNNN(num fn(num a, num b)) {}
+void takeOON(num fn(Object a, Object b)) {}
+void takeOOO(num fn(Object a, Object b)) {}
+void takeOOI(int fn(Object a, Object b)) {}
+void takeIIO(Object fn(int a, int b)) {}
+void takeDDO(Object fn(double a, double b)) {}
+  '''
+    });
+  });
+
+  // Regression test for https://github.com/dart-lang/dev_compiler/issues/47
+  testChecker('null literal should not infer as bottom', {
+    '/main.dart': '''
+      var h = null;
+      void foo(int f(Object _)) {}
+
+      main() {
+        var f = (x) => null;
+        f = (x) => 'hello';
+
+        var g = null;
+        g = 'hello';
+        (/*info:DYNAMIC_INVOKE*/g.foo());
+
+        h = 'hello';
+        (/*info:DYNAMIC_INVOKE*/h.foo());
+
+        foo(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x) => null);
+        foo(/*info:INFERRED_TYPE_CLOSURE,info:INFERRED_TYPE_CLOSURE*/(x) => throw "not implemented");
+      }
+  '''
   });
 }
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index f386377..5e346d0 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -118,6 +118,14 @@
         num/*=T*/ min/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) => null;
         num/*=T*/ max/*<T extends num>*/(num/*=T*/ a, num/*=T*/ b) => null;
         ''',
+
+  'dart:_foreign_helper': '''
+  library dart._foreign_helper;
+
+  JS(String typeDescription, String codeTemplate,
+    [arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9, arg10, arg11])
+  {}
+  '''
 };
 
 /// Returns an ANSII color escape sequence corresponding to [levelName]. Colors
diff --git a/pkg/analyzer/test/utils.dart b/pkg/analyzer/test/utils.dart
index a8c39a5..863b0ee 100644
--- a/pkg/analyzer/test/utils.dart
+++ b/pkg/analyzer/test/utils.dart
@@ -12,9 +12,9 @@
 import 'package:path/path.dart' as path;
 import 'package:unittest/unittest.dart';
 
-void initializeTestEnvironment() {
+void initializeTestEnvironment([path.Context context]) {
   groupSep = ' | ';
-  JavaFile.pathContext = path.posix;
+  JavaFile.pathContext = context ?? path.posix;
 }
 
 /**
diff --git a/pkg/analyzer/tool/summary/idl.dart b/pkg/analyzer/tool/summary/idl.dart
index cb2ee1d..927cbb3 100644
--- a/pkg/analyzer/tool/summary/idl.dart
+++ b/pkg/analyzer/tool/summary/idl.dart
@@ -108,6 +108,30 @@
   int paramReference;
 
   /**
+   * If this is a reference to a function type implicitly defined by a
+   * function-typed parameter, a list of zero-based indices indicating the path
+   * from the entity referred to by [reference] to the appropriate type
+   * parameter.  Otherwise the empty list.
+   *
+   * If there are N indices in this list, then the entity being referred to is
+   * the function type implicitly defined by a function-typed parameter of a
+   * function-typed parameter, to N levels of nesting.  The first index in the
+   * list refers to the outermost level of nesting; for example if [reference]
+   * refers to the entity defined by:
+   *
+   *     void f(x, void g(y, z, int h(String w))) { ... }
+   *
+   * Then to refer to the function type implicitly defined by parameter `h`
+   * (which is parameter 2 of parameter 1 of `f`), then
+   * [implicitFunctionTypeIndices] should be [1, 2].
+   *
+   * Note that if the entity being referred to is a generic method inside a
+   * generic class, then the type arguments in [typeArguments] are applied
+   * first to the class and then to the method.
+   */
+  List<int> implicitFunctionTypeIndices;
+
+  /**
    * 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.
@@ -142,8 +166,8 @@
  */
 class LinkedExportName {
   /**
-   * Name of the exported entity.  TODO(paulberry): do we include the trailing
-   * '=' for a setter?
+   * Name of the exported entity.  For an exported setter, this name includes
+   * the trailing '='.
    */
   String name;
 
@@ -228,6 +252,9 @@
   /**
    * Index into [LinkedLibrary.dependencies] indicating which imported library
    * declares the entity being referred to.
+   *
+   * Zero if this entity is contained within another entity (e.g. a class
+   * member).
    */
   int dependency;
 
@@ -242,6 +269,9 @@
    * definition of the entity.  As with indices into [LinkedLibrary.units],
    * zero represents the defining compilation unit, and nonzero values
    * represent parts in the order of the corresponding `part` declarations.
+   *
+   * Zero if this entity is contained within another entity (e.g. a class
+   * member).
    */
   int unit;
 
@@ -257,6 +287,19 @@
    * string is "dynamic".  For the pseudo-type `void`, the string is "void".
    */
   String name;
+
+  /**
+   * If this [LinkedReference] doesn't have an associated [UnlinkedReference],
+   * and the entity being referred to is contained within another entity, index
+   * of the containing entity.  This behaves similarly to
+   * [UnlinkedReference.prefixReference], however it is only used for class
+   * members, not for prefixed imports.
+   *
+   * Containing references must always point backward; that is, for all i, if
+   * LinkedUnit.references[i].containingReference != 0, then
+   * LinkedUnit.references[i].containingReference < i.
+   */
+  int containingReference;
 }
 
 /**
@@ -296,14 +339,16 @@
   constructor,
 
   /**
-   * The entity is a static const field.
+   * The entity is a getter or setter inside a class.  Note: this is used in
+   * the case where a constant refers to a static const declared inside a
+   * class.
    */
-  constField,
+  propertyAccessor,
 
   /**
-   * The entity is a static method.
+   * The entity is a method.
    */
-  staticMethod,
+  method,
 
   /**
    * The `length` property access.
@@ -500,27 +545,21 @@
  */
 enum UnlinkedConstOperation {
   /**
-   * Push the value of the n-th constructor argument (where n is obtained from
-   * [UnlinkedConst.ints]) onto the stack.
-   */
-  pushArgument,
-
-  /**
    * Push the next value from [UnlinkedConst.ints] (a 32-bit unsigned integer)
    * onto the stack.
    *
    * Note that Dart supports integers larger than 32 bits; these are
-   * represented by composing 32 bit values using the [shiftOr] operation.
+   * represented by composing 32-bit values using the [pushLongInt] operation.
    */
   pushInt,
 
   /**
-   * Pop the top value off the stack, which should be an integer.  Multiply it
-   * by 2^32, "or" in the next value from [UnlinkedConst.ints] (which is
-   * interpreted as a 32-bit unsigned integer), and push the result back onto
-   * the stack.
+   * Get the number of components from [UnlinkedConst.ints], then do this number
+   * of times the following operations: multiple the current value by 2^32, "or"
+   * it with the next value in [UnlinkedConst.ints]. The initial value is zero.
+   * Push the result into the stack.
    */
-  shiftOr,
+  pushLongInt,
 
   /**
    * Push the next value from [UnlinkedConst.doubles] (a double precision
@@ -554,8 +593,8 @@
   concatenate,
 
   /**
-   * Pop the top value from the stack which should be string, convert it to
-   * a symbol, and push it back onto the stack.
+   * Get the next value from [UnlinkedConst.strings], convert it to a symbol,
+   * and push it onto the stack.
    */
   makeSymbol,
 
@@ -641,12 +680,16 @@
   /**
    * Pop the top 2 values from the stack, evaluate `v1 == v2`, and push the
    * result back onto the stack.
-   *
-   * This is also used to represent `v1 != v2`, by composition with [not].
    */
   equal,
 
   /**
+   * Pop the top 2 values from the stack, evaluate `v1 != v2`, and push the
+   * result back onto the stack.
+   */
+  notEqual,
+
+  /**
    * Pop the top value from the stack, compute its boolean negation, and push
    * the result back onto the stack.
    */
diff --git a/pkg/analyzer_cli/bin/analyzer.dart b/pkg/analyzer_cli/bin/analyzer.dart
index b0a32fe..3172b0f 100644
--- a/pkg/analyzer_cli/bin/analyzer.dart
+++ b/pkg/analyzer_cli/bin/analyzer.dart
@@ -3,14 +3,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:analyzer_cli/src/driver.dart';
+import 'package:analyzer_cli/starter.dart';
 
-
-
-
-/// The entry point for the analyzer.
+/// The entry point for the command-line analyzer.
 void main(List<String> args) {
-  var starter = new Driver();
+  CommandLineStarter starter = new CommandLineStarter();
   starter.start(args);
-  
 }
diff --git a/pkg/analyzer_cli/lib/src/driver.dart b/pkg/analyzer_cli/lib/src/driver.dart
index 19b7af4..30547e6 100644
--- a/pkg/analyzer_cli/lib/src/driver.dart
+++ b/pkg/analyzer_cli/lib/src/driver.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/file_system/file_system.dart' as fileSystem;
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/plugin/options.dart';
+import 'package:analyzer/plugin/resolver_provider.dart';
 import 'package:analyzer/source/analysis_options_provider.dart';
 import 'package:analyzer/source/embedder.dart';
 import 'package:analyzer/source/package_map_provider.dart';
@@ -33,6 +34,7 @@
 import 'package:analyzer_cli/src/analyzer_impl.dart';
 import 'package:analyzer_cli/src/options.dart';
 import 'package:analyzer_cli/src/perf_report.dart';
+import 'package:analyzer_cli/starter.dart';
 import 'package:linter/src/plugin/linter_plugin.dart';
 import 'package:package_config/discovery.dart' as pkgDiscovery;
 import 'package:package_config/packages.dart' show Packages;
@@ -61,7 +63,7 @@
 
 typedef ErrorSeverity _BatchRunnerHandler(List<String> args);
 
-class Driver {
+class Driver implements CommandLineStarter {
   static final PerformanceTag _analyzeAllTag =
       new PerformanceTag("Driver._analyzeAll");
 
@@ -79,17 +81,20 @@
   /// creation.
   CommandLineOptions _previousOptions;
 
+  @override
+  ResolverProvider packageResolverProvider;
+
   /// This Driver's current analysis context.
   ///
   /// *Visible for testing.*
   AnalysisContext get context => _context;
 
-  /// Set the [plugins] that are defined outside the `analyzer_cli` package.
+  @override
   void set userDefinedPlugins(List<Plugin> plugins) {
     _userDefinedPlugins = plugins == null ? <Plugin>[] : plugins;
   }
 
-  /// Use the given command-line [args] to start this analysis driver.
+  @override
   void start(List<String> args) {
     int startTime = new DateTime.now().millisecondsSinceEpoch;
 
@@ -309,6 +314,21 @@
     Map<String, List<fileSystem.Folder>> packageMap;
     UriResolver packageUriResolver;
 
+    // Create a custom package resolver if one has been specified.
+    if (packageResolverProvider != null) {
+      fileSystem.Folder folder =
+          PhysicalResourceProvider.INSTANCE.getResource('.');
+      UriResolver resolver = packageResolverProvider(folder);
+      if (resolver != null) {
+        // TODO(brianwilkerson) This doesn't support either embedder files or sdk extensions.
+        List<UriResolver> resolvers = <UriResolver>[
+          new DartUriResolver(sdk),
+          resolver,
+          new FileUriResolver()
+        ];
+        return new SourceFactory(resolvers);
+      }
+    }
     // Process options, caching package resolution details.
     if (options.packageConfigPath != null) {
       String packageConfigPath = options.packageConfigPath;
@@ -454,6 +474,7 @@
     contextOptions.lint = options.lints;
     contextOptions.strongMode = options.strongMode;
     context.analysisOptions = contextOptions;
+    sourceFactory.dartSdk.context.analysisOptions = contextOptions;
     _context = context;
 
     // Process analysis options file (and notify all interested parties).
diff --git a/pkg/analyzer_cli/lib/starter.dart b/pkg/analyzer_cli/lib/starter.dart
new file mode 100644
index 0000000..a784a75
--- /dev/null
+++ b/pkg/analyzer_cli/lib/starter.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library analyzer_cli.starter;
+
+import 'package:analyzer/plugin/resolver_provider.dart';
+import 'package:analyzer_cli/src/driver.dart';
+import 'package:plugin/plugin.dart';
+
+/**
+ * An object that can be used to start a command-line analysis. This class
+ * exists so that clients can configure a command-line analyzer before starting
+ * it.
+ *
+ * Clients may not extend, implement or mix-in this class.
+ */
+abstract class CommandLineStarter {
+  /**
+   * Initialize a newly created starter to start up a command-line analysis.
+   */
+  factory CommandLineStarter() = Driver;
+
+  /**
+   * Set the package resolver provider used to override the way package URI's
+   * are resolved in some contexts. The provider should return `null` if the
+   * default package resolution scheme should be used instead.
+   */
+  void set packageResolverProvider(ResolverProvider provider);
+
+  /**
+   * Set the [plugins] that are defined outside the analyzer_cli package.
+   */
+  void set userDefinedPlugins(List<Plugin> plugins);
+
+  /**
+   * Use the given command-line [arguments] to start this analyzer.
+   */
+  void start(List<String> arguments);
+}
diff --git a/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/_embedder.yaml b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/_embedder.yaml
index 5253771..64fc9ed 100644
--- a/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/_embedder.yaml
+++ b/pkg/analyzer_cli/test/data/package_with_embedder_yaml/lib/_embedder.yaml
@@ -1,4 +1,4 @@
-embedder_libs:
+embedded_libs:
   "dart:bear": "grizzly.dart"
   "dart:core": "core.dart"
   "dart:async": "async.dart"
diff --git a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
index f98c9dd..37dc74b 100644
--- a/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
+++ b/pkg/compiler/lib/src/cps_ir/cps_ir_builder_task.dart
@@ -2198,7 +2198,17 @@
 
     List<ir.Primitive> arguments = argumentsNode.nodes.mapToList(visit);
     // Use default values from the effective target, not the immediate target.
-    ConstructorElement target = constructor.implementation;
+    ConstructorElement target;
+    if (constructor == compiler.symbolConstructor) {
+      // The Symbol constructor should perform validation of its argument
+      // which is not expressible as a Dart const constructor.  Instead, the
+      // libraries contain a dummy const constructor implementation that
+      // doesn't perform validation and the compiler compiles a call to
+      // (non-const) Symbol.validated when it sees new Symbol(...).
+      target = compiler.symbolValidatedConstructor;
+    } else {
+      target = constructor.implementation;
+    }
     while (target.isRedirectingFactory && !target.isCyclicRedirection) {
       target = target.effectiveTarget.implementation;
     }
diff --git a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
index 42ae6cd..298a082 100644
--- a/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
+++ b/pkg/compiler/lib/src/cps_ir/shrinking_reductions.dart
@@ -132,8 +132,6 @@
       case _ReductionKind.BRANCH:
         _reduceBranch(task);
         break;
-      default:
-        assert(false);
     }
   }
 
@@ -547,11 +545,15 @@
       falseInvoke.continuation.definition) {
     return false;
   }
-  assert(trueInvoke.arguments.length == falseInvoke.arguments.length);
   // Matching zero arguments should be adequate, since isomorphic true and false
   // invocations should result in redundant phis which are removed elsewhere.
-  if (trueInvoke.arguments.isNotEmpty) return false;
-  return true;
+  //
+  // Note that the argument lists are not necessarily the same length here,
+  // because we could be looking for new redexes in the middle of performing a
+  // dead parameter reduction, where some but not all of the invocations have
+  // been rewritten.  In that case, we will find the redex (once) after both
+  // of these invocations have been rewritten.
+  return trueInvoke.arguments.isEmpty && falseInvoke.arguments.isEmpty;
 }
 
 bool _isDeadParameter(Parameter parameter) {
@@ -638,6 +640,10 @@
     node.parent = null;
   }
 
+  void processBranch(Branch node) {
+    node.parent = null;
+  }
+
   void processReference(Reference reference) {
     reference.unlink();
 
diff --git a/pkg/compiler/lib/src/cps_ir/type_propagation.dart b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
index 6277667..f1944ce 100644
--- a/pkg/compiler/lib/src/cps_ir/type_propagation.dart
+++ b/pkg/compiler/lib/src/cps_ir/type_propagation.dart
@@ -2275,6 +2275,44 @@
     }
     return null;
   }
+
+  visitReadTypeVariable(ReadTypeVariable node) {
+    // Pattern match on
+    //
+    //    ReadTypeVariable(var, CreateInstance(..., TypeExpression(arguments)))
+    //
+    // and extract the argument that corresponds to the type variable. This is a
+    // shrinking reduction.
+    //
+    // TODO(sra): This is a shrinking reduction that does not depend on inferred
+    // types so it should be done in the shrinking reductions pass.
+    //
+    // TODO(sra): A non-shrinking version of this rewrite could be done as part
+    // of scalar replacement.
+
+    if (node.target.definition is CreateInstance) {
+      CreateInstance instance = node.target.definition;
+      if (instance.typeInformation != null &&
+          instance.typeInformation.definition is TypeExpression) {
+        TypeExpression typeExpression = instance.typeInformation.definition;
+        assert(typeExpression.kind == TypeExpressionKind.INSTANCE);
+        ClassElement context = node.variable.element.enclosingClass;
+        // In the general case, a substitution could generate a large type
+        // term. Avoid this by restricting to direct indexing.
+        // TODO(sra): Also include cases that require substitution but the end
+        // result is the same as some indexing or a simple constant type.
+        if (!functionCompiler.glue.needsSubstitutionForTypeVariableAccess(
+                context)) {
+          int index = functionCompiler.glue.getTypeVariableIndex(node.variable);
+          if (0 <= index && index < typeExpression.arguments.length) {
+            node.replaceUsesWith(typeExpression.arguments[index].definition);
+            return new CpsFragment();
+          }
+        }
+      }
+    }
+    return null;
+  }
 }
 
 /**
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 65d0519..11826c3 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -252,10 +252,9 @@
   }
 
   js.Statement buildDeferredInitializerGlobal() {
-    String global = deferredInitializersGlobal;
-    return js.js.statement(
-        "if (typeof($global) === 'undefined') var # = Object.create(null);",
-        new js.VariableDeclaration(global, allowRename: false));
+    return js.js.statement('self.#deferredInitializers = '
+        'self.#deferredInitializers || Object.create(null);',
+        {'deferredInitializers': deferredInitializersGlobal});
   }
 
   // Writes the given [fragment]'s [code] into a file.
diff --git a/pkg/compiler/lib/src/native/native.dart b/pkg/compiler/lib/src/native/native.dart
index ad88cbe..487832b 100644
--- a/pkg/compiler/lib/src/native/native.dart
+++ b/pkg/compiler/lib/src/native/native.dart
@@ -63,6 +63,8 @@
   String libraryName = library.canonicalUri.toString();
   if (library.entryCompilationUnit.script.name.contains(
           'sdk/tests/compiler/dart2js_native')
+      || library.entryCompilationUnit.script.name.contains(
+          'sdk/tests/compiler/dart2js_extra')
       || libraryName == 'dart:async'
       || libraryName == 'dart:html'
       || libraryName == 'dart:html_common'
diff --git a/pkg/dart_messages/bin/message_id.dart b/pkg/dart_messages/bin/message_id.dart
index f94b384..7d59fbd 100644
--- a/pkg/dart_messages/bin/message_id.dart
+++ b/pkg/dart_messages/bin/message_id.dart
@@ -30,6 +30,6 @@
   var newId;
   do {
     newId = computeId();
-  } while (!usedIds.contains(newId));
+  } while (usedIds.contains(newId));
   print("Available id: $newId");
 }
diff --git a/pkg/pkg.status b/pkg/pkg.status
index 4f93259..d6170c0 100644
--- a/pkg/pkg.status
+++ b/pkg/pkg.status
@@ -70,6 +70,7 @@
 analyzer/test/generated/utilities_test: Pass, Slow # Issue 21628
 analyzer/test/src/context/cache_test: Pass, Slow # Issue 21628
 analyzer/test/src/context/context_test: Pass, Timeout # dartbug.com/23658
+analyzer/test/src/dart/ast/utilities_test: Pass, Slow # Issue 24914
 analyzer/test/src/dart/element/element_test: Pass, Slow # Issue 24914
 analyzer/test/src/summary/prelinker_test: Pass, Slow # Issue 24914
 analyzer/test/src/summary/resynthesize_strong_test: Pass, Slow
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index b6d6ac1..adf0aa4 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -10,9 +10,9 @@
 
 resources_sources_gypi =
     exec_script("../../tools/gypi_to_gn.py",
-                [rebase_path("resources_sources.gypi")],
+                [rebase_path("vmservice/vmservice_sources.gypi")],
                 "scope",
-                ["resources_sources.gypi"])
+                ["vmservice/vmservice_sources.gypi"])
 
 # Generate a resources.cc file for the service isolate without Observatory.
 action("gen_resources_cc") {
@@ -21,7 +21,11 @@
   inputs = [
     "../tools/create_resources.py",
   ]
-  sources = resources_sources_gypi.sources
+  # The path below is hard coded for the Mojo and Flutter trees. When moving
+  # the Dart runtime to gn, this path might need to be updated.
+  sources = rebase_path(resources_sources_gypi.sources,
+                        "",
+                        "//dart/runtime/bin/vmservice/")
   outputs = [ "$target_gen_dir/resources_gen.cc" ]
   args = [
     "--output",
diff --git a/runtime/bin/bin.gypi b/runtime/bin/bin.gypi
index 11f84fc..fa81489 100644
--- a/runtime/bin/bin.gypi
+++ b/runtime/bin/bin.gypi
@@ -515,7 +515,7 @@
       'type': 'none',
       'toolsets':['host'],
       'includes': [
-        'resources_sources.gypi',
+        'vmservice/vmservice_sources.gypi',
       ],
       'actions': [
         {
@@ -546,7 +546,7 @@
       'type': 'none',
       'toolsets':['host'],
       'includes': [
-        'resources_sources.gypi',
+        'vmservice/vmservice_sources.gypi',
       ],
       'actions': [
         {
diff --git a/runtime/bin/builtin.dart b/runtime/bin/builtin.dart
index f162bcb..9a34b51 100644
--- a/runtime/bin/builtin.dart
+++ b/runtime/bin/builtin.dart
@@ -123,11 +123,18 @@
 
 // A class wrapping the load error message in an Error object.
 class _LoadError extends Error {
+  final _LoadRequest request;
   final String message;
-  final String uri;
-  _LoadError(this.uri, this.message);
+  _LoadError(this.request, this.message);
 
-  String toString() => 'Load Error for "$uri": $message';
+  String toString() {
+    var context = request._context;
+    if (context == null || context is! String) {
+      return 'Could not load "${request._uri}": $message';
+    } else {
+      return 'Could not import "${request._uri}" from "$context": $message';
+    }
+  }
 }
 
 // Class collecting all of the information about a particular load request.
@@ -372,13 +379,13 @@
       _finishLoadRequest(req);
     } else {
       assert(dataOrError is String);
-      var error = new _LoadError(req._uri, dataOrError.toString());
+      var error = new _LoadError(req, dataOrError.toString());
       _asyncLoadError(req, error, null);
     }
   } catch(e, s) {
     // Wrap inside a _LoadError unless we are already propagating a
     // previous _LoadError.
-    var error = (e is _LoadError) ? e : new _LoadError(req._uri, e.toString());
+    var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
     assert(req != null);
     _asyncLoadError(req, error, s);
   }
@@ -576,11 +583,12 @@
     if (_traceLoading) {
       _log("Exception when communicating with service isolate: $e");
     }
+    // Register a dummy load request so we can fail to load it.
+    var req = new _LoadRequest(tag, uri, resourceUri, context);
+
     // Wrap inside a _LoadError unless we are already propagating a previously
     // seen _LoadError.
-    var error = (e is _LoadError) ? e : new _LoadError(uri, e.toString());
-    // Register a dummy load request and fail to load it.
-    var req = new _LoadRequest(tag, uri, resourceUri, context);
+    var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
     _asyncLoadError(req, error, s);
   }
 }
@@ -597,11 +605,12 @@
       if (_traceLoading) {
         _log("Exception ($e) when resolving package URI: $resourceUri");
       }
+      // Register a dummy load request so we can fail to load it.
+      var req = new _LoadRequest(tag, uri, resourceUri, context);
+
       // Wrap inside a _LoadError unless we are already propagating a previously
       // seen _LoadError.
-      var error = (e is _LoadError) ? e : new _LoadError(uri, e.toString());
-      // Register a dummy load request and fail to load it.
-      var req = new _LoadRequest(tag, uri, resourceUri, context);
+      var error = (e is _LoadError) ? e : new _LoadError(req, e.toString());
       _asyncLoadError(req, error, s);
     }
     _loadData(tag, uri, resolvedUri, context);
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 0e12574..e15e49c 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -449,7 +449,7 @@
   if (Dart_IsError(source)) {
     return source;
   }
-  return Dart_LoadScript(resolved_script_uri, source, 0, 0);
+  return Dart_LoadLibrary(resolved_script_uri, source, 0, 0);
 }
 
 
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index ec70232..86d2d5d 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -107,12 +107,12 @@
   V(SecureSocket_RegisterHandshakeCompleteCallback, 2)                         \
   V(SecureSocket_Renegotiate, 4)                                               \
   V(SecurityContext_Allocate, 1)                                               \
-  V(SecurityContext_UsePrivateKey, 3)                                          \
+  V(SecurityContext_UsePrivateKeyBytes, 3)                                     \
   V(SecurityContext_SetAlpnProtocols, 3)                                       \
   V(SecurityContext_SetClientAuthorities, 2)                                   \
   V(SecurityContext_SetTrustedCertificates, 3)                                 \
   V(SecurityContext_TrustBuiltinRoots, 1)                                      \
-  V(SecurityContext_UseCertificateChain, 2)                                    \
+  V(SecurityContext_UseCertificateChainBytes, 2)                               \
   V(ServerSocket_Accept, 2)                                                    \
   V(ServerSocket_CreateBindListen, 6)                                          \
   V(Socket_CreateConnect, 3)                                                   \
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 5e57327..ee655d2 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -425,6 +425,8 @@
   }
 
   vm_options->AddArgument("--pause-isolates-on-exit");
+  vm_options->AddArgument("--pause-isolates-on-unhandled-exceptions");
+  vm_options->AddArgument("--warn-on-pause-with-no-debugger");
   return true;
 }
 
@@ -860,9 +862,11 @@
 "--packages=<path>\n"
 "  Where to find a package spec file.\n"
 "--observe[=<port>[/<bind-address>]]\n"
-"  Enable the VM service and cause isolates to pause on exit (default port is\n"
-"  8181, default bind address is 127.0.0.1). With the default options,\n"
-"  Observatory will be available locally at http://127.0.0.1:8181/\n"
+"  The observe flag is used to run a program with a default set of options\n"
+"  for debugging under Observatory. With the default options, Observatory\n"
+"  will be available at http://127.0.0.1:8181/ (default port is 8181,\n"
+"  default bind address is 127.0.0.1).  Isolates will pause at exit and\n"
+"  when they throw unhandled exceptions.\n"
 "--version\n"
 "  Print the VM version.\n");
   } else {
@@ -878,9 +882,11 @@
 "--packages=<path>\n"
 "  Where to find a package spec file.\n"
 "--observe[=<port>[/<bind-address>]]\n"
-"  Enable the VM service and cause isolates to pause on exit (default port is\n"
-"  8181, default bind address is 127.0.0.1). With the default options,\n"
-"  Observatory will be available locally at http://127.0.0.1:8181/\n"
+"  The observe flag is used to run a program with a default set of options\n"
+"  for debugging under Observatory. With the default options, Observatory\n"
+"  will be available at http://127.0.0.1:8181/ (default port is 8181,\n"
+"  default bind address is 127.0.0.1).  Isolates will pause at exit and\n"
+"  when they throw unhandled exceptions.\n"
 "--version\n"
 "  Print the VM version.\n"
 "\n"
@@ -890,9 +896,9 @@
 "--trace-loading\n"
 "  enables tracing of library and script loading\n"
 "\n"
-"--enable-vm-service[:<port number>]\n"
+"--enable-vm-service[:<port>[/<bind-address>]]\n"
 "  enables the VM service and listens on specified port for connections\n"
-"  (default port number is 8181)\n"
+"  (default port number is 8181, default bind address is 127.0.0.1).\n"
 "\n"
 "The following options are only used for VM development and may\n"
 "be changed in any future version:\n");
diff --git a/runtime/bin/resources_sources.gypi b/runtime/bin/resources_sources.gypi
deleted file mode 100644
index 91e0255..0000000
--- a/runtime/bin/resources_sources.gypi
+++ /dev/null
@@ -1,14 +0,0 @@
-# Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
-# for details. All rights reserved. Use of this source code is governed by a
-# BSD-style license that can be found in the LICENSE file.
-
-# This file contains all sources for the Resources table.
-{
-  'sources': [
-# Standalone VM service sources.
-    'vmservice/loader.dart',
-    'vmservice/server.dart',
-    'vmservice/vmservice_io.dart',
-  ],
-}
-
diff --git a/runtime/bin/secure_socket.cc b/runtime/bin/secure_socket.cc
index b1be87c..7f62fcf 100644
--- a/runtime/bin/secure_socket.cc
+++ b/runtime/bin/secure_socket.cc
@@ -376,16 +376,17 @@
 }
 
 
-void FUNCTION_NAME(SecurityContext_UsePrivateKey)(Dart_NativeArguments args) {
+void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
+    Dart_NativeArguments args) {
   SSL_CTX* context = GetSecurityContext(args);
-  Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
-  const char* filename = NULL;
-  if (Dart_IsString(filename_object)) {
-    ThrowIfError(Dart_StringToCString(filename_object, &filename));
-  } else {
+
+  Dart_Handle key_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
+  if (!Dart_IsTypedData(key_object) && !Dart_IsList(key_object)) {
     Dart_ThrowException(DartUtils::NewDartArgumentError(
-        "File argument to SecurityContext.usePrivateKey is not a String"));
+        "keyBytes argument to SecurityContext.usePrivateKeyBytes "
+        "is not a List<int>"));
   }
+
   Dart_Handle password_object = ThrowIfError(Dart_GetNativeArgument(args, 2));
   const char* password = NULL;
   if (Dart_IsString(password_object)) {
@@ -402,16 +403,45 @@
         "SecurityContext.usePrivateKey password is not a String or null"));
   }
 
-  SSL_CTX_set_default_passwd_cb(context, PasswordCallback);
-  SSL_CTX_set_default_passwd_cb_userdata(context, const_cast<char*>(password));
-  int status = SSL_CTX_use_PrivateKey_file(context,
-                                           filename,
-                                           SSL_FILETYPE_PEM);
+  uint8_t* key_bytes = NULL;
+  intptr_t key_bytes_len = 0;
+  bool is_typed_data = false;
+  if (Dart_IsTypedData(key_object)) {
+    is_typed_data = true;
+    Dart_TypedData_Type typ;
+    ThrowIfError(Dart_TypedDataAcquireData(
+        key_object,
+        &typ,
+        reinterpret_cast<void**>(&key_bytes),
+        &key_bytes_len));
+  } else {
+    ASSERT(Dart_IsList(key_object));
+    ThrowIfError(Dart_ListLength(key_object, &key_bytes_len));
+    key_bytes = new uint8_t[key_bytes_len];
+    Dart_Handle err =
+        Dart_ListGetAsBytes(key_object, 0, key_bytes, key_bytes_len);
+    if (Dart_IsError(err)) {
+      delete[] key_bytes;
+      Dart_PropagateError(err);
+    }
+  }
+  ASSERT(key_bytes != NULL);
+
+  BIO* bio = BIO_new_mem_buf(key_bytes, key_bytes_len);
+  EVP_PKEY *key = PEM_read_bio_PrivateKey(
+      bio, NULL, PasswordCallback, const_cast<char*>(password));
+  int status = SSL_CTX_use_PrivateKey(context, key);
+  BIO_free(bio);
+  if (is_typed_data) {
+    ThrowIfError(Dart_TypedDataReleaseData(key_object));
+  } else {
+    delete[] key_bytes;
+  }
+
   // TODO(24184): Handle different expected errors here - file missing,
   // incorrect password, file not a PEM, and throw exceptions.
   // CheckStatus should also throw an exception in uncaught cases.
-  CheckStatus(status, "TlsException", "Failure in usePrivateKey");
-  SSL_CTX_set_default_passwd_cb_userdata(context, NULL);
+  CheckStatus(status, "TlsException", "Failure in usePrivateKeyBytes");
 }
 
 
@@ -459,22 +489,111 @@
 }
 
 
-void FUNCTION_NAME(SecurityContext_UseCertificateChain)(
+static int UseChainBytes(
+    SSL_CTX* context, uint8_t* chain_bytes, intptr_t chain_bytes_len) {
+  int status = 0;
+  BIO* bio = BIO_new_mem_buf(chain_bytes, chain_bytes_len);
+  if (bio == NULL) {
+    return 0;
+  }
+
+  X509* x509 = PEM_read_bio_X509_AUX(bio, NULL, NULL, NULL);
+  if (x509 == NULL) {
+    BIO_free(bio);
+    return 0;
+  }
+
+  status = SSL_CTX_use_certificate(context, x509);
+  if (ERR_peek_error() != 0) {
+    // Key/certificate mismatch doesn't imply status is 0.
+    status = 0;
+  }
+  if (status == 0) {
+    X509_free(x509);
+    BIO_free(bio);
+    return status;
+  }
+
+  SSL_CTX_clear_chain_certs(context);
+
+  while (true) {
+    X509* ca = PEM_read_bio_X509(bio, NULL, NULL, NULL);
+    if (ca == NULL) {
+      break;
+    }
+    status = SSL_CTX_add0_chain_cert(context, ca);
+    if (status == 0) {
+      X509_free(ca);
+      X509_free(x509);
+      BIO_free(bio);
+      return status;
+    }
+    // Note that we must not free `ca` if it was successfully added to the
+    // chain. We must free the main certificate x509, though since its reference
+    // count is increased by SSL_CTX_use_certificate.
+  }
+
+  uint32_t err = ERR_peek_last_error();
+  if ((ERR_GET_LIB(err) == ERR_LIB_PEM) &&
+      (ERR_GET_REASON(err) == PEM_R_NO_START_LINE)) {
+    // Reached the end of the buffer.
+    ERR_clear_error();
+  } else {
+    // Some real error happened.
+    status = 0;
+  }
+
+  X509_free(x509);
+  BIO_free(bio);
+  return status;
+}
+
+
+void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
     Dart_NativeArguments args) {
   SSL_CTX* context = GetSecurityContext(args);
-  Dart_Handle filename_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
-  const char* filename = NULL;
-  if (Dart_IsString(filename_object)) {
-    ThrowIfError(Dart_StringToCString(filename_object, &filename));
-  } else {
+
+  Dart_Handle chain_object = ThrowIfError(Dart_GetNativeArgument(args, 1));
+  if (!Dart_IsTypedData(chain_object) && !Dart_IsList(chain_object)) {
     Dart_ThrowException(DartUtils::NewDartArgumentError(
-        "file argument in SecurityContext.useCertificateChain"
-        " is not a String"));
+        "chainBytes argument to SecurityContext.useCertificateChainBytes "
+        "is not a List<int>"));
   }
-  int status = SSL_CTX_use_certificate_chain_file(context, filename);
+
+  uint8_t* chain_bytes = NULL;
+  intptr_t chain_bytes_len = 0;
+  bool is_typed_data = false;
+  if (Dart_IsTypedData(chain_object)) {
+    is_typed_data = true;
+    Dart_TypedData_Type typ;
+    ThrowIfError(Dart_TypedDataAcquireData(
+        chain_object,
+        &typ,
+        reinterpret_cast<void**>(&chain_bytes),
+        &chain_bytes_len));
+  } else {
+    ASSERT(Dart_IsList(chain_object));
+    ThrowIfError(Dart_ListLength(chain_object, &chain_bytes_len));
+    chain_bytes = new uint8_t[chain_bytes_len];
+    Dart_Handle err =
+        Dart_ListGetAsBytes(chain_object, 0, chain_bytes, chain_bytes_len);
+    if (Dart_IsError(err)) {
+      delete[] chain_bytes;
+      Dart_PropagateError(err);
+    }
+  }
+  ASSERT(chain_bytes != NULL);
+
+  int status = UseChainBytes(context, chain_bytes, chain_bytes_len);
+
+  if (is_typed_data) {
+    ThrowIfError(Dart_TypedDataReleaseData(chain_object));
+  } else {
+    delete[] chain_bytes;
+  }
   CheckStatus(status,
               "TlsException",
-              "Failure in useCertificateChain");
+              "Failure in useCertificateChainBytes");
 }
 
 
diff --git a/runtime/bin/secure_socket_patch.dart b/runtime/bin/secure_socket_patch.dart
index 8d0b6bc..8ba0117 100644
--- a/runtime/bin/secure_socket_patch.dart
+++ b/runtime/bin/secure_socket_patch.dart
@@ -137,12 +137,22 @@
   static final SecurityContext defaultContext =
       new _SecurityContext().._trustBuiltinRoots();
 
-  void usePrivateKey(String keyFile, {String password})
-      native "SecurityContext_UsePrivateKey";
+  Future usePrivateKey(String keyFile, {String password}) {
+    return (new File(keyFile)).readAsBytes().then((bytes) {
+      usePrivateKeyBytes(bytes, password: password);
+    });
+  }
+  void usePrivateKeyBytes(List<int> keyBytes, {String password})
+      native "SecurityContext_UsePrivateKeyBytes";
   void setTrustedCertificates({String file, String directory})
       native "SecurityContext_SetTrustedCertificates";
-  void useCertificateChain(String file)
-      native "SecurityContext_UseCertificateChain";
+  Future useCertificateChain(String chainFile) {
+    return (new File(chainFile)).readAsBytes().then((bytes) {
+      useCertificateChainBytes(bytes);
+    });
+  }
+  void useCertificateChainBytes(List<int> chainBytes)
+      native "SecurityContext_UseCertificateChainBytes";
   void setClientAuthorities(String file)
       native "SecurityContext_SetClientAuthorities";
   void setAlpnProtocols(List<String> protocols, bool isServer) {
@@ -178,4 +188,4 @@
   }
   int _startValidity() native "X509_StartValidity";
   int _endValidity() native "X509_EndValidity";
-}
\ No newline at end of file
+}
diff --git a/runtime/bin/secure_socket_unsupported.cc b/runtime/bin/secure_socket_unsupported.cc
index 6bcc55e..a4df288 100644
--- a/runtime/bin/secure_socket_unsupported.cc
+++ b/runtime/bin/secure_socket_unsupported.cc
@@ -104,7 +104,8 @@
       "Secure Sockets unsupported on this platform"));
 }
 
-void FUNCTION_NAME(SecurityContext_UsePrivateKey)(Dart_NativeArguments args) {
+void FUNCTION_NAME(SecurityContext_UsePrivateKeyBytes)(
+    Dart_NativeArguments args) {
   Dart_ThrowException(DartUtils::NewDartArgumentError(
       "Secure Sockets unsupported on this platform"));
 }
@@ -133,7 +134,7 @@
       "Secure Sockets unsupported on this platform"));
 }
 
-void FUNCTION_NAME(SecurityContext_UseCertificateChain)(
+void FUNCTION_NAME(SecurityContext_UseCertificateChainBytes)(
     Dart_NativeArguments args) {
   Dart_ThrowException(DartUtils::NewDartArgumentError(
       "Secure Sockets unsupported on this platform"));
diff --git a/runtime/bin/socket.cc b/runtime/bin/socket.cc
index b0b6a34..596aa66 100644
--- a/runtime/bin/socket.cc
+++ b/runtime/bin/socket.cc
@@ -566,7 +566,9 @@
   } else if (new_socket == ServerSocket::kTemporaryFailure) {
     Dart_SetReturnValue(args, Dart_False());
   } else {
-    Dart_SetReturnValue(args, DartUtils::NewDartOSError());
+    Dart_Handle err = DartUtils::NewDartOSError();
+    if (Dart_IsError(err)) Dart_PropagateError(err);
+    Dart_SetReturnValue(args, err);
   }
 }
 
diff --git a/runtime/bin/vmservice/loader.dart b/runtime/bin/vmservice/loader.dart
index 9b7355e..7bec4a1 100644
--- a/runtime/bin/vmservice/loader.dart
+++ b/runtime/bin/vmservice/loader.dart
@@ -57,8 +57,7 @@
     _sendResourceResponse(sp, id, data);
   },
   onError: (e) {
-    var err = "Error loading $uri:\n  $e";
-    _sendResourceResponse(sp, id, err);
+    _sendResourceResponse(sp, id, e.toString());
   });
 }
 
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index 69e9b2e..c8334da 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -157,7 +157,6 @@
             '${request.uri}\n$e\n');
       rethrow;
     }
-
   }
 
   Future startup() {
@@ -166,26 +165,29 @@
       return new Future.value(this);
     }
 
+    var address = new InternetAddress(_ip);
     // Startup HTTP server.
-    return HttpServer.bind(_ip, _port).then((s) {
+    return HttpServer.bind(address, _port).then((s) {
       _server = s;
-      _server.listen(_requestHandler);
+      _server.listen(_requestHandler, cancelOnError: true);
       var ip = _server.address.address.toString();
+      var port = _server.port.toString();
       if (_displayMessages) {
-        var port = _server.port.toString();
         print('Observatory listening on http://$ip:$port');
       }
       // Server is up and running.
       _notifyServerState(ip, _server.port);
+      onServerAddressChange('http://$ip:$port');
       return this;
     }).catchError((e, st) {
       print('Could not start Observatory HTTP server:\n$e\n$st\n');
       _notifyServerState("", 0);
+      onServerAddressChange(null);
       return this;
     });
   }
 
-  close(bool force) {
+  Future cleanup(bool force) {
     if (_server == null) {
       return new Future.value(null);
     }
@@ -204,17 +206,19 @@
     // Shutdown HTTP server and subscription.
     var ip = _server.address.address.toString();
     var port = _server.port.toString();
-    return close(forced).then((_) {
+    return cleanup(forced).then((_) {
       if (_displayMessages) {
         print('Observatory no longer listening on http://$ip:$port');
       }
       _server = null;
       _notifyServerState("", 0);
+      onServerAddressChange(null);
       return this;
     }).catchError((e, st) {
       _server = null;
       print('Could not shutdown Observatory HTTP server:\n$e\n$st\n');
       _notifyServerState("", 0);
+      onServerAddressChange(null);
       return this;
     });
   }
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index 3816aa2..ba82441 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -21,45 +21,40 @@
 bool _autoStart;
 
 bool _isWindows = false;
-
 var _signalWatch;
 var _signalSubscription;
 
 // HTTP server.
 Server server;
 Future<Server> serverFuture;
-HashMap<String, Asset> _assets;
-HashMap<String, Asset> get assets {
-  if (_assets == null) {
-    try {
-      _assets = Asset.request();
-    } catch (e) {
-      print('Could not load Observatory assets: $e');
-    }
-  }
-  return _assets;
-}
 
-_onShutdown() {
+_lazyServerBoot() {
   if (server != null) {
-    server.close(true).catchError((e, st) {
-      print("Error in vm-service shutdown: $e\n$st\n");
-    });
+    return;
   }
-  if (_signalSubscription != null) {
-    _signalSubscription.cancel();
-    _signalSubscription = null;
-  }
-}
-
-_bootServer() {
   // Lazily create service.
   var service = new VMService();
-  service.onShutdown = _onShutdown;
   // Lazily create server.
   server = new Server(service, _ip, _port);
 }
 
+Future cleanupCallback() async {
+  // Cancel the sigquit subscription.
+  if (_signalSubscription != null) {
+    await _signalSubscription.cancel();
+    _signalSubscription = null;
+  }
+  if (server != null) {
+    try {
+      await server.cleanup(true);
+    } catch (e, st) {
+      print("Error in vm-service shutdown: $e\n$st\n");
+    }
+  }
+  // Call out to embedder's shutdown callback.
+  _shutdown();
+}
+
 _clearFuture(_) {
   serverFuture = null;
 }
@@ -69,9 +64,7 @@
     // Still waiting.
     return;
   }
-  if (server == null) {
-    _bootServer();
-  }
+  _lazyServerBoot();
   // Toggle HTTP server.
   if (server.running) {
     serverFuture = server.shutdown(true).then(_clearFuture);
@@ -81,6 +74,10 @@
 }
 
 _registerSignalHandler() {
+  if (_signalWatch == null) {
+    // Cannot register for signals.
+    return;
+  }
   if (_isWindows) {
     // Cannot register for signals on Windows.
     return;
@@ -88,28 +85,23 @@
   _signalSubscription = _signalWatch(ProcessSignal.SIGQUIT).listen(_onSignal);
 }
 
-const _shortDelay = const Duration(milliseconds: 10);
-
 main() {
+  // Set embedder hooks.
+  VMServiceEmbedderHooks.cleanup = cleanupCallback;
   if (_autoStart) {
-    _bootServer();
+    _lazyServerBoot();
     server.startup();
     // It's just here to push an event on the event loop so that we invoke the
     // scheduled microtasks.
     Timer.run(() {});
   }
-  // TODO(johnmccutchan, turnidge) Creating a VMService object here causes
-  // strange behavior from the legacy debug protocol and coverage tool.
-  // Enable this code, and remove the call to Isolate::KillIsolate() from
-  // service_isolate.cc when the strange behavior is solved.
-  // See: https://github.com/dart-lang/sdk/issues/23977
-  // else {
-  //   var service = new VMService();
-  //   service.onShutdown = _onShutdown;
-  // }
+  // TODO(johnmccutchan): Fixup service isolate shutdown in the general case.
+  // See ServiceIsolate::KillServiceIsolate and ServiceIsolate::Shutdown.
   scriptLoadPort.handler = _processLoadRequest;
   // Register signal handler after a small delay to avoid stalling main
   // isolate startup.
-  new Timer(_shortDelay, _registerSignalHandler);
+  new Timer(shortDelay, _registerSignalHandler);
   return scriptLoadPort;
 }
+
+_shutdown() native "VMServiceIO_Shutdown";
diff --git a/runtime/bin/vmservice/vmservice_sources.gypi b/runtime/bin/vmservice/vmservice_sources.gypi
new file mode 100644
index 0000000..a7d06cd
--- /dev/null
+++ b/runtime/bin/vmservice/vmservice_sources.gypi
@@ -0,0 +1,13 @@
+# Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+# This file contains all Dart sources for the dart:io implementation of
+# the VM Service server.
+{
+  'sources': [
+    'loader.dart',
+    'server.dart',
+    'vmservice_io.dart',
+  ],
+}
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 0c0a63c..836295c 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -115,6 +115,11 @@
   Dart_ExitScope();
 }
 
+
+static void Shutdown(Dart_NativeArguments args) {
+  // NO-OP.
+}
+
 struct VmServiceIONativeEntry {
   const char* name;
   int num_arguments;
@@ -124,6 +129,7 @@
 
 static VmServiceIONativeEntry _VmServiceIONativeEntries[] = {
   {"VMServiceIO_NotifyServerState", 2, NotifyServerState},
+  {"VMServiceIO_Shutdown", 0, Shutdown },
 };
 
 
diff --git a/runtime/lib/core_sources.gypi b/runtime/lib/core_sources.gypi
index 73a4e04..bef056e 100644
--- a/runtime/lib/core_sources.gypi
+++ b/runtime/lib/core_sources.gypi
@@ -47,6 +47,7 @@
     'resource_patch.dart',
     'stacktrace.cc',
     'stacktrace.dart',
+    'stacktrace.h',
     'stopwatch.cc',
     'stopwatch_patch.dart',
     'string.cc',
diff --git a/runtime/lib/errors.cc b/runtime/lib/errors.cc
index aa985da..dd7acd8 100644
--- a/runtime/lib/errors.cc
+++ b/runtime/lib/errors.cc
@@ -10,17 +10,23 @@
 
 namespace dart {
 
+DECLARE_FLAG(bool, abort_on_assertion_errors);
+
 // Allocate and throw a new AssertionError.
 // Arg0: index of the first token of the failed assertion.
 // Arg1: index of the first token after the failed assertion.
 // Return value: none, throws an exception.
 DEFINE_NATIVE_ENTRY(AssertionError_throwNew, 2) {
+  if (FLAG_abort_on_assertion_errors) {
+    Exceptions::PrintStackTraceAndAbort("an assertion failure");
+  }
+
   // No need to type check the arguments. This function can only be called
   // internally from the VM.
-  intptr_t assertion_start =
-      Smi::CheckedHandle(arguments->NativeArgAt(0)).Value();
-  intptr_t assertion_end =
-      Smi::CheckedHandle(arguments->NativeArgAt(1)).Value();
+  const TokenPosition assertion_start =
+      TokenPosition(Smi::CheckedHandle(arguments->NativeArgAt(0)).Value());
+  const TokenPosition assertion_end =
+      TokenPosition(Smi::CheckedHandle(arguments->NativeArgAt(1)).Value());
 
   const Array& args = Array::Handle(Array::New(4));
 
@@ -60,7 +66,8 @@
 DEFINE_NATIVE_ENTRY(TypeError_throwNew, 5) {
   // No need to type check the arguments. This function can only be called
   // internally from the VM.
-  intptr_t location = Smi::CheckedHandle(arguments->NativeArgAt(0)).Value();
+  const TokenPosition location =
+      TokenPosition(Smi::CheckedHandle(arguments->NativeArgAt(0)).Value());
   const Instance& src_value =
       Instance::CheckedHandle(arguments->NativeArgAt(1));
   const String& dst_type_name =
@@ -81,7 +88,7 @@
 // Return value: none, throws an exception.
 DEFINE_NATIVE_ENTRY(FallThroughError_throwNew, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_pos, arguments->NativeArgAt(0));
-  intptr_t fallthrough_pos = smi_pos.Value();
+  TokenPosition fallthrough_pos = TokenPosition(smi_pos.Value());
 
   const Array& args = Array::Handle(Array::New(2));
 
@@ -107,7 +114,7 @@
 DEFINE_NATIVE_ENTRY(AbstractClassInstantiationError_throwNew, 2) {
   GET_NON_NULL_NATIVE_ARGUMENT(Smi, smi_pos, arguments->NativeArgAt(0));
   GET_NON_NULL_NATIVE_ARGUMENT(String, class_name, arguments->NativeArgAt(1));
-  intptr_t error_pos = smi_pos.Value();
+  TokenPosition error_pos = TokenPosition(smi_pos.Value());
 
   const Array& args = Array::Handle(Array::New(3));
 
diff --git a/runtime/lib/isolate.cc b/runtime/lib/isolate.cc
index 4e1fce8..f6d248a 100644
--- a/runtime/lib/isolate.cc
+++ b/runtime/lib/isolate.cc
@@ -298,6 +298,7 @@
   Isolate* isolate = thread->isolate();
   Dart_LibraryTagHandler handler = isolate->library_tag_handler();
   if (handler != NULL) {
+    TransitionVMToNative transition(thread);
     Dart_EnterScope();
     Dart_Handle handle = handler(Dart_kCanonicalizeUrl,
                                  Api::NewHandle(thread, library.raw()),
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index 564db22..24254db 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -140,7 +140,7 @@
     has_extra_parameter_info = false;
   }
   if (func.IsSignatureFunction() &&
-      (func.token_pos() == Token::kNoSourcePos)) {
+      (func.token_pos() == TokenPosition::kNoSource)) {
     // Signature functions (except those describing typedefs) get canonicalized,
     // hence do not have a token position, and therefore cannot be reparsed.
     has_extra_parameter_info = false;
@@ -1448,7 +1448,7 @@
           TypeArguments::Handle(closure.GetTypeArguments());
       const Class& cls =
           Class::Handle(Isolate::Current()->object_store()->object_class());
-      instantiator = Type::New(cls, arguments, Token::kNoSourcePos);
+      instantiator = Type::New(cls, arguments, TokenPosition::kNoSource);
       instantiator.SetIsFinalized();
     }
     return CreateMethodMirror(function,
@@ -1969,7 +1969,7 @@
   }
 
   Script& script = Script::Handle();
-  intptr_t token_pos = Token::kNoSourcePos;
+  TokenPosition token_pos = TokenPosition::kNoSource;
 
   if (decl.IsFunction()) {
     const Function& func = Function::Cast(decl);
@@ -2017,13 +2017,13 @@
       return CreateSourceLocation(uri, 1, 1);
     }
     const TokenStream& stream = TokenStream::Handle(script.tokens());
-    TokenStream::Iterator tkit(stream, 0);
+    TokenStream::Iterator tkit(stream, TokenPosition::kMinSource);
     if (tkit.CurrentTokenKind() == Token::kSCRIPTTAG) tkit.Advance();
     token_pos = tkit.CurrentPosition();
   }
 
   ASSERT(!script.IsNull());
-  ASSERT(token_pos != Token::kNoSourcePos);
+  ASSERT(token_pos != TokenPosition::kNoSource);
 
   const String& uri = String::Handle(script.url());
   intptr_t from_line = 0;
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index d0eb27c..cc64a06 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -193,7 +193,7 @@
     DartFrameIterator iterator;
     StackFrame* caller_frame = iterator.NextFrame();
     ASSERT(caller_frame != NULL);
-    const intptr_t location = caller_frame->GetTokenPos();
+    const TokenPosition location = caller_frame->GetTokenPos();
     String& bound_error_message = String::Handle(
         zone, String::New(bound_error.ToErrorCString()));
     Exceptions::CreateAndThrowTypeError(
@@ -303,7 +303,7 @@
     DartFrameIterator iterator;
     StackFrame* caller_frame = iterator.NextFrame();
     ASSERT(caller_frame != NULL);
-    const intptr_t location = caller_frame->GetTokenPos();
+    const TokenPosition location = caller_frame->GetTokenPos();
     const AbstractType& instance_type =
         AbstractType::Handle(instance.GetType());
     const String& instance_type_name =
diff --git a/runtime/lib/stacktrace.cc b/runtime/lib/stacktrace.cc
index 7b79314..9d9a307 100644
--- a/runtime/lib/stacktrace.cc
+++ b/runtime/lib/stacktrace.cc
@@ -2,6 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+#include "lib/stacktrace.h"
 #include "vm/bootstrap_natives.h"
 #include "vm/exceptions.h"
 #include "vm/object_store.h"
@@ -36,7 +37,7 @@
 // Creates a Stacktrace object from the current stack.
 //
 // Skips the first skip_frames Dart frames.
-static const Stacktrace& GetCurrentStacktrace(int skip_frames) {
+const Stacktrace& GetCurrentStacktrace(int skip_frames) {
   const GrowableObjectArray& code_list =
       GrowableObjectArray::Handle(GrowableObjectArray::New());
   const GrowableObjectArray& pc_offset_list =
diff --git a/runtime/lib/stacktrace.h b/runtime/lib/stacktrace.h
new file mode 100644
index 0000000..c3b16e4
--- /dev/null
+++ b/runtime/lib/stacktrace.h
@@ -0,0 +1,21 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+#ifndef LIB_STACKTRACE_H_
+#define LIB_STACKTRACE_H_
+
+namespace dart {
+
+class Stacktrace;
+
+// Creates a Stacktrace object from the current stack.  Skips the
+// first skip_frames Dart frames.
+//
+// This function is exposed to provide stack trace printing in
+// assertion failures, etc.
+const Stacktrace& GetCurrentStacktrace(int skip_frames);
+
+}  // namespace dart
+
+#endif  // LIB_STACKTRACE_H_
diff --git a/runtime/lib/vmservice.cc b/runtime/lib/vmservice.cc
index 83a25e1..fd5d14b 100644
--- a/runtime/lib/vmservice.cc
+++ b/runtime/lib/vmservice.cc
@@ -134,6 +134,17 @@
 }
 
 
+DEFINE_NATIVE_ENTRY(VMService_OnServerAddressChange, 1) {
+  GET_NATIVE_ARGUMENT(String, address, arguments->NativeArgAt(0));
+  if (address.IsNull()) {
+    ServiceIsolate::SetServerAddress(NULL);
+  } else {
+    ServiceIsolate::SetServerAddress(address.ToCString());
+  }
+  return Object::null();
+}
+
+
 DEFINE_NATIVE_ENTRY(VMService_ListenStream, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(String, stream_id, arguments->NativeArgAt(0));
   bool result = Service::ListenStream(stream_id.ToCString());
@@ -342,6 +353,7 @@
 
 DEFINE_NATIVE_ENTRY(VMService_DecodeAssets, 1) {
   GET_NON_NULL_NATIVE_ARGUMENT(TypedData, data, arguments->NativeArgAt(0));
+  TransitionVMToNative transition(thread);
   Api::Scope scope(thread);
 
   Dart_Handle data_handle = Api::NewHandle(thread, data.raw());
diff --git a/runtime/lib/vmservice_patch.dart b/runtime/lib/vmservice_patch.dart
index 3db7bca..f26b93d 100644
--- a/runtime/lib/vmservice_patch.dart
+++ b/runtime/lib/vmservice_patch.dart
@@ -27,6 +27,8 @@
     native "VMService_SendRootServiceMessage";
 patch void _onStart() native "VMService_OnStart";
 patch void _onExit() native "VMService_OnExit";
+patch void onServerAddressChange(String address)
+    native "VMService_OnServerAddressChange";
 patch bool _vmListenStream(String streamId) native "VMService_ListenStream";
 patch void _vmCancelStream(String streamId) native "VMService_CancelStream";
 patch Uint8List _requestAssets() native "VMService_RequestAssets";
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index abc1ea4..bbf1c34 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -41,6 +41,7 @@
   static const kCannotAddBreakpoint     = 102;
   static const kStreamAlreadySubscribed = 103;
   static const kStreamNotSubscribed     = 104;
+  static const kIsolateMustBeRunnable   = 105;
 
   int code;
   Map data;
diff --git a/runtime/observatory/tests/service/coverage_test.dart b/runtime/observatory/tests/service/coverage_test.dart
index d1c71eb..7a8ee93 100644
--- a/runtime/observatory/tests/service/coverage_test.dart
+++ b/runtime/observatory/tests/service/coverage_test.dart
@@ -80,7 +80,7 @@
          equals([15, 1, 16, 0, 18, 1, 20, 1,
                  24, 1, 25, 1, 27, 0, 13, 0]));
   expect(coverage['coverage'][1]['hits'],
-         equals([33, 1, 34, 1, 105, 2]));
+         equals([33, 1, 34, 1, 106, 2]));
 
   // Script
   await cls.load();
@@ -92,10 +92,11 @@
          equals([15, 1, 16, 0, 18, 1, 20, 1,
                  24, 1, 25, 1, 27, 0, 13, 0]));
   expect(coverage['coverage'][1]['hits'],
-         equals([33, 1, 34, 1, 105, 2]));
+         equals([33, 1, 34, 1, 106, 2]));
 
   // Isolate
   coverage = await isolate.invokeRpcNoUpgrade('_getCoverage', {});
+  print('Done processing _getCoverage for full isolate');
   expect(coverage['type'], equals('CodeCoverage'));
   expect(coverage['coverage'].length, greaterThan(100));
 },
diff --git a/runtime/observatory/tests/service/get_allocation_samples_test.dart b/runtime/observatory/tests/service/get_allocation_samples_test.dart
index a21ed9c..19d8a86 100644
--- a/runtime/observatory/tests/service/get_allocation_samples_test.dart
+++ b/runtime/observatory/tests/service/get_allocation_samples_test.dart
@@ -67,7 +67,8 @@
     var tree = cpuProfile.loadCodeTree('exclusive');
     var node = tree.root;
     var expected =
-        ['Root', 'test', 'test', '_Closure.call', 'runIsolateTests'];
+        ['Root', 'test', 'test', '_Closure.call',
+         'runIsolateTests.<runIsolateTests_async_body>'];
     for (var i = 0; i < expected.length; i++) {
       expect(node.profileCode.code.name, equals(expected[i]));
       // Depth first traversal.
diff --git a/runtime/observatory/tests/service/get_object_rpc_test.dart b/runtime/observatory/tests/service/get_object_rpc_test.dart
index 6bfa71f..2fc74f4 100644
--- a/runtime/observatory/tests/service/get_object_rpc_test.dart
+++ b/runtime/observatory/tests/service/get_object_rpc_test.dart
@@ -86,6 +86,99 @@
     expect(result['fields'], isEmpty);
   },
 
+  // A string
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '"Chattanooga"');
+    var params = {
+      'objectId': evalResult['id'],
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('String'));
+    expect(result['_vmType'], equals('String'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], equals('Chattanooga'));
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_OneByteString'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(11));
+    expect(result['offset'], isNull);
+    expect(result['count'], isNull);
+  },
+
+  // String prefix.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '"Chattanooga"');
+    var params = {
+      'objectId': evalResult['id'],
+      'count': 4,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('String'));
+    expect(result['_vmType'], equals('String'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], equals('Chat'));
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_OneByteString'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(11));
+    expect(result['offset'], isNull);
+    expect(result['count'], equals(4));
+  },
+
+  // String subrange.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '"Chattanooga"');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 4,
+      'count': 6,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('String'));
+    expect(result['_vmType'], equals('String'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], equals('tanoog'));
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_OneByteString'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(11));
+    expect(result['offset'], equals(4));
+    expect(result['count'], equals(6));
+  },
+
+  // String with wacky offset.
+  (Isolate isolate) async {
+    // Call eval to get a Dart list.
+    var evalResult = await eval(isolate, '"Chattanooga"');
+    var params = {
+      'objectId': evalResult['id'],
+      'offset': 100,
+      'count': 2,
+    };
+    var result = await isolate.invokeRpcNoUpgrade('getObject', params);
+    expect(result['type'], equals('Instance'));
+    expect(result['kind'], equals('String'));
+    expect(result['_vmType'], equals('String'));
+    expect(result['id'], startsWith('objects/'));
+    expect(result['valueAsString'], equals(''));
+    expect(result['class']['type'], equals('@Class'));
+    expect(result['class']['name'], equals('_OneByteString'));
+    expect(result['size'], isPositive);
+    expect(result['fields'], isEmpty);
+    expect(result['length'], equals(11));
+    expect(result['offset'], equals(11));
+    expect(result['count'], equals(0));
+  },
+
   // A built-in List.
   (Isolate isolate) async {
     // Call eval to get a Dart list.
diff --git a/runtime/observatory/tests/service/get_version_rpc_test.dart b/runtime/observatory/tests/service/get_version_rpc_test.dart
index 3df8d67..f72c425 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(0));
+    expect(result['minor'], equals(1));
     expect(result['_privateMajor'], equals(0));
     expect(result['_privateMinor'], equals(0));
   },
diff --git a/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart b/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart
index 4a6b2dd..e9f233b 100644
--- a/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart
+++ b/runtime/observatory/tests/service/pause_on_unhandled_exceptions_test.dart
@@ -15,13 +15,15 @@
 
 var tests = [
   hasStoppedWithUnhandledException,
+
   (Isolate isolate) async {
+    print("We stoppped!");
     var stack = await isolate.getStack();
     expect(stack['frames'][0].function.name, equals('doThrow'));
   }
 ];
 
-main(args) => runIsolateTests(args,
-                              tests,
-                              pause_on_unhandled_exceptions: true,
-                              testeeConcurrent: doThrow);
+main(args) => runIsolateTestsSynchronous(args,
+                                         tests,
+                                         pause_on_unhandled_exceptions: true,
+                                         testeeConcurrent: doThrow);
diff --git a/runtime/observatory/tests/service/service.status b/runtime/observatory/tests/service/service.status
index 8a572de..7f5372f 100644
--- a/runtime/observatory/tests/service/service.status
+++ b/runtime/observatory/tests/service/service.status
@@ -25,4 +25,4 @@
 *: Skip # Issue 24651
 
 [ $runtime == vm ]
-coverage_test: Pass Slow
+coverage_test: Pass, Slow
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 6e64180..794cecd 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -109,15 +109,86 @@
 /// return a [Future]. Code for setting up state can run before and/or
 /// concurrently with the tests. Uses [mainArgs] to determine whether
 /// to run tests or testee in this invokation of the script.
-void runIsolateTests(List<String> mainArgs,
-                     List<IsolateTest> tests,
-                     {void testeeBefore(),
-                      void testeeConcurrent(),
-                      bool pause_on_start: false,
-                      bool pause_on_exit: false,
-                      bool trace_service: false,
-                      bool verbose_vm: false,
-                      bool pause_on_unhandled_exceptions: false}) {
+Future runIsolateTests(List<String> mainArgs,
+                       List<IsolateTest> tests,
+                       {testeeBefore(),
+                        void testeeConcurrent(),
+                        bool pause_on_start: false,
+                        bool pause_on_exit: false,
+                        bool trace_service: false,
+                        bool verbose_vm: false,
+                        bool pause_on_unhandled_exceptions: false}) async {
+  assert(!pause_on_start || testeeBefore == null);
+  if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
+    if (!pause_on_start) {
+      if (testeeBefore != null) {
+        var result = testeeBefore();
+        if (result is Future) {
+          await result;
+        }
+      }
+      print(''); // Print blank line to signal that we are ready.
+    }
+    if (testeeConcurrent != null) {
+      testeeConcurrent();
+    }
+    if (!pause_on_exit) {
+      // Wait around for the process to be killed.
+      stdin.first.then((_) => exit(0));
+    }
+  } else {
+    var process = new _TestLauncher();
+    process.launch(pause_on_start, pause_on_exit,
+                   pause_on_unhandled_exceptions, trace_service).then((port) {
+      if (mainArgs.contains("--gdb")) {
+        port = 8181;
+      }
+      String addr = 'ws://localhost:$port/ws';
+      serviceHttpAddress = 'http://localhost:$port';
+      var testIndex = 1;
+      var totalTests = tests.length;
+      var name = Platform.script.pathSegments.last;
+      runZoned(() {
+        new WebSocketVM(new WebSocketVMTarget(addr)).load()
+            .then((VM vm) => vm.isolates.first.load())
+            .then((Isolate isolate) => Future.forEach(tests, (test) {
+              isolate.vm.verbose = verbose_vm;
+              print('Running $name [$testIndex/$totalTests]');
+              testIndex++;
+              return test(isolate);
+            })).then((_) => process.requestExit());
+      }, onError: (e, st) {
+        process.requestExit();
+        if (!_isWebSocketDisconnect(e)) {
+          print('Unexpected exception in service tests: $e $st');
+          throw e;
+        }
+      });
+    });
+  }
+}
+
+/// Runs [tests] in sequence, each of which should take an [Isolate] and
+/// return a [Future]. Code for setting up state can run before and/or
+/// concurrently with the tests. Uses [mainArgs] to determine whether
+/// to run tests or testee in this invokation of the script.
+///
+/// This is a special version of this test harness specifically for the
+/// pause_on_unhandled_exceptions_test, which cannot properly function
+/// in an async context (because exceptions are *always* handled in async
+/// functions).
+///
+/// TODO(johnmccutchan): Don't use the shared harness for the
+/// pause_on_unhandled_exceptions_test.
+void runIsolateTestsSynchronous(List<String> mainArgs,
+                                List<IsolateTest> tests,
+                                {void testeeBefore(),
+                                 void testeeConcurrent(),
+                                 bool pause_on_start: false,
+                                 bool pause_on_exit: false,
+                                 bool trace_service: false,
+                                 bool verbose_vm: false,
+                                 bool pause_on_unhandled_exceptions: false}) {
   assert(!pause_on_start || testeeBefore == null);
   if (mainArgs.contains(_TESTEE_MODE_FLAG)) {
     if (!pause_on_start) {
diff --git a/runtime/platform/utils.h b/runtime/platform/utils.h
index 9e4a384..508e0e7 100644
--- a/runtime/platform/utils.h
+++ b/runtime/platform/utils.h
@@ -204,16 +204,9 @@
 
   // dart2js represents integers as double precision floats, which can
   // represent anything in the range -2^53 ... 2^53.
-  static bool IsJavascriptInt64(int64_t value) {
+  static bool IsJavascriptInt(int64_t value) {
     return ((-0x20000000000000LL <= value) && (value <= 0x20000000000000LL));
   }
-  static bool IsJavascriptInt(intptr_t value) {
-#if defined(ARCH_IS_64BIT)
-    return ((-0x20000000000000LL <= value) && (value <= 0x20000000000000LL));
-#else
-    return true;
-#endif
-  }
 
   static char* StrError(int err, char* buffer, size_t bufsize);
 };
diff --git a/runtime/vm/ast.cc b/runtime/vm/ast.cc
index 2deefa2..ef8d4cc 100644
--- a/runtime/vm/ast.cc
+++ b/runtime/vm/ast.cc
@@ -91,7 +91,7 @@
 }
 
 
-LetNode::LetNode(intptr_t token_pos)
+LetNode::LetNode(TokenPosition token_pos)
   : AstNode(token_pos),
     vars_(1),
     initializers_(1),
@@ -101,8 +101,8 @@
 LocalVariable* LetNode::AddInitializer(AstNode* node) {
   initializers_.Add(node);
   char name[64];
-  OS::SNPrint(name, sizeof(name), ":lt%" Pd "_%" Pd "",
-      token_pos(), vars_.length());
+  OS::SNPrint(name, sizeof(name), ":lt%s_%" Pd "",
+      token_pos().ToCString(), vars_.length());
   LocalVariable* temp_var =
       new LocalVariable(token_pos(),
                         String::ZoneHandle(Symbols::New(name)),
@@ -433,7 +433,7 @@
 }
 
 
-AstNode* UnaryOpNode::UnaryOpOrLiteral(intptr_t token_pos,
+AstNode* UnaryOpNode::UnaryOpOrLiteral(TokenPosition token_pos,
                                        Token::Kind kind,
                                        AstNode* operand) {
   AstNode* new_operand = operand->ApplyUnaryOp(kind);
diff --git a/runtime/vm/ast.h b/runtime/vm/ast.h
index 494d768..f212a15 100644
--- a/runtime/vm/ast.h
+++ b/runtime/vm/ast.h
@@ -12,6 +12,7 @@
 #include "vm/object.h"
 #include "vm/native_entry.h"
 #include "vm/token.h"
+#include "vm/token_position.h"
 
 namespace dart {
 
@@ -97,14 +98,14 @@
 
 class AstNode : public ZoneAllocated {
  public:
-  explicit AstNode(intptr_t token_pos)
+  explicit AstNode(TokenPosition token_pos)
       : token_pos_(token_pos) {
-    ASSERT(!Token::IsClassifying(token_pos_) ||
-           (token_pos_ == ClassifyingTokenPositions::kMethodExtractor));
+    ASSERT(!token_pos_.IsClassifying() ||
+           (token_pos_ == TokenPosition::kMethodExtractor));
   }
   virtual ~AstNode() { }
 
-  intptr_t token_pos() const { return token_pos_; }
+  TokenPosition token_pos() const { return token_pos_; }
 
 #define AST_TYPE_CHECK(BaseName)                                               \
   bool Is##BaseName##Node() { return As##BaseName##Node() != NULL; }           \
@@ -153,14 +154,14 @@
   friend class ParsedFunction;
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   DISALLOW_COPY_AND_ASSIGN(AstNode);
 };
 
 
 class AwaitNode : public AstNode {
  public:
-  AwaitNode(intptr_t token_pos,
+  AwaitNode(TokenPosition token_pos,
             AstNode* expr,
             LocalVariable* saved_try_ctx,
             LocalVariable* async_saved_try_ctx,
@@ -215,7 +216,7 @@
  public:
   AwaitMarkerNode(LocalScope* async_scope,
                   LocalScope* await_scope,
-                  intptr_t token_pos)
+                  TokenPosition token_pos)
     : AstNode(token_pos),
       async_scope_(async_scope),
       await_scope_(await_scope) {
@@ -241,7 +242,7 @@
 
 class SequenceNode : public AstNode {
  public:
-  SequenceNode(intptr_t token_pos, LocalScope* scope)
+  SequenceNode(TokenPosition token_pos, LocalScope* scope)
     : AstNode(token_pos),
       scope_(scope),
       nodes_(4),
@@ -276,7 +277,7 @@
 
 class CloneContextNode : public AstNode {
  public:
-  explicit CloneContextNode(intptr_t token_pos)
+  explicit CloneContextNode(TokenPosition token_pos)
     : AstNode(token_pos) {
   }
 
@@ -291,7 +292,7 @@
 
 class ArgumentListNode : public AstNode {
  public:
-  explicit ArgumentListNode(intptr_t token_pos)
+  explicit ArgumentListNode(TokenPosition token_pos)
      : AstNode(token_pos),
        nodes_(4),
        names_(Array::ZoneHandle()) {
@@ -323,7 +324,7 @@
 
 class LetNode : public AstNode {
  public:
-  explicit LetNode(intptr_t token_pos);
+  explicit LetNode(TokenPosition token_pos);
 
   LocalVariable* TempAt(intptr_t i) const { return vars_[i]; }
   AstNode* InitializerAt(intptr_t i) const { return initializers_[i]; }
@@ -356,13 +357,13 @@
 
 class ArrayNode : public AstNode {
  public:
-  ArrayNode(intptr_t token_pos, const AbstractType& type)
+  ArrayNode(TokenPosition token_pos, const AbstractType& type)
       : AstNode(token_pos),
         type_(type),
         elements_() {
     CheckFields();
   }
-  ArrayNode(intptr_t token_pos,
+  ArrayNode(TokenPosition token_pos,
             const AbstractType& type,
             const GrowableArray<AstNode*>& elements)
       : AstNode(token_pos),
@@ -407,7 +408,7 @@
 
 class StringInterpolateNode : public AstNode {
  public:
-  StringInterpolateNode(intptr_t token_pos, ArrayNode* value)
+  StringInterpolateNode(TokenPosition token_pos, ArrayNode* value)
       : AstNode(token_pos), value_(value) { }
 
   virtual void VisitChildren(AstNodeVisitor* visitor) const {
@@ -429,7 +430,7 @@
 
 class LiteralNode : public AstNode {
  public:
-  LiteralNode(intptr_t token_pos, const Instance& literal)
+  LiteralNode(TokenPosition token_pos, const Instance& literal)
       : AstNode(token_pos), literal_(literal) {
     ASSERT(literal_.IsNotTemporaryScopedHandle());
     ASSERT(literal_.IsSmi() || literal_.IsOld());
@@ -465,7 +466,7 @@
 
 class TypeNode : public AstNode {
  public:
-  TypeNode(intptr_t token_pos, const AbstractType& type)
+  TypeNode(TokenPosition token_pos, const AbstractType& type)
       : AstNode(token_pos), type_(type) {
     ASSERT(type_.IsZoneHandle());
     ASSERT(!type_.IsNull());
@@ -500,7 +501,7 @@
 
 class AssignableNode : public AstNode {
  public:
-  AssignableNode(intptr_t token_pos,
+  AssignableNode(TokenPosition token_pos,
                  AstNode* expr,
                  const AbstractType& type,
                  const String& dst_name)
@@ -533,7 +534,7 @@
 
 class ClosureNode : public AstNode {
  public:
-  ClosureNode(intptr_t token_pos,
+  ClosureNode(TokenPosition token_pos,
               const Function& function,
               AstNode* receiver,  // Non-null for implicit instance closures.
               LocalScope* scope)  // Null for implicit closures.
@@ -585,7 +586,7 @@
 // field access nodes.
 class PrimaryNode : public AstNode {
  public:
-  PrimaryNode(intptr_t token_pos, const Object& primary)
+  PrimaryNode(TokenPosition token_pos, const Object& primary)
       : AstNode(token_pos),
         primary_(primary),
         is_deferred_reference_(false) {
@@ -631,13 +632,13 @@
   };
 
   // Return from a void function returns the null object.
-  explicit ReturnNode(intptr_t token_pos)
+  explicit ReturnNode(TokenPosition token_pos)
       : AstNode(token_pos),
         value_(new LiteralNode(token_pos, Instance::ZoneHandle())),
         inlined_finally_list_(),
         return_type_(kRegular) { }
   // Return from a non-void function.
-  ReturnNode(intptr_t token_pos,
+  ReturnNode(TokenPosition token_pos,
              AstNode* value)
       : AstNode(token_pos),
         value_(value),
@@ -684,7 +685,7 @@
 
 class ComparisonNode : public AstNode {
  public:
-  ComparisonNode(intptr_t token_pos,
+  ComparisonNode(TokenPosition token_pos,
                  Token::Kind kind,
                  AstNode* left,
                  AstNode* right)
@@ -722,7 +723,7 @@
 
 class BinaryOpNode : public AstNode {
  public:
-  BinaryOpNode(intptr_t token_pos,
+  BinaryOpNode(TokenPosition token_pos,
                Token::Kind kind,
                AstNode* left,
                AstNode* right)
@@ -766,7 +767,7 @@
 
 class BinaryOpWithMask32Node : public BinaryOpNode {
  public:
-  BinaryOpWithMask32Node(intptr_t token_pos,
+  BinaryOpWithMask32Node(TokenPosition token_pos,
                          Token::Kind kind_value,
                          AstNode* left,
                          AstNode* right,
@@ -797,10 +798,10 @@
 class UnaryOpNode : public AstNode {
  public:
   // Returns optimized version, e.g., for ('-' '1') ('-1') literal is returned.
-  static AstNode* UnaryOpOrLiteral(intptr_t token_pos,
+  static AstNode* UnaryOpOrLiteral(TokenPosition token_pos,
                                    Token::Kind kind,
                                    AstNode* operand);
-  UnaryOpNode(intptr_t token_pos,
+  UnaryOpNode(TokenPosition token_pos,
               Token::Kind kind,
               AstNode* operand)
       : AstNode(token_pos), kind_(kind), operand_(operand) {
@@ -833,7 +834,7 @@
 
 class ConditionalExprNode : public AstNode {
  public:
-  ConditionalExprNode(intptr_t token_pos,
+  ConditionalExprNode(TokenPosition token_pos,
                       AstNode* condition,
                       AstNode* true_expr,
                       AstNode* false_expr)
@@ -881,7 +882,7 @@
 
 class IfNode : public AstNode {
  public:
-  IfNode(intptr_t token_pos,
+  IfNode(TokenPosition token_pos,
          AstNode* condition,
          SequenceNode* true_branch,
          SequenceNode* false_branch)
@@ -917,7 +918,7 @@
 
 class CaseNode : public AstNode {
  public:
-  CaseNode(intptr_t token_pos,
+  CaseNode(TokenPosition token_pos,
            SourceLabel* label,
            SequenceNode* case_expressions,
            bool contains_default,
@@ -961,7 +962,7 @@
 
 class SwitchNode : public AstNode {
  public:
-  SwitchNode(intptr_t token_pos,
+  SwitchNode(TokenPosition token_pos,
              SourceLabel* label,
              SequenceNode* body)
     : AstNode(token_pos),
@@ -990,7 +991,7 @@
 
 class WhileNode : public AstNode {
  public:
-  WhileNode(intptr_t token_pos,
+  WhileNode(TokenPosition token_pos,
             SourceLabel* label,
             AstNode* condition,
             SequenceNode* condition_preamble,
@@ -1032,7 +1033,7 @@
 
 class DoWhileNode : public AstNode {
  public:
-  DoWhileNode(intptr_t token_pos,
+  DoWhileNode(TokenPosition token_pos,
               SourceLabel* label,
               AstNode* condition,
               SequenceNode* body)
@@ -1068,7 +1069,7 @@
 // The condition can be NULL.
 class ForNode : public AstNode {
  public:
-  ForNode(intptr_t token_pos,
+  ForNode(TokenPosition token_pos,
           SourceLabel* label,
           SequenceNode* initializer,
           AstNode* condition,
@@ -1124,7 +1125,7 @@
 
 class JumpNode : public AstNode {
  public:
-  JumpNode(intptr_t token_pos,
+  JumpNode(TokenPosition token_pos,
            Token::Kind kind,
            SourceLabel* label)
     : AstNode(token_pos),
@@ -1165,7 +1166,7 @@
 
 class StopNode : public AstNode {
  public:
-  StopNode(intptr_t token_pos, const char* message)
+  StopNode(TokenPosition token_pos, const char* message)
       : AstNode(token_pos),
         message_(message) {
     ASSERT(message != NULL);
@@ -1186,7 +1187,7 @@
 
 class LoadLocalNode : public AstNode {
  public:
-  LoadLocalNode(intptr_t token_pos, const LocalVariable* local)
+  LoadLocalNode(TokenPosition token_pos, const LocalVariable* local)
       : AstNode(token_pos), local_(*local) {
     ASSERT(local != NULL);
   }
@@ -1210,7 +1211,9 @@
 
 class StoreLocalNode : public AstNode {
  public:
-  StoreLocalNode(intptr_t token_pos, const LocalVariable* local, AstNode* value)
+  StoreLocalNode(TokenPosition token_pos,
+                 const LocalVariable* local,
+                 AstNode* value)
       : AstNode(token_pos),  local_(*local), value_(value) {
     ASSERT(local != NULL);
     ASSERT(value_ != NULL);
@@ -1235,7 +1238,7 @@
 
 class LoadInstanceFieldNode : public AstNode {
  public:
-  LoadInstanceFieldNode(intptr_t token_pos,
+  LoadInstanceFieldNode(TokenPosition token_pos,
                         AstNode* instance,
                         const Field& field)
       : AstNode(token_pos), instance_(instance), field_(field) {
@@ -1262,7 +1265,7 @@
 
 class StoreInstanceFieldNode : public AstNode {
  public:
-  StoreInstanceFieldNode(intptr_t token_pos,
+  StoreInstanceFieldNode(TokenPosition token_pos,
                          AstNode* instance,
                          const Field& field,
                          AstNode* value)
@@ -1297,7 +1300,7 @@
 
 class LoadStaticFieldNode : public AstNode {
  public:
-  LoadStaticFieldNode(intptr_t token_pos, const Field& field)
+  LoadStaticFieldNode(TokenPosition token_pos, const Field& field)
       : AstNode(token_pos), field_(field), is_deferred_reference_(false) {
     ASSERT(field_.IsZoneHandle());
   }
@@ -1333,7 +1336,9 @@
 
 class StoreStaticFieldNode : public AstNode {
  public:
-  StoreStaticFieldNode(intptr_t token_pos, const Field& field, AstNode* value)
+  StoreStaticFieldNode(TokenPosition token_pos,
+                       const Field& field,
+                       AstNode* value)
       : AstNode(token_pos), field_(field), value_(value) {
     ASSERT(field_.IsZoneHandle());
     ASSERT(value_ != NULL);
@@ -1358,7 +1363,7 @@
 
 class LoadIndexedNode : public AstNode {
  public:
-  LoadIndexedNode(intptr_t token_pos,
+  LoadIndexedNode(TokenPosition token_pos,
                   AstNode* array,
                   AstNode* index,
                   const Class& super_class)
@@ -1395,7 +1400,7 @@
 
 class StoreIndexedNode : public AstNode {
  public:
-  StoreIndexedNode(intptr_t token_pos,
+  StoreIndexedNode(TokenPosition token_pos,
                    AstNode* array,
                    AstNode* index,
                    AstNode* value,
@@ -1436,7 +1441,7 @@
 
 class InstanceCallNode : public AstNode {
  public:
-  InstanceCallNode(intptr_t token_pos,
+  InstanceCallNode(TokenPosition token_pos,
                    AstNode* receiver,
                    const String& function_name,
                    ArgumentListNode* arguments,
@@ -1476,7 +1481,7 @@
 
 class InstanceGetterNode : public AstNode {
  public:
-  InstanceGetterNode(intptr_t token_pos,
+  InstanceGetterNode(TokenPosition token_pos,
                      AstNode* receiver,
                      const String& field_name,
                      bool is_conditional = false)
@@ -1515,7 +1520,7 @@
 
 class InstanceSetterNode : public AstNode {
  public:
-  InstanceSetterNode(intptr_t token_pos,
+  InstanceSetterNode(TokenPosition token_pos,
                      AstNode* receiver,
                      const String& field_name,
                      AstNode* value,
@@ -1555,7 +1560,7 @@
 
 class InitStaticFieldNode : public AstNode {
  public:
-  InitStaticFieldNode(intptr_t token_pos, const Field& field)
+  InitStaticFieldNode(TokenPosition token_pos, const Field& field)
       : AstNode(token_pos), field_(field) {
     ASSERT(field_.IsZoneHandle());
   }
@@ -1575,7 +1580,7 @@
 
 class StaticGetterNode : public AstNode {
  public:
-  StaticGetterNode(intptr_t token_pos,
+  StaticGetterNode(TokenPosition token_pos,
                    AstNode* receiver,
                    const Class& cls,
                    const String& field_name)
@@ -1632,7 +1637,7 @@
 class StaticSetterNode : public AstNode {
  public:
   // Static setter with resolved setter function.
-  StaticSetterNode(intptr_t token_pos,
+  StaticSetterNode(TokenPosition token_pos,
                    AstNode* receiver,
                    const String& field_name,
                    const Function& function,
@@ -1650,7 +1655,7 @@
   }
 
   // For unresolved setters.
-  StaticSetterNode(intptr_t token_pos,
+  StaticSetterNode(TokenPosition token_pos,
                    AstNode* receiver,
                    const Class& cls,
                    const String& field_name,
@@ -1694,7 +1699,7 @@
 
 class StaticCallNode : public AstNode {
  public:
-  StaticCallNode(intptr_t token_pos,
+  StaticCallNode(TokenPosition token_pos,
                  const Function& function,
                  ArgumentListNode* arguments)
       : AstNode(token_pos),
@@ -1725,7 +1730,7 @@
 
 class ClosureCallNode : public AstNode {
  public:
-  ClosureCallNode(intptr_t token_pos,
+  ClosureCallNode(TokenPosition token_pos,
                   AstNode* closure,
                   ArgumentListNode* arguments)
       : AstNode(token_pos),
@@ -1781,7 +1786,7 @@
 // instantiator_class.
 class ConstructorCallNode : public AstNode {
  public:
-  ConstructorCallNode(intptr_t token_pos,
+  ConstructorCallNode(TokenPosition token_pos,
                       const TypeArguments& type_arguments,
                       const Function& constructor,
                       ArgumentListNode* arguments)
@@ -1818,7 +1823,7 @@
 // The body of a Dart function marked as 'native' consists of this node.
 class NativeBodyNode : public AstNode {
  public:
-  NativeBodyNode(intptr_t token_pos,
+  NativeBodyNode(TokenPosition token_pos,
                  const Function& function,
                  const String& native_c_function_name,
                  LocalScope* scope,
@@ -1859,7 +1864,7 @@
  public:
   static const intptr_t kInvalidTryIndex = -1;
 
-  CatchClauseNode(intptr_t token_pos,
+  CatchClauseNode(TokenPosition token_pos,
                   SequenceNode* catch_block,
                   const Array& handler_types,
                   const LocalVariable* context_var,
@@ -1922,7 +1927,7 @@
 
 class TryCatchNode : public AstNode {
  public:
-  TryCatchNode(intptr_t token_pos,
+  TryCatchNode(TokenPosition token_pos,
                SequenceNode* try_block,
                const LocalVariable* context_var,
                CatchClauseNode* catch_block,
@@ -1975,7 +1980,7 @@
 
 class ThrowNode : public AstNode {
  public:
-  ThrowNode(intptr_t token_pos, AstNode* exception, AstNode* stacktrace)
+  ThrowNode(TokenPosition token_pos, AstNode* exception, AstNode* stacktrace)
       : AstNode(token_pos), exception_(exception), stacktrace_(stacktrace) {
     ASSERT(exception_ != NULL);
   }
@@ -2002,7 +2007,7 @@
 
 class InlinedFinallyNode : public AstNode {
  public:
-  InlinedFinallyNode(intptr_t token_pos,
+  InlinedFinallyNode(TokenPosition token_pos,
                      SequenceNode* finally_block,
                      const LocalVariable* context_var,
                      intptr_t try_index)
diff --git a/runtime/vm/ast_printer.cc b/runtime/vm/ast_printer.cc
index 7cc69d4..9997a98 100644
--- a/runtime/vm/ast_printer.cc
+++ b/runtime/vm/ast_printer.cc
@@ -30,9 +30,9 @@
   LocalScope* scope = node->scope();
   THR_Print("(%s (scope \"%p\"", node->PrettyName(), scope);
   if (scope != NULL) {
-    THR_Print(" (%" Pd "-%" Pd ") loop %d",
-              scope->begin_token_pos(),
-              scope->end_token_pos(),
+    THR_Print(" (%s-%s) loop %d",
+              scope->begin_token_pos().ToCString(),
+              scope->end_token_pos().ToCString(),
               scope->loop_level());
     if (scope->HasContextLevel()) {
       THR_Print(" context %d captures %d",
@@ -478,9 +478,9 @@
   } else if (var->owner()->function_level() != 0) {
     THR_Print(" lev %d", var->owner()->function_level());
   }
-  THR_Print(" valid %" Pd "-%" Pd ")\n",
-            var->token_pos(),
-            scope->end_token_pos());
+  THR_Print(" valid %s-%s)\n",
+            var->token_pos().ToCString(),
+            scope->end_token_pos().ToCString());
 }
 
 
@@ -551,9 +551,9 @@
         THR_Print(" ctx %d", param->owner()->context_level());
       }
     }
-    THR_Print(" valid %" Pd "-%" Pd ")\n",
-              param->token_pos(),
-              scope->end_token_pos());
+    THR_Print(" valid %s-%s)\n",
+              param->token_pos().ToCString(),
+              scope->end_token_pos().ToCString());
     pos++;
   }
   // Visit remaining non-parameter variables and children scopes.
diff --git a/runtime/vm/ast_printer_test.cc b/runtime/vm/ast_printer_test.cc
index 9ac8d72..082d8dc 100644
--- a/runtime/vm/ast_printer_test.cc
+++ b/runtime/vm/ast_printer_test.cc
@@ -13,7 +13,7 @@
 namespace dart {
 
 TEST_CASE(AstPrinter) {
-  const intptr_t kPos = Token::kNoSourcePos;
+  const TokenPosition kPos = TokenPosition::kNoSource;
   LocalVariable* v =
       new LocalVariable(kPos,
                         String::ZoneHandle(Symbols::New("wurscht")),
diff --git a/runtime/vm/ast_test.cc b/runtime/vm/ast_test.cc
index afe4bdb..88096e9 100644
--- a/runtime/vm/ast_test.cc
+++ b/runtime/vm/ast_test.cc
@@ -13,10 +13,10 @@
 namespace dart {
 
 TEST_CASE(Ast) {
-  LocalVariable* v = new LocalVariable(Token::kNoSourcePos,
+  LocalVariable* v = new LocalVariable(TokenPosition::kNoSource,
                                        String::ZoneHandle(Symbols::New("v")),
                                        Type::ZoneHandle(Type::DynamicType()));
-  AstNode* ll = new LoadLocalNode(Token::kNoSourcePos, v);
+  AstNode* ll = new LoadLocalNode(TokenPosition::kNoSource, v);
   EXPECT(ll->IsLoadLocalNode());
   EXPECT(!ll->IsLiteralNode());
   LoadLocalNode* lln = ll->AsLoadLocalNode();
@@ -24,7 +24,7 @@
   v->set_index(1);
   EXPECT_EQ(1, v->index());
 
-  LocalVariable* p = new LocalVariable(Token::kNoSourcePos,
+  LocalVariable* p = new LocalVariable(TokenPosition::kNoSource,
                                        String::ZoneHandle(Symbols::New("p")),
                                        Type::ZoneHandle(Type::DynamicType()));
   EXPECT(!p->HasIndex());
@@ -32,28 +32,31 @@
   EXPECT(p->HasIndex());
   EXPECT_EQ(-1, p->index());
 
-  ReturnNode* r = new ReturnNode(Token::kNoSourcePos, lln);
+  ReturnNode* r = new ReturnNode(TokenPosition::kNoSource, lln);
   EXPECT_EQ(lln, r->value());
 
-  LiteralNode* l =
-      new LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(3)));
+  LiteralNode* l = new LiteralNode(TokenPosition::kNoSource,
+                                   Smi::ZoneHandle(Smi::New(3)));
   EXPECT(l->literal().IsSmi());
   EXPECT_EQ(Smi::New(3), l->literal().raw());
 
   BinaryOpNode* b =
-      new BinaryOpNode(Token::kNoSourcePos, Token::kADD, l, lln);
+      new BinaryOpNode(TokenPosition::kNoSource, Token::kADD, l, lln);
   EXPECT_EQ(Token::kADD, b->kind());
   EXPECT_EQ(l, b->left());
   EXPECT_EQ(lln, b->right());
 
   UnaryOpNode* u =
-      new UnaryOpNode(Token::kNoSourcePos, Token::kNEGATE, b);
+      new UnaryOpNode(TokenPosition::kNoSource, Token::kNEGATE, b);
   EXPECT_EQ(Token::kNEGATE, u->kind());
   EXPECT_EQ(b, u->operand());
 
-  SequenceNode* sequence_node = new SequenceNode(1, new LocalScope(NULL, 0, 0));
-  LiteralNode* literal_node = new LiteralNode(2,  Smi::ZoneHandle(Smi::New(3)));
-  ReturnNode* return_node = new ReturnNode(3, literal_node);
+  SequenceNode* sequence_node =
+      new SequenceNode(TokenPosition(1), new LocalScope(NULL, 0, 0));
+  LiteralNode* literal_node =
+      new LiteralNode(TokenPosition(2),  Smi::ZoneHandle(Smi::New(3)));
+  ReturnNode* return_node =
+      new ReturnNode(TokenPosition(3), literal_node);
   sequence_node->Add(return_node);
   GrowableArray<AstNode*> nodes;
   sequence_node->CollectAllNodes(&nodes);
diff --git a/runtime/vm/ast_transformer.cc b/runtime/vm/ast_transformer.cc
index 8954f0a..8b14e29 100644
--- a/runtime/vm/ast_transformer.cc
+++ b/runtime/vm/ast_transformer.cc
@@ -14,7 +14,7 @@
 #define Z (thread()->zone())
 
 // Quick synthetic token position.
-#define ST(token_pos) Token::ToSynthetic(token_pos)
+#define ST(token_pos) ((token_pos).ToSynthetic())
 
 // Nodes that are unreachable from already parsed expressions.
 #define FOR_EACH_UNREACHABLE_NODE(V)                                           \
@@ -74,7 +74,7 @@
   if (await_tmp == NULL) {
     // We need a new temp variable; add it to the function's top scope.
     await_tmp = new (Z) LocalVariable(
-        Token::kNoSourcePos, symbol, Object::dynamic_type());
+        TokenPosition::kNoSource, symbol, Object::dynamic_type());
     async_temp_scope_->AddVariable(await_tmp);
     // After adding it to the top scope, we can look it up from the preamble.
     // The following call includes an ASSERT check.
@@ -92,10 +92,11 @@
 }
 
 
-LocalVariable* AwaitTransformer::AddToPreambleNewTempVar(AstNode* node,
-                                                         intptr_t token_pos) {
+LocalVariable* AwaitTransformer::AddToPreambleNewTempVar(
+    AstNode* node,
+    TokenPosition token_pos) {
   LocalVariable* tmp_var = EnsureCurrentTempVar();
-  ASSERT(Token::IsSynthetic(token_pos) || Token::IsNoSource(token_pos));
+  ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource());
   preamble_->Add(new(Z) StoreLocalNode(token_pos, tmp_var, node));
   NextTempVar();
   return tmp_var;
@@ -124,7 +125,7 @@
   //   :saved_try_ctx_var = :await_saved_try_ctx_var_y;
   //   :await_temp_var_(X+1) = :result_param;
 
-  const intptr_t token_pos = ST(node->token_pos());
+  const TokenPosition token_pos = ST(node->token_pos());
   LocalVariable* async_op = GetVariableInScope(
       preamble_->scope(), Symbols::AsyncOperation());
   LocalVariable* async_then_callback = GetVariableInScope(
diff --git a/runtime/vm/ast_transformer.h b/runtime/vm/ast_transformer.h
index d8c01d0..5930f41 100644
--- a/runtime/vm/ast_transformer.h
+++ b/runtime/vm/ast_transformer.h
@@ -51,7 +51,8 @@
 
  private:
   LocalVariable* EnsureCurrentTempVar();
-  LocalVariable* AddToPreambleNewTempVar(AstNode* node, intptr_t token_pos);
+  LocalVariable* AddToPreambleNewTempVar(AstNode* node,
+                                         TokenPosition token_pos);
   ArgumentListNode* TransformArguments(ArgumentListNode* node);
   AstNode* LazyTransform(const Token::Kind kind,
                          AstNode* new_left,
diff --git a/runtime/vm/atomic.h b/runtime/vm/atomic.h
index 809548a..59a45ac 100644
--- a/runtime/vm/atomic.h
+++ b/runtime/vm/atomic.h
@@ -18,15 +18,17 @@
   // Returns the original value at p.
   //
   // NOTE: Not to be used for any atomic operations involving memory locations
-  // that are accessed by generated code
+  // that are accessed by generated code.
   static uintptr_t FetchAndIncrement(uintptr_t* p);
+  static uintptr_t FetchAndIncrementBy(intptr_t* p, intptr_t value);
 
   // Atomically fetch the value at p and decrement the value at p.
   // Returns the original value at p.
   //
   // NOTE: Not to be used for any atomic operations involving memory locations
-  // that are accessed by generated code
+  // that are accessed by generated code.
   static uintptr_t FetchAndDecrement(uintptr_t* p);
+  static uintptr_t FetchAndDecrementBy(intptr_t* p, intptr_t value);
 
   // Atomically compare *ptr to old_value, and if equal, store new_value.
   // Returns the original value at ptr.
diff --git a/runtime/vm/atomic_android.h b/runtime/vm/atomic_android.h
index 8d01ae7..48f7f37 100644
--- a/runtime/vm/atomic_android.h
+++ b/runtime/vm/atomic_android.h
@@ -21,11 +21,23 @@
 }
 
 
+inline uintptr_t AtomicOperations::FetchAndIncrementBy(intptr_t* p,
+                                                       intptr_t value) {
+  return __sync_fetch_and_add(p, value);
+}
+
+
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
   return __sync_fetch_and_sub(p, 1);
 }
 
 
+inline uintptr_t AtomicOperations::FetchAndDecrementBy(intptr_t* p,
+                                                       intptr_t value) {
+  return __sync_fetch_and_sub(p, value);
+}
+
+
 #if !defined(USING_SIMULATOR)
 inline uword AtomicOperations::CompareAndSwapWord(uword* ptr,
                                                   uword old_value,
diff --git a/runtime/vm/atomic_linux.h b/runtime/vm/atomic_linux.h
index 1150857..0103b53 100644
--- a/runtime/vm/atomic_linux.h
+++ b/runtime/vm/atomic_linux.h
@@ -21,11 +21,23 @@
 }
 
 
+inline uintptr_t AtomicOperations::FetchAndIncrementBy(intptr_t* p,
+                                                       intptr_t value) {
+  return __sync_fetch_and_add(p, value);
+}
+
+
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
   return __sync_fetch_and_sub(p, 1);
 }
 
 
+inline uintptr_t AtomicOperations::FetchAndDecrementBy(intptr_t* p,
+                                                       intptr_t value) {
+  return __sync_fetch_and_sub(p, value);
+}
+
+
 #if !defined(USING_SIMULATOR)
 inline uword AtomicOperations::CompareAndSwapWord(uword* ptr,
                                                   uword old_value,
diff --git a/runtime/vm/atomic_macos.h b/runtime/vm/atomic_macos.h
index 31d219b..1cf951e 100644
--- a/runtime/vm/atomic_macos.h
+++ b/runtime/vm/atomic_macos.h
@@ -21,11 +21,23 @@
 }
 
 
+inline uintptr_t AtomicOperations::FetchAndIncrementBy(intptr_t* p,
+                                                       intptr_t value) {
+  return __sync_fetch_and_add(p, value);
+}
+
+
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
   return __sync_fetch_and_sub(p, 1);
 }
 
 
+inline uintptr_t AtomicOperations::FetchAndDecrementBy(intptr_t* p,
+                                                       intptr_t value) {
+  return __sync_fetch_and_sub(p, value);
+}
+
+
 #if !defined(USING_SIMULATOR)
 inline uword AtomicOperations::CompareAndSwapWord(uword* ptr,
                                                   uword old_value,
diff --git a/runtime/vm/atomic_test.cc b/runtime/vm/atomic_test.cc
index 2e327a5..db9be22 100644
--- a/runtime/vm/atomic_test.cc
+++ b/runtime/vm/atomic_test.cc
@@ -26,6 +26,22 @@
 }
 
 
+UNIT_TEST_CASE(FetchAndIncrementBy) {
+  intptr_t v = 42;
+  EXPECT_EQ(static_cast<uintptr_t>(42),
+            AtomicOperations::FetchAndIncrementBy(&v, 100));
+  EXPECT_EQ(static_cast<intptr_t>(142), v);
+}
+
+
+UNIT_TEST_CASE(FetchAndDecrementBy) {
+  intptr_t v = 42;
+  EXPECT_EQ(static_cast<uintptr_t>(42),
+            AtomicOperations::FetchAndDecrementBy(&v, 41));
+  EXPECT_EQ(static_cast<intptr_t>(1), v);
+}
+
+
 UNIT_TEST_CASE(LoadRelaxed) {
   uword v = 42;
   EXPECT_EQ(static_cast<uword>(42), AtomicOperations::LoadRelaxed(&v));
diff --git a/runtime/vm/atomic_win.h b/runtime/vm/atomic_win.h
index 8e07cd3..2ade768 100644
--- a/runtime/vm/atomic_win.h
+++ b/runtime/vm/atomic_win.h
@@ -28,6 +28,22 @@
 }
 
 
+inline uintptr_t AtomicOperations::FetchAndIncrementBy(intptr_t* p,
+                                                       intptr_t value) {
+#if defined(HOST_ARCH_X64)
+  return static_cast<uintptr_t>(
+      InterlockedExchangeAdd64(reinterpret_cast<LONGLONG*>(p),
+                               static_cast<LONGLONG>(value)));
+#elif defined(HOST_ARCH_IA32)
+  return static_cast<uintptr_t>(
+      InterlockedExchangeAdd(reinterpret_cast<LONG*>(p),
+                             static_cast<LONG>(value)));
+#else
+#error Unsupported host architecture.
+#endif
+}
+
+
 inline uintptr_t AtomicOperations::FetchAndDecrement(uintptr_t* p) {
 #if defined(HOST_ARCH_X64)
   return static_cast<uintptr_t>(
@@ -41,6 +57,22 @@
 }
 
 
+inline uintptr_t AtomicOperations::FetchAndDecrementBy(intptr_t* p,
+                                                       intptr_t value) {
+#if defined(HOST_ARCH_X64)
+  return static_cast<uintptr_t>(
+      InterlockedExchangeAdd64(reinterpret_cast<LONGLONG*>(p),
+                               static_cast<LONGLONG>(-value)));
+#elif defined(HOST_ARCH_IA32)
+  return static_cast<uintptr_t>(
+      InterlockedExchangeAdd(reinterpret_cast<LONG*>(p),
+                             static_cast<LONG>(-value)));
+#else
+#error Unsupported host architecture.
+#endif
+}
+
+
 #if !defined(USING_SIMULATOR)
 inline uword AtomicOperations::CompareAndSwapWord(uword* ptr,
                                                   uword old_value,
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index dc2fcdf..90cf8e6 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -39,6 +39,7 @@
 BENCHMARK(CorelibCompileAll) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+  TransitionNativeToVM transition(thread);
   Timer timer(true, "Compile all of Core lib benchmark");
   timer.Start();
   const Error& error = Error::Handle(Library::CompileAll());
@@ -55,6 +56,7 @@
 BENCHMARK(CorelibCompilerStats) {
   bin::Builtin::SetNativeResolver(bin::Builtin::kBuiltinLibrary);
   bin::Builtin::SetNativeResolver(bin::Builtin::kIOLibrary);
+  TransitionNativeToVM transition(thread);
   CompilerStats* stats = thread->isolate()->compiler_stats();
   ASSERT(stats != NULL);
   stats->EnableBenchmark();
@@ -78,7 +80,7 @@
   const int kNumIterations = 1000;
   Timer timer(true, "CorelibIsolateStartup");
   Isolate* isolate = thread->isolate();
-  Thread::ExitIsolate();
+  Dart_ExitIsolate();
   for (int i = 0; i < kNumIterations; i++) {
     timer.Start();
     TestCase::CreateTestIsolate();
@@ -86,7 +88,7 @@
     Dart_ShutdownIsolate();
   }
   benchmark->set_score(timer.TotalElapsedTime() / kNumIterations);
-  Thread::EnterIsolate(isolate);
+  Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(isolate));
 }
 
 
@@ -142,7 +144,7 @@
                                          int argument_count,
                                          bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   const char* cstr = NULL;
   Dart_Handle result = Dart_StringToCString(name, &cstr);
   EXPECT_VALID(result);
@@ -693,6 +695,7 @@
 
 
 BENCHMARK(SimpleMessage) {
+  TransitionNativeToVM transition(thread);
   const Array& array_object = Array::Handle(Array::New(2));
   array_object.SetAt(0, Integer::Handle(Smi::New(42)));
   array_object.SetAt(1, Object::Handle());
diff --git a/runtime/vm/bitfield.h b/runtime/vm/bitfield.h
index 6108065..42a121a 100644
--- a/runtime/vm/bitfield.h
+++ b/runtime/vm/bitfield.h
@@ -9,26 +9,26 @@
 
 static const uword kUwordOne = 1U;
 
-// BitField is a template for encoding and decoding a bit field inside
-// an unsigned machine word.
-template<typename T, int position, int size>
+// BitField is a template for encoding and decoding a value of type T
+// inside a storage of type S.
+template<typename S, typename T, int position, int size>
 class BitField {
  public:
   static const intptr_t kNextBit = position + size;
 
   // Tells whether the provided value fits into the bit field.
   static bool is_valid(T value) {
-    return (static_cast<uword>(value) & ~((kUwordOne << size) - 1)) == 0;
+    return (static_cast<S>(value) & ~((kUwordOne << size) - 1)) == 0;
   }
 
-  // Returns a uword mask of the bit field.
-  static uword mask() {
+  // Returns a S mask of the bit field.
+  static S mask() {
     return (kUwordOne << size) - 1;
   }
 
-  // Returns a uword mask of the bit field which can be applied directly to
+  // Returns a S mask of the bit field which can be applied directly to
   // to the raw unshifted bits.
-  static uword mask_in_place() {
+  static S mask_in_place() {
     return ((kUwordOne << size) - 1) << position;
   }
 
@@ -43,23 +43,24 @@
     return size;
   }
 
-  // Returns a uword with the bit field value encoded.
-  static uword encode(T value) {
+  // Returns an S with the bit field value encoded.
+  static S encode(T value) {
+    COMPILE_ASSERT((sizeof(S) * kBitsPerByte) >= (position + size));
     ASSERT(is_valid(value));
-    return static_cast<uword>(value) << position;
+    return static_cast<S>(value) << position;
   }
 
   // Extracts the bit field from the value.
-  static T decode(uword value) {
+  static T decode(S value) {
     return static_cast<T>((value >> position) & ((kUwordOne << size) - 1));
   }
 
-  // Returns a uword with the bit field value encoded based on the
+  // Returns an S with the bit field value encoded based on the
   // original value. Only the bits corresponding to this bit field
   // will be changed.
-  static uword update(T value, uword original) {
+  static S update(T value, S original) {
     ASSERT(is_valid(value));
-    return (static_cast<uword>(value) << position) |
+    return (static_cast<S>(value) << position) |
         (~mask_in_place() & original);
   }
 };
diff --git a/runtime/vm/bitfield_test.cc b/runtime/vm/bitfield_test.cc
index 7728b29..a9d41c9 100644
--- a/runtime/vm/bitfield_test.cc
+++ b/runtime/vm/bitfield_test.cc
@@ -10,7 +10,7 @@
 namespace dart {
 
 UNIT_TEST_CASE(BitFields) {
-  class TestBitFields : public BitField<int32_t, 1, 8> {};
+  class TestBitFields : public BitField<uword, int32_t, 1, 8> {};
   EXPECT(TestBitFields::is_valid(16));
   EXPECT(!TestBitFields::is_valid(256));
   EXPECT_EQ(0x00ffU, TestBitFields::mask());
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index f7bd22d..1868f07 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -209,6 +209,9 @@
                                               Dart_Handle uri) {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
+  // This handler calls into the VM directly and does not use the Dart
+  // API so we transition back to VM.
+  TransitionNativeToVM transition(thread);
   if (!Dart_IsLibrary(library)) {
     return Api::NewError("not a library");
   }
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 26e4d5d..00fa958 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -406,6 +406,7 @@
   V(VMService_SendRootServiceMessage, 1)                                       \
   V(VMService_OnStart, 0)                                                      \
   V(VMService_OnExit, 0)                                                       \
+  V(VMService_OnServerAddressChange, 1)                                        \
   V(VMService_ListenStream, 1)                                                 \
   V(VMService_CancelStream, 1)                                                 \
   V(VMService_RequestAssets, 0)                                                \
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 67b3683..ebf9868 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -526,7 +526,13 @@
     ASSERT(type.IsFunctionType());
     const Function& signature =
         Function::Handle(FunctionType::Cast(type).signature());
-    ResolveSignature(cls, signature);
+    const Class& scope_class =
+        Class::Handle(FunctionType::Cast(type).scope_class());
+    if (scope_class.IsTypedefClass()) {
+      ResolveSignature(scope_class, signature);
+    } else {
+      ResolveSignature(cls, signature);
+    }
     resolved_type = type.raw();
   }
   // Mark type as resolved before resolving its type arguments in order to avoid
@@ -1156,7 +1162,13 @@
   if (resolved_type.IsFunctionType()) {
     const Function& signature =
         Function::Handle(Z, FunctionType::Cast(resolved_type).signature());
-    FinalizeSignature(cls, signature);
+    const Class& scope_class =
+        Class::Handle(Z, FunctionType::Cast(resolved_type).scope_class());
+    if (scope_class.IsTypedefClass()) {
+      FinalizeSignature(scope_class, signature);
+    } else {
+      FinalizeSignature(cls, signature);
+    }
   }
 
   if (FLAG_trace_type_finalization) {
@@ -1951,10 +1963,15 @@
   const intptr_t num_super_type_params = super_class.NumTypeParameters();
   AbstractType& type = AbstractType::Handle(zone);
   // The instantiator is mapping finalized type parameters of mixin_class to
-  // unfinalized type parameters of mixin_app_class.
-  ASSERT(aliased_mixin_type.IsFinalized());
+  // unfinalized type parameters of mixin_app_class. Therefore, the type
+  // arguments of mixin_class_super_type must be finalized, since they get
+  // instantiated by this instantiator. Finalizing the types in mixin_class
+  // will finalize mixin_class_super_type.
+  // The aliased_mixin_type does not need to be finalized, but only resolved.
+  ASSERT(aliased_mixin_type.IsResolved());
   const Class& aliased_mixin_type_class = Class::Handle(zone,
       aliased_mixin_type.type_class());
+  FinalizeTypesInClass(mixin_class);
   const intptr_t num_aliased_mixin_type_params =
       aliased_mixin_type_class.NumTypeParameters();
   ASSERT(inserted_class.NumTypeParameters() ==
@@ -2060,10 +2077,10 @@
   const Class& mixin_class = Class::Handle(mixin_type.type_class());
 
   if (FLAG_trace_class_finalization) {
-    THR_Print("Applying mixin type '%s' to %s at pos %" Pd "\n",
+    THR_Print("Applying mixin type '%s' to %s at pos %s\n",
               String::Handle(mixin_type.Name()).ToCString(),
               mixin_app_class.ToCString(),
-              mixin_app_class.token_pos());
+              mixin_app_class.token_pos().ToCString());
   }
 
   // Check for illegal self references.
@@ -2190,10 +2207,10 @@
   // A default constructor will be created for the mixin app alias class.
 
   if (FLAG_trace_class_finalization) {
-    THR_Print("Applying mixin members of %s to %s at pos %" Pd "\n",
+    THR_Print("Applying mixin members of %s to %s at pos %s\n",
               mixin_cls.ToCString(),
               cls.ToCString(),
-              cls.token_pos());
+              cls.token_pos().ToCString());
   }
 
   const GrowableObjectArray& cloned_funcs =
@@ -2553,7 +2570,15 @@
     AbstractType& other_type = AbstractType::Handle();
     if (resolved_type.IsFunctionType()) {
       const Class& scope_class = Class::Handle(resolved_type.type_class());
-      if (!scope_class.is_type_finalized() && scope_class.IsTypedefClass()) {
+      const Function& signature_function =
+          Function::Handle(FunctionType::Cast(resolved_type).signature());
+      // The signature function of this function type may be a local signature
+      // function used in a formal parameter type of the typedef signature, but
+      // not the typedef signature function itself, thus not qualifying as an
+      // illegal self reference.
+      if (!scope_class.is_type_finalized() &&
+          scope_class.IsTypedefClass() &&
+          (scope_class.signature_function() == signature_function.raw())) {
         checking_typedef = true;
         const intptr_t scope_class_id = scope_class.id();
         ASSERT(visited != NULL);
@@ -2580,16 +2605,14 @@
         }
       }
       // Check the result type of the signature of this function type.
-      const Function& function =
-          Function::Handle(FunctionType::Cast(resolved_type).signature());
-      other_type = function.result_type();
+      other_type = signature_function.result_type();
       if (!IsTypedefCycleFree(cls, other_type, visited)) {
         return false;
       }
       // Check the parameter types of the signature of this function type.
-      const intptr_t num_parameters = function.NumParameters();
+      const intptr_t num_parameters = signature_function.NumParameters();
       for (intptr_t i = 0; i < num_parameters; i++) {
-        other_type = function.ParameterTypeAt(i);
+        other_type = signature_function.ParameterTypeAt(i);
         if (!IsTypedefCycleFree(cls, other_type, visited)) {
           return false;
         }
@@ -3119,7 +3142,7 @@
 
 RawType* ClassFinalizer::NewFinalizedMalformedType(const Error& prev_error,
                                                    const Script& script,
-                                                   intptr_t type_pos,
+                                                   TokenPosition type_pos,
                                                    const char* format, ...) {
   va_list args;
   va_start(args, format);
@@ -3179,7 +3202,7 @@
 
 void ClassFinalizer::ReportErrors(const Error& prev_error,
                                   const Class& cls,
-                                  intptr_t token_pos,
+                                  TokenPosition token_pos,
                                   const char* format, ...) {
   va_list args;
   va_start(args, format);
@@ -3191,7 +3214,7 @@
 
 
 void ClassFinalizer::ReportError(const Class& cls,
-                                 intptr_t token_pos,
+                                 TokenPosition token_pos,
                                  const char* format, ...) {
   va_list args;
   va_start(args, format);
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index a8c59a2..92a79ab 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -42,7 +42,7 @@
   // string and its arguments.
   static RawType* NewFinalizedMalformedType(const Error& prev_error,
                                             const Script& script,
-                                            intptr_t type_pos,
+                                            TokenPosition type_pos,
                                             const char* format, ...)
        PRINTF_ATTRIBUTE(4, 5);
 
@@ -166,11 +166,11 @@
                                 va_list args);
   static void ReportError(const Error& error);
   static void ReportError(const Class& cls,
-                          intptr_t token_pos,
+                          TokenPosition token_pos,
                           const char* format, ...) PRINTF_ATTRIBUTE(3, 4);
   static void ReportErrors(const Error& prev_error,
                            const Class& cls,
-                           intptr_t token_pos,
+                           TokenPosition token_pos,
                            const char* format, ...) PRINTF_ATTRIBUTE(4, 5);
 
   // Verify implicit offsets recorded in the VM for direct access to fields of
diff --git a/runtime/vm/class_finalizer_test.cc b/runtime/vm/class_finalizer_test.cc
index 2c87c9c..f1c492e 100644
--- a/runtime/vm/class_finalizer_test.cc
+++ b/runtime/vm/class_finalizer_test.cc
@@ -13,8 +13,8 @@
 static RawClass* CreateTestClass(const char* name) {
   const String& class_name = String::Handle(Symbols::New(name));
   const Script& script = Script::Handle();
-  const Class& cls =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& cls = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   cls.set_interfaces(Object::empty_array());
   cls.SetFunctions(Object::empty_array());
   cls.SetFields(Object::empty_array());
@@ -96,12 +96,12 @@
   const UnresolvedClass& unresolved = UnresolvedClass::Handle(
       UnresolvedClass::New(LibraryPrefix::Handle(),
                            superclass_name,
-                           Token::kNoSourcePos));
+                           TokenPosition::kNoSource));
   const TypeArguments& type_arguments = TypeArguments::Handle();
   rhb.set_super_type(Type::Handle(
       Type::New(Object::Handle(unresolved.raw()),
                 type_arguments,
-                Token::kNoSourcePos)));
+                TokenPosition::kNoSource)));
   EXPECT(ClassFinalizer::ProcessPendingClasses());
 }
 
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index aaabdf4..aa8c366 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -132,7 +132,8 @@
     kTraceAllocationBit = 0,
   };
 
-  class TraceAllocationBit : public BitField<bool, kTraceAllocationBit, 1> {};
+  class TraceAllocationBit :
+      public BitField<intptr_t, bool, kTraceAllocationBit, 1> {};
 
   // Recent old at start of last new GC (used to compute promoted_*).
   intptr_t old_pre_new_gc_count_;
diff --git a/runtime/vm/code_descriptors.cc b/runtime/vm/code_descriptors.cc
index ac4cb24..a286a04 100644
--- a/runtime/vm/code_descriptors.cc
+++ b/runtime/vm/code_descriptors.cc
@@ -3,32 +3,34 @@
 // BSD-style license that can be found in the LICENSE file.
 
 #include "vm/code_descriptors.h"
-#include "vm/compiler.h"
 
 namespace dart {
 
+DECLARE_FLAG(bool, precompilation);
+
 void DescriptorList::AddDescriptor(RawPcDescriptors::Kind kind,
                                    intptr_t pc_offset,
                                    intptr_t deopt_id,
-                                   intptr_t token_pos,
+                                   TokenPosition token_pos,
                                    intptr_t try_index) {
   ASSERT((kind == RawPcDescriptors::kRuntimeCall) ||
          (kind == RawPcDescriptors::kOther) ||
          (deopt_id != Thread::kNoDeoptId));
 
   // When precompiling, we only use pc descriptors for exceptions.
-  if (Compiler::allow_recompilation() || try_index != -1) {
+  if (!FLAG_precompilation || try_index != -1) {
     intptr_t merged_kind_try =
         RawPcDescriptors::MergedKindTry::Encode(kind, try_index);
 
     PcDescriptors::EncodeInteger(&encoded_data_, merged_kind_try);
     PcDescriptors::EncodeInteger(&encoded_data_, pc_offset - prev_pc_offset);
     PcDescriptors::EncodeInteger(&encoded_data_, deopt_id - prev_deopt_id);
-    PcDescriptors::EncodeInteger(&encoded_data_, token_pos - prev_token_pos);
+    PcDescriptors::EncodeInteger(&encoded_data_,
+                                 token_pos.value() - prev_token_pos);
 
     prev_pc_offset = pc_offset;
     prev_deopt_id = deopt_id;
-    prev_token_pos = token_pos;
+    prev_token_pos = token_pos.value();
   }
 }
 
@@ -43,12 +45,13 @@
 
 
 void CodeSourceMapBuilder::AddEntry(intptr_t pc_offset,
-                                    intptr_t token_pos) {
+                                    TokenPosition token_pos) {
   CodeSourceMap::EncodeInteger(&encoded_data_, pc_offset - prev_pc_offset);
-  CodeSourceMap::EncodeInteger(&encoded_data_, token_pos - prev_token_pos);
+  CodeSourceMap::EncodeInteger(&encoded_data_,
+                               token_pos.value() - prev_token_pos);
 
   prev_pc_offset = pc_offset;
-  prev_token_pos = token_pos;
+  prev_token_pos = token_pos.value();
 }
 
 
diff --git a/runtime/vm/code_descriptors.h b/runtime/vm/code_descriptors.h
index 11e3437..c5eeda7 100644
--- a/runtime/vm/code_descriptors.h
+++ b/runtime/vm/code_descriptors.h
@@ -26,7 +26,7 @@
   void AddDescriptor(RawPcDescriptors::Kind kind,
                      intptr_t pc_offset,
                      intptr_t deopt_id,
-                     intptr_t token_pos,
+                     TokenPosition token_pos,
                      intptr_t try_index);
 
   RawPcDescriptors* FinalizePcDescriptors(uword entry_point);
@@ -51,7 +51,7 @@
 
   ~CodeSourceMapBuilder() { }
 
-  void AddEntry(intptr_t pc_offset, intptr_t token_pos);
+  void AddEntry(intptr_t pc_offset, TokenPosition token_pos);
 
   RawCodeSourceMap* Finalize();
 
diff --git a/runtime/vm/code_descriptors_test.cc b/runtime/vm/code_descriptors_test.cc
index 30cedd4..5f8bb1d 100644
--- a/runtime/vm/code_descriptors_test.cc
+++ b/runtime/vm/code_descriptors_test.cc
@@ -18,7 +18,7 @@
 
 namespace dart {
 
-static const intptr_t kPos = Token::kNoSourcePos;
+static const TokenPosition kPos = TokenPosition::kNoSource;
 
 
 CODEGEN_TEST_GENERATE(StackmapCodegen, test) {
@@ -178,7 +178,10 @@
   EXPECT_EQ(10, value);
   EXPECT_VALID(Dart_IntegerToInt64(k, &value));
   EXPECT_EQ(20, value);
-  Isolate::Current()->heap()->CollectAllGarbage();
+  {
+    TransitionNativeToVM transition(Thread::Current());
+    Isolate::Current()->heap()->CollectAllGarbage();
+  }
 }
 
 
@@ -211,6 +214,8 @@
       "}\n";
   // First setup the script and compile the script.
   TestCase::LoadTestScript(kScriptChars, native_resolver);
+  TransitionNativeToVM transition(thread);
+
   EXPECT(ClassFinalizer::ProcessPendingClasses());
   const String& name = String::Handle(String::New(TestCase::url()));
   const Library& lib = Library::Handle(Library::LookupLibrary(name));
@@ -248,7 +253,8 @@
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
   int call_count = 0;
-  PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kUnoptStaticCall);
+  PcDescriptors::Iterator iter(descriptors,
+                               RawPcDescriptors::kUnoptStaticCall);
   while (iter.MoveNext()) {
     stackmap_table_builder->AddEntry(iter.PcOffset(), stack_bitmap, 0);
     ++call_count;
@@ -287,15 +293,15 @@
     33,
     5,
     5,
-    Token::kMinSourcePos,
-    Token::kMaxSourcePos,
+    TokenPosition::kMinSourcePos,
+    TokenPosition::kMaxSourcePos,
   };
   const intptr_t num_token_positions =
       sizeof(token_positions) / sizeof(token_positions[0]);
 
   for (intptr_t i = 0; i < num_token_positions; i++) {
     descriptors->AddDescriptor(RawPcDescriptors::kRuntimeCall, 0, 0,
-                               token_positions[i], 0);
+                               TokenPosition(token_positions[i]), 0);
   }
 
   const PcDescriptors& finalized_descriptors =
@@ -307,11 +313,11 @@
 
   intptr_t i = 0;
   while (it.MoveNext()) {
-    if (token_positions[i] != it.TokenPos()) {
+    if (token_positions[i] != it.TokenPos().value()) {
       OS::Print("[%" Pd "]: Expected: %" Pd " != %" Pd "\n",
-                i, token_positions[i], it.TokenPos());
+                i, token_positions[i], it.TokenPos().value());
     }
-    EXPECT(token_positions[i] == it.TokenPos());
+    EXPECT(token_positions[i] == it.TokenPos().value());
     i++;
   }
 }
@@ -333,8 +339,8 @@
     33,
     5,
     5,
-    Token::kMinSourcePos,
-    Token::kMaxSourcePos,
+    TokenPosition::kMinSourcePos,
+    TokenPosition::kMaxSourcePos,
   };
   const intptr_t num_token_positions =
       sizeof(token_positions) / sizeof(token_positions[0]);
@@ -343,7 +349,7 @@
   ASSERT(builder != NULL);
 
   for (intptr_t i = 0; i < num_token_positions; i++) {
-    builder->AddEntry(i, token_positions[i]);
+    builder->AddEntry(i, TokenPosition(token_positions[i]));
   }
 
   const CodeSourceMap& code_Source_map =
@@ -355,11 +361,11 @@
   uintptr_t i = 0;
   while (it.MoveNext()) {
     EXPECT(it.PcOffset() == i);
-    if (token_positions[i] != it.TokenPos()) {
+    if (token_positions[i] != it.TokenPos().value()) {
       OS::Print("[%" Pd "]: Expected: %" Pd " != %" Pd "\n",
-                i, token_positions[i], it.TokenPos());
+                i, token_positions[i], it.TokenPos().value());
     }
-    EXPECT(token_positions[i] == it.TokenPos());
+    EXPECT(token_positions[i] == it.TokenPos().value());
     i++;
   }
 }
diff --git a/runtime/vm/code_generator.cc b/runtime/vm/code_generator.cc
index d0cdd74e..0a207de 100644
--- a/runtime/vm/code_generator.cc
+++ b/runtime/vm/code_generator.cc
@@ -63,6 +63,7 @@
 DECLARE_FLAG(bool, trace_optimizing_compiler);
 DECLARE_FLAG(bool, warn_on_javascript_compatibility);
 DECLARE_FLAG(int, max_polymorphic_checks);
+DECLARE_FLAG(bool, precompilation);
 
 DEFINE_FLAG(bool, use_osr, true, "Use on-stack replacement.");
 DEFINE_FLAG(bool, trace_osr, false, "Trace attempts at on-stack replacement.");
@@ -147,7 +148,7 @@
 
 
 // Helper returning the token position of the Dart caller.
-static intptr_t GetCallerLocation() {
+static TokenPosition GetCallerLocation() {
   DartFrameIterator iterator;
   StackFrame* caller_frame = iterator.NextFrame();
   ASSERT(caller_frame != NULL);
@@ -207,7 +208,7 @@
   type = type.InstantiateFrom(instantiator, &bound_error, NULL, Heap::kOld);
   if (!bound_error.IsNull()) {
     // Throw a dynamic type error.
-    const intptr_t location = GetCallerLocation();
+    const TokenPosition location = GetCallerLocation();
     String& bound_error_message =  String::Handle(
         String::New(bound_error.ToErrorCString()));
     Exceptions::CreateAndThrowTypeError(
@@ -246,7 +247,7 @@
                                                       &bound_error);
     if (!bound_error.IsNull()) {
       // Throw a dynamic type error.
-      const intptr_t location = GetCallerLocation();
+      const TokenPosition location = GetCallerLocation();
       String& bound_error_message =  String::Handle(
           String::New(bound_error.ToErrorCString()));
       Exceptions::CreateAndThrowTypeError(
@@ -475,7 +476,7 @@
   }
   if (!result.value() && !bound_error.IsNull()) {
     // Throw a dynamic type error only if the instanceof test fails.
-    const intptr_t location = GetCallerLocation();
+    const TokenPosition location = GetCallerLocation();
     String& bound_error_message =  String::Handle(
         String::New(bound_error.ToErrorCString()));
     Exceptions::CreateAndThrowTypeError(
@@ -522,7 +523,7 @@
   }
   if (!is_instance_of) {
     // Throw a dynamic type error.
-    const intptr_t location = GetCallerLocation();
+    const TokenPosition location = GetCallerLocation();
     const AbstractType& src_type = AbstractType::Handle(src_instance.GetType());
     String& src_type_name = String::Handle(src_type.UserVisibleName());
     String& dst_type_name = String::Handle();
@@ -575,7 +576,7 @@
 // Arg0: bad object.
 // Return value: none, throws TypeError or AssertionError.
 DEFINE_RUNTIME_ENTRY(NonBoolTypeError, 1) {
-  const intptr_t location = GetCallerLocation();
+  const TokenPosition location = GetCallerLocation();
   const Instance& src_instance = Instance::CheckedHandle(arguments.ArgAt(0));
 
   if (src_instance.IsNull()) {
@@ -612,7 +613,7 @@
 // Arg2: type of destination being assigned to.
 // Return value: none, throws an exception.
 DEFINE_RUNTIME_ENTRY(BadTypeError, 3) {
-  const intptr_t location = GetCallerLocation();
+  const TokenPosition location = GetCallerLocation();
   const Instance& src_value = Instance::CheckedHandle(arguments.ArgAt(0));
   const String& dst_name = String::CheckedHandle(arguments.ArgAt(1));
   const AbstractType& dst_type =
@@ -1377,10 +1378,10 @@
     intptr_t num_frames = stack->Length();
     for (intptr_t i = 0; i < num_frames; i++) {
       ActivationFrame* frame = stack->FrameAt(i);
-      // Variable locations and number are unknown when 'always_optimize'.
+      // Variable locations and number are unknown when precompiling.
       const int num_vars =
-         Compiler::always_optimize() ? 0 : frame->NumLocalVariables();
-      intptr_t unused;
+         FLAG_precompilation ? 0 : frame->NumLocalVariables();
+      TokenPosition unused = TokenPosition::kNoSource;
       for (intptr_t v = 0; v < num_vars; v++) {
         frame->VariableAt(v, &var_name, &unused, &unused, &var_value);
       }
diff --git a/runtime/vm/code_generator_test.cc b/runtime/vm/code_generator_test.cc
index bea6025..e3c33a5 100644
--- a/runtime/vm/code_generator_test.cc
+++ b/runtime/vm/code_generator_test.cc
@@ -20,7 +20,7 @@
 
 namespace dart {
 
-static const intptr_t kPos = 0;
+static const TokenPosition kPos = TokenPosition::kMinSource;
 
 
 CODEGEN_TEST_GENERATE(SimpleReturnCodegen, test) {
diff --git a/runtime/vm/code_patcher_arm64_test.cc b/runtime/vm/code_patcher_arm64_test.cc
index bd569fc..32d8ada 100644
--- a/runtime/vm/code_patcher_arm64_test.cc
+++ b/runtime/vm/code_patcher_arm64_test.cc
@@ -23,12 +23,13 @@
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const Array& args_descriptor =
diff --git a/runtime/vm/code_patcher_arm_test.cc b/runtime/vm/code_patcher_arm_test.cc
index f7d741f..06b9f8c 100644
--- a/runtime/vm/code_patcher_arm_test.cc
+++ b/runtime/vm/code_patcher_arm_test.cc
@@ -23,12 +23,13 @@
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const Array& args_descriptor =
diff --git a/runtime/vm/code_patcher_ia32_test.cc b/runtime/vm/code_patcher_ia32_test.cc
index a8184bf..26fe49f 100644
--- a/runtime/vm/code_patcher_ia32_test.cc
+++ b/runtime/vm/code_patcher_ia32_test.cc
@@ -23,12 +23,13 @@
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const Array& args_descriptor =
diff --git a/runtime/vm/code_patcher_mips_test.cc b/runtime/vm/code_patcher_mips_test.cc
index 676a1b0..e99a987 100644
--- a/runtime/vm/code_patcher_mips_test.cc
+++ b/runtime/vm/code_patcher_mips_test.cc
@@ -23,12 +23,13 @@
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const Array& args_descriptor =
diff --git a/runtime/vm/code_patcher_x64_test.cc b/runtime/vm/code_patcher_x64_test.cc
index 7d1f31d..13d2978 100644
--- a/runtime/vm/code_patcher_x64_test.cc
+++ b/runtime/vm/code_patcher_x64_test.cc
@@ -23,12 +23,13 @@
 ASSEMBLER_TEST_GENERATE(IcDataAccess, assembler) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const String& function_name = String::Handle(Symbols::New("callerFunction"));
   const Function& function = Function::Handle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
 
   const String& target_name = String::Handle(String::New("targetFunction"));
   const Array& args_descriptor =
diff --git a/runtime/vm/compiler.cc b/runtime/vm/compiler.cc
index 7479506..c98bfe3 100644
--- a/runtime/vm/compiler.cc
+++ b/runtime/vm/compiler.cc
@@ -75,11 +75,9 @@
 DECLARE_FLAG(bool, trace_failed_optimization_attempts);
 DECLARE_FLAG(bool, trace_inlining_intervals);
 DECLARE_FLAG(bool, trace_irregexp);
+DECLARE_FLAG(bool, precompilation);
 
 
-bool Compiler::always_optimize_ = false;
-bool Compiler::allow_recompilation_ = true;
-
 #ifndef DART_PRECOMPILED_RUNTIME
 
 // TODO(zerny): Factor out unoptimizing/optimizing pipelines and remove
@@ -550,7 +548,7 @@
     // Register code with the classes it depends on because of CHA and
     // fields it depends on because of store guards, unless we cannot
     // deopt.
-    if (Compiler::allow_recompilation()) {
+    if (!FLAG_precompilation) {
       // Deoptimize field dependent code first, before registering
       // this yet uninstalled code as dependent on a field.
       // TODO(srdjan): Debugging dart2js crashes;
@@ -575,7 +573,7 @@
       }
     }
   } else {  // not optimized.
-    if (!Compiler::always_optimize() &&
+    if (!FLAG_precompilation &&
         (function.ic_data_array() == Array::null())) {
       function.SaveICDataMap(
           graph_compiler->deopt_id_to_ic_data(),
@@ -726,7 +724,7 @@
         FlowGraphOptimizer optimizer(flow_graph,
                                      use_speculative_inlining,
                                      &inlining_black_list);
-        if (Compiler::always_optimize()) {
+        if (FLAG_precompilation) {
           optimizer.PopulateWithICData();
 
           optimizer.ApplyClassIds();
@@ -1058,14 +1056,13 @@
           // instruction object, since the creation of instruction object
           // changes code page access permissions (makes them temporary not
           // executable).
-          isolate()->thread_registry()->SafepointThreads();
           {
+            SafepointOperationScope safepoint_scope(thread());
             // Do not Garbage collect during this stage and instead allow the
             // heap to grow.
             NoHeapGrowthControlScope no_growth_control;
             FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
           }
-          isolate()->thread_registry()->ResumeAllThreads();
           if (isolate()->heap()->NeedsGarbageCollection()) {
             isolate()->heap()->CollectAllGarbage();
           }
@@ -1092,7 +1089,7 @@
         // that caused the bailout.
         done = false;
 #if defined(DEBUG)
-        ASSERT(Compiler::always_optimize());
+        ASSERT(FLAG_precompilation);
         ASSERT(use_speculative_inlining);
         for (intptr_t i = 0; i < inlining_black_list.length(); ++i) {
           ASSERT(inlining_black_list[i] != val);
@@ -1220,7 +1217,8 @@
         THR_Print("  context var '%s' level %d offset %d",
             var_name.ToCString(), var_info.scope_id, var_info.index());
       }
-      THR_Print(" (valid %d-%d)\n", var_info.begin_pos, var_info.end_pos);
+      THR_Print(" (valid %s-%s)\n", var_info.begin_pos.ToCString(),
+                                    var_info.end_pos.ToCString());
     }
   }
   THR_Print("}\n");
@@ -1296,11 +1294,11 @@
                                        const Function& function,
                                        bool optimized,
                                        intptr_t osr_id) {
-  // Check that we optimize if 'Compiler::always_optimize()' is set to true,
+  // Check that we optimize if 'FLAG_precompilation' is set to true,
   // except if the function is marked as not optimizable.
   ASSERT(!function.IsOptimizable() ||
-         !Compiler::always_optimize() || optimized);
-  ASSERT(Compiler::allow_recompilation() || !function.HasCode());
+         !FLAG_precompilation || optimized);
+  ASSERT(!FLAG_precompilation || !function.HasCode());
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
     Thread* const thread = Thread::Current();
@@ -1316,12 +1314,14 @@
     ParsedFunction* parsed_function = new(zone) ParsedFunction(
         thread, Function::ZoneHandle(zone, function.raw()));
     if (trace_compiler) {
-      THR_Print("Compiling %s%sfunction: '%s' @ token %" Pd ", size %" Pd "\n",
+      const intptr_t token_size = function.end_token_pos().Pos() -
+                                  function.token_pos().Pos();
+      THR_Print("Compiling %s%sfunction: '%s' @ token %s, size %" Pd "\n",
                 (osr_id == Compiler::kNoOSRDeoptId ? "" : "osr "),
                 (optimized ? "optimized " : ""),
                 function.ToFullyQualifiedCString(),
-                function.token_pos(),
-                (function.end_token_pos() - function.token_pos()));
+                function.token_pos().ToCString(),
+                token_size);
     }
     INC_STAT(thread, num_functions_compiled, 1);
     if (optimized) {
@@ -1340,7 +1340,7 @@
     CompileParsedFunctionHelper helper(parsed_function, optimized, osr_id);
     const bool success = helper.Compile(pipeline);
     if (!success) {
-      if (optimized && !Compiler::always_optimize()) {
+      if (optimized && !FLAG_precompilation) {
         // Optimizer bailed out. Disable optimizations and never try again.
         if (trace_compiler) {
           THR_Print("--> disabling optimizations for '%s'\n",
@@ -1399,7 +1399,7 @@
     isolate->object_store()->clear_sticky_error();
     // Unoptimized compilation or precompilation may encounter compile-time
     // errors, but regular optimized compilation should not.
-    ASSERT(!optimized || Compiler::always_optimize());
+    ASSERT(!optimized || FLAG_precompilation);
     // Do not attempt to optimize functions that can cause errors.
     function.set_is_optimizable(false);
     return error.raw();
@@ -1416,9 +1416,9 @@
   TIMELINE_FUNCTION_COMPILATION_DURATION(thread, "Function", function);
 
   if (!isolate->compilation_allowed()) {
-    FATAL3("Precompilation missed function %s (%" Pd ", %s)\n",
+    FATAL3("Precompilation missed function %s (%s, %s)\n",
            function.ToLibNamePrefixedQualifiedCString(),
-           function.token_pos(),
+           function.token_pos().ToCString(),
            Function::KindToCString(function.kind()));
   }
 
@@ -1426,7 +1426,7 @@
       CompilationPipeline::New(thread->zone(), function);
 
   const bool optimized =
-      Compiler::always_optimize() && function.IsOptimizable();
+      FLAG_precompilation && function.IsOptimizable();
 
   return CompileFunctionHelper(pipeline,
                                function,
@@ -1899,9 +1899,7 @@
   {
     MonitorLocker ml_done(done_monitor);
     while (!(*task_done)) {
-      // In case that the compiler is waiting for safepoint.
-      Isolate::Current()->thread_registry()->CheckSafepoint();
-      ml_done.Wait(1);
+      ml_done.WaitWithSafepointCheck(Thread::Current());
     }
   }
   delete task_done;
diff --git a/runtime/vm/compiler.h b/runtime/vm/compiler.h
index 130567d..4aa4249 100644
--- a/runtime/vm/compiler.h
+++ b/runtime/vm/compiler.h
@@ -93,22 +93,7 @@
   // Returns Error::null() if there is no compilation error.
   static RawError* CompileAllFunctions(const Class& cls);
 
-  // The following global flags are changed by --noopt handler;
-  // the flags are changed when generating best unoptimized code (no runtime
-  // feedback, no deoptimization).
-
-  // Default: false.
-  static bool always_optimize() { return always_optimize_; }
-  static void set_always_optimize(bool value) { always_optimize_ = value; }
-
-  static bool allow_recompilation() { return allow_recompilation_; }
-  static void set_allow_recompilation(bool value) {
-    allow_recompilation_ = value;
-  }
-
- private:
-  static bool always_optimize_;
-  static bool allow_recompilation_;
+  static bool always_optimize();
 };
 
 
diff --git a/runtime/vm/compiler_stats.cc b/runtime/vm/compiler_stats.cc
index d5b20f4..d120682 100644
--- a/runtime/vm/compiler_stats.cc
+++ b/runtime/vm/compiler_stats.cc
@@ -33,7 +33,7 @@
     obj_ = raw_obj;
     if (obj_.GetClassId() == TokenStream::kClassId) {
       TokenStream::Iterator tkit(TokenStream::Cast(obj_),
-                                 0,
+                                 TokenPosition::kMinSource,
                                  TokenStream::Iterator::kNoNewlines);
       Token::Kind kind = tkit.CurrentTokenKind();
       while (kind != Token::kEOS) {
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index cab1593..f1b916c 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -8,16 +8,16 @@
 #include "vm/compiler.h"
 #include "vm/dart_api_impl.h"
 #include "vm/object.h"
+#include "vm/safepoint.h"
 #include "vm/symbols.h"
 #include "vm/thread_pool.h"
-#include "vm/thread_registry.h"
 #include "vm/unit_test.h"
 
 namespace dart {
 
 DECLARE_FLAG(bool, background_compilation);
 
-TEST_CASE(CompileScript) {
+VM_TEST_CASE(CompileScript) {
   const char* kScriptChars =
       "class A {\n"
       "  static foo() { return 42; }\n"
@@ -32,7 +32,7 @@
 }
 
 
-TEST_CASE(CompileFunction) {
+VM_TEST_CASE(CompileFunction) {
   const char* kScriptChars =
             "class A {\n"
             "  static foo() { return 42; }\n"
@@ -73,7 +73,7 @@
 }
 
 
-TEST_CASE(CompileFunctionOnHelperThread) {
+VM_TEST_CASE(CompileFunctionOnHelperThread) {
   // Create a simple function and compile it without optimization.
   const char* kScriptChars =
             "class A {\n"
@@ -106,8 +106,7 @@
   Monitor* m = new Monitor();
   MonitorLocker ml(m);
   while (!func.HasOptimizedCode()) {
-    Isolate::Current()->thread_registry()->CheckSafepoint();
-    ml.Wait(1);
+    ml.WaitWithSafepointCheck(thread, 1);
   }
   BackgroundCompiler::Stop(isolate->background_compiler());
 }
@@ -167,6 +166,7 @@
       Dart_Invoke(lib, Dart_NewStringFromCString("makeObj"), 0,  NULL);
   EXPECT(!Dart_IsNull(obj_handle));
   EXPECT(!Dart_IsError(obj_handle));
+  TransitionNativeToVM transition(thread);
   const Object& obj = Object::Handle(Api::UnwrapHandle(obj_handle));
   EXPECT(!obj.IsNull());
   EXPECT(obj.IsInstance());
@@ -184,7 +184,7 @@
 }
 
 
-TEST_CASE(EvalExpressionWithLazyCompile) {
+VM_TEST_CASE(EvalExpressionWithLazyCompile) {
   Library& lib = Library::Handle(Library::CoreLibrary());
 
   const String& expression = String::Handle(String::New(
@@ -199,7 +199,7 @@
 }
 
 
-TEST_CASE(EvalExpressionExhaustCIDs) {
+VM_TEST_CASE(EvalExpressionExhaustCIDs) {
   Library& lib = Library::Handle(Library::CoreLibrary());
 
   const String& expression = String::Handle(String::New("3 + 4"));
diff --git a/runtime/vm/coverage.cc b/runtime/vm/coverage.cc
index 42dff5e..acb61f3 100644
--- a/runtime/vm/coverage.cc
+++ b/runtime/vm/coverage.cc
@@ -41,10 +41,13 @@
     (*map)[i] = -1;
   }
 #endif
-  TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
+  TokenStream::Iterator tkit(tkns,
+                             TokenPosition::kMinSource,
+                             TokenStream::Iterator::kAllTokens);
   intptr_t cur_line = script.line_offset() + 1;
   while (tkit.CurrentTokenKind() != Token::kEOS) {
-    (*map)[tkit.CurrentPosition()] = cur_line;
+    const intptr_t position = tkit.CurrentPosition().Pos();
+    (*map)[position] = cur_line;
     if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
       cur_line++;
     }
@@ -87,8 +90,8 @@
   const PcDescriptors& descriptors = PcDescriptors::Handle(
       zone, code.pc_descriptors());
 
-  const intptr_t begin_pos = function.token_pos();
-  const intptr_t end_pos = function.end_token_pos();
+  const TokenPosition begin_pos = function.token_pos();
+  const TokenPosition end_pos = function.end_token_pos();
   intptr_t last_line = -1;
   intptr_t last_count = 0;
   // Only IC based calls have counting.
@@ -98,16 +101,18 @@
     HANDLESCOPE(thread);
     const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
     if (!ic_data->IsNull()) {
-      const intptr_t token_pos = iter.TokenPos();
+      const TokenPosition token_pos = iter.TokenPos();
       // Filter out descriptors that do not map to tokens in the source code.
       if ((token_pos < begin_pos) || (token_pos > end_pos)) {
         continue;
       }
       if (as_call_sites) {
         bool is_static_call = iter.Kind() == RawPcDescriptors::kUnoptStaticCall;
-        ic_data->PrintToJSONArray(hits_or_sites, token_pos, is_static_call);
+        ic_data->PrintToJSONArray(hits_or_sites,
+                                  token_pos,
+                                  is_static_call);
       } else {
-        intptr_t line = pos_to_line[token_pos];
+        intptr_t line = pos_to_line[token_pos.Pos()];
 #if defined(DEBUG)
         const Script& script = Script::Handle(zone, function.script());
         intptr_t test_line = -1;
diff --git a/runtime/vm/coverage_test.cc b/runtime/vm/coverage_test.cc
index 1a2b0eb..f1afe992 100644
--- a/runtime/vm/coverage_test.cc
+++ b/runtime/vm/coverage_test.cc
@@ -9,6 +9,7 @@
 namespace dart {
 
 static RawObject* ExecuteScript(const char* script) {
+  TransitionVMToNative transition(Thread::Current());
   Dart_Handle h_lib = TestCase::LoadTestScript(script, NULL);
   EXPECT_VALID(h_lib);
   Library& lib = Library::Handle();
@@ -34,7 +35,7 @@
 };
 
 
-TEST_CASE(Coverage_Empty) {
+VM_TEST_CASE(Coverage_Empty) {
   const char* kScript =
       "main() {\n"
       "}";
@@ -56,7 +57,7 @@
 }
 
 
-TEST_CASE(Coverage_MainWithClass) {
+VM_TEST_CASE(Coverage_MainWithClass) {
   const char* kScript =
       "class Foo {\n"
       "  var x;\n"
@@ -100,7 +101,7 @@
 }
 
 
-TEST_CASE(Coverage_FilterFunction) {
+VM_TEST_CASE(Coverage_FilterFunction) {
   const char* kScript =
       "class Foo {\n"
       "  var x;\n"
diff --git a/runtime/vm/custom_isolate_test.cc b/runtime/vm/custom_isolate_test.cc
index b78ea60..8f7796d 100644
--- a/runtime/vm/custom_isolate_test.cc
+++ b/runtime/vm/custom_isolate_test.cc
@@ -230,7 +230,7 @@
                                         int argc,
                                         bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   const char* name_str = NULL;
   EXPECT(Dart_IsString(name));
   EXPECT_VALID(Dart_StringToCString(name, &name_str));
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index d316138..09c2a10 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -7,6 +7,7 @@
 #include "include/dart_native_api.h"
 
 #include "platform/assert.h"
+#include "lib/stacktrace.h"
 #include "vm/class_finalizer.h"
 #include "vm/compiler.h"
 #include "vm/dart.h"
@@ -354,6 +355,26 @@
 }
 
 
+static const char* GetErrorString(Thread* thread, const Object& obj) {
+  // This function requires an API scope to be present.
+  if (obj.IsError()) {
+    ASSERT(thread->api_top_scope() != NULL);
+    const Error& error = Error::Cast(obj);
+    const char* str = error.ToErrorCString();
+    intptr_t len = strlen(str) + 1;
+    char* str_copy = Api::TopScope(thread)->zone()->Alloc<char>(len);
+    strncpy(str_copy, str, len);
+    // Strip a possible trailing '\n'.
+    if ((len > 1) && (str_copy[len - 2] == '\n')) {
+      str_copy[len - 2] = '\0';
+    }
+    return str_copy;
+  } else {
+    return "";
+  }
+}
+
+
 Dart_Handle Api::InitNewHandle(Thread* thread, RawObject* raw) {
   LocalHandles* local_handles = Api::TopScope(thread)->local_handles();
   ASSERT(local_handles != NULL);
@@ -448,7 +469,9 @@
 
 
 Dart_Handle Api::NewError(const char* format, ...) {
-  DARTSCOPE(Thread::Current());
+  Thread* T = Thread::Current();
+  CHECK_API_SCOPE(T);
+  HANDLESCOPE(T);
   CHECK_CALLBACK_STATE(T);
 
   va_list args;
@@ -745,20 +768,7 @@
   API_TIMELINE_DURATION;
   DARTSCOPE(Thread::Current());
   const Object& obj = Object::Handle(Z, Api::UnwrapHandle(handle));
-  if (obj.IsError()) {
-    const Error& error = Error::Cast(obj);
-    const char* str = error.ToErrorCString();
-    intptr_t len = strlen(str) + 1;
-    char* str_copy = Api::TopScope(T)->zone()->Alloc<char>(len);
-    strncpy(str_copy, str, len);
-    // Strip a possible trailing '\n'.
-    if ((len > 1) && (str_copy[len - 2] == '\n')) {
-      str_copy[len - 2] = '\0';
-    }
-    return str_copy;
-  } else {
-    return "";
-  }
+  return GetErrorString(T, obj);
 }
 
 
@@ -815,7 +825,8 @@
   Instance& obj = Instance::Handle(Z);
   intptr_t class_id = Api::ClassId(exception);
   if ((class_id == kApiErrorCid) || (class_id == kLanguageErrorCid)) {
-    obj = String::New(::Dart_GetError(exception));
+    const Object& excp = Object::Handle(Z, Api::UnwrapHandle(exception));
+    obj = String::New(GetErrorString(T, excp));
   } else {
     obj = Api::UnwrapInstanceHandle(Z, exception).raw();
     if (obj.IsNull()) {
@@ -845,6 +856,7 @@
     return Api::NewError("No Dart frames on stack, cannot propagate error.");
   }
 
+  TransitionNativeToVM transition(thread);
   // Unwind all the API scopes till the exit frame before propagating.
   const Error* error;
   {
@@ -1030,6 +1042,7 @@
   if (callback == NULL) {
     return NULL;
   }
+  TransitionNativeToVM transition(thread);
   return AllocateFinalizableHandle(thread,
                                    object,
                                    peer,
@@ -1248,6 +1261,12 @@
   #endif  // defined(DART_NO_SNAPSHOT).
       // We exit the API scope entered above.
       Dart_ExitScope();
+      // A Thread structure has been associated to the thread, we do the
+      // safepoint transition explicity here instead of using the
+      // TransitionXXX scope objects as the reverse transition happens
+      // outside this scope in Dart_ShutdownIsolate/Dart_ExitIsolate.
+      T->set_execution_state(Thread::kThreadInNative);
+      T->EnterSafepoint();
       return Api::CastIsolate(I);
     }
     *error = strdup(error_obj.ToErrorCString());
@@ -1269,6 +1288,12 @@
     HandleScope handle_scope(T);
     Dart::RunShutdownCallback();
   }
+  // The Thread structure is disassociated from the isolate, we do the
+  // safepoint transition explicity here instead of using the TransitionXXX
+  // scope objects as the original transition happened outside this scope in
+  // Dart_EnterIsolate/Dart_CreateIsolate.
+  T->ExitSafepoint();
+  T->set_execution_state(Thread::kThreadInVM);
   Dart::ShutdownIsolate();
 }
 
@@ -1312,6 +1337,13 @@
   if (!Thread::EnterIsolate(iso)) {
     FATAL("Unable to Enter Isolate as Dart VM is shutting down");
   }
+  // A Thread structure has been associated to the thread, we do the
+  // safepoint transition explicity here instead of using the
+  // TransitionXXX scope objects as the reverse transition happens
+  // outside this scope in Dart_ExitIsolate/Dart_ShutdownIsolate.
+  Thread* T = Thread::Current();
+  T->set_execution_state(Thread::kThreadInNative);
+  T->EnterSafepoint();
 }
 
 
@@ -1334,7 +1366,15 @@
 
 
 DART_EXPORT void Dart_ExitIsolate() {
-  CHECK_ISOLATE(Isolate::Current());
+  Thread* T = Thread::Current();
+  CHECK_ISOLATE(T->isolate());
+  // The Thread structure is disassociated from the isolate, we do the
+  // safepoint transition explicity here instead of using the TransitionXXX
+  // scope objects as the original transition happened outside this scope in
+  // Dart_EnterIsolate/Dart_CreateIsolate.
+  ASSERT(T->execution_state() == Thread::kThreadInNative);
+  T->ExitSafepoint();
+  T->set_execution_state(Thread::kThreadInVM);
   Thread::ExitIsolate();
 }
 
@@ -1376,8 +1416,6 @@
   I->heap()->IterateObjects(&check_canonical);
 #endif  // #if defined(DEBUG).
 
-  // Since this is only a snapshot the root library should not be set.
-  I->object_store()->set_root_library(Library::Handle(Z));
   FullSnapshotWriter writer(vm_isolate_snapshot_buffer,
                             isolate_snapshot_buffer,
                             NULL, /* instructions_snapshot_buffer */
@@ -1500,7 +1538,7 @@
   {
     // The message handler run loop does not expect to have a current isolate
     // so we exit the isolate here and enter it again after the runloop is done.
-    Thread::ExitIsolate();
+    Dart_ExitIsolate();
     RunLoopData data;
     data.monitor = &monitor;
     data.done = false;
@@ -1510,9 +1548,7 @@
     while (!data.done) {
       ml.Wait();
     }
-    if (!Thread::EnterIsolate(I)) {
-      FATAL("Inconsistent state, VM shutting down while in run loop.");
-    }
+    ::Dart_EnterIsolate(Api::CastIsolate(I));
   }
   if (I->object_store()->sticky_error() != Object::null()) {
     Dart_Handle error = Api::NewHandle(T, I->object_store()->sticky_error());
@@ -1533,6 +1569,7 @@
   CHECK_API_SCOPE(T);
   CHECK_CALLBACK_STATE(T);
   API_TIMELINE_BEGIN_END;
+  TransitionNativeToVM transition(T);
   if (I->message_handler()->HandleNextMessage() != MessageHandler::kOK) {
     Dart_Handle error = Api::NewHandle(T, I->object_store()->sticky_error());
     I->object_store()->clear_sticky_error();
@@ -1548,6 +1585,7 @@
   CHECK_API_SCOPE(T);
   CHECK_CALLBACK_STATE(T);
   API_TIMELINE_DURATION;
+  TransitionNativeToVM transition(T);
   ASSERT(I->GetAndClearResumeRequest() == false);
   MessageHandler::MessageStatus status =
       I->message_handler()->HandleOOBMessages();
@@ -4384,6 +4422,7 @@
     return Api::NewError("No Dart frames on stack, cannot throw exception");
   }
 
+  TransitionNativeToVM transition(thread);
   // Unwind all the API scopes till the exit frame before throwing an
   // exception.
   const Instance* saved_exception;
@@ -4422,6 +4461,7 @@
     return Api::NewError("No Dart frames on stack, cannot throw exception");
   }
 
+  TransitionNativeToVM transition(thread);
   // Unwind all the API scopes till the exit frame before throwing an
   // exception.
   const Instance* saved_exception;
@@ -4794,6 +4834,11 @@
   NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
   ASSERT(arguments->thread()->isolate() == Isolate::Current());
   if ((retval != Api::Null()) && (!Api::IsInstance(retval))) {
+    // Print the current stack trace to make the problematic caller
+    // easier to find.
+    const Stacktrace& stacktrace = GetCurrentStacktrace(0);
+    OS::PrintErr("=== Current Trace:\n%s===\n", stacktrace.ToCString());
+
     const Object& ret_obj = Object::Handle(Api::UnwrapHandle(retval));
     FATAL1("Return value check failed: saw '%s' expected a dart Instance.",
            ret_obj.ToCString());
@@ -4819,10 +4864,11 @@
 // --- Environment ---
 RawString* Api::CallEnvironmentCallback(Thread* thread, const String& name) {
   Isolate* isolate = thread->isolate();
-  Scope api_scope(thread);
   Dart_EnvironmentCallback callback = isolate->environment_callback();
   String& result = String::Handle(thread->zone());
   if (callback != NULL) {
+    TransitionVMToNative transition(thread);
+    Scope api_scope(thread);
     Dart_Handle response = callback(Api::NewHandle(thread, name.raw()));
     if (::Dart_IsString(response)) {
       result ^= Api::UnwrapHandle(response);
@@ -5126,7 +5172,7 @@
 
   // Construct the type object, canonicalize it and return.
   Type& instantiated_type = Type::Handle(
-      Type::New(cls, type_args_obj, Token::kNoSourcePos));
+      Type::New(cls, type_args_obj, TokenPosition::kNoSource));
   instantiated_type ^= ClassFinalizer::FinalizeType(
       cls, instantiated_type, ClassFinalizer::kCanonicalize);
   return Api::NewHandle(T, instantiated_type.raw());
diff --git a/runtime/vm/dart_api_impl.h b/runtime/vm/dart_api_impl.h
index 6172e1a..ee36410 100644
--- a/runtime/vm/dart_api_impl.h
+++ b/runtime/vm/dart_api_impl.h
@@ -8,6 +8,7 @@
 #include "vm/allocation.h"
 #include "vm/native_arguments.h"
 #include "vm/object.h"
+#include "vm/safepoint.h"
 
 namespace dart {
 
@@ -51,11 +52,12 @@
       FATAL1("%s expects to find a current scope. Did you forget to call "     \
            "Dart_EnterScope?", CURRENT_FUNC);                                  \
     }                                                                          \
-  } while (0)
+  } while (0);                                                                 \
 
 #define DARTSCOPE(thread)                                                      \
   Thread* T = (thread);                                                        \
   CHECK_API_SCOPE(T);                                                          \
+  TransitionNativeToVM trainsition(T);                                         \
   HANDLESCOPE(T);
 
 
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index 8a40a7a..0f89952 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -374,7 +374,7 @@
 static Dart_NativeFunction CurrentStackTraceNativeLookup(
     Dart_Handle name, int argument_count, bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   return reinterpret_cast<Dart_NativeFunction>(&CurrentStackTraceNative);
 }
 
@@ -515,7 +515,7 @@
 static Dart_NativeFunction PropagateError_native_lookup(
     Dart_Handle name, int argument_count, bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   return reinterpret_cast<Dart_NativeFunction>(&PropagateErrorNative);
 }
 
@@ -615,7 +615,8 @@
 
   // Non-instance objects.
   {
-    DARTSCOPE(thread);
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     Dart_Handle lib1 = Dart_LookupLibrary(dart_core);
     Dart_Handle lib2 = Dart_LookupLibrary(dart_mirrors);
 
@@ -660,7 +661,8 @@
 
   // Non-instance objects.
   {
-    DARTSCOPE(thread);
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     Dart_Handle lib1 = Dart_LookupLibrary(dart_core);
     Dart_Handle lib2 = Dart_LookupLibrary(dart_mirrors);
 
@@ -1182,14 +1184,17 @@
     Dart_ExitScope();
   }
 
-  EXPECT_EQ(40, peer8);
-  EXPECT_EQ(41, peer16);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(40, peer8);
-  EXPECT_EQ(41, peer16);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
-  EXPECT_EQ(80, peer8);
-  EXPECT_EQ(82, peer16);
+  {
+    TransitionNativeToVM transition(thread);
+    EXPECT_EQ(40, peer8);
+    EXPECT_EQ(41, peer16);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(40, peer8);
+    EXPECT_EQ(41, peer16);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+    EXPECT_EQ(80, peer8);
+    EXPECT_EQ(82, peer16);
+  }
 }
 
 
@@ -1224,7 +1229,8 @@
         NULL);
     EXPECT_VALID(small16);
     {
-      DARTSCOPE(thread);
+      CHECK_API_SCOPE(thread);
+      HANDLESCOPE(thread);
       String& handle = String::Handle();
       handle ^= Api::UnwrapHandle(big8);
       EXPECT(handle.IsOld());
@@ -1258,7 +1264,8 @@
         kSmallLength);
     EXPECT_VALID(small);
     {
-      DARTSCOPE(thread);
+      CHECK_API_SCOPE(thread);
+      HANDLESCOPE(thread);
       ExternalTypedData& handle = ExternalTypedData::Handle();
       handle ^= Api::UnwrapHandle(big);
       EXPECT(handle.IsOld());
@@ -1733,7 +1740,7 @@
                                                   int arg_count,
                                                   bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   return &ByteDataNativeFunction;
 }
 
@@ -1795,7 +1802,7 @@
 static Dart_NativeFunction ExternalByteDataNativeResolver(
     Dart_Handle name, int arg_count, bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   return &ExternalByteDataNativeFunction;
 }
 
@@ -1869,7 +1876,7 @@
 static Dart_NativeFunction OptExternalByteDataNativeResolver(
     Dart_Handle name, int arg_count, bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   return &OptExternalByteDataNativeFunction;
 }
 
@@ -2311,11 +2318,14 @@
     EXPECT_VALID(obj);
     Dart_ExitScope();
   }
-  EXPECT(peer == 0);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT(peer == 0);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
-  EXPECT(peer == 42);
+  {
+    TransitionNativeToVM transition(thread);
+    EXPECT(peer == 0);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT(peer == 0);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+    EXPECT(peer == 42);
+  }
 }
 
 
@@ -2367,8 +2377,11 @@
     CheckFloat32x4Data(lcl);
   }
   Dart_ExitScope();
-  Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
-  EXPECT(peer == 42);
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+    EXPECT(peer == 42);
+  }
 }
 
 
@@ -2383,7 +2396,7 @@
   Dart_EnterScope();
   {
     EXPECT(thread->api_top_scope() != NULL);
-    DARTSCOPE(Thread::Current());
+    HANDLESCOPE(thread);
     const String& str1 = String::Handle(String::New("Test String"));
     Dart_Handle ref = Api::NewHandle(thread, str1.raw());
     String& str2 = String::Handle();
@@ -2409,7 +2422,8 @@
   Dart_PersistentHandle handles[2000];
   Dart_EnterScope();
   {
-    DARTSCOPE(Thread::Current());
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     Dart_Handle ref1 = Api::NewHandle(thread, String::New(kTestString1));
     for (int i = 0; i < 1000; i++) {
       handles[i] = Dart_NewPersistentHandle(ref1);
@@ -2471,7 +2485,9 @@
   EXPECT(isolate != NULL);
   ApiState* state = isolate->api_state();
   EXPECT(state != NULL);
-  DARTSCOPE(Thread::Current());
+  Thread* thread = Thread::Current();
+  CHECK_API_SCOPE(thread);
+  HANDLESCOPE(thread);
 
   // Start with a known persistent handle.
   Dart_PersistentHandle obj1 = Dart_NewPersistentHandle(Dart_True());
@@ -2498,7 +2514,9 @@
   const char* kTestString2 = "Test String2";
   TestIsolateScope __test_isolate__;
 
-  DARTSCOPE(Thread::Current());
+  Thread* T = Thread::Current();
+  CHECK_API_SCOPE(T);
+  HANDLESCOPE(T);
   Isolate* isolate = T->isolate();
   EXPECT(isolate != NULL);
   ApiState* state = isolate->api_state();
@@ -2581,7 +2599,8 @@
     // Create an object in old space.
     Dart_Handle old_ref;
     {
-      DARTSCOPE(Thread::Current());
+      CHECK_API_SCOPE(thread);
+      HANDLESCOPE(thread);
       old_ref = Api::NewHandle(thread, String::New("old string", Heap::kOld));
       EXPECT_VALID(old_ref);
     }
@@ -2602,8 +2621,11 @@
     EXPECT_VALID(AsHandle(weak_old_ref));
     EXPECT(!Dart_IsNull(AsHandle(weak_old_ref)));
 
-    // Garbage collect new space.
-    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+    {
+      TransitionNativeToVM transition(thread);
+      // Garbage collect new space.
+      GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+    }
 
     // Nothing should be invalidated or cleared.
     EXPECT_VALID(new_ref);
@@ -2619,8 +2641,11 @@
     EXPECT(!Dart_IsNull(AsHandle(weak_old_ref)));
     EXPECT(Dart_IdentityEquals(old_ref, AsHandle(weak_old_ref)));
 
-    // Garbage collect old space.
-    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    {
+      TransitionNativeToVM transition(thread);
+      // Garbage collect old space.
+      Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    }
 
     // Nothing should be invalidated or cleared.
     EXPECT_VALID(new_ref);
@@ -2640,8 +2665,11 @@
     Dart_ExitScope();
   }
 
-  // Garbage collect new space again.
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+  {
+    TransitionNativeToVM transition(thread);
+    // Garbage collect new space again.
+    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+  }
 
   {
     Dart_EnterScope();
@@ -2652,8 +2680,11 @@
     Dart_ExitScope();
   }
 
-  // Garbage collect old space again.
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+  {
+    TransitionNativeToVM transition(thread);
+    // Garbage collect old space again.
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+  }
 
   {
     Dart_EnterScope();
@@ -2663,9 +2694,12 @@
     Dart_ExitScope();
   }
 
-  // Garbage collect one last time to revisit deleted handles.
-  Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+  {
+    TransitionNativeToVM transition(thread);
+    // Garbage collect one last time to revisit deleted handles.
+    Isolate::Current()->heap()->CollectGarbage(Heap::kNew);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+  }
 }
 
 
@@ -2689,10 +2723,13 @@
     EXPECT(peer == 0);
     Dart_ExitScope();
   }
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT(peer == 0);
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-  EXPECT(peer == 42);
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT(peer == 0);
+    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+    EXPECT(peer == 42);
+  }
 }
 
 
@@ -2712,10 +2749,13 @@
   Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
   Dart_DeleteWeakPersistentHandle(isolate, weak_ref);
   EXPECT(peer == 0);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT(peer == 0);
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-  EXPECT(peer == 0);
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT(peer == 0);
+    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+    EXPECT(peer == 0);
+  }
 }
 
 
@@ -2765,20 +2805,26 @@
     EXPECT_VALID(AsHandle(strong_ref));
     Dart_ExitScope();
   }
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT(heap->ExternalInWords(Heap::kNew) ==
-         (kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize);
-  // Collect weakly referenced string, and promote strongly referenced string.
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-  EXPECT(heap->ExternalInWords(Heap::kNew) == 0);
-  EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize);
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT(heap->ExternalInWords(Heap::kNew) ==
+           (kWeak1ExternalSize + kWeak2ExternalSize) / kWordSize);
+    // Collect weakly referenced string, and promote strongly referenced string.
+    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+    EXPECT(heap->ExternalInWords(Heap::kNew) == 0);
+    EXPECT(heap->ExternalInWords(Heap::kOld) == kWeak2ExternalSize / kWordSize);
+  }
   Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
   Dart_DeleteWeakPersistentHandle(isolate, weak1);
   Dart_DeleteWeakPersistentHandle(isolate, weak2);
   Dart_DeletePersistentHandle(strong_ref);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
+  }
 }
 
 
@@ -2808,7 +2854,8 @@
     // After the two scavenges above, 'obj' should now be promoted, hence its
     // external size charged to old space.
     {
-      DARTSCOPE(thread);
+      CHECK_API_SCOPE(thread);
+      HANDLESCOPE(thread);
       String& handle = String::Handle(thread->zone());
       handle ^= Api::UnwrapHandle(obj);
       EXPECT(handle.IsOld());
@@ -2818,8 +2865,11 @@
     Dart_ExitScope();
   }
   Dart_DeleteWeakPersistentHandle(isolate, weak1);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT(heap->ExternalInWords(Heap::kOld) == 0);
+  }
 }
 
 
@@ -2886,8 +2936,11 @@
   Dart_Isolate isolate = reinterpret_cast<Dart_Isolate>(Isolate::Current());
   Dart_DeleteWeakPersistentHandle(isolate, weak1);
   Dart_DeleteWeakPersistentHandle(isolate, weak2);
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld));
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(0, heap->ExternalInWords(Heap::kOld));
+  }
 }
 
 
@@ -2915,7 +2968,8 @@
 
   Dart_EnterScope();
   {
-    DARTSCOPE(Thread::Current());
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
 
     Dart_Handle local = Api::NewHandle(
         thread, String::New("strongly reachable", Heap::kOld));
@@ -2957,7 +3011,10 @@
     Dart_ExitScope();
   }
 
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+  {
+    TransitionNativeToVM transition(thread);
+    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+  }
 
   {
     Dart_EnterScope();
@@ -2978,7 +3035,8 @@
 
   Dart_EnterScope();
   {
-    DARTSCOPE(Thread::Current());
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
 
     Dart_Handle local = Api::NewHandle(
         thread, String::New("strongly reachable", Heap::kOld));
@@ -3020,7 +3078,10 @@
     Dart_ExitScope();
   }
 
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+  }
 
   {
     Dart_EnterScope();
@@ -3098,99 +3159,109 @@
   EXPECT_VALID(Dart_SetGcCallbacks(&PrologueCallbackTimes2,
                                    &EpilogueCallbackNOP));
 
-  // Garbage collect new space ignoring callbacks.  This should not
-  // invoke the prologue callback.  No status values should change.
-  global_prologue_callback_status = 3;
-  global_epilogue_callback_status = 7;
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-  EXPECT_EQ(3, global_prologue_callback_status);
-  EXPECT_EQ(7, global_epilogue_callback_status);
+  {
+    TransitionNativeToVM transition(thread);
 
-  // Garbage collect new space invoking callbacks.  This should
-  // invoke the prologue callback.  No status values should change.
-  global_prologue_callback_status = 3;
-  global_epilogue_callback_status = 7;
-  GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks);
-  EXPECT_EQ(6, global_prologue_callback_status);
-  EXPECT_EQ(7, global_epilogue_callback_status);
+    // Garbage collect new space ignoring callbacks.  This should not
+    // invoke the prologue callback.  No status values should change.
+    global_prologue_callback_status = 3;
+    global_epilogue_callback_status = 7;
+    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+    EXPECT_EQ(3, global_prologue_callback_status);
+    EXPECT_EQ(7, global_epilogue_callback_status);
+
+    // Garbage collect new space invoking callbacks.  This should
+    // invoke the prologue callback.  No status values should change.
+    global_prologue_callback_status = 3;
+    global_epilogue_callback_status = 7;
+    GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks);
+    EXPECT_EQ(6, global_prologue_callback_status);
+    EXPECT_EQ(7, global_epilogue_callback_status);
 
   // Garbage collect old space ignoring callbacks.  This should invoke
   // the prologue callback.  The prologue status value should change.
-  global_prologue_callback_status = 3;
-  global_epilogue_callback_status = 7;
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld,
-                                             Heap::kIgnoreApiCallbacks,
-                                             Heap::kGCTestCase);
-  EXPECT_EQ(3, global_prologue_callback_status);
-  EXPECT_EQ(7, global_epilogue_callback_status);
+    global_prologue_callback_status = 3;
+    global_epilogue_callback_status = 7;
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld,
+                                               Heap::kIgnoreApiCallbacks,
+                                               Heap::kGCTestCase);
+    EXPECT_EQ(3, global_prologue_callback_status);
+    EXPECT_EQ(7, global_epilogue_callback_status);
 
-  // Garbage collect old space.  This should invoke the prologue
-  // callback.  The prologue status value should change.
-  global_prologue_callback_status = 3;
-  global_epilogue_callback_status = 7;
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(6, global_prologue_callback_status);
-  EXPECT_EQ(7, global_epilogue_callback_status);
+    // Garbage collect old space.  This should invoke the prologue
+    // callback.  The prologue status value should change.
+    global_prologue_callback_status = 3;
+    global_epilogue_callback_status = 7;
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(6, global_prologue_callback_status);
+    EXPECT_EQ(7, global_epilogue_callback_status);
 
-  // Garbage collect old space again.  Callbacks are persistent so the
-  // prologue status value should change again.
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(12, global_prologue_callback_status);
-  EXPECT_EQ(7, global_epilogue_callback_status);
+    // Garbage collect old space again.  Callbacks are persistent so the
+    // prologue status value should change again.
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(12, global_prologue_callback_status);
+    EXPECT_EQ(7, global_epilogue_callback_status);
+  }
 
   // Add an epilogue callback.
   EXPECT_VALID(Dart_SetGcCallbacks(NULL, NULL));
   EXPECT_VALID(Dart_SetGcCallbacks(&PrologueCallbackTimes2,
                                    &EpilogueCallbackTimes4));
 
-  // Garbage collect new space.  This should not invoke the prologue
-  // or the epilogue callback.  No status values should change.
-  global_prologue_callback_status = 3;
-  global_epilogue_callback_status = 7;
-  GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
-  EXPECT_EQ(3, global_prologue_callback_status);
-  EXPECT_EQ(7, global_epilogue_callback_status);
+  {
+    TransitionNativeToVM transition(thread);
+    // Garbage collect new space.  This should not invoke the prologue
+    // or the epilogue callback.  No status values should change.
+    global_prologue_callback_status = 3;
+    global_epilogue_callback_status = 7;
+    GCTestHelper::CollectNewSpace(Heap::kIgnoreApiCallbacks);
+    EXPECT_EQ(3, global_prologue_callback_status);
+    EXPECT_EQ(7, global_epilogue_callback_status);
 
-  // Garbage collect new space.  This should invoke the prologue and
-  // the epilogue callback.  The prologue and epilogue status values
-  // should change.
-  GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks);
-  EXPECT_EQ(6, global_prologue_callback_status);
-  EXPECT_EQ(28, global_epilogue_callback_status);
+    // Garbage collect new space.  This should invoke the prologue and
+    // the epilogue callback.  The prologue and epilogue status values
+    // should change.
+    GCTestHelper::CollectNewSpace(Heap::kInvokeApiCallbacks);
+    EXPECT_EQ(6, global_prologue_callback_status);
+    EXPECT_EQ(28, global_epilogue_callback_status);
 
-  // Garbage collect old space.  This should invoke the prologue and
-  // the epilogue callbacks.  The prologue and epilogue status values
-  // should change.
-  global_prologue_callback_status = 3;
-  global_epilogue_callback_status = 7;
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(6, global_prologue_callback_status);
-  EXPECT_EQ(28, global_epilogue_callback_status);
+    // Garbage collect old space.  This should invoke the prologue and
+    // the epilogue callbacks.  The prologue and epilogue status values
+    // should change.
+    global_prologue_callback_status = 3;
+    global_epilogue_callback_status = 7;
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(6, global_prologue_callback_status);
+    EXPECT_EQ(28, global_epilogue_callback_status);
 
-  // Garbage collect old space again without invoking callbacks.
-  // Nothing should change.
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld,
-                                             Heap::kIgnoreApiCallbacks,
-                                             Heap::kGCTestCase);
-  EXPECT_EQ(6, global_prologue_callback_status);
-  EXPECT_EQ(28, global_epilogue_callback_status);
+    // Garbage collect old space again without invoking callbacks.
+    // Nothing should change.
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld,
+                                               Heap::kIgnoreApiCallbacks,
+                                               Heap::kGCTestCase);
+    EXPECT_EQ(6, global_prologue_callback_status);
+    EXPECT_EQ(28, global_epilogue_callback_status);
 
-  // Garbage collect old space again.  Callbacks are persistent so the
-  // prologue and epilogue status values should change again.
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(12, global_prologue_callback_status);
-  EXPECT_EQ(112, global_epilogue_callback_status);
+    // Garbage collect old space again.  Callbacks are persistent so the
+    // prologue and epilogue status values should change again.
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(12, global_prologue_callback_status);
+    EXPECT_EQ(112, global_epilogue_callback_status);
+  }
 
   // Remove the prologue and epilogue callbacks
   EXPECT_VALID(Dart_SetGcCallbacks(NULL, NULL));
 
-  // Garbage collect old space.  No callbacks should be invoked.  No
-  // status values should change.
-  global_prologue_callback_status = 3;
-  global_epilogue_callback_status = 7;
-  Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(3, global_prologue_callback_status);
-  EXPECT_EQ(7, global_epilogue_callback_status);
+  {
+    TransitionNativeToVM transition(thread);
+    // Garbage collect old space.  No callbacks should be invoked.  No
+    // status values should change.
+    global_prologue_callback_status = 3;
+    global_epilogue_callback_status = 7;
+    Isolate::Current()->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(3, global_prologue_callback_status);
+    EXPECT_EQ(7, global_epilogue_callback_status);
+  }
 }
 
 
@@ -4001,7 +4072,8 @@
   // Invoke a function which returns an object of type NativeFields.
   result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
   EXPECT_VALID(result);
-  DARTSCOPE(Thread::Current());
+  CHECK_API_SCOPE(thread);
+  HANDLESCOPE(thread);
   Instance& obj = Instance::Handle();
   obj ^= Api::UnwrapHandle(result);
   const Class& cls = Class::Handle(obj.clazz());
@@ -4071,7 +4143,8 @@
   // Invoke a function which returns an object of type NativeFields.
   result = Dart_Invoke(lib, NewString("testMain"), 0, NULL);
   EXPECT_VALID(result);
-  DARTSCOPE(Thread::Current());
+  CHECK_API_SCOPE(thread);
+  HANDLESCOPE(thread);
   Instance& obj = Instance::Handle();
   obj ^= Api::UnwrapHandle(result);
   const Class& cls = Class::Handle(obj.clazz());
@@ -4415,7 +4488,8 @@
       "  return () {};\n"
       "}\n";
   Dart_Handle result;
-  DARTSCOPE(Thread::Current());
+  CHECK_API_SCOPE(thread);
+  HANDLESCOPE(thread);
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -4493,7 +4567,8 @@
       "  };\n"
       "}\n";
 
-  DARTSCOPE(Thread::Current());
+  CHECK_API_SCOPE(thread);
+  HANDLESCOPE(thread);
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -5202,7 +5277,8 @@
       "  return InvokeClosure.method2(10);\n"
       "}\n";
   Dart_Handle result;
-  DARTSCOPE(Thread::Current());
+  CHECK_API_SCOPE(thread);
+  HANDLESCOPE(thread);
 
   // Create a test library and Load up a test script in it.
   Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
@@ -5255,7 +5331,7 @@
                                          int argument_count,
                                          bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   return reinterpret_cast<Dart_NativeFunction>(&ExceptionNative);
 }
 
@@ -5501,7 +5577,7 @@
                                        int argument_count,
                                        bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentCounter);
 }
 
@@ -7994,7 +8070,8 @@
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
   {
-    DARTSCOPE(Thread::Current());
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     Dart_Handle str = NewString("a string");
     EXPECT_VALID(str);
     EXPECT(Dart_IsString(str));
@@ -8008,15 +8085,21 @@
     out = &out;
     EXPECT_VALID(Dart_GetPeer(str, &out));
     EXPECT(out == reinterpret_cast<void*>(&peer));
-    isolate->heap()->CollectGarbage(Heap::kNew);
-    EXPECT_EQ(1, isolate->heap()->PeerCount());
+    {
+      TransitionNativeToVM transition(thread);
+      isolate->heap()->CollectGarbage(Heap::kNew);
+      EXPECT_EQ(1, isolate->heap()->PeerCount());
+    }
     out = &out;
     EXPECT_VALID(Dart_GetPeer(str, &out));
     EXPECT(out == reinterpret_cast<void*>(&peer));
   }
   Dart_ExitScope();
-  isolate->heap()->CollectGarbage(Heap::kNew);
-  EXPECT_EQ(0, isolate->heap()->PeerCount());
+  {
+    TransitionNativeToVM transition(thread);
+    isolate->heap()->CollectGarbage(Heap::kNew);
+    EXPECT_EQ(0, isolate->heap()->PeerCount());
+  }
 }
 
 
@@ -8067,7 +8150,8 @@
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
   {
-    DARTSCOPE(Thread::Current());
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     Dart_Handle s1 = NewString("s1");
     EXPECT_VALID(s1);
     EXPECT(Dart_IsString(s1));
@@ -8094,8 +8178,11 @@
     EXPECT(o2 == reinterpret_cast<void*>(&p2));
   }
   Dart_ExitScope();
-  isolate->heap()->CollectGarbage(Heap::kNew);
-  EXPECT_EQ(0, isolate->heap()->PeerCount());
+  {
+    TransitionNativeToVM transition(thread);
+    isolate->heap()->CollectGarbage(Heap::kNew);
+    EXPECT_EQ(0, isolate->heap()->PeerCount());
+  }
 }
 
 
@@ -8123,10 +8210,13 @@
     EXPECT(o == reinterpret_cast<void*>(&p[i]));
   }
   EXPECT_EQ(kPeerCount, isolate->heap()->PeerCount());
-  isolate->heap()->CollectGarbage(Heap::kNew);
-  EXPECT_EQ(kPeerCount, isolate->heap()->PeerCount());
-  isolate->heap()->CollectGarbage(Heap::kNew);
-  EXPECT_EQ(kPeerCount, isolate->heap()->PeerCount());
+  {
+    TransitionNativeToVM transition(thread);
+    isolate->heap()->CollectGarbage(Heap::kNew);
+    EXPECT_EQ(kPeerCount, isolate->heap()->PeerCount());
+    isolate->heap()->CollectGarbage(Heap::kNew);
+    EXPECT_EQ(kPeerCount, isolate->heap()->PeerCount());
+  }
 }
 
 
@@ -8148,10 +8238,14 @@
   EXPECT(Dart_GetPeer(str, &out));
   EXPECT(out == reinterpret_cast<void*>(&peer));
   EXPECT_EQ(1, isolate->heap()->PeerCount());
-  isolate->heap()->CollectGarbage(Heap::kNew);
-  isolate->heap()->CollectGarbage(Heap::kNew);
   {
-    DARTSCOPE(Thread::Current());
+    TransitionNativeToVM transition(thread);
+    isolate->heap()->CollectGarbage(Heap::kNew);
+    isolate->heap()->CollectGarbage(Heap::kNew);
+  }
+  {
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     String& handle = String::Handle();
     handle ^= Api::UnwrapHandle(str);
     EXPECT(handle.IsOld());
@@ -8185,8 +8279,11 @@
   out = &out;
   EXPECT_VALID(Dart_GetPeer(str, &out));
   EXPECT(out == reinterpret_cast<void*>(&peer));
-  isolate->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(1, isolate->heap()->PeerCount());
+  {
+    TransitionNativeToVM transition(thread);
+    isolate->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(1, isolate->heap()->PeerCount());
+  }
   EXPECT_VALID(Dart_GetPeer(str, &out));
   EXPECT(out == reinterpret_cast<void*>(&peer));
   EXPECT_VALID(Dart_SetPeer(str, NULL));
@@ -8204,7 +8301,9 @@
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
   {
-    DARTSCOPE(Thread::Current());
+    Thread* T = Thread::Current();
+    CHECK_API_SCOPE(T);
+    HANDLESCOPE(T);
     Dart_Handle str = Api::NewHandle(T, String::New("str", Heap::kOld));
     EXPECT_VALID(str);
     EXPECT(Dart_IsString(str));
@@ -8218,14 +8317,20 @@
     out = &out;
     EXPECT_VALID(Dart_GetPeer(str, &out));
     EXPECT(out == reinterpret_cast<void*>(&peer));
-    isolate->heap()->CollectGarbage(Heap::kOld);
-    EXPECT_EQ(1, isolate->heap()->PeerCount());
+    {
+      TransitionNativeToVM transition(thread);
+      isolate->heap()->CollectGarbage(Heap::kOld);
+      EXPECT_EQ(1, isolate->heap()->PeerCount());
+    }
     EXPECT_VALID(Dart_GetPeer(str, &out));
     EXPECT(out == reinterpret_cast<void*>(&peer));
   }
   Dart_ExitScope();
-  isolate->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(0, isolate->heap()->PeerCount());
+  {
+    TransitionNativeToVM transition(thread);
+    isolate->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(0, isolate->heap()->PeerCount());
+  }
 }
 
 
@@ -8280,7 +8385,9 @@
   Isolate* isolate = Isolate::Current();
   Dart_EnterScope();
   {
-    DARTSCOPE(Thread::Current());
+    Thread* T = Thread::Current();
+    CHECK_API_SCOPE(T);
+    HANDLESCOPE(T);
     Dart_Handle s1 = Api::NewHandle(T, String::New("s1", Heap::kOld));
     EXPECT_VALID(s1);
     EXPECT(Dart_IsString(s1));
@@ -8309,8 +8416,11 @@
     EXPECT(o2 == reinterpret_cast<void*>(&p2));
   }
   Dart_ExitScope();
-  isolate->heap()->CollectGarbage(Heap::kOld);
-  EXPECT_EQ(0, isolate->heap()->PeerCount());
+  {
+    TransitionNativeToVM transition(thread);
+    isolate->heap()->CollectGarbage(Heap::kOld);
+    EXPECT_EQ(0, isolate->heap()->PeerCount());
+  }
 }
 
 
@@ -8517,7 +8627,10 @@
   EXPECT_EQ(40, peer8);
   EXPECT_EQ(41, peer16);
   EXPECT_EQ(42, canonical_str_peer);
-  Isolate::Current()->heap()->CollectAllGarbage();
+  {
+    TransitionNativeToVM transition(thread);
+    Isolate::Current()->heap()->CollectAllGarbage();
+  }
   EXPECT_EQ(80, peer8);
   EXPECT_EQ(82, peer16);
   EXPECT_EQ(42, canonical_str_peer);  // "*" Symbol is not removed on GC.
@@ -8629,7 +8742,7 @@
 static Dart_NativeFunction ExternalStringDeoptimize_native_lookup(
     Dart_Handle name, int argument_count, bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   return reinterpret_cast<Dart_NativeFunction>(&A_change_str_native);
 }
 
diff --git a/runtime/vm/dart_api_state.h b/runtime/vm/dart_api_state.h
index e0f6e00..ec005b6 100644
--- a/runtime/vm/dart_api_state.h
+++ b/runtime/vm/dart_api_state.h
@@ -261,12 +261,14 @@
 
   // This part of external_data_ is the number of externally allocated bytes.
   // TODO(koda): Measure size in words instead.
-  class ExternalSizeBits : public BitField<intptr_t,
+  class ExternalSizeBits : public BitField<uword,
+                                           intptr_t,
                                            kExternalSizeBits,
-                                           kExternalSizeBitsSize> {};  // NOLINT
+                                           kExternalSizeBitsSize> {};
   // This bit of external_data_ is true if the referent was created in new
   // space and UpdateRelocated has not yet detected any promotion.
-  class ExternalNewSpaceBit : public BitField<bool, kExternalNewSpaceBit, 1> {};
+  class ExternalNewSpaceBit :
+      public BitField<uword, bool, kExternalNewSpaceBit, 1> {};
 
   friend class FinalizablePersistentHandles;
 
diff --git a/runtime/vm/dart_entry.cc b/runtime/vm/dart_entry.cc
index 3a53dcc..bf6a49e 100644
--- a/runtime/vm/dart_entry.cc
+++ b/runtime/vm/dart_entry.cc
@@ -10,6 +10,7 @@
 #include "vm/debugger.h"
 #include "vm/object_store.h"
 #include "vm/resolver.h"
+#include "vm/safepoint.h"
 #include "vm/simulator.h"
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
@@ -113,6 +114,7 @@
   ASSERT(thread->no_callback_scope_depth() == 0);
   ScopedIsolateStackLimits stack_limit(thread);
   SuspendLongJumpScope suspend_long_jump_scope(thread);
+  TransitionToGenerated transition(thread);
 #if defined(USING_SIMULATOR)
   return bit_copy<RawObject*, int64_t>(Simulator::Current()->Call(
       reinterpret_cast<intptr_t>(entrypoint),
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 1b3d84a..c961249 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -27,6 +27,7 @@
 #include "vm/stub_code.h"
 #include "vm/symbols.h"
 #include "vm/thread_interrupter.h"
+#include "vm/token_position.h"
 #include "vm/visitor.h"
 
 
@@ -44,6 +45,8 @@
             "the VM service.");
 
 DECLARE_FLAG(bool, trace_isolates);
+DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
+DECLARE_FLAG(bool, precompilation);
 
 
 Debugger::EventHandler* Debugger::event_handler_ = NULL;
@@ -67,8 +70,8 @@
 
 // Create an unresolved breakpoint in given token range and script.
 BreakpointLocation::BreakpointLocation(const Script& script,
-                                       intptr_t token_pos,
-                                       intptr_t end_token_pos,
+                                       TokenPosition token_pos,
+                                       TokenPosition end_token_pos,
                                        intptr_t requested_line_number,
                                        intptr_t requested_column_number)
     : script_(script.raw()),
@@ -84,7 +87,7 @@
       line_number_(-1),
       column_number_(-1) {
   ASSERT(!script.IsNull());
-  ASSERT(Token::IsReal(token_pos_));
+  ASSERT(token_pos_.IsReal());
 }
 
 // Create a latent breakpoint at given url and line number.
@@ -93,8 +96,8 @@
                                        intptr_t requested_column_number)
     : script_(Script::null()),
       url_(url.raw()),
-      token_pos_(Token::kNoSourcePos),
-      end_token_pos_(Token::kNoSourcePos),
+      token_pos_(TokenPosition::kNoSource),
+      end_token_pos_(TokenPosition::kNoSource),
       is_resolved_(false),
       next_(NULL),
       conditions_(NULL),
@@ -122,7 +125,8 @@
 }
 
 
-void BreakpointLocation::SetResolved(const Function& func, intptr_t token_pos) {
+void BreakpointLocation::SetResolved(const Function& func,
+                                     TokenPosition token_pos) {
   ASSERT(!IsLatent());
   ASSERT(func.script() == script_);
   ASSERT((func.token_pos() <= token_pos) &&
@@ -140,11 +144,11 @@
 // in more than one library, e.g. the text location of mixin functions.
 void BreakpointLocation::GetCodeLocation(Library* lib,
                                          Script* script,
-                                         intptr_t* pos) const {
+                                         TokenPosition* pos) const {
   if (IsLatent()) {
     *lib = Library::null();
     *script = Script::null();
-    *pos = -1;
+    *pos = TokenPosition::kNoSource;
   } else {
     *script = this->script();
     *pos = token_pos_;
@@ -239,7 +243,7 @@
       code_(Code::ZoneHandle(code.raw())),
       function_(Function::ZoneHandle(code.function())),
       token_pos_initialized_(false),
-      token_pos_(Token::kNoSourcePos),
+      token_pos_(TokenPosition::kNoSource),
       try_index_(-1),
       line_number_(-1),
       column_number_(-1),
@@ -281,7 +285,8 @@
     case DebuggerEvent::kBreakpointReached:
     case DebuggerEvent::kExceptionThrown:
     case DebuggerEvent::kIsolateInterrupted:
-      return Service::debug_stream.enabled();
+      return (Service::debug_stream.enabled() ||
+              FLAG_warn_on_pause_with_no_debugger);
 
     case DebuggerEvent::kIsolateCreated:
     case DebuggerEvent::kIsolateShutdown:
@@ -305,12 +310,15 @@
     Service::HandleEvent(&service_event);
   }
 
-  if ((FLAG_steal_breakpoints || (event_handler_ == NULL)) &&
-      event->IsPauseEvent()) {
-    // We allow the embedder's default breakpoint handler to be overridden.
-    isolate_->PauseEventHandler();
-  } else if (event_handler_ != NULL) {
-    (*event_handler_)(event);
+  {
+    TransitionVMToNative transition(Thread::Current());
+    if ((FLAG_steal_breakpoints || (event_handler_ == NULL)) &&
+        event->IsPauseEvent()) {
+      // We allow the embedder's default breakpoint handler to be overridden.
+      isolate_->PauseEventHandler();
+    } else if (event_handler_ != NULL) {
+      (*event_handler_)(event);
+    }
   }
 
   if (ServiceNeedsDebuggerEvent(event->type()) && event->IsPauseEvent()) {
@@ -451,7 +459,7 @@
 // Returns true if function contains the token position in the given script.
 static bool FunctionContains(const Function& func,
                              const Script& script,
-                             intptr_t token_pos) {
+                             TokenPosition token_pos) {
   if ((func.token_pos() <= token_pos) && (token_pos <= func.end_token_pos())) {
     // Check script equality second because it allocates
     // handles as a side effect.
@@ -563,10 +571,10 @@
 
 
 // Compute token_pos_ and try_index_ and token_pos_initialized_.
-intptr_t ActivationFrame::TokenPos() {
+TokenPosition ActivationFrame::TokenPos() {
   if (!token_pos_initialized_) {
     token_pos_initialized_ = true;
-    token_pos_ = Token::kNoSourcePos;
+    token_pos_ = TokenPosition::kNoSource;
     GetPcDescriptors();
     PcDescriptors::Iterator iter(pc_desc_, RawPcDescriptors::kAnyKind);
     uword pc_offset = pc_ - code().EntryPoint();
@@ -592,8 +600,8 @@
 
 intptr_t ActivationFrame::LineNumber() {
   // Compute line number lazily since it causes scanning of the script.
-  if ((line_number_ < 0) && Token::IsReal(TokenPos())) {
-    const intptr_t token_pos = TokenPos();
+  if ((line_number_ < 0) && TokenPos().IsReal()) {
+    const TokenPosition token_pos = TokenPos();
     const Script& script = Script::Handle(SourceScript());
     script.GetTokenLocation(token_pos, &line_number_, NULL);
   }
@@ -603,8 +611,8 @@
 
 intptr_t ActivationFrame::ColumnNumber() {
   // Compute column number lazily since it causes scanning of the script.
-  if ((column_number_ < 0) && Token::IsReal(TokenPos())) {
-    const intptr_t token_pos = TokenPos();
+  if ((column_number_ < 0) && TokenPos().IsReal()) {
+    const TokenPosition token_pos = TokenPos();
     const Script& script = Script::Handle(SourceScript());
     if (script.HasSource()) {
       script.GetTokenLocation(token_pos, &line_number_, &column_number_);
@@ -649,14 +657,14 @@
     // for the code position of the frame? For now say we are at context
     // level 0.
     TokenPos();
-    if (token_pos_ == -1) {
+    if (token_pos_ == TokenPosition::kNoSource) {
       // No PcDescriptor.
       return context_level_;
     }
     ASSERT(!pc_desc_.IsNull());
-    intptr_t innermost_begin_pos = 0;
-    intptr_t activation_token_pos = TokenPos();
-    ASSERT(Token::IsReal(activation_token_pos));
+    TokenPosition innermost_begin_pos = TokenPosition::kMinSource;
+    TokenPosition activation_token_pos = TokenPos();
+    ASSERT(activation_token_pos.IsReal());
     GetVarDescriptors();
     intptr_t var_desc_len = var_descriptors_.Length();
     for (intptr_t cur_idx = 0; cur_idx < var_desc_len; cur_idx++) {
@@ -768,8 +776,8 @@
   }
   GetVarDescriptors();
 
-  intptr_t activation_token_pos = TokenPos();
-  if (!Token::IsDebugPause(activation_token_pos)) {
+  TokenPosition activation_token_pos = TokenPos();
+  if (!activation_token_pos.IsDebugPause()) {
     // We don't have a token position for this frame, so can't determine
     // which variables are visible.
     vars_initialized_ = true;
@@ -929,8 +937,8 @@
 
 void ActivationFrame::VariableAt(intptr_t i,
                                  String* name,
-                                 intptr_t* token_pos,
-                                 intptr_t* end_pos,
+                                 TokenPosition* token_pos,
+                                 TokenPosition* end_pos,
                                  Object* value) {
   GetDescIndices();
   ASSERT(i < desc_indices_.length());
@@ -998,7 +1006,7 @@
   Object& value = Instance::Handle();
   const Array& list = Array::Handle(Array::New(2 * num_variables));
   for (intptr_t i = 0; i < num_variables; i++) {
-    intptr_t ignore;
+    TokenPosition ignore;
     VariableAt(i, &var_name, &ignore, &ignore, &value);
     list.SetAt(2 * i, var_name);
     list.SetAt((2 * i) + 1, value);
@@ -1013,7 +1021,7 @@
   String& var_name = String::Handle();
   Instance& value = Instance::Handle();
   for (intptr_t i = 0; i < num_variables; i++) {
-    intptr_t ignore;
+    TokenPosition ignore;
     VariableAt(i, &var_name, &ignore, &ignore, &value);
     if (var_name.Equals(Symbols::This())) {
       return value.raw();
@@ -1038,7 +1046,7 @@
   Object& value = Instance::Handle();
   intptr_t num_variables = desc_indices_.length();
   for (intptr_t i = 0; i < num_variables; i++) {
-    intptr_t ignore;
+    TokenPosition ignore;
     VariableAt(i, &name, &ignore, &ignore, &value);
     if (!name.Equals(Symbols::This())) {
       if (IsPrivateVariableName(name)) {
@@ -1109,8 +1117,8 @@
     for (intptr_t v = 0; v < num_vars; v++) {
       String& var_name = String::Handle();
       Instance& var_value = Instance::Handle();
-      intptr_t token_pos;
-      intptr_t end_token_pos;
+      TokenPosition token_pos;
+      TokenPosition end_token_pos;
       VariableAt(v, &var_name, &token_pos, &end_token_pos, &var_value);
       if (var_name.raw() != Symbols::AsyncOperation().raw()) {
         JSONObject jsvar(&jsvars);
@@ -1143,7 +1151,7 @@
 
 
 CodeBreakpoint::CodeBreakpoint(const Code& code,
-                               intptr_t token_pos,
+                               TokenPosition token_pos,
                                uword pc,
                                RawPcDescriptors::Kind kind)
     : code_(code.raw()),
@@ -1156,7 +1164,7 @@
       breakpoint_kind_(kind),
       saved_value_(Code::null()) {
   ASSERT(!code.IsNull());
-  ASSERT(token_pos_ > 0);
+  ASSERT(token_pos_.IsReal());
   ASSERT(pc_ != 0);
   ASSERT((breakpoint_kind_ & kSafepointKind) != 0);
 }
@@ -1483,7 +1491,7 @@
     }
     if (frame->IsDartFrame()) {
       code = frame->LookupDartCode();
-      if (code.is_optimized() && !Compiler::always_optimize()) {
+      if (code.is_optimized() && !FLAG_precompilation) {
         deopt_frame = DeoptimizeToArray(thread, frame, code);
         for (InlinedFunctionsIterator it(code, frame->pc());
              !it.Done();
@@ -1647,12 +1655,15 @@
 }
 
 
-static intptr_t LastTokenOnLine(const TokenStream& tokens, intptr_t pos) {
-  TokenStream::Iterator iter(tokens, pos, TokenStream::Iterator::kAllTokens);
+static TokenPosition LastTokenOnLine(const TokenStream& tokens,
+                                     TokenPosition pos) {
+  TokenStream::Iterator iter(tokens,
+                             pos,
+                             TokenStream::Iterator::kAllTokens);
   ASSERT(iter.IsValid());
-  intptr_t last_pos = pos;
+  TokenPosition last_pos = pos;
   while ((iter.CurrentTokenKind() != Token::kNEWLINE) &&
-      (iter.CurrentTokenKind() != Token::kEOS)) {
+         (iter.CurrentTokenKind() != Token::kEOS)) {
     last_pos = iter.CurrentPosition();
     iter.Advance();
   }
@@ -1716,10 +1727,11 @@
 // algorithm, which would be simpler.  I believe that it only needs
 // two passes to support the recursive try-the-whole-function case.
 // Rewrite this later, once there are more tests in place.
-intptr_t Debugger::ResolveBreakpointPos(const Function& func,
-                                        intptr_t requested_token_pos,
-                                        intptr_t last_token_pos,
-                                        intptr_t requested_column) {
+TokenPosition Debugger::ResolveBreakpointPos(
+    const Function& func,
+    TokenPosition requested_token_pos,
+    TokenPosition last_token_pos,
+    intptr_t requested_column) {
   ASSERT(func.HasCode());
   ASSERT(!func.HasOptimizedCode());
 
@@ -1737,12 +1749,12 @@
 
   // First pass: find the safe point which is closest to the beginning
   // of the given token range.
-  intptr_t best_fit_pos = INT_MAX;
+  TokenPosition best_fit_pos = TokenPosition::kMaxSource;
   intptr_t best_column = INT_MAX;
   PcDescriptors::Iterator iter(desc, kSafepointKind);
   while (iter.MoveNext()) {
-    const intptr_t pos = iter.TokenPos();
-    if ((!Token::IsReal(pos)) ||
+    const TokenPosition pos = iter.TokenPos();
+    if ((!pos.IsReal()) ||
         (pos < requested_token_pos) ||
         (pos > last_token_pos)) {
       // Token is not in the target range.
@@ -1779,16 +1791,16 @@
   // Second pass (if we found a safe point in the first pass).  Find
   // 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 != INT_MAX) {
+  if (best_fit_pos != TokenPosition::kMaxSource) {
     const Script& script = Script::Handle(func.script());
     const TokenStream& tokens = TokenStream::Handle(script.tokens());
-    const intptr_t begin_pos = best_fit_pos;
-    const intptr_t end_of_line_pos = LastTokenOnLine(tokens, begin_pos);
+    const TokenPosition begin_pos = best_fit_pos;
+    const TokenPosition end_of_line_pos = LastTokenOnLine(tokens, begin_pos);
     uword lowest_pc_offset = kUwordMax;
     PcDescriptors::Iterator iter(desc, kSafepointKind);
     while (iter.MoveNext()) {
-      const intptr_t pos = iter.TokenPos();
-      if ((!Token::IsReal(pos)) ||
+      const TokenPosition pos = iter.TokenPos();
+      if (!pos.IsReal() ||
           (pos < begin_pos) ||
           (pos > end_of_line_pos)) {
         // Token is not on same line as best fit.
@@ -1823,13 +1835,13 @@
     return ResolveBreakpointPos(func, last_token_pos, func.end_token_pos(),
                                 -1 /* no column */);
   }
-  return Token::kNoSourcePos;
+  return TokenPosition::kNoSource;
 }
 
 
 void Debugger::MakeCodeBreakpointAt(const Function& func,
                                     BreakpointLocation* loc) {
-  ASSERT(Token::IsReal(loc->token_pos_));
+  ASSERT(loc->token_pos_.IsReal());
   ASSERT((loc != NULL) && loc->IsResolved());
   ASSERT(!func.HasOptimizedCode());
   Code& code = Code::Handle(func.unoptimized_code());
@@ -1867,8 +1879,8 @@
 
 
 void Debugger::FindCompiledFunctions(const Script& script,
-                                     intptr_t start_pos,
-                                     intptr_t end_pos,
+                                     TokenPosition start_pos,
+                                     TokenPosition end_pos,
                                      GrowableObjectArray* function_list) {
   Zone* zone = Thread::Current()->zone();
   Class& cls = Class::Handle(zone);
@@ -1952,7 +1964,7 @@
 
 
 RawFunction* Debugger::FindBestFit(const Script& script,
-                                   intptr_t token_pos) {
+                                   TokenPosition token_pos) {
   Zone* zone = Thread::Current()->zone();
   Class& cls = Class::Handle(zone);
   Array& functions = Array::Handle(zone);
@@ -2011,8 +2023,8 @@
 
 
 BreakpointLocation* Debugger::SetBreakpoint(const Script& script,
-                                            intptr_t token_pos,
-                                            intptr_t last_token_pos,
+                                            TokenPosition token_pos,
+                                            TokenPosition last_token_pos,
                                             intptr_t requested_line,
                                             intptr_t requested_column) {
   Function& func = Function::Handle();
@@ -2037,9 +2049,9 @@
     // have already been compiled. We can resolve the breakpoint now.
     DeoptimizeWorld();
     func ^= functions.At(0);
-    intptr_t breakpoint_pos =
+    TokenPosition breakpoint_pos =
         ResolveBreakpointPos(func, token_pos, last_token_pos, requested_column);
-    if (breakpoint_pos >= 0) {
+    if (breakpoint_pos.IsReal()) {
       BreakpointLocation* bpt =
           GetBreakpointLocation(script, breakpoint_pos, requested_column);
       if (bpt != NULL) {
@@ -2242,16 +2254,16 @@
     return NULL;
   }
   script ^= scripts.At(0);
-  intptr_t first_token_idx, last_token_idx;
+  TokenPosition first_token_idx, last_token_idx;
   script.TokenRangeAtLine(line_number, &first_token_idx, &last_token_idx);
-  if (!Token::IsReal(first_token_idx)) {
+  if (!first_token_idx.IsReal()) {
     // Script does not contain the given line number.
     if (FLAG_verbose_debug) {
       OS::Print("Script '%s' does not contain line number %" Pd "\n",
                 script_url.ToCString(), line_number);
     }
     return NULL;
-  } else if (!Token::IsReal(last_token_idx)) {
+  } else if (!last_token_idx.IsReal()) {
     // Line does not contain any tokens.
     if (FLAG_verbose_debug) {
       OS::Print("No executable code at line %" Pd " in '%s'\n",
@@ -2265,7 +2277,7 @@
   while ((bpt == NULL) && (first_token_idx <= last_token_idx)) {
     bpt = SetBreakpoint(script, first_token_idx, last_token_idx,
                         line_number, column_number);
-    first_token_idx++;
+    first_token_idx.Next();
   }
   if ((bpt == NULL) && FLAG_verbose_debug) {
     OS::Print("No executable code at line %" Pd " in '%s'\n",
@@ -2659,7 +2671,7 @@
   if (!frame->IsDebuggable()) {
     return Error::null();
   }
-  if (!Token::IsDebugPause(frame->TokenPos())) {
+  if (!frame->TokenPos().IsDebugPause()) {
     return Error::null();
   }
 
@@ -2669,11 +2681,11 @@
   ASSERT(!HasActiveBreakpoint(frame->pc()));
 
   if (FLAG_verbose_debug) {
-    OS::Print(">>> single step break at %s:%" Pd " (func %s token %" Pd ")\n",
+    OS::Print(">>> single step break at %s:%" Pd " (func %s token %s)\n",
               String::Handle(frame->SourceUrl()).ToCString(),
               frame->LineNumber(),
               String::Handle(frame->QualifiedFunctionName()).ToCString(),
-              frame->TokenPos());
+              frame->TokenPos().ToCString());
   }
 
   ASSERT(stack_trace_ == NULL);
@@ -2754,11 +2766,11 @@
 
   if (FLAG_verbose_debug) {
     OS::Print(">>> hit %s breakpoint at %s:%" Pd " "
-              "(token %" Pd ") (address %#" Px ")\n",
+              "(token %s) (address %#" Px ")\n",
               cbpt->IsInternal() ? "internal" : "user",
               String::Handle(cbpt->SourceUrl()).ToCString(),
               cbpt->LineNumber(),
-              cbpt->token_pos(),
+              cbpt->token_pos().ToCString(),
               top_frame->pc());
   }
 
@@ -2837,7 +2849,7 @@
 // Return innermost closure contained in 'function' that contains
 // the given token position.
 RawFunction* Debugger::FindInnermostClosure(const Function& function,
-                                            intptr_t token_pos) {
+                                            TokenPosition token_pos) {
   Zone* zone = Thread::Current()->zone();
   const Script& outer_origin = Script::Handle(zone, function.script());
   const GrowableObjectArray& closures =
@@ -2902,33 +2914,33 @@
       // and set the code breakpoints.
       if (!loc->IsResolved()) {
         // Resolve source breakpoint in the newly compiled function.
-        intptr_t bp_pos =
+        TokenPosition bp_pos =
             ResolveBreakpointPos(func, loc->token_pos(), loc->end_token_pos(),
                                  loc->requested_column_number());
-        if (!Token::IsDebugPause(bp_pos)) {
+        if (!bp_pos.IsDebugPause()) {
           if (FLAG_verbose_debug) {
             OS::Print("Failed resolving breakpoint for function '%s'\n",
                       String::Handle(func.name()).ToCString());
           }
           continue;
         }
-        intptr_t requested_pos = loc->token_pos();
-        intptr_t requested_end_pos = loc->end_token_pos();
+        TokenPosition requested_pos = loc->token_pos();
+        TokenPosition requested_end_pos = loc->end_token_pos();
         loc->SetResolved(func, bp_pos);
         Breakpoint* bpt = loc->breakpoints();
         while (bpt != NULL) {
           if (FLAG_verbose_debug) {
-            OS::Print("Resolved BP %" Pd " to pos %" Pd ", "
+            OS::Print("Resolved BP %" Pd " to pos %s, "
                       "line %" Pd " col %" Pd ", "
-                      "function '%s' (requested range %" Pd "-%" Pd ", "
+                      "function '%s' (requested range %s-%s, "
                       "requested col %" Pd ")\n",
                       bpt->id(),
-                      loc->token_pos(),
+                      loc->token_pos().ToCString(),
                       loc->LineNumber(),
                       loc->ColumnNumber(),
                       func.ToFullyQualifiedCString(),
-                      requested_pos,
-                      requested_end_pos,
+                      requested_pos.ToCString(),
+                      requested_end_pos.ToCString(),
                       loc->requested_column_number());
           }
           SignalBpResolved(bpt);
@@ -2991,10 +3003,9 @@
         intptr_t line_number = matched_loc->requested_line_number();
         intptr_t column_number = matched_loc->requested_column_number();
         ASSERT(line_number >= 0);
-        intptr_t first_token_pos, last_token_pos;
+        TokenPosition first_token_pos, last_token_pos;
         script.TokenRangeAtLine(line_number, &first_token_pos, &last_token_pos);
-        if (!Token::IsDebugPause(first_token_pos) ||
-            !Token::IsDebugPause(last_token_pos)) {
+        if (!first_token_pos.IsDebugPause() || !last_token_pos.IsDebugPause()) {
           // Script does not contain the given line number or there are no
           // tokens on the line. Drop the breakpoint silently.
           Breakpoint* bpt = matched_loc->breakpoints();
@@ -3202,7 +3213,7 @@
 
 
 BreakpointLocation* Debugger::GetBreakpointLocation(const Script& script,
-                                                    intptr_t token_pos,
+                                                    TokenPosition token_pos,
                                                     intptr_t requested_column) {
   BreakpointLocation* bpt = breakpoint_locations_;
   while (bpt != NULL) {
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 5696e96..d6904d5 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -98,8 +98,8 @@
  public:
   // Create a new unresolved breakpoint.
   BreakpointLocation(const Script& script,
-                     intptr_t token_pos,
-                     intptr_t end_token_pos,
+                     TokenPosition token_pos,
+                     TokenPosition end_token_pos,
                      intptr_t requested_line_number,
                      intptr_t requested_column_number);
   // Create a new latent breakpoint.
@@ -110,8 +110,8 @@
   ~BreakpointLocation();
 
   RawFunction* function() const { return function_; }
-  intptr_t token_pos() const { return token_pos_; }
-  intptr_t end_token_pos() const { return end_token_pos_; }
+  TokenPosition token_pos() const { return token_pos_; }
+  TokenPosition end_token_pos() const { return end_token_pos_; }
 
   RawScript* script() const { return script_; }
   RawString* url() const { return url_; }
@@ -124,7 +124,7 @@
 
   void GetCodeLocation(Library* lib,
                        Script* script,
-                       intptr_t* token_pos) const;
+                       TokenPosition* token_pos) const;
 
   Breakpoint* AddRepeated(Debugger* dbg);
   Breakpoint* AddSingleShot(Debugger* dbg);
@@ -132,12 +132,12 @@
 
   bool AnyEnabled() const;
   bool IsResolved() const { return is_resolved_; }
-  bool IsLatent() const { return token_pos_ < 0; }
+  bool IsLatent() const { return !token_pos_.IsReal(); }
 
  private:
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
 
-  void SetResolved(const Function& func, intptr_t token_pos);
+  void SetResolved(const Function& func, TokenPosition token_pos);
 
   BreakpointLocation* next() const { return this->next_; }
   void set_next(BreakpointLocation* value) { next_ = value; }
@@ -149,8 +149,8 @@
 
   RawScript* script_;
   RawString* url_;
-  intptr_t token_pos_;
-  intptr_t end_token_pos_;
+  TokenPosition token_pos_;
+  TokenPosition end_token_pos_;
   bool is_resolved_;
   BreakpointLocation* next_;
   Breakpoint* conditions_;
@@ -173,14 +173,14 @@
 class CodeBreakpoint {
  public:
   CodeBreakpoint(const Code& code,
-                 intptr_t token_pos,
+                 TokenPosition token_pos,
                  uword pc,
                  RawPcDescriptors::Kind kind);
   ~CodeBreakpoint();
 
   RawFunction* function() const;
   uword pc() const { return pc_; }
-  intptr_t token_pos() const { return token_pos_; }
+  TokenPosition token_pos() const { return token_pos_; }
   bool IsInternal() const { return bpt_location_ == NULL; }
 
   RawScript* SourceCode();
@@ -206,7 +206,7 @@
   void RestoreCode();
 
   RawCode* code_;
-  intptr_t token_pos_;
+  TokenPosition token_pos_;
   uword pc_;
   intptr_t line_number_;
   bool is_enabled_;
@@ -245,7 +245,7 @@
   RawString* SourceUrl();
   RawScript* SourceScript();
   RawLibrary* Library();
-  intptr_t TokenPos();
+  TokenPosition TokenPos();
   intptr_t LineNumber();
   intptr_t ColumnNumber();
 
@@ -264,8 +264,8 @@
 
   void VariableAt(intptr_t i,
                   String* name,
-                  intptr_t* token_pos,
-                  intptr_t* end_pos,
+                  TokenPosition* token_pos,
+                  TokenPosition* end_pos,
                   Object* value);
 
   RawArray* GetLocalVariables();
@@ -305,7 +305,7 @@
   const Code& code_;
   const Function& function_;
   bool token_pos_initialized_;
-  intptr_t token_pos_;
+  TokenPosition token_pos_;
   intptr_t try_index_;
 
   intptr_t line_number_;
@@ -589,20 +589,20 @@
   void InvokeEventHandler(DebuggerEvent* event);
 
   void FindCompiledFunctions(const Script& script,
-                             intptr_t start_pos,
-                             intptr_t end_pos,
+                             TokenPosition start_pos,
+                             TokenPosition end_pos,
                              GrowableObjectArray* function_list);
-  RawFunction* FindBestFit(const Script& script, intptr_t token_pos);
+  RawFunction* FindBestFit(const Script& script, TokenPosition token_pos);
   RawFunction* FindInnermostClosure(const Function& function,
-                                    intptr_t token_pos);
-  intptr_t ResolveBreakpointPos(const Function& func,
-                                intptr_t requested_token_pos,
-                                intptr_t last_token_pos,
-                                intptr_t requested_column);
+                                    TokenPosition token_pos);
+  TokenPosition ResolveBreakpointPos(const Function& func,
+                                       TokenPosition requested_token_pos,
+                                       TokenPosition last_token_pos,
+                                       intptr_t requested_column);
   void DeoptimizeWorld();
   BreakpointLocation* SetBreakpoint(const Script& script,
-                                    intptr_t token_pos,
-                                    intptr_t last_token_pos,
+                                    TokenPosition token_pos,
+                                    TokenPosition last_token_pos,
                                     intptr_t requested_line,
                                     intptr_t requested_column);
   void RemoveInternalBreakpoints();
@@ -613,7 +613,7 @@
   void RegisterBreakpointLocation(BreakpointLocation* bpt);
   void RegisterCodeBreakpoint(CodeBreakpoint* bpt);
   BreakpointLocation* GetBreakpointLocation(const Script& script,
-                                            intptr_t token_pos,
+                                            TokenPosition token_pos,
                                             intptr_t requested_column);
   void MakeCodeBreakpointAt(const Function& func,
                             BreakpointLocation* bpt);
diff --git a/runtime/vm/debugger_api_impl.cc b/runtime/vm/debugger_api_impl.cc
index 5241d34..9ac461c 100644
--- a/runtime/vm/debugger_api_impl.cc
+++ b/runtime/vm/debugger_api_impl.cc
@@ -122,7 +122,7 @@
       location.script_url = Api::NewHandle(thread, top_frame->SourceUrl());
       const Library& lib = Library::Handle(top_frame->Library());
       location.library_id = lib.index();
-      location.token_pos = top_frame->TokenPos();
+      location.token_pos = top_frame->TokenPos().Pos();
       intptr_t bp_id = 0;
       if (event->breakpoint() != NULL) {
         ASSERT(event->breakpoint()->id() != ILLEGAL_BREAKPOINT_ID);
@@ -138,11 +138,11 @@
       Zone* zone = thread->zone();
       Library& library = Library::Handle(zone);
       Script& script = Script::Handle(zone);
-      intptr_t token_pos;
+      TokenPosition token_pos;
       bpt->bpt_location()->GetCodeLocation(&library, &script, &token_pos);
       location.script_url = Api::NewHandle(thread, script.url());
       location.library_id = library.index();
-      location.token_pos = token_pos;
+      location.token_pos = token_pos.Pos();
       (*bp_resolved_handler)(isolate_id, bpt->id(), location);
     }
   } else if (event->type() == DebuggerEvent::kExceptionThrown) {
@@ -292,7 +292,7 @@
     location->script_url = Api::NewHandle(T, frame->SourceUrl());
     const Library& lib = Library::Handle(Z, frame->Library());
     location->library_id = lib.index();
-    location->token_pos = frame->TokenPos();
+    location->token_pos = frame->TokenPos().Pos();
   }
   return Api::Success();
 }
@@ -652,7 +652,7 @@
 
   // Construct the super type object, canonicalize it and return.
   Type& instantiated_type = Type::Handle(
-      Type::New(super_cls, super_type_args_array, Token::kNoSourcePos));
+      Type::New(super_cls, super_type_args_array, TokenPosition::kNoSource));
   ASSERT(!instantiated_type.IsNull());
   instantiated_type.SetIsFinalized();
   return Api::NewHandle(T, instantiated_type.Canonicalize());
@@ -681,7 +681,7 @@
   }
 
   if (location != NULL) {
-    if (func.token_pos() >= 0) {
+    if (func.token_pos().IsReal()) {
       const Class& cls = Class::Handle(Z, func.origin());
       ASSERT(!cls.IsNull());
       const Library& lib = Library::Handle(Z, cls.library());
@@ -691,7 +691,7 @@
       ASSERT(!script.IsNull());
       location->script_url = Api::NewHandle(T, script.url());
       location->library_id = lib.index();
-      location->token_pos = func.token_pos();
+      location->token_pos = func.token_pos().Pos();
     } else {
       location->script_url = Api::NewHandle(T, String::null());
       location->library_id = -1;
diff --git a/runtime/vm/deopt_instructions.cc b/runtime/vm/deopt_instructions.cc
index 4970e59..bdb5035 100644
--- a/runtime/vm/deopt_instructions.cc
+++ b/runtime/vm/deopt_instructions.cc
@@ -356,7 +356,7 @@
     const Code& code = Code::Handle(top_frame->LookupDartCode());
     const Function& top_function = Function::Handle(code.function());
     const Script& script = Script::Handle(top_function.script());
-    const intptr_t token_pos = code.GetTokenIndexOfPC(top_frame->pc());
+    const TokenPosition token_pos = code.GetTokenIndexOfPC(top_frame->pc());
     intptr_t line, column;
     script.GetTokenLocation(token_pos, &line, &column);
     String& line_string = String::Handle(script.GetLine(line));
@@ -423,8 +423,10 @@
 
  private:
   static const intptr_t kFieldWidth = kBitsPerWord / 2;
-  class ObjectTableIndex : public BitField<intptr_t, 0, kFieldWidth> { };
-  class DeoptId : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
+  class ObjectTableIndex :
+      public BitField<intptr_t, intptr_t, 0, kFieldWidth> { };
+  class DeoptId :
+      public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> { };
 
   const intptr_t object_table_index_;
   const intptr_t deopt_id_;
@@ -547,8 +549,9 @@
 
  private:
   static const intptr_t kFieldWidth = kBitsPerWord / 2;
-  class LoRegister : public BitField<intptr_t, 0, kFieldWidth> { };
-  class HiRegister : public BitField<intptr_t, kFieldWidth, kFieldWidth> { };
+  class LoRegister : public BitField<intptr_t, intptr_t, 0, kFieldWidth> { };
+  class HiRegister :
+      public BitField<intptr_t, intptr_t, kFieldWidth, kFieldWidth> { };
 
   const CpuRegisterSource lo_;
   const CpuRegisterSource hi_;
diff --git a/runtime/vm/deopt_instructions.h b/runtime/vm/deopt_instructions.h
index acbf92b..3dd538f 100644
--- a/runtime/vm/deopt_instructions.h
+++ b/runtime/vm/deopt_instructions.h
@@ -399,8 +399,9 @@
   }
 
  private:
-  class KindField : public BitField<intptr_t, 0, 1> { };
-  class RawIndexField : public BitField<intptr_t, 1, kBitsPerWord - 1> { };
+  class KindField : public BitField<intptr_t, intptr_t, 0, 1> { };
+  class RawIndexField :
+      public BitField<intptr_t, intptr_t, 1, kBitsPerWord - 1> { };
 
   bool is_register() const {
     return KindField::decode(source_index_) == kRegister;
@@ -543,8 +544,9 @@
                     FlagsField::encode(flags));
   }
 
-  class ReasonField : public BitField<ICData::DeoptReasonId, 0, 8> { };
-  class FlagsField : public BitField<uint32_t, 8, 8> { };
+  class ReasonField :
+      public BitField<intptr_t, ICData::DeoptReasonId, 0, 8> { };
+  class FlagsField : public BitField<intptr_t, uint32_t, 8, 8> { };
 
  private:
   static const intptr_t kEntrySize = 3;
diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc
index 99563bb..29f1684 100644
--- a/runtime/vm/exceptions.cc
+++ b/runtime/vm/exceptions.cc
@@ -19,6 +19,8 @@
 
 namespace dart {
 
+DEFINE_FLAG(bool, abort_on_assertion_errors, false,
+            "Abort on assertion and typecheck failures");
 DEFINE_FLAG(bool, print_stacktrace_at_throw, false,
             "Prints a stack trace everytime a throw occurs.");
 
@@ -424,7 +426,7 @@
 
 // Allocate, initialize, and throw a TypeError or CastError.
 // If error_msg is not null, throw a TypeError, even for a type cast.
-void Exceptions::CreateAndThrowTypeError(intptr_t location,
+void Exceptions::CreateAndThrowTypeError(TokenPosition location,
                                          const String& src_type_name,
                                          const String& dst_type_name,
                                          const String& dst_name,
@@ -457,7 +459,7 @@
 
   // Type errors in the core library may be difficult to diagnose.
   // Print type error information before throwing the error when debugging.
-  if (FLAG_print_stacktrace_at_throw) {
+  if (FLAG_print_stacktrace_at_throw || FLAG_abort_on_assertion_errors) {
     if (!error_msg.IsNull()) {
       OS::Print("%s\n", error_msg.ToCString());
     }
@@ -472,6 +474,11 @@
       OS::Print("type error.\n");
     }
   }
+
+  if (FLAG_abort_on_assertion_errors) {
+    PrintStackTraceAndAbort("a type error");
+  }
+
   // Throw TypeError or CastError instance.
   Exceptions::ThrowByType(exception_type, args);
   UNREACHABLE();
@@ -677,4 +684,14 @@
   Exceptions::ThrowByType(Exceptions::kJavascriptCompatibilityError, exc_args);
 }
 
+
+void Exceptions::PrintStackTraceAndAbort(const char* reason) {
+  const Instance& stacktrace = Instance::Handle(CurrentStacktrace());
+
+  OS::PrintErr("\n\n\nAborting due to %s. Stacktrace:\n%s\n",
+               reason,
+               stacktrace.ToCString());
+  OS::Abort();
+}
+
 }  // namespace dart
diff --git a/runtime/vm/exceptions.h b/runtime/vm/exceptions.h
index 4282bb5..ada7606 100644
--- a/runtime/vm/exceptions.h
+++ b/runtime/vm/exceptions.h
@@ -6,6 +6,7 @@
 #define VM_EXCEPTIONS_H_
 
 #include "vm/allocation.h"
+#include "vm/token_position.h"
 
 namespace dart {
 
@@ -42,7 +43,7 @@
   static RawStacktrace* CurrentStacktrace();
   static RawScript* GetCallerScript(DartFrameIterator* iterator);
   static RawInstance* NewInstance(const char* class_name);
-  static void CreateAndThrowTypeError(intptr_t location,
+  static void CreateAndThrowTypeError(TokenPosition location,
                                       const String& src_type_name,
                                       const String& dst_type_name,
                                       const String& dst_name,
@@ -86,6 +87,8 @@
   // otherwise returns a RawError.
   static RawObject* Create(ExceptionType type, const Array& arguments);
 
+  static void PrintStackTraceAndAbort(const char* reason);
+
  private:
   DISALLOW_COPY_AND_ASSIGN(Exceptions);
 };
diff --git a/runtime/vm/exceptions_test.cc b/runtime/vm/exceptions_test.cc
index 1901c58..355bc01 100644
--- a/runtime/vm/exceptions_test.cc
+++ b/runtime/vm/exceptions_test.cc
@@ -79,7 +79,7 @@
                                          int argument_count,
                                          bool* auto_setup_scope) {
   ASSERT(auto_setup_scope != NULL);
-  *auto_setup_scope = false;
+  *auto_setup_scope = true;
   const Object& obj = Object::Handle(Api::UnwrapHandle(name));
   ASSERT(obj.IsString());
   const char* function_name = obj.ToCString();
diff --git a/runtime/vm/find_code_object_test.cc b/runtime/vm/find_code_object_test.cc
index 96ff8d3..caece81 100644
--- a/runtime/vm/find_code_object_test.cc
+++ b/runtime/vm/find_code_object_test.cc
@@ -13,7 +13,7 @@
 
 namespace dart {
 
-TEST_CASE(FindCodeObject) {
+VM_TEST_CASE(FindCodeObject) {
 #if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64)
   const int kLoopCount = 50000;
 #else
diff --git a/runtime/vm/flow_graph_builder.cc b/runtime/vm/flow_graph_builder.cc
index ee62949..861721a 100644
--- a/runtime/vm/flow_graph_builder.cc
+++ b/runtime/vm/flow_graph_builder.cc
@@ -49,7 +49,7 @@
 #define Z (zone())
 
 // Quick synthetic token position.
-#define ST(token_pos) Token::ToSynthetic(token_pos)
+#define ST(token_pos) ((token_pos).ToSynthetic())
 
 // TODO(srdjan): Allow compiler to add constants as they are encountered in
 // the compilation.
@@ -560,7 +560,7 @@
     ConstantInstr* true_const = caller_graph_->GetConstant(Bool::True());
     BranchInstr* branch =
         new(Z) BranchInstr(
-            new(Z) StrictCompareInstr(call_block->start_pos(),
+            new(Z) StrictCompareInstr(TokenPosition::kNoSource,
                                       Token::kEQ_STRICT,
                                       new(Z) Value(true_const),
                                       new(Z) Value(true_const),
@@ -707,7 +707,8 @@
 }
 
 
-void EffectGraphVisitor::AddReturnExit(intptr_t token_pos, Value* value) {
+void EffectGraphVisitor::AddReturnExit(TokenPosition token_pos,
+                                       Value* value) {
   ASSERT(is_open());
   ReturnInstr* return_instr = new(Z) ReturnInstr(token_pos, value);
   AddInstruction(return_instr);
@@ -781,7 +782,7 @@
 
 
 void EffectGraphVisitor::TieLoop(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const TestGraphVisitor& test_fragment,
     const EffectGraphVisitor& body_fragment,
     const EffectGraphVisitor& test_preamble_fragment) {
@@ -833,23 +834,23 @@
 
 Definition* EffectGraphVisitor::BuildStoreTemp(const LocalVariable& local,
                                                Value* value,
-                                               intptr_t token_pos) {
+                                               TokenPosition token_pos) {
   ASSERT(!local.is_captured());
-  ASSERT(!Token::IsClassifying(token_pos));
+  ASSERT(!token_pos.IsClassifying());
   return new(Z) StoreLocalInstr(local, value, ST(token_pos));
 }
 
 
 Definition* EffectGraphVisitor::BuildStoreExprTemp(Value* value,
-                                                   intptr_t token_pos) {
+                                                   TokenPosition token_pos) {
   return BuildStoreTemp(*owner()->parsed_function().expression_temp_var(),
                         value,
                         token_pos);
 }
 
 
-Definition* EffectGraphVisitor::BuildLoadExprTemp(intptr_t token_pos) {
-  ASSERT(!Token::IsClassifying(token_pos));
+Definition* EffectGraphVisitor::BuildLoadExprTemp(TokenPosition token_pos) {
+  ASSERT(!token_pos.IsClassifying());
   return BuildLoadLocal(*owner()->parsed_function().expression_temp_var(),
                         token_pos);
 }
@@ -857,7 +858,7 @@
 
 Definition* EffectGraphVisitor::BuildStoreLocal(const LocalVariable& local,
                                                 Value* value,
-                                                intptr_t token_pos) {
+                                                TokenPosition token_pos) {
   if (local.is_captured()) {
     LocalVariable* tmp_var = EnterTempLocalScope(value, token_pos);
     intptr_t delta =
@@ -885,7 +886,7 @@
 
 
 Definition* EffectGraphVisitor::BuildLoadLocal(const LocalVariable& local,
-                                               intptr_t token_pos) {
+                                               TokenPosition token_pos) {
   if (local.IsConst()) {
     return new(Z) ConstantInstr(*local.ConstValue(), token_pos);
   } else if (local.is_captured()) {
@@ -911,8 +912,8 @@
 // Stores current context into the 'variable'
 void EffectGraphVisitor::BuildSaveContext(
     const LocalVariable& variable,
-    intptr_t token_pos) {
-  ASSERT(Token::IsSynthetic(token_pos) || Token::IsNoSource(token_pos));
+    TokenPosition token_pos) {
+  ASSERT(token_pos.IsSynthetic() || token_pos.IsNoSource());
   Value* context = Bind(BuildCurrentContext(token_pos));
   Do(BuildStoreLocal(variable, context, token_pos));
 }
@@ -921,20 +922,20 @@
 // Loads context saved in 'context_variable' into the current context.
 void EffectGraphVisitor::BuildRestoreContext(
     const LocalVariable& variable,
-    intptr_t token_pos) {
+    TokenPosition token_pos) {
   Value* load_saved_context = Bind(BuildLoadLocal(variable, token_pos));
   Do(BuildStoreContext(load_saved_context, token_pos));
 }
 
 
 Definition* EffectGraphVisitor::BuildStoreContext(
-    Value* value, intptr_t token_pos) {
+    Value* value, TokenPosition token_pos) {
   return new(Z) StoreLocalInstr(
       *owner()->parsed_function().current_context_var(), value, token_pos);
 }
 
 
-Definition* EffectGraphVisitor::BuildCurrentContext(intptr_t token_pos) {
+Definition* EffectGraphVisitor::BuildCurrentContext(TokenPosition token_pos) {
   return new(Z) LoadLocalInstr(
       *owner()->parsed_function().current_context_var(),
       token_pos);
@@ -1132,7 +1133,8 @@
   // statements for which there is no associated source position.
   const Function& function = owner()->function();
   if (FLAG_support_debugger &&
-      Token::IsDebugPause(node->token_pos()) && !function.is_native()) {
+      node->token_pos().IsDebugPause() &&
+      !function.is_native()) {
     AddInstruction(new(Z) DebugStepCheckInstr(node->token_pos(),
                                               RawPcDescriptors::kRuntimeCall));
   }
@@ -1266,7 +1268,7 @@
 // Returns true if the type check can be skipped, for example, if the
 // destination type is dynamic or if the compile type of the value is a subtype
 // of the destination type.
-bool EffectGraphVisitor::CanSkipTypeCheck(intptr_t token_pos,
+bool EffectGraphVisitor::CanSkipTypeCheck(TokenPosition token_pos,
                                           Value* value,
                                           const AbstractType& dst_type,
                                           const String& dst_name) {
@@ -1507,7 +1509,7 @@
 
 
 void EffectGraphVisitor::BuildTypecheckPushArguments(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     PushArgumentInstr** push_instantiator_type_arguments_result) {
   const Class& instantiator_class = Class::Handle(
       Z, owner()->function().Owner());
@@ -1530,7 +1532,7 @@
 
 
 void EffectGraphVisitor::BuildTypecheckArguments(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     Value** instantiator_type_arguments_result) {
   Value* instantiator = NULL;
   Value* instantiator_type_arguments = NULL;
@@ -1551,7 +1553,7 @@
 }
 
 
-Value* EffectGraphVisitor::BuildNullValue(intptr_t token_pos) {
+Value* EffectGraphVisitor::BuildNullValue(TokenPosition token_pos) {
   return Bind(new(Z) ConstantInstr(Object::ZoneHandle(Z, Object::null()),
                                    token_pos));
 }
@@ -1559,7 +1561,7 @@
 
 // Used for testing incoming arguments.
 AssertAssignableInstr* EffectGraphVisitor::BuildAssertAssignable(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     Value* value,
     const AbstractType& dst_type,
     const String& dst_name) {
@@ -1582,7 +1584,7 @@
 
 
 // Used for type casts and to test assignments.
-Value* EffectGraphVisitor::BuildAssignableValue(intptr_t token_pos,
+Value* EffectGraphVisitor::BuildAssignableValue(TokenPosition token_pos,
                                                 Value* value,
                                                 const AbstractType& dst_type,
                                                 const String& dst_name) {
@@ -1752,10 +1754,11 @@
 }
 
 
-StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(AstNode* left,
-                                                           AstNode* right,
-                                                           Token::Kind kind,
-                                                           intptr_t token_pos) {
+StrictCompareInstr* EffectGraphVisitor::BuildStrictCompare(
+    AstNode* left,
+    AstNode* right,
+    Token::Kind kind,
+    TokenPosition token_pos) {
   ValueGraphVisitor for_left_value(owner());
   left->Visit(&for_left_value);
   Append(for_left_value);
@@ -2286,8 +2289,7 @@
   // We need to create a new await state which involves:
   // * Increase the jump counter. Sanity check against the list of targets.
   // * Save the current context for resuming.
-  ASSERT(Token::IsSynthetic(node->token_pos()) ||
-         Token::IsNoSource(node->token_pos()));
+  ASSERT(node->token_pos().IsSynthetic() || node->token_pos().IsNoSource());
   ASSERT(node->async_scope() != NULL);
   ASSERT(node->await_scope() != NULL);
   LocalVariable* jump_var = node->async_scope()->LookupVariable(
@@ -2320,7 +2322,7 @@
 
 
 LocalVariable* EffectGraphVisitor::EnterTempLocalScope(
-    Value* value, intptr_t token_pos) {
+    Value* value, TokenPosition token_pos) {
   Do(new(Z) PushTempInstr(value));
   owner()->AllocateTemp();
 
@@ -2329,7 +2331,7 @@
   char name[64];
   OS::SNPrint(name, 64, ":tmp_local%" Pd, index);
   LocalVariable*  var =
-      new(Z) LocalVariable(Token::kNoSourcePos,
+      new(Z) LocalVariable(TokenPosition::kNoSource,
                            String::ZoneHandle(Z, Symbols::New(name)),
                            *value->Type()->ToAbstractType());
   var->set_index(index);
@@ -2338,7 +2340,7 @@
 
 
 Definition* EffectGraphVisitor::ExitTempLocalScope(
-    LocalVariable* var, intptr_t token_pos) {
+    LocalVariable* var, TokenPosition token_pos) {
   Value* tmp = Bind(new(Z) LoadLocalInstr(*var, token_pos));
   owner()->DeallocateTemps(1);
   ASSERT(GetCurrentTempLocalIndex() == var->index());
@@ -2626,7 +2628,7 @@
 
 
 void EffectGraphVisitor::BuildInstanceCallConditional(InstanceCallNode* node) {
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
   LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var);
 
@@ -2918,7 +2920,7 @@
 }
 
 
-Value* EffectGraphVisitor::BuildInstantiator(intptr_t token_pos) {
+Value* EffectGraphVisitor::BuildInstantiator(TokenPosition token_pos) {
   Function& outer_function = Function::Handle(Z, owner()->function().raw());
   while (outer_function.IsLocalFunction()) {
     outer_function = outer_function.parent_function();
@@ -2937,7 +2939,7 @@
 // 'expression_temp_var' may not be used inside this method if 'instantiator'
 // is not NULL.
 Value* EffectGraphVisitor::BuildInstantiatorTypeArguments(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const Class& instantiator_class,
     Value* instantiator) {
   if (!instantiator_class.IsGeneric()) {
@@ -2987,7 +2989,7 @@
 
 
 Value* EffectGraphVisitor::BuildInstantiatedTypeArguments(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const TypeArguments& type_arguments) {
   if (type_arguments.IsNull() || type_arguments.IsInstantiated()) {
     return Bind(new(Z) ConstantInstr(type_arguments));
@@ -3039,7 +3041,7 @@
 
 void EffectGraphVisitor::BuildInstanceGetterConditional(
     InstanceGetterNode* node) {
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   LocalVariable* temp_var = owner()->parsed_function().expression_temp_var();
   LoadLocalNode* load_temp = new(Z) LoadLocalNode(token_pos, temp_var);
 
@@ -3135,7 +3137,7 @@
 
 
 void EffectGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   if (node->is_conditional()) {
     ValueGraphVisitor for_receiver(owner());
     node->receiver()->Visit(&for_receiver);
@@ -3185,7 +3187,7 @@
 
 
 void ValueGraphVisitor::VisitInstanceSetterNode(InstanceSetterNode* node) {
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   if (node->is_conditional()) {
     ValueGraphVisitor for_receiver(owner());
     node->receiver()->Visit(&for_receiver);
@@ -3317,7 +3319,7 @@
       String::ZoneHandle(Z, Field::SetterSymbol(node->field_name()));
   ZoneGrowableArray<PushArgumentInstr*>* arguments =
       new(Z) ZoneGrowableArray<PushArgumentInstr*>(1);
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   // A super setter is an instance setter whose setter function is
   // resolved at compile time (in the caller instance getter's super class).
   // Unlike a static getter, a super getter has a receiver parameter.
@@ -3417,7 +3419,7 @@
 
 
 LoadLocalInstr* EffectGraphVisitor::BuildLoadThisVar(
-    LocalScope* scope, intptr_t token_pos) {
+    LocalScope* scope, TokenPosition token_pos) {
   LocalVariable* receiver_var = scope->LookupVariable(Symbols::This(),
                                                       true);  // Test only.
   return new(Z) LoadLocalInstr(*receiver_var, token_pos);
@@ -3462,7 +3464,7 @@
 
 void EffectGraphVisitor::VisitNativeBodyNode(NativeBodyNode* node) {
   const Function& function = owner()->function();
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   if (!function.IsClosureFunction()) {
     MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(function);
     switch (kind) {
@@ -3665,7 +3667,7 @@
             !node->value()->AsLoadLocalNode()->local().IsInternal()) ||
         node->value()->IsClosureNode()) &&
         !node->local().IsInternal() &&
-        Token::IsDebugPause(node->token_pos())) {
+        node->token_pos().IsDebugPause()) {
       AddInstruction(new(Z) DebugStepCheckInstr(
           node->token_pos(), RawPcDescriptors::kRuntimeCall));
     }
@@ -3711,7 +3713,7 @@
 
 void EffectGraphVisitor::VisitStoreInstanceFieldNode(
     StoreInstanceFieldNode* node) {
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   ValueGraphVisitor for_instance(owner());
   node->instance()->Visit(&for_instance);
   Append(for_instance);
@@ -3757,7 +3759,7 @@
 
 
 void EffectGraphVisitor::VisitLoadStaticFieldNode(LoadStaticFieldNode* node) {
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   if (node->field().is_const()) {
     ASSERT(node->field().StaticValue() != Object::sentinel().raw());
     ASSERT(node->field().StaticValue() !=
@@ -3776,7 +3778,7 @@
 Definition* EffectGraphVisitor::BuildStoreStaticField(
     StoreStaticFieldNode* node,
     bool result_is_needed,
-    intptr_t token_pos) {
+    TokenPosition token_pos) {
   ValueGraphVisitor for_value(owner());
   node->value()->Visit(&for_value);
   Append(for_value);
@@ -3874,7 +3876,7 @@
     StoreIndexedNode* node,
     bool result_is_needed) {
   Function* super_function = NULL;
-  const intptr_t token_pos = node->token_pos();
+  const TokenPosition token_pos = node->token_pos();
   if (node->IsSuperStore()) {
     // Resolve the store indexed operator in the super class.
     super_function = &Function::ZoneHandle(
@@ -3984,7 +3986,7 @@
 
 void EffectGraphVisitor::UnchainContexts(intptr_t n) {
   // TODO(johnmccutchan): Pass this in.
-  const intptr_t token_pos = ClassifyingTokenPositions::kContext;
+  const TokenPosition token_pos = TokenPosition::kContext;
   if (n > 0) {
     Value* context = Bind(BuildCurrentContext(token_pos));
     while (n-- > 0) {
@@ -4082,7 +4084,7 @@
           // Create a temporary local describing the original position.
           const String& temp_name = Symbols::TempParam();
           LocalVariable* temp_local = new(Z) LocalVariable(
-              Token::kNoSourcePos,  // Token index.
+              TokenPosition::kNoSource,  // Token index.
               temp_name,
               Object::dynamic_type());  // Type.
           temp_local->set_index(param_frame_index);
@@ -4117,15 +4119,16 @@
     // basic block. Place this check at the last parameter to ensure parameters
     // are in scope in the debugger at method entry.
     const int num_params = function.NumParameters();
-    intptr_t check_pos = Token::kNoSourcePos;
+    TokenPosition check_pos = TokenPosition::kNoSource;
     if (num_params > 0) {
       const LocalVariable& parameter = *scope->VariableAt(num_params - 1);
       check_pos = parameter.token_pos();
     }
-    if (!Token::IsDebugPause(check_pos)) {
+
+    if (!check_pos.IsDebugPause()) {
       // No parameters or synthetic parameters.
       check_pos = node->token_pos();
-      ASSERT(Token::IsDebugPause(check_pos));
+      ASSERT(check_pos.IsDebugPause());
     }
     AddInstruction(new(Z) DebugStepCheckInstr(check_pos,
                                               RawPcDescriptors::kRuntimeCall));
@@ -4429,7 +4432,7 @@
     ArgumentListNode* method_arguments,
     bool save_last_arg,
     bool is_super_invocation) {
-  intptr_t args_pos = method_arguments->token_pos();
+  TokenPosition args_pos = method_arguments->token_pos();
   LocalVariable* temp = NULL;
   if (save_last_arg) {
     temp = owner()->parsed_function().expression_temp_var();
@@ -4456,7 +4459,7 @@
 
 
 StaticCallInstr* EffectGraphVisitor::BuildThrowNoSuchMethodError(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const Class& function_class,
     const String& function_name,
     ArgumentListNode* function_arguments,
diff --git a/runtime/vm/flow_graph_builder.h b/runtime/vm/flow_graph_builder.h
index 2c2d14d..6dc14ce 100644
--- a/runtime/vm/flow_graph_builder.h
+++ b/runtime/vm/flow_graph_builder.h
@@ -288,7 +288,7 @@
   // Append a 'while loop' test and back edge to this graph, depending on
   // which parts are reachable.  Afterward, the graph exit is the false
   // successor of the loop condition.
-  void TieLoop(intptr_t token_pos,
+  void TieLoop(TokenPosition token_pos,
                const TestGraphVisitor& test_fragment,
                const EffectGraphVisitor& body_fragment,
                const EffectGraphVisitor& test_preamble_fragment);
@@ -300,21 +300,22 @@
   // This implementation shares state among visitors by using the builder.
   // The implementation is incorrect if a visitor that hits a return is not
   // actually added to the graph.
-  void AddReturnExit(intptr_t token_pos, Value* value);
+  void AddReturnExit(TokenPosition token_pos, Value* value);
 
  protected:
   Definition* BuildStoreTemp(const LocalVariable& local,
                              Value* value,
-                             intptr_t token_pos);
-  Definition* BuildStoreExprTemp(Value* value, intptr_t token_pos);
-  Definition* BuildLoadExprTemp(intptr_t token_pos);
+                             TokenPosition token_pos);
+  Definition* BuildStoreExprTemp(Value* value, TokenPosition token_pos);
+  Definition* BuildLoadExprTemp(TokenPosition token_pos);
 
   Definition* BuildStoreLocal(const LocalVariable& local,
                               Value* value,
-                              intptr_t token_pos);
+                              TokenPosition token_pos);
   Definition* BuildLoadLocal(const LocalVariable& local,
-                             intptr_t token_pos);
-  LoadLocalInstr* BuildLoadThisVar(LocalScope* scope, intptr_t token_pos);
+                             TokenPosition token_pos);
+  LoadLocalInstr* BuildLoadThisVar(LocalScope* scope,
+                                   TokenPosition token_pos);
   LoadFieldInstr* BuildNativeGetter(
       NativeBodyNode* node,
       MethodRecognizer::Kind kind,
@@ -335,27 +336,27 @@
   // allocation call.
   // May be called only if allocating an object of a parameterized class.
   Value* BuildInstantiatedTypeArguments(
-      intptr_t token_pos,
+      TokenPosition token_pos,
       const TypeArguments& type_arguments);
 
   void BuildTypecheckPushArguments(
-      intptr_t token_pos,
+      TokenPosition token_pos,
       PushArgumentInstr** push_instantiator_type_arguments);
-  void BuildTypecheckArguments(intptr_t token_pos,
+  void BuildTypecheckArguments(TokenPosition token_pos,
                                Value** instantiator_type_arguments);
-  Value* BuildInstantiator(intptr_t token_pos);
-  Value* BuildInstantiatorTypeArguments(intptr_t token_pos,
+  Value* BuildInstantiator(TokenPosition token_pos);
+  Value* BuildInstantiatorTypeArguments(TokenPosition token_pos,
                                         const Class& instantiator_class,
                                         Value* instantiator);
 
   // Perform a type check on the given value.
-  AssertAssignableInstr* BuildAssertAssignable(intptr_t token_pos,
+  AssertAssignableInstr* BuildAssertAssignable(TokenPosition token_pos,
                                                Value* value,
                                                const AbstractType& dst_type,
                                                const String& dst_name);
 
   // Perform a type check on the given value and return it.
-  Value* BuildAssignableValue(intptr_t token_pos,
+  Value* BuildAssignableValue(TokenPosition token_pos,
                               Value* value,
                               const AbstractType& dst_type,
                               const String& dst_name);
@@ -374,7 +375,7 @@
   StrictCompareInstr* BuildStrictCompare(AstNode* left,
                                          AstNode* right,
                                          Token::Kind kind,
-                                         intptr_t token_pos);
+                                         TokenPosition token_pos);
 
   virtual void BuildTypeTest(ComparisonNode* node);
   virtual void BuildTypeCast(ComparisonNode* node);
@@ -399,12 +400,12 @@
                             PushArgumentInstr* alloc_value);
 
   void BuildSaveContext(const LocalVariable& variable,
-                        intptr_t token_pos);
+                        TokenPosition token_pos);
   void BuildRestoreContext(const LocalVariable& variable,
-                           intptr_t token_pos);
+                           TokenPosition token_pos);
 
-  Definition* BuildStoreContext(Value* value, intptr_t token_pos);
-  Definition* BuildCurrentContext(intptr_t token_pos);
+  Definition* BuildStoreContext(Value* value, TokenPosition token_pos);
+  Definition* BuildCurrentContext(TokenPosition token_pos);
 
   void BuildThrowNode(ThrowNode* node);
 
@@ -417,7 +418,7 @@
       bool is_super_invocation);
 
   StaticCallInstr* BuildThrowNoSuchMethodError(
-      intptr_t token_pos,
+      TokenPosition token_pos,
       const Class& function_class,
       const String& function_name,
       ArgumentListNode* function_arguments,
@@ -426,22 +427,22 @@
   void BuildStaticSetter(StaticSetterNode* node, bool result_is_needed);
   Definition* BuildStoreStaticField(StoreStaticFieldNode* node,
                                     bool result_is_needed,
-                                    intptr_t token_pos);
+                                    TokenPosition token_pos);
 
   void BuildClosureCall(ClosureCallNode* node, bool result_needed);
 
-  Value* BuildNullValue(intptr_t token_pos);
+  Value* BuildNullValue(TokenPosition token_pos);
 
   // Returns true if the run-time type check can be eliminated.
-  bool CanSkipTypeCheck(intptr_t token_pos,
+  bool CanSkipTypeCheck(TokenPosition token_pos,
                         Value* value,
                         const AbstractType& dst_type,
                         const String& dst_name);
 
   // Helpers for allocating and deallocating temporary locals on top of the
   // expression stack.
-  LocalVariable* EnterTempLocalScope(Value* value, intptr_t token_pos);
-  Definition* ExitTempLocalScope(LocalVariable* var, intptr_t token_pos);
+  LocalVariable* EnterTempLocalScope(Value* value, TokenPosition token_pos);
+  Definition* ExitTempLocalScope(LocalVariable* var, TokenPosition token_pos);
 
   void BuildLetTempExpressions(LetNode* node);
 
@@ -545,7 +546,7 @@
 class TestGraphVisitor : public ValueGraphVisitor {
  public:
   TestGraphVisitor(FlowGraphBuilder* owner,
-                   intptr_t condition_token_pos)
+                   TokenPosition condition_token_pos)
       : ValueGraphVisitor(owner),
         true_successor_addresses_(1),
         false_successor_addresses_(1),
@@ -559,7 +560,7 @@
 
   virtual void VisitBinaryOpNode(BinaryOpNode* node);
 
-  intptr_t condition_token_pos() const { return condition_token_pos_; }
+  TokenPosition condition_token_pos() const { return condition_token_pos_; }
 
  private:
   // Construct and concatenate a Branch instruction to this graph fragment.
@@ -584,7 +585,7 @@
   GrowableArray<TargetEntryInstr**> true_successor_addresses_;
   GrowableArray<TargetEntryInstr**> false_successor_addresses_;
 
-  intptr_t condition_token_pos_;
+  TokenPosition condition_token_pos_;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/flow_graph_builder_test.cc b/runtime/vm/flow_graph_builder_test.cc
index 2213d0b..ba8f52a 100644
--- a/runtime/vm/flow_graph_builder_test.cc
+++ b/runtime/vm/flow_graph_builder_test.cc
@@ -166,29 +166,29 @@
     }
   }
 
-  // Fails if any of the IR nodes has a token position of Token::kNoSourcePos.
+  // Fails if any of the IR nodes has a token position of
+  // TokenPosition::kNoSourcePos.
   void EnsureSourcePositions() {
     for (intptr_t i = 0; i < blocks_->length(); i++) {
       BlockEntryInstr* entry = (*blocks_)[i];
-      DUMP_ASSERT(entry->token_pos() != Token::kNoSourcePos);
+      DUMP_ASSERT(entry->token_pos() != TokenPosition::kNoSource);
       for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
         Instruction* instr = it.Current();
-        DUMP_ASSERT(instr->token_pos() != Token::kNoSourcePos);
+        DUMP_ASSERT(instr->token_pos() != TokenPosition::kNoSource);
       }
     }
   }
 
  private:
   void DumpInstruction(Instruction* instr) {
-    intptr_t token_pos = instr->token_pos();
+    TokenPosition token_pos = instr->token_pos();
     bool synthetic = false;
-    if (Token::IsSynthetic(token_pos)) {
+    if (token_pos.IsSynthetic()) {
       synthetic = true;
-      token_pos = Token::FromSynthetic(token_pos);
+      token_pos = token_pos.FromSynthetic();
     }
-    if (token_pos < 0) {
-      const char* token_pos_string =
-          ClassifyingTokenPositions::ToCString(token_pos);
+    if (token_pos.IsClassifying()) {
+      const char* token_pos_string = token_pos.ToCString();
       THR_Print("%12s -- %s\n", token_pos_string, instr->ToCString());
       return;
     }
@@ -228,11 +228,11 @@
       BlockEntryInstr* entry = (*blocks_)[i];
       for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
         Instruction* instr = it.Current();
-        intptr_t token_pos = instr->token_pos();
-        if (Token::IsSynthetic(token_pos)) {
-          token_pos = Token::FromSynthetic(token_pos);
+        TokenPosition token_pos = instr->token_pos();
+        if (token_pos.IsSynthetic()) {
+          token_pos = token_pos.FromSynthetic();
         }
-        if (token_pos < 0) {
+        if (!token_pos.IsReal()) {
           continue;
         }
         intptr_t token_line = -1;
@@ -258,7 +258,7 @@
       BlockEntryInstr* entry = (*blocks_)[i];
       for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
         Instruction* instr = it.Current();
-        if (instr->token_pos() == token_pos) {
+        if (instr->token_pos().value() == token_pos) {
           instructions->Add(instr);
         }
       }
@@ -780,26 +780,28 @@
 }
 
 
-static bool SyntheticRoundTripTest(intptr_t token_pos) {
-  return Token::FromSynthetic(Token::ToSynthetic(token_pos)) == token_pos;
+static bool SyntheticRoundTripTest(TokenPosition token_pos) {
+  const TokenPosition synthetic_token_pos = token_pos.ToSynthetic();
+  return synthetic_token_pos.FromSynthetic() == token_pos;
 }
 
 
 UNIT_TEST_CASE(SourcePosition_SyntheticTokens) {
-  EXPECT(Token::kNoSourcePos == -1);
-  EXPECT(Token::kMinSourcePos == 0);
-  EXPECT(Token::kMaxSourcePos > 0);
-
-  EXPECT(!Token::IsSynthetic(0));
-  EXPECT(Token::IsSynthetic(Token::ToSynthetic(0)));
-  EXPECT(Token::IsSynthetic(Token::ToSynthetic(9)));
-  EXPECT(!Token::IsSynthetic(Token::FromSynthetic(-1)));
-  EXPECT(!Token::IsSynthetic(ClassifyingTokenPositions::kPrivate));
-  EXPECT(!Token::IsSynthetic(ClassifyingTokenPositions::kLast));
-
-  EXPECT(SyntheticRoundTripTest(0));
-  EXPECT(SyntheticRoundTripTest(Token::kMaxSourcePos));
-  EXPECT(SyntheticRoundTripTest(Token::kMinSourcePos));
+  EXPECT(TokenPosition::kNoSourcePos == -1);
+  EXPECT(TokenPosition::kMinSourcePos == 0);
+  EXPECT(TokenPosition::kMaxSourcePos > 0);
+  EXPECT(TokenPosition::kMaxSourcePos > TokenPosition::kMinSourcePos);
+  EXPECT(TokenPosition::kMinSource.value() == TokenPosition::kMinSourcePos);
+  EXPECT(TokenPosition::kMaxSource.value() == TokenPosition::kMaxSourcePos);
+  EXPECT(!TokenPosition(0).IsSynthetic());
+  EXPECT(TokenPosition(0).ToSynthetic().IsSynthetic());
+  EXPECT(TokenPosition(9).ToSynthetic().IsSynthetic());
+  EXPECT(!TokenPosition(-1).FromSynthetic().IsSynthetic());
+  EXPECT(!TokenPosition::kNoSource.IsSynthetic());
+  EXPECT(!TokenPosition::kLast.IsSynthetic());
+  EXPECT(SyntheticRoundTripTest(TokenPosition(0)));
+  EXPECT(SyntheticRoundTripTest(TokenPosition::kMaxSource));
+  EXPECT(SyntheticRoundTripTest(TokenPosition::kMinSource));
 }
 
 }  // namespace dart
diff --git a/runtime/vm/flow_graph_compiler.cc b/runtime/vm/flow_graph_compiler.cc
index eabcbf1..69640c4 100644
--- a/runtime/vm/flow_graph_compiler.cc
+++ b/runtime/vm/flow_graph_compiler.cc
@@ -107,11 +107,6 @@
     FLAG_load_deferred_eagerly = true;
     FLAG_deoptimize_alot = false;  // Used in some tests.
     FLAG_deoptimize_every = 0;     // Used in some tests.
-    Compiler::set_always_optimize(true);
-    // Triggers assert if we try to recompile (e.g., because of deferred
-    // loading, deoptimization, ...). Noopt mode simulates behavior
-    // of precompiled code, therefore do not allow recompilation.
-    Compiler::set_allow_recompilation(false);
     // Precompilation finalizes all classes and thus allows CHA optimizations.
     // Do not require CHA triggered deoptimization.
     FLAG_use_cha_deopt = false;
@@ -449,7 +444,7 @@
 
 
 void FlowGraphCompiler::EmitSourceLine(Instruction* instr) {
-  if ((instr->token_pos() < 0) || (instr->env() == NULL)) {
+  if (!instr->token_pos().IsReal() || (instr->env() == NULL)) {
     return;
   }
   const Script& script =
@@ -764,7 +759,7 @@
 // Uses current pc position and try-index.
 void FlowGraphCompiler::AddCurrentDescriptor(RawPcDescriptors::Kind kind,
                                              intptr_t deopt_id,
-                                             intptr_t token_pos) {
+                                             TokenPosition token_pos) {
   // When running with optimizations disabled, don't emit deopt-descriptors.
   if (!CanOptimize() && (kind == RawPcDescriptors::kDeopt)) return;
   pc_descriptors_list()->AddDescriptor(kind,
@@ -790,7 +785,7 @@
 
 
 void FlowGraphCompiler::AddDeoptIndexAtCall(intptr_t deopt_id,
-                                            intptr_t token_pos) {
+                                            TokenPosition token_pos) {
   ASSERT(is_optimizing());
   ASSERT(!intrinsic_mode());
   CompilerDeoptInfo* info =
@@ -940,7 +935,7 @@
   }
 
   // No deoptimization allowed when 'always_optimize' is set.
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     if (FLAG_trace_compiler) {
       THR_Print(
           "Retrying compilation %s, suppressing inlining of deopt_id:%" Pd "\n",
@@ -988,7 +983,7 @@
 
 RawArray* FlowGraphCompiler::CreateDeoptInfo(Assembler* assembler) {
   // No deopt information if we 'always_optimize' (no deoptimization allowed).
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     return Array::empty_array().raw();
   }
   // For functions with optional arguments, all incoming arguments are copied
@@ -1049,8 +1044,8 @@
     RawLocalVarDescriptors::VarInfo info;
     info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
     info.scope_id = 0;
-    info.begin_pos = 0;
-    info.end_pos = 0;
+    info.begin_pos = TokenPosition::kMinSource;
+    info.end_pos = TokenPosition::kMinSource;
     info.set_index(parsed_function().current_context_var()->index());
     var_descs.SetVar(0, Symbols::CurrentContextVar(), &info);
   }
@@ -1140,12 +1135,12 @@
 
 void FlowGraphCompiler::GenerateInstanceCall(
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     intptr_t argument_count,
     LocationSummary* locs,
     const ICData& ic_data_in) {
   const ICData& ic_data = ICData::ZoneHandle(ic_data_in.Original());
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     EmitSwitchableInstanceCall(ic_data, argument_count,
                                deopt_id, token_pos, locs);
     return;
@@ -1206,7 +1201,7 @@
 
 
 void FlowGraphCompiler::GenerateStaticCall(intptr_t deopt_id,
-                                           intptr_t token_pos,
+                                           TokenPosition token_pos,
                                            const Function& function,
                                            intptr_t argument_count,
                                            const Array& argument_names,
@@ -1785,7 +1780,7 @@
     intptr_t argument_count,
     const Array& argument_names,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   if (FLAG_polymorphic_with_deopt) {
     Label* deopt = AddDeoptStub(deopt_id,
diff --git a/runtime/vm/flow_graph_compiler.h b/runtime/vm/flow_graph_compiler.h
index b6d4c4c..57bff29 100644
--- a/runtime/vm/flow_graph_compiler.h
+++ b/runtime/vm/flow_graph_compiler.h
@@ -219,7 +219,7 @@
   MegamorphicSlowPath(const ICData& ic_data,
                       intptr_t argument_count,
                       intptr_t deopt_id,
-                      intptr_t token_pos,
+                      TokenPosition token_pos,
                       LocationSummary* locs,
                       intptr_t try_index)
     : SlowPathCode(),
@@ -237,7 +237,7 @@
   const ICData& ic_data_;
   intptr_t argument_count_;
   intptr_t deopt_id_;
-  intptr_t token_pos_;
+  TokenPosition token_pos_;
   LocationSummary* locs_;
   const intptr_t try_index_;  // For try/catch ranges.
 
@@ -365,43 +365,43 @@
   // Returns 'true' if regular code generation should be skipped.
   bool TryIntrinsify();
 
-  void GenerateRuntimeCall(intptr_t token_pos,
+  void GenerateRuntimeCall(TokenPosition token_pos,
                            intptr_t deopt_id,
                            const RuntimeEntry& entry,
                            intptr_t argument_count,
                            LocationSummary* locs);
 
-  void GenerateCall(intptr_t token_pos,
+  void GenerateCall(TokenPosition token_pos,
                     const StubEntry& stub_entry,
                     RawPcDescriptors::Kind kind,
                     LocationSummary* locs);
 
   void GenerateDartCall(intptr_t deopt_id,
-                        intptr_t token_pos,
+                        TokenPosition token_pos,
                         const StubEntry& stub_entry,
                         RawPcDescriptors::Kind kind,
                         LocationSummary* locs);
 
-  void GenerateAssertAssignable(intptr_t token_pos,
+  void GenerateAssertAssignable(TokenPosition token_pos,
                                 intptr_t deopt_id,
                                 const AbstractType& dst_type,
                                 const String& dst_name,
                                 LocationSummary* locs);
 
-  void GenerateInstanceOf(intptr_t token_pos,
+  void GenerateInstanceOf(TokenPosition token_pos,
                           intptr_t deopt_id,
                           const AbstractType& type,
                           bool negate_result,
                           LocationSummary* locs);
 
   void GenerateInstanceCall(intptr_t deopt_id,
-                            intptr_t token_pos,
+                            TokenPosition token_pos,
                             intptr_t argument_count,
                             LocationSummary* locs,
                             const ICData& ic_data);
 
   void GenerateStaticCall(intptr_t deopt_id,
-                          intptr_t token_pos,
+                          TokenPosition token_pos,
                           const Function& function,
                           intptr_t argument_count,
                           const Array& argument_names,
@@ -428,21 +428,21 @@
                                  const ICData& ic_data,
                                  intptr_t argument_count,
                                  intptr_t deopt_id,
-                                 intptr_t token_pos,
+                                 TokenPosition token_pos,
                                  LocationSummary* locs);
 
   void EmitInstanceCall(const StubEntry& stub_entry,
                         const ICData& ic_data,
                         intptr_t argument_count,
                         intptr_t deopt_id,
-                        intptr_t token_pos,
+                        TokenPosition token_pos,
                         LocationSummary* locs);
 
   void EmitPolymorphicInstanceCall(const ICData& ic_data,
                                    intptr_t argument_count,
                                    const Array& argument_names,
                                    intptr_t deopt_id,
-                                   intptr_t token_pos,
+                                   TokenPosition token_pos,
                                    LocationSummary* locs);
 
   // Pass a value for try-index where block is not available (e.g. slow path).
@@ -450,14 +450,14 @@
       const ICData& ic_data,
       intptr_t argument_count,
       intptr_t deopt_id,
-      intptr_t token_pos,
+      TokenPosition token_pos,
       LocationSummary* locs,
       intptr_t try_index = CatchClauseNode::kInvalidTryIndex);
 
   void EmitSwitchableInstanceCall(const ICData& ic_data,
                                   intptr_t argument_count,
                                   intptr_t deopt_id,
-                                  intptr_t token_pos,
+                                  TokenPosition token_pos,
                                   LocationSummary* locs);
 
   void EmitTestAndCall(const ICData& ic_data,
@@ -466,17 +466,17 @@
                        Label* failed,
                        Label* match_found,
                        intptr_t deopt_id,
-                       intptr_t token_index,
+                       TokenPosition token_index,
                        LocationSummary* locs);
 
   Condition EmitEqualityRegConstCompare(Register reg,
                                         const Object& obj,
                                         bool needs_number_check,
-                                        intptr_t token_pos);
+                                        TokenPosition token_pos);
   Condition EmitEqualityRegRegCompare(Register left,
                                       Register right,
                                       bool needs_number_check,
-                                      intptr_t token_pos);
+                                      TokenPosition token_pos);
 
   void EmitTrySync(Instruction* instr, intptr_t try_index);
 
@@ -504,7 +504,7 @@
   void SetNeedsStacktrace(intptr_t try_index);
   void AddCurrentDescriptor(RawPcDescriptors::Kind kind,
                             intptr_t deopt_id,
-                            intptr_t token_pos);
+                            TokenPosition token_pos);
 
   void RecordSafepoint(LocationSummary* locs);
 
@@ -512,7 +512,7 @@
                       ICData::DeoptReasonId reason,
                       uint32_t flags = 0);
 
-  void AddDeoptIndexAtCall(intptr_t deopt_id, intptr_t token_pos);
+  void AddDeoptIndexAtCall(intptr_t deopt_id, TokenPosition token_pos);
 
   void AddSlowPathCode(SlowPathCode* slow_path);
 
@@ -605,12 +605,12 @@
                                const Array& arguments_descriptor,
                                intptr_t argument_count,
                                intptr_t deopt_id,
-                               intptr_t token_pos,
+                               TokenPosition token_pos,
                                LocationSummary* locs);
 
   void EmitUnoptimizedStaticCall(intptr_t argument_count,
                                  intptr_t deopt_id,
-                                 intptr_t token_pos,
+                                 TokenPosition token_pos,
                                  LocationSummary* locs,
                                  const ICData& ic_data);
 
@@ -620,30 +620,30 @@
                      Label* is_instance_lbl,
                      Label* is_not_instance_lbl);
 
-  RawSubtypeTestCache* GenerateInlineInstanceof(intptr_t token_pos,
+  RawSubtypeTestCache* GenerateInlineInstanceof(TokenPosition token_pos,
                                                 const AbstractType& type,
                                                 Label* is_instance_lbl,
                                                 Label* is_not_instance_lbl);
 
   RawSubtypeTestCache* GenerateInstantiatedTypeWithArgumentsTest(
-      intptr_t token_pos,
+      TokenPosition token_pos,
       const AbstractType& dst_type,
       Label* is_instance_lbl,
       Label* is_not_instance_lbl);
 
-  bool GenerateInstantiatedTypeNoArgumentsTest(intptr_t token_pos,
+  bool GenerateInstantiatedTypeNoArgumentsTest(TokenPosition token_pos,
                                                const AbstractType& dst_type,
                                                Label* is_instance_lbl,
                                                Label* is_not_instance_lbl);
 
   RawSubtypeTestCache* GenerateUninstantiatedTypeTest(
-      intptr_t token_pos,
+      TokenPosition token_pos,
       const AbstractType& dst_type,
       Label* is_instance_lbl,
       Label* is_not_instance_label);
 
   RawSubtypeTestCache* GenerateSubtype1TestCacheLookup(
-      intptr_t token_pos,
+      TokenPosition token_pos,
       const Class& type_class,
       Label* is_instance_lbl,
       Label* is_not_instance_lbl);
diff --git a/runtime/vm/flow_graph_compiler_arm.cc b/runtime/vm/flow_graph_compiler_arm.cc
index 429631f..e3780cb 100644
--- a/runtime/vm/flow_graph_compiler_arm.cc
+++ b/runtime/vm/flow_graph_compiler_arm.cc
@@ -29,6 +29,7 @@
 DEFINE_FLAG(bool, unbox_doubles, true, "Optimize double arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
 DECLARE_FLAG(bool, use_megamorphic_stub);
+DECLARE_FLAG(bool, precompilation);
 
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -266,7 +267,7 @@
 // Clobbers R2.
 RawSubtypeTestCache*
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -356,7 +357,7 @@
 // Clobbers R2, R3.
 // Returns true if there is a fallthrough.
 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -426,7 +427,7 @@
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const Class& type_class,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -454,7 +455,7 @@
 // Generates inlined check if 'type' is a type parameter or type itself
 // R0: instance (preserved).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -537,7 +538,7 @@
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -590,7 +591,7 @@
 // - R1: instantiator type arguments or raw_null.
 // Returns:
 // - true or false in R0.
-void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
                                            intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
@@ -670,12 +671,12 @@
 // - object in R0 for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(!Token::IsClassifying(token_pos));
+  ASSERT(!token_pos.IsClassifying());
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1124,7 +1125,7 @@
   ASSERT(assembler()->constant_pool_allowed());
   GenerateDeferredCode();
 
-  if (is_optimizing() && Compiler::allow_recompilation()) {
+  if (is_optimizing() && !FLAG_precompilation) {
     // Leave enough space for patching in case of lazy deoptimization from
     // deferred code.
     for (intptr_t i = 0;
@@ -1138,7 +1139,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
                                      const StubEntry& stub_entry,
                                      RawPcDescriptors::Kind kind,
                                      LocationSummary* locs) {
@@ -1149,7 +1150,7 @@
 
 
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          const StubEntry& stub_entry,
                                          RawPcDescriptors::Kind kind,
                                          LocationSummary* locs) {
@@ -1170,7 +1171,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1224,7 +1225,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   // Each ICData propagated from unoptimized to optimized code contains the
@@ -1249,7 +1250,7 @@
                                          const ICData& ic_data,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   __ LoadUniqueObject(R9, ic_data);
@@ -1266,7 +1267,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
@@ -1288,7 +1289,7 @@
 
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     // Megamorphic calls may occur in slow path stubs.
     // If valid use try_index argument.
     if (try_index == CatchClauseNode::kInvalidTryIndex) {
@@ -1319,7 +1320,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ Comment("SwitchableCall");
   __ LoadFromOffset(kWord, R0, SP, (argument_count - 1) * kWordSize);
@@ -1358,7 +1359,7 @@
 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     const ICData& ic_data) {
   const StubEntry* stub_entry =
@@ -1378,7 +1379,7 @@
     const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ LoadObject(R4, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
@@ -1397,7 +1398,7 @@
     Register reg,
     const Object& obj,
     bool needs_number_check,
-    intptr_t token_pos) {
+    TokenPosition token_pos) {
   if (needs_number_check) {
     ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
     __ Push(reg);
@@ -1409,7 +1410,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1424,10 +1425,11 @@
 }
 
 
-Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                       Register right,
-                                                       bool needs_number_check,
-                                                       intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
+    Register left,
+    Register right,
+    bool needs_number_check,
+    TokenPosition token_pos) {
   if (needs_number_check) {
     __ Push(left);
     __ Push(right);
@@ -1438,7 +1440,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1552,7 +1554,7 @@
                                         Label* failed,
                                         Label* match_found,
                                         intptr_t deopt_id,
-                                        intptr_t token_index,
+                                        TokenPosition token_index,
                                         LocationSummary* locs) {
   ASSERT(is_optimizing());
   __ Comment("EmitTestAndCall");
diff --git a/runtime/vm/flow_graph_compiler_arm64.cc b/runtime/vm/flow_graph_compiler_arm64.cc
index 977010a..b86c581 100644
--- a/runtime/vm/flow_graph_compiler_arm64.cc
+++ b/runtime/vm/flow_graph_compiler_arm64.cc
@@ -26,6 +26,7 @@
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DECLARE_FLAG(bool, enable_simd_inline);
 DECLARE_FLAG(bool, use_megamorphic_stub);
+DECLARE_FLAG(bool, precompilation);
 
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -258,7 +259,7 @@
 // Clobbers R2.
 RawSubtypeTestCache*
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -348,7 +349,7 @@
 // Clobbers R2, R3.
 // Returns true if there is a fallthrough.
 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -418,7 +419,7 @@
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const Class& type_class,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -446,7 +447,7 @@
 // Generates inlined check if 'type' is a type parameter or type itself
 // R0: instance (preserved).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -529,7 +530,7 @@
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -582,7 +583,7 @@
 // - R1: instantiator type arguments or raw_null.
 // Returns:
 // - true or false in R0.
-void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
                                            intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
@@ -662,12 +663,12 @@
 // - object in R0 for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(!Token::IsClassifying(token_pos));
+  ASSERT(!TokenPosition(token_pos).IsClassifying());
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1117,7 +1118,7 @@
   ASSERT(assembler()->constant_pool_allowed());
   GenerateDeferredCode();
 
-  if (is_optimizing() && Compiler::allow_recompilation()) {
+  if (is_optimizing() && !FLAG_precompilation) {
     // Leave enough space for patching in case of lazy deoptimization from
     // deferred code.
     for (intptr_t i = 0;
@@ -1131,7 +1132,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
                                      const StubEntry& stub_entry,
                                      RawPcDescriptors::Kind kind,
                                      LocationSummary* locs) {
@@ -1142,7 +1143,7 @@
 
 
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          const StubEntry& stub_entry,
                                          RawPcDescriptors::Kind kind,
                                          LocationSummary* locs) {
@@ -1162,7 +1163,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1206,7 +1207,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   // Each ICData propagated from unoptimized to optimized code contains the
@@ -1231,7 +1232,7 @@
                                          const ICData& ic_data,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   __ LoadUniqueObject(R5, ic_data);
@@ -1248,7 +1249,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
@@ -1270,7 +1271,7 @@
 
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     // Megamorphic calls may occur in slow path stubs.
     // If valid use try_index argument.
     if (try_index == CatchClauseNode::kInvalidTryIndex) {
@@ -1300,7 +1301,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ Comment("SwitchableCall");
   __ LoadFromOffset(R0, SP, (argument_count - 1) * kWordSize);
@@ -1339,7 +1340,7 @@
 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     const ICData& ic_data) {
   const StubEntry* stub_entry =
@@ -1359,7 +1360,7 @@
     const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ LoadObject(R4, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
@@ -1378,7 +1379,7 @@
     Register reg,
     const Object& obj,
     bool needs_number_check,
-    intptr_t token_pos) {
+    TokenPosition token_pos) {
   if (needs_number_check) {
     ASSERT(!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint());
     __ Push(reg);
@@ -1390,7 +1391,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1405,10 +1406,11 @@
 }
 
 
-Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                       Register right,
-                                                       bool needs_number_check,
-                                                       intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
+    Register left,
+    Register right,
+    bool needs_number_check,
+    TokenPosition token_pos) {
   if (needs_number_check) {
     __ Push(left);
     __ Push(right);
@@ -1419,7 +1421,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1508,7 +1510,7 @@
                                         Label* failed,
                                         Label* match_found,
                                         intptr_t deopt_id,
-                                        intptr_t token_index,
+                                        TokenPosition token_index,
                                         LocationSummary* locs) {
   ASSERT(is_optimizing());
 
diff --git a/runtime/vm/flow_graph_compiler_ia32.cc b/runtime/vm/flow_graph_compiler_ia32.cc
index 3a2ee04..e142041 100644
--- a/runtime/vm/flow_graph_compiler_ia32.cc
+++ b/runtime/vm/flow_graph_compiler_ia32.cc
@@ -31,6 +31,7 @@
 
 DECLARE_FLAG(bool, enable_simd_inline);
 DECLARE_FLAG(bool, use_megamorphic_stub);
+DECLARE_FLAG(bool, precompilation);
 
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -270,7 +271,7 @@
 // Clobbers ECX, EDI.
 RawSubtypeTestCache*
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -359,7 +360,7 @@
 // Clobbers ECX, EDI.
 // Returns true if there is a fallthrough.
 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -429,7 +430,7 @@
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const Class& type_class,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -458,7 +459,7 @@
 // EAX: instance (preserved).
 // Clobbers EDX, EDI, ECX.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -543,7 +544,7 @@
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -597,7 +598,7 @@
 // Clobbers EDX.
 // Returns:
 // - true or false in EAX.
-void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
                                            intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
@@ -679,12 +680,12 @@
 // - object in EAX for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(!Token::IsClassifying(token_pos));
+  ASSERT(!token_pos.IsClassifying());
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1137,7 +1138,7 @@
   __ int3();
   GenerateDeferredCode();
 
-  if (is_optimizing() && Compiler::allow_recompilation()) {
+  if (is_optimizing() && !FLAG_precompilation) {
     // Leave enough space for patching in case of lazy deoptimization from
     // deferred code.
     __ nop(CallPattern::pattern_length_in_bytes());
@@ -1147,7 +1148,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
                                      const StubEntry& stub_entry,
                                      RawPcDescriptors::Kind kind,
                                      LocationSummary* locs) {
@@ -1158,7 +1159,7 @@
 
 
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          const StubEntry& stub_entry,
                                          RawPcDescriptors::Kind kind,
                                          LocationSummary* locs) {
@@ -1178,7 +1179,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1204,7 +1205,7 @@
 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     const ICData& ic_data) {
   const StubEntry& stub_entry =
@@ -1237,7 +1238,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
   // Each ICData propagated from unoptimized to optimized code contains the
@@ -1261,7 +1262,7 @@
                                          const ICData& ic_data,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          LocationSummary* locs) {
   ASSERT(Array::Handle(ic_data.arguments_descriptor()).Length() > 0);
   __ LoadObject(ECX, ic_data);
@@ -1278,7 +1279,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
@@ -1303,7 +1304,7 @@
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
   // Precompilation not implemented on ia32 platform.
-  ASSERT(!Compiler::always_optimize());
+  ASSERT(!FLAG_precompilation);
   if (is_optimizing()) {
     AddDeoptIndexAtCall(deopt_id_after, token_pos);
   } else {
@@ -1319,7 +1320,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   // Only generated with precompilation.
   UNREACHABLE();
@@ -1331,7 +1332,7 @@
     const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ LoadObject(EDX, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
@@ -1350,7 +1351,7 @@
     Register reg,
     const Object& obj,
     bool needs_number_check,
-    intptr_t token_pos) {
+    TokenPosition token_pos) {
   ASSERT(!needs_number_check ||
          (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
 
@@ -1368,7 +1369,7 @@
     } else {
       __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1383,10 +1384,11 @@
 }
 
 
-Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                       Register right,
-                                                       bool needs_number_check,
-                                                       intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
+    Register left,
+    Register right,
+    bool needs_number_check,
+    TokenPosition token_pos) {
   if (needs_number_check) {
     __ pushl(left);
     __ pushl(right);
@@ -1395,7 +1397,7 @@
     } else {
       __ Call(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1492,7 +1494,7 @@
                                         Label* failed,
                                         Label* match_found,
                                         intptr_t deopt_id,
-                                        intptr_t token_index,
+                                        TokenPosition token_index,
                                         LocationSummary* locs) {
   ASSERT(is_optimizing());
   __ Comment("EmitTestAndCall");
diff --git a/runtime/vm/flow_graph_compiler_mips.cc b/runtime/vm/flow_graph_compiler_mips.cc
index a6fef0b..654b755 100644
--- a/runtime/vm/flow_graph_compiler_mips.cc
+++ b/runtime/vm/flow_graph_compiler_mips.cc
@@ -24,6 +24,7 @@
 
 DEFINE_FLAG(bool, trap_on_deoptimization, false, "Trap on deoptimization.");
 DECLARE_FLAG(bool, use_megamorphic_stub);
+DECLARE_FLAG(bool, precompilation);
 
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
@@ -258,7 +259,7 @@
 // Clobbers T0.
 RawSubtypeTestCache*
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -347,7 +348,7 @@
 // Clobbers: T0, T1, T2
 // Returns true if there is a fallthrough.
 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -415,7 +416,7 @@
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const Class& type_class,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -442,7 +443,7 @@
 // Generates inlined check if 'type' is a type parameter or type itself
 // A0: instance (preserved).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -525,7 +526,7 @@
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -578,7 +579,7 @@
 // - A1: instantiator type arguments or raw_null.
 // Returns:
 // - true or false in V0.
-void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
                                            intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
@@ -663,13 +664,13 @@
 // Clobbers: T0, T1, T2
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
   __ Comment("AssertAssignable");
-  ASSERT(!Token::IsClassifying(token_pos));
+  ASSERT(!token_pos.IsClassifying());
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1137,7 +1138,7 @@
   __ break_(0);
   GenerateDeferredCode();
 
-  if (is_optimizing() && Compiler::allow_recompilation()) {
+  if (is_optimizing() && !FLAG_precompilation) {
     // Leave enough space for patching in case of lazy deoptimization from
     // deferred code.
     for (intptr_t i = 0;
@@ -1151,7 +1152,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
                                      const StubEntry& stub_entry,
                                      RawPcDescriptors::Kind kind,
                                      LocationSummary* locs) {
@@ -1162,7 +1163,7 @@
 
 
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          const StubEntry& stub_entry,
                                          RawPcDescriptors::Kind kind,
                                          LocationSummary* locs) {
@@ -1184,7 +1185,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1229,7 +1230,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   // Each ICData propagated from unoptimized to optimized code contains the
@@ -1254,7 +1255,7 @@
                                          const ICData& ic_data,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   __ Comment("InstanceCall");
@@ -1273,7 +1274,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
@@ -1295,7 +1296,7 @@
 
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     // Megamorphic calls may occur in slow path stubs.
     // If valid use try_index argument.
     if (try_index == CatchClauseNode::kInvalidTryIndex) {
@@ -1325,7 +1326,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ Comment("SwitchableCall");
   __ lw(T0, Address(SP, (argument_count - 1) * kWordSize));
@@ -1364,7 +1365,7 @@
 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     const ICData& ic_data) {
   const StubEntry* stub_entry =
@@ -1384,7 +1385,7 @@
     const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ Comment("StaticCall");
   __ LoadObject(S4, arguments_descriptor);
@@ -1404,7 +1405,7 @@
     Register reg,
     const Object& obj,
     bool needs_number_check,
-    intptr_t token_pos) {
+    TokenPosition token_pos) {
   __ Comment("EqualityRegConstCompare");
   ASSERT(!needs_number_check ||
          (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
@@ -1421,7 +1422,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1439,10 +1440,11 @@
 }
 
 
-Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                       Register right,
-                                                       bool needs_number_check,
-                                                       intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
+    Register left,
+    Register right,
+    bool needs_number_check,
+    TokenPosition token_pos) {
   __ Comment("EqualityRegRegCompare");
   if (needs_number_check) {
     __ addiu(SP, SP, Immediate(-2 * kWordSize));
@@ -1455,7 +1457,7 @@
       __ BranchLinkPatchable(
           *StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1575,7 +1577,7 @@
                                         Label* failed,
                                         Label* match_found,
                                         intptr_t deopt_id,
-                                        intptr_t token_index,
+                                        TokenPosition token_index,
                                         LocationSummary* locs) {
   ASSERT(is_optimizing());
   __ Comment("EmitTestAndCall");
diff --git a/runtime/vm/flow_graph_compiler_x64.cc b/runtime/vm/flow_graph_compiler_x64.cc
index 4662afb..68004fb 100644
--- a/runtime/vm/flow_graph_compiler_x64.cc
+++ b/runtime/vm/flow_graph_compiler_x64.cc
@@ -27,7 +27,7 @@
 DEFINE_FLAG(bool, unbox_mints, true, "Optimize 64-bit integer arithmetic.");
 DECLARE_FLAG(bool, enable_simd_inline);
 DECLARE_FLAG(bool, use_megamorphic_stub);
-
+DECLARE_FLAG(bool, precompilation);
 
 void MegamorphicSlowPath::EmitNativeCode(FlowGraphCompiler* compiler) {
   Assembler* assembler = compiler->assembler();
@@ -267,7 +267,7 @@
 // Clobbers R10.
 RawSubtypeTestCache*
 FlowGraphCompiler::GenerateInstantiatedTypeWithArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -356,7 +356,7 @@
 // Clobbers R10, R13.
 // Returns true if there is a fallthrough.
 bool FlowGraphCompiler::GenerateInstantiatedTypeNoArgumentsTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -426,7 +426,7 @@
 // arrays can grow too high, but they may be useful when optimizing
 // code (type-feedback).
 RawSubtypeTestCache* FlowGraphCompiler::GenerateSubtype1TestCacheLookup(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const Class& type_class,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -455,7 +455,7 @@
 // RAX: instance (preserved).
 // Clobbers RDI, RDX, R10.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateUninstantiatedTypeTest(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -539,7 +539,7 @@
 // may fall through to it. Otherwise, this inline code will jump to the label
 // is_instance or to the label is_not_instance.
 RawSubtypeTestCache* FlowGraphCompiler::GenerateInlineInstanceof(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const AbstractType& type,
     Label* is_instance_lbl,
     Label* is_not_instance_lbl) {
@@ -593,7 +593,7 @@
 // Clobbers RDX.
 // Returns:
 // - true or false in RAX.
-void FlowGraphCompiler::GenerateInstanceOf(intptr_t token_pos,
+void FlowGraphCompiler::GenerateInstanceOf(TokenPosition token_pos,
                                            intptr_t deopt_id,
                                            const AbstractType& type,
                                            bool negate_result,
@@ -673,12 +673,12 @@
 // - object in RAX for successful assignable check (or throws TypeError).
 // Performance notes: positive checks must be quick, negative checks can be slow
 // as they throw an exception.
-void FlowGraphCompiler::GenerateAssertAssignable(intptr_t token_pos,
+void FlowGraphCompiler::GenerateAssertAssignable(TokenPosition token_pos,
                                                  intptr_t deopt_id,
                                                  const AbstractType& dst_type,
                                                  const String& dst_name,
                                                  LocationSummary* locs) {
-  ASSERT(!Token::IsClassifying(token_pos));
+  ASSERT(!token_pos.IsClassifying());
   ASSERT(!dst_type.IsNull());
   ASSERT(dst_type.IsFinalized());
   // Assignable check is skipped in FlowGraphBuilder, not here.
@@ -1139,7 +1139,7 @@
   // Emit function patching code. This will be swapped with the first 13 bytes
   // at entry point.
 
-  if (is_optimizing() && Compiler::allow_recompilation()) {
+  if (is_optimizing() && !FLAG_precompilation) {
     // Leave enough space for patching in case of lazy deoptimization from
     // deferred code.
     __ nop(ShortCallPattern::pattern_length_in_bytes());
@@ -1149,7 +1149,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateCall(TokenPosition token_pos,
                                      const StubEntry& stub_entry,
                                      RawPcDescriptors::Kind kind,
                                      LocationSummary* locs) {
@@ -1160,7 +1160,7 @@
 
 
 void FlowGraphCompiler::GenerateDartCall(intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          const StubEntry& stub_entry,
                                          RawPcDescriptors::Kind kind,
                                          LocationSummary* locs) {
@@ -1180,7 +1180,7 @@
 }
 
 
-void FlowGraphCompiler::GenerateRuntimeCall(intptr_t token_pos,
+void FlowGraphCompiler::GenerateRuntimeCall(TokenPosition token_pos,
                                             intptr_t deopt_id,
                                             const RuntimeEntry& entry,
                                             intptr_t argument_count,
@@ -1206,7 +1206,7 @@
 void FlowGraphCompiler::EmitUnoptimizedStaticCall(
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     const ICData& ic_data) {
   const StubEntry* stub_entry =
@@ -1240,7 +1240,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   // Each ICData propagated from unoptimized to optimized code contains the
@@ -1264,7 +1264,7 @@
                                          const ICData& ic_data,
                                          intptr_t argument_count,
                                          intptr_t deopt_id,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          LocationSummary* locs) {
   ASSERT(Array::Handle(zone(), ic_data.arguments_descriptor()).Length() > 0);
   __ LoadUniqueObject(RBX, ic_data);
@@ -1281,7 +1281,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs,
     intptr_t try_index) {
   const String& name = String::Handle(zone(), ic_data.target_name());
@@ -1303,7 +1303,7 @@
 
   RecordSafepoint(locs);
   const intptr_t deopt_id_after = Thread::ToDeoptAfter(deopt_id);
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     // Megamorphic calls may occur in slow path stubs.
     // If valid use try_index argument.
     if (try_index == CatchClauseNode::kInvalidTryIndex) {
@@ -1333,7 +1333,7 @@
     const ICData& ic_data,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ Comment("SwitchableCall");
   __ movq(RDI, Address(RSP, (argument_count - 1) * kWordSize));
@@ -1374,7 +1374,7 @@
     const Array& arguments_descriptor,
     intptr_t argument_count,
     intptr_t deopt_id,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     LocationSummary* locs) {
   __ LoadObject(R10, arguments_descriptor);
   // Do not use the code from the function, but let the code be patched so that
@@ -1393,7 +1393,7 @@
     Register reg,
     const Object& obj,
     bool needs_number_check,
-    intptr_t token_pos) {
+    TokenPosition token_pos) {
   ASSERT(!needs_number_check ||
          (!obj.IsMint() && !obj.IsDouble() && !obj.IsBigint()));
 
@@ -1411,7 +1411,7 @@
     } else {
       __ CallPatchable(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1426,10 +1426,11 @@
 }
 
 
-Condition FlowGraphCompiler::EmitEqualityRegRegCompare(Register left,
-                                                       Register right,
-                                                       bool needs_number_check,
-                                                       intptr_t token_pos) {
+Condition FlowGraphCompiler::EmitEqualityRegRegCompare(
+    Register left,
+    Register right,
+    bool needs_number_check,
+    TokenPosition token_pos) {
   if (needs_number_check) {
     __ pushq(left);
     __ pushq(right);
@@ -1438,7 +1439,7 @@
     } else {
       __ CallPatchable(*StubCode::UnoptimizedIdenticalWithNumberCheck_entry());
     }
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       AddCurrentDescriptor(RawPcDescriptors::kRuntimeCall,
                            Thread::kNoDeoptId,
                            token_pos);
@@ -1494,7 +1495,7 @@
                                         Label* failed,
                                         Label* match_found,
                                         intptr_t deopt_id,
-                                        intptr_t token_index,
+                                        TokenPosition token_index,
                                         LocationSummary* locs) {
   ASSERT(is_optimizing());
 
diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc
index 1b39f97..d0d6b3e 100644
--- a/runtime/vm/flow_graph_inliner.cc
+++ b/runtime/vm/flow_graph_inliner.cc
@@ -61,6 +61,7 @@
 DECLARE_FLAG(bool, compiler_stats);
 DECLARE_FLAG(int, max_deoptimization_counter_threshold);
 DECLARE_FLAG(bool, polymorphic_with_deopt);
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, print_flow_graph);
 DECLARE_FLAG(bool, print_flow_graph_optimized);
 DECLARE_FLAG(bool, verify_compiler);
@@ -629,7 +630,7 @@
 
     // Function has no type feedback. With precompilation we don't rely on
     // type feedback.
-    if (!Compiler::always_optimize() &&
+    if (!FLAG_precompilation &&
         function.ic_data_array() == Object::null()) {
       TRACE_INLINING(THR_Print("     Bailout: not compiled yet\n"));
       PRINT_INLINING_TREE("Not compiled",
@@ -786,7 +787,7 @@
           FlowGraphOptimizer optimizer(callee_graph,
                                        inliner_->use_speculative_inlining_,
                                        inliner_->inlining_black_list_);
-          if (Compiler::always_optimize()) {
+          if (FLAG_precompilation) {
             optimizer.PopulateWithICData();
 
             optimizer.ApplyClassIds();
@@ -913,7 +914,7 @@
     // Propagate a compile-time error. Only in precompilation do we attempt to
     // inline functions that have never been compiled before; when JITing we
     // should only see compile-time errors in unoptimized compilation.
-    ASSERT(Compiler::always_optimize());
+    ASSERT(FLAG_precompilation);
     Thread::Current()->long_jump_base()->Jump(1, error);
     UNREACHABLE();
     return false;
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index ecc3350..848cdb0 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -254,7 +254,7 @@
     return true;
   }
 
-  if (Compiler::always_optimize() &&
+  if (FLAG_precompilation &&
       (isolate()->object_store()->unique_dynamic_targets() != Array::null())) {
     // Check if the target is unique.
     Function& target_function = Function::Handle(Z);
@@ -1128,7 +1128,7 @@
 Instruction* FlowGraphOptimizer::GetCheckClass(Definition* to_check,
                                                const ICData& unary_checks,
                                                intptr_t deopt_id,
-                                               intptr_t token_pos) {
+                                               TokenPosition token_pos) {
   if ((unary_checks.NumberOfUsedChecks() == 1) &&
       unary_checks.HasReceiverClassId(kSmiCid)) {
     return new(Z) CheckSmiInstr(new(Z) Value(to_check),
@@ -1282,7 +1282,7 @@
     const Function& target,
     Instruction* call,
     Definition* receiver,
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const ICData& value_check,
     TargetEntryInstr** entry,
     Definition** last) {
@@ -1453,7 +1453,7 @@
                                                    const Function& target,
                                                    Instruction* call,
                                                    Definition* receiver,
-                                                   intptr_t token_pos,
+                                                   TokenPosition token_pos,
                                                    const ICData& ic_data,
                                                    TargetEntryInstr** entry,
                                                    Definition** last) {
@@ -3173,7 +3173,7 @@
 bool FlowGraphOptimizer::TryInlineFloat32x4Constructor(
     StaticCallInstr* call,
     MethodRecognizer::Kind recognized_kind) {
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     // Cannot handle unboxed instructions.
     return false;
   }
@@ -3220,7 +3220,7 @@
 bool FlowGraphOptimizer::TryInlineFloat64x2Constructor(
     StaticCallInstr* call,
     MethodRecognizer::Kind recognized_kind) {
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     // Cannot handle unboxed instructions.
     return false;
   }
@@ -3259,7 +3259,7 @@
 bool FlowGraphOptimizer::TryInlineInt32x4Constructor(
     StaticCallInstr* call,
     MethodRecognizer::Kind recognized_kind) {
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     // Cannot handle unboxed instructions.
     return false;
   }
@@ -4363,7 +4363,7 @@
 // Tries to optimize instance call by replacing it with a faster instruction
 // (e.g, binary op, field load, ..).
 void FlowGraphOptimizer::VisitInstanceCall(InstanceCallInstr* instr) {
-  if (Compiler::always_optimize()) {
+  if (FLAG_precompilation) {
     InstanceCallNoopt(instr);
     return;
   }
@@ -4495,7 +4495,7 @@
       break;
   }
   if (unary_kind != MathUnaryInstr::kIllegal) {
-    if (Compiler::always_optimize()) {
+    if (FLAG_precompilation) {
       // TODO(srdjan): Adapt MathUnaryInstr to allow tagged inputs as well.
     } else {
       MathUnaryInstr* math_unary =
@@ -4564,7 +4564,7 @@
       }
     }
   } else if (recognized_kind == MethodRecognizer::kMathDoublePow) {
-    if (Compiler::always_optimize()) {
+    if (FLAG_precompilation) {
       // No UnboxDouble instructons allowed.
       return;
     }
@@ -5226,7 +5226,7 @@
 
 void LICM::OptimisticallySpecializeSmiPhis() {
   if (!flow_graph()->function().allows_hoisting_check_class() ||
-      Compiler::always_optimize()) {
+      FLAG_precompilation) {
     // Do not hoist any: Either deoptimized on a hoisted check,
     // or compiling precompiled code where we can't do optimistic
     // hoisting of checks.
@@ -5822,10 +5822,11 @@
     return offset & ~(ElementSizeMultiplier(size) - 1);
   }
 
-  typedef BitField<Kind, 0, 3> KindBits;
-  typedef BitField<Representation, KindBits::kNextBit, 11> RepresentationBits;
-  typedef BitField<
-      ElementSize, RepresentationBits::kNextBit, 3> ElementSizeBits;
+  class KindBits : public BitField<uword, Kind, 0, 3> {};
+  class RepresentationBits :
+      public BitField<uword, Representation, KindBits::kNextBit, 11> {};
+  class ElementSizeBits :
+      public BitField<uword, ElementSize, RepresentationBits::kNextBit, 3> {};
 
   uword flags_;
   Definition* instance_;
diff --git a/runtime/vm/flow_graph_optimizer.h b/runtime/vm/flow_graph_optimizer.h
index 9d500aa..afbb455 100644
--- a/runtime/vm/flow_graph_optimizer.h
+++ b/runtime/vm/flow_graph_optimizer.h
@@ -64,7 +64,7 @@
                                  const Function& target,
                                  Instruction* call,
                                  Definition* receiver,
-                                 intptr_t token_pos,
+                                 TokenPosition token_pos,
                                  const ICData& ic_data,
                                  TargetEntryInstr** entry,
                                  Definition** last);
@@ -97,7 +97,7 @@
                         const Function& target,
                         Instruction* call,
                         Definition* receiver,
-                        intptr_t token_pos,
+                        TokenPosition token_pos,
                         const ICData& value_check,
                         TargetEntryInstr** entry,
                         Definition** last);
@@ -201,7 +201,7 @@
   Instruction* GetCheckClass(Definition* to_check,
                              const ICData& unary_checks,
                              intptr_t deopt_id,
-                             intptr_t token_pos);
+                             TokenPosition token_pos);
 
   // Insert a Smi check if needed.
   void AddCheckSmi(Definition* to_check,
diff --git a/runtime/vm/flow_graph_range_analysis.cc b/runtime/vm/flow_graph_range_analysis.cc
index 16cf90c..2f44af3 100644
--- a/runtime/vm/flow_graph_range_analysis.cc
+++ b/runtime/vm/flow_graph_range_analysis.cc
@@ -5,7 +5,6 @@
 #include "vm/flow_graph_range_analysis.h"
 
 #include "vm/bit_vector.h"
-#include "vm/compiler.h"
 #include "vm/il_printer.h"
 
 namespace dart {
@@ -15,6 +14,7 @@
 DEFINE_FLAG(bool, trace_range_analysis, false, "Trace range analysis progress");
 DEFINE_FLAG(bool, trace_integer_ir_selection, false,
     "Print integer IR selection optimization pass.");
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, trace_constant_propagation);
 
 // Quick access to the locally defined isolate() and zone() methods.
@@ -1534,7 +1534,7 @@
     // optimistic hoisting of checks possible)
     const bool try_generalization =
         function.allows_bounds_check_generalization() &&
-        !Compiler::always_optimize();
+        !FLAG_precompilation;
 
     BoundsCheckGeneralizer generalizer(this, flow_graph_);
 
diff --git a/runtime/vm/gc_marker.cc b/runtime/vm/gc_marker.cc
index 1638b3d..e9f33c3 100644
--- a/runtime/vm/gc_marker.cc
+++ b/runtime/vm/gc_marker.cc
@@ -485,7 +485,7 @@
   if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
     (isolate->gc_prologue_callback())();
   }
-  isolate->thread_registry()->PrepareForGC();
+  isolate->PrepareForGC();
   // The store buffers will be rebuilt as part of marking, reset them now.
   isolate->store_buffer()->Reset();
 }
diff --git a/runtime/vm/gc_sweeper.cc b/runtime/vm/gc_sweeper.cc
index a192138..0dcf62f 100644
--- a/runtime/vm/gc_sweeper.cc
+++ b/runtime/vm/gc_sweeper.cc
@@ -9,8 +9,8 @@
 #include "vm/heap.h"
 #include "vm/lockers.h"
 #include "vm/pages.h"
+#include "vm/safepoint.h"
 #include "vm/thread_pool.h"
-#include "vm/thread_registry.h"
 
 namespace dart {
 
@@ -116,13 +116,14 @@
   virtual void Run() {
     bool result = Thread::EnterIsolateAsHelper(task_isolate_);
     ASSERT(result);
+    Thread* thread = Thread::Current();
     GCSweeper sweeper;
 
     HeapPage* page = first_;
     HeapPage* prev_page = NULL;
 
     while (page != NULL) {
-      task_isolate_->thread_registry()->CheckSafepoint();
+      thread->CheckForSafepoint();
       HeapPage* next_page = page->next();
       ASSERT(page->type() == HeapPage::kData);
       bool page_in_use = sweeper.SweepPage(page, freelist_, false);
diff --git a/runtime/vm/heap.cc b/runtime/vm/heap.cc
index 10586bd..8a18924 100644
--- a/runtime/vm/heap.cc
+++ b/runtime/vm/heap.cc
@@ -99,20 +99,20 @@
   if (addr != 0) {
     return addr;
   }
-  // If we are in the process of running a sweep wait for the sweeper to free
+  // If we are in the process of running a sweep, wait for the sweeper to free
   // memory.
+  Thread* thread = Thread::Current();
   {
     MonitorLocker ml(old_space_.tasks_lock());
     addr = old_space_.TryAllocate(size, type);
     while ((addr == 0) && (old_space_.tasks() > 0)) {
-      ml.Wait();
+      ml.WaitWithSafepointCheck(thread);
       addr = old_space_.TryAllocate(size, type);
     }
   }
   if (addr != 0) {
     return addr;
   }
-  Thread* thread = Thread::Current();
   if (thread->CanCollectGarbage()) {
     // All GC tasks finished without allocating successfully. Run a full GC.
     CollectAllGarbage();
@@ -125,7 +125,7 @@
       MonitorLocker ml(old_space_.tasks_lock());
       addr = old_space_.TryAllocate(size, type);
       while ((addr == 0) && (old_space_.tasks() > 0)) {
-        ml.Wait();
+        ml.WaitWithSafepointCheck(thread);
         addr = old_space_.TryAllocate(size, type);
       }
     }
@@ -142,7 +142,7 @@
     {
       MonitorLocker ml(old_space_.tasks_lock());
       while (old_space_.tasks() > 0) {
-        ml.Wait();
+        ml.WaitWithSafepointCheck(thread);
       }
     }
   }
@@ -314,13 +314,13 @@
 }
 
 
-bool Heap::BeginNewSpaceGC() {
+bool Heap::BeginNewSpaceGC(Thread* thread) {
   MonitorLocker ml(&gc_in_progress_monitor_);
   bool start_gc_on_thread = true;
   while (gc_new_space_in_progress_ ||
          gc_old_space_in_progress_) {
     start_gc_on_thread = !gc_new_space_in_progress_;
-    ml.Wait();
+    ml.WaitWithSafepointCheck(thread);
   }
   if (start_gc_on_thread) {
     gc_new_space_in_progress_ = true;
@@ -338,13 +338,13 @@
 }
 
 
-bool Heap::BeginOldSpaceGC() {
+bool Heap::BeginOldSpaceGC(Thread* thread) {
   MonitorLocker ml(&gc_in_progress_monitor_);
   bool start_gc_on_thread = true;
   while (gc_new_space_in_progress_ ||
          gc_old_space_in_progress_) {
     start_gc_on_thread = !gc_old_space_in_progress_;
-    ml.Wait();
+    ml.WaitWithSafepointCheck(thread);
   }
   if (start_gc_on_thread) {
     gc_old_space_in_progress_ = true;
@@ -375,7 +375,7 @@
 void Heap::CollectNewSpaceGarbage(Thread* thread,
                                   ApiCallbacks api_callbacks,
                                   GCReason reason) {
-  if (BeginNewSpaceGC()) {
+  if (BeginNewSpaceGC(thread)) {
     bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
     RecordBeforeGC(kNew, reason);
     VMTagScope tagScope(thread, VMTag::kGCNewSpaceTagId);
@@ -400,7 +400,7 @@
 void Heap::CollectOldSpaceGarbage(Thread* thread,
                                   ApiCallbacks api_callbacks,
                                   GCReason reason) {
-  if (BeginOldSpaceGC()) {
+  if (BeginOldSpaceGC(thread)) {
     bool invoke_api_callbacks = (api_callbacks == kInvokeApiCallbacks);
     RecordBeforeGC(kOld, reason);
     VMTagScope tagScope(thread, VMTag::kGCOldSpaceTagId);
diff --git a/runtime/vm/heap.h b/runtime/vm/heap.h
index 4a8ae93..bd685c5 100644
--- a/runtime/vm/heap.h
+++ b/runtime/vm/heap.h
@@ -323,9 +323,9 @@
   void UpdatePretenurePolicy();
 
   // Updates gc in progress flags.
-  bool BeginNewSpaceGC();
+  bool BeginNewSpaceGC(Thread* thread);
   void EndNewSpaceGC();
-  bool BeginOldSpaceGC();
+  bool BeginOldSpaceGC(Thread* thread);
   void EndOldSpaceGC();
 
   // If this heap is non-empty, updates start and end to the smallest range that
diff --git a/runtime/vm/heap_test.cc b/runtime/vm/heap_test.cc
index f52a81c..c76297d 100644
--- a/runtime/vm/heap_test.cc
+++ b/runtime/vm/heap_test.cc
@@ -26,6 +26,7 @@
   EXPECT_VALID(result);
   EXPECT(!Dart_IsNull(result));
   EXPECT(Dart_IsList(result));
+  TransitionNativeToVM transition(thread);
   Isolate* isolate = Isolate::Current();
   Heap* heap = isolate->heap();
   heap->CollectGarbage(Heap::kOld);
@@ -45,6 +46,7 @@
   EXPECT_VALID(result);
   EXPECT(!Dart_IsNull(result));
   EXPECT(Dart_IsList(result));
+  TransitionNativeToVM transition(thread);
   Isolate* isolate = Isolate::Current();
   Heap* heap = isolate->heap();
   heap->CollectGarbage(Heap::kOld);
@@ -64,6 +66,7 @@
   EXPECT_VALID(result);
   EXPECT(!Dart_IsNull(result));
   EXPECT(Dart_IsList(result));
+  TransitionNativeToVM transition(thread);
   Isolate* isolate = Isolate::Current();
   Heap* heap = isolate->heap();
   heap->CollectGarbage(Heap::kOld);
@@ -115,6 +118,7 @@
   Dart_Handle result = Dart_Invoke(h_lib, NewString("main"), 0, NULL);
   EXPECT_VALID(result);
   EXPECT(!Dart_IsNull(result));
+  TransitionNativeToVM transition(thread);
   Library& lib = Library::Handle();
   lib ^= Api::UnwrapHandle(h_lib);
   EXPECT(!lib.IsNull());
diff --git a/runtime/vm/il_printer.cc b/runtime/vm/il_printer.cc
index 97de0b1..12bcc09 100644
--- a/runtime/vm/il_printer.cc
+++ b/runtime/vm/il_printer.cc
@@ -145,7 +145,7 @@
 
 
 void FlowGraphPrinter::PrintTypeCheck(const ParsedFunction& parsed_function,
-                                      intptr_t token_pos,
+                                      TokenPosition token_pos,
                                       Value* value,
                                       const AbstractType& dst_type,
                                       const String& dst_name,
diff --git a/runtime/vm/il_printer.h b/runtime/vm/il_printer.h
index c1d036f..bc19c75 100644
--- a/runtime/vm/il_printer.h
+++ b/runtime/vm/il_printer.h
@@ -48,7 +48,7 @@
   void PrintInstruction(Instruction* instr);
   static void PrintOneInstruction(Instruction* instr, bool print_locations);
   static void PrintTypeCheck(const ParsedFunction& parsed_function,
-                             intptr_t token_pos,
+                             TokenPosition token_pos,
                              Value* value,
                              const AbstractType& dst_type,
                              const String& dst_name,
diff --git a/runtime/vm/intermediate_language.cc b/runtime/vm/intermediate_language.cc
index 12663f3..9aa7cd5 100644
--- a/runtime/vm/intermediate_language.cc
+++ b/runtime/vm/intermediate_language.cc
@@ -127,7 +127,7 @@
 CheckClassInstr::CheckClassInstr(Value* value,
                                  intptr_t deopt_id,
                                  const ICData& unary_checks,
-                                 intptr_t token_pos)
+                                 TokenPosition token_pos)
     : TemplateInstruction(deopt_id),
       unary_checks_(unary_checks),
       cids_(unary_checks.NumberOfChecks()),
@@ -420,7 +420,7 @@
 }
 
 
-ConstantInstr::ConstantInstr(const Object& value, intptr_t token_pos)
+ConstantInstr::ConstantInstr(const Object& value, TokenPosition token_pos)
     : value_(value),
       token_pos_(token_pos) {
   // Check that the value is not an incorrect Integer representation.
@@ -2734,7 +2734,7 @@
   if (!compiler->is_optimizing()) {
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Token::kNoSourcePos);
+                                   TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -2760,7 +2760,7 @@
     // code that matches backwards from the end of the pattern.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Token::kNoSourcePos);
+                                   TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -2961,7 +2961,7 @@
 }
 
 
-StrictCompareInstr::StrictCompareInstr(intptr_t token_pos,
+StrictCompareInstr::StrictCompareInstr(TokenPosition token_pos,
                                        Token::Kind kind,
                                        Value* left,
                                        Value* right,
@@ -3519,7 +3519,7 @@
     ZoneGrowableArray<Value*>* inputs,
     intptr_t deopt_id,
     MethodRecognizer::Kind recognized_kind,
-    intptr_t token_pos)
+    TokenPosition token_pos)
     : PureDefinition(deopt_id),
       inputs_(inputs),
       recognized_kind_(recognized_kind),
diff --git a/runtime/vm/intermediate_language.h b/runtime/vm/intermediate_language.h
index 60e25a9..f03f11e 100644
--- a/runtime/vm/intermediate_language.h
+++ b/runtime/vm/intermediate_language.h
@@ -13,6 +13,7 @@
 #include "vm/method_recognizer.h"
 #include "vm/object.h"
 #include "vm/parser.h"
+#include "vm/token_position.h"
 
 namespace dart {
 
@@ -627,7 +628,9 @@
   const ICData* GetICData(
       const ZoneGrowableArray<const ICData*>& ic_data_array) const;
 
-  virtual intptr_t token_pos() const { return Token::kNoSourcePos; }
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kNoSource;
+  }
 
   virtual intptr_t InputCount() const = 0;
   virtual Value* InputAt(intptr_t i) const = 0;
@@ -1053,8 +1056,8 @@
 
   virtual void PrintTo(BufferFormatter* f) const;
 
-  virtual intptr_t token_pos() const {
-    return ClassifyingTokenPositions::kParallelMove;
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kParallelMove;
   }
 
  private:
@@ -1082,6 +1085,8 @@
 
   intptr_t block_id() const { return block_id_; }
 
+  // NOTE: These are SSA positions and not token positions. These are used by
+  // the register allocator.
   void set_start_pos(intptr_t pos) { start_pos_ = pos; }
   intptr_t start_pos() const { return start_pos_; }
   void  set_end_pos(intptr_t pos) { end_pos_ = pos; }
@@ -1189,8 +1194,8 @@
     return this;
   }
 
-  virtual intptr_t token_pos() const {
-    return ClassifyingTokenPositions::kControlFlow;
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kControlFlow;
   }
 
   // Helper to mutate the graph during inlining. This block should be
@@ -2042,8 +2047,8 @@
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
-  virtual intptr_t token_pos() const {
-    return ClassifyingTokenPositions::kPushArgument;
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kPushArgument;
   }
 
  private:
@@ -2058,7 +2063,7 @@
 
 class ReturnInstr : public TemplateInstruction<1, NoThrow> {
  public:
-  ReturnInstr(intptr_t token_pos, Value* value)
+  ReturnInstr(TokenPosition token_pos, Value* value)
       : TemplateInstruction(Thread::Current()->GetNextDeoptId()),
         token_pos_(token_pos) {
     SetInputAt(0, value);
@@ -2066,7 +2071,7 @@
 
   DECLARE_INSTRUCTION(Return)
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   Value* value() const { return inputs_[0]; }
 
   virtual bool CanBecomeDeoptimizationTarget() const {
@@ -2080,7 +2085,7 @@
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(ReturnInstr);
 };
@@ -2088,7 +2093,7 @@
 
 class ThrowInstr : public TemplateInstruction<0, Throws> {
  public:
-  explicit ThrowInstr(intptr_t token_pos)
+  explicit ThrowInstr(TokenPosition token_pos)
       : TemplateInstruction(Thread::Current()->GetNextDeoptId()),
         token_pos_(token_pos) {
   }
@@ -2097,14 +2102,14 @@
 
   virtual intptr_t ArgumentCount() const { return 1; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   virtual bool CanDeoptimize() const { return true; }
 
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(ThrowInstr);
 };
@@ -2114,7 +2119,7 @@
  public:
   // 'catch_try_index' can be CatchClauseNode::kInvalidTryIndex if the
   // rethrow has been artifically generated by the parser.
-  ReThrowInstr(intptr_t token_pos, intptr_t catch_try_index)
+  ReThrowInstr(TokenPosition token_pos, intptr_t catch_try_index)
       : TemplateInstruction(Thread::Current()->GetNextDeoptId()),
         token_pos_(token_pos),
         catch_try_index_(catch_try_index) {
@@ -2124,7 +2129,7 @@
 
   virtual intptr_t ArgumentCount() const { return 2; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   intptr_t catch_try_index() const { return catch_try_index_; }
 
   virtual bool CanDeoptimize() const { return true; }
@@ -2132,7 +2137,7 @@
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const intptr_t catch_try_index_;
 
   DISALLOW_COPY_AND_ASSIGN(ReThrowInstr);
@@ -2220,8 +2225,8 @@
 
   virtual void PrintTo(BufferFormatter* f) const;
 
-  virtual intptr_t token_pos() const {
-    return ClassifyingTokenPositions::kControlFlow;
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kControlFlow;
   }
 
  private:
@@ -2297,7 +2302,7 @@
   Value* left() const { return inputs_[0]; }
   Value* right() const { return inputs_[1]; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   Token::Kind kind() const { return kind_; }
 
   virtual ComparisonInstr* CopyWithNewOperands(Value* left, Value* right) = 0;
@@ -2332,7 +2337,7 @@
   DEFINE_INSTRUCTION_TYPE_CHECK(Comparison)
 
  protected:
-  ComparisonInstr(intptr_t token_pos,
+  ComparisonInstr(TokenPosition token_pos,
                   Token::Kind kind,
                   Value* left,
                   Value* right,
@@ -2348,7 +2353,7 @@
   }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   Token::Kind kind_;
   intptr_t operation_cid_;  // Set by optimizer.
 
@@ -2380,7 +2385,7 @@
 
   Value* InputAt(intptr_t i) const { return comparison()->InputAt(i); }
 
-  virtual intptr_t token_pos() const { return comparison_->token_pos(); }
+  virtual TokenPosition token_pos() const { return comparison_->token_pos(); }
 
   virtual bool CanDeoptimize() const {
     // Branches need a deoptimization info in checked mode if they
@@ -2558,7 +2563,7 @@
 class ConstantInstr : public TemplateDefinition<0, NoThrow, Pure> {
  public:
   ConstantInstr(const Object& value,
-                intptr_t token_pos = ClassifyingTokenPositions::kConstant);
+                TokenPosition token_pos = TokenPosition::kConstant);
 
   DECLARE_INSTRUCTION(Constant)
   virtual CompileType ComputeType() const;
@@ -2575,11 +2580,11 @@
 
   virtual bool AttributesEqual(Instruction* other) const;
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
  private:
   const Object& value_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(ConstantInstr);
 };
@@ -2612,7 +2617,7 @@
 
 class AssertAssignableInstr : public TemplateDefinition<2, Throws, Pure> {
  public:
-  AssertAssignableInstr(intptr_t token_pos,
+  AssertAssignableInstr(TokenPosition token_pos,
                         Value* value,
                         Value* instantiator_type_arguments,
                         const AbstractType& dst_type,
@@ -2635,7 +2640,7 @@
   Value* value() const { return inputs_[0]; }
   Value* instantiator_type_arguments() const { return inputs_[1]; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   const AbstractType& dst_type() const { return dst_type_; }
   void set_dst_type(const AbstractType& dst_type) {
     dst_type_ = dst_type.raw();
@@ -2657,7 +2662,7 @@
   virtual bool AttributesEqual(Instruction* other) const;
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   AbstractType& dst_type_;
   const String& dst_name_;
 
@@ -2667,7 +2672,7 @@
 
 class AssertBooleanInstr : public TemplateDefinition<1, Throws, Pure> {
  public:
-  AssertBooleanInstr(intptr_t token_pos, Value* value)
+  AssertBooleanInstr(TokenPosition token_pos, Value* value)
       : TemplateDefinition(Thread::Current()->GetNextDeoptId()),
         token_pos_(token_pos) {
     SetInputAt(0, value);
@@ -2676,7 +2681,7 @@
   DECLARE_INSTRUCTION(AssertBoolean)
   virtual CompileType ComputeType() const;
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   Value* value() const { return inputs_[0]; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
@@ -2688,7 +2693,7 @@
   virtual bool AttributesEqual(Instruction* other) const { return true; }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr);
 };
@@ -2730,7 +2735,9 @@
   DECLARE_INSTRUCTION(ClosureCall)
 
   const Array& argument_names() const { return ast_node_.arguments()->names(); }
-  virtual intptr_t token_pos() const { return ast_node_.token_pos(); }
+  virtual TokenPosition token_pos() const {
+    return ast_node_.token_pos();
+  }
 
   virtual intptr_t ArgumentCount() const { return arguments_->length(); }
   virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
@@ -2756,7 +2763,7 @@
 
 class InstanceCallInstr : public TemplateDefinition<0, Throws> {
  public:
-  InstanceCallInstr(intptr_t token_pos,
+  InstanceCallInstr(TokenPosition token_pos,
                     const String& function_name,
                     Token::Kind token_kind,
                     ZoneGrowableArray<PushArgumentInstr*>* arguments,
@@ -2797,7 +2804,7 @@
   // ICData can be replaced by optimizer.
   void set_ic_data(const ICData* value) { ic_data_ = value; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   const String& function_name() const { return function_name_; }
   Token::Kind token_kind() const { return token_kind_; }
   virtual intptr_t ArgumentCount() const { return arguments_->length(); }
@@ -2825,7 +2832,7 @@
 
  private:
   const ICData* ic_data_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const String& function_name_;
   const Token::Kind token_kind_;  // Binary op, unary op, kGET or kILLEGAL.
   ZoneGrowableArray<PushArgumentInstr*>* const arguments_;
@@ -2851,7 +2858,9 @@
 
   InstanceCallInstr* instance_call() const { return instance_call_; }
   bool with_checks() const { return with_checks_; }
-  virtual intptr_t token_pos() const { return instance_call_->token_pos(); }
+  virtual TokenPosition token_pos() const {
+    return instance_call_->token_pos();
+  }
 
   virtual intptr_t ArgumentCount() const {
     return instance_call()->ArgumentCount();
@@ -2887,7 +2896,7 @@
 
 class StrictCompareInstr : public ComparisonInstr {
  public:
-  StrictCompareInstr(intptr_t token_pos,
+  StrictCompareInstr(TokenPosition token_pos,
                      Token::Kind kind,
                      Value* left,
                      Value* right,
@@ -2929,7 +2938,10 @@
 // comparison pattern.
 class TestSmiInstr : public ComparisonInstr {
  public:
-  TestSmiInstr(intptr_t token_pos, Token::Kind kind, Value* left, Value* right)
+  TestSmiInstr(TokenPosition token_pos,
+               Token::Kind kind,
+               Value* left,
+               Value* right)
       : ComparisonInstr(token_pos, kind, left, right) {
     ASSERT(kind == Token::kEQ || kind == Token::kNE);
   }
@@ -2963,7 +2975,7 @@
 // TestCidInstr needs only one argument
 class TestCidsInstr : public ComparisonInstr {
  public:
-  TestCidsInstr(intptr_t token_pos,
+  TestCidsInstr(TokenPosition token_pos,
                 Token::Kind kind,
                 Value* value,
                 const ZoneGrowableArray<intptr_t>& cid_results,
@@ -3012,7 +3024,7 @@
 
 class EqualityCompareInstr : public ComparisonInstr {
  public:
-  EqualityCompareInstr(intptr_t token_pos,
+  EqualityCompareInstr(TokenPosition token_pos,
                        Token::Kind kind,
                        Value* left,
                        Value* right,
@@ -3053,7 +3065,7 @@
 
 class RelationalOpInstr : public ComparisonInstr {
  public:
-  RelationalOpInstr(intptr_t token_pos,
+  RelationalOpInstr(TokenPosition token_pos,
                     Token::Kind kind,
                     Value* left,
                     Value* right,
@@ -3176,7 +3188,7 @@
 
 class StaticCallInstr : public TemplateDefinition<0, Throws> {
  public:
-  StaticCallInstr(intptr_t token_pos,
+  StaticCallInstr(TokenPosition token_pos,
                   const Function& function,
                   const Array& argument_names,
                   ZoneGrowableArray<PushArgumentInstr*>* arguments,
@@ -3208,7 +3220,7 @@
   // Accessors forwarded to the AST node.
   const Function& function() const { return function_; }
   const Array& argument_names() const { return argument_names_; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   virtual intptr_t ArgumentCount() const { return arguments_->length(); }
   virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
@@ -3252,7 +3264,7 @@
 
  private:
   const ICData* ic_data_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const Function& function_;
   const Array& argument_names_;
   ZoneGrowableArray<PushArgumentInstr*>* arguments_;
@@ -3271,7 +3283,7 @@
 class LoadLocalInstr : public TemplateDefinition<0, NoThrow> {
  public:
   LoadLocalInstr(const LocalVariable& local,
-                 intptr_t token_pos)
+                 TokenPosition token_pos)
       : local_(local), is_last_(false), token_pos_(token_pos) { }
 
   DECLARE_INSTRUCTION(LoadLocal)
@@ -3291,12 +3303,12 @@
   void mark_last() { is_last_ = true; }
   bool is_last() const { return is_last_; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
  private:
   const LocalVariable& local_;
   bool is_last_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr);
 };
@@ -3321,8 +3333,8 @@
     return EffectSet::None();
   }
 
-  virtual intptr_t token_pos() const {
-    return ClassifyingTokenPositions::kTempMove;
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kTempMove;
   }
 
  private:
@@ -3367,8 +3379,8 @@
     return false;
   }
 
-  virtual intptr_t token_pos() const {
-    return ClassifyingTokenPositions::kTempMove;
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kTempMove;
   }
 
  private:
@@ -3387,7 +3399,7 @@
  public:
   StoreLocalInstr(const LocalVariable& local,
                   Value* value,
-                  intptr_t token_pos)
+                  TokenPosition token_pos)
       : local_(local), is_dead_(false), is_last_(false), token_pos_(token_pos) {
     SetInputAt(0, value);
   }
@@ -3413,13 +3425,13 @@
     return EffectSet::None();
   }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
  private:
   const LocalVariable& local_;
   bool is_dead_;
   bool is_last_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr);
 };
@@ -3434,7 +3446,9 @@
 
   DECLARE_INSTRUCTION(NativeCall)
 
-  virtual intptr_t token_pos() const { return ast_node_.token_pos(); }
+  virtual TokenPosition token_pos() const {
+    return ast_node_.token_pos();
+  }
 
   const Function& function() const { return ast_node_.function(); }
 
@@ -3479,7 +3493,7 @@
 
 class DebugStepCheckInstr : public TemplateInstruction<0, NoThrow> {
  public:
-  DebugStepCheckInstr(intptr_t token_pos,
+  DebugStepCheckInstr(TokenPosition token_pos,
                       RawPcDescriptors::Kind stub_kind)
       : token_pos_(token_pos),
         stub_kind_(stub_kind) {
@@ -3487,13 +3501,13 @@
 
   DECLARE_INSTRUCTION(DebugStepCheck)
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   virtual bool CanDeoptimize() const { return false; }
   virtual EffectSet Effects() const { return EffectSet::All(); }
   virtual Instruction* Canonicalize(FlowGraph* flow_graph);
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const RawPcDescriptors::Kind stub_kind_;
 
   DISALLOW_COPY_AND_ASSIGN(DebugStepCheckInstr);
@@ -3512,7 +3526,7 @@
                           Value* instance,
                           Value* value,
                           StoreBarrierType emit_store_barrier,
-                          intptr_t token_pos)
+                          TokenPosition token_pos)
       : field_(field),
         offset_in_bytes_(field.Offset()),
         emit_store_barrier_(emit_store_barrier),
@@ -3527,7 +3541,7 @@
                           Value* instance,
                           Value* value,
                           StoreBarrierType emit_store_barrier,
-                          intptr_t token_pos)
+                          TokenPosition token_pos)
       : field_(Field::ZoneHandle()),
         offset_in_bytes_(offset_in_bytes),
         emit_store_barrier_(emit_store_barrier),
@@ -3560,7 +3574,7 @@
   bool is_object_reference_initialization() const {
     return is_object_reference_initialization_;
   }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   const Field& field() const { return field_; }
   intptr_t offset_in_bytes() const { return offset_in_bytes_; }
@@ -3603,7 +3617,7 @@
   const Field& field_;
   intptr_t offset_in_bytes_;
   const StoreBarrierType emit_store_barrier_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   // This may be the first store to an unboxed field.
   bool is_potential_unboxed_initialization_;
   // True if this store initializes an object reference field of an object that
@@ -3681,7 +3695,7 @@
 
 class LoadStaticFieldInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  LoadStaticFieldInstr(Value* field_value, intptr_t token_pos)
+  LoadStaticFieldInstr(Value* field_value, TokenPosition token_pos)
       : token_pos_(token_pos) {
     ASSERT(field_value->BindsToConstant());
     SetInputAt(0, field_value);
@@ -3703,10 +3717,10 @@
   virtual EffectSet Dependencies() const;
   virtual bool AttributesEqual(Instruction* other) const;
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr);
 };
@@ -3716,7 +3730,7 @@
  public:
   StoreStaticFieldInstr(const Field& field,
                         Value* value,
-                        intptr_t token_pos)
+                        TokenPosition token_pos)
       : field_(field),
         token_pos_(token_pos) {
     ASSERT(field.IsZoneHandle());
@@ -3741,7 +3755,7 @@
   // are marked as having no side-effects.
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
  private:
   bool CanValueBeSmi() const {
@@ -3752,7 +3766,7 @@
   }
 
   const Field& field_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreStaticFieldInstr);
 };
@@ -3765,7 +3779,7 @@
                    intptr_t index_scale,
                    intptr_t class_id,
                    intptr_t deopt_id,
-                   intptr_t token_pos)
+                   TokenPosition token_pos)
       : TemplateDefinition(deopt_id),
         index_scale_(index_scale),
         class_id_(class_id),
@@ -3774,7 +3788,7 @@
     SetInputAt(1, index);
   }
 
-  intptr_t token_pos() const { return token_pos_; }
+  TokenPosition token_pos() const { return token_pos_; }
 
   DECLARE_INSTRUCTION(LoadIndexed)
   virtual CompileType ComputeType() const;
@@ -3807,7 +3821,7 @@
  private:
   const intptr_t index_scale_;
   const intptr_t class_id_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
 };
@@ -3826,7 +3840,7 @@
                      Value* index,
                      intptr_t element_count,
                      intptr_t class_id,
-                     intptr_t token_pos)
+                     TokenPosition token_pos)
       : class_id_(class_id),
         token_pos_(token_pos),
         element_count_(element_count),
@@ -3837,7 +3851,7 @@
     SetInputAt(1, index);
   }
 
-  intptr_t token_pos() const { return token_pos_; }
+  TokenPosition token_pos() const { return token_pos_; }
 
   DECLARE_INSTRUCTION(LoadCodeUnits)
   virtual CompileType ComputeType() const;
@@ -3875,7 +3889,7 @@
 
  private:
   const intptr_t class_id_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const intptr_t element_count_;
   Representation representation_;
 
@@ -3938,7 +3952,7 @@
 
 class StringInterpolateInstr : public TemplateDefinition<1, Throws> {
  public:
-  StringInterpolateInstr(Value* value, intptr_t token_pos)
+  StringInterpolateInstr(Value* value, TokenPosition token_pos)
       : TemplateDefinition(Thread::Current()->GetNextDeoptId()),
         token_pos_(token_pos),
         function_(Function::ZoneHandle()) {
@@ -3946,7 +3960,7 @@
   }
 
   Value* value() const { return inputs_[0]; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   virtual CompileType ComputeType() const;
   // Issues a static call to Dart code which calls toString on objects.
@@ -3960,7 +3974,7 @@
   DECLARE_INSTRUCTION(StringInterpolate)
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   Function& function_;
 
   DISALLOW_COPY_AND_ASSIGN(StringInterpolateInstr);
@@ -3976,7 +3990,7 @@
                     intptr_t index_scale,
                     intptr_t class_id,
                     intptr_t deopt_id,
-                    intptr_t token_pos)
+                    TokenPosition token_pos)
       : TemplateDefinition(deopt_id),
         emit_store_barrier_(emit_store_barrier),
         index_scale_(index_scale),
@@ -4027,7 +4041,7 @@
   const StoreBarrierType emit_store_barrier_;
   const intptr_t index_scale_;
   const intptr_t class_id_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr);
 };
@@ -4058,7 +4072,7 @@
 
 class InstanceOfInstr : public TemplateDefinition<2, Throws> {
  public:
-  InstanceOfInstr(intptr_t token_pos,
+  InstanceOfInstr(TokenPosition token_pos,
                   Value* value,
                   Value* instantiator_type_arguments,
                   const AbstractType& type,
@@ -4081,7 +4095,7 @@
 
   bool negate_result() const { return negate_result_; }
   const AbstractType& type() const { return type_; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
@@ -4090,7 +4104,7 @@
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   Value* value_;
   Value* type_arguments_;
   const AbstractType& type_;
@@ -4102,7 +4116,7 @@
 
 class AllocateObjectInstr : public TemplateDefinition<0, NoThrow> {
  public:
-  AllocateObjectInstr(intptr_t token_pos,
+  AllocateObjectInstr(TokenPosition token_pos,
                       const Class& cls,
                       ZoneGrowableArray<PushArgumentInstr*>* arguments)
       : token_pos_(token_pos),
@@ -4123,7 +4137,7 @@
   }
 
   const Class& cls() const { return cls_; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   const Function& closure_function() const { return closure_function_; }
   void set_closure_function(const Function& function) {
@@ -4140,7 +4154,7 @@
   virtual void SetIdentity(AliasIdentity identity) { identity_ = identity; }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const Class& cls_;
   ZoneGrowableArray<PushArgumentInstr*>* const arguments_;
   AliasIdentity identity_;
@@ -4153,7 +4167,7 @@
 class AllocateUninitializedContextInstr
     : public TemplateDefinition<0, NoThrow> {
  public:
-  AllocateUninitializedContextInstr(intptr_t token_pos,
+  AllocateUninitializedContextInstr(TokenPosition token_pos,
                                     intptr_t num_context_variables)
       : token_pos_(token_pos),
         num_context_variables_(num_context_variables),
@@ -4162,7 +4176,7 @@
   DECLARE_INSTRUCTION(AllocateUninitializedContext)
   virtual CompileType ComputeType() const;
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   intptr_t num_context_variables() const { return num_context_variables_; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
@@ -4175,7 +4189,7 @@
   virtual void SetIdentity(AliasIdentity identity) { identity_ = identity; }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const intptr_t num_context_variables_;
   AliasIdentity identity_;
 
@@ -4299,7 +4313,7 @@
 
 class CreateArrayInstr : public TemplateDefinition<2, Throws> {
  public:
-  CreateArrayInstr(intptr_t token_pos,
+  CreateArrayInstr(TokenPosition token_pos,
                    Value* element_type,
                    Value* num_elements)
       : TemplateDefinition(Thread::Current()->GetNextDeoptId()),
@@ -4317,7 +4331,7 @@
   DECLARE_INSTRUCTION(CreateArray)
   virtual CompileType ComputeType() const;
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   Value* element_type() const { return inputs_[kElementTypePos]; }
   Value* num_elements() const { return inputs_[kLengthPos]; }
 
@@ -4331,7 +4345,7 @@
   virtual void SetIdentity(AliasIdentity identity) { identity_ = identity; }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   AliasIdentity identity_;
 
   DISALLOW_COPY_AND_ASSIGN(CreateArrayInstr);
@@ -4409,7 +4423,7 @@
   LoadFieldInstr(Value* instance,
                  intptr_t offset_in_bytes,
                  const AbstractType& type,
-                 intptr_t token_pos)
+                 TokenPosition token_pos)
       : offset_in_bytes_(offset_in_bytes),
         type_(type),
         result_cid_(kDynamicCid),
@@ -4426,7 +4440,7 @@
   LoadFieldInstr(Value* instance,
                  const Field* field,
                  const AbstractType& type,
-                 intptr_t token_pos)
+                 TokenPosition token_pos)
       : offset_in_bytes_(field->Offset()),
         type_(type),
         result_cid_(kDynamicCid),
@@ -4447,7 +4461,7 @@
   const AbstractType& type() const { return type_; }
   void set_result_cid(intptr_t value) { result_cid_ = value; }
   intptr_t result_cid() const { return result_cid_; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   const Field* field() const { return field_; }
 
@@ -4495,7 +4509,7 @@
 
   MethodRecognizer::Kind recognized_kind_;
   const Field* field_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(LoadFieldInstr);
 };
@@ -4503,7 +4517,7 @@
 
 class InstantiateTypeInstr : public TemplateDefinition<1, Throws> {
  public:
-  InstantiateTypeInstr(intptr_t token_pos,
+  InstantiateTypeInstr(TokenPosition token_pos,
                        const AbstractType& type,
                        const Class& instantiator_class,
                        Value* instantiator)
@@ -4521,7 +4535,7 @@
   const AbstractType& type() const { return type_;
   }
   const Class& instantiator_class() const { return instantiator_class_; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
@@ -4530,7 +4544,7 @@
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const AbstractType& type_;
   const Class& instantiator_class_;
 
@@ -4540,7 +4554,7 @@
 
 class InstantiateTypeArgumentsInstr : public TemplateDefinition<1, Throws> {
  public:
-  InstantiateTypeArgumentsInstr(intptr_t token_pos,
+  InstantiateTypeArgumentsInstr(TokenPosition token_pos,
                                 const TypeArguments& type_arguments,
                                 const Class& instantiator_class,
                                 Value* instantiator)
@@ -4559,7 +4573,7 @@
     return type_arguments_;
   }
   const Class& instantiator_class() const { return instantiator_class_; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
@@ -4570,7 +4584,7 @@
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const TypeArguments& type_arguments_;
   const Class& instantiator_class_;
 
@@ -4580,7 +4594,7 @@
 
 class AllocateContextInstr : public TemplateDefinition<0, NoThrow> {
  public:
-  AllocateContextInstr(intptr_t token_pos,
+  AllocateContextInstr(TokenPosition token_pos,
                        intptr_t num_context_variables)
       : token_pos_(token_pos),
         num_context_variables_(num_context_variables) { }
@@ -4588,7 +4602,7 @@
   DECLARE_INSTRUCTION(AllocateContext)
   virtual CompileType ComputeType() const;
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   intptr_t num_context_variables() const { return num_context_variables_; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
@@ -4598,7 +4612,7 @@
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const intptr_t num_context_variables_;
 
   DISALLOW_COPY_AND_ASSIGN(AllocateContextInstr);
@@ -4613,7 +4627,9 @@
     SetInputAt(0, input);
   }
 
-  virtual intptr_t token_pos() const { return field_.token_pos(); }
+  virtual TokenPosition token_pos() const {
+    return field_.token_pos();
+  }
   const Field& field() const { return field_; }
 
   DECLARE_INSTRUCTION(InitStaticField)
@@ -4631,13 +4647,13 @@
 
 class CloneContextInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  CloneContextInstr(intptr_t token_pos, Value* context_value)
+  CloneContextInstr(TokenPosition token_pos, Value* context_value)
       : TemplateDefinition(Thread::Current()->GetNextDeoptId()),
         token_pos_(token_pos) {
     SetInputAt(0, context_value);
   }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   Value* context_value() const { return inputs_[0]; }
 
   DECLARE_INSTRUCTION(CloneContext)
@@ -4648,7 +4664,7 @@
   virtual EffectSet Effects() const { return EffectSet::None(); }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(CloneContextInstr);
 };
@@ -4768,8 +4784,8 @@
 
   Definition* Canonicalize(FlowGraph* flow_graph);
 
-  virtual intptr_t token_pos() const {
-    return ClassifyingTokenPositions::kBox;
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kBox;
   }
 
  protected:
@@ -4894,8 +4910,8 @@
     return GetDeoptId();
   }
 
-  virtual intptr_t token_pos() const {
-    return ClassifyingTokenPositions::kBox;
+  virtual TokenPosition token_pos() const {
+    return TokenPosition::kBox;
   }
 
  protected:
@@ -5214,7 +5230,7 @@
                       Value* left,
                       Value* right,
                       intptr_t deopt_id,
-                      intptr_t token_pos)
+                      TokenPosition token_pos)
       : TemplateDefinition(deopt_id),
         op_kind_(op_kind),
         token_pos_(token_pos) {
@@ -5227,7 +5243,7 @@
 
   Token::Kind op_kind() const { return op_kind_; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
@@ -5259,7 +5275,7 @@
 
  private:
   const Token::Kind op_kind_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(BinaryDoubleOpInstr);
 };
@@ -7165,13 +7181,13 @@
 
 class CheckStackOverflowInstr : public TemplateInstruction<0, NoThrow> {
  public:
-  CheckStackOverflowInstr(intptr_t token_pos, intptr_t loop_depth)
+  CheckStackOverflowInstr(TokenPosition token_pos, intptr_t loop_depth)
       : TemplateInstruction(Thread::Current()->GetNextDeoptId()),
         token_pos_(token_pos),
         loop_depth_(loop_depth) {
   }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
   bool in_loop() const { return loop_depth_ > 0; }
   intptr_t loop_depth() const { return loop_depth_; }
 
@@ -7184,7 +7200,7 @@
   virtual void PrintOperandsTo(BufferFormatter* f) const;
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const intptr_t loop_depth_;
 
   DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr);
@@ -7194,13 +7210,13 @@
 // TODO(vegorov): remove this instruction in favor of Int32ToDouble.
 class SmiToDoubleInstr : public TemplateDefinition<1, NoThrow, Pure> {
  public:
-  SmiToDoubleInstr(Value* value, intptr_t token_pos)
+  SmiToDoubleInstr(Value* value, TokenPosition token_pos)
       : token_pos_(token_pos) {
     SetInputAt(0, value);
   }
 
   Value* value() const { return inputs_[0]; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   DECLARE_INSTRUCTION(SmiToDouble)
   virtual CompileType ComputeType() const;
@@ -7214,7 +7230,7 @@
   virtual bool AttributesEqual(Instruction* other) const { return true; }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr);
 };
@@ -7461,7 +7477,7 @@
   InvokeMathCFunctionInstr(ZoneGrowableArray<Value*>* inputs,
                            intptr_t deopt_id,
                            MethodRecognizer::Kind recognized_kind,
-                           intptr_t token_pos);
+                           TokenPosition token_pos);
 
   static intptr_t ArgumentCountFor(MethodRecognizer::Kind recognized_kind_);
 
@@ -7469,7 +7485,7 @@
 
   MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   DECLARE_INSTRUCTION(InvokeMathCFunction)
   virtual CompileType ComputeType() const;
@@ -7514,7 +7530,7 @@
 
   ZoneGrowableArray<Value*>* inputs_;
   const MethodRecognizer::Kind recognized_kind_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(InvokeMathCFunctionInstr);
 };
@@ -7675,13 +7691,13 @@
   CheckClassInstr(Value* value,
                   intptr_t deopt_id,
                   const ICData& unary_checks,
-                  intptr_t token_pos);
+                  TokenPosition token_pos);
 
   DECLARE_INSTRUCTION(CheckClass)
 
   virtual bool CanDeoptimize() const { return true; }
 
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   Value* value() const { return inputs_[0]; }
 
@@ -7717,7 +7733,7 @@
   const ICData& unary_checks_;
   GrowableArray<intptr_t> cids_;  // Sorted, lowest first.
   bool licm_hoisted_;
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
 
   DISALLOW_COPY_AND_ASSIGN(CheckClassInstr);
 };
@@ -7725,7 +7741,7 @@
 
 class CheckSmiInstr : public TemplateInstruction<1, NoThrow, Pure> {
  public:
-  CheckSmiInstr(Value* value, intptr_t deopt_id, intptr_t token_pos)
+  CheckSmiInstr(Value* value, intptr_t deopt_id, TokenPosition token_pos)
       : TemplateInstruction(deopt_id),
         token_pos_(token_pos),
         licm_hoisted_(false) {
@@ -7733,7 +7749,7 @@
   }
 
   Value* value() const { return inputs_[0]; }
-  virtual intptr_t token_pos() const { return token_pos_; }
+  virtual TokenPosition token_pos() const { return token_pos_; }
 
   DECLARE_INSTRUCTION(CheckSmi)
 
@@ -7746,7 +7762,7 @@
   void set_licm_hoisted(bool value) { licm_hoisted_ = value; }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   bool licm_hoisted_;
 
   DISALLOW_COPY_AND_ASSIGN(CheckSmiInstr);
diff --git a/runtime/vm/intermediate_language_arm.cc b/runtime/vm/intermediate_language_arm.cc
index c585771..2be4d9a 100644
--- a/runtime/vm/intermediate_language_arm.cc
+++ b/runtime/vm/intermediate_language_arm.cc
@@ -8,7 +8,6 @@
 #include "vm/intermediate_language.h"
 
 #include "vm/cpu.h"
-#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -28,6 +27,7 @@
 DECLARE_FLAG(bool, allow_absolute_addresses);
 DECLARE_FLAG(bool, emit_edge_counters);
 DECLARE_FLAG(int, optimization_counter_threshold);
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, use_osr);
 
 // Generic summary for call instructions that have all arguments pushed
@@ -369,7 +369,7 @@
 
 
 static void EmitAssertBoolean(Register reg,
-                              intptr_t token_pos,
+                              TokenPosition token_pos,
                               intptr_t deopt_id,
                               LocationSummary* locs,
                               FlowGraphCompiler* compiler) {
@@ -942,15 +942,13 @@
   // into the runtime system.
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
-  const bool is_leaf_call =
-      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
     entry = NativeEntry::LinkNativeCallEntry();
   } else {
     entry = reinterpret_cast<uword>(native_c_function());
-    if (is_bootstrap_native() || is_leaf_call) {
+    if (is_bootstrap_native()) {
       stub_entry = StubCode::CallBootstrapCFunction_entry();
 #if defined(USING_SIMULATOR)
       entry = Simulator::RedirectExternalReference(
@@ -961,12 +959,6 @@
       // stub generates the redirection address when running under the simulator
       // and hence we do not change 'entry' here.
       stub_entry = StubCode::CallNativeCFunction_entry();
-#if defined(USING_SIMULATOR)
-      if (!function().IsNativeAutoSetupScope()) {
-        entry = Simulator::RedirectExternalReference(
-            entry, Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments);
-      }
-#endif
     }
   }
   __ LoadImmediate(R1, argc_tag);
@@ -1834,7 +1826,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -2377,7 +2369,7 @@
   ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
 
   if (compiler->is_optimizing() &&
-      !Compiler::always_optimize() &&
+      !FLAG_precompilation &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
@@ -2905,7 +2897,7 @@
       // In unoptimized code, record loop stack checks as possible OSR entries.
       compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
                                      instruction_->deopt_id(),
-                                     0);  // No token position.
+                                     TokenPosition::kNoSource);
     }
     compiler->pending_deoptimization_env_ = NULL;
     compiler->RestoreLiveRegisters(instruction_->locs());
@@ -6651,7 +6643,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Token::kNoSourcePos);
+                                   TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -6854,7 +6846,7 @@
   const Register result = locs()->out(0).reg();
   __ PushObject(Object::null_object());
   __ Push(typed_data);
-  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(TokenPosition::kNoSource,
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intermediate_language_arm64.cc b/runtime/vm/intermediate_language_arm64.cc
index 18d82cd..4b8b565 100644
--- a/runtime/vm/intermediate_language_arm64.cc
+++ b/runtime/vm/intermediate_language_arm64.cc
@@ -7,7 +7,6 @@
 
 #include "vm/intermediate_language.h"
 
-#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -27,6 +26,7 @@
 DECLARE_FLAG(bool, allow_absolute_addresses);
 DECLARE_FLAG(bool, emit_edge_counters);
 DECLARE_FLAG(int, optimization_counter_threshold);
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, use_osr);
 
 // Generic summary for call instructions that have all arguments pushed
@@ -357,7 +357,7 @@
 
 
 static void EmitAssertBoolean(Register reg,
-                              intptr_t token_pos,
+                              TokenPosition token_pos,
                               intptr_t deopt_id,
                               LocationSummary* locs,
                               FlowGraphCompiler* compiler) {
@@ -796,15 +796,13 @@
   // into the runtime system.
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
-  const bool is_leaf_call =
-      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
     entry = NativeEntry::LinkNativeCallEntry();
   } else {
     entry = reinterpret_cast<uword>(native_c_function());
-    if (is_bootstrap_native() || is_leaf_call) {
+    if (is_bootstrap_native()) {
       stub_entry = StubCode::CallBootstrapCFunction_entry();
 #if defined(USING_SIMULATOR)
       entry = Simulator::RedirectExternalReference(
@@ -815,12 +813,6 @@
       // stub generates the redirection address when running under the simulator
       // and hence we do not change 'entry' here.
       stub_entry = StubCode::CallNativeCFunction_entry();
-#if defined(USING_SIMULATOR)
-      if (!function().IsNativeAutoSetupScope()) {
-        entry = Simulator::RedirectExternalReference(
-            entry, Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments);
-      }
-#endif
     }
   }
   __ LoadImmediate(R1, argc_tag);
@@ -1686,7 +1678,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -2100,7 +2092,7 @@
   ASSERT(locs()->in(kLengthPos).reg() == kLengthReg);
 
   if (compiler->is_optimizing() &&
-      !Compiler::always_optimize() &&
+      !FLAG_precompilation &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
@@ -2615,7 +2607,7 @@
       // In unoptimized code, record loop stack checks as possible OSR entries.
       compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
                                      instruction_->deopt_id(),
-                                     0);  // No token position.
+                                     TokenPosition::kNoSource);
     }
     compiler->pending_deoptimization_env_ = NULL;
     compiler->RestoreLiveRegisters(instruction_->locs());
@@ -5414,7 +5406,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Token::kNoSourcePos);
+                                   TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -5616,7 +5608,7 @@
   const Register result = locs()->out(0).reg();
   __ PushObject(Object::null_object());
   __ Push(typed_data);
-  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(TokenPosition::kNoSource,
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intermediate_language_ia32.cc b/runtime/vm/intermediate_language_ia32.cc
index 3ceb83c..7487d86 100644
--- a/runtime/vm/intermediate_language_ia32.cc
+++ b/runtime/vm/intermediate_language_ia32.cc
@@ -242,7 +242,7 @@
 
 
 static void EmitAssertBoolean(Register reg,
-                              intptr_t token_pos,
+                              TokenPosition token_pos,
                               intptr_t deopt_id,
                               LocationSummary* locs,
                               FlowGraphCompiler* compiler) {
@@ -820,8 +820,6 @@
   SetupNative();
   Register result = locs()->out(0).reg();
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
-  const bool is_leaf_call =
-      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
 
   // Push the result place holder initialized to NULL.
   __ PushObject(Object::null_object());
@@ -839,7 +837,7 @@
     stub_entry = StubCode::CallBootstrapCFunction_entry();
     __ movl(ECX, Immediate(NativeEntry::LinkNativeCallEntry()));
   } else {
-    stub_entry = (is_bootstrap_native() || is_leaf_call) ?
+    stub_entry = (is_bootstrap_native()) ?
         StubCode::CallBootstrapCFunction_entry() :
         StubCode::CallNativeCFunction_entry();
     const ExternalLabel label(reinterpret_cast<uword>(native_c_function()));
@@ -1675,7 +1673,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(TokenPosition::kNoSource,
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -2625,7 +2623,7 @@
       // In unoptimized code, record loop stack checks as possible OSR entries.
       compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
                                      instruction_->deopt_id(),
-                                     0);  // No token position.
+                                     TokenPosition::kNoSource);
     }
     compiler->pending_deoptimization_env_ = NULL;
     compiler->RestoreLiveRegisters(instruction_->locs());
@@ -6551,7 +6549,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Token::kNoSourcePos);
+                                   TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -6862,7 +6860,7 @@
   const Register result = locs()->out(0).reg();
   __ PushObject(Object::null_object());
   __ pushl(typed_data);
-  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(TokenPosition::kNoSource,
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intermediate_language_mips.cc b/runtime/vm/intermediate_language_mips.cc
index ebdd48b..79736b9 100644
--- a/runtime/vm/intermediate_language_mips.cc
+++ b/runtime/vm/intermediate_language_mips.cc
@@ -7,7 +7,6 @@
 
 #include "vm/intermediate_language.h"
 
-#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -27,6 +26,7 @@
 DECLARE_FLAG(bool, allow_absolute_addresses);
 DECLARE_FLAG(bool, emit_edge_counters);
 DECLARE_FLAG(int, optimization_counter_threshold);
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, use_osr);
 
 // Generic summary for call instructions that have all arguments pushed
@@ -418,7 +418,7 @@
 
 
 static void EmitAssertBoolean(Register reg,
-                              intptr_t token_pos,
+                              TokenPosition token_pos,
                               intptr_t deopt_id,
                               LocationSummary* locs,
                               FlowGraphCompiler* compiler) {
@@ -993,15 +993,13 @@
   // into the runtime system.
   uword entry;
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
-  const bool is_leaf_call =
-      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
   const StubEntry* stub_entry;
   if (link_lazily()) {
     stub_entry = StubCode::CallBootstrapCFunction_entry();
     entry = NativeEntry::LinkNativeCallEntry();
   } else {
     entry = reinterpret_cast<uword>(native_c_function());
-    if (is_bootstrap_native() || is_leaf_call) {
+    if (is_bootstrap_native()) {
       stub_entry = StubCode::CallBootstrapCFunction_entry();
 #if defined(USING_SIMULATOR)
       entry = Simulator::RedirectExternalReference(
@@ -1012,12 +1010,6 @@
       // stub generates the redirection address when running under the simulator
       // and hence we do not change 'entry' here.
       stub_entry = StubCode::CallNativeCFunction_entry();
-#if defined(USING_SIMULATOR)
-      if (!function().IsNativeAutoSetupScope()) {
-        entry = Simulator::RedirectExternalReference(
-            entry, Simulator::kBootstrapNativeCall, NativeEntry::kNumArguments);
-      }
-#endif
     }
   }
   __ LoadImmediate(A1, argc_tag);
@@ -1859,7 +1851,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -2231,7 +2223,7 @@
 
   Label slow_path, done;
   if (compiler->is_optimizing() &&
-      !Compiler::always_optimize() &&
+      !FLAG_precompilation &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
@@ -2733,7 +2725,7 @@
       // In unoptimized code, record loop stack checks as possible OSR entries.
       compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
                                      instruction_->deopt_id(),
-                                     0);  // No token position.
+                                     TokenPosition::kNoSource);
     }
     compiler->pending_deoptimization_env_ = NULL;
     compiler->RestoreLiveRegisters(instruction_->locs());
@@ -5389,7 +5381,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Token::kNoSourcePos);
+                                   TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -5591,7 +5583,7 @@
   __ LoadObject(TMP, Object::null_object());
   __ sw(TMP, Address(SP, 1 * kWordSize));
   __ sw(typed_data, Address(SP, 0 * kWordSize));
-  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(TokenPosition::kNoSource,
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intermediate_language_x64.cc b/runtime/vm/intermediate_language_x64.cc
index 8c164fc..53ca97b 100644
--- a/runtime/vm/intermediate_language_x64.cc
+++ b/runtime/vm/intermediate_language_x64.cc
@@ -7,7 +7,6 @@
 
 #include "vm/intermediate_language.h"
 
-#include "vm/compiler.h"
 #include "vm/dart_entry.h"
 #include "vm/flow_graph.h"
 #include "vm/flow_graph_compiler.h"
@@ -28,6 +27,7 @@
 DECLARE_FLAG(int, optimization_counter_threshold);
 DECLARE_FLAG(bool, throw_on_javascript_int_overflow);
 DECLARE_FLAG(bool, use_osr);
+DECLARE_FLAG(bool, precompilation);
 
 // Generic summary for call instructions that have all arguments pushed
 // on the stack and return the result in a fixed register RAX.
@@ -329,7 +329,7 @@
 
 
 static void EmitAssertBoolean(Register reg,
-                              intptr_t token_pos,
+                              TokenPosition token_pos,
                               intptr_t deopt_id,
                               LocationSummary* locs,
                               FlowGraphCompiler* compiler) {
@@ -775,8 +775,6 @@
   SetupNative();
   Register result = locs()->out(0).reg();
   const intptr_t argc_tag = NativeArguments::ComputeArgcTag(function());
-  const bool is_leaf_call =
-      (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
 
   // Push the result place holder initialized to NULL.
   __ PushObject(Object::null_object());
@@ -794,9 +792,9 @@
     ExternalLabel label(NativeEntry::LinkNativeCallEntry());
     __ LoadNativeEntry(RBX, &label, kPatchable);
   } else {
-    stub_entry = (is_bootstrap_native() || is_leaf_call)
-        ? StubCode::CallBootstrapCFunction_entry()
-        : StubCode::CallNativeCFunction_entry();
+    stub_entry = (is_bootstrap_native()) ?
+        StubCode::CallBootstrapCFunction_entry() :
+        StubCode::CallNativeCFunction_entry();
     const ExternalLabel label(reinterpret_cast<uword>(native_c_function()));
     __ LoadNativeEntry(RBX, &label, kNotPatchable);
   }
@@ -1685,7 +1683,7 @@
     locs->live_registers()->Remove(Location::RegisterLocation(result_));
 
     compiler->SaveLiveRegisters(locs);
-    compiler->GenerateCall(Token::kNoSourcePos,  // No token position.
+    compiler->GenerateCall(TokenPosition::kNoSource,  // No token position.
                            stub_entry,
                            RawPcDescriptors::kOther,
                            locs);
@@ -2115,7 +2113,7 @@
 
   Label slow_path, done;
   if (compiler->is_optimizing() &&
-      !Compiler::always_optimize() &&
+      !FLAG_precompilation &&
       num_elements()->BindsToConstant() &&
       num_elements()->BoundConstant().IsSmi()) {
     const intptr_t length = Smi::Cast(num_elements()->BoundConstant()).Value();
@@ -2628,7 +2626,7 @@
       // In unoptimized code, record loop stack checks as possible OSR entries.
       compiler->AddCurrentDescriptor(RawPcDescriptors::kOsrEntry,
                                      instruction_->deopt_id(),
-                                     0);  // No token position.
+                                     TokenPosition::kNoSource);
     }
     compiler->pending_deoptimization_env_ = NULL;
     compiler->RestoreLiveRegisters(instruction_->locs());
@@ -6192,7 +6190,7 @@
     // may be inserted before this instruction.
     compiler->AddCurrentDescriptor(RawPcDescriptors::kDeopt,
                                    GetDeoptId(),
-                                   Token::kNoSourcePos);
+                                   TokenPosition::kNoSource);
   }
   if (HasParallelMove()) {
     compiler->parallel_move_resolver()->EmitNativeCode(parallel_move());
@@ -6444,7 +6442,7 @@
   const Register result = locs()->out(0).reg();
   __ PushObject(Object::null_object());
   __ pushq(typed_data);
-  compiler->GenerateRuntimeCall(Token::kNoSourcePos,  // No token position.
+  compiler->GenerateRuntimeCall(TokenPosition::kNoSource,
                                 deopt_id(),
                                 kGrowRegExpStackRuntimeEntry,
                                 1,
diff --git a/runtime/vm/intrinsifier.cc b/runtime/vm/intrinsifier.cc
index 748c8c4..accc70f 100644
--- a/runtime/vm/intrinsifier.cc
+++ b/runtime/vm/intrinsifier.cc
@@ -264,7 +264,7 @@
                          SPREG));
   }
 
-  intptr_t TokenPos() {
+  TokenPosition TokenPos() {
     return flow_graph_->function().token_pos();
   }
 
@@ -294,7 +294,7 @@
                              Definition* array,
                              Definition* index,
                              intptr_t length_offset) {
-  intptr_t token_pos = builder->TokenPos();
+  TokenPosition token_pos = builder->TokenPos();
   builder->AddInstruction(
       new CheckSmiInstr(new Value(index),
                         Thread::kNoDeoptId,
@@ -304,7 +304,7 @@
       new LoadFieldInstr(new Value(array),
                          length_offset,
                          Type::ZoneHandle(Type::SmiType()),
-                         Token::kNoSourcePos));
+                         TokenPosition::kNoSource));
   builder->AddInstruction(
       new CheckArrayBoundInstr(new Value(length),
                                new Value(index),
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index a62ac0e..dc99e4c 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -29,6 +29,7 @@
 #include "vm/port.h"
 #include "vm/profiler.h"
 #include "vm/reusable_handles.h"
+#include "vm/safepoint.h"
 #include "vm/service.h"
 #include "vm/service_event.h"
 #include "vm/service_isolate.h"
@@ -84,6 +85,8 @@
 DEFINE_FLAG(bool, error_on_bad_type, false,
             "Report error for malformed types.");
 
+DECLARE_FLAG(bool, warn_on_pause_with_no_debugger);
+
 static void CheckedModeHandler(bool value) {
   FLAG_enable_asserts = value;
   FLAG_enable_type_checks = value;
@@ -569,7 +572,7 @@
 
 
 void IsolateMessageHandler::NotifyPauseOnStart() {
-  if (Service::debug_stream.enabled()) {
+  if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) {
     StartIsolateScope start_isolate(I);
     StackZone zone(T);
     HandleScope handle_scope(T);
@@ -583,7 +586,7 @@
 
 
 void IsolateMessageHandler::NotifyPauseOnExit() {
-  if (Service::debug_stream.enabled()) {
+  if (Service::debug_stream.enabled() || FLAG_warn_on_pause_with_no_debugger) {
     StartIsolateScope start_isolate(I);
     StackZone zone(T);
     HandleScope handle_scope(T);
@@ -746,6 +749,7 @@
       class_table_(),
       single_step_(false),
       thread_registry_(new ThreadRegistry()),
+      safepoint_handler_(new SafepointHandler(this)),
       message_notify_callback_(NULL),
       name_(NULL),
       debugger_name_(NULL),
@@ -839,17 +843,11 @@
     delete compiler_stats_;
     compiler_stats_ = NULL;
   }
+  delete safepoint_handler_;
   delete thread_registry_;
 }
 
 
-#if defined(DEBUG)
-bool Isolate::IsIsolateOf(Thread* thread) {
-  return this == thread->isolate();
-}
-#endif  // DEBUG
-
-
 void Isolate::InitOnce() {
   create_callback_ = NULL;
   isolates_list_monitor_ = new Monitor();
@@ -1457,7 +1455,6 @@
 RawError* Isolate::HandleInterrupts() {
   uword interrupt_bits = GetAndClearInterrupts();
   if ((interrupt_bits & kVMInterrupt) != 0) {
-    thread_registry()->CheckSafepoint();
     if (store_buffer()->Overflowed()) {
       if (FLAG_verbose_gc) {
         OS::PrintErr("Scavenge scheduled by store buffer overflow.\n");
@@ -1508,7 +1505,7 @@
 // all closure functions becomes more difficult, especially when
 // the list/map changes while iterating over it.
 RawFunction* Isolate::LookupClosureFunction(const Function& parent,
-                                            intptr_t token_pos) const {
+                                            TokenPosition token_pos) const {
   const GrowableObjectArray& closures =
       GrowableObjectArray::Handle(object_store()->closure_functions());
   ASSERT(!closures.IsNull());
@@ -1766,7 +1763,7 @@
     deopt_context()->VisitObjectPointers(visitor);
   }
 
-  // Visit objects in thread registry (e.g., Dart stack, handles in zones).
+  // Visit objects in all threads (e.g., Dart stack, handles in zones).
   thread_registry()->VisitObjectPointers(visitor, validate_frames);
 }
 
@@ -1778,6 +1775,11 @@
 }
 
 
+void Isolate::PrepareForGC() {
+  thread_registry()->PrepareForGC();
+}
+
+
 static const char* ExceptionPauseInfoToServiceEnum(Dart_ExceptionPauseInfo pi) {
   switch (pi) {
     case kPauseOnAllExceptions:
@@ -2335,6 +2337,77 @@
 }
 
 
+Monitor* Isolate::threads_lock() const {
+  return thread_registry_->threads_lock();
+}
+
+
+Thread* Isolate::ScheduleThread(bool is_mutator, bool bypass_safepoint) {
+  // Schedule the thread into the isolate by associating
+  // a 'Thread' structure with it (this is done while we are holding
+  // the thread registry lock).
+  Thread* thread = NULL;
+  OSThread* os_thread = OSThread::Current();
+  if (os_thread != NULL) {
+    MonitorLocker ml(threads_lock());
+
+    // If a safepoint operation is in progress wait for it
+    // to finish before scheduling this thread in.
+    while (!bypass_safepoint && safepoint_handler()->safepoint_in_progress()) {
+      ml.Wait();
+    }
+
+    // Now get a free Thread structure.
+    thread = thread_registry()->GetFreeThreadLocked(this, is_mutator);
+    ASSERT(thread != NULL);
+
+    // Set up other values and set the TLS value.
+    thread->isolate_ = this;
+    ASSERT(heap() != NULL);
+    thread->heap_ = heap();
+    thread->set_os_thread(os_thread);
+    ASSERT(thread->execution_state() == Thread::kThreadInVM);
+    thread->set_safepoint_state(0);
+    thread->set_vm_tag(VMTag::kVMTagId);
+    os_thread->set_thread(thread);
+    if (is_mutator) {
+      mutator_thread_ = thread;
+    }
+    Thread::SetCurrent(thread);
+    os_thread->EnableThreadInterrupts();
+  }
+  return thread;
+}
+
+
+void Isolate::UnscheduleThread(Thread* thread,
+                               bool is_mutator,
+                               bool bypass_safepoint) {
+  // Disassociate the 'Thread' structure and unschedule the thread
+  // from this isolate.
+  MonitorLocker ml(threads_lock());
+  if (!bypass_safepoint) {
+    // Ensure that the thread reports itself as being at a safepoint.
+    thread->EnterSafepoint();
+  }
+  OSThread* os_thread = thread->os_thread();
+  ASSERT(os_thread != NULL);
+  os_thread->DisableThreadInterrupts();
+  os_thread->set_thread(NULL);
+  OSThread::SetCurrent(os_thread);
+  if (is_mutator) {
+    mutator_thread_ = NULL;
+  }
+  thread->isolate_ = NULL;
+  thread->heap_ = NULL;
+  thread->set_os_thread(NULL);
+  thread->set_execution_state(Thread::kThreadInVM);
+  thread->set_safepoint_state(0);
+  // Return thread structure.
+  thread_registry()->ReturnThreadLocked(is_mutator, thread);
+}
+
+
 static RawInstance* DeserializeObject(Thread* thread,
                                       uint8_t* obj_data,
                                       intptr_t obj_len) {
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index 56cf82e..ee0404b 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -56,6 +56,7 @@
 class RawFloat32x4;
 class RawInt32x4;
 class RawUserTag;
+class SafepointHandler;
 class SampleBuffer;
 class SendPort;
 class ServiceIdZone;
@@ -126,9 +127,13 @@
   // Visits weak object pointers.
   void VisitWeakPersistentHandles(HandleVisitor* visitor);
 
+  // Prepares all threads in an isolate for Garbage Collection.
+  void PrepareForGC();
+
   StoreBuffer* store_buffer() { return store_buffer_; }
 
-  ThreadRegistry* thread_registry() { return thread_registry_; }
+  ThreadRegistry* thread_registry() const { return thread_registry_; }
+  SafepointHandler* safepoint_handler() const { return safepoint_handler_; }
 
   ClassTable* class_table() { return &class_table_; }
   static intptr_t class_table_offset() {
@@ -635,7 +640,7 @@
 
   void AddClosureFunction(const Function& function) const;
   RawFunction* LookupClosureFunction(const Function& parent,
-                                     intptr_t token_pos) const;
+                                     TokenPosition token_pos) const;
   intptr_t FindClosureIndex(const Function& needle) const;
   RawFunction* ClosureFunctionFromIndex(intptr_t idx) const;
 
@@ -687,17 +692,10 @@
   void set_registered_service_extension_handlers(
       const GrowableObjectArray& value);
 
-  void ClearMutatorThread() {
-    mutator_thread_ = NULL;
-  }
-  void MakeCurrentThreadMutator(Thread* thread) {
-    ASSERT(thread == Thread::Current());
-    DEBUG_ASSERT(IsIsolateOf(thread));
-    mutator_thread_ = thread;
-  }
-#if defined(DEBUG)
-  bool IsIsolateOf(Thread* thread);
-#endif  // DEBUG
+  Monitor* threads_lock() const;
+  Thread* ScheduleThread(bool is_mutator, bool bypass_safepoint = false);
+  void UnscheduleThread(
+      Thread* thread, bool is_mutator, bool bypass_safepoint = false);
 
   // DEPRECATED: Use Thread's methods instead. During migration, these default
   // to using the mutator thread (which must also be the current thread).
@@ -721,6 +719,7 @@
   bool skip_step_;  // skip the next single step.
 
   ThreadRegistry* thread_registry_;
+  SafepointHandler* safepoint_handler_;
   Dart_MessageNotifyCallback message_notify_callback_;
   char* name_;
   char* debugger_name_;
@@ -860,6 +859,7 @@
 #undef REUSABLE_FRIEND_DECLARATION
 
   friend class GCMarker;  // VisitObjectPointers
+  friend class SafepointHandler;
   friend class Scavenger;  // VisitObjectPointers
   friend class ServiceIsolate;
   friend class Thread;
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 4851875..6a2694a 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -396,10 +396,12 @@
 }
 
 
-bool JSONStream::PrintValueStr(const String& s, intptr_t limit) {
+bool JSONStream::PrintValueStr(const String& s,
+                               intptr_t offset,
+                               intptr_t count) {
   PrintCommaIfNeeded();
   buffer_.AddChar('"');
-  bool did_truncate = AddDartString(s, limit);
+  bool did_truncate = AddDartString(s, offset, count);
   buffer_.AddChar('"');
   return did_truncate;
 }
@@ -442,6 +444,12 @@
 }
 
 
+void JSONStream::PrintValue(TokenPosition tp) {
+  PrintCommaIfNeeded();
+  PrintValue(tp.value());
+}
+
+
 void JSONStream::PrintValue(const ServiceEvent* event) {
   PrintCommaIfNeeded();
   event->PrintJSON(this);
@@ -534,9 +542,10 @@
 
 bool JSONStream::PrintPropertyStr(const char* name,
                                   const String& s,
-                                  intptr_t limit) {
+                                  intptr_t offset,
+                                  intptr_t count) {
   PrintPropertyName(name);
-  return PrintValueStr(s, limit);
+  return PrintValueStr(s, offset, count);
 }
 
 
@@ -558,6 +567,12 @@
 }
 
 
+void JSONStream::PrintProperty(const char* name, TokenPosition tp) {
+  PrintPropertyName(name);
+  PrintValue(tp);
+}
+
+
 void JSONStream::PrintProperty(const char* name, Metric* metric) {
   PrintPropertyName(name);
   PrintValue(metric);
@@ -702,23 +717,24 @@
 }
 
 
-bool JSONStream::AddDartString(const String& s, intptr_t limit) {
-  bool did_truncate = false;
+bool JSONStream::AddDartString(const String& s,
+                               intptr_t offset,
+                               intptr_t count) {
   intptr_t length = s.Length();
-  if (limit == -1) {
-    limit = length;
+  ASSERT(offset >= 0);
+  if (offset > length) {
+    offset = length;
   }
-  if (length <= limit) {
-    limit = length;
-  } else {
-    did_truncate = true;
+  if (!Utils::RangeCheck(offset, count, length)) {
+    count = length - offset;
   }
-
-  for (intptr_t i = 0; i < limit; i++) {
+  intptr_t limit = offset + count;
+  for (intptr_t i = offset; i < limit; i++) {
     intptr_t code_unit = s.CharAt(i);
     buffer_.EscapeAndAddCodeUnit(code_unit);
   }
-  return did_truncate;
+  // Return value indicates whether the string is truncated.
+  return (offset > 0) || (limit < length);
 }
 
 
@@ -749,13 +765,13 @@
 
 
 void JSONObject::AddLocation(const Script& script,
-                             intptr_t token_pos,
-                             intptr_t end_token_pos) const {
+                             TokenPosition token_pos,
+                             TokenPosition end_token_pos) const {
   JSONObject location(this, "location");
   location.AddProperty("type", "SourceLocation");
   location.AddProperty("script", script);
   location.AddProperty("tokenPos", token_pos);
-  if (end_token_pos >= 0) {
+  if (end_token_pos.IsReal()) {
     location.AddProperty("endTokenPos", end_token_pos);
   }
 }
@@ -767,7 +783,7 @@
   Zone* zone = Thread::Current()->zone();
   Library& library = Library::Handle(zone);
   Script& script = Script::Handle(zone);
-  intptr_t token_pos;
+  TokenPosition token_pos = TokenPosition::kNoSource;
   bpt_loc->GetCodeLocation(&library, &script, &token_pos);
   AddLocation(script, token_pos);
 }
@@ -780,7 +796,7 @@
   Zone* zone = Thread::Current()->zone();
   Library& library = Library::Handle(zone);
   Script& script = Script::Handle(zone);
-  intptr_t token_pos;
+  TokenPosition token_pos = TokenPosition::kNoSource;
   bpt_loc->GetCodeLocation(&library, &script, &token_pos);
 
   JSONObject location(this, "location");
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 239c4e7..8c145681 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -9,6 +9,7 @@
 #include "platform/text_buffer.h"
 #include "vm/allocation.h"
 #include "vm/service.h"
+#include "vm/token_position.h"
 
 
 namespace dart {
@@ -50,6 +51,7 @@
   kCannotAddBreakpoint     = 102,
   kStreamAlreadySubscribed = 103,
   kStreamNotSubscribed     = 104,
+  kIsolateMustBeRunnable   = 105,
 };
 
 
@@ -154,11 +156,12 @@
   void PrintfValue(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
   void PrintValue(const Object& o, bool ref = true);
   void PrintValue(Breakpoint* bpt);
+  void PrintValue(TokenPosition tp);
   void PrintValue(const ServiceEvent* event);
   void PrintValue(Metric* metric);
   void PrintValue(MessageQueue* queue);
   void PrintValue(Isolate* isolate, bool ref = true);
-  bool PrintValueStr(const String& s, intptr_t limit);
+  bool PrintValueStr(const String& s, intptr_t offset, intptr_t count);
   void PrintValue(TimelineEvent* timeline_event);
   void PrintValueVM(bool ref = true);
 
@@ -173,7 +176,8 @@
                            const uint8_t* bytes,
                            intptr_t length);
   void PrintProperty(const char* name, const char* s);
-  bool PrintPropertyStr(const char* name, const String& s, intptr_t limit);
+  bool PrintPropertyStr(const char* name, const String& s,
+                        intptr_t offset, intptr_t count);
   void PrintPropertyNoEscape(const char* name, const char* s);
   void PrintfProperty(const char* name, const char* format, ...)
   PRINTF_ATTRIBUTE(3, 4);
@@ -181,6 +185,7 @@
 
   void PrintProperty(const char* name, const ServiceEvent* event);
   void PrintProperty(const char* name, Breakpoint* bpt);
+  void PrintProperty(const char* name, TokenPosition tp);
   void PrintProperty(const char* name, Metric* metric);
   void PrintProperty(const char* name, MessageQueue* queue);
   void PrintProperty(const char* name, Isolate* isolate);
@@ -190,7 +195,7 @@
   void PrintCommaIfNeeded();
   bool NeedComma();
 
-  bool AddDartString(const String& s, intptr_t limit);
+  bool AddDartString(const String& s, intptr_t offset, intptr_t count);
   void AddEscapedUTF8String(const char* s);
   void AddEscapedUTF8String(const char* s, intptr_t len);
 
@@ -239,9 +244,10 @@
 
   void AddFixedServiceId(const char* format, ...) const PRINTF_ATTRIBUTE(2, 3);
 
-  void AddLocation(const Script& script,
-                   intptr_t token_pos,
-                   intptr_t end_token_pos = -1) const;
+  void AddLocation(
+      const Script& script,
+      TokenPosition token_pos,
+      TokenPosition end_token_pos = TokenPosition::kNoSource) const;
 
   void AddLocation(const BreakpointLocation* bpt_loc) const;
 
@@ -275,8 +281,9 @@
   }
   bool AddPropertyStr(const char* name,
                       const String& s,
-                      intptr_t limit = -1) const {
-    return stream_->PrintPropertyStr(name, s, limit);
+                      intptr_t offset = 0,
+                      intptr_t count = -1) const {
+    return stream_->PrintPropertyStr(name, s, offset, count);
   }
   void AddPropertyNoEscape(const char* name, const char* s) const {
     stream_->PrintPropertyNoEscape(name, s);
@@ -290,6 +297,9 @@
   void AddProperty(const char* name, Breakpoint* bpt) const {
     stream_->PrintProperty(name, bpt);
   }
+  void AddProperty(const char* name, TokenPosition tp) const {
+    stream_->PrintProperty(name, tp);
+  }
   void AddProperty(const char* name, Metric* metric) const {
     stream_->PrintProperty(name, metric);
   }
@@ -354,6 +364,9 @@
   void AddValue(Breakpoint* bpt) const {
     stream_->PrintValue(bpt);
   }
+  void AddValue(TokenPosition tp) const {
+    stream_->PrintValue(tp);
+  }
   void AddValue(const ServiceEvent* event) const {
     stream_->PrintValue(event);
   }
diff --git a/runtime/vm/json_test.cc b/runtime/vm/json_test.cc
index 245bdd6..985b547 100644
--- a/runtime/vm/json_test.cc
+++ b/runtime/vm/json_test.cc
@@ -236,9 +236,22 @@
     JSONStream js;
     {
       JSONObject jsobj(&js);
-      jsobj.AddPropertyStr("ascci", obj);;
+      EXPECT(!jsobj.AddPropertyStr("ascii", obj));
     }
-    EXPECT_STREQ("{\"ascci\":\"Hello, World!\"}", js.ToCString());
+    EXPECT_STREQ("{\"ascii\":\"Hello, World!\"}", js.ToCString());
+  }
+
+  {
+    result = Dart_GetField(lib, NewString("ascii"));
+    EXPECT_VALID(result);
+    obj ^= Api::UnwrapHandle(result);
+
+    JSONStream js;
+    {
+      JSONObject jsobj(&js);
+      EXPECT(jsobj.AddPropertyStr("subrange", obj, 1, 4));
+    }
+    EXPECT_STREQ("{\"subrange\":\"ello\"}", js.ToCString());
   }
 
   {
@@ -249,7 +262,7 @@
     JSONStream js;
     {
       JSONObject jsobj(&js);
-      jsobj.AddPropertyStr("unicode", obj);
+      EXPECT(!jsobj.AddPropertyStr("unicode", obj));
     }
     EXPECT_STREQ("{\"unicode\":\"\\u00CE\\u00F1\\u0163\\u00E9r\\u00F1\\u00E5"
                  "\\u0163\\u00EE\\u00F6\\u00F1\\u00E5\\u013C\\u00EE\\u017E"
@@ -264,7 +277,7 @@
     JSONStream js;
     {
       JSONObject jsobj(&js);
-      jsobj.AddPropertyStr("surrogates", obj);
+      EXPECT(!jsobj.AddPropertyStr("surrogates", obj));
     }
     EXPECT_STREQ("{\"surrogates\":\"\\uD834\\uDD1E\\uD834\\uDD1E\\uD834\\uDD1E"
                  "\\uD834\\uDD1E\\uD834\\uDD1E\"}", js.ToCString());
@@ -278,7 +291,7 @@
     JSONStream js;
     {
       JSONObject jsobj(&js);
-      jsobj.AddPropertyStr("nullInMiddle", obj);
+      EXPECT(!jsobj.AddPropertyStr("nullInMiddle", obj));
     }
     EXPECT_STREQ("{\"nullInMiddle\":\"This has\\u0000 four words.\"}",
                  js.ToCString());
diff --git a/runtime/vm/locations.h b/runtime/vm/locations.h
index 047b663..963c4b4 100644
--- a/runtime/vm/locations.h
+++ b/runtime/vm/locations.h
@@ -387,19 +387,20 @@
     return PayloadField::decode(value_);
   }
 
-  typedef BitField<Kind, 0, kBitsForKind> KindField;
-  typedef BitField<uword, kBitsForKind, kBitsForPayload> PayloadField;
+  class KindField : public BitField<uword, Kind, 0, kBitsForKind> {};
+  class PayloadField :
+      public BitField<uword, uword, kBitsForKind, kBitsForPayload> {};
 
   // Layout for kUnallocated locations payload.
-  typedef BitField<Policy, 0, 3> PolicyField;
+  typedef BitField<uword, Policy, 0, 3> PolicyField;
 
   // Layout for stack slots.
   static const intptr_t kBitsForBaseReg = 5;
   static const intptr_t kBitsForStackIndex = kBitsForPayload - kBitsForBaseReg;
-  typedef BitField<Register, 0, kBitsForBaseReg> StackSlotBaseField;
-  typedef BitField<intptr_t,
-                   kBitsForBaseReg,
-                   kBitsForStackIndex> StackIndexField;
+  class StackSlotBaseField :
+      public BitField<uword, Register, 0, kBitsForBaseReg> {};
+  class StackIndexField :
+      public BitField<uword, intptr_t, kBitsForBaseReg, kBitsForStackIndex> {};
   COMPILE_ASSERT(1 << kBitsForBaseReg >= kNumberOfCpuRegisters);
 
   static const intptr_t kStackIndexBias =
diff --git a/runtime/vm/lockers.cc b/runtime/vm/lockers.cc
new file mode 100644
index 0000000..1c95381
--- /dev/null
+++ b/runtime/vm/lockers.cc
@@ -0,0 +1,37 @@
+// 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/lockers.h"
+#include "vm/safepoint.h"
+
+namespace dart {
+
+
+Monitor::WaitResult MonitorLocker::WaitWithSafepointCheck(Thread* thread,
+                                                          int64_t millis) {
+  ASSERT(thread == Thread::Current());
+  thread->set_execution_state(Thread::kThreadInBlockedState);
+  thread->EnterSafepoint();
+  Monitor::WaitResult result = monitor_->Wait(millis);
+  // First try a fast update of the thread state to indicate it is not at a
+  // safepoint anymore.
+  uword old_state = Thread::SetAtSafepoint(true, 0);
+  uword addr =
+      reinterpret_cast<uword>(thread) + Thread::safepoint_state_offset();
+  if (AtomicOperations::CompareAndSwapWord(
+          reinterpret_cast<uword*>(addr), old_state, 0) != old_state) {
+    // Fast update failed which means we could potentially be in the middle
+    // of a safepoint operation and need to block for it.
+    monitor_->Exit();
+    SafepointHandler* handler = thread->isolate()->safepoint_handler();
+    handler->ExitSafepointUsingLock(thread);
+    monitor_->Enter();
+  }
+  thread->set_execution_state(Thread::kThreadInVM);
+  return result;
+}
+
+
+}  // namespace dart
diff --git a/runtime/vm/lockers.h b/runtime/vm/lockers.h
index f3f5540..42b0984 100644
--- a/runtime/vm/lockers.h
+++ b/runtime/vm/lockers.h
@@ -50,6 +50,9 @@
     return monitor_->Wait(millis);
   }
 
+  Monitor::WaitResult WaitWithSafepointCheck(
+      Thread* thread, int64_t millis = Monitor::kNoTimeout);
+
   Monitor::WaitResult WaitMicros(int64_t micros = Monitor::kNoTimeout) {
     return monitor_->WaitMicros(micros);
   }
diff --git a/runtime/vm/megamorphic_cache_table.cc b/runtime/vm/megamorphic_cache_table.cc
index 6f2d172..062941e 100644
--- a/runtime/vm/megamorphic_cache_table.cc
+++ b/runtime/vm/megamorphic_cache_table.cc
@@ -71,7 +71,7 @@
                                      false,  // Not external.
                                      false,  // Not native.
                                      cls,
-                                     0));  // No token position.
+                                     TokenPosition::kNoSource));
   function.set_result_type(Type::Handle(Type::DynamicType()));
   function.set_is_debuggable(false);
   function.set_is_visible(false);
diff --git a/runtime/vm/native_api_impl.cc b/runtime/vm/native_api_impl.cc
index 8a546e4..1bc5d4c 100644
--- a/runtime/vm/native_api_impl.cc
+++ b/runtime/vm/native_api_impl.cc
@@ -28,12 +28,13 @@
       : saved_isolate_(current_isolate) {
     if (current_isolate != NULL) {
       ASSERT(current_isolate == Isolate::Current());
-      Thread::ExitIsolate();
+      Dart_ExitIsolate();
     }
   }
   ~IsolateSaver() {
     if (saved_isolate_ != NULL) {
-      Thread::EnterIsolate(saved_isolate_);
+      Dart_Isolate I = reinterpret_cast<Dart_Isolate>(saved_isolate_);
+      Dart_EnterIsolate(I);
     }
   }
  private:
diff --git a/runtime/vm/native_arguments.h b/runtime/vm/native_arguments.h
index 0655a69..8bb1d6e 100644
--- a/runtime/vm/native_arguments.h
+++ b/runtime/vm/native_arguments.h
@@ -96,6 +96,10 @@
     return *arg_ptr;
   }
 
+  bool IsNativeAutoSetupScope() const {
+    return AutoSetupScopeBits::decode(argc_tag_);
+  }
+
   int NativeArgCount() const {
     int function_bits = FunctionBits::decode(argc_tag_);
     return ArgCount() - NumHiddenArgs(function_bits);
@@ -185,9 +189,11 @@
     kFunctionSize = 2,
     kAutoSetupScopeBit = 26,
   };
-  class ArgcBits : public BitField<int, kArgcBit, kArgcSize> {};
-  class FunctionBits : public BitField<int, kFunctionBit, kFunctionSize> {};
-  class AutoSetupScopeBits : public BitField<int, kAutoSetupScopeBit, 1> {};
+  class ArgcBits : public BitField<intptr_t, int32_t, kArgcBit, kArgcSize> {};
+  class FunctionBits :
+      public BitField<intptr_t, int, kFunctionBit, kFunctionSize> {};
+  class AutoSetupScopeBits :
+      public BitField<intptr_t, int, kAutoSetupScopeBit, 1> {};
   friend class Api;
   friend class BootstrapNatives;
   friend class Simulator;
@@ -222,7 +228,7 @@
   }
 
   Thread* thread_;  // Current thread pointer.
-  int argc_tag_;  // Encodes argument count and invoked native call type.
+  intptr_t argc_tag_;  // Encodes argument count and invoked native call type.
   RawObject*(*argv_)[];  // Pointer to an array of arguments to runtime call.
   RawObject** retval_;  // Pointer to the return value area.
 };
diff --git a/runtime/vm/native_entry.cc b/runtime/vm/native_entry.cc
index 92a99e8..2277319 100644
--- a/runtime/vm/native_entry.cc
+++ b/runtime/vm/native_entry.cc
@@ -12,6 +12,7 @@
 #include "vm/dart_api_state.h"
 #include "vm/object_store.h"
 #include "vm/reusable_handles.h"
+#include "vm/safepoint.h"
 #include "vm/stack_frame.h"
 #include "vm/symbols.h"
 #include "vm/tags.h"
@@ -33,12 +34,16 @@
     // class belongs in.
     return NULL;
   }
-  Dart_EnterScope();  // Enter a new Dart API scope as we invoke API entries.
-  Dart_NativeEntryResolver resolver = library.native_entry_resolver();
-  Dart_NativeFunction native_function =
-      resolver(Api::NewHandle(Thread::Current(), function_name.raw()),
-               number_of_arguments, auto_setup_scope);
-  Dart_ExitScope();  // Exit the Dart API scope.
+  Dart_NativeFunction native_function = NULL;
+  {
+    Thread* T = Thread::Current();
+    TransitionVMToNative transition(T);
+    Dart_EnterScope();  // Enter a new Dart API scope as we invoke API entries.
+    Dart_NativeEntryResolver resolver = library.native_entry_resolver();
+    native_function = resolver(Api::NewHandle(T, function_name.raw()),
+                               number_of_arguments, auto_setup_scope);
+    Dart_ExitScope();  // Exit the Dart API scope.
+  }
   return reinterpret_cast<NativeFunction>(native_function);
 }
 
@@ -94,38 +99,43 @@
   /* Tell MemorySanitizer 'arguments' is initialized by generated code. */
   MSAN_UNPOISON(arguments, sizeof(*arguments));
   Thread* thread = arguments->thread();
-  Isolate* isolate = thread->isolate();
-
-  ApiState* state = isolate->api_state();
-  ASSERT(state != NULL);
-  ApiLocalScope* current_top_scope = thread->api_top_scope();
-  ApiLocalScope* scope = thread->api_reusable_scope();
-  TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func));
-  if (scope == NULL) {
-    scope = new ApiLocalScope(current_top_scope,
-                              thread->top_exit_frame_info());
-    ASSERT(scope != NULL);
+  if (!arguments->IsNativeAutoSetupScope()) {
+    TransitionGeneratedToNative transition(thread);
+    func(args);
   } else {
-    scope->Reinit(thread,
-                  current_top_scope,
-                  thread->top_exit_frame_info());
-    thread->set_api_reusable_scope(NULL);
-  }
-  thread->set_api_top_scope(scope);  // New scope is now the top scope.
+    Isolate* isolate = thread->isolate();
+    ApiState* state = isolate->api_state();
+    ASSERT(state != NULL);
+    ApiLocalScope* current_top_scope = thread->api_top_scope();
+    ApiLocalScope* scope = thread->api_reusable_scope();
+    TRACE_NATIVE_CALL("0x%" Px "", reinterpret_cast<uintptr_t>(func));
+    TransitionGeneratedToNative transition(thread);
+    if (scope == NULL) {
+      scope = new ApiLocalScope(current_top_scope,
+                                thread->top_exit_frame_info());
+      ASSERT(scope != NULL);
+    } else {
+      scope->Reinit(thread,
+                    current_top_scope,
+                    thread->top_exit_frame_info());
+      thread->set_api_reusable_scope(NULL);
+    }
+    thread->set_api_top_scope(scope);  // New scope is now the top scope.
 
-  func(args);
+    func(args);
 
-  ASSERT(current_top_scope == scope->previous());
-  thread->set_api_top_scope(current_top_scope);  // Reset top scope to previous.
-  if (thread->api_reusable_scope() == NULL) {
-    scope->Reset(thread);  // Reset the old scope which we just exited.
-    thread->set_api_reusable_scope(scope);
-  } else {
-    ASSERT(thread->api_reusable_scope() != scope);
-    delete scope;
+    ASSERT(current_top_scope == scope->previous());
+    thread->set_api_top_scope(current_top_scope);  // Reset top scope to prev.
+    if (thread->api_reusable_scope() == NULL) {
+      scope->Reset(thread);  // Reset the old scope which we just exited.
+      thread->set_api_reusable_scope(scope);
+    } else {
+      ASSERT(thread->api_reusable_scope() != scope);
+      delete scope;
+    }
+    DEOPTIMIZE_ALOT;
+    VERIFY_ON_TRANSITION;
   }
-  DEOPTIMIZE_ALOT;
-  VERIFY_ON_TRANSITION;
 }
 
 
@@ -168,11 +178,9 @@
 
   NativeFunction target_function = NULL;
   bool call_through_wrapper = false;
-#ifdef USING_SIMULATOR
-  bool is_native_auto_setup_scope = false;
-#endif
 
   {
+    TransitionGeneratedToVM transition(arguments->thread());
     StackZone zone(arguments->thread());
 
     DartFrameIterator iterator;
@@ -180,9 +188,6 @@
 
     const Code& code = Code::Handle(caller_frame->LookupDartCode());
     const Function& func = Function::Handle(code.function());
-#ifdef USING_SIMULATOR
-    is_native_auto_setup_scope = func.IsNativeAutoSetupScope();
-#endif
 
     if (FLAG_trace_natives) {
       OS::Print("Resolving native target for %s\n", func.ToCString());
@@ -216,19 +221,14 @@
     }
 #endif
 
-    const intptr_t argc_tag = NativeArguments::ComputeArgcTag(func);
-    const bool is_leaf_call =
-        (argc_tag & NativeArguments::AutoSetupScopeMask()) == 0;
-
-    call_through_wrapper = !is_bootstrap_native && !is_leaf_call;
-
+    call_through_wrapper = !is_bootstrap_native;
     const Code& trampoline = Code::Handle(call_through_wrapper ?
         StubCode::CallNativeCFunction_entry()->code() :
         StubCode::CallBootstrapCFunction_entry()->code());
 
     NativeFunction patch_target_function = target_function;
 #if defined(USING_SIMULATOR)
-    if (!call_through_wrapper || !is_native_auto_setup_scope) {
+    if (!call_through_wrapper) {
       patch_target_function = reinterpret_cast<NativeFunction>(
           Simulator::RedirectExternalReference(
               reinterpret_cast<uword>(patch_target_function),
@@ -240,10 +240,9 @@
         caller_frame->pc(), code, patch_target_function, trampoline);
 
     if (FLAG_trace_natives) {
-      OS::Print("    -> %p (%s, %s)\n",
+      OS::Print("    -> %p (%s)\n",
                 target_function,
-                is_bootstrap_native ? "bootstrap" : "non-bootstrap",
-                is_leaf_call ? "leaf" : "non-leaf");
+                is_bootstrap_native ? "bootstrap" : "non-bootstrap");
     }
   }
   VERIFY_ON_TRANSITION;
diff --git a/runtime/vm/native_entry.h b/runtime/vm/native_entry.h
index 25dee39..e9dab6c 100644
--- a/runtime/vm/native_entry.h
+++ b/runtime/vm/native_entry.h
@@ -54,6 +54,7 @@
       Thread* thread = arguments->thread();                                    \
       ASSERT(thread == Thread::Current());                                     \
       Isolate* isolate = thread->isolate();                                    \
+      TransitionGeneratedToVM transition(thread);                              \
       StackZone zone(thread);                                                  \
       SET_NATIVE_RETVAL(arguments,                                             \
                         DN_Helper##name(isolate,                               \
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index df6fde0..340735f 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -67,6 +67,7 @@
 
 DECLARE_FLAG(charp, coverage_dir);
 DECLARE_FLAG(bool, load_deferred_eagerly);
+DECLARE_FLAG(bool, precompilation);
 DECLARE_FLAG(bool, show_invisible_frames);
 DECLARE_FLAG(bool, trace_deoptimization);
 DECLARE_FLAG(bool, trace_deoptimization_verbose);
@@ -1184,7 +1185,7 @@
   // could expect. Use with caution.
   type ^= Type::New(Object::Handle(zone, cls.raw()),
                     TypeArguments::Handle(zone),
-                    Token::kNoSourcePos);
+                    TokenPosition::kNoSource);
   type.SetIsFinalized();
   type ^= type.Canonicalize();
   object_store->set_array_type(type);
@@ -1585,7 +1586,7 @@
 #define ADD_SET_FIELD(clazz)                                                   \
   field_name = Symbols::New("cid"#clazz);                                      \
   field = Field::New(field_name, true, false, true, false, cls,                \
-      Type::Handle(Type::IntType()), 0);                                       \
+      Type::Handle(Type::IntType()), TokenPosition::kMinSource);             \
   value = Smi::New(k##clazz##Cid);                                             \
   field.SetStaticValue(value, true);                                           \
   cls.AddField(field);                                                         \
@@ -1971,7 +1972,7 @@
   const Type& type = Type::Handle(Type::New(
       *this,
       Object::null_type_arguments(),
-      Token::kNoSourcePos));
+      TokenPosition::kNoSource));
   return ClassFinalizer::FinalizeType(*this,
                                       type,
                                       ClassFinalizer::kCanonicalize);
@@ -1983,7 +1984,7 @@
   const Type& type = Type::Handle(Type::New(
       *this,
       args,
-      Token::kNoSourcePos));
+      TokenPosition::kNoSource));
   return ClassFinalizer::FinalizeType(*this,
                                       type,
                                       ClassFinalizer::kCanonicalize);
@@ -2021,7 +2022,7 @@
   result.set_num_type_arguments(0);
   result.set_num_own_type_arguments(0);
   result.set_num_native_fields(0);
-  result.set_token_pos(Token::kNoSourcePos);
+  result.set_token_pos(TokenPosition::kNoSource);
   result.InitEmptyFields();
   Isolate::Current()->RegisterClass(result);
   return result.raw();
@@ -2621,7 +2622,7 @@
                     false,  // Not external.
                     false,  // Not native.
                     *this,
-                    0));    // token_pos
+                    TokenPosition::kMinSource));
   ArgumentsDescriptor desc(args_desc);
   invocation.set_num_fixed_parameters(desc.PositionalCount());
   invocation.SetNumOptionalParameters(desc.NamedCount(),
@@ -2678,7 +2679,7 @@
                   false,  // Not external.
                   false,  // Not native.
                   owner,
-                  ClassifyingTokenPositions::kMethodExtractor));  // token_pos
+                  TokenPosition::kMethodExtractor));
 
   // Initialize signature: receiver is a single fixed parameter.
   const intptr_t kNumParameters = 1;
@@ -2779,8 +2780,7 @@
 #if defined(DEBUG)
 static bool IsMutatorOrAtSafepoint() {
   Thread* thread = Thread::Current();
-  return thread->IsMutatorThread() ||
-         thread->isolate()->thread_registry()->AtSafepoint();
+  return thread->IsMutatorThread() || thread->IsAtSafepoint();
 }
 #endif
 
@@ -3091,7 +3091,7 @@
   result.set_num_type_arguments(kUnknownNumTypeArguments);
   result.set_num_own_type_arguments(kUnknownNumTypeArguments);
   result.set_num_native_fields(0);
-  result.set_token_pos(Token::kNoSourcePos);
+  result.set_token_pos(TokenPosition::kNoSource);
   result.InitEmptyFields();
   Isolate::Current()->RegisterClass(result);
   return result.raw();
@@ -3100,7 +3100,7 @@
 
 RawClass* Class::New(const String& name,
                      const Script& script,
-                     intptr_t token_pos) {
+                     TokenPosition token_pos) {
   Class& result = Class::Handle(New<Instance>(kIllegalCid));
   result.set_name(name);
   result.set_script(script);
@@ -3114,7 +3114,7 @@
                                   int field_count) {
   Class& cls = Class::Handle(library.LookupClass(name));
   if (cls.IsNull()) {
-    cls = New(name, Script::Handle(), Token::kNoSourcePos);
+    cls = New(name, Script::Handle(), TokenPosition::kNoSource);
     cls.SetFields(Object::empty_array());
     cls.SetFunctions(Object::empty_array());
     // Set super class to Object.
@@ -3359,13 +3359,13 @@
 }
 
 
-void Class::set_token_pos(intptr_t token_pos) const {
-  ASSERT(!Token::IsClassifying(token_pos));
+void Class::set_token_pos(TokenPosition token_pos) const {
+  ASSERT(!token_pos.IsClassifying());
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
 
-intptr_t Class::ComputeEndTokenPos() const {
+TokenPosition Class::ComputeEndTokenPos() const {
   // Return the begin token for synthetic classes.
   if (IsMixinApplication() || IsTopLevel()) {
     return token_pos();
@@ -3373,8 +3373,9 @@
   const Script& scr = Script::Handle(script());
   ASSERT(!scr.IsNull());
   const TokenStream& tkns = TokenStream::Handle(scr.tokens());
-  TokenStream::Iterator tkit(
-      tkns, token_pos(), TokenStream::Iterator::kNoNewlines);
+  TokenStream::Iterator tkit(tkns,
+                             token_pos(),
+                             TokenStream::Iterator::kNoNewlines);
   intptr_t level = 0;
   while (tkit.CurrentTokenKind() != Token::kEOS) {
     if (tkit.CurrentTokenKind() == Token::kLBRACE) {
@@ -3387,7 +3388,7 @@
     tkit.Advance();
   }
   UNREACHABLE();
-  return 0;
+  return TokenPosition::kNoSource;
 }
 
 
@@ -4246,7 +4247,7 @@
 
 RawUnresolvedClass* UnresolvedClass::New(const LibraryPrefix& library_prefix,
                                          const String& ident,
-                                         intptr_t token_pos) {
+                                         TokenPosition token_pos) {
   const UnresolvedClass& type = UnresolvedClass::Handle(UnresolvedClass::New());
   type.set_library_prefix(library_prefix);
   type.set_ident(ident);
@@ -4264,8 +4265,8 @@
 }
 
 
-void UnresolvedClass::set_token_pos(intptr_t token_pos) const {
-  ASSERT(!Token::IsClassifying(token_pos));
+void UnresolvedClass::set_token_pos(TokenPosition token_pos) const {
+  ASSERT(!token_pos.IsClassifying());
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -5259,7 +5260,7 @@
 
 
 void Function::set_eval_script(const Script& script) const {
-  ASSERT(token_pos() == 0);
+  ASSERT(token_pos() == TokenPosition::kMinSource);
   ASSERT(raw_ptr()->data_ == Object::null());
   set_data(script);
 }
@@ -5409,7 +5410,7 @@
       scope_class = Isolate::Current()->object_store()->closure_class();
       if (IsSignatureFunction()) {
         set_owner(scope_class);
-        set_token_pos(Token::kNoSourcePos);
+        set_token_pos(TokenPosition::kNoSource);
       }
     }
     const TypeArguments& signature_type_arguments =
@@ -5701,8 +5702,8 @@
 }
 
 
-void Function::set_token_pos(intptr_t token_pos) const {
-  ASSERT(!Token::IsClassifying(token_pos) || IsMethodExtractor());
+void Function::set_token_pos(TokenPosition token_pos) const {
+  ASSERT(!token_pos.IsClassifying() || IsMethodExtractor());
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -5746,8 +5747,9 @@
     // Native methods don't need to be optimized.
     return false;
   }
+  const intptr_t function_length = end_token_pos().Pos() - token_pos().Pos();
   if (is_optimizable() && (script() != Script::null()) &&
-      ((end_token_pos() - token_pos()) < FLAG_huge_method_cutoff_in_tokens)) {
+      (function_length < FLAG_huge_method_cutoff_in_tokens)) {
     // Additional check needed for implicit getters.
     return (unoptimized_code() == Object::null()) ||
         (Code::Handle(unoptimized_code()).Size() <
@@ -6321,7 +6323,7 @@
                            bool is_external,
                            bool is_native,
                            const Object& owner,
-                           intptr_t token_pos) {
+                           TokenPosition token_pos) {
   ASSERT(!owner.IsNull());
   const Function& result = Function::Handle(Function::New());
   result.set_parameter_types(Object::empty_array());
@@ -6401,7 +6403,7 @@
 
 RawFunction* Function::NewClosureFunction(const String& name,
                                           const Function& parent,
-                                          intptr_t token_pos) {
+                                          TokenPosition token_pos) {
   ASSERT(!parent.IsNull());
   // Use the owner defining the parent function and not the class containing it.
   const Object& parent_owner = Object::Handle(parent.raw_ptr()->owner_);
@@ -6422,7 +6424,7 @@
 
 
 RawFunction* Function::NewSignatureFunction(const Class& owner,
-                                            intptr_t token_pos) {
+                                            TokenPosition token_pos) {
   const Function& result = Function::Handle(Function::New(
       Symbols::AnonymousSignature(),
       RawFunction::kSignatureFunction,
@@ -6452,7 +6454,7 @@
                     /* is_external = */ false,
                     /* is_native = */ false,
                     owner,
-                    /* token_pos = */ 0));
+                    TokenPosition::kMinSource));
   ASSERT(!script.IsNull());
   result.set_is_debuggable(false);
   result.set_is_visible(true);
@@ -6743,7 +6745,7 @@
 
 
 RawScript* Function::script() const {
-  if (token_pos() == 0) {
+  if (token_pos() == TokenPosition::kMinSource) {
     // Testing for position 0 is an optimization that relies on temporary
     // eval functions having token position 0.
     const Script& script = Script::Handle(eval_script());
@@ -6846,7 +6848,7 @@
   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() + 1);
+    return stream.GenerateSource(token_pos(), end_token_pos().Next());
   }
 
   const TokenStream::Iterator tkit(stream, end_token_pos());
@@ -7353,7 +7355,7 @@
                      bool is_reflectable,
                      const Class& owner,
                      const AbstractType& type,
-                     intptr_t token_pos) {
+                     TokenPosition token_pos) {
   ASSERT(!owner.IsNull());
   const Field& result = Field::Handle(Field::New());
   result.set_name(name);
@@ -7387,7 +7389,7 @@
                              bool is_final,
                              bool is_const,
                              const Object& owner,
-                             intptr_t token_pos) {
+                             TokenPosition token_pos) {
   ASSERT(!owner.IsNull());
   const Field& result = Field::Handle(Field::New());
   result.set_name(name);
@@ -7986,11 +7988,12 @@
 }
 
 RawString* TokenStream::GenerateSource() const {
-  return GenerateSource(0, kMaxElements);
+  return GenerateSource(TokenPosition::kMinSource,
+                        TokenPosition::kMaxSource);
 }
 
-RawString* TokenStream::GenerateSource(intptr_t start_pos,
-                                       intptr_t end_pos) const {
+RawString* TokenStream::GenerateSource(TokenPosition start_pos,
+                                       TokenPosition end_pos) const {
   Iterator iterator(*this, start_pos, Iterator::kAllTokens);
   const ExternalTypedData& data = ExternalTypedData::Handle(GetStream());
   const GrowableObjectArray& literals =
@@ -8164,14 +8167,15 @@
 }
 
 
-intptr_t TokenStream::ComputeSourcePosition(intptr_t tok_pos) const {
-  Iterator iterator(*this, 0, Iterator::kAllTokens);
-  intptr_t src_pos = 0;
+TokenPosition TokenStream::ComputeSourcePosition(
+    TokenPosition tok_pos) const {
+  Iterator iterator(*this, TokenPosition::kMinSource, Iterator::kAllTokens);
+  TokenPosition src_pos = TokenPosition::kMinSource;
   Token::Kind kind = iterator.CurrentTokenKind();
-  while (iterator.CurrentPosition() < tok_pos && kind != Token::kEOS) {
+  while ((iterator.CurrentPosition() < tok_pos) && (kind != Token::kEOS)) {
     iterator.Advance();
     kind = iterator.CurrentTokenKind();
-    src_pos += 1;
+    src_pos.Next();
   }
   return src_pos;
 }
@@ -8206,7 +8210,7 @@
 
 
 // CompressedTokenMap maps String and LiteralToken keys to Smi values.
-// It also supports lookup by Scanner::TokenDescriptor.
+// It also supports lookup by TokenDescriptor.
 class CompressedTokenTraits {
  public:
   static bool IsMatch(const Scanner::TokenDescriptor& descriptor,
@@ -8444,7 +8448,7 @@
 
 
 TokenStream::Iterator::Iterator(const TokenStream& tokens,
-                                intptr_t token_pos,
+                                TokenPosition token_pos,
                                 Iterator::StreamType stream_type)
     : tokens_(TokenStream::Handle(tokens.raw())),
       data_(ExternalTypedData::Handle(tokens.GetStream())),
@@ -8452,26 +8456,26 @@
       token_objects_(Array::Handle(
           GrowableObjectArray::Handle(tokens.TokenObjects()).data())),
       obj_(Object::Handle()),
-      cur_token_pos_(token_pos),
+      cur_token_pos_(token_pos.Pos()),
       cur_token_kind_(Token::kILLEGAL),
       cur_token_obj_index_(-1),
       stream_type_(stream_type) {
-  ASSERT(token_pos != Token::kNoSourcePos);
-  if (token_pos >= 0) {
+  ASSERT(token_pos != TokenPosition::kNoSource);
+  if (token_pos.IsReal()) {
     SetCurrentPosition(token_pos);
   }
 }
 
 
 void TokenStream::Iterator::SetStream(const TokenStream& tokens,
-                                      intptr_t token_pos) {
+                                      TokenPosition token_pos) {
   tokens_ = tokens.raw();
   data_ = tokens.GetStream();
   stream_.SetStream(reinterpret_cast<uint8_t*>(data_.DataAddr(0)),
                     data_.Length());
   token_objects_ = GrowableObjectArray::Handle(tokens.TokenObjects()).data();
   obj_ = Object::null();
-  cur_token_pos_ = token_pos;
+  cur_token_pos_ = token_pos.Pos();
   cur_token_kind_ = Token::kILLEGAL;
   cur_token_obj_index_ = -1;
   SetCurrentPosition(token_pos);
@@ -8513,13 +8517,13 @@
 }
 
 
-intptr_t TokenStream::Iterator::CurrentPosition() const {
-  return cur_token_pos_;
+TokenPosition TokenStream::Iterator::CurrentPosition() const {
+  return TokenPosition(cur_token_pos_);
 }
 
 
-void TokenStream::Iterator::SetCurrentPosition(intptr_t value) {
-  stream_.SetPosition(value);
+void TokenStream::Iterator::SetCurrentPosition(TokenPosition token_pos) {
+  stream_.SetPosition(token_pos.value());
   Advance();
 }
 
@@ -8617,7 +8621,9 @@
   Smi& value = Smi::Handle(zone);
   String& tokenValue = String::Handle(zone);
   ASSERT(!tkns.IsNull());
-  TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
+  TokenStream::Iterator tkit(tkns,
+                             TokenPosition::kMinSource,
+                             TokenStream::Iterator::kAllTokens);
   int current_line = -1;
   Scanner s(source, key);
   s.Scan();
@@ -8672,7 +8678,7 @@
     // TODO(hausner): Could optimize here by not reporting tokens
     // that will never be a location used by the debugger, e.g.
     // braces, semicolons, most keywords etc.
-    value = Smi::New(tkit.CurrentPosition());
+    value = Smi::New(tkit.CurrentPosition().Pos());
     info.Add(value);
     int column = s.current_token().position.column;
     // On the first line of the script we must add the column offset.
@@ -8759,7 +8765,7 @@
 }
 
 
-void Script::GetTokenLocation(intptr_t token_pos,
+void Script::GetTokenLocation(TokenPosition token_pos,
                               intptr_t* line,
                               intptr_t* column,
                               intptr_t* token_len) const {
@@ -8777,10 +8783,12 @@
     return;
   }
   if (column == NULL) {
-    TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
+    TokenStream::Iterator tkit(tkns,
+                               TokenPosition::kMinSource,
+                               TokenStream::Iterator::kAllTokens);
     intptr_t cur_line = line_offset() + 1;
-    while (tkit.CurrentPosition() < token_pos &&
-           tkit.CurrentTokenKind() != Token::kEOS) {
+    while ((tkit.CurrentPosition() < token_pos) &&
+           (tkit.CurrentTokenKind() != Token::kEOS)) {
       if (tkit.CurrentTokenKind() == Token::kNEWLINE) {
         cur_line++;
       }
@@ -8789,7 +8797,7 @@
     *line = cur_line;
   } else {
     const String& src = String::Handle(Source());
-    intptr_t src_pos = tkns.ComputeSourcePosition(token_pos);
+    TokenPosition src_pos = tkns.ComputeSourcePosition(token_pos);
     Scanner scanner(src, Symbols::Empty());
     scanner.ScanTo(src_pos);
     intptr_t relative_line = scanner.CurrentPosition().line;
@@ -8811,16 +8819,18 @@
 
 
 void Script::TokenRangeAtLine(intptr_t line_number,
-                              intptr_t* first_token_index,
-                              intptr_t* last_token_index) const {
+                              TokenPosition* first_token_index,
+                              TokenPosition* last_token_index) const {
   ASSERT(first_token_index != NULL && last_token_index != NULL);
   ASSERT(line_number > 0);
-  *first_token_index = -1;
-  *last_token_index = -1;
+  *first_token_index = TokenPosition::kNoSource;
+  *last_token_index = TokenPosition::kNoSource;
   const TokenStream& tkns = TokenStream::Handle(tokens());
   line_number -= line_offset();
   if (line_number < 1) line_number = 1;
-  TokenStream::Iterator tkit(tkns, 0, TokenStream::Iterator::kAllTokens);
+  TokenStream::Iterator tkit(tkns,
+                             TokenPosition::kMinSource,
+                             TokenStream::Iterator::kAllTokens);
   // Scan through the token stream to the required line.
   intptr_t cur_line = 1;
   while (cur_line < line_number && tkit.CurrentTokenKind() != Token::kEOS) {
@@ -8848,7 +8858,7 @@
   *first_token_index = tkit.CurrentPosition();
   // We cannot do "CurrentPosition() - 1" for the last token, because we do not
   // know whether the previous token is a simple one or not.
-  intptr_t end_pos = *first_token_index;
+  TokenPosition end_pos = *first_token_index;
   while (tkit.CurrentTokenKind() != Token::kNEWLINE &&
          tkit.CurrentTokenKind() != Token::kEOS) {
     end_pos = tkit.CurrentPosition();
@@ -9151,7 +9161,7 @@
   const String& url = String::Handle(lib.url());
   Report::MessageF(Report::kError,
                    Script::Handle(lib.LookupScript(url)),
-                   Token::kNoSourcePos,
+                   TokenPosition::kNoSource,
                    Report::AtLocation,
                    "too many imports in library '%s'",
                    url.ToCString());
@@ -9338,7 +9348,7 @@
 
 void Library::AddMetadata(const Object& owner,
                           const String& name,
-                          intptr_t token_pos) const {
+                          TokenPosition token_pos) const {
   const String& metaname = String::Handle(Symbols::New(name));
   const Field& field = Field::Handle(
       Field::NewTopLevel(metaname,
@@ -9357,7 +9367,7 @@
 
 void Library::AddClassMetadata(const Class& cls,
                                const Object& tl_owner,
-                               intptr_t token_pos) const {
+                               TokenPosition token_pos) const {
   // We use the toplevel class as the owner of a class's metadata field because
   // a class's metadata is in scope of the library, not the class.
   AddMetadata(tl_owner,
@@ -9367,7 +9377,7 @@
 
 
 void Library::AddFieldMetadata(const Field& field,
-                               intptr_t token_pos) const {
+                               TokenPosition token_pos) const {
   AddMetadata(Object::Handle(field.RawOwner()),
               String::Handle(MakeFieldMetaName(field)),
               token_pos);
@@ -9375,7 +9385,7 @@
 
 
 void Library::AddFunctionMetadata(const Function& func,
-                                  intptr_t token_pos) const {
+                                  TokenPosition token_pos) const {
   AddMetadata(Object::Handle(func.RawOwner()),
               String::Handle(MakeFunctionMetaName(func)),
               token_pos);
@@ -9383,7 +9393,7 @@
 
 
 void Library::AddTypeParameterMetadata(const TypeParameter& param,
-                                       intptr_t token_pos) const {
+                                       TokenPosition token_pos) const {
   AddMetadata(Class::Handle(param.parameterized_class()),
               String::Handle(MakeTypeParameterMetaName(param)),
               token_pos);
@@ -9391,7 +9401,7 @@
 
 
 void Library::AddLibraryMetadata(const Object& tl_owner,
-                                 intptr_t token_pos) const {
+                                 TokenPosition token_pos) const {
   AddMetadata(tl_owner, Symbols::TopLevel(), token_pos);
 }
 
@@ -10692,7 +10702,6 @@
   } else if (deferred_lib.LoadNotStarted()) {
     Thread* thread = Thread::Current();
     Isolate* isolate = thread->isolate();
-    Api::Scope api_scope(thread);
     Zone* zone = thread->zone();
     deferred_lib.SetLoadRequested();
     const GrowableObjectArray& pending_deferred_loads =
@@ -10701,9 +10710,13 @@
     pending_deferred_loads.Add(deferred_lib);
     const String& lib_url = String::Handle(zone, deferred_lib.url());
     Dart_LibraryTagHandler handler = isolate->library_tag_handler();
-    handler(Dart_kImportTag,
-            Api::NewHandle(thread, importer()),
-            Api::NewHandle(thread, lib_url.raw()));
+    {
+      TransitionVMToNative transition(thread);
+      Api::Scope api_scope(thread);
+      handler(Dart_kImportTag,
+              Api::NewHandle(thread, importer()),
+              Api::NewHandle(thread, lib_url.raw()));
+    }
   } else {
     // Another load request is in flight.
     ASSERT(deferred_lib.LoadRequested());
@@ -10840,7 +10853,7 @@
 }
 
 
-void Namespace::AddMetadata(const Object& owner, intptr_t token_pos) {
+void Namespace::AddMetadata(const Object& owner, TokenPosition token_pos) {
   ASSERT(Field::Handle(metadata_field()).IsNull());
   Field& field = Field::Handle(Field::NewTopLevel(Symbols::TopLevel(),
                                           false,  // is_final
@@ -11409,7 +11422,7 @@
 const char* PcDescriptors::ToCString() const {
   // "*" in a printf format specifier tells it to read the field width from
   // the printf argument list.
-#define FORMAT "%#-*" Px "\t%s\t%" Pd "\t\t%" Pd "\t%" Pd "\n"
+#define FORMAT "%#-*" Px "\t%s\t%" Pd "\t\t%s\t%" Pd "\n"
   if (Length() == 0) {
     return "empty PcDescriptors\n";
   }
@@ -11424,7 +11437,7 @@
                          iter.PcOffset(),
                          KindAsStr(iter.Kind()),
                          iter.DeoptId(),
-                         iter.TokenPos(),
+                         iter.TokenPos().ToCString(),
                          iter.TryIndex());
     }
   }
@@ -11438,7 +11451,7 @@
                          iter.PcOffset(),
                          KindAsStr(iter.Kind()),
                          iter.DeoptId(),
-                         iter.TokenPos(),
+                         iter.TokenPos().ToCString(),
                          iter.TryIndex());
   }
   return buffer;
@@ -11580,7 +11593,7 @@
 const char* CodeSourceMap::ToCString() const {
   // "*" in a printf format specifier tells it to read the field width from
   // the printf argument list.
-#define FORMAT "%#-*" Px "\t%" Pd "\n"
+#define FORMAT "%#-*" Px "\t%s\n"
   if (Length() == 0) {
     return "empty CodeSourceMap\n";
   }
@@ -11593,7 +11606,7 @@
     while (iter.MoveNext()) {
       len += OS::SNPrint(NULL, 0, FORMAT, addr_width,
                          iter.PcOffset(),
-                         iter.TokenPos());
+                         iter.TokenPos().ToCString());
     }
   }
   // Allocate the buffer.
@@ -11604,7 +11617,7 @@
   while (iter.MoveNext()) {
     index += OS::SNPrint((buffer + index), (len - index), FORMAT, addr_width,
                          iter.PcOffset(),
-                         iter.TokenPos());
+                         iter.TokenPos().ToCString());
   }
   return buffer;
 #undef FORMAT
@@ -11794,8 +11807,8 @@
                        LocalVarDescriptors::KindToCString(kind),
                        index,
                        info.scope_id,
-                       info.begin_pos,
-                       info.end_pos);
+                       static_cast<int>(info.begin_pos.Pos()),
+                       static_cast<int>(info.end_pos.Pos()));
   } else if (kind == RawLocalVarDescriptors::kContextVar) {
     return OS::SNPrint(buffer, len,
                        "%2" Pd " %-13s level=%-3d index=%-3d"
@@ -11804,8 +11817,8 @@
                        LocalVarDescriptors::KindToCString(kind),
                        info.scope_id,
                        index,
-                       info.begin_pos,
-                       info.end_pos,
+                       static_cast<int>(info.begin_pos.Pos()),
+                       static_cast<int>(info.end_pos.Pos()),
                        var_name.ToCString());
   } else {
     return OS::SNPrint(buffer, len,
@@ -11815,8 +11828,8 @@
                        LocalVarDescriptors::KindToCString(kind),
                        info.scope_id,
                        index,
-                       info.begin_pos,
-                       info.end_pos,
+                       static_cast<int>(info.begin_pos.Pos()),
+                       static_cast<int>(info.end_pos.Pos()),
                        var_name.ToCString());
   }
 }
@@ -11871,8 +11884,8 @@
     JSONObject var(&members);
     var.AddProperty("name", var_name.ToCString());
     var.AddProperty("index", static_cast<intptr_t>(info.index()));
-    var.AddProperty("beginPos", static_cast<intptr_t>(info.begin_pos));
-    var.AddProperty("endPos", static_cast<intptr_t>(info.end_pos));
+    var.AddProperty("beginPos", info.begin_pos);
+    var.AddProperty("endPos", info.end_pos);
     var.AddProperty("scopeId", static_cast<intptr_t>(info.scope_id));
     var.AddProperty("kind", KindToCString(info.kind()));
   }
@@ -12949,7 +12962,7 @@
 
 
 void ICData::PrintToJSONArray(const JSONArray& jsarray,
-                              intptr_t token_pos,
+                              TokenPosition token_pos,
                               bool is_static_call) const {
   Isolate* isolate = Isolate::Current();
   Class& cls = Class::Handle();
@@ -12985,7 +12998,7 @@
 
 
 void ICData::PrintToJSONArrayNew(const JSONArray& jsarray,
-                                 intptr_t token_pos,
+                                 TokenPosition token_pos,
                                  bool is_static_call) const {
   Isolate* isolate = Isolate::Current();
   Class& cls = Class::Handle();
@@ -12993,7 +13006,7 @@
 
   JSONObject jsobj(&jsarray);
   jsobj.AddProperty("name", String::Handle(target_name()).ToCString());
-  jsobj.AddProperty("tokenPos", token_pos);
+  jsobj.AddProperty("tokenPos", token_pos.value());
   // TODO(rmacnak): Figure out how to stringify DeoptReasons().
   // jsobj.AddProperty("deoptReasons", ...);
 
@@ -13613,7 +13626,7 @@
 }
 
 
-intptr_t Code::GetTokenIndexOfPC(uword pc) const {
+TokenPosition Code::GetTokenIndexOfPC(uword pc) const {
   uword pc_offset = pc - EntryPoint();
   const PcDescriptors& descriptors = PcDescriptors::Handle(pc_descriptors());
   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
@@ -13622,7 +13635,7 @@
       return iter.TokenPos();
     }
   }
-  return -1;
+  return TokenPosition::kNoSource;
 }
 
 
@@ -14120,15 +14133,15 @@
 }
 
 
-intptr_t ContextScope::TokenIndexAt(intptr_t scope_index) const {
-  return Smi::Value(VariableDescAddr(scope_index)->token_pos);
+TokenPosition ContextScope::TokenIndexAt(intptr_t scope_index) const {
+  return TokenPosition(Smi::Value(VariableDescAddr(scope_index)->token_pos));
 }
 
 
 void ContextScope::SetTokenIndexAt(intptr_t scope_index,
-                                   intptr_t token_pos) const {
+                                   TokenPosition token_pos) const {
   StoreSmi(&VariableDescAddr(scope_index)->token_pos,
-           Smi::New(token_pos));
+           Smi::New(token_pos.value()));
 }
 
 
@@ -14219,12 +14232,12 @@
   for (int i = 0; i < num_variables(); i++) {
     name = NameAt(i);
     const char* cname = name.ToCString();
-    intptr_t pos = TokenIndexAt(i);
+    TokenPosition pos = TokenIndexAt(i);
     intptr_t idx = ContextIndexAt(i);
     intptr_t lvl = ContextLevelAt(i);
     char* chars = OS::SCreate(Thread::Current()->zone(),
-        "%s\nvar %s  token-pos %" Pd "  ctx lvl %" Pd "  index %" Pd "",
-        prev_cstr, cname, pos, lvl, idx);
+        "%s\nvar %s  token-pos %s  ctx lvl %" Pd "  index %" Pd "",
+        prev_cstr, cname, pos.ToCString(), lvl, idx);
     prev_cstr = chars;
   }
   return prev_cstr;
@@ -14545,7 +14558,7 @@
 
 RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error,
                                                const Script& script,
-                                               intptr_t token_pos,
+                                               TokenPosition token_pos,
                                                bool report_after_token,
                                                Report::Kind kind,
                                                Heap::Space space,
@@ -14573,7 +14586,7 @@
 
 RawLanguageError* LanguageError::NewFormatted(const Error& prev_error,
                                               const Script& script,
-                                              intptr_t token_pos,
+                                              TokenPosition token_pos,
                                               bool report_after_token,
                                               Report::Kind kind,
                                               Heap::Space space,
@@ -14617,8 +14630,8 @@
 }
 
 
-void LanguageError::set_token_pos(intptr_t token_pos) const {
-  ASSERT(!Token::IsClassifying(token_pos));
+void LanguageError::set_token_pos(TokenPosition token_pos) const {
+  ASSERT(!token_pos.IsClassifying());
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -15029,7 +15042,7 @@
     ASSERT(scope_cls.NumTypeArguments() > 0);
     TypeArguments& type_arguments = TypeArguments::Handle(GetTypeArguments());
     type = FunctionType::New(
-        scope_cls, type_arguments, signature, Token::kNoSourcePos);
+        scope_cls, type_arguments, signature, TokenPosition::kNoSource);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
     return type.raw();
@@ -15043,7 +15056,7 @@
     if (cls.NumTypeArguments() > 0) {
       type_arguments = GetTypeArguments();
     }
-    type = Type::New(cls, type_arguments, Token::kNoSourcePos);
+    type = Type::New(cls, type_arguments, TokenPosition::kNoSource);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
   }
@@ -15370,8 +15383,8 @@
     if (num_type_arguments > 0) {
       type_arguments = GetTypeArguments();
     }
-    const Type& type =
-        Type::Handle(Type::New(cls, type_arguments, Token::kNoSourcePos));
+    const Type& type = Type::Handle(
+        Type::New(cls, type_arguments, TokenPosition::kNoSource));
     const String& type_name = String::Handle(type.UserVisibleName());
     return OS::SCreate(Thread::Current()->zone(),
         "Instance of '%s'", type_name.ToCString());
@@ -15510,10 +15523,10 @@
   UNREACHABLE();
 }
 
-intptr_t AbstractType::token_pos() const {
+TokenPosition AbstractType::token_pos() const {
   // AbstractType is an abstract class.
   UNREACHABLE();
-  return -1;
+  return TokenPosition::kNoSource;
 }
 
 
@@ -15707,9 +15720,10 @@
   Class& cls = Class::Handle(zone);
   if (IsFunctionType()) {
     cls = type_class();
-    if (!cls.IsTypedefClass()) {
-      const Function& signature_function = Function::Handle(
-          zone, FunctionType::Cast(*this).signature());
+    const Function& signature_function = Function::Handle(
+        zone, FunctionType::Cast(*this).signature());
+    if (!cls.IsTypedefClass() ||
+        (cls.signature_function() != signature_function.raw())) {
       if (!IsFinalized() || IsBeingFinalized() || IsMalformed()) {
         return signature_function.UserVisibleSignature();
       }
@@ -16106,7 +16120,7 @@
     const TypeArguments& no_type_arguments = TypeArguments::Handle();
     type ^= Type::New(Object::Handle(type_class.raw()),
                       no_type_arguments,
-                      Token::kNoSourcePos);
+                      TokenPosition::kNoSource);
     type.SetIsFinalized();
     type ^= type.Canonicalize();
   }
@@ -16564,7 +16578,7 @@
 
 RawType* Type::New(const Object& clazz,
                    const TypeArguments& arguments,
-                   intptr_t token_pos,
+                   TokenPosition token_pos,
                    Heap::Space space) {
   const Type& result = Type::Handle(Type::New(space));
   result.set_type_class(clazz);
@@ -16575,8 +16589,8 @@
 }
 
 
-void Type::set_token_pos(intptr_t token_pos) const {
-  ASSERT(!Token::IsClassifying(token_pos));
+void Type::set_token_pos(TokenPosition token_pos) const {
+  ASSERT(!token_pos.IsClassifying());
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -16994,10 +17008,8 @@
   // Replace the actual function by a signature function.
   const Function& fun = Function::Handle(zone, signature());
   if (!fun.IsSignatureFunction()) {
-    Function& sig_fun =
-        Function::Handle(zone,
-                         Function::NewSignatureFunction(scope_cls,
-                                                        Token::kNoSourcePos));
+    Function& sig_fun = Function::Handle(zone,
+        Function::NewSignatureFunction(scope_cls, TokenPosition::kNoSource));
     type = fun.result_type();
     type = type.Canonicalize(trail);
     sig_fun.set_result_type(type);
@@ -17108,7 +17120,7 @@
 RawFunctionType* FunctionType::New(const Class& clazz,
                                    const TypeArguments& arguments,
                                    const Function& signature,
-                                   intptr_t token_pos,
+                                   TokenPosition token_pos,
                                    Heap::Space space) {
   const FunctionType& result = FunctionType::Handle(FunctionType::New(space));
   result.set_scope_class(clazz);
@@ -17121,8 +17133,8 @@
 }
 
 
-void FunctionType::set_token_pos(intptr_t token_pos) const {
-  ASSERT(!Token::IsClassifying(token_pos));
+void FunctionType::set_token_pos(TokenPosition token_pos) const {
+  ASSERT(!token_pos.IsClassifying());
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -17139,9 +17151,11 @@
   const Class& scope_cls = Class::Handle(scope_class());
   const TypeArguments& type_arguments = TypeArguments::Handle(arguments());
   const Function& signature_function = Function::Handle(signature());
-  const String& signature_string = String::Handle(
-      signature_function.InstantiatedSignatureFrom(type_arguments,
-                                                   kInternalName));
+  const String& signature_string = IsFinalized() ?
+      String::Handle(
+          signature_function.InstantiatedSignatureFrom(type_arguments,
+                                                       kInternalName)) :
+      String::Handle(signature_function.Signature());
   if (scope_cls.IsClosureClass()) {
     ASSERT(arguments() == TypeArguments::null());
     return OS::SCreate(
@@ -17540,7 +17554,7 @@
                                      intptr_t index,
                                      const String& name,
                                      const AbstractType& bound,
-                                     intptr_t token_pos) {
+                                     TokenPosition token_pos) {
   const TypeParameter& result = TypeParameter::Handle(TypeParameter::New());
   result.set_parameterized_class(parameterized_class);
   result.set_index(index);
@@ -17553,8 +17567,8 @@
 }
 
 
-void TypeParameter::set_token_pos(intptr_t token_pos) const {
-  ASSERT(!Token::IsClassifying(token_pos));
+void TypeParameter::set_token_pos(TokenPosition token_pos) const {
+  ASSERT(!token_pos.IsClassifying());
   StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
 }
 
@@ -17831,7 +17845,7 @@
 }
 
 
-intptr_t MixinAppType::token_pos() const {
+TokenPosition MixinAppType::token_pos() const {
   return AbstractType::Handle(MixinTypeAt(0)).token_pos();
 }
 
@@ -17980,7 +17994,7 @@
   const bool is_smi = Smi::IsValid(value);
   if (!silent &&
       FLAG_throw_on_javascript_int_overflow &&
-      !Utils::IsJavascriptInt64(value)) {
+      !Utils::IsJavascriptInt(value)) {
     const Integer& i = is_smi ?
         Integer::Handle(Smi::New(static_cast<intptr_t>(value))) :
         Integer::Handle(Mint::New(value, space));
@@ -18078,7 +18092,7 @@
       value = AsInt64Value();
     }
   }
-  return !Utils::IsJavascriptInt64(value);
+  return !Utils::IsJavascriptInt(value);
 }
 
 
@@ -18100,7 +18114,9 @@
   if (Bigint::Cast(*this).FitsIntoInt64()) {
     const int64_t value = AsInt64Value();
     if (Smi::IsValid(value)) {
-      return Smi::New(value);
+      // This cast is safe because Smi::IsValid verifies that value will fit.
+      intptr_t val = static_cast<intptr_t>(value);
+      return Smi::New(val);
     }
     return Mint::New(value);
   }
@@ -20207,15 +20223,27 @@
   PrintSharedInstanceJSON(&jsobj, ref);
   jsobj.AddProperty("kind", "String");
   jsobj.AddServiceId(*this);
+  jsobj.AddProperty("length", Length());
   if (ref) {
-    bool did_truncate = jsobj.AddPropertyStr("valueAsString", *this, 128);
-    if (did_truncate) {
-      jsobj.AddProperty("valueAsStringIsTruncated", did_truncate);
+    // String refs always truncate to a fixed count;
+    const intptr_t kFixedCount = 128;
+    if (jsobj.AddPropertyStr("valueAsString", *this, 0, kFixedCount)) {
+      jsobj.AddProperty("count", kFixedCount);
+      jsobj.AddProperty("valueAsStringIsTruncated", true);
     }
-  } else {
-    bool did_truncate = jsobj.AddPropertyStr("valueAsString", *this);
-    ASSERT(!did_truncate);
+    return;
   }
+
+  intptr_t offset;
+  intptr_t count;
+  stream->ComputeOffsetAndCount(Length(), &offset, &count);
+  if (offset > 0) {
+    jsobj.AddProperty("offset", offset);
+  }
+  if (count < Length()) {
+    jsobj.AddProperty("count", count);
+  }
+  jsobj.AddPropertyStr("valueAsString", *this, offset, count);
 }
 
 
@@ -22329,14 +22357,14 @@
                                    const Function& function,
                                    const Code& code,
                                    intptr_t frame_index) {
-  const intptr_t token_pos = code.GetTokenIndexOfPC(pc);
+  const TokenPosition token_pos = code.GetTokenIndexOfPC(pc);
   const Script& script = Script::Handle(zone, function.script());
   const String& function_name =
       String::Handle(zone, function.QualifiedUserVisibleName());
   const String& url = String::Handle(zone, script.url());
   intptr_t line = -1;
   intptr_t column = -1;
-  if (token_pos >= 0) {
+  if (token_pos.IsReal()) {
     if (script.HasSource()) {
       script.GetTokenLocation(token_pos, &line, &column);
     } else {
@@ -22408,7 +22436,7 @@
       uword pc = code.EntryPoint() + Smi::Value(PcOffsetAtFrame(i));
       if (code.is_optimized() && expand_inlined()) {
         // Traverse inlined frames.
-        if (Compiler::allow_recompilation()) {
+        if (!FLAG_precompilation) {
           for (InlinedFunctionsIterator it(code, pc);
                !it.Done() && (*frame_index < max_frames); it.Advance()) {
             function = it.function();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 5ce318c..a78a0f4 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -23,6 +23,7 @@
 #include "vm/scanner.h"
 #include "vm/tags.h"
 #include "vm/thread.h"
+#include "vm/token_position.h"
 #include "vm/verified_memory.h"
 
 namespace dart {
@@ -938,10 +939,10 @@
   RawScript* script() const { return raw_ptr()->script_; }
   void set_script(const Script& value) const;
 
-  intptr_t token_pos() const { return raw_ptr()->token_pos_; }
-  void set_token_pos(intptr_t value) const;
+  TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
+  void set_token_pos(TokenPosition value) const;
 
-  intptr_t ComputeEndTokenPos() const;
+  TokenPosition ComputeEndTokenPos() const;
 
   // This class represents a typedef if the signature function is not null.
   RawFunction* signature_function() const {
@@ -1306,7 +1307,7 @@
   // Allocate instance classes.
   static RawClass* New(const String& name,
                        const Script& script,
-                       intptr_t token_pos);
+                       TokenPosition token_pos);
   static RawClass* NewNativeWrapper(const Library& library,
                                     const String& name,
                                     int num_fields);
@@ -1361,22 +1362,29 @@
     kEnumBit = 13,
     kIsAllocatedBit = 15,
   };
-  class ConstBit : public BitField<bool, kConstBit, 1> {};
-  class ImplementedBit : public BitField<bool, kImplementedBit, 1> {};
-  class TypeFinalizedBit : public BitField<bool, kTypeFinalizedBit, 1> {};
-  class ClassFinalizedBits : public BitField<RawClass::ClassFinalizedState,
-      kClassFinalizedPos, kClassFinalizedSize> {};  // NOLINT
-  class AbstractBit : public BitField<bool, kAbstractBit, 1> {};
-  class PatchBit : public BitField<bool, kPatchBit, 1> {};
-  class SynthesizedClassBit : public BitField<bool, kSynthesizedClassBit, 1> {};
-  class MarkedForParsingBit : public BitField<bool, kMarkedForParsingBit, 1> {};
-  class MixinAppAliasBit : public BitField<bool, kMixinAppAliasBit, 1> {};
-  class MixinTypeAppliedBit : public BitField<bool, kMixinTypeAppliedBit, 1> {};
-  class FieldsMarkedNullableBit : public BitField<bool,
-      kFieldsMarkedNullableBit, 1> {};  // NOLINT
-  class CycleFreeBit : public BitField<bool, kCycleFreeBit, 1> {};
-  class EnumBit : public BitField<bool, kEnumBit, 1> {};
-  class IsAllocatedBit : public BitField<bool, kIsAllocatedBit, 1> {};
+  class ConstBit : public BitField<uint16_t, bool, kConstBit, 1> {};
+  class ImplementedBit : public BitField<uint16_t, bool, kImplementedBit, 1> {};
+  class TypeFinalizedBit :
+      public BitField<uint16_t, bool, kTypeFinalizedBit, 1> {};
+  class ClassFinalizedBits : public BitField<uint16_t,
+                                             RawClass::ClassFinalizedState,
+                                             kClassFinalizedPos,
+                                             kClassFinalizedSize> {};
+  class AbstractBit : public BitField<uint16_t, bool, kAbstractBit, 1> {};
+  class PatchBit : public BitField<uint16_t, bool, kPatchBit, 1> {};
+  class SynthesizedClassBit :
+      public BitField<uint16_t, bool, kSynthesizedClassBit, 1> {};
+  class MarkedForParsingBit :
+      public BitField<uint16_t, bool, kMarkedForParsingBit, 1> {};
+  class MixinAppAliasBit :
+      public BitField<uint16_t, bool, kMixinAppAliasBit, 1> {};
+  class MixinTypeAppliedBit :
+      public BitField<uint16_t, bool, kMixinTypeAppliedBit, 1> {};
+  class FieldsMarkedNullableBit :
+      public BitField<uint16_t, bool, kFieldsMarkedNullableBit, 1> {};
+  class CycleFreeBit : public BitField<uint16_t, bool, kCycleFreeBit, 1> {};
+  class EnumBit : public BitField<uint16_t, bool, kEnumBit, 1> {};
+  class IsAllocatedBit : public BitField<uint16_t, bool, kIsAllocatedBit, 1> {};
 
   void set_name(const String& value) const;
   void set_pretty_name(const String& value) const;
@@ -1469,7 +1477,7 @@
     return raw_ptr()->library_prefix_;
   }
   RawString* ident() const { return raw_ptr()->ident_; }
-  intptr_t token_pos() const { return raw_ptr()->token_pos_; }
+  TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
 
   RawString* Name() const;
 
@@ -1479,12 +1487,12 @@
 
   static RawUnresolvedClass* New(const LibraryPrefix& library_prefix,
                                  const String& ident,
-                                 intptr_t token_pos);
+                                 TokenPosition token_pos);
 
  private:
   void set_library_prefix(const LibraryPrefix& library_prefix) const;
   void set_ident(const String& ident) const;
-  void set_token_pos(intptr_t token_pos) const;
+  void set_token_pos(TokenPosition token_pos) const;
 
   static RawUnresolvedClass* New();
 
@@ -1997,10 +2005,10 @@
   RangeFeedback DecodeRangeFeedbackAt(intptr_t idx) const;
 
   void PrintToJSONArray(const JSONArray& jsarray,
-                        intptr_t token_pos,
+                        TokenPosition token_pos,
                         bool is_static_call) const;
   void PrintToJSONArrayNew(const JSONArray& jsarray,
-                           intptr_t token_pos,
+                           TokenPosition token_pos,
                            bool is_static_call) const;
 
   // Initialize the preallocated empty ICData entry arrays.
@@ -2036,12 +2044,19 @@
   };
 
   class NumArgsTestedBits : public BitField<uint32_t,
-      kNumArgsTestedPos, kNumArgsTestedSize> {};  // NOLINT
+                                            uint32_t,
+                                            kNumArgsTestedPos,
+                                            kNumArgsTestedSize> {};
   class DeoptReasonBits : public BitField<uint32_t,
-      ICData::kDeoptReasonPos, ICData::kDeoptReasonSize> {};  // NOLINT
-  class IssuedJSWarningBit : public BitField<bool, kIssuedJSWarningBit, 1> {};
+                                          uint32_t,
+                                          ICData::kDeoptReasonPos,
+                                          ICData::kDeoptReasonSize> {};
+  class IssuedJSWarningBit :
+      public BitField<uint32_t, bool, kIssuedJSWarningBit, 1> {};
   class RangeFeedbackBits : public BitField<uint32_t,
-      ICData::kRangeFeedbackPos, ICData::kRangeFeedbackSize> {};  // NOLINT
+                                            uint32_t,
+                                            ICData::kRangeFeedbackPos,
+                                            ICData::kRangeFeedbackSize> {};
 
 #if defined(DEBUG)
   // Used in asserts to verify that a check is not added twice.
@@ -2312,11 +2327,11 @@
   }
   bool IsInFactoryScope() const;
 
-  intptr_t token_pos() const { return raw_ptr()->token_pos_; }
-  void set_token_pos(intptr_t value) const;
+  TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
+  void set_token_pos(TokenPosition value) const;
 
-  intptr_t end_token_pos() const { return raw_ptr()->end_token_pos_; }
-  void set_end_token_pos(intptr_t value) const {
+  TokenPosition end_token_pos() const { return raw_ptr()->end_token_pos_; }
+  void set_end_token_pos(TokenPosition value) const {
     StoreNonPointer(&raw_ptr()->end_token_pos_, value);
   }
 
@@ -2604,17 +2619,17 @@
                           bool is_external,
                           bool is_native,
                           const Object& owner,
-                          intptr_t token_pos);
+                          TokenPosition token_pos);
 
   // Allocates a new Function object representing a closure function.
   static RawFunction* NewClosureFunction(const String& name,
                                          const Function& parent,
-                                         intptr_t token_pos);
+                                         TokenPosition token_pos);
 
   // Allocates a new Function object representing a signature function.
   // The owner is the scope class of the function type.
   static RawFunction* NewSignatureFunction(const Class& owner,
-                                           intptr_t token_pos);
+                                           TokenPosition token_pos);
 
   static RawFunction* NewEvalFunction(const Class& owner,
                                       const Script& script,
@@ -2731,18 +2746,19 @@
       (kBitsPerByte * sizeof(static_cast<RawFunction*>(0)->kind_tag_)));
 
   class KindBits :
-    public BitField<RawFunction::Kind, kKindTagPos, kKindTagSize> {};  // NOLINT
+    public BitField<uint32_t, RawFunction::Kind, kKindTagPos, kKindTagSize> {};
 
-  class RecognizedBits : public BitField<MethodRecognizer::Kind,
+  class RecognizedBits : public BitField<uint32_t,
+                                         MethodRecognizer::Kind,
                                          kRecognizedTagPos,
                                          kRecognizedTagSize> {};
-  class ModifierBits :
-    public BitField<RawFunction::AsyncModifier,
-                   kModifierPos,
-                   kModifierSize> {};  // NOLINT
+  class ModifierBits : public BitField<uint32_t,
+                                       RawFunction::AsyncModifier,
+                                       kModifierPos,
+                                       kModifierSize> {};
 
 #define DEFINE_BIT(name, _) \
-  class name##Bit : public BitField<bool, k##name##Bit, 1> {};
+  class name##Bit : public BitField<uint32_t, bool, k##name##Bit, 1> {};
 FOR_EACH_FUNCTION_KIND_BIT(DEFINE_BIT)
 #undef DEFINE_BIT
 
@@ -2907,13 +2923,13 @@
                        bool is_reflectable,
                        const Class& owner,
                        const AbstractType& type,
-                       intptr_t token_pos);
+                       TokenPosition token_pos);
 
   static RawField* NewTopLevel(const String& name,
                                bool is_final,
                                bool is_const,
                                const Object& owner,
-                               intptr_t token_pos);
+                               TokenPosition token_pos);
 
   // Allocate new field object, clone values from this field. The
   // owner of the clone is new_owner.
@@ -2928,7 +2944,7 @@
 
   static intptr_t kind_bits_offset() { return OFFSET_OF(RawField, kind_bits_); }
 
-  intptr_t token_pos() const { return raw_ptr()->token_pos_; }
+  TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
 
   bool has_initializer() const {
     return HasInitializerBit::decode(raw_ptr()->kind_bits_);
@@ -3079,15 +3095,16 @@
     kReflectableBit,
     kDoubleInitializedBit,
   };
-  class ConstBit : public BitField<bool, kConstBit, 1> {};
-  class StaticBit : public BitField<bool, kStaticBit, 1> {};
-  class FinalBit : public BitField<bool, kFinalBit, 1> {};
-  class HasInitializerBit : public BitField<bool, kHasInitializerBit, 1> {};
-  class UnboxingCandidateBit : public BitField<bool,
-                                               kUnboxingCandidateBit, 1> {};
-  class ReflectableBit : public BitField<bool, kReflectableBit, 1> {};
-  class DoubleInitializedBit : public BitField<bool,
-                                               kDoubleInitializedBit, 1> {};
+  class ConstBit : public BitField<uint8_t, bool, kConstBit, 1> {};
+  class StaticBit : public BitField<uint8_t, bool, kStaticBit, 1> {};
+  class FinalBit : public BitField<uint8_t, bool, kFinalBit, 1> {};
+  class HasInitializerBit :
+      public BitField<uint8_t, bool, kHasInitializerBit, 1> {};
+  class UnboxingCandidateBit :
+      public BitField<uint8_t, bool, kUnboxingCandidateBit, 1> {};
+  class ReflectableBit : public BitField<uint8_t, bool, kReflectableBit, 1> {};
+  class DoubleInitializedBit :
+      public BitField<uint8_t, bool, kDoubleInitializedBit, 1> {};
 
   // Update guarded cid and guarded length for this field. Returns true, if
   // deoptimization of dependent code is required.
@@ -3106,11 +3123,11 @@
   void set_owner(const Object& value) const {
     StorePointer(&raw_ptr()->owner_, value.raw());
   }
-  void set_token_pos(intptr_t token_pos) const {
+  void set_token_pos(TokenPosition token_pos) const {
     StoreNonPointer(&raw_ptr()->token_pos_, token_pos);
   }
-  void set_kind_bits(intptr_t value) const {
-    StoreNonPointer(&raw_ptr()->kind_bits_, static_cast<uint8_t>(value));
+  void set_kind_bits(uint8_t value) const {
+    StoreNonPointer(&raw_ptr()->kind_bits_, value);
   }
 
   static RawField* New();
@@ -3156,8 +3173,9 @@
   void SetStream(const ExternalTypedData& stream) const;
 
   RawString* GenerateSource() const;
-  RawString* GenerateSource(intptr_t start, intptr_t end) const;
-  intptr_t ComputeSourcePosition(intptr_t tok_pos) const;
+  RawString* GenerateSource(TokenPosition start,
+                            TokenPosition end) const;
+  TokenPosition ComputeSourcePosition(TokenPosition tok_pos) const;
 
   RawString* PrivateKey() const;
 
@@ -3186,10 +3204,10 @@
     };
 
     Iterator(const TokenStream& tokens,
-             intptr_t token_pos,
+             TokenPosition token_pos,
              Iterator::StreamType stream_type = kNoNewlines);
 
-    void SetStream(const TokenStream& tokens, intptr_t token_pos);
+    void SetStream(const TokenStream& tokens, TokenPosition token_pos);
     bool IsValid() const;
 
     inline Token::Kind CurrentTokenKind() const {
@@ -3198,8 +3216,8 @@
 
     Token::Kind LookaheadTokenKind(intptr_t num_tokens);
 
-    intptr_t CurrentPosition() const;
-    void SetCurrentPosition(intptr_t value);
+    TokenPosition CurrentPosition() const;
+    void SetCurrentPosition(TokenPosition token_pos);
 
     void Advance();
 
@@ -3269,7 +3287,7 @@
 
   void SetLocationOffset(intptr_t line_offset, intptr_t col_offset) const;
 
-  void GetTokenLocation(intptr_t token_pos,
+  void GetTokenLocation(TokenPosition token_pos,
                         intptr_t* line,
                         intptr_t* column,
                         intptr_t* token_len = NULL) const;
@@ -3279,8 +3297,8 @@
   // after, but not on given line, returns in *first_token_index the index of
   // the first token after the line, and a negative value in *last_token_index.
   void TokenRangeAtLine(intptr_t line_number,
-                        intptr_t* first_token_index,
-                        intptr_t* last_token_index) const;
+                        TokenPosition* first_token_index,
+                        TokenPosition* last_token_index) const;
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(RawScript));
@@ -3448,12 +3466,14 @@
 
   void AddClassMetadata(const Class& cls,
                         const Object& tl_owner,
-                        intptr_t token_pos) const;
-  void AddFieldMetadata(const Field& field, intptr_t token_pos) const;
-  void AddFunctionMetadata(const Function& func, intptr_t token_pos) const;
-  void AddLibraryMetadata(const Object& tl_owner, intptr_t token_pos) const;
+                        TokenPosition token_pos) const;
+  void AddFieldMetadata(const Field& field, TokenPosition token_pos) const;
+  void AddFunctionMetadata(const Function& func,
+                           TokenPosition token_pos) const;
+  void AddLibraryMetadata(const Object& tl_owner,
+                          TokenPosition token_pos) const;
   void AddTypeParameterMetadata(const TypeParameter& param,
-                                intptr_t token_pos) const;
+                                TokenPosition token_pos) const;
   RawObject* GetMetadata(const Object& obj) const;
 
   RawClass* toplevel_class() const {
@@ -3610,7 +3630,7 @@
   RawField* GetMetadataField(const String& metaname) const;
   void AddMetadata(const Object& owner,
                    const String& name,
-                   intptr_t token_pos) const;
+                   TokenPosition token_pos) const;
 
   FINAL_HEAP_OBJECT_IMPLEMENTATION(Library, Object);
 
@@ -3631,7 +3651,7 @@
   RawArray* show_names() const { return raw_ptr()->show_names_; }
   RawArray* hide_names() const { return raw_ptr()->hide_names_; }
 
-  void AddMetadata(const Object& owner, intptr_t token_pos);
+  void AddMetadata(const Object& owner, TokenPosition token_pos);
   RawObject* GetMetadata() const;
 
   static intptr_t InstanceSize() {
@@ -3928,7 +3948,7 @@
 
     uword PcOffset() const { return cur_pc_offset_; }
     intptr_t DeoptId() const { return cur_deopt_id_; }
-    intptr_t TokenPos() const { return cur_token_pos_; }
+    TokenPosition TokenPos() const { return TokenPosition(cur_token_pos_); }
     intptr_t TryIndex() const { return cur_try_index_; }
     RawPcDescriptors::Kind Kind() const {
       return static_cast<RawPcDescriptors::Kind>(cur_kind_);
@@ -4021,7 +4041,7 @@
     }
 
     uword PcOffset() const { return cur_pc_offset_; }
-    intptr_t TokenPos() const { return cur_token_pos_; }
+    TokenPosition TokenPos() const { return TokenPosition(cur_token_pos_); }
 
    private:
     friend class CodeSourceMap;
@@ -4455,7 +4475,7 @@
     NoSafepointScope no_safepoint;
     return *PointerOffsetAddrAt(index);
   }
-  intptr_t GetTokenIndexOfPC(uword pc) const;
+  TokenPosition GetTokenIndexOfPC(uword pc) const;
 
   enum {
     kInvalidPc = -1
@@ -4516,9 +4536,10 @@
     kPtrOffSize = 30,
   };
 
-  class OptimizedBit : public BitField<bool, kOptimizedBit, 1> {};
-  class AliveBit : public BitField<bool, kAliveBit, 1> {};
-  class PtrOffBits : public BitField<intptr_t, kPtrOffBit, kPtrOffSize> {};
+  class OptimizedBit : public BitField<int32_t, bool, kOptimizedBit, 1> {};
+  class AliveBit : public BitField<int32_t, bool, kAliveBit, 1> {};
+  class PtrOffBits :
+      public BitField<int32_t, intptr_t, kPtrOffBit, kPtrOffSize> {};
 
   class SlowFindRawCodeVisitor : public FindObjectVisitor {
    public:
@@ -4660,8 +4681,8 @@
  public:
   intptr_t num_variables() const { return raw_ptr()->num_variables_; }
 
-  intptr_t TokenIndexAt(intptr_t scope_index) const;
-  void SetTokenIndexAt(intptr_t scope_index, intptr_t token_pos) const;
+  TokenPosition TokenIndexAt(intptr_t scope_index) const;
+  void SetTokenIndexAt(intptr_t scope_index, TokenPosition token_pos) const;
 
   RawString* NameAt(intptr_t scope_index) const;
   void SetNameAt(intptr_t scope_index, const String& name) const;
@@ -4885,7 +4906,7 @@
   // A null script means no source and a negative token_pos means no position.
   static RawLanguageError* NewFormatted(const Error& prev_error,
                                         const Script& script,
-                                        intptr_t token_pos,
+                                        TokenPosition token_pos,
                                         bool report_after_token,
                                         Report::Kind kind,
                                         Heap::Space space,
@@ -4894,7 +4915,7 @@
 
   static RawLanguageError* NewFormattedV(const Error& prev_error,
                                          const Script& script,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          bool report_after_token,
                                          Report::Kind kind,
                                          Heap::Space space,
@@ -4915,8 +4936,8 @@
   RawScript* script() const { return raw_ptr()->script_; }
   void set_script(const Script& value) const;
 
-  intptr_t token_pos() const { return raw_ptr()->token_pos_; }
-  void set_token_pos(intptr_t value) const;
+  TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
+  void set_token_pos(TokenPosition value) const;
 
   bool report_after_token() const { return raw_ptr()->report_after_token_; }
   void set_report_after_token(bool value);
@@ -5199,7 +5220,7 @@
   virtual RawUnresolvedClass* unresolved_class() const;
   virtual RawTypeArguments* arguments() const;
   virtual void set_arguments(const TypeArguments& value) const;
-  virtual intptr_t token_pos() const;
+  virtual TokenPosition token_pos() const;
   virtual bool IsInstantiated(TrailPtr trail = NULL) const;
   virtual bool CanonicalizeEquals(const Instance& other) const {
     return Equals(other);
@@ -5386,7 +5407,7 @@
   virtual RawUnresolvedClass* unresolved_class() const;
   virtual RawTypeArguments* arguments() const { return raw_ptr()->arguments_; }
   virtual void set_arguments(const TypeArguments& value) const;
-  virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
+  virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated(TrailPtr trail = NULL) const;
   virtual bool IsEquivalent(const Instance& other, TrailPtr trail = NULL) const;
   virtual bool IsRecursive() const;
@@ -5460,11 +5481,11 @@
 
   static RawType* New(const Object& clazz,
                       const TypeArguments& arguments,
-                      intptr_t token_pos,
+                      TokenPosition token_pos,
                       Heap::Space space = Heap::kOld);
 
  private:
-  void set_token_pos(intptr_t token_pos) const;
+  void set_token_pos(TokenPosition token_pos) const;
   void set_type_state(int8_t state) const;
 
   static RawType* New(Heap::Space space = Heap::kOld);
@@ -5533,7 +5554,7 @@
   virtual RawTypeArguments* arguments() const { return raw_ptr()->arguments_; }
   virtual void set_arguments(const TypeArguments& value) const;
   RawFunction* signature() const { return raw_ptr()->signature_; }
-  virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
+  virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated(TrailPtr trail = NULL) const;
   virtual bool IsEquivalent(const Instance& other, TrailPtr trail = NULL) const;
   virtual bool IsRecursive() const;
@@ -5557,12 +5578,12 @@
   static RawFunctionType* New(const Class& scope_class,
                               const TypeArguments& arguments,
                               const Function& signature,
-                              intptr_t token_pos,
+                              TokenPosition token_pos,
                               Heap::Space space = Heap::kOld);
 
  private:
   void set_signature(const Function& value) const;
-  void set_token_pos(intptr_t token_pos) const;
+  void set_token_pos(TokenPosition token_pos) const;
   void set_type_state(int8_t state) const;
 
   static RawFunctionType* New(Heap::Space space = Heap::kOld);
@@ -5606,7 +5627,7 @@
   virtual RawTypeArguments* arguments() const {
     return AbstractType::Handle(type()).arguments();
   }
-  virtual intptr_t token_pos() const {
+  virtual TokenPosition token_pos() const {
     return AbstractType::Handle(type()).token_pos();
   }
   virtual bool IsInstantiated(TrailPtr trail = NULL) const;
@@ -5689,7 +5710,7 @@
                   const AbstractType& upper_bound,
                   Error* bound_error,
                   Heap::Space space = Heap::kNew) const;
-  virtual intptr_t token_pos() const { return raw_ptr()->token_pos_; }
+  virtual TokenPosition token_pos() const { return raw_ptr()->token_pos_; }
   virtual bool IsInstantiated(TrailPtr trail = NULL) const {
     return false;
   }
@@ -5717,12 +5738,12 @@
                                intptr_t index,
                                const String& name,
                                const AbstractType& bound,
-                               intptr_t token_pos);
+                               TokenPosition token_pos);
 
  private:
   void set_parameterized_class(const Class& value) const;
   void set_name(const String& value) const;
-  void set_token_pos(intptr_t token_pos) const;
+  void set_token_pos(TokenPosition token_pos) const;
   void set_type_state(int8_t state) const;
 
   static RawTypeParameter* New();
@@ -5768,7 +5789,7 @@
   RawTypeParameter* type_parameter() const {
     return raw_ptr()->type_parameter_;
   }
-  virtual intptr_t token_pos() const {
+  virtual TokenPosition token_pos() const {
     return AbstractType::Handle(type()).token_pos();
   }
   virtual bool IsInstantiated(TrailPtr trail = NULL) const {
@@ -5832,7 +5853,7 @@
   virtual bool IsResolved() const { return false; }
   virtual bool HasResolvedTypeClass() const { return false; }
   virtual RawString* Name() const;
-  virtual intptr_t token_pos() const;
+  virtual TokenPosition token_pos() const;
 
   // Returns the mixin composition depth of this mixin application type.
   intptr_t Depth() const;
@@ -8012,8 +8033,8 @@
     kFlagsSize = 4,
   };
 
-  class TypeBits : public BitField<RegExType, kTypePos, kTypeSize> {};
-  class FlagsBits : public BitField<intptr_t, kFlagsPos, kFlagsSize> {};
+  class TypeBits : public BitField<int8_t, RegExType, kTypePos, kTypeSize> {};
+  class FlagsBits : public BitField<int8_t, intptr_t, kFlagsPos, kFlagsSize> {};
 
   bool is_initialized() const { return (type() != kUnitialized); }
   bool is_simple() const { return (type() == kSimple); }
diff --git a/runtime/vm/object_graph_test.cc b/runtime/vm/object_graph_test.cc
index 1afcc44..801d01c 100644
--- a/runtime/vm/object_graph_test.cc
+++ b/runtime/vm/object_graph_test.cc
@@ -38,7 +38,7 @@
 };
 
 
-TEST_CASE(ObjectGraph) {
+VM_TEST_CASE(ObjectGraph) {
   Isolate* isolate = thread->isolate();
   // Create a simple object graph with objects a, b, c, d:
   //  a+->b+->c
diff --git a/runtime/vm/object_id_ring_test.cc b/runtime/vm/object_id_ring_test.cc
index 27347ea..e2eda2e 100644
--- a/runtime/vm/object_id_ring_test.cc
+++ b/runtime/vm/object_id_ring_test.cc
@@ -48,7 +48,7 @@
 
 
 // Test that serial number wrapping works.
-TEST_CASE(ObjectIdRingSerialWrapTest) {
+VM_TEST_CASE(ObjectIdRingSerialWrapTest) {
   Isolate* isolate = Isolate::Current();
   ObjectIdRing* ring = isolate->object_id_ring();
   ObjectIdRingTestHelper::SetCapacityAndMaxSerial(ring, 2, 4);
@@ -160,8 +160,11 @@
   EXPECT_NE(Object::null(), raw_obj2);
   EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj1));
   EXPECT_EQ(RawObject::ToAddr(raw_obj), RawObject::ToAddr(raw_obj2));
-  // Force a scavenge.
-  heap->CollectGarbage(Heap::kNew);
+  {
+    TransitionNativeToVM transition(thread);
+    // Force a scavenge.
+    heap->CollectGarbage(Heap::kNew);
+  }
   RawObject* raw_object_moved1 = ring->GetObjectForId(raw_obj_id1, &kind);
   EXPECT_EQ(ObjectIdRing::kValid, kind);
   RawObject* raw_object_moved2 = ring->GetObjectForId(raw_obj_id2, &kind);
@@ -187,7 +190,7 @@
 
 
 // Test that the ring table is updated with nulls when the old GC collects.
-TEST_CASE(ObjectIdRingOldGCTest) {
+VM_TEST_CASE(ObjectIdRingOldGCTest) {
   Isolate* isolate = thread->isolate();
   Heap* heap = isolate->heap();
   ObjectIdRing* ring = isolate->object_id_ring();
@@ -241,7 +244,7 @@
 
 // Test that the ring table correctly reports an entry as expired when it is
 // overridden by new entries.
-TEST_CASE(ObjectIdRingExpiredEntryTest) {
+VM_TEST_CASE(ObjectIdRingExpiredEntryTest) {
   Isolate* isolate = Isolate::Current();
   ObjectIdRing* ring = isolate->object_id_ring();
 
diff --git a/runtime/vm/object_test.cc b/runtime/vm/object_test.cc
index 9f31fee..d681c08 100644
--- a/runtime/vm/object_test.cc
+++ b/runtime/vm/object_test.cc
@@ -29,13 +29,13 @@
 static RawClass* CreateDummyClass(const String& class_name,
                                   const Script& script) {
   const Class& cls = Class::Handle(
-      Class::New(class_name, script, Token::kNoSourcePos));
+      Class::New(class_name, script, TokenPosition::kNoSource));
   cls.set_is_synthesized_class();  // Dummy class for testing.
   return cls.raw();
 }
 
 
-TEST_CASE(Class) {
+VM_TEST_CASE(Class) {
   // Allocate the class first.
   const String& class_name = String::Handle(Symbols::New("MyClass"));
   const Script& script = Script::Handle();
@@ -68,12 +68,12 @@
   function_name = Symbols::New("foo");
   function = Function::New(
       function_name, RawFunction::kRegularFunction,
-      false, false, false, false, false, cls, 0);
+      false, false, false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(0, function);
   function_name = Symbols::New("bar");
   function = Function::New(
       function_name, RawFunction::kRegularFunction,
-      false, false, false, false, false, cls, 0);
+      false, false, false, false, false, cls, TokenPosition::kMinSource);
 
   const int kNumFixedParameters = 2;
   const int kNumOptionalParameters = 3;
@@ -86,24 +86,24 @@
   function_name = Symbols::New("baz");
   function = Function::New(
       function_name, RawFunction::kRegularFunction,
-      false, false, false, false, false, cls, 0);
+      false, false, false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(2, function);
 
   function_name = Symbols::New("Foo");
   function = Function::New(
       function_name, RawFunction::kRegularFunction,
-      true, false, false, false, false, cls, 0);
+      true, false, false, false, false, cls, TokenPosition::kMinSource);
 
   functions.SetAt(3, function);
   function_name = Symbols::New("Bar");
   function = Function::New(
       function_name, RawFunction::kRegularFunction,
-      true, false, false, false, false, cls, 0);
+      true, false, false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(4, function);
   function_name = Symbols::New("BaZ");
   function = Function::New(
       function_name, RawFunction::kRegularFunction,
-      true, false, false, false, false, cls, 0);
+      true, false, false, false, false, cls, TokenPosition::kMinSource);
   functions.SetAt(5, function);
 
   // Setup the functions in the class.
@@ -143,7 +143,7 @@
 }
 
 
-TEST_CASE(TypeArguments) {
+VM_TEST_CASE(TypeArguments) {
   const Type& type1 = Type::Handle(Type::Double());
   const Type& type2 = Type::Handle(Type::StringType());
   const TypeArguments& type_arguments1 = TypeArguments::Handle(
@@ -165,7 +165,7 @@
 }
 
 
-TEST_CASE(TokenStream) {
+VM_TEST_CASE(TokenStream) {
   String& source = String::Handle(String::New("= ( 9 , ."));
   String& private_key = String::Handle(String::New(""));
   Scanner scanner(source, private_key);
@@ -174,7 +174,7 @@
   EXPECT_EQ(Token::kLPAREN, ts[1].kind);
   const TokenStream& token_stream = TokenStream::Handle(
       TokenStream::New(ts, private_key, false));
-  TokenStream::Iterator iterator(token_stream, 0);
+  TokenStream::Iterator iterator(token_stream, TokenPosition::kMinSource);
   // EXPECT_EQ(6, token_stream.Length());
   iterator.Advance();  // Advance to '(' token.
   EXPECT_EQ(Token::kLPAREN, iterator.CurrentTokenKind());
@@ -187,7 +187,7 @@
 }
 
 
-TEST_CASE(GenerateExactSource) {
+VM_TEST_CASE(GenerateExactSource) {
   // Verify the exact formatting of generated sources.
   const char* kScriptChars =
   "\n"
@@ -241,7 +241,7 @@
   const Class& cls = Class::Handle(
       lib.LookupClass(String::Handle(String::New("A"))));
   EXPECT(!cls.IsNull());
-  const intptr_t end_token_pos = cls.ComputeEndTokenPos();
+  const TokenPosition end_token_pos = cls.ComputeEndTokenPos();
   const Script& scr = Script::Handle(cls.script());
   intptr_t line;
   intptr_t col;
@@ -250,7 +250,7 @@
 }
 
 
-TEST_CASE(InstanceClass) {
+VM_TEST_CASE(InstanceClass) {
   // Allocate the class first.
   String& class_name = String::Handle(Symbols::New("EmptyClass"));
   Script& script = Script::Handle();
@@ -282,7 +282,7 @@
   const String& field_name = String::Handle(Symbols::New("the_field"));
   const Field& field = Field::Handle(
       Field::New(field_name, false, false, false, true, one_field_class,
-                 Object::dynamic_type(), 0));
+                 Object::dynamic_type(), TokenPosition::kMinSource));
   one_fields.SetAt(0, field);
   one_field_class.SetFields(one_fields);
   one_field_class.Finalize();
@@ -296,7 +296,7 @@
 }
 
 
-TEST_CASE(Smi) {
+VM_TEST_CASE(Smi) {
   const Smi& smi = Smi::Handle(Smi::New(5));
   Object& smi_object = Object::Handle(smi.raw());
   EXPECT(smi.IsSmi());
@@ -358,7 +358,7 @@
 }
 
 
-TEST_CASE(StringCompareTo) {
+VM_TEST_CASE(StringCompareTo) {
   const String& abcd = String::Handle(String::New("abcd"));
   const String& abce = String::Handle(String::New("abce"));
   EXPECT_EQ(0, abcd.CompareTo(abcd));
@@ -402,7 +402,7 @@
 }
 
 
-TEST_CASE(StringEncodeIRI) {
+VM_TEST_CASE(StringEncodeIRI) {
   const char* kInput =
       "file:///usr/local/johnmccutchan/workspace/dart-repo/dart/test.dart";
   const char* kOutput =
@@ -415,7 +415,7 @@
 }
 
 
-TEST_CASE(StringDecodeIRI) {
+VM_TEST_CASE(StringDecodeIRI) {
   const char* kOutput =
       "file:///usr/local/johnmccutchan/workspace/dart-repo/dart/test.dart";
   const char* kInput =
@@ -428,7 +428,7 @@
 }
 
 
-TEST_CASE(StringDecodeIRIInvalid) {
+VM_TEST_CASE(StringDecodeIRIInvalid) {
   String& input = String::Handle();
   input = String::New("file%");
   String& decoded = String::Handle();
@@ -443,7 +443,7 @@
 }
 
 
-TEST_CASE(StringIRITwoByte) {
+VM_TEST_CASE(StringIRITwoByte) {
   const intptr_t kInputLen = 3;
   const uint16_t kInput[kInputLen] = { 'x', '/', 256 };
   const String& input = String::Handle(String::FromUTF16(kInput, kInputLen));
@@ -458,7 +458,7 @@
 }
 
 
-TEST_CASE(Mint) {
+VM_TEST_CASE(Mint) {
 // On 64-bit architectures a Smi is stored in a 64 bit word. A Midint cannot
 // be allocated if it does fit into a Smi.
 #if !defined(ARCH_IS_64_BIT)
@@ -532,7 +532,7 @@
 }
 
 
-TEST_CASE(Double) {
+VM_TEST_CASE(Double) {
   {
     const double dbl_const = 5.0;
     const Double& dbl = Double::Handle(Double::New(dbl_const));
@@ -616,7 +616,7 @@
 }
 
 
-TEST_CASE(Bigint) {
+VM_TEST_CASE(Bigint) {
   Bigint& b = Bigint::Handle();
   EXPECT(b.IsNull());
   const char* cstr = "18446744073709551615000";
@@ -655,7 +655,7 @@
 }
 
 
-TEST_CASE(Integer) {
+VM_TEST_CASE(Integer) {
   Integer& i = Integer::Handle();
   i = Integer::NewCanonical(String::Handle(String::New("12")));
   EXPECT(i.IsSmi());
@@ -672,7 +672,7 @@
 }
 
 
-TEST_CASE(String) {
+VM_TEST_CASE(String) {
   const char* kHello = "Hello World!";
   int32_t hello_len = strlen(kHello);
   const String& str = String::Handle(String::New(kHello));
@@ -819,7 +819,7 @@
 }
 
 
-TEST_CASE(StringFormat) {
+VM_TEST_CASE(StringFormat) {
   const char* hello_str = "Hello World!";
   const String& str =
       String::Handle(String::NewFormatted("Hello %s!", "World"));
@@ -832,7 +832,7 @@
 }
 
 
-TEST_CASE(StringConcat) {
+VM_TEST_CASE(StringConcat) {
   // Create strings from concatenated 1-byte empty strings.
   {
     const String& empty1 = String::Handle(String::New(""));
@@ -1366,7 +1366,7 @@
 }
 
 
-TEST_CASE(StringHashConcat) {
+VM_TEST_CASE(StringHashConcat) {
   EXPECT_EQ(String::Handle(String::New("onebyte")).Hash(),
             String::HashConcat(String::Handle(String::New("one")),
                                String::Handle(String::New("byte"))));
@@ -1382,7 +1382,7 @@
 }
 
 
-TEST_CASE(StringSubStringDifferentWidth) {
+VM_TEST_CASE(StringSubStringDifferentWidth) {
   // Create 1-byte substring from a 1-byte source string.
   const char* onechars =
       "\xC3\xB6\xC3\xB1\xC3\xA9";
@@ -1444,7 +1444,7 @@
 }
 
 
-TEST_CASE(StringFromUtf8Literal) {
+VM_TEST_CASE(StringFromUtf8Literal) {
   // Create a 1-byte string from a UTF-8 encoded string literal.
   {
     const char* src =
@@ -1612,7 +1612,7 @@
 }
 
 
-TEST_CASE(StringEqualsUtf8) {
+VM_TEST_CASE(StringEqualsUtf8) {
   const char* onesrc = "abc";
   const String& onestr = String::Handle(String::New(onesrc));
   EXPECT(onestr.IsOneByteString());
@@ -1643,7 +1643,7 @@
 }
 
 
-TEST_CASE(StringEqualsUTF32) {
+VM_TEST_CASE(StringEqualsUTF32) {
   const String& empty = String::Handle(String::New(""));
   const String& t_str = String::Handle(String::New("t"));
   const String& th_str = String::Handle(String::New("th"));
@@ -1660,7 +1660,7 @@
 }
 
 
-TEST_CASE(ExternalOneByteString) {
+VM_TEST_CASE(ExternalOneByteString) {
   uint8_t characters[] = { 0xF6, 0xF1, 0xE9 };
   intptr_t len = ARRAY_SIZE(characters);
 
@@ -1692,7 +1692,7 @@
 }
 
 
-TEST_CASE(EscapeSpecialCharactersOneByteString) {
+VM_TEST_CASE(EscapeSpecialCharactersOneByteString) {
   uint8_t characters[] =
       { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
   intptr_t len = ARRAY_SIZE(characters);
@@ -1713,7 +1713,7 @@
 }
 
 
-TEST_CASE(EscapeSpecialCharactersExternalOneByteString) {
+VM_TEST_CASE(EscapeSpecialCharactersExternalOneByteString) {
   uint8_t characters[] =
       { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
   intptr_t len = ARRAY_SIZE(characters);
@@ -1738,7 +1738,7 @@
   EXPECT_EQ(escaped_empty_str.Length(), 0);
 }
 
-TEST_CASE(EscapeSpecialCharactersTwoByteString) {
+VM_TEST_CASE(EscapeSpecialCharactersTwoByteString) {
   uint16_t characters[] =
       { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
   intptr_t len = ARRAY_SIZE(characters);
@@ -1761,7 +1761,7 @@
 }
 
 
-TEST_CASE(EscapeSpecialCharactersExternalTwoByteString) {
+VM_TEST_CASE(EscapeSpecialCharactersExternalTwoByteString) {
   uint16_t characters[] =
       { 'a', '\n', '\f', '\b', '\t', '\v', '\r', '\\', '$', 'z' };
   intptr_t len = ARRAY_SIZE(characters);
@@ -1786,7 +1786,7 @@
 }
 
 
-TEST_CASE(ExternalTwoByteString) {
+VM_TEST_CASE(ExternalTwoByteString) {
   uint16_t characters[] = { 0x1E6B, 0x1E85, 0x1E53 };
   intptr_t len = ARRAY_SIZE(characters);
 
@@ -1819,7 +1819,7 @@
 }
 
 
-TEST_CASE(Symbol) {
+VM_TEST_CASE(Symbol) {
   const String& one = String::Handle(Symbols::New("Eins"));
   EXPECT(one.IsSymbol());
   const String& two = String::Handle(Symbols::New("Zwei"));
@@ -1881,7 +1881,7 @@
 }
 
 
-TEST_CASE(SymbolUnicode) {
+VM_TEST_CASE(SymbolUnicode) {
   uint16_t monkey_utf16[] = { 0xd83d, 0xdc35 };  // Unicode Monkey Face.
   String& monkey = String::Handle(Symbols::FromUTF16(monkey_utf16, 2));
   EXPECT(monkey.IsSymbol());
@@ -1903,13 +1903,13 @@
 }
 
 
-TEST_CASE(Bool) {
+VM_TEST_CASE(Bool) {
   EXPECT(Bool::True().value());
   EXPECT(!Bool::False().value());
 }
 
 
-TEST_CASE(Array) {
+VM_TEST_CASE(Array) {
   const int kArrayLen = 5;
   const Array& array = Array::Handle(Array::New(kArrayLen));
   EXPECT_EQ(kArrayLen, array.Length());
@@ -2056,7 +2056,7 @@
 }
 
 
-TEST_CASE(StringCodePointIterator) {
+VM_TEST_CASE(StringCodePointIterator) {
   const String& str0 = String::Handle(String::New(""));
   String::CodePointIterator it0(str0);
   EXPECT(!it0.Next());
@@ -2111,7 +2111,7 @@
 }
 
 
-TEST_CASE(StringCodePointIteratorRange) {
+VM_TEST_CASE(StringCodePointIteratorRange) {
   const String& str = String::Handle(String::New("foo bar baz"));
 
   String::CodePointIterator it0(str, 3, 0);
@@ -2128,7 +2128,7 @@
 }
 
 
-TEST_CASE(GrowableObjectArray) {
+VM_TEST_CASE(GrowableObjectArray) {
   const int kArrayLen = 5;
   Smi& value = Smi::Handle();
   Smi& expected_value = Smi::Handle();
@@ -2250,7 +2250,7 @@
 }
 
 
-TEST_CASE(InternalTypedData) {
+VM_TEST_CASE(InternalTypedData) {
   uint8_t data[] = { 253, 254, 255, 0, 1, 2, 3, 4 };
   intptr_t data_length = ARRAY_SIZE(data);
 
@@ -2306,7 +2306,7 @@
 }
 
 
-TEST_CASE(ExternalTypedData) {
+VM_TEST_CASE(ExternalTypedData) {
   uint8_t data[] = { 253, 254, 255, 0, 1, 2, 3, 4 };
   intptr_t data_length = ARRAY_SIZE(data);
 
@@ -2407,7 +2407,7 @@
 }
 
 
-TEST_CASE(EmbeddedScript) {
+VM_TEST_CASE(EmbeddedScript) {
   const char* url_chars = "builtin:test-case";
   const char* text =
       /* 1 */ "<!DOCTYPE html>\n"
@@ -2462,47 +2462,47 @@
 
   intptr_t line, col;
   intptr_t fast_line;
-  script.GetTokenLocation(0, &line, &col);
+  script.GetTokenLocation(TokenPosition(0), &line, &col);
   EXPECT_EQ(first_dart_line, line);
   EXPECT_EQ(col, col_offset + 1);
 
   // We allow asking for only the line number, which only scans the token stream
   // instead of rescanning the script.
-  script.GetTokenLocation(0, &fast_line, NULL);
+  script.GetTokenLocation(TokenPosition(0), &fast_line, NULL);
   EXPECT_EQ(line, fast_line);
 
-  script.GetTokenLocation(5, &line, &col);  // Token 'return'
+  script.GetTokenLocation(TokenPosition(5), &line, &col);  // Token 'return'
   EXPECT_EQ(4, line);  // 'return' is in line 4.
   EXPECT_EQ(5, col);   // Four spaces before 'return'.
 
   // We allow asking for only the line number, which only scans the token stream
   // instead of rescanning the script.
-  script.GetTokenLocation(5, &fast_line, NULL);
+  script.GetTokenLocation(TokenPosition(5), &fast_line, NULL);
   EXPECT_EQ(line, fast_line);
 
-  intptr_t first_idx, last_idx;
+  TokenPosition first_idx, last_idx;
   script.TokenRangeAtLine(3, &first_idx, &last_idx);
-  EXPECT_EQ(0, first_idx);  // Token 'main' is first token.
-  EXPECT_EQ(3, last_idx);   // Token { is last token.
+  EXPECT_EQ(0, first_idx.value());  // Token 'main' is first token.
+  EXPECT_EQ(3, last_idx.value());   // Token { is last token.
   script.TokenRangeAtLine(4, &first_idx, &last_idx);
-  EXPECT_EQ(5, first_idx);  // Token 'return' is first token.
-  EXPECT_EQ(7, last_idx);   // Token ; is last token.
+  EXPECT_EQ(5, first_idx.value());  // Token 'return' is first token.
+  EXPECT_EQ(7, last_idx.value());   // Token ; is last token.
   script.TokenRangeAtLine(5, &first_idx, &last_idx);
-  EXPECT_EQ(9, first_idx);  // Token } is first and only token.
-  EXPECT_EQ(9, last_idx);
+  EXPECT_EQ(9, first_idx.value());  // Token } is first and only token.
+  EXPECT_EQ(9, last_idx.value());
   script.TokenRangeAtLine(1, &first_idx, &last_idx);
-  EXPECT_EQ(0, first_idx);
-  EXPECT_EQ(3, last_idx);
+  EXPECT_EQ(0, first_idx.value());
+  EXPECT_EQ(3, last_idx.value());
   script.TokenRangeAtLine(6, &first_idx, &last_idx);
-  EXPECT_EQ(-1, first_idx);
-  EXPECT_EQ(-1, last_idx);
+  EXPECT_EQ(-1, first_idx.value());
+  EXPECT_EQ(-1, last_idx.value());
   script.TokenRangeAtLine(1000, &first_idx, &last_idx);
-  EXPECT_EQ(-1, first_idx);
-  EXPECT_EQ(-1, last_idx);
+  EXPECT_EQ(-1, first_idx.value());
+  EXPECT_EQ(-1, last_idx.value());
 }
 
 
-TEST_CASE(Context) {
+VM_TEST_CASE(Context) {
   const int kNumVariables = 5;
   const Context& parent_context = Context::Handle(Context::New(0));
   const Context& context = Context::Handle(Context::New(kNumVariables));
@@ -2525,7 +2525,7 @@
 }
 
 
-TEST_CASE(ContextScope) {
+VM_TEST_CASE(ContextScope) {
   const intptr_t parent_scope_function_level = 0;
   LocalScope* parent_scope =
       new LocalScope(NULL, parent_scope_function_level, 0);
@@ -2537,17 +2537,17 @@
   const Type& dynamic_type = Type::ZoneHandle(Type::DynamicType());
   const String& a = String::ZoneHandle(Symbols::New("a"));
   LocalVariable* var_a =
-      new LocalVariable(Token::kNoSourcePos, a, dynamic_type);
+      new LocalVariable(TokenPosition::kNoSource, a, dynamic_type);
   parent_scope->AddVariable(var_a);
 
   const String& b = String::ZoneHandle(Symbols::New("b"));
   LocalVariable* var_b =
-      new LocalVariable(Token::kNoSourcePos, b, dynamic_type);
+      new LocalVariable(TokenPosition::kNoSource, b, dynamic_type);
   local_scope->AddVariable(var_b);
 
   const String& c = String::ZoneHandle(Symbols::New("c"));
   LocalVariable* var_c =
-      new LocalVariable(Token::kNoSourcePos, c, dynamic_type);
+      new LocalVariable(TokenPosition::kNoSource, c, dynamic_type);
   parent_scope->AddVariable(var_c);
 
   bool test_only = false;  // Please, insert alias.
@@ -2612,7 +2612,7 @@
 }
 
 
-TEST_CASE(Closure) {
+VM_TEST_CASE(Closure) {
   // Allocate the class first.
   const String& class_name = String::Handle(Symbols::New("MyClass"));
   const Script& script = Script::Handle();
@@ -2623,13 +2623,15 @@
   Function& parent = Function::Handle();
   const String& parent_name = String::Handle(Symbols::New("foo_papa"));
   parent = Function::New(parent_name, RawFunction::kRegularFunction,
-                         false, false, false, false, false, cls, 0);
+                         false, false, false, false, false, cls,
+                         TokenPosition::kMinSource);
   functions.SetAt(0, parent);
   cls.SetFunctions(functions);
 
   Function& function = Function::Handle();
   const String& function_name = String::Handle(Symbols::New("foo"));
-  function = Function::NewClosureFunction(function_name, parent, 0);
+  function = Function::NewClosureFunction(
+      function_name, parent, TokenPosition::kMinSource);
   const Closure& closure = Closure::Handle(Closure::New(function, context));
   const Class& closure_class = Class::Handle(closure.clazz());
   EXPECT_EQ(closure_class.id(), kClosureCid);
@@ -2640,7 +2642,7 @@
 }
 
 
-TEST_CASE(ObjectPrinting) {
+VM_TEST_CASE(ObjectPrinting) {
   // Simple Smis.
   EXPECT_STREQ("2", Smi::Handle(Smi::New(2)).ToCString());
   EXPECT_STREQ("-15", Smi::Handle(Smi::New(-15)).ToCString());
@@ -2659,7 +2661,7 @@
 }
 
 
-TEST_CASE(CheckedHandle) {
+VM_TEST_CASE(CheckedHandle) {
   // Ensure that null handles have the correct C++ vtable setup.
   const String& str1 = String::Handle();
   EXPECT(str1.IsString());
@@ -2692,12 +2694,13 @@
   owner_class.set_library(owner_library);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
   return Function::New(function_name, RawFunction::kRegularFunction,
-                       true, false, false, false, false, owner_class, 0);
+                       true, false, false, false, false, owner_class,
+                       TokenPosition::kMinSource);
 }
 
 
 // Test for Code and Instruction object creation.
-TEST_CASE(Code) {
+VM_TEST_CASE(Code) {
   extern void GenerateIncrement(Assembler* assembler);
   Assembler _assembler_;
   GenerateIncrement(&_assembler_);
@@ -2715,7 +2718,7 @@
 
 // Test for immutability of generated instructions. The test crashes with a
 // segmentation fault when writing into it.
-TEST_CASE(CodeImmutability) {
+VM_TEST_CASE(CodeImmutability) {
   extern void GenerateIncrement(Assembler* assembler);
   Assembler _assembler_;
   GenerateIncrement(&_assembler_);
@@ -2737,7 +2740,7 @@
 
 
 // Test for Embedded String object in the instructions.
-TEST_CASE(EmbedStringInCode) {
+VM_TEST_CASE(EmbedStringInCode) {
   extern void GenerateEmbedStringInCode(Assembler* assembler, const char* str);
   const char* kHello = "Hello World!";
   word expected_length = static_cast<word>(strlen(kHello));
@@ -2760,7 +2763,7 @@
 
 
 // Test for Embedded Smi object in the instructions.
-TEST_CASE(EmbedSmiInCode) {
+VM_TEST_CASE(EmbedSmiInCode) {
   extern void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value);
   const intptr_t kSmiTestValue = 5;
   Assembler _assembler_;
@@ -2777,7 +2780,7 @@
 
 #if defined(ARCH_IS_64_BIT)
 // Test for Embedded Smi object in the instructions.
-TEST_CASE(EmbedSmiIn64BitCode) {
+VM_TEST_CASE(EmbedSmiIn64BitCode) {
   extern void GenerateEmbedSmiInCode(Assembler* assembler, intptr_t value);
   const intptr_t kSmiTestValue = DART_INT64_C(5) << 32;
   Assembler _assembler_;
@@ -2793,7 +2796,7 @@
 #endif  // ARCH_IS_64_BIT
 
 
-TEST_CASE(ExceptionHandlers) {
+VM_TEST_CASE(ExceptionHandlers) {
   const int kNumEntries = 4;
   // Add an exception handler table to the code.
   ExceptionHandlers& exception_handlers = ExceptionHandlers::Handle();
@@ -2831,16 +2834,22 @@
 }
 
 
-TEST_CASE(PcDescriptors) {
+VM_TEST_CASE(PcDescriptors) {
   DescriptorList* builder = new DescriptorList(0);
 
   // kind, pc_offset, deopt_id, token_pos, try_index
-  builder->AddDescriptor(RawPcDescriptors::kOther, 10, 1, 20, 1);
-  builder->AddDescriptor(RawPcDescriptors::kDeopt, 20, 2, 30, 0);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 30, 3, 40, 1);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 10, 4, 40, 2);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 10, 5, 80, 3);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 80, 6, 150, 3);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         10, 1, TokenPosition(20), 1);
+  builder->AddDescriptor(RawPcDescriptors::kDeopt,
+                         20, 2, TokenPosition(30), 0);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         30, 3, TokenPosition(40), 1);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         10, 4, TokenPosition(40), 2);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         10, 5, TokenPosition(80), 3);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         80, 6, TokenPosition(150), 3);
 
   PcDescriptors& descriptors = PcDescriptors::Handle();
   descriptors ^= builder->FinalizePcDescriptors(0);
@@ -2857,47 +2866,53 @@
   PcDescriptors::Iterator iter(pc_descs, RawPcDescriptors::kAnyKind);
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(20, iter.TokenPos());
+  EXPECT_EQ(20, iter.TokenPos().value());
   EXPECT_EQ(1, iter.TryIndex());
   EXPECT_EQ(static_cast<uword>(10), iter.PcOffset());
   EXPECT_EQ(1, iter.DeoptId());
   EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(30, iter.TokenPos());
+  EXPECT_EQ(30, iter.TokenPos().value());
   EXPECT_EQ(RawPcDescriptors::kDeopt, iter.Kind());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(40, iter.TokenPos());
+  EXPECT_EQ(40, iter.TokenPos().value());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(40, iter.TokenPos());
+  EXPECT_EQ(40, iter.TokenPos().value());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(80, iter.TokenPos());
+  EXPECT_EQ(80, iter.TokenPos().value());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(150, iter.TokenPos());
+  EXPECT_EQ(150, iter.TokenPos().value());
 
   EXPECT_EQ(3, iter.TryIndex());
   EXPECT_EQ(static_cast<uword>(80), iter.PcOffset());
-  EXPECT_EQ(150, iter.TokenPos());
+  EXPECT_EQ(150, iter.TokenPos().value());
   EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
 
   EXPECT_EQ(false, iter.MoveNext());
 }
 
 
-TEST_CASE(PcDescriptorsLargeDeltas) {
+VM_TEST_CASE(PcDescriptorsLargeDeltas) {
   DescriptorList* builder = new DescriptorList(0);
 
   // kind, pc_offset, deopt_id, token_pos, try_index
-  builder->AddDescriptor(RawPcDescriptors::kOther, 100, 1, 200, 1);
-  builder->AddDescriptor(RawPcDescriptors::kDeopt, 200, 2, 300, 0);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 300, 3, 400, 1);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 100, 4, 0, 2);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 100, 5, 800, 3);
-  builder->AddDescriptor(RawPcDescriptors::kOther, 800, 6, 150, 3);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         100, 1, TokenPosition(200), 1);
+  builder->AddDescriptor(RawPcDescriptors::kDeopt,
+                         200, 2, TokenPosition(300), 0);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         300, 3, TokenPosition(400), 1);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         100, 4, TokenPosition(0), 2);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         100, 5, TokenPosition(800), 3);
+  builder->AddDescriptor(RawPcDescriptors::kOther,
+                         800, 6, TokenPosition(150), 3);
 
   PcDescriptors& descriptors = PcDescriptors::Handle();
   descriptors ^= builder->FinalizePcDescriptors(0);
@@ -2914,31 +2929,31 @@
   PcDescriptors::Iterator iter(pc_descs, RawPcDescriptors::kAnyKind);
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(200, iter.TokenPos());
+  EXPECT_EQ(200, iter.TokenPos().value());
   EXPECT_EQ(1, iter.TryIndex());
   EXPECT_EQ(static_cast<uword>(100), iter.PcOffset());
   EXPECT_EQ(1, iter.DeoptId());
   EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(300, iter.TokenPos());
+  EXPECT_EQ(300, iter.TokenPos().value());
   EXPECT_EQ(RawPcDescriptors::kDeopt, iter.Kind());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(400, iter.TokenPos());
+  EXPECT_EQ(400, iter.TokenPos().value());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(0, iter.TokenPos());
+  EXPECT_EQ(0, iter.TokenPos().value());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(800, iter.TokenPos());
+  EXPECT_EQ(800, iter.TokenPos().value());
 
   EXPECT_EQ(true, iter.MoveNext());
-  EXPECT_EQ(150, iter.TokenPos());
+  EXPECT_EQ(150, iter.TokenPos().value());
 
   EXPECT_EQ(3, iter.TryIndex());
   EXPECT_EQ(static_cast<uword>(800), iter.PcOffset());
-  EXPECT_EQ(150, iter.TokenPos());
+  EXPECT_EQ(150, iter.TokenPos().value());
   EXPECT_EQ(RawPcDescriptors::kOther, iter.Kind());
 
   EXPECT_EQ(false, iter.MoveNext());
@@ -2958,12 +2973,12 @@
   const String& field_name = String::Handle(Symbols::New(name));
   const Field& field =
       Field::Handle(Field::New(field_name, true, false, false, true, cls,
-          Object::dynamic_type(), 0));
+          Object::dynamic_type(), TokenPosition::kMinSource));
   return field.raw();
 }
 
 
-TEST_CASE(ClassDictionaryIterator) {
+VM_TEST_CASE(ClassDictionaryIterator) {
   Class& ae66 = Class::ZoneHandle(CreateTestClass("Ae6/6"));
   Class& re44 = Class::ZoneHandle(CreateTestClass("Re4/4"));
   Field& ce68 = Field::ZoneHandle(CreateTestField("Ce6/8"));
@@ -3003,11 +3018,11 @@
                        is_external,
                        is_native,
                        cls,
-                       0);
+                       TokenPosition::kMinSource);
 }
 
 
-TEST_CASE(ICData) {
+VM_TEST_CASE(ICData) {
   Function& function = Function::Handle(GetDummyTarget("Bern"));
   const intptr_t id = 12;
   const intptr_t num_args_tested = 1;
@@ -3079,7 +3094,7 @@
 }
 
 
-TEST_CASE(SubtypeTestCache) {
+VM_TEST_CASE(SubtypeTestCache) {
   String& class_name = String::Handle(Symbols::New("EmptyClass"));
   Script& script = Script::Handle();
   const Class& empty_class =
@@ -3105,7 +3120,7 @@
 }
 
 
-TEST_CASE(FieldTests) {
+VM_TEST_CASE(FieldTests) {
   const String& f = String::Handle(String::New("oneField"));
   const String& getter_f = String::Handle(Field::GetterName(f));
   const String& setter_f = String::Handle(Field::SetterName(f));
@@ -3128,7 +3143,7 @@
 bool EqualsIgnoringPrivate(const String& name, const String& private_name);
 
 
-TEST_CASE(EqualsIgnoringPrivate) {
+VM_TEST_CASE(EqualsIgnoringPrivate) {
   String& mangled_name = String::Handle();
   String& bare_name = String::Handle();
 
@@ -3261,7 +3276,7 @@
 }
 
 
-TEST_CASE(ArrayNew_Overflow_Crash) {
+VM_TEST_CASE(ArrayNew_Overflow_Crash) {
   Array::Handle(Array::New(Array::kMaxElements + 1));
 }
 
@@ -3327,7 +3342,7 @@
 }
 
 
-TEST_CASE(WeakProperty_PreserveCrossGen) {
+VM_TEST_CASE(WeakProperty_PreserveCrossGen) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak = WeakProperty::Handle();
   {
@@ -3439,7 +3454,7 @@
 }
 
 
-TEST_CASE(WeakProperty_PreserveRecurse) {
+VM_TEST_CASE(WeakProperty_PreserveRecurse) {
   // This used to end in an infinite recursion. Caused by scavenging the weak
   // property before scavenging the key.
   Isolate* isolate = Isolate::Current();
@@ -3462,7 +3477,7 @@
 }
 
 
-TEST_CASE(WeakProperty_PreserveOne_NewSpace) {
+VM_TEST_CASE(WeakProperty_PreserveOne_NewSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak = WeakProperty::Handle();
   String& key = String::Handle();
@@ -3481,7 +3496,7 @@
 }
 
 
-TEST_CASE(WeakProperty_PreserveTwo_NewSpace) {
+VM_TEST_CASE(WeakProperty_PreserveTwo_NewSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak1 = WeakProperty::Handle();
   String& key1 = String::Handle();
@@ -3510,7 +3525,7 @@
 }
 
 
-TEST_CASE(WeakProperty_PreserveTwoShared_NewSpace) {
+VM_TEST_CASE(WeakProperty_PreserveTwoShared_NewSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak1 = WeakProperty::Handle();
   WeakProperty& weak2 = WeakProperty::Handle();
@@ -3537,7 +3552,7 @@
 }
 
 
-TEST_CASE(WeakProperty_PreserveOne_OldSpace) {
+VM_TEST_CASE(WeakProperty_PreserveOne_OldSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak = WeakProperty::Handle();
   String& key = String::Handle();
@@ -3556,7 +3571,7 @@
 }
 
 
-TEST_CASE(WeakProperty_PreserveTwo_OldSpace) {
+VM_TEST_CASE(WeakProperty_PreserveTwo_OldSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak1 = WeakProperty::Handle();
   String& key1 = String::Handle();
@@ -3585,7 +3600,7 @@
 }
 
 
-TEST_CASE(WeakProperty_PreserveTwoShared_OldSpace) {
+VM_TEST_CASE(WeakProperty_PreserveTwoShared_OldSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak1 = WeakProperty::Handle();
   WeakProperty& weak2 = WeakProperty::Handle();
@@ -3612,7 +3627,7 @@
 }
 
 
-TEST_CASE(WeakProperty_ClearOne_NewSpace) {
+VM_TEST_CASE(WeakProperty_ClearOne_NewSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak = WeakProperty::Handle();
   {
@@ -3633,7 +3648,7 @@
 }
 
 
-TEST_CASE(WeakProperty_ClearTwoShared_NewSpace) {
+VM_TEST_CASE(WeakProperty_ClearTwoShared_NewSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak1 = WeakProperty::Handle();
   WeakProperty& weak2 = WeakProperty::Handle();
@@ -3660,7 +3675,7 @@
 }
 
 
-TEST_CASE(WeakProperty_ClearOne_OldSpace) {
+VM_TEST_CASE(WeakProperty_ClearOne_OldSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak = WeakProperty::Handle();
   {
@@ -3681,7 +3696,7 @@
 }
 
 
-TEST_CASE(WeakProperty_ClearTwoShared_OldSpace) {
+VM_TEST_CASE(WeakProperty_ClearTwoShared_OldSpace) {
   Isolate* isolate = Isolate::Current();
   WeakProperty& weak1 = WeakProperty::Handle();
   WeakProperty& weak2 = WeakProperty::Handle();
@@ -3708,7 +3723,7 @@
 }
 
 
-TEST_CASE(MirrorReference) {
+VM_TEST_CASE(MirrorReference) {
   const MirrorReference& reference =
       MirrorReference::Handle(MirrorReference::New(Object::Handle()));
   Object& initial_referent = Object::Handle(reference.referent());
@@ -3766,7 +3781,7 @@
 }
 
 
-TEST_CASE(FindClosureIndex) {
+VM_TEST_CASE(FindClosureIndex) {
   // Allocate the class first.
   const String& class_name = String::Handle(Symbols::New("MyClass"));
   const Script& script = Script::Handle();
@@ -3777,13 +3792,15 @@
   Function& parent = Function::Handle();
   const String& parent_name = String::Handle(Symbols::New("foo_papa"));
   parent = Function::New(parent_name, RawFunction::kRegularFunction,
-                         false, false, false, false, false, cls, 0);
+                         false, false, false, false, false, cls,
+                         TokenPosition::kMinSource);
   functions.SetAt(0, parent);
   cls.SetFunctions(functions);
 
   Function& function = Function::Handle();
   const String& function_name = String::Handle(Symbols::New("foo"));
-  function = Function::NewClosureFunction(function_name, parent, 0);
+  function = Function::NewClosureFunction(function_name, parent,
+                                          TokenPosition::kMinSource);
   // Add closure function to class.
   iso->AddClosureFunction(function);
 
@@ -3802,7 +3819,7 @@
 }
 
 
-TEST_CASE(FindInvocationDispatcherFunctionIndex) {
+VM_TEST_CASE(FindInvocationDispatcherFunctionIndex) {
   const String& class_name = String::Handle(Symbols::New("MyClass"));
   const Script& script = Script::Handle();
   const Class& cls = Class::Handle(CreateDummyClass(class_name, script));
@@ -3812,7 +3829,8 @@
   Function& parent = Function::Handle();
   const String& parent_name = String::Handle(Symbols::New("foo_papa"));
   parent = Function::New(parent_name, RawFunction::kRegularFunction,
-                         false, false, false, false, false, cls, 0);
+                         false, false, false, false, false, cls,
+                         TokenPosition::kMinSource);
   functions.SetAt(0, parent);
   cls.SetFunctions(functions);
   cls.Finalize();
@@ -4053,7 +4071,7 @@
 }
 
 
-TEST_CASE(SpecialClassesHaveEmptyArrays) {
+VM_TEST_CASE(SpecialClassesHaveEmptyArrays) {
   ObjectStore* object_store = Isolate::Current()->object_store();
   Class& cls = Class::Handle();
   Object& array = Object::Handle();
@@ -4108,7 +4126,7 @@
 };
 
 
-TEST_CASE(PrintJSON) {
+VM_TEST_CASE(PrintJSON) {
   Heap* heap = Isolate::Current()->heap();
   heap->CollectAllGarbage();
   GrowableArray<Object*> objects;
@@ -4122,7 +4140,7 @@
 }
 
 
-TEST_CASE(PrintJSONPrimitives) {
+VM_TEST_CASE(PrintJSONPrimitives) {
   char buffer[1024];
   Isolate* isolate = Isolate::Current();
 
@@ -4266,7 +4284,7 @@
         "\"class\":{\"type\":\"@Class\",\"fixedId\":true,\"id\":\"\","
         "\"name\":\"_OneByteString\",\"_vmName\":\"\"},"
         "\"kind\":\"String\","
-        "\"id\":\"\",\"valueAsString\":\"dw\"}",
+        "\"id\":\"\",\"length\":2,\"valueAsString\":\"dw\"}",
         buffer);
   }
   // Array reference
@@ -4587,7 +4605,7 @@
 }
 
 
-TEST_CASE(Symbols_FromConcatAll) {
+VM_TEST_CASE(Symbols_FromConcatAll) {
   {
     const String* data[3] = { &Symbols::FallThroughError(),
                               &Symbols::Dot(),
@@ -4659,7 +4677,7 @@
 };
 
 
-TEST_CASE(String_IdentifierPrettyName) {
+VM_TEST_CASE(String_IdentifierPrettyName) {
   TestResult tests[] = {
     {"(dynamic, dynamic) => void", "(dynamic, dynamic) => void"},
     {"_List@915557746", "_List"},
diff --git a/runtime/vm/os_thread.h b/runtime/vm/os_thread.h
index 84f11b6a..ce22b2b 100644
--- a/runtime/vm/os_thread.h
+++ b/runtime/vm/os_thread.h
@@ -237,9 +237,9 @@
   static OSThread* thread_list_head_;
   static bool creation_enabled_;
 
+  friend class Isolate;  // to access set_thread(Thread*).
   friend class OSThreadIterator;
   friend class ThreadInterrupterWin;
-  friend class ThreadRegistry;
 };
 
 
diff --git a/runtime/vm/pages.cc b/runtime/vm/pages.cc
index 5d5df0e..6ea473a 100644
--- a/runtime/vm/pages.cc
+++ b/runtime/vm/pages.cc
@@ -11,7 +11,7 @@
 #include "vm/lockers.h"
 #include "vm/object.h"
 #include "vm/os_thread.h"
-#include "vm/thread_registry.h"
+#include "vm/safepoint.h"
 #include "vm/verified_memory.h"
 #include "vm/virtual_memory.h"
 
@@ -50,7 +50,9 @@
   ASSERT(memory != NULL);
   ASSERT(memory->size() > VirtualMemory::PageSize());
   bool is_executable = (type == kExecutable);
-  if (!memory->Commit(is_executable)) {
+  // Create the new page executable (RWX) only if we're not in W^X mode
+  bool create_executable = !FLAG_write_protect_code && is_executable;
+  if (!memory->Commit(create_executable)) {
     return NULL;
   }
   HeapPage* result = reinterpret_cast<HeapPage*>(memory->address());
@@ -344,7 +346,8 @@
     // Start of the newly allocated page is the allocated object.
     result = page->object_start();
     // Note: usage_.capacity_in_words is increased by AllocatePage.
-    usage_.used_in_words += size >> kWordSizeLog2;
+    AtomicOperations::FetchAndIncrementBy(&(usage_.used_in_words),
+                                          (size >> kWordSizeLog2));
     // Enqueue the remainder in the free list.
     uword free_start = result + size;
     intptr_t free_size = page->object_end() - free_start;
@@ -381,7 +384,8 @@
       result = TryAllocateInFreshPage(size, type, growth_policy, is_locked);
       // usage_ is updated by the call above.
     } else {
-      usage_.used_in_words += size >> kWordSizeLog2;
+      AtomicOperations::FetchAndIncrementBy(&(usage_.used_in_words),
+                                            (size >> kWordSizeLog2));
     }
   } else {
     // Large page allocation.
@@ -400,21 +404,19 @@
       if (page != NULL) {
         result = page->object_start();
         // Note: usage_.capacity_in_words is increased by AllocateLargePage.
-        usage_.used_in_words += size >> kWordSizeLog2;
+        AtomicOperations::FetchAndIncrementBy(&(usage_.used_in_words),
+                                              (size >> kWordSizeLog2));
       }
     }
   }
-  if (result != 0) {
 #ifdef DEBUG
+  if (result != 0) {
     // A successful allocation should increase usage_.
     ASSERT(usage_before.used_in_words < usage_.used_in_words);
-#endif
-  } else {
-#ifdef DEBUG
-    // A failed allocation should not change used_in_words.
-    ASSERT(usage_before.used_in_words == usage_.used_in_words);
-#endif
   }
+  // Note we cannot assert that a failed allocation should not change
+  // used_in_words as another thread could have changed used_in_words.
+#endif
   ASSERT((result & kObjectAlignmentMask) == kOldObjectAlignmentOffset);
   return result;
 }
@@ -432,14 +434,16 @@
 
 void PageSpace::AllocateExternal(intptr_t size) {
   intptr_t size_in_words = size >> kWordSizeLog2;
-  usage_.external_in_words += size_in_words;
+  AtomicOperations::FetchAndIncrementBy(&(usage_.external_in_words),
+                                        size_in_words);
   // TODO(koda): Control growth.
 }
 
 
 void PageSpace::FreeExternal(intptr_t size) {
   intptr_t size_in_words = size >> kWordSizeLog2;
-  usage_.external_in_words -= size_in_words;
+  AtomicOperations::FetchAndDecrementBy(&(usage_.external_in_words),
+                                        size_in_words);
 }
 
 
@@ -791,6 +795,7 @@
 
 
 void PageSpace::MarkSweep(bool invoke_api_callbacks) {
+  Thread* thread = Thread::Current();
   Isolate* isolate = heap_->isolate();
   ASSERT(isolate == Isolate::Current());
 
@@ -798,114 +803,95 @@
   {
     MonitorLocker locker(tasks_lock());
     while (tasks() > 0) {
-      locker.Wait();
+      locker.WaitWithSafepointCheck(thread);
     }
     set_tasks(1);
   }
-  // Ensure that all threads for this isolate are at a safepoint (either stopped
-  // or in native code). If two threads are racing at this point, the loser
-  // will continue with its collection after waiting for the winner to complete.
-  // TODO(koda): Consider moving SafepointThreads into allocation failure/retry
-  // logic to avoid needless collections.
-  isolate->thread_registry()->SafepointThreads();
-
-  // Perform various cleanup that relies on no tasks interfering.
-  isolate->class_table()->FreeOldTables();
-
-  NoSafepointScope no_safepoints;
-
-  if (FLAG_print_free_list_before_gc) {
-    OS::Print("Data Freelist (before GC):\n");
-    freelist_[HeapPage::kData].Print();
-    OS::Print("Executable Freelist (before GC):\n");
-    freelist_[HeapPage::kExecutable].Print();
-  }
-
-  if (FLAG_verify_before_gc) {
-    OS::PrintErr("Verifying before marking...");
-    heap_->VerifyGC();
-    OS::PrintErr(" done.\n");
-  }
-
-  const int64_t start = OS::GetCurrentTimeMicros();
-
-  // Make code pages writable.
-  WriteProtectCode(false);
-
-  // Save old value before GCMarker visits the weak persistent handles.
-  SpaceUsage usage_before = GetCurrentUsage();
-
-  // Mark all reachable old-gen objects.
-  bool collect_code = FLAG_collect_code && ShouldCollectCode();
-  GCMarker marker(heap_);
-  marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code);
-  usage_.used_in_words = marker.marked_words();
-
-  int64_t mid1 = OS::GetCurrentTimeMicros();
-
-  // Abandon the remainder of the bump allocation block.
-  AbandonBumpAllocation();
-  // Reset the freelists and setup sweeping.
-  freelist_[HeapPage::kData].Reset();
-  freelist_[HeapPage::kExecutable].Reset();
-
-  int64_t mid2 = OS::GetCurrentTimeMicros();
-  int64_t mid3 = 0;
-
+  // Ensure that all threads for this isolate are at a safepoint (either
+  // stopped or in native code). We have guards around Newgen GC and oldgen GC
+  // to ensure that if two threads are racing to collect at the same time the
+  // loser skips collection and goes straight to allocation.
   {
+    SafepointOperationScope safepoint_scope(thread);
+
+    // Perform various cleanup that relies on no tasks interfering.
+    isolate->class_table()->FreeOldTables();
+
+    NoSafepointScope no_safepoints;
+
+    if (FLAG_print_free_list_before_gc) {
+      OS::Print("Data Freelist (before GC):\n");
+      freelist_[HeapPage::kData].Print();
+      OS::Print("Executable Freelist (before GC):\n");
+      freelist_[HeapPage::kExecutable].Print();
+    }
+
     if (FLAG_verify_before_gc) {
-      OS::PrintErr("Verifying before sweeping...");
-      heap_->VerifyGC(kAllowMarked);
+      OS::PrintErr("Verifying before marking...");
+      heap_->VerifyGC();
       OS::PrintErr(" done.\n");
     }
-    GCSweeper sweeper;
 
-    // During stop-the-world phases we should use bulk lock when adding elements
-    // to the free list.
-    MutexLocker mld(freelist_[HeapPage::kData].mutex());
-    MutexLocker mle(freelist_[HeapPage::kExecutable].mutex());
+    const int64_t start = OS::GetCurrentTimeMicros();
 
-    // Large and executable pages are always swept immediately.
-    HeapPage* prev_page = NULL;
-    HeapPage* page = large_pages_;
-    while (page != NULL) {
-      HeapPage* next_page = page->next();
-      const intptr_t words_to_end = sweeper.SweepLargePage(page);
-      if (words_to_end == 0) {
-        FreeLargePage(page, prev_page);
-      } else {
-        TruncateLargePage(page, words_to_end << kWordSizeLog2);
-        prev_page = page;
+    // Make code pages writable.
+    WriteProtectCode(false);
+
+    // Save old value before GCMarker visits the weak persistent handles.
+    SpaceUsage usage_before = GetCurrentUsage();
+
+    // Mark all reachable old-gen objects.
+    bool collect_code = FLAG_collect_code && ShouldCollectCode();
+    GCMarker marker(heap_);
+    marker.MarkObjects(isolate, this, invoke_api_callbacks, collect_code);
+    usage_.used_in_words = marker.marked_words();
+
+    int64_t mid1 = OS::GetCurrentTimeMicros();
+
+    // Abandon the remainder of the bump allocation block.
+    AbandonBumpAllocation();
+    // Reset the freelists and setup sweeping.
+    freelist_[HeapPage::kData].Reset();
+    freelist_[HeapPage::kExecutable].Reset();
+
+    int64_t mid2 = OS::GetCurrentTimeMicros();
+    int64_t mid3 = 0;
+
+    {
+      if (FLAG_verify_before_gc) {
+        OS::PrintErr("Verifying before sweeping...");
+        heap_->VerifyGC(kAllowMarked);
+        OS::PrintErr(" done.\n");
       }
-      // Advance to the next page.
-      page = next_page;
-    }
+      GCSweeper sweeper;
 
-    prev_page = NULL;
-    page = exec_pages_;
-    FreeList* freelist = &freelist_[HeapPage::kExecutable];
-    while (page != NULL) {
-      HeapPage* next_page = page->next();
-      bool page_in_use = sweeper.SweepPage(page, freelist, true);
-      if (page_in_use) {
-        prev_page = page;
-      } else {
-        FreePage(page, prev_page);
-      }
-      // Advance to the next page.
-      page = next_page;
-    }
+      // During stop-the-world phases we should use bulk lock when adding
+      // elements to the free list.
+      MutexLocker mld(freelist_[HeapPage::kData].mutex());
+      MutexLocker mle(freelist_[HeapPage::kExecutable].mutex());
 
-    mid3 = OS::GetCurrentTimeMicros();
-
-    if (!FLAG_concurrent_sweep) {
-      // Sweep all regular sized pages now.
-      prev_page = NULL;
-      page = pages_;
+      // Large and executable pages are always swept immediately.
+      HeapPage* prev_page = NULL;
+      HeapPage* page = large_pages_;
       while (page != NULL) {
         HeapPage* next_page = page->next();
-        bool page_in_use = sweeper.SweepPage(
-            page, &freelist_[page->type()], true);
+        const intptr_t words_to_end = sweeper.SweepLargePage(page);
+        if (words_to_end == 0) {
+          FreeLargePage(page, prev_page);
+        } else {
+          TruncateLargePage(page, words_to_end << kWordSizeLog2);
+          prev_page = page;
+        }
+        // Advance to the next page.
+        page = next_page;
+      }
+
+      prev_page = NULL;
+      page = exec_pages_;
+      FreeList* freelist = &freelist_[HeapPage::kExecutable];
+      while (page != NULL) {
+        HeapPage* next_page = page->next();
+        bool page_in_use = sweeper.SweepPage(page, freelist, true);
         if (page_in_use) {
           prev_page = page;
         } else {
@@ -914,47 +900,65 @@
         // Advance to the next page.
         page = next_page;
       }
-      if (FLAG_verify_after_gc) {
-        OS::PrintErr("Verifying after sweeping...");
-        heap_->VerifyGC(kForbidMarked);
-        OS::PrintErr(" done.\n");
+
+      mid3 = OS::GetCurrentTimeMicros();
+
+      if (!FLAG_concurrent_sweep) {
+        // Sweep all regular sized pages now.
+        prev_page = NULL;
+        page = pages_;
+        while (page != NULL) {
+          HeapPage* next_page = page->next();
+          bool page_in_use = sweeper.SweepPage(
+              page, &freelist_[page->type()], true);
+          if (page_in_use) {
+            prev_page = page;
+          } else {
+            FreePage(page, prev_page);
+          }
+          // Advance to the next page.
+          page = next_page;
+        }
+        if (FLAG_verify_after_gc) {
+          OS::PrintErr("Verifying after sweeping...");
+          heap_->VerifyGC(kForbidMarked);
+          OS::PrintErr(" done.\n");
+        }
+      } else {
+        // Start the concurrent sweeper task now.
+        GCSweeper::SweepConcurrent(
+            isolate, pages_, pages_tail_, &freelist_[HeapPage::kData]);
       }
-    } else {
-      // Start the concurrent sweeper task now.
-      GCSweeper::SweepConcurrent(
-          isolate, pages_, pages_tail_, &freelist_[HeapPage::kData]);
+    }
+
+    // Make code pages read-only.
+    WriteProtectCode(true);
+
+    int64_t end = OS::GetCurrentTimeMicros();
+
+    // Record signals for growth control. Include size of external allocations.
+    page_space_controller_.EvaluateGarbageCollection(usage_before,
+                                                     GetCurrentUsage(),
+                                                     start, end);
+
+    heap_->RecordTime(kMarkObjects, mid1 - start);
+    heap_->RecordTime(kResetFreeLists, mid2 - mid1);
+    heap_->RecordTime(kSweepPages, mid3 - mid2);
+    heap_->RecordTime(kSweepLargePages, end - mid3);
+
+    if (FLAG_print_free_list_after_gc) {
+      OS::Print("Data Freelist (after GC):\n");
+      freelist_[HeapPage::kData].Print();
+      OS::Print("Executable Freelist (after GC):\n");
+      freelist_[HeapPage::kExecutable].Print();
+    }
+
+    UpdateMaxUsed();
+    if (heap_ != NULL) {
+      heap_->UpdateGlobalMaxUsed();
     }
   }
 
-  // Make code pages read-only.
-  WriteProtectCode(true);
-
-  int64_t end = OS::GetCurrentTimeMicros();
-
-  // Record signals for growth control. Include size of external allocations.
-  page_space_controller_.EvaluateGarbageCollection(usage_before,
-                                                   GetCurrentUsage(),
-                                                   start, end);
-
-  heap_->RecordTime(kMarkObjects, mid1 - start);
-  heap_->RecordTime(kResetFreeLists, mid2 - mid1);
-  heap_->RecordTime(kSweepPages, mid3 - mid2);
-  heap_->RecordTime(kSweepLargePages, end - mid3);
-
-  if (FLAG_print_free_list_after_gc) {
-    OS::Print("Data Freelist (after GC):\n");
-    freelist_[HeapPage::kData].Print();
-    OS::Print("Executable Freelist (after GC):\n");
-    freelist_[HeapPage::kExecutable].Print();
-  }
-
-  UpdateMaxUsed();
-  if (heap_ != NULL) {
-    heap_->UpdateGlobalMaxUsed();
-  }
-
-  isolate->thread_registry()->ResumeAllThreads();
-
   // Done, reset the task count.
   {
     MonitorLocker ml(tasks_lock());
@@ -1005,7 +1009,8 @@
   ASSERT(remaining >= size);
   uword result = bump_top_;
   bump_top_ += size;
-  usage_.used_in_words += size >> kWordSizeLog2;
+  AtomicOperations::FetchAndIncrementBy(&(usage_.used_in_words),
+                                        (size >> kWordSizeLog2));
   // Note: Remaining block is unwalkable until MakeIterable is called.
 #ifdef DEBUG
   if (bump_top_ < bump_end_) {
@@ -1035,7 +1040,8 @@
   FreeList* freelist = &freelist_[HeapPage::kData];
   uword result = freelist->TryAllocateSmallLocked(size);
   if (result != 0) {
-    usage_.used_in_words += size >> kWordSizeLog2;
+    AtomicOperations::FetchAndIncrementBy(&(usage_.used_in_words),
+                                          (size >> kWordSizeLog2));
     return result;
   }
   result = TryAllocateDataBumpLocked(size, growth_policy);
diff --git a/runtime/vm/parser.cc b/runtime/vm/parser.cc
index 5440dfb..bed681e 100644
--- a/runtime/vm/parser.cc
+++ b/runtime/vm/parser.cc
@@ -30,6 +30,7 @@
 #include "vm/regexp_assembler.h"
 #include "vm/report.h"
 #include "vm/resolver.h"
+#include "vm/safepoint.h"
 #include "vm/scanner.h"
 #include "vm/scopes.h"
 #include "vm/stack_frame.h"
@@ -67,12 +68,12 @@
 #define Z (zone())
 
 // Quick synthetic token position.
-#define ST(token_pos) Token::ToSynthetic(token_pos)
+#define ST(token_pos) ((token_pos).ToSynthetic())
 
 #if defined(DEBUG)
 class TraceParser : public ValueObject {
  public:
-  TraceParser(intptr_t token_pos,
+  TraceParser(TokenPosition token_pos,
               const Script& script,
               intptr_t* trace_indent,
               const char* msg) {
@@ -84,7 +85,7 @@
         script.GetTokenLocation(token_pos, &line, &column);
         PrintIndent();
         OS::Print("%s (line %" Pd ", col %" Pd ", token %" Pd ")\n",
-                  msg, line, column, token_pos);
+                  msg, line, column, token_pos.value());
       }
       (*indent_)++;
     }
@@ -262,8 +263,11 @@
 
 struct CatchParamDesc {
   CatchParamDesc()
-      : token_pos(Token::kNoSourcePos), type(NULL), name(NULL), var(NULL) { }
-  intptr_t token_pos;
+      : token_pos(TokenPosition::kNoSource),
+        type(NULL),
+        name(NULL),
+        var(NULL) { }
+  TokenPosition token_pos;
   const AbstractType* type;
   const String* name;
   LocalVariable* var;
@@ -349,7 +353,9 @@
 
 
 // For parsing a compilation unit.
-Parser::Parser(const Script& script, const Library& library, intptr_t token_pos)
+Parser::Parser(const Script& script,
+               const Library& library,
+               TokenPosition token_pos)
     : isolate_(Thread::Current()->isolate()),
       thread_(Thread::Current()),
       script_(Script::Handle(zone(), script.raw())),
@@ -380,12 +386,12 @@
 // For parsing a function.
 Parser::Parser(const Script& script,
                ParsedFunction* parsed_function,
-               intptr_t token_position)
+               TokenPosition token_pos)
     : isolate_(Thread::Current()->isolate()),
       thread_(Thread::Current()),
       script_(Script::Handle(zone(), script.raw())),
       tokens_iterator_(TokenStream::Handle(zone(), script.tokens()),
-                       token_position),
+                       token_pos),
       token_kind_(Token::kILLEGAL),
       current_block_(NULL),
       is_top_level_(false),
@@ -435,7 +441,7 @@
 }
 
 
-void Parser::SetScript(const Script& script, intptr_t token_pos) {
+void Parser::SetScript(const Script& script, TokenPosition token_pos) {
   script_ = script.raw();
   tokens_iterator_.SetStream(
       TokenStream::Handle(Z, script.tokens()), token_pos);
@@ -471,7 +477,7 @@
 }
 
 
-void Parser::SetPosition(intptr_t position) {
+void Parser::SetPosition(TokenPosition position) {
   tokens_iterator_.SetCurrentPosition(position);
   token_kind_ = Token::kILLEGAL;
   prev_token_pos_ = position;
@@ -492,7 +498,7 @@
     tds.CopyArgument(0, "script", String::Handle(script.url()).ToCString());
   }
 
-  Parser parser(script, library, 0);
+  Parser parser(script, library, TokenPosition::kMinSource);
   parser.ParseTopLevel();
 }
 
@@ -544,7 +550,7 @@
 struct ParamDesc {
   ParamDesc()
       : type(NULL),
-        name_pos(Token::kNoSourcePos),
+        name_pos(TokenPosition::kNoSource),
         name(NULL),
         default_value(NULL),
         metadata(NULL),
@@ -553,7 +559,7 @@
         is_field_initializer(false),
         has_explicit_type(false) { }
   const AbstractType* type;
-  intptr_t name_pos;
+  TokenPosition name_pos;
   const String* name;
   const Instance* default_value;  // NULL if not an optional parameter.
   const Object* metadata;  // NULL if no metadata or metadata not evaluated.
@@ -581,7 +587,7 @@
     this->parameters = new ZoneGrowableArray<ParamDesc>();
   }
 
-  void AddFinalParameter(intptr_t name_pos,
+  void AddFinalParameter(TokenPosition name_pos,
                          const String* name,
                          const AbstractType* type) {
     this->num_fixed_parameters++;
@@ -593,7 +599,8 @@
     this->parameters->Add(param);
   }
 
-  void AddReceiver(const AbstractType* receiver_type, intptr_t token_pos) {
+  void AddReceiver(const AbstractType* receiver_type,
+                   TokenPosition token_pos) {
     ASSERT(this->parameters->is_empty());
     AddFinalParameter(token_pos, &Symbols::This(), receiver_type);
   }
@@ -649,10 +656,10 @@
     has_factory = false;
     has_operator = false;
     has_native = false;
-    metadata_pos = Token::kNoSourcePos;
+    metadata_pos = TokenPosition::kNoSource;
     operator_token = Token::kILLEGAL;
     type = NULL;
-    name_pos = Token::kNoSourcePos;
+    name_pos = TokenPosition::kNoSource;
     name = NULL;
     redirect_name = NULL;
     dict_name = NULL;
@@ -702,11 +709,11 @@
   bool has_factory;
   bool has_operator;
   bool has_native;
-  intptr_t metadata_pos;
+  TokenPosition metadata_pos;
   Token::Kind operator_token;
   const AbstractType* type;
-  intptr_t name_pos;
-  intptr_t decl_begin_pos;
+  TokenPosition name_pos;
+  TokenPosition decl_begin_pos;
   String* name;
   // For constructors: NULL or name of redirected to constructor.
   String* redirect_name;
@@ -729,7 +736,7 @@
             const Class& cls,
             const String& cls_name,
             bool is_interface,
-            intptr_t token_pos)
+            TokenPosition token_pos)
       : zone_(zone),
         clazz_(cls),
         class_name_(cls_name),
@@ -772,7 +779,7 @@
     return false;
   }
 
-  intptr_t token_pos() const {
+  TokenPosition token_pos() const {
     return token_pos_;
   }
 
@@ -806,7 +813,7 @@
   Zone* zone_;
   const Class& clazz_;
   const String& class_name_;
-  intptr_t token_pos_;   // Token index of "class" keyword.
+  TokenPosition token_pos_;   // Token index of "class" keyword.
   GrowableArray<const Function*> functions_;
   GrowableArray<const Field*> fields_;
   GrowableArray<MemberDesc> members_;
@@ -1068,7 +1075,7 @@
     Zone* zone = stack_zone.GetZone();
     const Class& owner_class = Class::Handle(zone, meta_data.owner());
     const Script& script = Script::Handle(zone, meta_data.script());
-    const intptr_t token_pos = meta_data.token_pos();
+    const TokenPosition token_pos = meta_data.token_pos();
     // Parsing metadata can involve following paths in the parser that are
     // normally used for expressions and assume current_function is non-null,
     // so we create a fake function to use as the current_function rather than
@@ -1113,7 +1120,7 @@
       GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld));
   while (CurrentToken() == Token::kAT) {
     ConsumeToken();
-    intptr_t expr_pos = TokenPos();
+    TokenPosition expr_pos = TokenPos();
     if (!IsIdentifier()) {
       ExpectIdentifier("identifier expected");
     }
@@ -1157,7 +1164,7 @@
                       "or constructor");
         }
         ConsumeToken();
-        const intptr_t ident_pos = TokenPos();
+        const TokenPosition ident_pos = TokenPos();
         String* ident = ExpectIdentifier("identifier expected");
         const Field& field = Field::Handle(Z, cls.LookupStaticField(*ident));
         if (field.IsNull()) {
@@ -1190,7 +1197,7 @@
   CheckToken(Token::kASSIGN, "field initialier expected");
   ConsumeToken();
   OpenFunctionBlock(parsed_function()->function());
-  intptr_t expr_pos = TokenPos();
+  TokenPosition expr_pos = TokenPos();
   AstNode* expr = ParseExpr(kAllowConst, kConsumeCascades);
   ReturnNode* ret = new(Z) ReturnNode(expr_pos, expr);
   current_block_->statements->Add(ret);
@@ -1264,7 +1271,7 @@
   OpenFunctionBlock(func);
   AddFormalParamsToScope(&params, current_block_->scope);
 
-  intptr_t ident_pos = TokenPos();
+  TokenPosition ident_pos = TokenPos();
   const String& field_name = *ExpectIdentifier("field name expected");
   const Class& field_class = Class::Handle(Z, func.Owner());
   const Field& field =
@@ -1274,7 +1281,7 @@
   // Static final fields must have an initializer.
   ExpectToken(Token::kASSIGN);
 
-  const intptr_t expr_pos = TokenPos();
+  const TokenPosition expr_pos = TokenPos();
   if (field.is_const()) {
     // We don't want to use ParseConstExpr() here because we don't want
     // the constant folding code to create, compile and execute a code
@@ -1312,7 +1319,7 @@
   TRACE_PARSER("ParseInstanceGetter");
   ParamList params;
   // func.token_pos() points to the name of the field.
-  const intptr_t ident_pos = func.token_pos();
+  const TokenPosition ident_pos = func.token_pos();
   ASSERT(current_class().raw() == func.Owner());
   params.AddReceiver(ReceiverType(current_class()), ident_pos);
   ASSERT(func.num_fixed_parameters() == 1);  // receiver.
@@ -1351,7 +1358,7 @@
 SequenceNode* Parser::ParseInstanceSetter(const Function& func) {
   TRACE_PARSER("ParseInstanceSetter");
   // func.token_pos() points to the name of the field.
-  const intptr_t ident_pos = func.token_pos();
+  const TokenPosition ident_pos = func.token_pos();
   const String& field_name = *CurrentLiteral();
   const Class& field_class = Class::ZoneHandle(Z, func.Owner());
   const Field& field =
@@ -1388,7 +1395,7 @@
 
 SequenceNode* Parser::ParseConstructorClosure(const Function& func) {
   TRACE_PARSER("ParseConstructorClosure");
-  const intptr_t token_pos = func.token_pos();
+  const TokenPosition token_pos = func.token_pos();
 
   Function& constructor = Function::ZoneHandle(Z);
   TypeArguments& type_args = TypeArguments::ZoneHandle(Z);
@@ -1442,7 +1449,7 @@
 
 SequenceNode* Parser::ParseImplicitClosure(const Function& func) {
   TRACE_PARSER("ParseImplicitClosure");
-  intptr_t token_pos = func.token_pos();
+  TokenPosition token_pos = func.token_pos();
 
   OpenFunctionBlock(func);
 
@@ -1454,7 +1461,7 @@
 
   const Function& parent = Function::ZoneHandle(func.parent_function());
   if (parent.IsImplicitSetterFunction()) {
-    const intptr_t ident_pos = func.token_pos();
+    const TokenPosition ident_pos = func.token_pos();
     ASSERT(IsIdentifier());
     const String& field_name = *CurrentLiteral();
     const Class& field_class = Class::ZoneHandle(Z, parent.Owner());
@@ -1508,8 +1515,8 @@
 
   ParamList params;
 
-  const intptr_t ident_pos = func.token_pos();
-  ASSERT(func.token_pos() == ClassifyingTokenPositions::kMethodExtractor);
+  const TokenPosition ident_pos = func.token_pos();
+  ASSERT(func.token_pos() == TokenPosition::kMethodExtractor);
   ASSERT(current_class().raw() == func.Owner());
   params.AddReceiver(ReceiverType(current_class()), ident_pos);
   ASSERT(func.num_fixed_parameters() == 1);  // Receiver.
@@ -1539,7 +1546,7 @@
                                   const ArgumentsDescriptor& desc) {
   ParamList params;
   // Receiver first.
-  intptr_t token_pos = func.token_pos();
+  TokenPosition token_pos = func.token_pos();
   params.AddReceiver(ReceiverType(current_class()), token_pos);
   // Remaining positional parameters.
   intptr_t i = 1;
@@ -1579,8 +1586,8 @@
   TRACE_PARSER("ParseNoSuchMethodDispatcher");
   ASSERT(FLAG_lazy_dispatchers);
   ASSERT(func.IsNoSuchMethodDispatcher());
-  intptr_t token_pos = func.token_pos();
-  ASSERT(func.token_pos() == 0);
+  TokenPosition token_pos = func.token_pos();
+  ASSERT(func.token_pos() == TokenPosition::kMinSource);
   ASSERT(current_class().raw() == func.Owner());
 
   ArgumentsDescriptor desc(Array::Handle(Z, func.saved_args_desc()));
@@ -1634,8 +1641,8 @@
 SequenceNode* Parser::ParseInvokeFieldDispatcher(const Function& func) {
   TRACE_PARSER("ParseInvokeFieldDispatcher");
   ASSERT(func.IsInvokeFieldDispatcher());
-  intptr_t token_pos = func.token_pos();
-  ASSERT(func.token_pos() == 0);
+  TokenPosition token_pos = func.token_pos();
+  ASSERT(func.token_pos() == TokenPosition::kMinSource);
   ASSERT(current_class().raw() == func.Owner());
 
   const Array& args_desc = Array::Handle(Z, func.saved_args_desc());
@@ -1696,7 +1703,7 @@
 }
 
 
-AstNode* Parser::BuildClosureCall(intptr_t token_pos,
+AstNode* Parser::BuildClosureCall(TokenPosition token_pos,
                                   AstNode* closure,
                                   ArgumentListNode* arguments) {
   return new InstanceCallNode(token_pos,
@@ -1711,17 +1718,17 @@
   ASSERT((opening_token == Token::kLBRACE) ||
          (opening_token == Token::kLPAREN));
   GrowableArray<Token::Kind> token_stack(8);
-  GrowableArray<intptr_t> token_pos_stack(8);
+  GrowableArray<TokenPosition> token_pos_stack(8);
   // Adding the first opening brace here, because it will be consumed
   // in the loop right away.
   token_stack.Add(opening_token);
-  const intptr_t start_pos =  TokenPos();
-  intptr_t opening_pos = start_pos;
+  const TokenPosition start_pos =  TokenPos();
+  TokenPosition opening_pos = start_pos;
   token_pos_stack.Add(start_pos);
   bool is_match = true;
   bool unexpected_token_found = false;
   Token::Kind token = opening_token;
-  intptr_t token_pos;
+  TokenPosition token_pos;
   do {
     ConsumeToken();
     token = CurrentToken();
@@ -1912,7 +1919,7 @@
       // actual current class as owner of the signature function.
       const Function& signature_function = Function::Handle(Z,
           Function::NewSignatureFunction(current_class(),
-                                         Token::kNoSourcePos));
+                                         TokenPosition::kNoSource));
       signature_function.set_result_type(result_type);
       AddFormalParamsToFunction(&func_params, signature_function);
       FunctionType& signature_type =
@@ -2053,7 +2060,7 @@
 // If it is not found, and resolve_getter is true, try to resolve a getter of
 // the same name. If it is still not found, return noSuchMethod and
 // set is_no_such_method to true..
-RawFunction* Parser::GetSuperFunction(intptr_t token_pos,
+RawFunction* Parser::GetSuperFunction(TokenPosition token_pos,
                                       const String& name,
                                       ArgumentListNode* arguments,
                                       bool resolve_getter,
@@ -2089,12 +2096,12 @@
 
 
 StaticCallNode* Parser::BuildInvocationMirrorAllocation(
-    intptr_t call_pos,
+    TokenPosition call_pos,
     const String& function_name,
     const ArgumentListNode& function_args,
     const LocalVariable* temp_for_last_arg,
     bool is_super_invocation) {
-  const intptr_t args_pos = function_args.token_pos();
+  const TokenPosition args_pos = function_args.token_pos();
   // Build arguments to the call to the static
   // InvocationMirror._allocateInvocationMirror method.
   ArgumentListNode* arguments = new ArgumentListNode(args_pos);
@@ -2138,13 +2145,13 @@
 
 
 ArgumentListNode* Parser::BuildNoSuchMethodArguments(
-    intptr_t call_pos,
+    TokenPosition call_pos,
     const String& function_name,
     const ArgumentListNode& function_args,
     const LocalVariable* temp_for_last_arg,
     bool is_super_invocation) {
   ASSERT(function_args.length() >= 1);  // The receiver is the first argument.
-  const intptr_t args_pos = function_args.token_pos();
+  const TokenPosition args_pos = function_args.token_pos();
   ArgumentListNode* arguments = new ArgumentListNode(args_pos);
   arguments->Add(function_args.NodeAt(0));
   // The second argument is the invocation mirror.
@@ -2160,7 +2167,7 @@
 AstNode* Parser::ParseSuperCall(const String& function_name) {
   TRACE_PARSER("ParseSuperCall");
   ASSERT(CurrentToken() == Token::kLPAREN);
-  const intptr_t supercall_pos = TokenPos();
+  const TokenPosition supercall_pos = TokenPos();
 
   // 'this' parameter is the first argument to super call.
   ArgumentListNode* arguments = new ArgumentListNode(supercall_pos);
@@ -2208,7 +2215,7 @@
 AstNode* Parser::BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super) {
   ASSERT(super->IsSuper());
   AstNode* super_op = NULL;
-  const intptr_t super_pos = super->token_pos();
+  const TokenPosition super_pos = super->token_pos();
   if ((op == Token::kNEGATE) ||
       (op == Token::kBIT_NOT)) {
     // Resolve the operator function in the superclass.
@@ -2240,7 +2247,7 @@
 AstNode* Parser::ParseSuperOperator() {
   TRACE_PARSER("ParseSuperOperator");
   AstNode* super_op = NULL;
-  const intptr_t operator_pos = TokenPos();
+  const TokenPosition operator_pos = TokenPos();
 
   if (CurrentToken() == Token::kLBRACK) {
     ConsumeToken();
@@ -2297,7 +2304,7 @@
 
 
 ClosureNode* Parser::CreateImplicitClosureNode(const Function& func,
-                                               intptr_t token_pos,
+                                               TokenPosition token_pos,
                                                AstNode* receiver) {
   Function& implicit_closure_function =
       Function::ZoneHandle(Z, func.ImplicitClosureFunction());
@@ -2319,7 +2326,7 @@
 
 
 AstNode* Parser::ParseSuperFieldAccess(const String& field_name,
-                                       intptr_t field_pos) {
+                                       TokenPosition field_pos) {
   TRACE_PARSER("ParseSuperFieldAccess");
   const Class& super_class = Class::ZoneHandle(Z, current_class().SuperClass());
   if (super_class.IsNull()) {
@@ -2366,7 +2373,7 @@
 
 StaticCallNode* Parser::GenerateSuperConstructorCall(
       const Class& cls,
-      intptr_t supercall_pos,
+      TokenPosition supercall_pos,
       LocalVariable* receiver,
       ArgumentListNode* forwarding_args) {
   const Class& super_class = Class::Handle(Z, cls.SuperClass());
@@ -2433,7 +2440,7 @@
                                               LocalVariable* receiver) {
   TRACE_PARSER("ParseSuperInitializer");
   ASSERT(CurrentToken() == Token::kSUPER);
-  const intptr_t supercall_pos = TokenPos();
+  const TokenPosition supercall_pos = TokenPos();
   ConsumeToken();
   const Class& super_class = Class::Handle(Z, cls.SuperClass());
   ASSERT(!super_class.IsNull());
@@ -2484,7 +2491,7 @@
                                   LocalVariable* receiver,
                                   GrowableArray<Field*>* initialized_fields) {
   TRACE_PARSER("ParseInitializer");
-  const intptr_t field_pos = TokenPos();
+  const TokenPosition field_pos = TokenPos();
   if (CurrentToken() == Token::kTHIS) {
     ConsumeToken();
     ExpectToken(Token::kPERIOD);
@@ -2560,7 +2567,7 @@
   const Class& saved_class = Class::Handle(Z, current_class().raw());
   const Library& saved_library = Library::Handle(Z, library().raw());
   const Script& saved_script = Script::Handle(Z, script().raw());
-  const intptr_t saved_token_pos = TokenPos();
+  const TokenPosition saved_token_pos = TokenPos();
 
   set_current_class(Class::Handle(Z, field.origin()));
   set_library(Library::Handle(Z, current_class().library()));
@@ -2570,7 +2577,7 @@
   ConsumeToken();
   ExpectToken(Token::kASSIGN);
   AstNode* init_expr = NULL;
-  intptr_t expr_pos = TokenPos();
+  TokenPosition expr_pos = TokenPos();
   if (field.is_const()) {
     init_expr = ParseConstExpr();
   } else {
@@ -2597,7 +2604,7 @@
   TRACE_PARSER("ParseInitializedInstanceFields");
   const Array& fields = Array::Handle(Z, cls.fields());
   Field& f = Field::Handle(Z);
-  const intptr_t saved_pos = TokenPos();
+  const TokenPosition saved_pos = TokenPos();
   for (int i = 0; i < fields.Length(); i++) {
     f ^= fields.At(i);
     if (!f.is_static() && f.has_initializer()) {
@@ -2622,7 +2629,7 @@
           // expression must be a compile-time constant.
           init_expr = ParseConstExpr();
         } else {
-          intptr_t expr_pos = TokenPos();
+          TokenPosition expr_pos = TokenPos();
           init_expr = ParseExpr(kAllowConst, kConsumeCascades);
           if (init_expr->EvalConstExpr() != NULL) {
             Instance& expr_value = Instance::ZoneHandle(Z);
@@ -2651,7 +2658,7 @@
 
 
 AstNode* Parser::CheckDuplicateFieldInit(
-    intptr_t init_pos,
+    TokenPosition init_pos,
     GrowableArray<Field*>* initialized_fields,
     AstNode* instance,
     Field* field,
@@ -2824,7 +2831,7 @@
   TRACE_PARSER("ParseConstructorRedirection");
   ExpectToken(Token::kCOLON);
   ASSERT(CurrentToken() == Token::kTHIS);
-  const intptr_t call_pos = TokenPos();
+  const TokenPosition call_pos = TokenPos();
   ConsumeToken();
   String& ctor_name = String::Handle(Z, cls.Name());
   GrowableHandlePtrArray<const String> pieces(Z, 3);
@@ -2868,11 +2875,13 @@
 SequenceNode* Parser::MakeImplicitConstructor(const Function& func) {
   ASSERT(func.IsGenerativeConstructor());
   ASSERT(func.Owner() == current_class().raw());
-  const intptr_t ctor_pos = TokenPos();
+  const TokenPosition ctor_pos = TokenPos();
   OpenFunctionBlock(func);
 
   LocalVariable* receiver = new LocalVariable(
-      Token::kNoSourcePos, Symbols::This(), *ReceiverType(current_class()));
+      TokenPosition::kNoSource,
+      Symbols::This(),
+      *ReceiverType(current_class()));
   current_block_->scope->InsertParameterAt(0, receiver);
 
   // Parse expressions of instance fields that have an explicit
@@ -2918,7 +2927,7 @@
     forwarding_args = new ArgumentListNode(ST(ctor_pos));
     for (int i = 1; i < func.NumParameters(); i++) {
       LocalVariable* param = new LocalVariable(
-          Token::kNoSourcePos,
+          TokenPosition::kNoSource,
           String::ZoneHandle(Z, func.ParameterNameAt(i)),
           Object::dynamic_type());
       current_block_->scope->InsertParameterAt(i, param);
@@ -3275,7 +3284,7 @@
     }
   }
 
-  const intptr_t modifier_pos = TokenPos();
+  const TokenPosition modifier_pos = TokenPos();
   RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
   if (!func.is_generated_body()) {
     // Don't add a modifier to the closure representing the body of
@@ -3314,7 +3323,7 @@
 
   BoolScope allow_await(&this->await_is_keyword_,
                         func.IsAsyncOrGenerator() || func.is_generated_body());
-  intptr_t end_token_pos = Token::kNoSourcePos;
+  TokenPosition end_token_pos = TokenPosition::kNoSource;
   if (CurrentToken() == Token::kLBRACE) {
     ConsumeToken();
     if (String::Handle(Z, func.name()).Equals(Symbols::EqualOperator())) {
@@ -3339,7 +3348,7 @@
         AddEqualityNullCheck();
       }
     }
-    const intptr_t expr_pos = TokenPos();
+    const TokenPosition expr_pos = TokenPos();
     AstNode* expr = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
     ASSERT(expr != NULL);
     current_block_->statements->Add(new ReturnNode(expr_pos, expr));
@@ -3407,24 +3416,24 @@
 
 void Parser::AddEqualityNullCheck() {
   AstNode* argument =
-      new LoadLocalNode(Token::kNoSourcePos,
+      new LoadLocalNode(TokenPosition::kNoSource,
                         current_block_->scope->parent()->VariableAt(1));
   LiteralNode* null_operand =
-      new LiteralNode(Token::kNoSourcePos, Instance::ZoneHandle(Z));
+      new LiteralNode(TokenPosition::kNoSource, Instance::ZoneHandle(Z));
   ComparisonNode* check_arg =
-      new ComparisonNode(Token::kNoSourcePos,
+      new ComparisonNode(TokenPosition::kNoSource,
                          Token::kEQ_STRICT,
                          argument,
                          null_operand);
   ComparisonNode* result =
-      new ComparisonNode(Token::kNoSourcePos,
+      new ComparisonNode(TokenPosition::kNoSource,
                          Token::kEQ_STRICT,
-                         LoadReceiver(Token::kNoSourcePos),
+                         LoadReceiver(TokenPosition::kNoSource),
                          null_operand);
-  SequenceNode* arg_is_null = new SequenceNode(Token::kNoSourcePos,
+  SequenceNode* arg_is_null = new SequenceNode(TokenPosition::kNoSource,
                                                current_block_->scope);
-  arg_is_null->Add(new ReturnNode(Token::kNoSourcePos, result));
-  IfNode* if_arg_null = new IfNode(Token::kNoSourcePos,
+  arg_is_null->Add(new ReturnNode(TokenPosition::kNoSource, result));
+  IfNode* if_arg_null = new IfNode(TokenPosition::kNoSource,
                                    check_arg,
                                    arg_is_null,
                                    NULL);
@@ -3536,7 +3545,7 @@
   // Parse the formal parameters.
   const bool are_implicitly_final = method->has_const;
   const bool allow_explicit_default_values = true;
-  const intptr_t formal_param_pos = TokenPos();
+  const TokenPosition formal_param_pos = TokenPos();
   method->params.Clear();
   // Static functions do not have a receiver.
   // The first parameter of a factory is the TypeArguments vector of
@@ -3610,7 +3619,7 @@
                   method->name->ToCString());
     }
     ConsumeToken();
-    const intptr_t type_pos = TokenPos();
+    const TokenPosition type_pos = TokenPos();
     is_redirecting = true;
     const bool consume_unresolved_prefix =
         (LookaheadToken(3) == Token::kLT) ||
@@ -3689,7 +3698,7 @@
                 method->name->ToCString());
   }
 
-  const intptr_t modifier_pos = TokenPos();
+  const TokenPosition modifier_pos = TokenPos();
   RawFunction::AsyncModifier async_modifier = ParseFunctionModifier();
   if ((method->IsFactoryOrConstructor() || method->IsSetter()) &&
       (async_modifier != RawFunction::kNoModifier)) {
@@ -3699,7 +3708,7 @@
                 method->name->ToCString());
   }
 
-  intptr_t method_end_pos = TokenPos();
+  TokenPosition method_end_pos = TokenPos();
   String* native_name = NULL;
   if ((CurrentToken() == Token::kLBRACE) ||
       (CurrentToken() == Token::kARROW)) {
@@ -3831,7 +3840,7 @@
   if (library_.is_dart_scheme() && library_.IsPrivate(*method->name)) {
     func.set_is_reflectable(false);
   }
-  if (FLAG_enable_mirrors && (method->metadata_pos >= 0)) {
+  if (FLAG_enable_mirrors && (method->metadata_pos.IsReal())) {
     library_.AddFunctionMetadata(func, method->metadata_pos);
   }
   if (method->has_native) {
@@ -3862,7 +3871,7 @@
          CurrentToken() == Token::kCOMMA ||
          CurrentToken() == Token::kASSIGN);
   ASSERT(field->type != NULL);
-  ASSERT(field->name_pos >= 0);
+  ASSERT(field->name_pos.IsReal());
   ASSERT(current_member_ == field);
   // All const fields are also final.
   ASSERT(!field->has_const || field->has_final);
@@ -3931,7 +3940,7 @@
     class_field.set_has_initializer(has_initializer);
     members->AddField(class_field);
     field->field_ = &class_field;
-    if (FLAG_enable_mirrors && (field->metadata_pos >= 0)) {
+    if (FLAG_enable_mirrors && (field->metadata_pos.IsReal())) {
       library_.AddFieldMetadata(class_field, field->metadata_pos);
     }
 
@@ -4078,7 +4087,7 @@
 
 
 void Parser::ParseClassMemberDefinition(ClassDesc* members,
-                                        intptr_t metadata_pos) {
+                                        TokenPosition metadata_pos) {
   TRACE_PARSER("ParseClassMemberDefinition");
   MemberDesc member;
   current_member_ = &member;
@@ -4289,12 +4298,12 @@
 
 void Parser::ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
                                   const Object& tl_owner,
-                                  intptr_t metadata_pos) {
+                                  TokenPosition metadata_pos) {
   TRACE_PARSER("ParseEnumDeclaration");
-  const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos
-                                                       : TokenPos();
+  const TokenPosition declaration_pos =
+      (metadata_pos.IsReal()) ? metadata_pos : TokenPos();
   ConsumeToken();
-  const intptr_t name_pos = TokenPos();
+  const TokenPosition name_pos = TokenPos();
   String* enum_name =
       ExpectUserDefinedTypeIdentifier("enum type name expected");
   if (FLAG_trace_parser) {
@@ -4329,7 +4338,7 @@
   library_.AddClass(cls);
   cls.set_is_synthesized_class();
   cls.set_is_enum_class();
-  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+  if (FLAG_enable_mirrors && (metadata_pos.IsReal())) {
     library_.AddClassMetadata(cls, tl_owner, metadata_pos);
   }
   cls.set_super_type(Type::Handle(Z, Type::ObjectType()));
@@ -4339,11 +4348,12 @@
 
 void Parser::ParseClassDeclaration(const GrowableObjectArray& pending_classes,
                                    const Object& tl_owner,
-                                   intptr_t metadata_pos) {
+                                   TokenPosition metadata_pos) {
   TRACE_PARSER("ParseClassDeclaration");
   bool is_patch = false;
   bool is_abstract = false;
-  intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos();
+  TokenPosition declaration_pos =
+      metadata_pos.IsReal() ? metadata_pos : TokenPos();
   if (is_patch_source() &&
       (CurrentToken() == Token::kIDENT) &&
       CurrentLiteral()->Equals("patch")) {
@@ -4354,7 +4364,7 @@
     ConsumeToken();
   }
   ExpectToken(Token::kCLASS);
-  const intptr_t classname_pos = TokenPos();
+  const TokenPosition classname_pos = TokenPos();
   String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected");
   if (FLAG_trace_parser) {
     OS::Print("TopLevel parsing class '%s'\n", class_name.ToCString());
@@ -4448,7 +4458,7 @@
   if (is_abstract) {
     cls.set_is_abstract();
   }
-  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+  if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
     library_.AddClassMetadata(cls, tl_owner, metadata_pos);
   }
 
@@ -4462,7 +4472,7 @@
   AbstractType& super_type = Type::Handle(Z);
   if ((CurrentToken() == Token::kEXTENDS) || is_mixin_declaration) {
     ConsumeToken();  // extends or =
-    const intptr_t type_pos = TokenPos();
+    const TokenPosition type_pos = TokenPos();
     super_type = ParseType(ClassFinalizer::kResolveTypeParameters);
     if (super_type.IsMalformedOrMalbounded()) {
       ReportError(Error::Handle(Z, super_type.error()));
@@ -4539,14 +4549,14 @@
     ConsumeToken();
   }
   ExpectToken(Token::kCLASS);
-  const intptr_t class_pos = TokenPos();
+  const TokenPosition class_pos = TokenPos();
   ClassDesc members(Z, cls, class_name, false, class_pos);
   while (CurrentToken() != Token::kLBRACE) {
     ConsumeToken();
   }
   ExpectToken(Token::kLBRACE);
   while (CurrentToken() != Token::kRBRACE) {
-    intptr_t metadata_pos = SkipMetadata();
+    TokenPosition metadata_pos = SkipMetadata();
     ParseClassMemberDefinition(&members, metadata_pos);
   }
   ExpectToken(Token::kRBRACE);
@@ -4825,9 +4835,9 @@
 void Parser::ParseMixinAppAlias(
     const GrowableObjectArray& pending_classes,
     const Object& tl_owner,
-    intptr_t metadata_pos) {
+    TokenPosition metadata_pos) {
   TRACE_PARSER("ParseMixinAppAlias");
-  const intptr_t classname_pos = TokenPos();
+  const TokenPosition classname_pos = TokenPos();
   String& class_name = *ExpectUserDefinedTypeIdentifier("class name expected");
   if (FLAG_trace_parser) {
     OS::Print("toplevel parsing mixin application alias class '%s'\n",
@@ -4852,7 +4862,7 @@
     ConsumeToken();
   }
 
-  const intptr_t type_pos = TokenPos();
+  const TokenPosition type_pos = TokenPos();
   AbstractType& type =
       AbstractType::Handle(Z,
                            ParseType(ClassFinalizer::kResolveTypeParameters));
@@ -4877,7 +4887,7 @@
   }
   ExpectSemicolon();
   pending_classes.Add(mixin_application, Heap::kOld);
-  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+  if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
     library_.AddClassMetadata(mixin_application, tl_owner, metadata_pos);
   }
 }
@@ -4891,7 +4901,7 @@
   if (IsIdentifier() && (LookaheadToken(1) == Token::kLPAREN)) {
     return true;
   }
-  const intptr_t saved_pos = TokenPos();
+  const TokenPosition saved_pos = TokenPos();
   bool is_alias_name = false;
   if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
     ConsumeToken();
@@ -4910,7 +4920,7 @@
   if (IsIdentifier() && (LookaheadToken(1) == Token::kASSIGN)) {
     return true;
   }
-  const intptr_t saved_pos = TokenPos();
+  const TokenPosition saved_pos = TokenPos();
   bool is_mixin_def = false;
   if (IsIdentifier() && (LookaheadToken(1) == Token::kLT)) {
     ConsumeToken();
@@ -4925,9 +4935,10 @@
 
 void Parser::ParseTypedef(const GrowableObjectArray& pending_classes,
                           const Object& tl_owner,
-                          intptr_t metadata_pos) {
+                          TokenPosition metadata_pos) {
   TRACE_PARSER("ParseTypedef");
-  intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos : TokenPos();
+  TokenPosition declaration_pos =
+      metadata_pos.IsReal() ? metadata_pos : TokenPos();
   ExpectToken(Token::kTYPEDEF);
 
   if (IsMixinAppAlias()) {
@@ -4949,7 +4960,7 @@
     result_type = ParseType(ClassFinalizer::kDoNotResolve);
   }
 
-  const intptr_t alias_name_pos = TokenPos();
+  const TokenPosition alias_name_pos = TokenPos();
   const String* alias_name =
       ExpectUserDefinedTypeIdentifier("function alias name expected");
 
@@ -5012,7 +5023,7 @@
   // checked in the class finalizer for illegal self references.
   ASSERT(!function_type_alias.is_finalized());
   pending_classes.Add(function_type_alias, Heap::kOld);
-  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+  if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
     library_.AddClassMetadata(function_type_alias,
                               tl_owner,
                               metadata_pos);
@@ -5035,11 +5046,11 @@
 }
 
 
-intptr_t Parser::SkipMetadata() {
+TokenPosition Parser::SkipMetadata() {
   if (CurrentToken() != Token::kAT) {
-    return Token::kNoSourcePos;
+    return TokenPosition::kNoSource;
   }
-  intptr_t metadata_pos = TokenPos();
+  TokenPosition metadata_pos = TokenPos();
   while (CurrentToken() == Token::kAT) {
     ConsumeToken();
     ExpectIdentifier("identifier expected");
@@ -5103,10 +5114,10 @@
     AbstractType& type_parameter_bound = Type::Handle(Z);
     do {
       ConsumeToken();
-      const intptr_t metadata_pos = SkipMetadata();
-      const intptr_t type_parameter_pos = TokenPos();
-      const intptr_t declaration_pos = (metadata_pos >= 0) ? metadata_pos
-                                                           : type_parameter_pos;
+      const TokenPosition metadata_pos = SkipMetadata();
+      const TokenPosition type_parameter_pos = TokenPos();
+      const TokenPosition declaration_pos =
+          metadata_pos.IsReal() ? metadata_pos : type_parameter_pos;
       String& type_parameter_name =
           *ExpectUserDefinedTypeIdentifier("type parameter expected");
       // Check for duplicate type parameters.
@@ -5135,7 +5146,7 @@
                                           declaration_pos);
       type_parameters_array.Add(
           &AbstractType::ZoneHandle(Z, type_parameter.raw()));
-      if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+      if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
         library_.AddTypeParameterMetadata(type_parameter, metadata_pos);
       }
       index++;
@@ -5210,7 +5221,7 @@
   // Now parse and add the new interfaces.
   do {
     ConsumeToken();
-    intptr_t interface_pos = TokenPos();
+    TokenPosition interface_pos = TokenPos();
     interface = ParseType(ClassFinalizer::kResolveTypeParameters);
     if (interface.IsTypeParameter()) {
       ReportError(interface_pos,
@@ -5252,7 +5263,7 @@
 
 void Parser::ParseTopLevelVariable(TopLevel* top_level,
                                    const Object& owner,
-                                   intptr_t metadata_pos) {
+                                   TokenPosition metadata_pos) {
   TRACE_PARSER("ParseTopLevelVariable");
   const bool is_const = (CurrentToken() == Token::kCONST);
   // Const fields are implicitly final.
@@ -5263,7 +5274,7 @@
   Field& field = Field::Handle(Z);
   Function& getter = Function::Handle(Z);
   while (true) {
-    const intptr_t name_pos = TokenPos();
+    const TokenPosition name_pos = TokenPos();
     String& var_name = *ExpectIdentifier("variable name expected");
 
     if (library_.LookupLocalObject(var_name) != Object::null()) {
@@ -5294,7 +5305,7 @@
     field.SetStaticValue(Object::null_instance(), true);
     top_level->AddField(field);
     library_.AddObject(field, var_name);
-    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+    if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
       library_.AddFieldMetadata(field, metadata_pos);
     }
     if (CurrentToken() == Token::kASSIGN) {
@@ -5370,9 +5381,9 @@
 
 void Parser::ParseTopLevelFunction(TopLevel* top_level,
                                    const Object& owner,
-                                   intptr_t metadata_pos) {
+                                   TokenPosition metadata_pos) {
   TRACE_PARSER("ParseTopLevelFunction");
-  const intptr_t decl_begin_pos = TokenPos();
+  const TokenPosition decl_begin_pos = TokenPos();
   AbstractType& result_type = Type::Handle(Z, Type::DynamicType());
   const bool is_static = true;
   bool is_external = false;
@@ -5397,7 +5408,7 @@
       result_type = ParseType(ClassFinalizer::kResolveTypeParameters);
     }
   }
-  const intptr_t name_pos = TokenPos();
+  const TokenPosition name_pos = TokenPos();
   const String& func_name = *ExpectIdentifier("function name expected");
 
   bool found = library_.LookupLocalObject(func_name) != Object::null();
@@ -5416,15 +5427,15 @@
   // not need to check setters.
 
   CheckToken(Token::kLPAREN);
-  const intptr_t function_pos = TokenPos();
+  const TokenPosition function_pos = TokenPos();
   ParamList params;
   const bool allow_explicit_default_values = true;
   ParseFormalParameterList(allow_explicit_default_values, false, &params);
 
-  const intptr_t modifier_pos = TokenPos();
+  const TokenPosition modifier_pos = TokenPos();
   RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
 
-  intptr_t function_end_pos = function_pos;
+  TokenPosition function_end_pos = function_pos;
   bool is_native = false;
   String* native_name = NULL;
   if (is_external) {
@@ -5485,7 +5496,7 @@
     toplevel_cls.RemoveFunction(replaced_func);
     library_.ReplaceObject(func, func_name);
   }
-  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+  if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
     library_.AddFunctionMetadata(func, metadata_pos);
   }
 }
@@ -5493,9 +5504,9 @@
 
 void Parser::ParseTopLevelAccessor(TopLevel* top_level,
                                    const Object& owner,
-                                   intptr_t metadata_pos) {
+                                   TokenPosition metadata_pos) {
   TRACE_PARSER("ParseTopLevelAccessor");
-  const intptr_t decl_begin_pos = TokenPos();
+  const TokenPosition decl_begin_pos = TokenPos();
   const bool is_static = true;
   bool is_external = false;
   bool is_patch = false;
@@ -5528,10 +5539,10 @@
       UnexpectedToken();
     }
   }
-  const intptr_t name_pos = TokenPos();
+  const TokenPosition name_pos = TokenPos();
   const String* field_name = ExpectIdentifier("accessor name expected");
 
-  const intptr_t accessor_pos = TokenPos();
+  const TokenPosition accessor_pos = TokenPos();
   ParamList params;
 
   if (!is_getter) {
@@ -5578,14 +5589,14 @@
                 field_name->ToCString());
   }
 
-  const intptr_t modifier_pos = TokenPos();
+  const TokenPosition modifier_pos = TokenPos();
   RawFunction::AsyncModifier func_modifier = ParseFunctionModifier();
   if (!is_getter && (func_modifier != RawFunction::kNoModifier)) {
     ReportError(modifier_pos,
                 "setter function cannot be async, async* or sync*");
   }
 
-  intptr_t accessor_end_pos = accessor_pos;
+  TokenPosition accessor_end_pos = accessor_pos;
   bool is_native = false;
   String* native_name = NULL;
   if (is_external) {
@@ -5650,14 +5661,14 @@
     toplevel_cls.RemoveFunction(replaced_func);
     library_.ReplaceObject(func, accessor_name);
   }
-  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+  if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
     library_.AddFunctionMetadata(func, metadata_pos);
   }
 }
 
 
 RawObject* Parser::CallLibraryTagHandler(Dart_LibraryTag tag,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          const String& url) {
   Dart_LibraryTagHandler handler = I->library_tag_handler();
   if (handler == NULL) {
@@ -5672,24 +5683,28 @@
   // Block class finalization attempts when calling into the library
   // tag handler.
   I->BlockClassFinalization();
-  Api::Scope api_scope(T);
-  Dart_Handle result = handler(tag,
-                               Api::NewHandle(T, library_.raw()),
-                               Api::NewHandle(T, url.raw()));
+  Object& result = Object::Handle(Z);
+  {
+    TransitionVMToNative transition(T);
+    Api::Scope api_scope(T);
+    Dart_Handle retval = handler(tag,
+                                 Api::NewHandle(T, library_.raw()),
+                                 Api::NewHandle(T, url.raw()));
+    result = Api::UnwrapHandle(retval);
+  }
   I->UnblockClassFinalization();
-  if (Dart_IsError(result)) {
+  if (result.IsError()) {
     // In case of an error we append an explanatory error message to the
     // error obtained from the library tag handler.
-    Error& prev_error = Error::Handle(Z);
-    prev_error ^= Api::UnwrapHandle(result);
+    const Error& prev_error = Error::Cast(result);
     Report::LongJumpF(prev_error, script_, token_pos, "library handler failed");
   }
   if (tag == Dart_kCanonicalizeUrl) {
-    if (!Dart_IsString(result)) {
+    if (!result.IsString()) {
       ReportError(token_pos, "library handler failed URI canonicalization");
     }
   }
-  return Api::UnwrapHandle(result);
+  return result.raw();
 }
 
 
@@ -5728,11 +5743,11 @@
 
 
 void Parser::ParseLibraryImportExport(const Object& tl_owner,
-                                      intptr_t metadata_pos) {
+                                      TokenPosition metadata_pos) {
   bool is_import = (CurrentToken() == Token::kIMPORT);
   bool is_export = (CurrentToken() == Token::kEXPORT);
   ASSERT(is_import || is_export);
-  const intptr_t import_pos = TokenPos();
+  const TokenPosition import_pos = TokenPos();
   ConsumeToken();
   CheckToken(Token::kSTRING, "library url expected");
   AstNode* url_literal = ParseStringLiteral(false);
@@ -5796,7 +5811,7 @@
     CheckToken(Token::kAS, "'as' expected");
   }
   String& prefix = String::Handle(Z);
-  intptr_t prefix_pos = Token::kNoSourcePos;
+  TokenPosition prefix_pos = TokenPosition::kNoSource;
   if (is_import && (CurrentToken() == Token::kAS)) {
     ConsumeToken();
     prefix_pos = TokenPos();
@@ -5859,7 +5874,7 @@
 
   Namespace& ns = Namespace::Handle(Z,
       Namespace::New(library, show_names, hide_names));
-  if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+  if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
     ns.AddMetadata(tl_owner, metadata_pos);
   }
 
@@ -5909,7 +5924,7 @@
 
 
 void Parser::ParseLibraryPart() {
-  const intptr_t source_pos = TokenPos();
+  const TokenPosition source_pos = TokenPos();
   ConsumeToken();  // Consume "part".
   CheckToken(Token::kSTRING, "url expected");
   AstNode* url_literal = ParseStringLiteral(false);
@@ -5938,14 +5953,14 @@
   // declaration that follows the library definitions. Therefore, we
   // need to remember the position of the last token that was
   // successfully consumed.
-  intptr_t rewind_pos = TokenPos();
-  intptr_t metadata_pos = SkipMetadata();
+  TokenPosition rewind_pos = TokenPos();
+  TokenPosition metadata_pos = SkipMetadata();
   if (CurrentToken() == Token::kLIBRARY) {
     if (is_patch_source()) {
       ReportError("patch cannot override library name");
     }
     ParseLibraryName();
-    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+    if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
       library_.AddLibraryMetadata(tl_owner, metadata_pos);
     }
     rewind_pos = TokenPos();
@@ -6002,7 +6017,7 @@
   ObjectStore* object_store = I->object_store();
   const GrowableObjectArray& pending_classes =
       GrowableObjectArray::Handle(Z, object_store->pending_classes());
-  SetPosition(0);
+  SetPosition(TokenPosition::kMinSource);
   is_top_level_ = true;
   TopLevel top_level(Z);
 
@@ -6027,7 +6042,7 @@
   const Class& cls = Class::Handle(Z);
   while (true) {
     set_current_class(cls);  // No current class.
-    intptr_t metadata_pos = SkipMetadata();
+    TokenPosition metadata_pos = SkipMetadata();
     if (CurrentToken() == Token::kCLASS) {
       ParseClassDeclaration(pending_classes, tl_owner, metadata_pos);
     } else if (CurrentToken() == Token::kENUM) {
@@ -6152,7 +6167,7 @@
   // We only get here when parsing an async generator body.
   ASSERT(innermost_function().IsAsyncGenClosure());
 
-  const intptr_t try_end_pos = innermost_function().end_token_pos();
+  const TokenPosition try_end_pos = innermost_function().end_token_pos();
 
   // The try-block (closure body code) has been parsed. We are now
   // generating the code for the catch block.
@@ -6164,10 +6179,10 @@
   // Add the exception and stack trace parameters to the scope.
   CatchParamDesc exception_param;
   CatchParamDesc stack_trace_param;
-  exception_param.token_pos = Token::kNoSourcePos;
+  exception_param.token_pos = TokenPosition::kNoSource;
   exception_param.type = &Object::dynamic_type();
   exception_param.name = &Symbols::ExceptionParameter();
-  stack_trace_param.token_pos = Token::kNoSourcePos;
+  stack_trace_param.token_pos = TokenPosition::kNoSource;
   stack_trace_param.type = &Object::dynamic_type();
   stack_trace_param.name = &Symbols::StackTraceParameter();
 
@@ -6187,9 +6202,9 @@
     // Generate code to load the exception object (:exception_var) into
     // the exception variable specified in this block.
     current_block_->statements->Add(new(Z) StoreLocalNode(
-        Token::kNoSourcePos,
+        TokenPosition::kNoSource,
         exception_param.var,
-        new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var)));
+        new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var)));
   }
 
   LocalVariable* stack_trace_var =
@@ -6200,9 +6215,9 @@
     // to load the stack trace object (:stack_trace_var) into the stack
     // trace variable specified in this block.
     current_block_->statements->Add(new(Z) StoreLocalNode(
-        Token::kNoSourcePos,
+        TokenPosition::kNoSource,
         stack_trace_param.var,
-        new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var)));
+        new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var)));
   }
   LocalVariable* saved_exception_var = try_scope->LocalLookupVariable(
       Symbols::SavedExceptionVar());
@@ -6221,15 +6236,17 @@
       current_block_->scope->LookupVariable(Symbols::Controller(), false);
   ASSERT(controller != NULL);
   ArgumentListNode* args =
-      new(Z) ArgumentListNode(Token::kNoSourcePos);
-  args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var));
-  args->Add(new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var));
+      new(Z) ArgumentListNode(TokenPosition::kNoSource);
+  args->Add(new(Z) LoadLocalNode(
+      TokenPosition::kNoSource, exception_param.var));
+  args->Add(new(Z) LoadLocalNode(
+      TokenPosition::kNoSource, stack_trace_param.var));
   current_block_->statements->Add(
       new(Z) InstanceCallNode(try_end_pos,
-          new(Z) LoadLocalNode(Token::kNoSourcePos, controller),
+          new(Z) LoadLocalNode(TokenPosition::kNoSource, controller),
           Symbols::AddError(),
           args));
-  ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos);
+  ReturnNode* return_node = new(Z) ReturnNode(TokenPosition::kNoSource);
   AddNodeForFinallyInlining(return_node);
   current_block_->statements->Add(return_node);
   AstNode* catch_block = CloseBlock();
@@ -6254,10 +6271,10 @@
   do {
     OpenBlock();
     ArgumentListNode* no_args =
-        new(Z) ArgumentListNode(Token::kNoSourcePos);
+        new(Z) ArgumentListNode(TokenPosition::kNoSource);
     current_block_->statements->Add(
         new(Z) InstanceCallNode(try_end_pos,
-            new(Z) LoadLocalNode(Token::kNoSourcePos, controller),
+            new(Z) LoadLocalNode(TokenPosition::kNoSource, controller),
             Symbols::Close(),
             no_args));
 
@@ -6265,7 +6282,7 @@
     AwaitMarkerNode* await_marker =
         new(Z) AwaitMarkerNode(async_temp_scope_,
                                current_block_->scope,
-                               Token::kNoSourcePos);
+                               TokenPosition::kNoSource);
     current_block_->statements->Add(await_marker);
     ReturnNode* continuation_ret = new(Z) ReturnNode(try_end_pos);
     continuation_ret->set_return_type(ReturnNode::kContinuationTarget);
@@ -6296,7 +6313,7 @@
   handler_types.Add(Object::dynamic_type());
 
   CatchClauseNode* catch_clause = new(Z) CatchClauseNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       catch_handler_list,
       Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
       context_var,
@@ -6310,7 +6327,7 @@
   const intptr_t try_index = try_statement->try_index();
 
   AstNode* try_catch_node =
-      new(Z) TryCatchNode(Token::kNoSourcePos,
+      new(Z) TryCatchNode(TokenPosition::kNoSource,
                           body,
                           context_var,
                           catch_clause,
@@ -6335,10 +6352,10 @@
   OpenBlock();  // Catch block.
   CatchParamDesc exception_param;
   CatchParamDesc stack_trace_param;
-  exception_param.token_pos = Token::kNoSourcePos;
+  exception_param.token_pos = TokenPosition::kNoSource;
   exception_param.type = &Object::dynamic_type();
   exception_param.name = &Symbols::ExceptionParameter();
-  stack_trace_param.token_pos = Token::kNoSourcePos;
+  stack_trace_param.token_pos = TokenPosition::kNoSource;
   stack_trace_param.type = &Object::dynamic_type();
   stack_trace_param.name = &Symbols::StackTraceParameter();
 
@@ -6356,9 +6373,9 @@
     // the exception variable specified in this block.
     ASSERT(exception_var != NULL);
     current_block_->statements->Add(new(Z) StoreLocalNode(
-        Token::kNoSourcePos,
+        TokenPosition::kNoSource,
         exception_param.var,
-        new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var)));
+        new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var)));
   }
 
   LocalVariable* stack_trace_var =
@@ -6369,9 +6386,9 @@
     // trace variable specified in this block.
     ASSERT(stack_trace_var != NULL);
     current_block_->statements->Add(new(Z) StoreLocalNode(
-        Token::kNoSourcePos,
+        TokenPosition::kNoSource,
         stack_trace_param.var,
-        new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var)));
+        new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var)));
   }
   LocalVariable* saved_exception_var = try_scope->LocalLookupVariable(
       Symbols::SavedExceptionVar());
@@ -6389,17 +6406,18 @@
       Symbols::AsyncCompleter(), false);
   ASSERT(async_completer != NULL);
   ArgumentListNode* completer_args =
-      new (Z) ArgumentListNode(Token::kNoSourcePos);
+      new (Z) ArgumentListNode(TokenPosition::kNoSource);
   completer_args->Add(
-      new (Z) LoadLocalNode(Token::kNoSourcePos, exception_param.var));
+      new (Z) LoadLocalNode(TokenPosition::kNoSource, exception_param.var));
   completer_args->Add(
-      new (Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_param.var));
+      new (Z) LoadLocalNode(TokenPosition::kNoSource,
+                            stack_trace_param.var));
   current_block_->statements->Add(new (Z) InstanceCallNode(
       TokenPos(),
-      new (Z) LoadLocalNode(Token::kNoSourcePos, async_completer),
+      new (Z) LoadLocalNode(TokenPosition::kNoSource, async_completer),
       Symbols::CompleterCompleteError(),
       completer_args));
-  ReturnNode* return_node = new (Z) ReturnNode(Token::kNoSourcePos);
+  ReturnNode* return_node = new (Z) ReturnNode(TokenPosition::kNoSource);
   // Behavior like a continuation return, i.e,. don't call a completer.
   return_node->set_return_type(ReturnNode::kContinuation);
   current_block_->statements->Add(return_node);
@@ -6416,7 +6434,7 @@
   const intptr_t try_index = try_statement->try_index();
 
   CatchClauseNode* catch_clause = new (Z) CatchClauseNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       catch_handler_list,
       Array::ZoneHandle(Z, Array::MakeArray(handler_types)),
       context_var,
@@ -6427,7 +6445,7 @@
       CatchClauseNode::kInvalidTryIndex,
       true);
   AstNode* try_catch_node = new (Z) TryCatchNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       try_block,
       context_var,
       catch_clause,
@@ -6473,7 +6491,9 @@
   // Add implicit closure parameter if not already present.
   if (params->parameters->length() == 0) {
     params->AddFinalParameter(
-        0, &Symbols::ClosureParameter(), &Object::dynamic_type());
+        TokenPosition::kMinSource,
+        &Symbols::ClosureParameter(),
+        &Object::dynamic_type());
   }
   ParamDesc iterator_param;
   iterator_param.name = &Symbols::IteratorParameter();
@@ -6490,7 +6510,7 @@
 }
 
 
-RawFunction* Parser::OpenSyncGeneratorFunction(intptr_t func_pos) {
+RawFunction* Parser::OpenSyncGeneratorFunction(TokenPosition func_pos) {
   Function& body = Function::Handle(Z);
   String& body_closure_name = String::Handle(Z);
   bool is_new_closure = false;
@@ -6557,10 +6577,10 @@
   // :await_jump_var = -1;
   LocalVariable* jump_var =
       current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
-  LiteralNode* init_value =
-      new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
+  LiteralNode* init_value = new(Z) LiteralNode(TokenPosition::kNoSource,
+                                               Smi::ZoneHandle(Smi::New(-1)));
   current_block_->statements->Add(
-      new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value));
+      new(Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value));
 
   // return new SyncIterable(body_closure);
   const Class& iterable_class =
@@ -6574,17 +6594,18 @@
   const String& closure_name = String::Handle(Z, closure.name());
   ASSERT(closure_name.IsSymbol());
 
-  ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos);
+  ArgumentListNode* arguments =
+      new(Z) ArgumentListNode(TokenPosition::kNoSource);
   ClosureNode* closure_obj = new(Z) ClosureNode(
-      Token::kNoSourcePos, closure, NULL, closure_body->scope());
+      TokenPosition::kNoSource, closure, NULL, closure_body->scope());
   arguments->Add(closure_obj);
   ConstructorCallNode* new_iterable =
-      new(Z) ConstructorCallNode(Token::kNoSourcePos,
+      new(Z) ConstructorCallNode(TokenPosition::kNoSource,
           TypeArguments::ZoneHandle(Z),
           iterable_constructor,
           arguments);
   ReturnNode* return_node =
-      new (Z) ReturnNode(Token::kNoSourcePos, new_iterable);
+      new (Z) ReturnNode(TokenPosition::kNoSource, new_iterable);
   current_block_->statements->Add(return_node);
   return CloseBlock();
 }
@@ -6599,7 +6620,9 @@
   // Add implicit closure parameter if not yet present.
   if (params->parameters->length() == 0) {
     params->AddFinalParameter(
-        0, &Symbols::ClosureParameter(), &Object::dynamic_type());
+        TokenPosition::kMinSource,
+        &Symbols::ClosureParameter(),
+        &Object::dynamic_type());
   }
   ParamDesc result_param;
   result_param.name = &Symbols::AsyncOperationParam();
@@ -6621,7 +6644,7 @@
 }
 
 
-RawFunction* Parser::OpenAsyncFunction(intptr_t async_func_pos) {
+RawFunction* Parser::OpenAsyncFunction(TokenPosition async_func_pos) {
   TRACE_PARSER("OpenAsyncFunction");
   AddContinuationVariables();
   AddAsyncClosureVariables();
@@ -6678,10 +6701,12 @@
   //   var :await_jump_var;
   //   var :await_ctx_var;
   LocalVariable* await_jump_var = new (Z) LocalVariable(
-      Token::kNoSourcePos, Symbols::AwaitJumpVar(), Object::dynamic_type());
+      TokenPosition::kNoSource,
+      Symbols::AwaitJumpVar(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(await_jump_var);
   LocalVariable* await_ctx_var = new (Z) LocalVariable(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       Symbols::AwaitContextVar(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(await_ctx_var);
@@ -6695,20 +6720,22 @@
   //   var :async_catch_error_callback;
   //   var :async_completer;
   LocalVariable* async_op_var = new(Z) LocalVariable(
-      Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
+      TokenPosition::kNoSource,
+      Symbols::AsyncOperation(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_op_var);
   LocalVariable* async_then_callback_var = new(Z) LocalVariable(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       Symbols::AsyncThenCallback(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_then_callback_var);
   LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       Symbols::AsyncCatchErrorCallback(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_catch_error_callback_var);
   LocalVariable* async_completer = new(Z) LocalVariable(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       Symbols::AsyncCompleter(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_completer);
@@ -6727,25 +6754,30 @@
   // These variables are used to store the async generator closure containing
   // the body of the async* function. They are used by the await operator.
   LocalVariable* controller_var = new(Z) LocalVariable(
-      Token::kNoSourcePos, Symbols::Controller(), Object::dynamic_type());
+      TokenPosition::kNoSource,
+      Symbols::Controller(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(controller_var);
   LocalVariable* async_op_var = new(Z) LocalVariable(
-      Token::kNoSourcePos, Symbols::AsyncOperation(), Object::dynamic_type());
+      TokenPosition::kNoSource,
+      Symbols::AsyncOperation(),
+      Object::dynamic_type());
   current_block_->scope->AddVariable(async_op_var);
   LocalVariable* async_then_callback_var = new(Z) LocalVariable(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       Symbols::AsyncThenCallback(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_then_callback_var);
   LocalVariable* async_catch_error_callback_var = new(Z) LocalVariable(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       Symbols::AsyncCatchErrorCallback(),
       Object::dynamic_type());
   current_block_->scope->AddVariable(async_catch_error_callback_var);
 }
 
 
-RawFunction* Parser::OpenAsyncGeneratorFunction(intptr_t async_func_pos) {
+RawFunction* Parser::OpenAsyncGeneratorFunction(
+    TokenPosition async_func_pos) {
   TRACE_PARSER("OpenAsyncGeneratorFunction");
   AddContinuationVariables();
   AddAsyncGeneratorVariables();
@@ -6856,19 +6888,19 @@
   // :await_jump_var = -1;
   LocalVariable* jump_var =
       current_block_->scope->LookupVariable(Symbols::AwaitJumpVar(), false);
-  LiteralNode* init_value =
-      new(Z) LiteralNode(Token::kNoSourcePos, Smi::ZoneHandle(Smi::New(-1)));
+  LiteralNode* init_value = new(Z) LiteralNode(TokenPosition::kNoSource,
+                                               Smi::ZoneHandle(Smi::New(-1)));
   current_block_->statements->Add(
-      new(Z) StoreLocalNode(Token::kNoSourcePos, jump_var, init_value));
+      new(Z) StoreLocalNode(TokenPosition::kNoSource, jump_var, init_value));
 
   // Add to AST:
   //   :async_op = <closure>;  (containing the original body)
   LocalVariable* async_op_var =
       current_block_->scope->LookupVariable(Symbols::AsyncOperation(), false);
   ClosureNode* closure_obj = new(Z) ClosureNode(
-      Token::kNoSourcePos, closure_func, NULL, closure_body->scope());
+      TokenPosition::kNoSource, closure_func, NULL, closure_body->scope());
   StoreLocalNode* store_async_op = new (Z) StoreLocalNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       async_op_var,
       closure_obj);
 
@@ -6880,18 +6912,18 @@
           Symbols::AsyncThenWrapperHelper()));
   ASSERT(!async_then_wrapper_helper.IsNull());
   ArgumentListNode* async_then_wrapper_helper_args = new (Z) ArgumentListNode(
-      Token::kNoSourcePos);
+      TokenPosition::kNoSource);
   async_then_wrapper_helper_args->Add(
-      new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var));
+      new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var));
   StaticCallNode* then_wrapper_call = new (Z) StaticCallNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       async_then_wrapper_helper,
       async_then_wrapper_helper_args);
   LocalVariable* async_then_callback_var =
       current_block_->scope->LookupVariable(
           Symbols::AsyncThenCallback(), false);
   StoreLocalNode* store_async_then_callback = new (Z) StoreLocalNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       async_then_callback_var,
       then_wrapper_call);
 
@@ -6904,43 +6936,45 @@
           Symbols::AsyncErrorWrapperHelper()));
   ASSERT(!async_error_wrapper_helper.IsNull());
   ArgumentListNode* async_error_wrapper_helper_args = new (Z) ArgumentListNode(
-      Token::kNoSourcePos);
+      TokenPosition::kNoSource);
   async_error_wrapper_helper_args->Add(
-      new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var));
+      new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var));
   StaticCallNode* error_wrapper_call = new (Z) StaticCallNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       async_error_wrapper_helper,
       async_error_wrapper_helper_args);
   LocalVariable* async_catch_error_callback_var =
       current_block_->scope->LookupVariable(
           Symbols::AsyncCatchErrorCallback(), false);
   StoreLocalNode* store_async_catch_error_callback = new (Z) StoreLocalNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       async_catch_error_callback_var,
       error_wrapper_call);
 
   current_block_->statements->Add(store_async_catch_error_callback);
 
   // :controller = new _AsyncStarStreamController(body_closure);
-  ArgumentListNode* arguments = new(Z) ArgumentListNode(Token::kNoSourcePos);
-  arguments->Add(new (Z) LoadLocalNode(Token::kNoSourcePos, async_op_var));
+  ArgumentListNode* arguments =
+      new(Z) ArgumentListNode(TokenPosition::kNoSource);
+  arguments->Add(
+      new (Z) LoadLocalNode(TokenPosition::kNoSource, async_op_var));
   ConstructorCallNode* controller_constructor_call =
-      new(Z) ConstructorCallNode(Token::kNoSourcePos,
+      new(Z) ConstructorCallNode(TokenPosition::kNoSource,
                                  TypeArguments::ZoneHandle(Z),
                                  controller_constructor,
                                  arguments);
   LocalVariable* controller_var =
      current_block_->scope->LookupVariable(Symbols::Controller(), false);
   StoreLocalNode* store_controller =
-      new(Z) StoreLocalNode(Token::kNoSourcePos,
+      new(Z) StoreLocalNode(TokenPosition::kNoSource,
                             controller_var,
                             controller_constructor_call);
   current_block_->statements->Add(store_controller);
 
   // return :controller.stream;
-  ReturnNode* return_node = new(Z) ReturnNode(Token::kNoSourcePos,
-      new(Z) InstanceGetterNode(Token::kNoSourcePos,
-          new(Z) LoadLocalNode(Token::kNoSourcePos,
+  ReturnNode* return_node = new(Z) ReturnNode(TokenPosition::kNoSource,
+      new(Z) InstanceGetterNode(TokenPosition::kNoSource,
+          new(Z) LoadLocalNode(TokenPosition::kNoSource,
               controller_var),
               Symbols::Stream()));
   current_block_->statements->Add(return_node);
@@ -6966,7 +7000,8 @@
 
 
 // Add a return node to the sequence if necessary.
-void Parser::EnsureHasReturnStatement(SequenceNode* seq, intptr_t return_pos) {
+void Parser::EnsureHasReturnStatement(SequenceNode* seq,
+                                      TokenPosition return_pos) {
   if ((seq->length() == 0) ||
       !seq->NodeAt(seq->length() - 1)->IsReturnNode()) {
     const Function& func = innermost_function();
@@ -7034,7 +7069,7 @@
   LocalVariable* async_completer = current_block_->scope->LookupVariable(
       Symbols::AsyncCompleter(), false);
 
-  const intptr_t token_pos = ST(closure_body->token_pos());
+  const TokenPosition token_pos = ST(closure_body->token_pos());
   // Add to AST:
   //   :async_completer = new Completer.sync();
   ArgumentListNode* empty_args =
@@ -7280,7 +7315,7 @@
 }
 
 
-AstNode* Parser::LoadReceiver(intptr_t token_pos) {
+AstNode* Parser::LoadReceiver(TokenPosition token_pos) {
   // A nested function may access 'this', referring to the receiver of the
   // outermost enclosing function.
   const bool kTestOnly = false;
@@ -7292,7 +7327,7 @@
 }
 
 
-InstanceGetterNode* Parser::CallGetter(intptr_t token_pos,
+InstanceGetterNode* Parser::CallGetter(TokenPosition token_pos,
                                        AstNode* object,
                                        const String& name) {
   return new(Z) InstanceGetterNode(token_pos, object, name);
@@ -7306,10 +7341,10 @@
                                           SequenceNode** await_preamble) {
   TRACE_PARSER("ParseVariableDeclaration");
   ASSERT(IsIdentifier());
-  const intptr_t ident_pos = TokenPos();
+  const TokenPosition ident_pos = TokenPos();
   const String& ident = *CurrentLiteral();
   ConsumeToken();  // Variable identifier.
-  const intptr_t assign_pos = TokenPos();
+  const TokenPosition assign_pos = TokenPos();
   AstNode* initialization = NULL;
   LocalVariable* variable = NULL;
   if (CurrentToken() == Token::kASSIGN) {
@@ -7317,7 +7352,7 @@
     ConsumeToken();
     AstNode* expr = ParseAwaitableExpr(
         is_const, kConsumeCascades, await_preamble);
-    const intptr_t expr_end_pos = TokenPos();
+    const TokenPosition expr_end_pos = TokenPos();
     variable = new(Z) LocalVariable(
         expr_end_pos, ident, type);
     initialization = new(Z) StoreLocalNode(
@@ -7339,9 +7374,9 @@
   }
 
   ASSERT(current_block_ != NULL);
-  const intptr_t previous_pos =
+  const TokenPosition previous_pos =
       current_block_->scope->PreviousReferencePos(ident);
-  if (previous_pos >= 0) {
+  if (previous_pos.IsReal()) {
     ASSERT(!script_.IsNull());
     if (previous_pos > ident_pos) {
       ReportError(ident_pos,
@@ -7468,8 +7503,8 @@
 
   result_type = Type::DynamicType();
 
-  const intptr_t function_pos = TokenPos();
-  intptr_t metadata_pos = Token::kNoSourcePos;
+  const TokenPosition function_pos = TokenPos();
+  TokenPosition metadata_pos = TokenPosition::kNoSource;
   if (is_literal) {
     ASSERT(CurrentToken() == Token::kLPAREN);
     function_name = &Symbols::AnonymousClosure();
@@ -7482,16 +7517,16 @@
                (LookaheadToken(1) != Token::kLPAREN)) {
       result_type = ParseType(ClassFinalizer::kCanonicalize);
     }
-    const intptr_t name_pos = TokenPos();
+    const TokenPosition name_pos = TokenPos();
     variable_name = ExpectIdentifier("function name expected");
     function_name = variable_name;
 
     // Check that the function name has not been referenced
     // before this declaration.
     ASSERT(current_block_ != NULL);
-    const intptr_t previous_pos =
+    const TokenPosition previous_pos =
         current_block_->scope->PreviousReferencePos(*function_name);
-    if (previous_pos >= 0) {
+    if (previous_pos.IsReal()) {
       ASSERT(!script_.IsNull());
       intptr_t line_number;
       script_.GetTokenLocation(previous_pos, &line_number, NULL);
@@ -7521,7 +7556,7 @@
                                             innermost_function(),
                                             function_pos);
     function.set_result_type(result_type);
-    if (FLAG_enable_mirrors && (metadata_pos >= 0)) {
+    if (FLAG_enable_mirrors && metadata_pos.IsReal()) {
       library_.AddFunctionMetadata(function, metadata_pos);
     }
   }
@@ -7797,7 +7832,7 @@
   }
   // Skip optional metadata.
   if (CurrentToken() == Token::kAT) {
-    const intptr_t saved_pos = TokenPos();
+    const TokenPosition saved_pos = TokenPos();
     SkipMetadata();
     const bool is_var_decl = IsVariableDeclaration();
     SetPosition(saved_pos);
@@ -7807,7 +7842,7 @@
     // Not a legal type identifier or const keyword or metadata.
     return false;
   }
-  const intptr_t saved_pos = TokenPos();
+  const TokenPosition saved_pos = TokenPos();
   bool is_var_decl = false;
   bool have_type = false;
   if (CurrentToken() == Token::kCONST) {
@@ -7820,7 +7855,7 @@
         (follower == Token::kPERIOD) ||  // Qualified class name of type.
         Token::IsIdentifier(follower)) {  // Variable name following a type.
       // We see the beginning of something that could be a type.
-      const intptr_t type_pos = TokenPos();
+      const TokenPosition type_pos = TokenPos();
       if (TryParseOptionalType()) {
         have_type = true;
       } else {
@@ -7844,7 +7879,7 @@
 // Look ahead to detect whether the next tokens should be parsed as
 // a function declaration. Token position remains unchanged.
 bool Parser::IsFunctionDeclaration() {
-  const intptr_t saved_pos = TokenPos();
+  const TokenPosition saved_pos = TokenPos();
   bool is_external = false;
   SkipMetadata();
   if (is_top_level_) {
@@ -7892,7 +7927,7 @@
 
 
 bool Parser::IsTopLevelAccessor() {
-  const intptr_t saved_pos = TokenPos();
+  const TokenPosition saved_pos = TokenPos();
   if (is_patch_source() && IsSymbol(Symbols::Patch())) {
     ConsumeToken();
   } else if (CurrentToken() == Token::kEXTERNAL) {
@@ -7919,7 +7954,7 @@
   if (CurrentToken() != Token::kLPAREN || !allow_function_literals_) {
     return false;
   }
-  const intptr_t saved_pos = TokenPos();
+  const TokenPosition saved_pos = TokenPos();
   bool is_function_literal = false;
   SkipToMatchingParenthesis();
   ParseFunctionModifier();
@@ -7936,7 +7971,7 @@
 // statement. Returns true if we recognize a for ( .. in expr)
 // statement.
 bool Parser::IsForInStatement() {
-  const intptr_t saved_pos = TokenPos();
+  const TokenPosition saved_pos = TokenPos();
   bool result = false;
   // Allow const modifier as well when recognizing a for-in statement
   // pattern. We will get an error later if the loop variable is
@@ -7988,7 +8023,7 @@
   bool abrupt_completing_seen = false;
   RecursionChecker rc(this);
   while (CurrentToken() != Token::kRBRACE) {
-    const intptr_t statement_pos = TokenPos();
+    const TokenPosition statement_pos = TokenPos();
     AstNode* statement = ParseStatement();
     // Do not add statements with no effect (e.g., LoadLocalNode).
     if ((statement != NULL) && statement->IsLoadLocalNode()) {
@@ -8040,7 +8075,7 @@
 AstNode* Parser::ParseIfStatement(String* label_name) {
   TRACE_PARSER("ParseIfStatement");
   ASSERT(CurrentToken() == Token::kIF);
-  const intptr_t if_pos = TokenPos();
+  const TokenPosition if_pos = TokenPos();
   SourceLabel* label = NULL;
   if (label_name != NULL) {
     label = SourceLabel::New(if_pos, label_name, SourceLabel::kStatement);
@@ -8095,7 +8130,7 @@
   const Instance& first_value = values[0]->literal();
   for (intptr_t i = 0; i < num_expressions; i++) {
     const Instance& val = values[i]->literal();
-    const intptr_t val_pos = values[i]->token_pos();
+    const TokenPosition val_pos = values[i]->token_pos();
     if (first_value.IsInteger()) {
       if (!val.IsInteger()) {
         ReportError(val_pos, "expected case expression of type int");
@@ -8143,7 +8178,7 @@
                                   SourceLabel* case_label) {
   TRACE_PARSER("ParseCaseClause");
   bool default_seen = false;
-  const intptr_t case_pos = TokenPos();
+  const TokenPosition case_pos = TokenPos();
   // The case expressions node sequence does not own the enclosing scope.
   SequenceNode* case_expressions = new(Z) SequenceNode(case_pos, NULL);
   while (CurrentToken() == Token::kCASE || CurrentToken() == Token::kDEFAULT) {
@@ -8152,7 +8187,7 @@
         ReportError("default clause must be last case");
       }
       ConsumeToken();  // Keyword case.
-      const intptr_t expr_pos = TokenPos();
+      const TokenPosition expr_pos = TokenPos();
       AstNode* expr = ParseExpr(kRequireConst, kConsumeCascades);
       ASSERT(expr->IsLiteralNode());
       case_expr_values->Add(expr->AsLiteralNode());
@@ -8195,7 +8230,8 @@
       if (!abrupt_completing_seen) {
         ArgumentListNode* arguments = new(Z) ArgumentListNode(TokenPos());
         arguments->Add(new(Z) LiteralNode(
-            TokenPos(), Integer::ZoneHandle(Z, Integer::New(TokenPos()))));
+            TokenPos(),
+            Integer::ZoneHandle(Z, Integer::New(TokenPos().value()))));
         current_block_->statements->Add(
             MakeStaticCall(Symbols::FallThroughError(),
                            Library::PrivateCoreLibName(Symbols::ThrowNew()),
@@ -8219,12 +8255,12 @@
 AstNode* Parser::ParseSwitchStatement(String* label_name) {
   TRACE_PARSER("ParseSwitchStatement");
   ASSERT(CurrentToken() == Token::kSWITCH);
-  const intptr_t switch_pos = TokenPos();
+  const TokenPosition switch_pos = TokenPos();
   SourceLabel* label =
       SourceLabel::New(switch_pos, label_name, SourceLabel::kSwitch);
   ConsumeToken();
   ExpectToken(Token::kLPAREN);
-  const intptr_t expr_pos = TokenPos();
+  const TokenPosition expr_pos = TokenPos();
   AstNode* switch_expr = ParseAwaitableExpr(
       kAllowConst, kConsumeCascades, NULL);
   ExpectToken(Token::kRPAREN);
@@ -8258,7 +8294,7 @@
     if (IsIdentifier() && LookaheadToken(1) == Token::kCOLON) {
       // Case statements start with a label.
       String* label_name = CurrentLiteral();
-      const intptr_t label_pos = TokenPos();
+      const TokenPosition label_pos = TokenPos();
       ConsumeToken();  // Consume label identifier.
       ConsumeToken();  // Consume colon.
       case_label = current_block_->scope->LocalLookupLabel(*label_name);
@@ -8318,7 +8354,7 @@
 
 AstNode* Parser::ParseWhileStatement(String* label_name) {
   TRACE_PARSER("ParseWhileStatement");
-  const intptr_t while_pos = TokenPos();
+  const TokenPosition while_pos = TokenPos();
   SourceLabel* label =
       SourceLabel::New(while_pos, label_name, SourceLabel::kWhile);
   ConsumeToken();
@@ -8340,7 +8376,7 @@
 
 AstNode* Parser::ParseDoWhileStatement(String* label_name) {
   TRACE_PARSER("ParseDoWhileStatement");
-  const intptr_t do_pos = TokenPos();
+  const TokenPosition do_pos = TokenPos();
   SourceLabel* label =
       SourceLabel::New(do_pos, label_name, SourceLabel::kDoWhile);
   ConsumeToken();
@@ -8349,7 +8385,7 @@
   ExpectToken(Token::kWHILE);
   ExpectToken(Token::kLPAREN);
   SequenceNode* await_preamble = NULL;
-  intptr_t expr_pos = TokenPos();
+  TokenPosition expr_pos = TokenPos();
   AstNode* cond_expr =
       ParseAwaitableExpr(kAllowConst, kConsumeCascades, &await_preamble);
   if (await_preamble != NULL) {
@@ -8450,11 +8486,12 @@
   const Function& print_fn = Function::ZoneHandle(
       Z, lib.LookupFunctionAllowPrivate(Symbols::print()));
   ASSERT(!print_fn.IsNull());
-  ArgumentListNode* one_arg = new(Z) ArgumentListNode(Token::kNoSourcePos);
+  ArgumentListNode* one_arg =
+      new(Z) ArgumentListNode(TokenPosition::kNoSource);
   String& msg = String::ZoneHandle(Symbols::NewFormatted("%s", str));
-  one_arg->Add(new(Z) LiteralNode(Token::kNoSourcePos, msg));
+  one_arg->Add(new(Z) LiteralNode(TokenPosition::kNoSource, msg));
   AstNode* print_call =
-      new(Z) StaticCallNode(Token::kNoSourcePos, print_fn, one_arg);
+      new(Z) StaticCallNode(TokenPosition::kNoSource, print_fn, one_arg);
   return print_call;
 }
 
@@ -8462,7 +8499,7 @@
 AstNode* Parser::ParseAwaitForStatement(String* label_name) {
   TRACE_PARSER("ParseAwaitForStatement");
   ASSERT(IsAwaitKeyword());
-  const intptr_t await_for_pos = TokenPos();
+  const TokenPosition await_for_pos = TokenPos();
   ConsumeToken();  // await.
   ASSERT(CurrentToken() == Token::kFOR);
   ConsumeToken();  // for.
@@ -8492,12 +8529,12 @@
        I->flags().type_checks() ? ClassFinalizer::kCanonicalize :
                                   ClassFinalizer::kIgnore);
   }
-  intptr_t loop_var_pos = TokenPos();
+  TokenPosition loop_var_pos = TokenPos();
   const String* loop_var_name = ExpectIdentifier("variable name expected");
 
   // Parse stream expression.
   ExpectToken(Token::kIN);
-  const intptr_t stream_expr_pos = TokenPos();
+  const TokenPosition stream_expr_pos = TokenPos();
   AstNode* stream_expr =
       ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
   ExpectToken(Token::kRPAREN);
@@ -8594,7 +8631,7 @@
   SourceLabel* label =
       SourceLabel::New(await_for_pos, label_name, SourceLabel::kFor);
   current_block_->scope->AddLabel(label);
-  const intptr_t loop_var_assignment_pos = TokenPos();
+  const TokenPosition loop_var_assignment_pos = TokenPos();
 
   AstNode* iterator_current = new(Z) InstanceGetterNode(
       loop_var_assignment_pos,
@@ -8659,9 +8696,9 @@
 
   if (outer_saved_try_ctx != NULL) {
     catch_block->Add(new (Z) StoreLocalNode(
-        Token::kNoSourcePos,
+        TokenPosition::kNoSource,
         outer_saved_try_ctx,
-        new (Z) LoadLocalNode(Token::kNoSourcePos,
+        new (Z) LoadLocalNode(TokenPosition::kNoSource,
                               outer_async_saved_try_ctx)));
   }
 
@@ -8682,7 +8719,7 @@
       outer_try->try_index() : CatchClauseNode::kInvalidTryIndex;
 
   // The finally block contains a call to cancel the stream.
-  // :for-in-iter.cancel()
+  // :for-in-iter.cancel();
 
   // Inline the finally block to the exit points in the try block.
   intptr_t node_index = 0;
@@ -8692,18 +8729,30 @@
   }
   do {
     OpenBlock();
+
+    // Restore the saved try context of the enclosing try block if one
+    // exists.
+    if (outer_saved_try_ctx != NULL) {
+      current_block_->statements->Add(new (Z) StoreLocalNode(
+          TokenPosition::kNoSource,
+          outer_saved_try_ctx,
+          new (Z) LoadLocalNode(TokenPosition::kNoSource,
+                                outer_async_saved_try_ctx)));
+    }
+    // :for-in-iter.cancel();
     ArgumentListNode* no_args =
-        new(Z) ArgumentListNode(Token::kNoSourcePos);
+        new(Z) ArgumentListNode(TokenPosition::kNoSource);
     current_block_->statements->Add(
-        new(Z) InstanceCallNode(Token::kNoSourcePos,
-            new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_var),
+        new(Z) InstanceCallNode(TokenPosition::kNoSource,
+            new(Z) LoadLocalNode(TokenPosition::kNoSource, iterator_var),
             Symbols::Cancel(),
             no_args));
     finally_clause = CloseBlock();
+
     AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
     if (node_to_inline != NULL) {
       InlinedFinallyNode* node =
-          new(Z) InlinedFinallyNode(Token::kNoSourcePos,
+          new(Z) InlinedFinallyNode(TokenPosition::kNoSource,
                                     finally_clause,
                                     context_var,
                                     outer_try_index);
@@ -8751,7 +8800,7 @@
 }
 
 
-AstNode* Parser::ParseForInStatement(intptr_t forin_pos,
+AstNode* Parser::ParseForInStatement(TokenPosition forin_pos,
                                      SourceLabel* label) {
   TRACE_PARSER("ParseForInStatement");
   bool loop_var_is_final = (CurrentToken() == Token::kFINAL);
@@ -8759,7 +8808,7 @@
     ReportError("Loop variable cannot be 'const'");
   }
   const String* loop_var_name = NULL;
-  intptr_t loop_var_pos = Token::kNoSourcePos;
+  TokenPosition loop_var_pos = TokenPosition::kNoSource;
   bool new_loop_var = false;
   AbstractType& loop_var_type =  AbstractType::ZoneHandle(Z);
   if (LookaheadToken(1) == Token::kIN) {
@@ -8776,7 +8825,7 @@
     loop_var_name = ExpectIdentifier("variable name expected");
   }
   ExpectToken(Token::kIN);
-  const intptr_t collection_pos = TokenPos();
+  const TokenPosition collection_pos = TokenPos();
   AstNode* collection_expr =
       ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
   ExpectToken(Token::kRPAREN);
@@ -8815,7 +8864,7 @@
   // loop body.
   OpenLoopBlock();
   current_block_->scope->AddLabel(label);
-  const intptr_t loop_var_assignment_pos = TokenPos();
+  const TokenPosition loop_var_assignment_pos = TokenPos();
 
   AstNode* iterator_current = new(Z) InstanceGetterNode(
       loop_var_assignment_pos,
@@ -8873,7 +8922,7 @@
 
 AstNode* Parser::ParseForStatement(String* label_name) {
   TRACE_PARSER("ParseForStatement");
-  const intptr_t for_pos = TokenPos();
+  const TokenPosition for_pos = TokenPos();
   ConsumeToken();
   ExpectToken(Token::kLPAREN);
   SourceLabel* label = SourceLabel::New(for_pos, label_name, SourceLabel::kFor);
@@ -8884,7 +8933,7 @@
   // that we allocate a new context if the loop variable is captured.
   OpenLoopBlock();
   AstNode* initializer = NULL;
-  const intptr_t init_pos = TokenPos();
+  const TokenPosition init_pos = TokenPos();
   LocalScope* init_scope = current_block_->scope;
   if (CurrentToken() != Token::kSEMICOLON) {
     if (IsVariableDeclaration()) {
@@ -8902,7 +8951,7 @@
   }
   ExpectSemicolon();
   AstNode* increment = NULL;
-  const intptr_t incr_pos = TokenPos();
+  const TokenPosition incr_pos = TokenPos();
   if (CurrentToken() != Token::kRPAREN) {
     increment = ParseAwaitableExprList();
   }
@@ -8955,12 +9004,12 @@
 }
 
 
-AstNode* Parser::MakeAssertCall(intptr_t begin, intptr_t end) {
+AstNode* Parser::MakeAssertCall(TokenPosition begin, TokenPosition end) {
   ArgumentListNode* arguments = new(Z) ArgumentListNode(begin);
   arguments->Add(new(Z) LiteralNode(begin,
-      Integer::ZoneHandle(Z, Integer::New(begin))));
+      Integer::ZoneHandle(Z, Integer::New(begin.value()))));
   arguments->Add(new(Z) LiteralNode(end,
-      Integer::ZoneHandle(Z, Integer::New(end))));
+      Integer::ZoneHandle(Z, Integer::New(end.value()))));
   return MakeStaticCall(Symbols::AssertionError(),
                         Library::PrivateCoreLibName(Symbols::ThrowNew()),
                         arguments);
@@ -8972,7 +9021,7 @@
       (condition->IsStoreLocalNode() &&
        condition->AsStoreLocalNode()->value()->IsClosureNode())) {
     // Function literal in assert implies a call.
-    const intptr_t pos = condition->token_pos();
+    const TokenPosition pos = condition->token_pos();
     condition = BuildClosureCall(pos,
                                  condition,
                                  new(Z) ArgumentListNode(pos));
@@ -8989,14 +9038,14 @@
   TRACE_PARSER("ParseAssertStatement");
   ConsumeToken();  // Consume assert keyword.
   ExpectToken(Token::kLPAREN);
-  const intptr_t condition_pos = TokenPos();
+  const TokenPosition condition_pos = TokenPos();
   if (!I->flags().asserts()) {
     SkipExpr();
     ExpectToken(Token::kRPAREN);
     return NULL;
   }
   AstNode* condition = ParseAwaitableExpr(kAllowConst, kConsumeCascades, NULL);
-  const intptr_t condition_end = TokenPos();
+  const TokenPosition condition_end = TokenPos();
   ExpectToken(Token::kRPAREN);
   condition = InsertClosureCallNodes(condition);
   condition = new(Z) UnaryOpNode(condition_pos, Token::kNOT, condition);
@@ -9060,16 +9109,16 @@
   ASSERT(saved_exception_var != NULL);
   ASSERT(exception_var != NULL);
   statements->Add(new(Z) StoreLocalNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       saved_exception_var,
-      new(Z) LoadLocalNode(Token::kNoSourcePos, exception_var)));
+      new(Z) LoadLocalNode(TokenPosition::kNoSource, exception_var)));
 
   ASSERT(saved_stack_trace_var != NULL);
   ASSERT(stack_trace_var != NULL);
   statements->Add(new(Z) StoreLocalNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       saved_stack_trace_var,
-      new(Z) LoadLocalNode(Token::kNoSourcePos, stack_trace_var)));
+      new(Z) LoadLocalNode(TokenPosition::kNoSource, stack_trace_var)));
 }
 
 
@@ -9090,7 +9139,7 @@
   if (try_stack_ != NULL) {
     try_stack_->enter_finally();
   }
-  // In case of async closures we need to restore the saved try index of an
+  // In case of async closures we need to restore the saved try context of an
   // outer try block (if it exists).  The current try block has already been
   // removed from the stack of try blocks.
   if (is_async) {
@@ -9104,9 +9153,9 @@
                                           try_stack_->try_index());
         current_block_->statements->Add(
             new (Z) StoreLocalNode(
-                Token::kNoSourcePos,
+                TokenPosition::kNoSource,
                 saved_try_ctx,
-                new (Z) LoadLocalNode(Token::kNoSourcePos,
+                new (Z) LoadLocalNode(TokenPosition::kNoSource,
                                       async_saved_try_ctx)));
       }
     }
@@ -9190,7 +9239,7 @@
 
 
 SequenceNode* Parser::ParseCatchClauses(
-    intptr_t handler_pos,
+    TokenPosition handler_pos,
     bool is_async,
     LocalVariable* exception_var,
     LocalVariable* stack_trace_var,
@@ -9210,7 +9259,7 @@
     // Open a block that contains the if or an unconditional body.  It's
     // closed in the loop that builds the if-then-else nest.
     OpenBlock();
-    const intptr_t catch_pos = TokenPos();
+    const TokenPosition catch_pos = TokenPos();
     CatchParamDesc exception_param;
     CatchParamDesc stack_trace_param;
     if (IsSymbol(Symbols::On())) {
@@ -9377,9 +9426,9 @@
                                           try_block->try_index());
         async_code->Add(
             new (Z) StoreLocalNode(
-                Token::kNoSourcePos,
+                TokenPosition::kNoSource,
                 saved_try_ctx,
-                new (Z) LoadLocalNode(Token::kNoSourcePos,
+                new (Z) LoadLocalNode(TokenPosition::kNoSource,
                                       async_saved_try_ctx)));
       }
     }
@@ -9406,16 +9455,16 @@
                            Symbols::AsyncSavedTryCtxVarPrefix().ToCString(),
                            last_used_try_index_ - 1));
   LocalVariable* async_saved_try_ctx = new (Z) LocalVariable(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       async_saved_try_ctx_name,
       Object::dynamic_type());
   ASSERT(async_temp_scope_ != NULL);
   async_temp_scope_->AddVariable(async_saved_try_ctx);
   ASSERT(saved_try_context != NULL);
   current_block_->statements->Add(new(Z) StoreLocalNode(
-      Token::kNoSourcePos,
+      TokenPosition::kNoSource,
       async_saved_try_ctx,
-      new(Z) LoadLocalNode(Token::kNoSourcePos, saved_try_context)));
+      new(Z) LoadLocalNode(TokenPosition::kNoSource, saved_try_context)));
 }
 
 
@@ -9494,7 +9543,7 @@
 AstNode* Parser::ParseTryStatement(String* label_name) {
   TRACE_PARSER("ParseTryStatement");
 
-  const intptr_t try_pos = TokenPos();
+  const TokenPosition try_pos = TokenPos();
   SourceLabel* try_label = NULL;
   if (label_name != NULL) {
     try_label = SourceLabel::New(try_pos, label_name, SourceLabel::kStatement);
@@ -9543,7 +9592,7 @@
 
   // Now parse the 'catch' blocks if any.
   try_stack_->enter_catch();
-  const intptr_t handler_pos = TokenPos();
+  const TokenPosition handler_pos = TokenPos();
   const GrowableObjectArray& handler_types =
       GrowableObjectArray::Handle(Z, GrowableObjectArray::New(Heap::kOld));
   bool needs_stack_trace = false;
@@ -9574,7 +9623,7 @@
     if (parse) {
       ConsumeToken();  // Consume the 'finally'.
     }
-    const intptr_t finally_pos = TokenPos();
+    const TokenPosition finally_pos = TokenPos();
     // Add the finally block to the exit points recorded so far.
     intptr_t node_index = 0;
     AstNode* node_to_inline = try_statement->GetNodeToInlineFinally(node_index);
@@ -9654,7 +9703,7 @@
   TRACE_PARSER("ParseJump");
   ASSERT(CurrentToken() == Token::kBREAK || CurrentToken() == Token::kCONTINUE);
   Token::Kind jump_kind = CurrentToken();
-  const intptr_t jump_pos = TokenPos();
+  const TokenPosition jump_pos = TokenPos();
   SourceLabel* target = NULL;
   ConsumeToken();
   if (IsIdentifier()) {
@@ -9719,7 +9768,7 @@
 
 AstNode* Parser::ParseYieldStatement() {
   bool is_yield_each = false;
-  const intptr_t yield_pos = TokenPos();
+  const TokenPosition yield_pos = TokenPos();
   ConsumeToken();  // yield reserved word.
   if (CurrentToken() == Token::kMUL) {
     is_yield_each = true;
@@ -9744,9 +9793,9 @@
     ASSERT(iterator_param != NULL);
     // Generate :iterator.current = expr;
     AstNode* iterator =
-        new(Z) LoadLocalNode(Token::kNoSourcePos, iterator_param);
+        new(Z) LoadLocalNode(TokenPosition::kNoSource, iterator_param);
     AstNode* store_current =
-        new(Z) InstanceSetterNode(Token::kNoSourcePos,
+        new(Z) InstanceSetterNode(TokenPosition::kNoSource,
                                   iterator,
                                   String::ZoneHandle(Symbols::Current().raw()),
                                   expr);
@@ -9754,7 +9803,7 @@
     if (is_yield_each) {
       // Generate :iterator.isYieldEach = true;
       AstNode* set_is_yield_each =
-          new(Z) InstanceSetterNode(Token::kNoSourcePos,
+          new(Z) InstanceSetterNode(TokenPosition::kNoSource,
               iterator,
               String::ZoneHandle(Symbols::IsYieldEach().raw()),
               new(Z) LiteralNode(TokenPos(), Bool::True()));
@@ -9763,7 +9812,7 @@
     AwaitMarkerNode* await_marker =
         new(Z) AwaitMarkerNode(async_temp_scope_,
                                current_block_->scope,
-                               Token::kNoSourcePos);
+                               TokenPosition::kNoSource);
     yield->AddNode(await_marker);
     // Return true to indicate that a value has been generated.
     ReturnNode* return_true = new(Z) ReturnNode(yield_pos,
@@ -9784,15 +9833,15 @@
                            &outer_async_saved_try_ctx);
     if (saved_try_ctx != NULL) {
       yield->AddNode(new (Z) StoreLocalNode(
-          Token::kNoSourcePos,
+          TokenPosition::kNoSource,
           saved_try_ctx,
-          new (Z) LoadLocalNode(Token::kNoSourcePos,
+          new (Z) LoadLocalNode(TokenPosition::kNoSource,
                                 async_saved_try_ctx)));
       if (outer_saved_try_ctx != NULL) {
         yield->AddNode(new (Z) StoreLocalNode(
-            Token::kNoSourcePos,
+            TokenPosition::kNoSource,
             outer_saved_try_ctx,
-            new (Z) LoadLocalNode(Token::kNoSourcePos,
+            new (Z) LoadLocalNode(TokenPosition::kNoSource,
                                   outer_async_saved_try_ctx)));
       }
     } else {
@@ -9810,7 +9859,7 @@
     add_args->Add(expr);
     AstNode* add_call =
         new(Z) InstanceCallNode(yield_pos,
-            new(Z) LoadLocalNode(Token::kNoSourcePos, controller_var),
+            new(Z) LoadLocalNode(TokenPosition::kNoSource, controller_var),
             is_yield_each ? Symbols::AddStream() : Symbols::add(),
             add_args);
 
@@ -9822,18 +9871,18 @@
     // restore saved_try_context
 
     SequenceNode* true_branch =
-        new(Z) SequenceNode(Token::kNoSourcePos, NULL);
+        new(Z) SequenceNode(TokenPosition::kNoSource, NULL);
     AstNode* return_from_generator = new(Z) ReturnNode(yield_pos);
     true_branch->Add(return_from_generator);
     AddNodeForFinallyInlining(return_from_generator);
     AstNode* if_is_cancelled =
-       new(Z) IfNode(Token::kNoSourcePos, add_call, true_branch, NULL);
+       new(Z) IfNode(TokenPosition::kNoSource, add_call, true_branch, NULL);
     yield->AddNode(if_is_cancelled);
 
     AwaitMarkerNode* await_marker =
         new(Z) AwaitMarkerNode(async_temp_scope_,
                                current_block_->scope,
-                               Token::kNoSourcePos);
+                               TokenPosition::kNoSource);
     yield->AddNode(await_marker);
     ReturnNode* continuation_return = new(Z) ReturnNode(yield_pos);
     continuation_return->set_return_type(ReturnNode::kContinuationTarget);
@@ -9852,15 +9901,15 @@
                            &outer_async_saved_try_ctx);
     if (saved_try_ctx != NULL) {
       yield->AddNode(new (Z) StoreLocalNode(
-          Token::kNoSourcePos,
+          TokenPosition::kNoSource,
           saved_try_ctx,
-          new (Z) LoadLocalNode(Token::kNoSourcePos,
+          new (Z) LoadLocalNode(TokenPosition::kNoSource,
                                 async_saved_try_ctx)));
       if (outer_saved_try_ctx != NULL) {
         yield->AddNode(new (Z) StoreLocalNode(
-            Token::kNoSourcePos,
+            TokenPosition::kNoSource,
             outer_saved_try_ctx,
-            new (Z) LoadLocalNode(Token::kNoSourcePos,
+            new (Z) LoadLocalNode(TokenPosition::kNoSource,
                                   outer_async_saved_try_ctx)));
       }
     } else {
@@ -9874,19 +9923,19 @@
 AstNode* Parser::ParseStatement() {
   TRACE_PARSER("ParseStatement");
   AstNode* statement = NULL;
-  intptr_t label_pos = Token::kNoSourcePos;
+  TokenPosition label_pos = TokenPosition::kNoSource;
   String* label_name = NULL;
   if (IsIdentifier()) {
     if (LookaheadToken(1) == Token::kCOLON) {
       // Statement starts with a label.
       label_name = CurrentLiteral();
       label_pos = TokenPos();
-      ASSERT(label_pos >= 0);
+      ASSERT(label_pos.IsReal());
       ConsumeToken();  // Consume identifier.
       ConsumeToken();  // Consume colon.
     }
   }
-  const intptr_t statement_pos = TokenPos();
+  const TokenPosition statement_pos = TokenPos();
   const Token::Kind token = CurrentToken();
 
   if (token == Token::kWHILE) {
@@ -9902,10 +9951,10 @@
   } else if (token == Token::kTRY) {
     statement = ParseTryStatement(label_name);
   } else if (token == Token::kRETURN) {
-    const intptr_t return_pos = TokenPos();
+    const TokenPosition return_pos = TokenPos();
     ConsumeToken();
     if (CurrentToken() != Token::kSEMICOLON) {
-      const intptr_t expr_pos = TokenPos();
+      const TokenPosition expr_pos = TokenPos();
       if (current_function().IsGenerativeConstructor() &&
           (current_block_->scope->function_level() == 0)) {
         ReportError(expr_pos,
@@ -10021,7 +10070,7 @@
 
 
 void Parser::ReportErrors(const Error& prev_error,
-                          const Script& script, intptr_t token_pos,
+                          const Script& script, TokenPosition token_pos,
                           const char* format, ...) {
   va_list args;
   va_start(args, format);
@@ -10031,7 +10080,8 @@
 }
 
 
-void Parser::ReportError(intptr_t token_pos, const char* format, ...) const {
+void Parser::ReportError(TokenPosition token_pos,
+                         const char* format, ...) const {
   va_list args;
   va_start(args, format);
   Report::MessageV(Report::kError,
@@ -10062,7 +10112,8 @@
 }
 
 
-void Parser::ReportWarning(intptr_t token_pos, const char* format, ...) const {
+void Parser::ReportWarning(TokenPosition token_pos,
+                           const char* format, ...) const {
   va_list args;
   va_start(args, format);
   Report::MessageV(Report::kWarning,
@@ -10162,7 +10213,7 @@
 }
 
 
-SequenceNode* Parser::NodeAsSequenceNode(intptr_t sequence_pos,
+SequenceNode* Parser::NodeAsSequenceNode(TokenPosition sequence_pos,
                                          AstNode* node,
                                          LocalScope* scope) {
   if ((node == NULL) || !node->IsSequenceNode()) {
@@ -10177,7 +10228,8 @@
 
 
 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew.
-AstNode* Parser::ThrowTypeError(intptr_t type_pos, const AbstractType& type,
+AstNode* Parser::ThrowTypeError(TokenPosition type_pos,
+                                const AbstractType& type,
                                 LibraryPrefix* prefix) {
   ArgumentListNode* arguments = new(Z) ArgumentListNode(type_pos);
 
@@ -10191,7 +10243,7 @@
   }
   // Location argument.
   arguments->Add(new(Z) LiteralNode(
-      type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos))));
+      type_pos, Integer::ZoneHandle(Z, Integer::New(type_pos.value()))));
   // Src value argument.
   arguments->Add(new(Z) LiteralNode(type_pos, Object::null_instance()));
   // Dst type name argument.
@@ -10208,7 +10260,7 @@
 
 
 // Call _throwNewIfNotLoaded if prefix is not NULL, otherwise call _throwNew.
-AstNode* Parser::ThrowNoSuchMethodError(intptr_t call_pos,
+AstNode* Parser::ThrowNoSuchMethodError(TokenPosition call_pos,
                                         const Class& cls,
                                         const String& function_name,
                                         ArgumentListNode* function_arguments,
@@ -10314,7 +10366,7 @@
   while (current_preced >= min_preced) {
     while (Token::Precedence(CurrentToken()) == current_preced) {
       Token::Kind op_kind = CurrentToken();
-      const intptr_t op_pos = TokenPos();
+      const TokenPosition op_pos = TokenPos();
       ConsumeToken();
       AstNode* right_operand = NULL;
       if ((op_kind != Token::kIS) && (op_kind != Token::kAS)) {
@@ -10325,7 +10377,7 @@
           ConsumeToken();
           op_kind = Token::kISNOT;
         }
-        const intptr_t type_pos = TokenPos();
+        const TokenPosition type_pos = TokenPos();
         const AbstractType& type = AbstractType::ZoneHandle(Z,
             ParseType(ClassFinalizer::kCanonicalize));
         if (!type.IsInstantiated() &&
@@ -10403,10 +10455,10 @@
 }
 
 
-LocalVariable* Parser::CreateTempConstVariable(intptr_t token_pos,
+LocalVariable* Parser::CreateTempConstVariable(TokenPosition token_pos,
                                                const char* s) {
   char name[64];
-  OS::SNPrint(name, 64, ":%s%" Pd, s, token_pos);
+  OS::SNPrint(name, 64, ":%s%" Pd "", s, token_pos.value());
   LocalVariable* temp = new(Z) LocalVariable(
       token_pos,
       String::ZoneHandle(Z, Symbols::New(name)),
@@ -10418,7 +10470,7 @@
 
 
 // TODO(srdjan): Implement other optimizations.
-AstNode* Parser::OptimizeBinaryOpNode(intptr_t op_pos,
+AstNode* Parser::OptimizeBinaryOpNode(TokenPosition op_pos,
                                       Token::Kind binary_op,
                                       AstNode* lhs,
                                       AstNode* rhs) {
@@ -10476,7 +10528,7 @@
     LetNode* result = new(Z) LetNode(op_pos);
     LocalVariable* left_temp = result->AddInitializer(lhs);
     left_temp->set_is_final();
-    const intptr_t no_pos = Token::kNoSourcePos;
+    const TokenPosition no_pos = TokenPosition::kNoSource;
     LiteralNode* null_operand =
         new(Z) LiteralNode(no_pos, Object::null_instance());
     LoadLocalNode* load_left_temp = new(Z) LoadLocalNode(no_pos, left_temp);
@@ -10495,7 +10547,7 @@
 }
 
 
-AstNode* Parser::ExpandAssignableOp(intptr_t op_pos,
+AstNode* Parser::ExpandAssignableOp(TokenPosition op_pos,
                                     Token::Kind assignment_op,
                                     AstNode* lhs,
                                     AstNode* rhs) {
@@ -10539,7 +10591,7 @@
 
 // Evaluates the value of the compile time constant expression
 // and returns a literal node for the value.
-LiteralNode* Parser::FoldConstExpr(intptr_t expr_pos, AstNode* expr) {
+LiteralNode* Parser::FoldConstExpr(TokenPosition expr_pos, AstNode* expr) {
   if (expr->IsLiteralNode()) {
     return expr->AsLiteralNode();
   }
@@ -10553,7 +10605,7 @@
 
 LetNode* Parser::PrepareCompoundAssignmentNodes(AstNode** expr) {
   AstNode* node = *expr;
-  intptr_t token_pos = node->token_pos();
+  TokenPosition token_pos = node->token_pos();
   LetNode* result = new(Z) LetNode(token_pos);
   if (node->IsLoadIndexedNode()) {
     LoadIndexedNode* load_indexed = node->AsLoadIndexedNode();
@@ -10597,8 +10649,8 @@
 // A syntactically legal assignable expression always ends with an
 // identifier token or a ] token. We rewind the token iterator and
 // check whether the token before end_pos is an identifier or ].
-bool Parser::IsLegalAssignableSyntax(AstNode* expr, intptr_t end_pos) {
-  ASSERT(expr->token_pos() >= 0);
+bool Parser::IsLegalAssignableSyntax(AstNode* expr, TokenPosition end_pos) {
+  ASSERT(expr->token_pos().IsReal());
   ASSERT(expr->token_pos() < end_pos);
   SetPosition(expr->token_pos());
   Token::Kind token = Token::kILLEGAL;
@@ -10614,7 +10666,7 @@
 AstNode* Parser::CreateAssignmentNode(AstNode* original,
                                       AstNode* rhs,
                                       const String* left_ident,
-                                      intptr_t left_pos,
+                                      TokenPosition left_pos,
                                       bool is_compound /* = false */) {
   AstNode* result = original->MakeAssignmentNode(rhs);
   if (result == NULL) {
@@ -10672,7 +10724,7 @@
 
 
 AstNode* Parser::ParseCascades(AstNode* expr) {
-  intptr_t cascade_pos = TokenPos();
+  TokenPosition cascade_pos = TokenPos();
   LetNode* cascade = new(Z) LetNode(cascade_pos);
   LocalVariable* cascade_receiver_var = cascade->AddInitializer(expr);
   while (CurrentToken() == Token::kCASCADE) {
@@ -10689,14 +10741,14 @@
     }
     String* expr_ident =
         Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL;
-    const intptr_t expr_pos = TokenPos();
+    const TokenPosition expr_pos = TokenPos();
     expr = ParseSelectors(load_cascade_receiver, true);
 
     // Assignments after a cascade are part of the cascade. The
     // assigned expression must not contain cascades.
     if (Token::IsAssignmentOperator(CurrentToken())) {
       Token::Kind assignment_op = CurrentToken();
-      const intptr_t assignment_pos = TokenPos();
+      const TokenPosition assignment_pos = TokenPos();
       ConsumeToken();
       AstNode* right_expr = ParseExpr(kAllowConst, kNoCascades);
       if (assignment_op != Token::kASSIGN) {
@@ -10776,7 +10828,7 @@
   TRACE_PARSER("ParseExpr");
   String* expr_ident =
       Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL;
-  const intptr_t expr_pos = TokenPos();
+  const TokenPosition expr_pos = TokenPos();
 
   RecursionChecker rc(this);
 
@@ -10822,9 +10874,9 @@
     ReportError(expr_pos, "expression is not assignable");
   }
   const Token::Kind assignment_op = CurrentToken();
-  const intptr_t assignment_pos = TokenPos();
+  const TokenPosition assignment_pos = TokenPos();
   ConsumeToken();
-  const intptr_t right_expr_pos = TokenPos();
+  const TokenPosition right_expr_pos = TokenPos();
   if (require_compiletime_const && (assignment_op != Token::kASSIGN)) {
     ReportError(right_expr_pos,
                 "expression is not a valid compile-time constant");
@@ -10852,7 +10904,7 @@
 
 LiteralNode* Parser::ParseConstExpr() {
   TRACE_PARSER("ParseConstExpr");
-  intptr_t expr_pos = TokenPos();
+  TokenPosition expr_pos = TokenPos();
   AstNode* expr = ParseExpr(kRequireConst, kNoCascades);
   if (!expr->IsLiteralNode()) {
     ReportError(expr_pos, "expression must be a compile-time constant");
@@ -10863,7 +10915,7 @@
 
 AstNode* Parser::ParseConditionalExpr() {
   TRACE_PARSER("ParseConditionalExpr");
-  const intptr_t expr_pos = TokenPos();
+  const TokenPosition expr_pos = TokenPos();
   AstNode* expr = ParseBinaryExpr(Token::Precedence(Token::kIFNULL));
   if (CurrentToken() == Token::kCONDITIONAL) {
     EnsureExpressionTemp();
@@ -10880,7 +10932,7 @@
 AstNode* Parser::ParseUnaryExpr() {
   TRACE_PARSER("ParseUnaryExpr");
   AstNode* expr = NULL;
-  const intptr_t op_pos = TokenPos();
+  const TokenPosition op_pos = TokenPos();
   if (IsAwaitKeyword()) {
     TRACE_PARSER("ParseAwaitExpr");
     if (!innermost_function().IsAsyncFunction() &&
@@ -10924,7 +10976,7 @@
     ConsumeToken();
     String* expr_ident =
         Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL;
-    const intptr_t expr_pos = TokenPos();
+    const TokenPosition expr_pos = TokenPos();
     expr = ParseUnaryExpr();
     if (!IsLegalAssignableSyntax(expr, TokenPos())) {
       ReportError(expr_pos, "expression is not assignable");
@@ -11005,9 +11057,9 @@
 
 AstNode* Parser::ParseStaticCall(const Class& cls,
                                  const String& func_name,
-                                 intptr_t ident_pos) {
+                                 TokenPosition ident_pos) {
   TRACE_PARSER("ParseStaticCall");
-  const intptr_t call_pos = TokenPos();
+  const TokenPosition call_pos = TokenPos();
   ASSERT(CurrentToken() == Token::kLPAREN);
   ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst);
   const int num_arguments = arguments->length();
@@ -11093,7 +11145,7 @@
 
 AstNode* Parser::ParseInstanceCall(AstNode* receiver,
                                    const String& func_name,
-                                   intptr_t ident_pos,
+                                   TokenPosition ident_pos,
                                    bool is_conditional) {
   TRACE_PARSER("ParseInstanceCall");
   CheckToken(Token::kLPAREN);
@@ -11108,7 +11160,7 @@
 
 AstNode* Parser::ParseClosureCall(AstNode* closure) {
   TRACE_PARSER("ParseClosureCall");
-  const intptr_t call_pos = TokenPos();
+  const TokenPosition call_pos = TokenPos();
   ASSERT(CurrentToken() == Token::kLPAREN);
   ArgumentListNode* arguments = ParseActualParameters(NULL, kAllowConst);
   return BuildClosureCall(call_pos, closure, arguments);
@@ -11116,7 +11168,7 @@
 
 
 AstNode* Parser::GenerateStaticFieldLookup(const Field& field,
-                                           intptr_t ident_pos) {
+                                           TokenPosition ident_pos) {
   // If the static field has an initializer, initialize the field at compile
   // time, which is only possible if the field is const.
   AstNode* initializing_getter = RunStaticFieldInitializer(field, ident_pos);
@@ -11150,7 +11202,7 @@
 // Reference to 'field_name' with explicit class as primary.
 AstNode* Parser::GenerateStaticFieldAccess(const Class& cls,
                                            const String& field_name,
-                                           intptr_t ident_pos) {
+                                           TokenPosition ident_pos) {
   AstNode* access = NULL;
   const Field& field = Field::ZoneHandle(Z, cls.LookupStaticField(field_name));
   Function& func = Function::ZoneHandle(Z);
@@ -11257,7 +11309,7 @@
       ConsumeToken();
       if (left->IsPrimaryNode()) {
         PrimaryNode* primary_node = left->AsPrimaryNode();
-        const intptr_t primary_pos = primary_node->token_pos();
+        const TokenPosition primary_pos = primary_node->token_pos();
         if (primary_node->primary().IsFunction()) {
           left = LoadClosure(primary_node);
         } else if (primary_node->primary().IsTypeParameter()) {
@@ -11287,7 +11339,7 @@
           left = LoadFieldIfUnresolved(left);
         }
       }
-      const intptr_t ident_pos = TokenPos();
+      const TokenPosition ident_pos = TokenPos();
       String* ident = ExpectIdentifier("identifier expected");
       if (CurrentToken() == Token::kLPAREN) {
         // Identifier followed by a opening paren: method call.
@@ -11333,7 +11385,7 @@
       // Super index operator handled in ParseSuperOperator().
       ASSERT(!left->IsPrimaryNode() || !left->AsPrimaryNode()->IsSuper());
 
-      const intptr_t bracket_pos = TokenPos();
+      const TokenPosition bracket_pos = TokenPos();
       ConsumeToken();
       left = LoadFieldIfUnresolved(left);
       const bool saved_mode = SetAllowFunctionLiterals(true);
@@ -11343,7 +11395,7 @@
       AstNode* array = left;
       if (left->IsPrimaryNode()) {
         PrimaryNode* primary_node = left->AsPrimaryNode();
-        const intptr_t primary_pos = primary_node->token_pos();
+        const TokenPosition primary_pos = primary_node->token_pos();
         if (primary_node->primary().IsFunction()) {
           array = LoadClosure(primary_node);
         } else if (primary_node->primary().IsClass()) {
@@ -11385,7 +11437,7 @@
     } else if (CurrentToken() == Token::kLPAREN) {
       if (left->IsPrimaryNode()) {
         PrimaryNode* primary_node = left->AsPrimaryNode();
-        const intptr_t primary_pos = primary_node->token_pos();
+        const TokenPosition primary_pos = primary_node->token_pos();
         if (primary_node->primary().IsFunction()) {
           const Function& func = Function::Cast(primary_node->primary());
           const String& func_name = String::ZoneHandle(Z, func.name());
@@ -11461,7 +11513,7 @@
       left = LoadFieldIfUnresolved(left);
       if (left->IsPrimaryNode()) {
         PrimaryNode* primary_node = left->AsPrimaryNode();
-        const intptr_t primary_pos = primary->token_pos();
+        const TokenPosition primary_pos = primary->token_pos();
         if (primary_node->primary().IsFunction()) {
           // Treat as implicit closure.
           left = LoadClosure(primary_node);
@@ -11514,7 +11566,7 @@
 // Closurization e#m of getter, setter, method or operator.
 AstNode* Parser::ParseClosurization(AstNode* primary) {
   ExpectToken(Token::kHASH);
-  intptr_t property_pos = TokenPos();
+  TokenPosition property_pos = TokenPos();
   bool is_setter_name = false;
 
   String& extractor_name = String::ZoneHandle(Z);
@@ -11655,7 +11707,7 @@
   TRACE_PARSER("ParsePostfixExpr");
   String* expr_ident =
       Token::IsIdentifier(CurrentToken()) ? CurrentLiteral() : NULL;
-  const intptr_t expr_pos = TokenPos();
+  const TokenPosition expr_pos = TokenPos();
   AstNode* expr = ParsePrimary();
   if (CurrentToken() == Token::kHASH) {
     expr = LoadFieldIfUnresolved(expr);
@@ -11669,7 +11721,7 @@
       ReportError(expr_pos, "expression is not assignable");
     }
     Token::Kind incr_op = CurrentToken();
-    const intptr_t op_pos = TokenPos();
+    const TokenPosition op_pos = TokenPos();
     ConsumeToken();
     // Not prefix.
     LetNode* let_expr = PrepareCompoundAssignmentNodes(&expr);
@@ -11802,7 +11854,7 @@
 }
 
 
-void Parser::CheckInstanceFieldAccess(intptr_t field_pos,
+void Parser::CheckInstanceFieldAccess(TokenPosition field_pos,
                                       const String& field_name) {
   // Fields are not accessible from a static function, except from a
   // constructor, which is considered as non-static by the compiler.
@@ -11865,10 +11917,10 @@
 // ConstantPosKey allows us to look up a constant in the map without
 // allocating a key pair (array).
 struct ConstantPosKey : ValueObject {
-  ConstantPosKey(const String& url, intptr_t pos)
+  ConstantPosKey(const String& url, TokenPosition pos)
       : script_url(url), token_pos(pos) { }
   const String& script_url;
-  intptr_t token_pos;
+  TokenPosition token_pos;
 };
 
 
@@ -11884,7 +11936,7 @@
     const Array& key2 = Array::Cast(b);
     // Compare raw strings of script url symbol and token positon.
     return (key1.script_url.raw() == key2.At(0))
-        && (key1.token_pos == Smi::Value(Smi::RawCast(key2.At(1))));
+        && (key1.token_pos.value() == Smi::Value(Smi::RawCast(key2.At(1))));
   }
   static uword Hash(const Object& obj) {
     const Array& key = Array::Cast(obj);
@@ -11894,13 +11946,13 @@
   }
   static uword Hash(const ConstantPosKey& key) {
     return HashValue(String::HashRawSymbol(key.script_url.raw()),
-                     key.token_pos);
+                     key.token_pos.value());
   }
   // Used by CachConstantValue 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);
-    key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos)));
+    key_obj.SetAt(1, Smi::Handle(Smi::New(key.token_pos.value())));
     return key_obj.raw();;
   }
 
@@ -11912,7 +11964,8 @@
 typedef UnorderedHashMap<ConstMapKeyEqualsTraits> ConstantsMap;
 
 
-void Parser::CacheConstantValue(intptr_t token_pos, const Instance& value) {
+void Parser::CacheConstantValue(TokenPosition token_pos,
+                                const Instance& value) {
   ConstantPosKey key(String::Handle(Z, script_.url()), token_pos);
   if (isolate()->object_store()->compile_time_constants() == Array::null()) {
     const intptr_t kInitialConstMapSize = 16;
@@ -11929,7 +11982,7 @@
 }
 
 
-bool Parser::GetCachedConstant(intptr_t token_pos, Instance* value) {
+bool Parser::GetCachedConstant(TokenPosition token_pos, Instance* value) {
   if (isolate()->object_store()->compile_time_constants() == Array::null()) {
     return false;
   }
@@ -11949,7 +12002,7 @@
 
 
 RawInstance* Parser::TryCanonicalize(const Instance& instance,
-                                     intptr_t token_pos) {
+                                     TokenPosition token_pos) {
   if (instance.IsNull()) {
     return instance.raw();
   }
@@ -11966,8 +12019,8 @@
 // If the field is already initialized, return no ast (NULL).
 // Otherwise, if the field is constant, initialize the field and return no ast.
 // If the field is not initialized and not const, return the ast for the getter.
-StaticGetterNode* Parser::RunStaticFieldInitializer(const Field& field,
-                                                    intptr_t field_ref_pos) {
+StaticGetterNode* Parser::RunStaticFieldInitializer(
+    const Field& field, TokenPosition field_ref_pos) {
   ASSERT(field.is_static());
   const Class& field_owner = Class::ZoneHandle(Z, field.owner());
   const String& field_name = String::ZoneHandle(Z, field.name());
@@ -12104,7 +12157,7 @@
 // Do a lookup for the identifier in the block scope and the class scope
 // return true if the identifier is found, false otherwise.
 // If node is non NULL return an AST node corresponding to the identifier.
-bool Parser::ResolveIdentInLocalScope(intptr_t ident_pos,
+bool Parser::ResolveIdentInLocalScope(TokenPosition ident_pos,
                                       const String &ident,
                                       AstNode** node) {
   TRACE_PARSER("ResolveIdentInLocalScope");
@@ -12209,7 +12262,7 @@
 // Resolve an identifier by checking the global scope of the current
 // library. If not found in the current library, then look in the scopes
 // of all libraries that are imported without a library prefix.
-AstNode* Parser::ResolveIdentInCurrentLibraryScope(intptr_t ident_pos,
+AstNode* Parser::ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos,
                                                    const String& ident) {
   TRACE_PARSER("ResolveIdentInCurrentLibraryScope");
   HANDLESCOPE(thread());
@@ -12255,7 +12308,7 @@
 // Do a lookup for the identifier in the scope of the specified
 // library prefix. This means trying to resolve it locally in all of the
 // libraries present in the library prefix.
-AstNode* Parser::ResolveIdentInPrefixScope(intptr_t ident_pos,
+AstNode* Parser::ResolveIdentInPrefixScope(TokenPosition ident_pos,
                                            const LibraryPrefix& prefix,
                                            const String& ident) {
   TRACE_PARSER("ResolveIdentInPrefixScope");
@@ -12334,7 +12387,7 @@
 // If the name cannot be resolved, turn it into an instance field access
 // if we're compiling an instance method, or generate
 // throw NoSuchMethodError if we're compiling a static method.
-AstNode* Parser::ResolveIdent(intptr_t ident_pos,
+AstNode* Parser::ResolveIdent(TokenPosition ident_pos,
                               const String& ident,
                               bool allow_closure_names) {
   TRACE_PARSER("ResolveIdent");
@@ -12365,7 +12418,7 @@
   }
   if (resolved->IsPrimaryNode()) {
     PrimaryNode* primary = resolved->AsPrimaryNode();
-    const intptr_t primary_pos = primary->token_pos();
+    const TokenPosition primary_pos = primary->token_pos();
     if (primary->primary().IsString()) {
       // We got an unresolved name. If we are compiling a static
       // method, evaluation of an unresolved identifier causes a
@@ -12424,7 +12477,7 @@
     LibraryPrefix* prefix) {
   TRACE_PARSER("ParseType");
   CheckToken(Token::kIDENT, "type name expected");
-  intptr_t ident_pos = TokenPos();
+  TokenPosition ident_pos = TokenPos();
   String& type_name = String::Handle(Z);
 
   if (finalization == ClassFinalizer::kIgnore) {
@@ -12537,7 +12590,7 @@
 
 
 void Parser::CheckConstructorCallTypeArguments(
-    intptr_t pos, const Function& constructor,
+    TokenPosition pos, const Function& constructor,
     const TypeArguments& type_arguments) {
   if (!type_arguments.IsNull()) {
     const Class& constructor_class = Class::Handle(Z, constructor.Owner());
@@ -12557,13 +12610,13 @@
 // Note: if the list literal is empty and the brackets have no whitespace
 // between them, the scanner recognizes the opening and closing bracket
 // as one token of type Token::kINDEX.
-AstNode* Parser::ParseListLiteral(intptr_t type_pos,
+AstNode* Parser::ParseListLiteral(TokenPosition type_pos,
                                   bool is_const,
                                   const TypeArguments& type_arguments) {
   TRACE_PARSER("ParseListLiteral");
-  ASSERT(type_pos >= 0);
+  ASSERT(type_pos.IsReal());
   ASSERT(CurrentToken() == Token::kLBRACK || CurrentToken() == Token::kINDEX);
-  const intptr_t literal_pos = TokenPos();
+  const TokenPosition literal_pos = TokenPos();
 
   if (is_const) {
     Instance& existing_const = Instance::ZoneHandle(Z);
@@ -12617,7 +12670,7 @@
   if (!is_empty_literal) {
     const bool saved_mode = SetAllowFunctionLiterals(true);
     while (CurrentToken() != Token::kRBRACK) {
-      const intptr_t element_pos = TokenPos();
+      const TokenPosition element_pos = TokenPos();
       AstNode* element = ParseExpr(is_const, kConsumeCascades);
       if (I->flags().type_checks() &&
           !is_const &&
@@ -12723,7 +12776,7 @@
 
 
 ConstructorCallNode* Parser::CreateConstructorCallNode(
-    intptr_t token_pos,
+    TokenPosition token_pos,
     const TypeArguments& type_arguments,
     const Function& constructor,
     ArgumentListNode* arguments) {
@@ -12760,13 +12813,13 @@
 }
 
 
-AstNode* Parser::ParseMapLiteral(intptr_t type_pos,
+AstNode* Parser::ParseMapLiteral(TokenPosition type_pos,
                                  bool is_const,
                                  const TypeArguments& type_arguments) {
   TRACE_PARSER("ParseMapLiteral");
-  ASSERT(type_pos >= 0);
+  ASSERT(type_pos.IsReal());
   ASSERT(CurrentToken() == Token::kLBRACE);
-  const intptr_t literal_pos = TokenPos();
+  const TokenPosition literal_pos = TokenPos();
 
   if (is_const) {
     Instance& existing_const = Instance::ZoneHandle(Z);
@@ -12819,7 +12872,7 @@
   // comma after the last entry.
   while (CurrentToken() != Token::kRBRACE) {
     const bool saved_mode = SetAllowFunctionLiterals(true);
-    const intptr_t key_pos = TokenPos();
+    const TokenPosition key_pos = TokenPos();
     AstNode* key = ParseExpr(is_const, kConsumeCascades);
     if (I->flags().type_checks() &&
         !is_const &&
@@ -12841,7 +12894,7 @@
       }
     }
     ExpectToken(Token::kCOLON);
-    const intptr_t value_pos = TokenPos();
+    const TokenPosition value_pos = TokenPos();
     AstNode* value = ParseExpr(is_const, kConsumeCascades);
     SetAllowFunctionLiterals(saved_mode);
     if (I->flags().type_checks() &&
@@ -12991,7 +13044,7 @@
     is_const = true;
     ConsumeToken();
   }
-  const intptr_t type_pos = TokenPos();
+  const TokenPosition type_pos = TokenPos();
   TypeArguments& type_arguments = TypeArguments::Handle(Z,
       ParseTypeArguments(ClassFinalizer::kCanonicalize));
   // Malformed type arguments are mapped to dynamic, so we will not encounter
@@ -13014,7 +13067,7 @@
 AstNode* Parser::ParseSymbolLiteral() {
   ASSERT(CurrentToken() == Token::kHASH);
   ConsumeToken();
-  intptr_t symbol_pos = TokenPos();
+  TokenPosition symbol_pos = TokenPos();
   String& symbol = String::ZoneHandle(Z);
   if (IsIdentifier()) {
     symbol = CurrentLiteral()->raw();
@@ -13064,8 +13117,8 @@
 }
 
 
-RawFunction* Parser::BuildConstructorClosureFunction(const Function& ctr,
-                                                     intptr_t token_pos) {
+RawFunction* Parser::BuildConstructorClosureFunction(
+    const Function& ctr, TokenPosition token_pos) {
   ASSERT(ctr.kind() == RawFunction::kConstructor);
   Function& closure = Function::Handle(Z);
   closure = I->LookupClosureFunction(innermost_function(), token_pos);
@@ -13182,13 +13235,13 @@
 
 AstNode* Parser::ParseNewOperator(Token::Kind op_kind) {
   TRACE_PARSER("ParseNewOperator");
-  const intptr_t new_pos = TokenPos();
+  const TokenPosition new_pos = TokenPos();
   ASSERT((op_kind == Token::kNEW) || (op_kind == Token::kCONST));
   bool is_const = (op_kind == Token::kCONST);
   if (!IsIdentifier()) {
     ReportError("type name expected");
   }
-  intptr_t type_pos = TokenPos();
+  TokenPosition type_pos = TokenPos();
   // Can't allocate const objects of a deferred type.
   const bool allow_deferred_type = !is_const;
   const Token::Kind la3 = LookaheadToken(3);
@@ -13259,7 +13312,7 @@
   }
 
   // Parse constructor parameters.
-  intptr_t call_pos = TokenPos();
+  TokenPosition call_pos = TokenPos();
   ArgumentListNode* arguments = NULL;
   if (!is_tearoff_expression) {
     CheckToken(Token::kLPAREN);
@@ -13399,7 +13452,7 @@
     }
     ArgumentListNode* error_arguments = new(Z) ArgumentListNode(type_pos);
     error_arguments->Add(new(Z) LiteralNode(
-        TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos))));
+        TokenPos(), Integer::ZoneHandle(Z, Integer::New(type_pos.value()))));
     error_arguments->Add(new(Z) LiteralNode(
         TokenPos(), String::ZoneHandle(Z, type_class_name.raw())));
     result->AddNode(
@@ -13577,7 +13630,7 @@
 AstNode* Parser::ParseStringLiteral(bool allow_interpolation) {
   TRACE_PARSER("ParseStringLiteral");
   AstNode* primary = NULL;
-  const intptr_t literal_start = TokenPos();
+  const TokenPosition literal_start = TokenPos();
   ASSERT(CurrentToken() == Token::kSTRING);
   Token::Kind l1_token = LookaheadToken(1);
   if ((l1_token != Token::kSTRING) &&
@@ -13616,7 +13669,7 @@
       }
       has_interpolation = true;
       AstNode* expr = NULL;
-      const intptr_t expr_pos = TokenPos();
+      const TokenPosition expr_pos = TokenPos();
       if (CurrentToken() == Token::kINTERPOL_VAR) {
         expr = ResolveIdent(TokenPos(), *CurrentLiteral(), true);
         ConsumeToken();
@@ -13689,7 +13742,7 @@
     primary = ParseFunctionStatement(true);
     CloseBlock();
   } else if (IsIdentifier()) {
-    intptr_t qual_ident_pos = TokenPos();
+    TokenPosition qual_ident_pos = TokenPos();
     const LibraryPrefix& prefix = LibraryPrefix::ZoneHandle(Z, ParsePrefix());
     if (!prefix.IsNull()) {
       if (CurrentToken() == Token::kHASH) {
@@ -13848,11 +13901,11 @@
       ReportError("class '%s' does not have a superclass",
                   String::Handle(Z, current_class().Name()).ToCString());
     }
-    const intptr_t super_pos = TokenPos();
+    const TokenPosition super_pos = TokenPos();
     ConsumeToken();
     if (CurrentToken() == Token::kPERIOD) {
       ConsumeToken();
-      const intptr_t ident_pos = TokenPos();
+      const TokenPosition ident_pos = TokenPos();
       const String& ident = *ExpectIdentifier("identifier expected");
       if (CurrentToken() == Token::kLPAREN) {
         primary = ParseSuperCall(ident);
@@ -13877,7 +13930,8 @@
 
 // Evaluate expression in expr and return the value. The expression must
 // be a compile time constant.
-const Instance& Parser::EvaluateConstExpr(intptr_t expr_pos, AstNode* expr) {
+const Instance& Parser::EvaluateConstExpr(TokenPosition expr_pos,
+                                          AstNode* expr) {
   if (expr->IsLiteralNode()) {
     return expr->AsLiteralNode()->literal();
   } else if (expr->IsLoadLocalNode() &&
@@ -14349,7 +14403,7 @@
 
 
 ArgumentListNode* Parser::BuildNoSuchMethodArguments(
-    intptr_t call_pos,
+    TokenPosition call_pos,
     const String& function_name,
     const ArgumentListNode& function_args,
     const LocalVariable* temp_for_last_arg,
diff --git a/runtime/vm/parser.h b/runtime/vm/parser.h
index 9d9e503..ebf38d3 100644
--- a/runtime/vm/parser.h
+++ b/runtime/vm/parser.h
@@ -233,8 +233,12 @@
   struct Block;
   class TryStack;
 
-  Parser(const Script& script, const Library& library, intptr_t token_pos);
-  Parser(const Script& script, ParsedFunction* function, intptr_t token_pos);
+  Parser(const Script& script,
+         const Library& library,
+         TokenPosition token_pos);
+  Parser(const Script& script,
+         ParsedFunction* function,
+         TokenPosition token_pos);
   ~Parser();
 
   // The function for which we will generate code.
@@ -274,7 +278,7 @@
   }
 
   const Script& script() const { return script_; }
-  void SetScript(const Script& script, intptr_t token_pos);
+  void SetScript(const Script& script, TokenPosition token_pos);
 
   const Library& library() const { return library_; }
   void set_library(const Library& value) const { library_ = value.raw(); }
@@ -294,8 +298,10 @@
     return script_.kind() == RawScript::kPatchTag;
   }
 
-  intptr_t TokenPos() const { return tokens_iterator_.CurrentPosition(); }
-  intptr_t PrevTokenPos() const { return prev_token_pos_; }
+  TokenPosition TokenPos() const {
+    return tokens_iterator_.CurrentPosition();
+  }
+  TokenPosition PrevTokenPos() const { return prev_token_pos_; }
 
   Token::Kind CurrentToken() {
     if (token_kind_ == Token::kILLEGAL) {
@@ -314,7 +320,7 @@
   RawInteger* CurrentIntegerLiteral() const;
 
   // Sets parser to given token position in the stream.
-  void SetPosition(intptr_t position);
+  void SetPosition(TokenPosition position);
 
   void ConsumeToken() {
     // Reset cache and advance the token.
@@ -337,7 +343,7 @@
   void SkipToMatching();
   void SkipToMatchingParenthesis();
   void SkipBlock();
-  intptr_t SkipMetadata();
+  TokenPosition SkipMetadata();
   void SkipTypeArguments();
   void SkipType(bool allow_void);
   void SkipInitializers();
@@ -362,7 +368,7 @@
 
   AstNode* DartPrint(const char* str);
 
-  void CheckConstructorCallTypeArguments(intptr_t pos,
+  void CheckConstructorCallTypeArguments(TokenPosition pos,
                                          const Function& constructor,
                                          const TypeArguments& type_arguments);
 
@@ -374,7 +380,7 @@
 
   // Concatenate and report an already formatted error and a new error message.
   static void ReportErrors(const Error& prev_error,
-                           const Script& script, intptr_t token_pos,
+                           const Script& script, TokenPosition token_pos,
                            const char* format, ...) PRINTF_ATTRIBUTE(4, 5);
 
   // Report error message at location of current token in current script.
@@ -383,62 +389,62 @@
   void ReportErrorBefore(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
 
   // Report error message at given location in current script.
-  void ReportError(intptr_t token_pos,
+  void ReportError(TokenPosition token_pos,
                    const char* msg, ...) const PRINTF_ATTRIBUTE(3, 4);
 
   // Report warning message at location of current token in current script.
   void ReportWarning(const char* msg, ...) const PRINTF_ATTRIBUTE(2, 3);
 
   // Report warning message at given location in current script.
-  void ReportWarning(intptr_t token_pos,
+  void ReportWarning(TokenPosition token_pos,
                      const char* msg, ...) const PRINTF_ATTRIBUTE(3, 4);
 
   void CheckRecursiveInvocation();
 
-  const Instance& EvaluateConstExpr(intptr_t expr_pos, AstNode* expr);
+  const Instance& EvaluateConstExpr(TokenPosition expr_pos, AstNode* expr);
   StaticGetterNode* RunStaticFieldInitializer(const Field& field,
-                                              intptr_t field_ref_pos);
+                                              TokenPosition field_ref_pos);
   RawObject* EvaluateConstConstructorCall(const Class& type_class,
                                           const TypeArguments& type_arguments,
                                           const Function& constructor,
                                           ArgumentListNode* arguments);
-  LiteralNode* FoldConstExpr(intptr_t expr_pos, AstNode* expr);
+  LiteralNode* FoldConstExpr(TokenPosition expr_pos, AstNode* expr);
 
   // Support for parsing of scripts.
   void ParseTopLevel();
   void ParseEnumDeclaration(const GrowableObjectArray& pending_classes,
                             const Object& tl_owner,
-                            intptr_t metadata_pos);
+                            TokenPosition metadata_pos);
   void ParseEnumDefinition(const Class& cls);
   void ParseClassDeclaration(const GrowableObjectArray& pending_classes,
                              const Object& tl_owner,
-                             intptr_t metadata_pos);
+                             TokenPosition metadata_pos);
   void ParseClassDefinition(const Class& cls);
   void ParseMixinAppAlias(const GrowableObjectArray& pending_classes,
                           const Object& tl_owner,
-                          intptr_t metadata_pos);
+                          TokenPosition metadata_pos);
   void ParseTypedef(const GrowableObjectArray& pending_classes,
                     const Object& tl_owner,
-                    intptr_t metadata_pos);
+                    TokenPosition metadata_pos);
   void ParseTopLevelVariable(TopLevel* top_level,
-                             const Object& owner, intptr_t metadata_pos);
+                             const Object& owner, TokenPosition metadata_pos);
   void ParseTopLevelFunction(TopLevel* top_level,
-                             const Object& owner, intptr_t metadata_pos);
+                             const Object& owner, TokenPosition metadata_pos);
   void ParseTopLevelAccessor(TopLevel* top_level,
-                             const Object& owner, intptr_t metadata_pos);
+                             const Object& owner, TokenPosition metadata_pos);
   RawArray* EvaluateMetadata();
 
   RawFunction::AsyncModifier ParseFunctionModifier();
 
   // Support for parsing libraries.
   RawObject* CallLibraryTagHandler(Dart_LibraryTag tag,
-                                   intptr_t token_pos,
+                                   TokenPosition token_pos,
                                    const String& url);
   void ParseIdentList(GrowableObjectArray* names);
   void ParseLibraryDefinition(const Object& tl_owner);
   void ParseLibraryName();
   void ParseLibraryImportExport(const Object& tl_owner,
-                                intptr_t metadata_pos);
+                                TokenPosition metadata_pos);
   void ParseLibraryPart();
   void ParsePartHeader();
   void ParseLibraryNameObsoleteSyntax();
@@ -464,7 +470,7 @@
   void ParseFieldDefinition(ClassDesc* members, MemberDesc* field);
   void CheckMemberNameConflict(ClassDesc* members, MemberDesc* member);
   void ParseClassMemberDefinition(ClassDesc* members,
-                                  intptr_t metadata_pos);
+                                  TokenPosition metadata_pos);
   void ParseFormalParameter(bool allow_explicit_default_value,
                             bool evaluate_metadata,
                             ParamList* params);
@@ -483,14 +489,14 @@
       LocalVariable* receiver,
       GrowableArray<Field*>* initialized_fields);
   AstNode* CheckDuplicateFieldInit(
-      intptr_t init_pos,
+      TokenPosition init_pos,
       GrowableArray<Field*>* initialized_fields,
       AstNode* instance,
       Field* field,
       AstNode* init_value);
   StaticCallNode* GenerateSuperConstructorCall(
       const Class& cls,
-      intptr_t supercall_pos,
+      TokenPosition supercall_pos,
       LocalVariable* receiver,
       ArgumentListNode* forwarding_args);
   StaticCallNode* ParseSuperInitializer(
@@ -507,7 +513,7 @@
   void ParseInterfaceList(const Class& cls);
   RawAbstractType* ParseMixins(const AbstractType& super_type);
   static StaticCallNode* BuildInvocationMirrorAllocation(
-      intptr_t call_pos,
+      TokenPosition call_pos,
       const String& function_name,
       const ArgumentListNode& function_args,
       const LocalVariable* temp,
@@ -515,18 +521,19 @@
   // Build arguments for a NoSuchMethodCall. If LocalVariable temp is not NULL,
   // the last argument is stored in temp.
   static ArgumentListNode* BuildNoSuchMethodArguments(
-      intptr_t call_pos,
+      TokenPosition call_pos,
       const String& function_name,
       const ArgumentListNode& function_args,
       const LocalVariable* temp,
       bool is_super_invocation);
-  RawFunction* GetSuperFunction(intptr_t token_pos,
+  RawFunction* GetSuperFunction(TokenPosition token_pos,
                                 const String& name,
                                 ArgumentListNode* arguments,
                                 bool resolve_getter,
                                 bool* is_no_such_method);
   AstNode* ParseSuperCall(const String& function_name);
-  AstNode* ParseSuperFieldAccess(const String& field_name, intptr_t field_pos);
+  AstNode* ParseSuperFieldAccess(const String& field_name,
+                                 TokenPosition field_pos);
   AstNode* ParseSuperOperator();
   AstNode* BuildUnarySuperOperator(Token::Kind op, PrimaryNode* super);
 
@@ -534,7 +541,7 @@
 
   void SetupDefaultsForOptionalParams(const ParamList& params);
   ClosureNode* CreateImplicitClosureNode(const Function& func,
-                                         intptr_t token_pos,
+                                         TokenPosition token_pos,
                                          AstNode* receiver);
   static void AddFormalParamsToFunction(const ParamList* params,
                                         const Function& func);
@@ -558,21 +565,21 @@
   void BuildDispatcherScope(const Function& func,
                             const ArgumentsDescriptor& desc);
 
-  void EnsureHasReturnStatement(SequenceNode* seq, intptr_t return_pos);
+  void EnsureHasReturnStatement(SequenceNode* seq, TokenPosition return_pos);
   void ChainNewBlock(LocalScope* outer_scope);
   void OpenBlock();
   void OpenLoopBlock();
   void OpenFunctionBlock(const Function& func);
   void OpenAsyncClosure();
-  RawFunction* OpenAsyncFunction(intptr_t formal_param_pos);
-  RawFunction* OpenSyncGeneratorFunction(intptr_t func_pos);
+  RawFunction* OpenAsyncFunction(TokenPosition formal_param_pos);
+  RawFunction* OpenSyncGeneratorFunction(TokenPosition func_pos);
   SequenceNode* CloseSyncGenFunction(const Function& closure,
                                      SequenceNode* closure_node);
   void AddSyncGenClosureParameters(ParamList* params);
   void AddAsyncGenClosureParameters(ParamList* params);
 
   // Support for async* functions.
-  RawFunction* OpenAsyncGeneratorFunction(intptr_t func_pos);
+  RawFunction* OpenAsyncGeneratorFunction(TokenPosition func_pos);
   SequenceNode* CloseAsyncGeneratorFunction(const Function& closure,
                                             SequenceNode* closure_node);
   void OpenAsyncGeneratorClosure();
@@ -596,10 +603,10 @@
   LocalVariable* LookupTypeArgumentsParameter(LocalScope* from_scope,
                                               bool test_only);
   void CaptureInstantiator();
-  AstNode* LoadReceiver(intptr_t token_pos);
+  AstNode* LoadReceiver(TokenPosition token_pos);
   AstNode* LoadFieldIfUnresolved(AstNode* node);
   AstNode* LoadClosure(PrimaryNode* primary);
-  InstanceGetterNode* CallGetter(intptr_t token_pos,
+  InstanceGetterNode* CallGetter(TokenPosition token_pos,
                                  AstNode* object,
                                  const String& name);
 
@@ -610,7 +617,7 @@
   AstNode* ParseDoWhileStatement(String* label_name);
   AstNode* ParseForStatement(String* label_name);
   AstNode* ParseAwaitForStatement(String* label_name);
-  AstNode* ParseForInStatement(intptr_t forin_pos, SourceLabel* label);
+  AstNode* ParseForInStatement(TokenPosition forin_pos, SourceLabel* label);
   RawClass* CheckCaseExpressions(const GrowableArray<LiteralNode*>& values);
   CaseNode* ParseCaseClause(LocalVariable* switch_expr_value,
                             GrowableArray<LiteralNode*>* case_expr_values,
@@ -634,7 +641,7 @@
                                   LocalVariable* saved_exception_var,
                                   LocalVariable* saved_stack_trace_var);
   // Parse all the catch clause of a try.
-  SequenceNode* ParseCatchClauses(intptr_t handler_pos,
+  SequenceNode* ParseCatchClauses(TokenPosition handler_pos,
                                   bool is_async,
                                   LocalVariable* exception_var,
                                   LocalVariable* stack_trace_var,
@@ -717,15 +724,15 @@
   String* ParseImportStringLiteral();
   AstNode* ParseCompoundLiteral();
   AstNode* ParseSymbolLiteral();
-  AstNode* ParseListLiteral(intptr_t type_pos,
+  AstNode* ParseListLiteral(TokenPosition type_pos,
                             bool is_const,
                             const TypeArguments& type_arguments);
-  AstNode* ParseMapLiteral(intptr_t type_pos,
+  AstNode* ParseMapLiteral(TokenPosition type_pos,
                            bool is_const,
                            const TypeArguments& type_arguments);
 
   RawFunction* BuildConstructorClosureFunction(const Function& ctr,
-                                               intptr_t token_pos);
+                                               TokenPosition token_pos);
   AstNode* ParseNewOperator(Token::Kind op_kind);
   void ParseConstructorClosurization(Function* constructor,
                                      TypeArguments* type_arguments);
@@ -735,24 +742,25 @@
                                           bool require_const);
   AstNode* ParseStaticCall(const Class& cls,
                            const String& method_name,
-                           intptr_t ident_pos);
+                           TokenPosition ident_pos);
   AstNode* ParseInstanceCall(AstNode* receiver,
                              const String& method_name,
-                             intptr_t ident_pos,
+                             TokenPosition ident_pos,
                              bool is_conditional);
   AstNode* ParseClosureCall(AstNode* closure);
   AstNode* GenerateStaticFieldLookup(const Field& field,
-                                     intptr_t ident_pos);
+                                     TokenPosition ident_pos);
   AstNode* GenerateStaticFieldAccess(const Class& cls,
                                      const String& field_name,
-                                     intptr_t ident_pos);
+                                     TokenPosition ident_pos);
 
   LocalVariable* LookupLocalScope(const String& ident);
-  void CheckInstanceFieldAccess(intptr_t field_pos, const String& field_name);
+  void CheckInstanceFieldAccess(TokenPosition field_pos,
+                                const String& field_name);
   bool ParsingStaticMember() const;
   const AbstractType* ReceiverType(const Class& cls);
   bool IsInstantiatorRequired() const;
-  bool ResolveIdentInLocalScope(intptr_t ident_pos,
+  bool ResolveIdentInLocalScope(TokenPosition ident_pos,
                                 const String &ident,
                                 AstNode** node);
   static const bool kResolveLocally = true;
@@ -760,28 +768,29 @@
 
   // Resolve a primary identifier in the library or prefix scope and
   // generate the corresponding AstNode.
-  AstNode* ResolveIdentInCurrentLibraryScope(intptr_t ident_pos,
+  AstNode* ResolveIdentInCurrentLibraryScope(TokenPosition ident_pos,
                                              const String& ident);
-  AstNode* ResolveIdentInPrefixScope(intptr_t ident_pos,
+  AstNode* ResolveIdentInPrefixScope(TokenPosition ident_pos,
                                      const LibraryPrefix& prefix,
                                      const String& ident);
 
-  AstNode* ResolveIdent(intptr_t ident_pos,
+  AstNode* ResolveIdent(TokenPosition ident_pos,
                         const String& ident,
                         bool allow_closure_names);
-  RawString* ResolveImportVar(intptr_t ident_pos, const String& ident);
-  AstNode* OptimizeBinaryOpNode(intptr_t op_pos,
+  RawString* ResolveImportVar(TokenPosition ident_pos, const String& ident);
+  AstNode* OptimizeBinaryOpNode(TokenPosition op_pos,
                                 Token::Kind binary_op,
                                 AstNode* lhs,
                                 AstNode* rhs);
-  AstNode* ExpandAssignableOp(intptr_t op_pos,
+  AstNode* ExpandAssignableOp(TokenPosition op_pos,
                               Token::Kind assignment_op,
                               AstNode* lhs,
                               AstNode* rhs);
   LetNode* PrepareCompoundAssignmentNodes(AstNode** expr);
-  LocalVariable* CreateTempConstVariable(intptr_t token_pos, const char* s);
+  LocalVariable* CreateTempConstVariable(TokenPosition token_pos,
+                                         const char* s);
 
-  static SequenceNode* NodeAsSequenceNode(intptr_t sequence_pos,
+  static SequenceNode* NodeAsSequenceNode(TokenPosition sequence_pos,
                                           AstNode* node,
                                           LocalScope* scope);
 
@@ -790,10 +799,11 @@
                           const String& func_name,
                           ArgumentListNode* arguments);
   String& Interpolate(const GrowableArray<AstNode*>& values);
-  AstNode* MakeAssertCall(intptr_t begin, intptr_t end);
-  AstNode* ThrowTypeError(intptr_t type_pos, const AbstractType& type,
-                           LibraryPrefix* prefix = NULL);
-  AstNode* ThrowNoSuchMethodError(intptr_t call_pos,
+  AstNode* MakeAssertCall(TokenPosition begin, TokenPosition end);
+  AstNode* ThrowTypeError(TokenPosition type_pos,
+                          const AbstractType& type,
+                          LibraryPrefix* prefix = NULL);
+  AstNode* ThrowNoSuchMethodError(TokenPosition call_pos,
                                   const Class& cls,
                                   const String& function_name,
                                   ArgumentListNode* function_arguments,
@@ -807,29 +817,30 @@
   void CheckOperatorArity(const MemberDesc& member);
 
   void EnsureExpressionTemp();
-  bool IsLegalAssignableSyntax(AstNode* expr, intptr_t end_pos);
+  bool IsLegalAssignableSyntax(AstNode* expr, TokenPosition end_pos);
   AstNode* CreateAssignmentNode(AstNode* original,
                                 AstNode* rhs,
                                 const String* left_ident,
-                                intptr_t left_pos,
+                                TokenPosition left_pos,
                                 bool is_compound = false);
   AstNode* InsertClosureCallNodes(AstNode* condition);
 
   ConstructorCallNode* CreateConstructorCallNode(
-      intptr_t token_pos,
+      TokenPosition token_pos,
       const TypeArguments& type_arguments,
       const Function& constructor,
       ArgumentListNode* arguments);
 
   void AddEqualityNullCheck();
 
-  AstNode* BuildClosureCall(intptr_t token_pos,
+  AstNode* BuildClosureCall(TokenPosition token_pos,
                             AstNode* closure,
                             ArgumentListNode* arguments);
 
-  RawInstance* TryCanonicalize(const Instance& instance, intptr_t token_pos);
-  void CacheConstantValue(intptr_t token_pos, const Instance& value);
-  bool GetCachedConstant(intptr_t token_pos, Instance* value);
+  RawInstance* TryCanonicalize(const Instance& instance,
+                               TokenPosition token_pos);
+  void CacheConstantValue(TokenPosition token_pos, const Instance& value);
+  bool GetCachedConstant(TokenPosition token_pos, Instance* value);
 
   Thread* thread() const { return thread_; }
   Isolate* isolate() const { return isolate_; }
@@ -841,7 +852,7 @@
   Script& script_;
   TokenStream::Iterator tokens_iterator_;
   Token::Kind token_kind_;  // Cached token kind for current token.
-  intptr_t prev_token_pos_;
+  TokenPosition prev_token_pos_;
   Block* current_block_;
 
   // is_top_level_ is true if parsing the "top level" of a compilation unit,
diff --git a/runtime/vm/precompiler.cc b/runtime/vm/precompiler.cc
index 2131faf..f5098bb 100644
--- a/runtime/vm/precompiler.cc
+++ b/runtime/vm/precompiler.cc
@@ -55,7 +55,7 @@
 
 Precompiler::Precompiler(Thread* thread, bool reset_fields) :
     thread_(thread),
-    zone_(thread->zone()),
+    zone_(NULL),
     isolate_(thread->isolate()),
     reset_fields_(reset_fields),
     changed_(false),
@@ -64,12 +64,12 @@
     selector_count_(0),
     dropped_function_count_(0),
     dropped_field_count_(0),
-    libraries_(GrowableObjectArray::Handle(Z, I->object_store()->libraries())),
+    libraries_(GrowableObjectArray::Handle(I->object_store()->libraries())),
     pending_functions_(
-        GrowableObjectArray::Handle(Z, GrowableObjectArray::New())),
+        GrowableObjectArray::Handle(GrowableObjectArray::New())),
     sent_selectors_(),
     enqueued_functions_(),
-    error_(Error::Handle(Z)) {
+    error_(Error::Handle()) {
 }
 
 
@@ -77,63 +77,76 @@
     Dart_QualifiedFunctionName embedder_entry_points[]) {
   ASSERT(I->compilation_allowed());
 
-  // Make sure class hierarchy is stable before compilation so that CHA
-  // can be used. Also ensures lookup of entry points won't miss functions
-  // because their class hasn't been finalized yet.
-  FinalizeAllClasses();
+  {
+    StackZone stack_zone(T);
+    zone_ = stack_zone.GetZone();
 
-  const intptr_t kPrecompilerRounds = 1;
-  for (intptr_t round = 0; round < kPrecompilerRounds; round++) {
-    if (FLAG_trace_precompiler) {
-      OS::Print("Precompiler round %" Pd "\n", round);
+    // Make sure class hierarchy is stable before compilation so that CHA
+    // can be used. Also ensures lookup of entry points won't miss functions
+    // because their class hasn't been finalized yet.
+    FinalizeAllClasses();
+
+    const intptr_t kPrecompilerRounds = 1;
+    for (intptr_t round = 0; round < kPrecompilerRounds; round++) {
+      if (FLAG_trace_precompiler) {
+        OS::Print("Precompiler round %" Pd "\n", round);
+      }
+
+      if (round > 0) {
+        ResetPrecompilerState();
+      }
+
+      // TODO(rmacnak): We should be able to do a more thorough job and drop
+      // some
+      //  - implicit static closures
+      //  - field initializers
+      //  - invoke-field-dispatchers
+      //  - method-extractors
+      // that are needed in early iterations but optimized away in later
+      // iterations.
+      ClearAllCode();
+
+      CollectDynamicFunctionNames();
+
+      // Start with the allocations and invocations that happen from C++.
+      AddRoots(embedder_entry_points);
+
+      // Compile newly found targets and add their callees until we reach a
+      // fixed point.
+      Iterate();
     }
 
-    if (round > 0) {
-      ResetPrecompilerState();
-    }
+    I->set_compilation_allowed(false);
 
-    // TODO(rmacnak): We should be able to do a more thorough job and drop some
-    //  - implicit static closures
-    //  - field initializers
-    //  - invoke-field-dispatchers
-    //  - method-extractors
-    // that are needed in early iterations but optimized away in later
-    // iterations.
-    ClearAllCode();
+    DropUncompiledFunctions();
+    DropFields();
 
-    CollectDynamicFunctionNames();
+    // TODO(rmacnak): DropEmptyClasses();
 
-    // Start with the allocations and invocations that happen from C++.
-    AddRoots(embedder_entry_points);
+    BindStaticCalls();
 
-    // Compile newly found targets and add their callees until we reach a fixed
-    // point.
-    Iterate();
+    DedupStackmaps();
+    DedupStackmapLists();
+
+    I->object_store()->set_compile_time_constants(Array::null_array());
+    I->object_store()->set_unique_dynamic_targets(Array::null_array());
+
+    zone_ = NULL;
   }
 
-  DropUncompiledFunctions();
-  DropFields();
-
-  // TODO(rmacnak): DropEmptyClasses();
-
-  BindStaticCalls();
-
-  DedupStackmaps();
+  intptr_t dropped_symbols_count = Symbols::Compact(I);
 
   if (FLAG_trace_precompiler) {
     THR_Print("Precompiled %" Pd " functions, %" Pd " dynamic types,"
               " %" Pd " dynamic selectors.\n Dropped %" Pd " functions, %" Pd
-              " fields.\n",
+              " fields, %" Pd " symbols.\n",
               function_count_,
               class_count_,
               selector_count_,
               dropped_function_count_,
-              dropped_field_count_);
+              dropped_field_count_,
+              dropped_symbols_count);
   }
-
-  I->set_compilation_allowed(false);
-  I->object_store()->set_compile_time_constants(Array::null_array());
-  I->object_store()->set_unique_dynamic_targets(Array::null_array());
 }
 
 
@@ -371,10 +384,10 @@
     function_count_++;
 
     if (FLAG_trace_precompiler) {
-      THR_Print("Precompiling %" Pd " %s (%" Pd ", %s)\n",
+      THR_Print("Precompiling %" Pd " %s (%s, %s)\n",
                 function_count_,
                 function.ToLibNamePrefixedQualifiedCString(),
-                function.token_pos(),
+                function.token_pos().ToCString(),
                 Function::KindToCString(function.kind()));
     }
 
@@ -389,9 +402,9 @@
     if (FLAG_trace_precompiler) {
       // This function was compiled from somewhere other than Precompiler,
       // such as const constructors compiled by the parser.
-      THR_Print("Already has code: %s (%" Pd ", %s)\n",
+      THR_Print("Already has code: %s (%s, %s)\n",
                 function.ToLibNamePrefixedQualifiedCString(),
-                function.token_pos(),
+                function.token_pos().ToCString(),
                 Function::KindToCString(function.kind()));
     }
   }
@@ -1108,6 +1121,55 @@
 }
 
 
+void Precompiler::DedupStackmapLists() {
+  class DedupStackmapListsVisitor : public FunctionVisitor {
+   public:
+    explicit DedupStackmapListsVisitor(Zone* zone) :
+      zone_(zone),
+      canonical_stackmap_lists_(),
+      code_(Code::Handle(zone)),
+      stackmaps_(Array::Handle(zone)),
+      stackmap_(Stackmap::Handle(zone)) {
+    }
+
+    void VisitFunction(const Function& function) {
+      if (!function.HasCode()) {
+        ASSERT(function.HasImplicitClosureFunction());
+        return;
+      }
+      code_ = function.CurrentCode();
+      stackmaps_ = code_.stackmaps();
+      if (stackmaps_.IsNull()) return;
+
+      stackmaps_ = DedupStackmapList(stackmaps_);
+      code_.set_stackmaps(stackmaps_);
+    }
+
+    RawArray* DedupStackmapList(const Array& stackmaps) {
+      const Array* canonical_stackmap_list =
+          canonical_stackmap_lists_.Lookup(&stackmaps);
+      if (canonical_stackmap_list == NULL) {
+        canonical_stackmap_lists_.Insert(
+            &Array::ZoneHandle(zone_, stackmaps.raw()));
+        return stackmaps.raw();
+      } else {
+        return canonical_stackmap_list->raw();
+      }
+    }
+
+   private:
+    Zone* zone_;
+    ArraySet canonical_stackmap_lists_;
+    Code& code_;
+    Array& stackmaps_;
+    Stackmap& stackmap_;
+  };
+
+  DedupStackmapListsVisitor visitor(Z);
+  VisitFunctions(&visitor);
+}
+
+
 void Precompiler::VisitFunctions(FunctionVisitor* visitor) {
   Library& lib = Library::Handle(Z);
   Class& cls = Class::Handle(Z);
diff --git a/runtime/vm/precompiler.h b/runtime/vm/precompiler.h
index fe7ec2d..da267c0 100644
--- a/runtime/vm/precompiler.h
+++ b/runtime/vm/precompiler.h
@@ -64,6 +64,38 @@
 
 typedef DirectChainedHashMap<StackmapKeyValueTrait> StackmapSet;
 
+
+class ArrayKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef const Array* Key;
+  typedef const Array* Value;
+  typedef const Array* Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) {
+    return key->Length();
+  }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    if (pair->Length() != key->Length()) {
+      return false;
+    }
+    for (intptr_t i = 0; i < pair->Length(); i++) {
+      if (pair->At(i) != key->At(i)) {
+        return false;
+      }
+    }
+    return true;
+  }
+};
+
+typedef DirectChainedHashMap<ArrayKeyValueTrait> ArraySet;
+
+
 class FunctionKeyValueTrait {
  public:
   // Typedefs needed for the DirectChainedHashMap template.
@@ -76,7 +108,7 @@
   static Value ValueOf(Pair kv) { return kv; }
 
   static inline intptr_t Hashcode(Key key) {
-    return key->token_pos();
+    return key->token_pos().value();
   }
 
   static inline bool IsKeyEqual(Pair pair, Key key) {
@@ -99,7 +131,7 @@
   static Value ValueOf(Pair kv) { return kv; }
 
   static inline intptr_t Hashcode(Key key) {
-    return key->token_pos();
+    return key->token_pos().value();
   }
 
   static inline bool IsKeyEqual(Pair pair, Key key) {
@@ -152,6 +184,7 @@
   void CollectDynamicFunctionNames();
   void BindStaticCalls();
   void DedupStackmaps();
+  void DedupStackmapLists();
   void ResetPrecompilerState();
 
   class FunctionVisitor : public ValueObject {
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index c755890..e4f6c8d 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -340,17 +340,19 @@
     kClassAllocationSampleBit = 6,
     kContinuationSampleBit = 7,
   };
-  class HeadSampleBit : public BitField<bool, kHeadSampleBit, 1> {};
-  class LeafFrameIsDart : public BitField<bool, kLeafFrameIsDartBit, 1> {};
-  class IgnoreBit : public BitField<bool, kIgnoreBit, 1> {};
-  class ExitFrameBit : public BitField<bool, kExitFrameBit, 1> {};
+  class HeadSampleBit : public BitField<uword, bool, kHeadSampleBit, 1> {};
+  class LeafFrameIsDart :
+      public BitField<uword, bool, kLeafFrameIsDartBit, 1> {};
+  class IgnoreBit : public BitField<uword, bool, kIgnoreBit, 1> {};
+  class ExitFrameBit : public BitField<uword, bool, kExitFrameBit, 1> {};
   class MissingFrameInsertedBit
-      : public BitField<bool, kMissingFrameInsertedBit, 1> {};
-  class TruncatedTraceBit : public BitField<bool, kTruncatedTraceBit, 1> {};
+      : public BitField<uword, bool, kMissingFrameInsertedBit, 1> {};
+  class TruncatedTraceBit :
+      public BitField<uword, bool, kTruncatedTraceBit, 1> {};
   class ClassAllocationSampleBit
-      : public BitField<bool, kClassAllocationSampleBit, 1> {};
+      : public BitField<uword, bool, kClassAllocationSampleBit, 1> {};
   class ContinuationSampleBit
-      : public BitField<bool, kContinuationSampleBit, 1> {};
+      : public BitField<uword, bool, kContinuationSampleBit, 1> {};
 
   int64_t timestamp_;
   ThreadId tid_;
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index 35be68a..f4b07eb 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -10,6 +10,7 @@
 #include "vm/globals.h"
 #include "vm/snapshot.h"
 #include "vm/token.h"
+#include "vm/token_position.h"
 #include "vm/verified_memory.h"
 
 namespace dart {
@@ -284,7 +285,8 @@
 
    private:
     // The actual unscaled bit field used within the tag field.
-    class SizeBits : public BitField<intptr_t, kSizeTagPos, kSizeTagSize> {};
+    class SizeBits :
+        public BitField<uword, intptr_t, kSizeTagPos, kSizeTagSize> {};
 
     static intptr_t SizeToTagValue(intptr_t size) {
       ASSERT(Utils::IsAligned(size, kObjectAlignment));
@@ -296,7 +298,7 @@
   };
 
   class ClassIdTag :
-      public BitField<intptr_t, kClassIdTagPos, kClassIdTagSize> {};  // NOLINT
+      public BitField<uword, intptr_t, kClassIdTagPos, kClassIdTagSize> {};
 
   bool IsWellFormed() const {
     uword value = reinterpret_cast<uword>(this);
@@ -431,6 +433,9 @@
   bool IsCode() {
     return ((GetClassId() == kCodeCid));
   }
+  bool IsString() {
+    return IsStringClassId(GetClassId());
+  }
 
   intptr_t Size() const {
     uword tags = ptr()->tags_;
@@ -493,18 +498,18 @@
  private:
   uword tags_;  // Various object tags (bits).
 
-  class WatchedBit : public BitField<bool, kWatchedBit, 1> {};
+  class WatchedBit : public BitField<uword, bool, kWatchedBit, 1> {};
 
-  class MarkBit : public BitField<bool, kMarkBit, 1> {};
+  class MarkBit : public BitField<uword, bool, kMarkBit, 1> {};
 
-  class RememberedBit : public BitField<bool, kRememberedBit, 1> {};
+  class RememberedBit : public BitField<uword, bool, kRememberedBit, 1> {};
 
-  class CanonicalObjectTag : public BitField<bool, kCanonicalBit, 1> {};
+  class CanonicalObjectTag : public BitField<uword, bool, kCanonicalBit, 1> {};
 
-  class VMHeapObjectTag : public BitField<bool, kVMHeapObjectBit, 1> {};
+  class VMHeapObjectTag : public BitField<uword, bool, kVMHeapObjectBit, 1> {};
 
   class ReservedBits : public
-      BitField<intptr_t, kReservedTagPos, kReservedTagSize> {};  // NOLINT
+      BitField<uword, intptr_t, kReservedTagPos, kReservedTagSize> {};
 
   // TODO(koda): After handling tags_, return const*, like Object::raw_ptr().
   RawObject* ptr() const {
@@ -675,7 +680,7 @@
   }
 
   cpp_vtable handle_vtable_;
-  int32_t token_pos_;
+  TokenPosition token_pos_;
   int32_t instance_size_in_words_;  // Size if fixed len or 0 if variable len.
   int32_t type_arguments_field_offset_in_words_;  // Offset of type args fld.
   int32_t next_field_offset_in_words_;  // Offset of the next instance field.
@@ -704,7 +709,7 @@
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->ident_);
   }
-  int32_t token_pos_;
+  TokenPosition token_pos_;
 };
 
 
@@ -813,8 +818,8 @@
   }
   uword entry_point_;
 
-  int32_t token_pos_;
-  int32_t end_token_pos_;
+  TokenPosition token_pos_;
+  TokenPosition end_token_pos_;
   int32_t usage_counter_;  // Incremented while function is running.
   int16_t num_fixed_parameters_;
   int16_t num_optional_parameters_;  // > 0: positional; < 0: named.
@@ -890,7 +895,7 @@
     return reinterpret_cast<RawObject**>(&ptr()->guarded_list_length_);
   }
 
-  int32_t token_pos_;
+  TokenPosition token_pos_;
   classid_t guarded_cid_;
   classid_t is_nullable_;  // kNullCid if field can contain null value and
                            // any other value otherwise.
@@ -1270,14 +1275,14 @@
     kMaxIndex = (1 << (kIndexSize - 1)) - 1,
   };
 
-  class IndexBits : public BitField<int32_t, kIndexPos, kIndexSize> {};
-  class KindBits : public BitField<int8_t, kKindPos, kKindSize>{};
+  class IndexBits : public BitField<int32_t, int32_t, kIndexPos, kIndexSize> {};
+  class KindBits : public BitField<int32_t, int8_t, kKindPos, kKindSize>{};
 
   struct VarInfo {
     int32_t index_kind;  // Bitfield for slot index on stack or in context,
                          // and Entry kind of type VarInfoKind.
-    int32_t begin_pos;   // Token position of scope start.
-    int32_t end_pos;     // Token position of scope end.
+    TokenPosition begin_pos;   // Token position of scope start.
+    TokenPosition end_pos;     // Token position of scope end.
     int16_t scope_id;    // Scope to which the variable belongs.
 
     VarInfoKind kind() const {
@@ -1492,7 +1497,7 @@
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->formatted_message_);
   }
-  int32_t token_pos_;  // Source position in script_.
+  TokenPosition token_pos_;  // Source position in script_.
   bool report_after_token_;  // Report message at or after the token.
   int8_t kind_;  // Of type LanguageError::Kind.
 };
@@ -1580,7 +1585,7 @@
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->error_);
   }
-  int32_t token_pos_;
+  TokenPosition token_pos_;
   int8_t type_state_;
 };
 
@@ -1599,7 +1604,7 @@
   RawObject** to() {
     return reinterpret_cast<RawObject**>(&ptr()->error_);
   }
-  int32_t token_pos_;
+  TokenPosition token_pos_;
   int8_t type_state_;
 };
 
@@ -1629,7 +1634,7 @@
   RawString* name_;
   RawAbstractType* bound_;  // ObjectType if no explicit bound specified.
   RawObject** to() { return reinterpret_cast<RawObject**>(&ptr()->bound_); }
-  int32_t token_pos_;
+  TokenPosition token_pos_;
   int16_t index_;
   int8_t type_state_;
 };
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 3a934d5..1a617ba 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -77,7 +77,7 @@
     cls.set_num_type_arguments(reader->Read<int16_t>());
     cls.set_num_own_type_arguments(reader->Read<int16_t>());
     cls.set_num_native_fields(reader->Read<uint16_t>());
-    cls.set_token_pos(reader->Read<int32_t>());
+    cls.set_token_pos(TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
     cls.set_state_bits(reader->Read<uint16_t>());
 
     // Set all the object fields.
@@ -127,7 +127,7 @@
     writer->Write<uint16_t>(ptr()->num_type_arguments_);
     writer->Write<uint16_t>(ptr()->num_own_type_arguments_);
     writer->Write<uint16_t>(ptr()->num_native_fields_);
-    writer->Write<int32_t>(ptr()->token_pos_);
+    writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
     writer->Write<uint16_t>(ptr()->state_bits_);
 
     // Write out all the object pointer fields.
@@ -160,7 +160,8 @@
   reader->AddBackRef(object_id, &unresolved_class, kIsDeserialized);
 
   // Set all non object fields.
-  unresolved_class.set_token_pos(reader->Read<int32_t>());
+  unresolved_class.set_token_pos(
+      TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
 
   // Set all the object fields.
   READ_OBJECT_FIELDS(unresolved_class,
@@ -186,7 +187,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_);
+  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
 
   // Write out all the object pointer fields.
   SnapshotWriterVisitor visitor(writer, kAsReference);
@@ -230,7 +231,7 @@
   reader->AddBackRef(object_id, &type, kIsDeserialized, defer_canonicalization);
 
   // Set all non object fields.
-  type.set_token_pos(reader->Read<int32_t>());
+  type.set_token_pos(TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
   type.set_type_state(reader->Read<int8_t>());
 
   // Set all the object fields.
@@ -272,7 +273,7 @@
   writer->Write<bool>(typeclass_is_in_fullsnapshot);
 
   // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_);
+  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
   writer->Write<int8_t>(ptr()->type_state_);
 
   // Write out all the object pointer fields.
@@ -304,7 +305,8 @@
                      defer_canonicalization);
 
   // Set all non object fields.
-  function_type.set_token_pos(reader->Read<int32_t>());
+  function_type.set_token_pos(
+      TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
   function_type.set_type_state(reader->Read<int8_t>());
 
   // Set all the object fields.
@@ -348,7 +350,7 @@
   writer->Write<bool>(scopeclass_is_in_fullsnapshot);
 
   // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_);
+  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
   writer->Write<int8_t>(ptr()->type_state_);
 
   // Write out all the object pointer fields.
@@ -411,7 +413,8 @@
   reader->AddBackRef(object_id, &type_parameter, kIsDeserialized);
 
   // Set all non object fields.
-  type_parameter.set_token_pos(reader->Read<int32_t>());
+  type_parameter.set_token_pos(
+      TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
   type_parameter.set_index(reader->Read<int16_t>());
   type_parameter.set_type_state(reader->Read<int8_t>());
 
@@ -441,7 +444,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object pointer fields.
-  writer->Write<int32_t>(ptr()->token_pos_);
+  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
   writer->Write<int16_t>(ptr()->index_);
   writer->Write<int8_t>(ptr()->type_state_);
 
@@ -797,8 +800,8 @@
     func.set_num_fixed_parameters(reader->Read<int16_t>());
     func.set_num_optional_parameters(reader->Read<int16_t>());
     func.set_kind_tag(reader->Read<uint32_t>());
-    func.set_token_pos(token_pos);
-    func.set_end_token_pos(end_token_pos);
+    func.set_token_pos(TokenPosition::SnapshotDecode(token_pos));
+    func.set_end_token_pos(TokenPosition::SnapshotDecode(end_token_pos));
     if (reader->snapshot_code()) {
       func.set_usage_counter(0);
       func.set_deoptimization_counter(0);
@@ -874,8 +877,8 @@
     bool is_optimized = Code::IsOptimized(ptr()->code_);
 
     // Write out all the non object fields.
-    writer->Write<int32_t>(ptr()->token_pos_);
-    writer->Write<int32_t>(ptr()->end_token_pos_);
+    writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
+    writer->Write<int32_t>(ptr()->end_token_pos_.SnapshotEncode());
     writer->Write<int16_t>(ptr()->num_fixed_parameters_);
     writer->Write<int16_t>(ptr()->num_optional_parameters_);
     writer->Write<uint32_t>(ptr()->kind_tag_);
@@ -926,12 +929,13 @@
 
   // Set all non object fields.
   if (reader->snapshot_code()) {
-    field.set_token_pos(0);
+    field.set_token_pos(TokenPosition::kNoSource);
     ASSERT(!FLAG_use_field_guards);
     field.set_guarded_cid(kDynamicCid);
     field.set_is_nullable(true);
   } else {
-    field.set_token_pos(reader->Read<int32_t>());
+    field.set_token_pos(
+        TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
     field.set_guarded_cid(reader->Read<int32_t>());
     field.set_is_nullable(reader->Read<int32_t>());
   }
@@ -973,7 +977,7 @@
 
   // Write out all the non object fields.
   if (!writer->snapshot_code()) {
-    writer->Write<int32_t>(ptr()->token_pos_);
+    writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
     writer->Write<int32_t>(ptr()->guarded_cid_);
     writer->Write<int32_t>(ptr()->is_nullable_);
   }
@@ -1960,7 +1964,7 @@
     *reader->TypeHandle() ^= reader->ReadObjectImpl(kAsInlinedObject);
 
     // Create a descriptor for 'this' variable.
-    context_scope.SetTokenIndexAt(0, 0);
+    context_scope.SetTokenIndexAt(0, TokenPosition::kMinSource);
     context_scope.SetNameAt(0, Symbols::This());
     context_scope.SetIsFinalAt(0, true);
     context_scope.SetIsConstAt(0, false);
@@ -2209,7 +2213,8 @@
   reader->AddBackRef(object_id, &language_error, kIsDeserialized);
 
   // Set all non object fields.
-  language_error.set_token_pos(reader->Read<int32_t>());
+  language_error.set_token_pos(
+      TokenPosition::SnapshotDecode(reader->Read<int32_t>()));
   language_error.set_report_after_token(reader->Read<bool>());
   language_error.set_kind(reader->Read<uint8_t>());
 
@@ -2236,7 +2241,7 @@
   writer->WriteTags(writer->GetObjectTags(this));
 
   // Write out all the non object fields.
-  writer->Write<int32_t>(ptr()->token_pos_);
+  writer->Write<int32_t>(ptr()->token_pos_.SnapshotEncode());
   writer->Write<bool>(ptr()->report_after_token_);
   writer->Write<uint8_t>(ptr()->kind_);
 
diff --git a/runtime/vm/regexp.cc b/runtime/vm/regexp.cc
index 46122bd..6ac5782 100644
--- a/runtime/vm/regexp.cc
+++ b/runtime/vm/regexp.cc
@@ -5267,7 +5267,7 @@
       false,  // Not external.
       false,  // Not native.
       owner,
-      0));  // No token position.
+      TokenPosition::kMinSource));
 
   // TODO(zerny): Share these arrays between all irregexp functions.
   fn.set_num_fixed_parameters(kParamCount);
diff --git a/runtime/vm/regexp_assembler_ir.cc b/runtime/vm/regexp_assembler_ir.cc
index 40043b7..367e65fd 100644
--- a/runtime/vm/regexp_assembler_ir.cc
+++ b/runtime/vm/regexp_assembler_ir.cc
@@ -36,7 +36,7 @@
 
 
 static const intptr_t kInvalidTryIndex = CatchClauseNode::kInvalidTryIndex;
-static const intptr_t kNoSourcePos = Token::kNoSourcePos;
+static const TokenPosition kNoSourcePos = TokenPosition::kNoSource;
 static const intptr_t kMinStackSize = 512;
 
 
diff --git a/runtime/vm/report.cc b/runtime/vm/report.cc
index e5ab2ec..196b471 100644
--- a/runtime/vm/report.cc
+++ b/runtime/vm/report.cc
@@ -25,7 +25,7 @@
 
 RawString* Report::PrependSnippet(Kind kind,
                                   const Script& script,
-                                  intptr_t token_pos,
+                                  TokenPosition token_pos,
                                   bool report_after_token,
                                   const String& message) {
   const char* message_header;
@@ -41,7 +41,7 @@
   String& result = String::Handle();
   if (!script.IsNull()) {
     const String& script_url = String::Handle(script.url());
-    if (token_pos >= 0) {
+    if (token_pos.IsReal()) {
       intptr_t line, column, token_len;
       script.GetTokenLocation(token_pos, &line, &column, &token_len);
       if (report_after_token) {
@@ -110,7 +110,7 @@
 
 
 void Report::LongJumpF(const Error& prev_error,
-                       const Script& script, intptr_t token_pos,
+                       const Script& script, TokenPosition token_pos,
                        const char* format, ...) {
   va_list args;
   va_start(args, format);
@@ -121,7 +121,7 @@
 
 
 void Report::LongJumpV(const Error& prev_error,
-                       const Script& script, intptr_t token_pos,
+                       const Script& script, TokenPosition token_pos,
                        const char* format, va_list args) {
   const Error& error = Error::Handle(LanguageError::NewFormattedV(
       prev_error, script, token_pos, Report::AtLocation,
@@ -132,8 +132,11 @@
 }
 
 
-void Report::MessageF(Kind kind, const Script& script, intptr_t token_pos,
-                      bool report_after_token, const char* format, ...) {
+void Report::MessageF(Kind kind,
+                      const Script& script,
+                      TokenPosition token_pos,
+                      bool report_after_token,
+                      const char* format, ...) {
   va_list args;
   va_start(args, format);
   MessageV(kind, script, token_pos, report_after_token, format, args);
@@ -143,7 +146,7 @@
 
 void Report::MessageV(Kind kind,
                       const Script& script,
-                      intptr_t token_pos,
+                      TokenPosition token_pos,
                       bool report_after_token,
                       const char* format, va_list args) {
   if (kind < kError) {
@@ -236,7 +239,7 @@
                                          caller_frame->LookupDartCode());
   ASSERT(!caller_code.IsNull());
   const uword caller_pc = caller_frame->pc();
-  const intptr_t token_pos = caller_code.GetTokenIndexOfPC(caller_pc);
+  const TokenPosition token_pos = caller_code.GetTokenIndexOfPC(caller_pc);
   const Function& caller = Function::Handle(zone, caller_code.function());
   const Script& script = Script::Handle(zone, caller.script());
   MessageF(kJSWarning, script, token_pos, Report::AtLocation, "%s", msg);
@@ -244,7 +247,7 @@
 
 
 void Report::TraceJSWarning(const Script& script,
-                            intptr_t token_pos,
+                            TokenPosition token_pos,
                             const String& message) {
   const int64_t micros = OS::GetCurrentTimeMicros();
   Isolate* isolate = Isolate::Current();
diff --git a/runtime/vm/report.h b/runtime/vm/report.h
index 1a8d22a..3cf48ac 100644
--- a/runtime/vm/report.h
+++ b/runtime/vm/report.h
@@ -6,6 +6,7 @@
 #define VM_REPORT_H_
 
 #include "vm/allocation.h"
+#include "vm/token_position.h"
 
 namespace dart {
 
@@ -36,17 +37,21 @@
 
   // Concatenate and report an already formatted error and a new error message.
   static void LongJumpF(const Error& prev_error,
-                        const Script& script, intptr_t token_pos,
+                        const Script& script, TokenPosition token_pos,
                         const char* format, ...) PRINTF_ATTRIBUTE(4, 5);
   static void LongJumpV(const Error& prev_error,
-                        const Script& script, intptr_t token_pos,
+                        const Script& script, TokenPosition token_pos,
                         const char* format, va_list args);
 
   // Report a warning/jswarning/error/bailout message.
-  static void MessageF(Kind kind, const Script& script, intptr_t token_pos,
+  static void MessageF(Kind kind,
+                       const Script& script,
+                       TokenPosition token_pos,
                        bool report_after_token,
                        const char* format, ...) PRINTF_ATTRIBUTE(5, 6);
-  static void MessageV(Kind kind, const Script& script, intptr_t token_pos,
+  static void MessageV(Kind kind,
+                       const Script& script,
+                       TokenPosition token_pos,
                        bool report_after_token,
                        const char* format, va_list args);
 
@@ -71,14 +76,14 @@
   // A null script means no source and a negative token_pos means no position.
   static RawString* PrependSnippet(Kind kind,
                                    const Script& script,
-                                   intptr_t token_pos,
+                                   TokenPosition token_pos,
                                    bool report_after_token,
                                    const String& message);
 
  private:
   // Emit a Javascript compatibility warning to the current trace buffer.
   static void TraceJSWarning(const Script& script,
-                             intptr_t token_pos,
+                             TokenPosition token_pos,
                              const String& message);
 
   DISALLOW_COPY_AND_ASSIGN(Report);
diff --git a/runtime/vm/report_test.cc b/runtime/vm/report_test.cc
index 95e469e..08fbe70 100644
--- a/runtime/vm/report_test.cc
+++ b/runtime/vm/report_test.cc
@@ -19,7 +19,7 @@
       Script::New(url, source, RawScript::kEvaluateTag));
   script.Tokenize(String::Handle(String::New("")));
   {
-    const intptr_t token_pos = 0;
+    const TokenPosition token_pos = TokenPosition(0);
     const char* message = "High Voltage";
     Report::MessageF(Report::kJSWarning,
                      script, token_pos, Report::AtLocation, "%s", message);
@@ -44,7 +44,7 @@
     }
   }
   {
-    const intptr_t token_pos = 1;
+    const TokenPosition token_pos = TokenPosition(1);
     const char* message = "Low Voltage";
     Report::MessageF(Report::kJSWarning,
                      script, token_pos, Report::AtLocation, "%s", message);
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index 6e0b1bb..101898f 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -17,11 +17,19 @@
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
   const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+      Class::Handle(Class::New(class_name, script,
+                               TokenPosition::kNoSource));
   const String& function_name = String::ZoneHandle(Symbols::New(name));
   const Function& function = Function::ZoneHandle(
-      Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+      Function::New(function_name,
+                    RawFunction::kRegularFunction,
+                    true,
+                    false,
+                    false,
+                    false,
+                    false,
+                    owner_class,
+                    TokenPosition::kMinSource));
   const Array& functions = Array::Handle(Array::New(1));
   functions.SetAt(0, function);
   owner_class.SetFunctions(functions);
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index fe8d2898..d3f8428 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -9,6 +9,7 @@
 #include "vm/flags.h"
 #include "vm/native_arguments.h"
 #include "vm/runtime_entry_list.h"
+#include "vm/safepoint.h"
 #include "vm/tags.h"
 
 namespace dart {
@@ -95,6 +96,7 @@
       Thread* thread = arguments.thread();                                     \
       ASSERT(thread == Thread::Current());                                     \
       Isolate* isolate = thread->isolate();                                    \
+      TransitionGeneratedToVM transition(thread);                              \
       StackZone zone(thread);                                                  \
       HANDLESCOPE(thread);                                                     \
       DRT_Helper##name(isolate, thread, zone.GetZone(), arguments);            \
diff --git a/runtime/vm/safepoint.cc b/runtime/vm/safepoint.cc
new file mode 100644
index 0000000..47ef257
--- /dev/null
+++ b/runtime/vm/safepoint.cc
@@ -0,0 +1,174 @@
+// 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 "vm/safepoint.h"
+
+#include "vm/thread.h"
+#include "vm/thread_registry.h"
+
+namespace dart {
+
+SafepointOperationScope::SafepointOperationScope(Thread* T) : StackResource(T) {
+  ASSERT(T != NULL);
+  Isolate* I = T->isolate();
+  ASSERT(I != NULL);
+  ASSERT(T->no_safepoint_scope_depth() == 0);
+
+  SafepointHandler* handler = I->safepoint_handler();
+  ASSERT(handler != NULL);
+
+  // Signal all threads to get to a safepoint and wait for them to
+  // get to a safepoint.
+  handler->SafepointThreads(T);
+}
+
+
+SafepointOperationScope::~SafepointOperationScope() {
+  Thread* T = thread();
+  ASSERT(T != NULL);
+  Isolate* I = T->isolate();
+  ASSERT(I != NULL);
+
+  // Resume all threads which are blocked for the safepoint operation.
+  SafepointHandler* handler = I->safepoint_handler();
+  ASSERT(handler != NULL);
+  handler->ResumeThreads(T);
+}
+
+
+SafepointHandler::SafepointHandler(Isolate* isolate)
+    : isolate_(isolate),
+      safepoint_lock_(new Monitor()),
+      number_threads_not_at_safepoint_(0),
+      safepoint_in_progress_(false) {
+}
+
+
+SafepointHandler::~SafepointHandler() {
+  ASSERT(safepoint_in_progress_ == false);
+  delete safepoint_lock_;
+  safepoint_lock_ = NULL;
+  isolate_ = NULL;
+}
+
+
+void SafepointHandler::SafepointThreads(Thread* T) {
+  {
+    // First grab the threads list lock for this isolate
+    // and check if a safepoint is already in progress. This
+    // ensures that two threads do not start a safepoint operation
+    // at the same time.
+    MonitorLocker sl(threads_lock());
+
+    // Now check to see if a safepoint operation is already in progress
+    // for this isolate, block if an operation is in progress.
+    while (safepoint_in_progress()) {
+      sl.WaitWithSafepointCheck(T);
+    }
+
+    // Set safepoint in progress by this thread.
+    set_safepoint_in_progress(true);
+
+    // Go over the active thread list and ensure that all threads active
+    // in the isolate reach a safepoint.
+    Thread* current = isolate()->thread_registry()->active_list();
+    while (current != NULL) {
+      MonitorLocker tl(current->thread_lock());
+      if (current != T) {
+        uint32_t state = current->SetSafepointRequested(true);
+        if (!Thread::IsAtSafepoint(state)) {
+          // Thread is not already at a safepoint so try to
+          // get it to a safepoint and wait for it to check in.
+          if (current->IsMutatorThread()) {
+            ASSERT(T->isolate() != NULL);
+            T->isolate()->ScheduleInterrupts(Isolate::kVMInterrupt);
+          }
+          MonitorLocker sl(safepoint_lock_);
+          ++number_threads_not_at_safepoint_;
+        }
+      } else {
+        current->SetAtSafepoint(true);
+      }
+      current = current->next();
+    }
+  }
+  // Now wait for all threads that are not already at a safepoint to check-in.
+  {
+    MonitorLocker sl(safepoint_lock_);
+    while (number_threads_not_at_safepoint_ > 0) {
+      sl.Wait();
+    }
+  }
+}
+
+
+void SafepointHandler::ResumeThreads(Thread* T) {
+  // First resume all the threads which are blocked for the safepoint
+  // operation.
+  MonitorLocker sl(threads_lock());
+  Thread* current = isolate()->thread_registry()->active_list();
+  while (current != NULL) {
+    MonitorLocker tl(current->thread_lock());
+    if (current != T) {
+      uint32_t state = current->SetSafepointRequested(false);
+      if (Thread::IsBlockedForSafepoint(state)) {
+        tl.Notify();
+      }
+    } else {
+      current->SetAtSafepoint(false);
+    }
+    current = current->next();
+  }
+  // Now set the safepoint_in_progress_ flag to false and notify all threads
+  // that are waiting to enter the isolate or waiting to start another
+  // safepoint operation.
+  set_safepoint_in_progress(false);
+  sl.NotifyAll();
+}
+
+
+void SafepointHandler::EnterSafepointUsingLock(Thread* T) {
+  MonitorLocker tl(T->thread_lock());
+  T->SetAtSafepoint(true);
+  if (T->IsSafepointRequested()) {
+    MonitorLocker sl(safepoint_lock_);
+    ASSERT(number_threads_not_at_safepoint_ > 0);
+    number_threads_not_at_safepoint_ -= 1;
+    sl.Notify();
+  }
+}
+
+
+void SafepointHandler::ExitSafepointUsingLock(Thread* T) {
+  MonitorLocker tl(T->thread_lock());
+  ASSERT(T->IsAtSafepoint());
+  while (T->IsSafepointRequested()) {
+    T->SetBlockedForSafepoint(true);
+    tl.Wait();
+    T->SetBlockedForSafepoint(false);
+  }
+  T->SetAtSafepoint(false);
+}
+
+
+void SafepointHandler::BlockForSafepoint(Thread* T) {
+  MonitorLocker tl(T->thread_lock());
+  if (T->IsSafepointRequested()) {
+    T->SetAtSafepoint(true);
+    {
+      MonitorLocker sl(safepoint_lock_);
+      ASSERT(number_threads_not_at_safepoint_ > 0);
+      number_threads_not_at_safepoint_ -= 1;
+      sl.Notify();
+    }
+    while (T->IsSafepointRequested()) {
+      T->SetBlockedForSafepoint(true);
+      tl.Wait();
+      T->SetBlockedForSafepoint(false);
+    }
+    T->SetAtSafepoint(false);
+  }
+}
+
+}  // namespace dart
diff --git a/runtime/vm/safepoint.h b/runtime/vm/safepoint.h
new file mode 100644
index 0000000..1c13a87
--- /dev/null
+++ b/runtime/vm/safepoint.h
@@ -0,0 +1,328 @@
+// 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.
+
+#ifndef VM_SAFEPOINT_H_
+#define VM_SAFEPOINT_H_
+
+#include "vm/globals.h"
+#include "vm/lockers.h"
+#include "vm/thread.h"
+
+namespace dart {
+
+// A stack based scope that can be used to perform an operation after getting
+// all threads to a safepoint. At the end of the operation all the threads are
+// resumed.
+class SafepointOperationScope : public StackResource {
+ public:
+  explicit SafepointOperationScope(Thread* T);
+  ~SafepointOperationScope();
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(SafepointOperationScope);
+};
+
+
+// Implements handling of safepoint operations for all threads in an Isolate.
+class SafepointHandler {
+ public:
+  explicit SafepointHandler(Isolate* I);
+  ~SafepointHandler();
+
+  void EnterSafepointUsingLock(Thread* T);
+  void ExitSafepointUsingLock(Thread* T);
+
+  void SafepointThreads(Thread* T);
+  void ResumeThreads(Thread* T);
+
+  void BlockForSafepoint(Thread* T);
+
+ private:
+  Isolate* isolate() const { return isolate_; }
+  Monitor* threads_lock() const { return isolate_->threads_lock(); }
+  bool safepoint_in_progress() const {
+    ASSERT(threads_lock()->IsOwnedByCurrentThread());
+    return safepoint_in_progress_;
+  }
+  void set_safepoint_in_progress(bool value) {
+    ASSERT(threads_lock()->IsOwnedByCurrentThread());
+    safepoint_in_progress_ = value;
+  }
+
+  Isolate* isolate_;
+
+  // Monitor used by thread initiating a safepoint operation to track threads
+  // not at a safepoint and wait for these threads to reach a safepoint.
+  Monitor* safepoint_lock_;
+  int32_t number_threads_not_at_safepoint_;
+
+  // Flag to indicate if a safepoint operation is currently in progress.
+  bool safepoint_in_progress_;
+
+  friend class Isolate;
+  friend class SafepointOperationScope;
+};
+
+
+/*
+ * Set of StackResource classes to track thread execution state transitions:
+ *
+ * kThreadInGenerated transitioning to
+ *   ==> kThreadInVM:
+ *       - set_execution_state(kThreadInVM).
+ *       - block if safepoint is requested.
+ *   ==> kThreadInNative:
+ *       - set_execution_state(kThreadInNative).
+ *       - EnterSafepoint().
+ *   ==> kThreadInBlockedState:
+ *       - Invalid transition
+ *
+ * kThreadInVM transitioning to
+ *   ==> kThreadInGenerated
+ *       - set_execution_state(kThreadInGenerated).
+ *   ==> kThreadInNative
+ *       - set_execution_state(kThreadInNative).
+ *       - EnterSafepoint.
+ *   ==> kThreadInBlockedState
+ *       - set_execution_state(kThreadInBlockedState).
+ *       - EnterSafepoint.
+ *
+ * kThreadInNative transitioning to
+ *   ==> kThreadInGenerated
+ *       - ExitSafepoint.
+ *       - set_execution_state(kThreadInGenerated).
+ *   ==> kThreadInVM
+ *       - ExitSafepoint.
+ *       - set_execution_state(kThreadInVM).
+ *   ==> kThreadInBlocked
+ *       - Invalid transition.
+ *
+ * kThreadInBlocked transitioning to
+ *   ==> kThreadInVM
+ *       - ExitSafepoint.
+ *       - set_execution_state(kThreadInVM).
+ *   ==> kThreadInNative
+ *       - Invalid transition.
+ *   ==> kThreadInGenerated
+ *       - Invalid transition.
+ */
+class TransitionSafepointState : public StackResource {
+ public:
+  explicit TransitionSafepointState(Thread* T) : StackResource(T) {}
+  ~TransitionSafepointState() {}
+
+  SafepointHandler* handler() const {
+    ASSERT(thread()->isolate() != NULL);
+    ASSERT(thread()->isolate()->safepoint_handler() != NULL);
+    return thread()->isolate()->safepoint_handler();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TransitionSafepointState);
+};
+
+
+// TransitionGeneratedToVM is used to transition the safepoint state of a
+// thread from "running generated code" to "running vm code" and ensures
+// that the state is reverted back to "running generated code" when
+// exiting the scope/frame.
+class TransitionGeneratedToVM : public TransitionSafepointState {
+ public:
+  explicit TransitionGeneratedToVM(Thread* T) : TransitionSafepointState(T) {
+    ASSERT(T == Thread::Current());
+    ASSERT(T->execution_state() == Thread::kThreadInGenerated);
+    T->set_execution_state(Thread::kThreadInVM);
+    // Fast check to see if a safepoint is requested or not.
+    // We do the more expensive operation of blocking the thread
+    // only if a safepoint is requested.
+    if (T->IsSafepointRequested()) {
+      handler()->BlockForSafepoint(T);
+    }
+  }
+
+  ~TransitionGeneratedToVM() {
+    ASSERT(thread()->execution_state() == Thread::kThreadInVM);
+    thread()->set_execution_state(Thread::kThreadInGenerated);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TransitionGeneratedToVM);
+};
+
+
+// TransitionGeneratedToNative is used to transition the safepoint state of a
+// thread from "running generated code" to "running native code" and ensures
+// that the state is reverted back to "running generated code" when
+// exiting the scope/frame.
+class TransitionGeneratedToNative : public TransitionSafepointState {
+ public:
+  explicit TransitionGeneratedToNative(Thread* T)
+      : TransitionSafepointState(T) {
+    // Native code is considered to be at a safepoint and so we mark it
+    // accordingly.
+    ASSERT(T->execution_state() == Thread::kThreadInGenerated);
+    T->set_execution_state(Thread::kThreadInNative);
+    T->EnterSafepoint();
+  }
+
+  ~TransitionGeneratedToNative() {
+    // We are returning to generated code and so we are not at a safepoint
+    // anymore.
+    ASSERT(thread()->execution_state() == Thread::kThreadInNative);
+    thread()->ExitSafepoint();
+    thread()->set_execution_state(Thread::kThreadInGenerated);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TransitionGeneratedToNative);
+};
+
+
+// TransitionVMToBlocked is used to transition the safepoint state of a
+// thread from "running vm code" to "blocked on a monitor" and ensures
+// that the state is reverted back to "running vm code" when
+// exiting the scope/frame.
+class TransitionVMToBlocked : public TransitionSafepointState {
+ public:
+  explicit TransitionVMToBlocked(Thread* T) : TransitionSafepointState(T) {
+    // A thread blocked on a monitor is considered to be at a safepoint.
+    ASSERT(T->execution_state() == Thread::kThreadInVM);
+    T->set_execution_state(Thread::kThreadInBlockedState);
+    T->EnterSafepoint();
+  }
+
+  ~TransitionVMToBlocked() {
+    // We are returning to vm code and so we are not at a safepoint anymore.
+    ASSERT(thread()->execution_state() == Thread::kThreadInBlockedState);
+    thread()->ExitSafepoint();
+    thread()->set_execution_state(Thread::kThreadInVM);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TransitionVMToBlocked);
+};
+
+
+// TransitionVMToNative is used to transition the safepoint state of a
+// thread from "running vm code" to "running native code" and ensures
+// that the state is reverted back to "running vm code" when
+// exiting the scope/frame.
+class TransitionVMToNative : public TransitionSafepointState {
+ public:
+  explicit TransitionVMToNative(Thread* T) : TransitionSafepointState(T) {
+    // A thread running native code is considered to be at a safepoint.
+    ASSERT(T->execution_state() == Thread::kThreadInVM);
+    T->set_execution_state(Thread::kThreadInNative);
+    T->EnterSafepoint();
+  }
+
+  ~TransitionVMToNative() {
+    // We are returning to vm code and so we are not at a safepoint anymore.
+    ASSERT(thread()->execution_state() == Thread::kThreadInNative);
+    thread()->ExitSafepoint();
+    thread()->set_execution_state(Thread::kThreadInVM);
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TransitionVMToNative);
+};
+
+
+// TransitionVMToGenerated is used to transition the safepoint state of a
+// thread from "running vm code" to "running generated code" and ensures
+// that the state is reverted back to "running vm code" when
+// exiting the scope/frame.
+class TransitionVMToGenerated : public TransitionSafepointState {
+ public:
+  explicit TransitionVMToGenerated(Thread* T) : TransitionSafepointState(T) {
+    ASSERT(T == Thread::Current());
+    ASSERT(T->execution_state() == Thread::kThreadInVM);
+    T->set_execution_state(Thread::kThreadInGenerated);
+  }
+
+  ~TransitionVMToGenerated() {
+    ASSERT(thread()->execution_state() == Thread::kThreadInGenerated);
+    thread()->set_execution_state(Thread::kThreadInVM);
+    // Fast check to see if a safepoint is requested or not.
+    // We do the more expensive operation of blocking the thread
+    // only if a safepoint is requested.
+    if (thread()->IsSafepointRequested()) {
+      handler()->BlockForSafepoint(thread());
+    }
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TransitionVMToGenerated);
+};
+
+
+// TransitionNativeToVM is used to transition the safepoint state of a
+// thread from "running native code" to "running vm code" and ensures
+// that the state is reverted back to "running native code" when
+// exiting the scope/frame.
+class TransitionNativeToVM : public TransitionSafepointState {
+ public:
+  explicit TransitionNativeToVM(Thread* T) : TransitionSafepointState(T) {
+    // We are about to execute vm code and so we are not at a safepoint anymore.
+    ASSERT(T->execution_state() == Thread::kThreadInNative);
+    T->ExitSafepoint();
+    T->set_execution_state(Thread::kThreadInVM);
+  }
+
+  ~TransitionNativeToVM() {
+    // We are returning to native code and so we are at a safepoint.
+    ASSERT(thread()->execution_state() == Thread::kThreadInVM);
+    thread()->set_execution_state(Thread::kThreadInNative);
+    thread()->EnterSafepoint();
+  }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(TransitionNativeToVM);
+};
+
+
+// TransitionToGenerated is used to transition the safepoint state of a
+// thread from "running vm code" or "running native code" to
+// "running generated code" and ensures that the state is reverted back
+// to "running vm code" or "running native code" when exiting the
+// scope/frame.
+class TransitionToGenerated : public TransitionSafepointState {
+ public:
+  explicit TransitionToGenerated(Thread* T)
+      : TransitionSafepointState(T),
+        execution_state_(T->execution_state()) {
+    ASSERT(T == Thread::Current());
+    ASSERT((execution_state_ == Thread::kThreadInVM) ||
+           (execution_state_ == Thread::kThreadInNative));
+    if (execution_state_ == Thread::kThreadInNative) {
+      T->ExitSafepoint();
+    }
+    T->set_execution_state(Thread::kThreadInGenerated);
+  }
+
+  ~TransitionToGenerated() {
+    ASSERT(thread()->execution_state() == Thread::kThreadInGenerated);
+    if (execution_state_ == Thread::kThreadInNative) {
+      thread()->set_execution_state(Thread::kThreadInNative);
+      thread()->EnterSafepoint();
+    } else {
+      ASSERT(execution_state_ == Thread::kThreadInVM);
+      thread()->set_execution_state(Thread::kThreadInVM);
+      // Fast check to see if a safepoint is requested or not.
+      // We do the more expensive operation of blocking the thread
+      // only if a safepoint is requested.
+      if (thread()->IsSafepointRequested()) {
+        handler()->BlockForSafepoint(thread());
+      }
+    }
+  }
+
+ private:
+  int16_t execution_state_;
+  DISALLOW_COPY_AND_ASSIGN(TransitionToGenerated);
+};
+
+}  // namespace dart
+
+#endif  // VM_SAFEPOINT_H_
diff --git a/runtime/vm/scanner.cc b/runtime/vm/scanner.cc
index 50073cd..a040476 100644
--- a/runtime/vm/scanner.cc
+++ b/runtime/vm/scanner.cc
@@ -909,8 +909,8 @@
 }
 
 
-void Scanner::ScanTo(intptr_t token_index) {
-  int index = 0;
+void Scanner::ScanTo(TokenPosition token_index) {
+  TokenPosition index = TokenPosition::kMinSource;
   Reset();
   do {
     Scan();
@@ -919,16 +919,18 @@
     for (intptr_t diff = current_token_.position.line - prev_token_line_;
          diff > 0;
          diff--) {
-      index++;  // Advance the index to account for tokens added in ScanAll.
+      // Advance the index to account for tokens added in ScanAll.
+      index.Next();
       inserted_new_lines = true;
     }
 
     if (inserted_new_lines &&
         ((current_token_.kind == Token::kINTERPOL_VAR) ||
          (current_token_.kind == Token::kINTERPOL_START))) {
-          index++;  // Advance the index to account for tokens added in ScanAll.
+          // Advance the index to account for tokens added in ScanAll.
+          index.Next();
     }
-    index++;
+    index.Next();
     prev_token_line_ = current_token_.position.line;
   } while ((token_index >= index) && (current_token_.kind != Token::kEOS));
 }
diff --git a/runtime/vm/scanner.h b/runtime/vm/scanner.h
index 5b35317..92ebcd6 100644
--- a/runtime/vm/scanner.h
+++ b/runtime/vm/scanner.h
@@ -11,6 +11,7 @@
 
 #include "vm/growable_array.h"
 #include "vm/token.h"
+#include "vm/token_position.h"
 
 namespace dart {
 
@@ -55,7 +56,7 @@
 
   // Scans to specified token position.
   // Use CurrentPosition() to extract position.
-  void ScanTo(intptr_t token_index);
+  void ScanTo(TokenPosition token_index);
 
   // Scans entire source and returns a stream of tokens.
   // Should be called only once.
diff --git a/runtime/vm/scavenger.cc b/runtime/vm/scavenger.cc
index 60478d3..5dc0aae 100644
--- a/runtime/vm/scavenger.cc
+++ b/runtime/vm/scavenger.cc
@@ -14,6 +14,7 @@
 #include "vm/lockers.h"
 #include "vm/object.h"
 #include "vm/object_id_ring.h"
+#include "vm/safepoint.h"
 #include "vm/stack_frame.h"
 #include "vm/store_buffer.h"
 #include "vm/thread_registry.h"
@@ -449,7 +450,7 @@
   if (invoke_api_callbacks && (isolate->gc_prologue_callback() != NULL)) {
     (isolate->gc_prologue_callback())();
   }
-  isolate->thread_registry()->PrepareForGC();
+  isolate->PrepareForGC();
   // Flip the two semi-spaces so that to_ is always the space for allocating
   // objects.
   SemiSpace* from = to_;
@@ -763,7 +764,7 @@
   // will continue with its scavenge after waiting for the winner to complete.
   // TODO(koda): Consider moving SafepointThreads into allocation failure/retry
   // logic to avoid needless collections.
-  isolate->thread_registry()->SafepointThreads();
+  SafepointOperationScope safepoint_scope(Thread::Current());
 
   // Scavenging is not reentrant. Make sure that is the case.
   ASSERT(!scavenging_);
@@ -823,8 +824,6 @@
   // Done scavenging. Reset the marker.
   ASSERT(scavenging_);
   scavenging_ = false;
-
-  isolate->thread_registry()->ResumeAllThreads();
 }
 
 
diff --git a/runtime/vm/scopes.cc b/runtime/vm/scopes.cc
index 9b609c1..6060e7a 100644
--- a/runtime/vm/scopes.cc
+++ b/runtime/vm/scopes.cc
@@ -29,8 +29,8 @@
       loop_level_(loop_level),
       context_level_(LocalScope::kUnitializedContextLevel),
       num_context_variables_(0),
-      begin_token_pos_(Token::kNoSourcePos),
-      end_token_pos_(Token::kNoSourcePos),
+      begin_token_pos_(TokenPosition::kNoSourcePos),
+      end_token_pos_(TokenPosition::kNoSourcePos),
       variables_(),
       labels_(),
       referenced_() {
@@ -110,7 +110,7 @@
 }
 
 
-void LocalScope::AddReferencedName(intptr_t token_pos,
+void LocalScope::AddReferencedName(TokenPosition token_pos,
                                    const String& name) {
   if (LocalLookupVariable(name) != NULL) {
     return;
@@ -132,12 +132,12 @@
 }
 
 
-intptr_t LocalScope::PreviousReferencePos(const String& name) const {
+TokenPosition LocalScope::PreviousReferencePos(const String& name) const {
   NameReference* ref = FindReference(name);
   if (ref != NULL) {
     return ref->token_pos();
   }
-  return -1;
+  return TokenPosition::kNoSource;
 }
 
 
@@ -328,8 +328,8 @@
         desc.name = &var->name();
         desc.info.set_kind(RawLocalVarDescriptors::kSavedCurrentContext);
         desc.info.scope_id = 0;
-        desc.info.begin_pos = 0;
-        desc.info.end_pos = 0;
+        desc.info.begin_pos = TokenPosition::kMinSource;
+        desc.info.end_pos = TokenPosition::kMinSource;
         desc.info.set_index(var->index());
         vars->Add(desc);
       } else if (!IsFilteredIdentifier(var->name())) {
diff --git a/runtime/vm/scopes.h b/runtime/vm/scopes.h
index e68a244..aaf120d 100644
--- a/runtime/vm/scopes.h
+++ b/runtime/vm/scopes.h
@@ -21,7 +21,7 @@
 
 class LocalVariable : public ZoneAllocated {
  public:
-  LocalVariable(intptr_t token_pos,
+  LocalVariable(TokenPosition token_pos,
                 const String& name,
                 const AbstractType& type)
     : token_pos_(token_pos),
@@ -39,7 +39,7 @@
     ASSERT(name.IsSymbol());
   }
 
-  intptr_t token_pos() const { return token_pos_; }
+  TokenPosition token_pos() const { return token_pos_; }
   const String& name() const { return name_; }
   LocalScope* owner() const { return owner_; }
   void set_owner(LocalScope* owner) {
@@ -109,7 +109,7 @@
  private:
   static const int kUninitializedIndex = INT_MIN;
 
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const String& name_;
   LocalScope* owner_;  // Local scope declaring this variable.
 
@@ -132,16 +132,16 @@
 
 class NameReference : public ZoneAllocated {
  public:
-  NameReference(intptr_t token_pos, const String& name)
+  NameReference(TokenPosition token_pos, const String& name)
     : token_pos_(token_pos),
       name_(name) {
     ASSERT(name.IsSymbol());
   }
   const String& name() const { return name_; }
-  intptr_t token_pos() const { return token_pos_; }
-  void set_token_pos(intptr_t value) { token_pos_ = value; }
+  TokenPosition token_pos() const { return token_pos_; }
+  void set_token_pos(TokenPosition value) { token_pos_ = value; }
  private:
-  intptr_t token_pos_;
+  TokenPosition token_pos_;
   const String& name_;
 };
 
@@ -160,7 +160,7 @@
     kStatement  // Any statement other than the above
   };
 
-  SourceLabel(intptr_t token_pos, const String& name, Kind kind)
+  SourceLabel(TokenPosition token_pos, const String& name, Kind kind)
     : token_pos_(token_pos),
       name_(name),
       owner_(NULL),
@@ -168,7 +168,7 @@
     ASSERT(name.IsSymbol());
   }
 
-  static SourceLabel* New(intptr_t token_pos, String* name, Kind kind) {
+  static SourceLabel* New(TokenPosition token_pos, String* name, Kind kind) {
     if (name != NULL) {
       return new SourceLabel(token_pos, *name, kind);
     } else {
@@ -178,7 +178,7 @@
     }
   }
 
-  intptr_t token_pos() const { return token_pos_; }
+  TokenPosition token_pos() const { return token_pos_; }
   const String& name() const { return name_; }
   LocalScope* owner() const { return owner_; }
   void set_owner(LocalScope* owner) {
@@ -194,7 +194,7 @@
   void ResolveForwardReference() { kind_ = kCase; }
 
  private:
-  const intptr_t token_pos_;
+  const TokenPosition token_pos_;
   const String& name_;
   LocalScope* owner_;  // Local scope declaring this label.
 
@@ -232,11 +232,11 @@
     context_level_ = context_level;
   }
 
-  intptr_t begin_token_pos() const { return begin_token_pos_; }
-  void set_begin_token_pos(intptr_t value) { begin_token_pos_ = value; }
+  TokenPosition begin_token_pos() const { return begin_token_pos_; }
+  void set_begin_token_pos(TokenPosition value) { begin_token_pos_ = value; }
 
-  intptr_t end_token_pos() const { return end_token_pos_; }
-  void set_end_token_pos(intptr_t value) { end_token_pos_ = value; }
+  TokenPosition end_token_pos() const { return end_token_pos_; }
+  void set_end_token_pos(TokenPosition value) { end_token_pos_ = value; }
 
   // The number of variables allocated in the context and belonging to this
   // scope and to its children at the same loop level.
@@ -302,8 +302,8 @@
   // Add a reference to the given name into this scope and the enclosing
   // scopes that do not have a local variable declaration for this name
   // already.
-  void AddReferencedName(intptr_t token_pos, const String& name);
-  intptr_t PreviousReferencePos(const String& name) const;
+  void AddReferencedName(TokenPosition token_pos, const String& name);
+  TokenPosition PreviousReferencePos(const String& name) const;
 
   // Allocate both captured and non-captured variables declared in this scope
   // and in its children scopes of the same function level. Allocating means
@@ -367,8 +367,8 @@
   int loop_level_;      // Reflects the loop nesting level.
   int context_level_;   // Reflects the level of the runtime context.
   int num_context_variables_;   // Only set if this scope is a context owner.
-  intptr_t begin_token_pos_;  // Token index of beginning of scope.
-  intptr_t end_token_pos_;    // Token index of end of scope.
+  TokenPosition begin_token_pos_;  // Token index of beginning of scope.
+  TokenPosition end_token_pos_;    // Token index of end of scope.
   GrowableArray<LocalVariable*> variables_;
   GrowableArray<SourceLabel*> labels_;
 
diff --git a/runtime/vm/scopes_test.cc b/runtime/vm/scopes_test.cc
index c3ad21d..8dac606 100644
--- a/runtime/vm/scopes_test.cc
+++ b/runtime/vm/scopes_test.cc
@@ -14,18 +14,18 @@
   const Type& dynamic_type = Type::ZoneHandle(Type::DynamicType());
   const String& a = String::ZoneHandle(Symbols::New("a"));
   LocalVariable* var_a =
-      new LocalVariable(Token::kNoSourcePos, a, dynamic_type);
+      new LocalVariable(TokenPosition::kNoSource, a, dynamic_type);
   LocalVariable* inner_var_a =
-      new LocalVariable(Token::kNoSourcePos, a, dynamic_type);
+      new LocalVariable(TokenPosition::kNoSource, a, dynamic_type);
   const String& b = String::ZoneHandle(Symbols::New("b"));
   LocalVariable* var_b =
-      new LocalVariable(Token::kNoSourcePos, b, dynamic_type);
+      new LocalVariable(TokenPosition::kNoSource, b, dynamic_type);
   const String& c = String::ZoneHandle(Symbols::New("c"));
   LocalVariable* var_c =
-      new LocalVariable(Token::kNoSourcePos, c, dynamic_type);
+      new LocalVariable(TokenPosition::kNoSource, c, dynamic_type);
   const String& L = String::ZoneHandle(Symbols::New("L"));
   SourceLabel* label_L =
-      new SourceLabel(Token::kNoSourcePos, L, SourceLabel::kFor);
+      new SourceLabel(TokenPosition::kNoSource, L, SourceLabel::kFor);
 
   LocalScope* outer_scope = new LocalScope(NULL, 0, 0);
   LocalScope* inner_scope1 = new LocalScope(outer_scope, 0, 0);
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index 8991390..24c1598 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -47,6 +47,10 @@
             "The default name of this vm as reported by the VM service "
             "protocol");
 
+DEFINE_FLAG(bool, warn_on_pause_with_no_debugger, false,
+            "Print a message when an isolate is paused but there is no "
+            "debugger attached.");
+
 // The name of this of this vm as reported by the VM service protocol.
 static char* vm_name = NULL;
 
@@ -142,6 +146,8 @@
     }
   }
   if (stream_listen_callback_) {
+    Thread* T = Thread::Current();
+    TransitionVMToNative transition(T);
     return (*stream_listen_callback_)(stream_id);
   }
   return false;
@@ -162,12 +168,15 @@
     }
   }
   if (stream_cancel_callback_) {
+    Thread* T = Thread::Current();
+    TransitionVMToNative transition(T);
     return (*stream_cancel_callback_)(stream_id);
   }
 }
 
 RawObject* Service::RequestAssets() {
   Thread* T = Thread::Current();
+  TransitionVMToNative transition(T);
   Api::Scope api_scope(T);
   if (get_service_assets_callback_ == NULL) {
     return Object::null();
@@ -234,6 +243,7 @@
   jsobj.AddProperty("type", "Success");
 }
 
+
 static bool GetIntegerId(const char* s, intptr_t* id, int base = 10) {
   if ((s == NULL) || (*s == '\0')) {
     // Empty string.
@@ -404,6 +414,12 @@
     return required_;
   }
 
+  virtual void PrintError(const char* name,
+                          const char* value,
+                          JSONStream* js) const {
+    PrintInvalidParamError(js, name);
+  }
+
  private:
   const char* name_;
   bool required_;
@@ -422,9 +438,6 @@
 };
 
 
-#define NO_ISOLATE_PARAMETER new NoSuchParameter("isolateId")
-
-
 class BoolParameter : public MethodParameter {
  public:
   BoolParameter(const char* name, bool required)
@@ -519,8 +532,29 @@
 };
 
 
-#define ISOLATE_PARAMETER new IdParameter("isolateId", true)
+class RunnableIsolateParameter : public MethodParameter {
+ public:
+  explicit RunnableIsolateParameter(const char* name)
+      : MethodParameter(name, true) {
+  }
 
+  virtual bool Validate(const char* value) const {
+    Isolate* isolate = Isolate::Current();
+    return (value != NULL) && (isolate != NULL) && (isolate->is_runnable());
+  }
+
+  virtual void PrintError(const char* name,
+                          const char* value,
+                          JSONStream* js) const {
+    js->PrintError(kIsolateMustBeRunnable,
+                   "Isolate must be runnable before this request is made.");
+  }
+};
+
+
+#define ISOLATE_PARAMETER new IdParameter("isolateId", true)
+#define NO_ISOLATE_PARAMETER new NoSuchParameter("isolateId")
+#define RUNNABLE_ISOLATE_PARAMETER new RunnableIsolateParameter("isolateId")
 
 class EnumParameter : public MethodParameter {
  public:
@@ -708,7 +742,7 @@
       return false;
     }
     if (has_parameter && !parameter->Validate(value)) {
-      PrintInvalidParamError(js, name);
+      parameter->PrintError(name, value, js);
       return false;
     }
   }
@@ -922,11 +956,60 @@
 }
 
 
+static void ReportPauseOnConsole(ServiceEvent* event) {
+  const char* name = event->isolate()->debugger_name();
+  switch (event->kind())  {
+    case ServiceEvent::kPauseStart:
+      OS::PrintErr(
+          "vm-service: isolate '%s' has no debugger attached and is paused at "
+          "start.", name);
+      break;
+    case ServiceEvent::kPauseExit:
+      OS::PrintErr(
+          "vm-service: isolate '%s' has no debugger attached and is paused at "
+          "exit.", name);
+      break;
+    case ServiceEvent::kPauseException:
+      OS::PrintErr(
+          "vm-service: isolate '%s' has no debugger attached and is paused due "
+          "to exception.", name);
+      break;
+    case ServiceEvent::kPauseInterrupted:
+      OS::PrintErr(
+          "vm-service: isolate '%s' has no debugger attached and is paused due "
+          "to interrupt.", name);
+      break;
+    case ServiceEvent::kPauseBreakpoint:
+      OS::PrintErr(
+          "vm-service: isolate '%s' has no debugger attached and is paused.",
+          name);
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  if (!ServiceIsolate::IsRunning()) {
+    OS::PrintErr("  Start the vm-service to debug.\n");
+  } else if (ServiceIsolate::server_address() == NULL) {
+    OS::PrintErr("  Connect to Observatory to debug.\n");
+  } else {
+    OS::PrintErr("  Connect to Observatory at %s to debug.\n",
+                 ServiceIsolate::server_address());
+  }
+}
+
+
 void Service::HandleEvent(ServiceEvent* event) {
   if (event->isolate() != NULL &&
       ServiceIsolate::IsServiceIsolateDescendant(event->isolate())) {
     return;
   }
+  if (FLAG_warn_on_pause_with_no_debugger &&
+      event->IsPause() && !Service::debug_stream.enabled()) {
+    // If we are about to pause a running program which has no
+    // debugger connected, tell the user about it.
+    ReportPauseOnConsole(event);
+  }
   if (!ServiceIsolate::IsRunning()) {
     return;
   }
@@ -1170,7 +1253,7 @@
 
 
 static const MethodParameter* get_stack_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new BoolParameter("_full", false),
   NULL,
 };
@@ -1779,7 +1862,7 @@
 
 
 static const MethodParameter* get_inbound_references_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -1878,7 +1961,7 @@
 
 
 static const MethodParameter* get_retaining_path_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -1921,7 +2004,7 @@
 
 
 static const MethodParameter* get_retained_size_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("targetId", true),
   NULL,
 };
@@ -1963,7 +2046,7 @@
 
 
 static const MethodParameter* get_reachable_size_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("targetId", true),
   NULL,
 };
@@ -2005,7 +2088,7 @@
 
 
 static const MethodParameter* evaluate_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -2076,7 +2159,7 @@
 
 
 static const MethodParameter* evaluate_in_frame_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new UIntParameter("frameIndex", true),
   new MethodParameter("expression", true),
   NULL,
@@ -2141,7 +2224,7 @@
 
 
 static const MethodParameter* get_instances_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -2299,7 +2382,7 @@
 
 
 static const MethodParameter* get_coverage_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("targetId", false),
   NULL,
 };
@@ -2329,7 +2412,7 @@
 
 
 static const MethodParameter* get_source_report_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   reports_parameter,
   new IdParameter("scriptId", false),
   new UIntParameter("tokenPos", false),
@@ -2390,13 +2473,16 @@
     }
   }
   SourceReport report(report_set, compile_mode);
-  report.PrintJSON(js, script, start_pos, end_pos);
+  report.PrintJSON(js,
+                   script,
+                   TokenPosition(start_pos),
+                   TokenPosition(end_pos));
   return true;
 }
 
 
 static const MethodParameter* get_call_site_data_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("targetId", false),
   NULL,
 };
@@ -2443,7 +2529,7 @@
 
 
 static const MethodParameter* add_breakpoint_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("scriptId", true),
   new UIntParameter("line", true),
   new UIntParameter("column", false),
@@ -2471,7 +2557,7 @@
 
 
 static const MethodParameter* add_breakpoint_with_script_uri_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("scriptUri", true),
   new UIntParameter("line", true),
   new UIntParameter("column", false),
@@ -2492,7 +2578,7 @@
 
 
 static const MethodParameter* add_breakpoint_at_entry_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("functionId", true),
   NULL,
 };
@@ -2525,7 +2611,7 @@
 
 
 static const MethodParameter* add_breakpoint_at_activation_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("objectId", true),
   NULL,
 };
@@ -2558,7 +2644,7 @@
 
 
 static const MethodParameter* remove_breakpoint_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -2688,7 +2774,7 @@
 
 
 static const MethodParameter* get_isolate_metric_list_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -2716,7 +2802,7 @@
 
 
 static const MethodParameter* get_isolate_metric_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -2864,7 +2950,7 @@
 
 
 static const MethodParameter* resume_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -2917,7 +3003,7 @@
 
 
 static const MethodParameter* pause_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -2936,7 +3022,7 @@
 
 
 static const MethodParameter* get_tag_profile_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -2970,7 +3056,7 @@
 
 
 static const MethodParameter* get_cpu_profile_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new EnumParameter("tags", true, tags_enum_names),
   new BoolParameter("_codeTransitionTags", false),
   new Int64Parameter("timeOriginMicros", false),
@@ -3001,7 +3087,7 @@
 
 
 static const MethodParameter* get_cpu_profile_timeline_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new EnumParameter("tags", true, tags_enum_names),
   new Int64Parameter("timeOriginMicros", false),
   new Int64Parameter("timeExtentMicros", false),
@@ -3025,7 +3111,7 @@
 
 
 static const MethodParameter* get_allocation_samples_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new EnumParameter("tags", true, tags_enum_names),
   new IdParameter("classId", false),
   new Int64Parameter("timeOriginMicros", false),
@@ -3060,7 +3146,7 @@
 
 
 static const MethodParameter* clear_cpu_profile_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -3073,7 +3159,7 @@
 
 
 static const MethodParameter* get_allocation_profile_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -3112,7 +3198,7 @@
 
 
 static const MethodParameter* get_heap_map_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -3125,7 +3211,7 @@
 
 
 static const MethodParameter* request_heap_snapshot_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -3279,7 +3365,7 @@
 
 
 static const MethodParameter* get_object_by_address_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -3334,7 +3420,7 @@
 
 
 static const MethodParameter* get_ports_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -3367,7 +3453,7 @@
 
 
 static const MethodParameter* get_object_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new UIntParameter("offset", false),
   new UIntParameter("count", false),
   NULL,
@@ -3429,7 +3515,7 @@
 
 
 static const MethodParameter* get_class_list_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -3443,7 +3529,7 @@
 
 
 static const MethodParameter* get_type_arguments_list_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   NULL,
 };
 
@@ -3486,7 +3572,7 @@
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "Version");
   jsobj.AddProperty("major", static_cast<intptr_t>(3));
-  jsobj.AddProperty("minor", static_cast<intptr_t>(0));
+  jsobj.AddProperty("minor", static_cast<intptr_t>(1));
   jsobj.AddProperty("_privateMajor", static_cast<intptr_t>(0));
   jsobj.AddProperty("_privateMinor", static_cast<intptr_t>(0));
   return true;
@@ -3652,7 +3738,7 @@
 
 
 static const MethodParameter* set_library_debuggable_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("libraryId", true),
   new BoolParameter("isDebuggable", true),
   NULL,
@@ -3716,7 +3802,7 @@
 
 
 static const MethodParameter* set_trace_class_allocation_params[] = {
-  ISOLATE_PARAMETER,
+  RUNNABLE_ISOLATE_PARAMETER,
   new IdParameter("classId", true),
   new BoolParameter("enable", true),
   NULL,
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 6d2d894..bba5252 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1,8 +1,8 @@
-# Dart VM Service Protocol 3.0
+# Dart VM Service Protocol 3.1
 
 > Please post feedback to the [observatory-discuss group][discuss-list]
 
-This document describes of _version 3.0_ of the Dart VM Service Protocol. This
+This document describes of _version 3.1_ 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.
@@ -32,6 +32,7 @@
 	- [getFlagList](#getflaglist)
 	- [getIsolate](#getisolate)
 	- [getObject](#getobject)
+	- [getSourceReport](#getsourcereport)
 	- [getStack](#getstack)
 	- [getVersion](#getversion)
 	- [getVM](#getvm)
@@ -77,6 +78,10 @@
 	- [SentinelKind](#sentinelkind)
 	- [Script](#script)
 	- [SourceLocation](#sourcelocation)
+	- [SourceReport](#sourcereport)
+	- [SourceReportCoverage](#sourcereportcoverage)
+	- [SourceReportKind](#sourcereportkind)
+	- [SourceReportRange](#sourcereportrange)
 	- [Stack](#stack)
 	- [StepOption](#stepoption)
 	- [Success](#success)
@@ -177,6 +182,7 @@
 102 | Cannot add breakpoint | The VM is unable to add a breakpoint at the specified line or function
 103 | Stream already subscribed | The client is already subscribed to the specified _streamId_
 104 | Stream not subscribed | The client is not subscribed to the specified _streamId_
+105 | Isolate must be runnable | This operation cannot happen until the isolate is runnable
 
 
 
@@ -550,7 +556,7 @@
 collected, then an [Object](#object) will be returned.
 
 The _offset_ and _count_ parameters are used to request subranges of
-Instance objects with the kinds: List, Map, Uint8ClampedList,
+Instance objects with the kinds: String, List, Map, Uint8ClampedList,
 Uint8List, Uint16List, Uint32List, Uint64List, Int8List, Int16List,
 Int32List, Int64List, Flooat32List, Float64List, Inst32x3List,
 Float32x4List, and Float64x2List.  These parameters are otherwise
@@ -567,6 +573,52 @@
 
 See [Stack](#stack).
 
+### getSourceReport
+
+```
+SourceReport getSourceReport(string isolateId,
+                             SourceReportKind[] reports,
+                             string scriptId [optional],
+                             int tokenPos [optional],
+                             int endTokenPos [optional],
+                             bool forceCompile [optional])
+```
+
+The _getSourceReport_ RPC is used to generate a set of reports tied to
+source locations in an isolate.
+
+The _reports_ parameter is used to specify which reports should be
+generated.  The _reports_ parameter is a list, which allows multiple
+reports to be generated simultaneously from a consistent isolate
+state.  The _reports_ parameter is allowed to be empty (this might be
+used to force compilation of a particular subrange of some script).
+
+The available report kinds are:
+
+report kind | meaning
+----------- | -------
+Coverage | Provide code coverage information
+PossibleBreakpoints | Provide a list of token positions which correspond to possible breakpoints.
+
+The _scriptId_ parameter is used to restrict the report to a
+particular script.  When analyzing a particular script, either or both
+of the _tokenPos_ and _endTokenPos_ parameters may be provided to
+restrict the analysis to a subrange of a script (for example, these
+can be used to restrict the report to the range of a particular class
+or function).
+
+If the _scriptId_ parameter is not provided then the reports are
+generated for all loaded scripts and the _tokenPos_ and _endTokenPos_
+parameters are disallowed.
+
+The _forceCompilation_ parameter can be used to force compilation of
+all functions in the range of the report.  Forcing compilation can
+cause a compilation error, which could terminate the running Dart
+program.  If this parameter is not provided, it is considered to have
+the value _false_.
+
+See [SourceReport](#sourcereport).
+
 ### getVersion
 
 ```
@@ -1419,11 +1471,15 @@
 
   // The valueAsString for String references may be truncated. If so,
   // this property is added with the value 'true'.
+  //
+  // New code should use 'length' and 'count' instead.
   bool valueAsStringIsTruncated [optional];
 
-  // The length of a List or the number of associations in a Map.
+  // The length of a List or the number of associations in a Map or the
+  // number of codeunits in a String.
   //
   // Provided for instance kinds:
+  //   String
   //   List
   //   Map
   //   Uint8ClampedList
@@ -1492,11 +1548,15 @@
 
   // The valueAsString for String references may be truncated. If so,
   // this property is added with the value 'true'.
+  //
+  // New code should use 'length' and 'count' instead.
   bool valueAsStringIsTruncated [optional];
 
-  // The length of a List or the number of associations in a Map.
+  // The length of a List or the number of associations in a Map or the
+  // number of codeunits in a String.
   //
   // Provided for instance kinds:
+  //   String
   //   List
   //   Map
   //   Uint8ClampedList
@@ -1515,10 +1575,11 @@
   //   Float64x2List
   int length [optional];
 
-  // The index of the first element or association returned.
+  // The index of the first element or association or codeunit returned.
   // This is only provided when it is non-zero.
   //
   // Provided for instance kinds:
+  //   String
   //   List
   //   Map
   //   Uint8ClampedList
@@ -1537,10 +1598,11 @@
   //   Float64x2List
   int offset [optional];
 
-  // The number of elements or associations returned.
+  // The number of elements or associations or codeunits returned.
   // This is only provided when it is less than length.
   //
   // Provided for instance kinds:
+  //   String
   //   List
   //   Map
   //   Uint8ClampedList
@@ -2149,6 +2211,97 @@
 The _SourceLocation_ class is used to designate a position or range in
 some script.
 
+### SourceReport
+
+```
+class SourceReport extends Response {
+  // A list of ranges in the program source.  These ranges correspond
+  // to ranges of executable code in the user's program (functions,
+  // methods, constructors, etc.)
+  //
+  // Note that ranges may nest in other ranges, in the case of nested
+  // functions.
+  //
+  // Note that ranges may be duplicated, in the case of mixins.
+  SourceReportRange[] ranges;
+
+  // A list of scripts, referenced by index in the report's ranges.
+  ScriptRef[] scripts;
+}
+```
+
+The _SourceReport_ class represents a set of reports tied to source
+locations in an isolate.
+
+### SourceReportCoverage
+
+```
+class SourceReportCoverage {
+  // A list of token positions in a SourceReportRange which have been
+  // executed.  The list is sorted.
+  int[] hits;
+
+  // A list of token positions in a SourceReportRange which have not been
+  // executed.  The list is sorted.
+  int[] misses;
+}
+```
+
+The _SourceReportCoverage_ class represents coverage information for
+one [SourceReportRange](#sourcereportrange).
+
+Note that _SourceReportCoverage_ does not extend [Response](#response)
+and therefore will not contain a _type_ property.
+
+### SourceReportKind
+
+```
+enum SourceReportKind {
+  // Used to request a code coverage information.
+  Coverage,
+
+  // Used to request a list of token positions of possible breakpoints.
+  PossibleBreakpoints
+}
+```
+
+### SourceReportRange
+
+```
+class SourceReportRange {
+  // An index into the script table of the SourceReport, indicating
+  // which script contains this range of code.
+  int scriptIndex;
+
+  // The token position at which this range begins.
+  int startPos;
+
+  // The token position at which this range ends.  Inclusive.
+  int endPos;
+
+  // Has this range been compiled by the Dart VM?
+  bool compiled;
+
+  // Code coverage information for this range.  Provided only when the
+  // Coverage report has been requested and the range has been
+  // compiled.
+  SourceReportCoverage coverage [optional];
+
+  // Possible breakpoint information for this range, represented as a
+  // sorted list of token positions.  Provided only when the when the
+  // PossibleBreakpoint report has been requested and the range has been
+  // compiled.
+  int possibleBreakpoints[] [optional];
+}
+```
+
+The _SourceReportRange_ class represents a range of executable code
+(function, method, constructor, etc) in the running program.  It is
+part of a [SourceReport](#sourcereport).
+
+Note that _SourceReportRange_ does not extend [Response](#response)
+and therefore will not contain a _type_ property.
+
 ### Stack
 
 ```
@@ -2317,6 +2470,7 @@
 1.0 | initial revision
 2.0 | Describe protocol version 2.0.
 3.0 | Describe protocol version 3.0.  Added UnresolvedSourceLocation.  Added Sentinel return to getIsolate.  Add AddedBreakpointWithScriptUri.  Removed Isolate.entry. The type of VM.pid was changed from string to int.  Added VMUpdate events.  Add offset and count parameters to getObject() and offset and count fields to Instance. Added ServiceExtensionAdded event.
+3.1 | Add the getSourceReport RPC.  The getObject RPC now accepts offset and count for string objects.  String objects now contain length, offset, and count properties.
 
 
 [discuss-list]: https://groups.google.com/a/dartlang.org/forum/#!forum/observatory-discuss
diff --git a/runtime/vm/service_event.h b/runtime/vm/service_event.h
index ed4153b..45ebb71 100644
--- a/runtime/vm/service_event.h
+++ b/runtime/vm/service_event.h
@@ -70,6 +70,19 @@
 
   EventKind kind() const { return kind_; }
 
+  bool IsPause() const {
+    switch (kind())  {
+      case kPauseStart:
+      case kPauseExit:
+      case kPauseBreakpoint:
+      case kPauseInterrupted:
+      case kPauseException:
+        return true;
+      default:
+        return false;
+    }
+  }
+
   const char* embedder_kind() const { return embedder_kind_; }
 
   const char* KindAsCString() const;
diff --git a/runtime/vm/service_isolate.cc b/runtime/vm/service_isolate.cc
index a316c6c..dcfc541 100644
--- a/runtime/vm/service_isolate.cc
+++ b/runtime/vm/service_isolate.cc
@@ -78,6 +78,18 @@
 Monitor* ServiceIsolate::monitor_ = NULL;
 bool ServiceIsolate::initializing_ = true;
 bool ServiceIsolate::shutting_down_ = false;
+char* ServiceIsolate::server_address_ = NULL;
+
+void ServiceIsolate::SetServerAddress(const char* address) {
+  if (server_address_ != NULL) {
+    free(server_address_);
+    server_address_ = NULL;
+  }
+  if (address == NULL) {
+    return;
+  }
+  server_address_ = strdup(address);
+}
 
 
 bool ServiceIsolate::NameEquals(const char* name) {
@@ -467,6 +479,10 @@
       ml.Wait();
     }
   }
+  if (server_address_ != NULL) {
+    free(server_address_);
+    server_address_ = NULL;
+  }
 }
 
 
diff --git a/runtime/vm/service_isolate.h b/runtime/vm/service_isolate.h
index a942ec1..1b1a9f6 100644
--- a/runtime/vm/service_isolate.h
+++ b/runtime/vm/service_isolate.h
@@ -34,6 +34,13 @@
 
   static void BootVmServiceLibrary();
 
+  static void SetServerAddress(const char* address);
+
+  // Returns the server's web address or NULL if none is running.
+  static const char* server_address() {
+    return server_address_;
+  }
+
  private:
   static void KillServiceIsolate();
 
@@ -59,6 +66,7 @@
   static Dart_Port port_;
   static Dart_Port load_port_;
   static Dart_Port origin_;
+  static char* server_address_;
 
   friend class Dart;
   friend class RunServiceTask;
diff --git a/runtime/vm/service_test.cc b/runtime/vm/service_test.cc
index d55fe3b..dd2c004 100644
--- a/runtime/vm/service_test.cc
+++ b/runtime/vm/service_test.cc
@@ -167,6 +167,7 @@
       "}";
 
   Isolate* isolate = thread->isolate();
+  isolate->set_is_runnable(true);
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& vmlib = Library::Handle();
@@ -273,7 +274,7 @@
       "}";
 
   Isolate* isolate = thread->isolate();
-
+  isolate->set_is_runnable(true);
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& vmlib = Library::Handle();
@@ -332,6 +333,7 @@
     "}";
 
   Isolate* isolate = thread->isolate();
+  isolate->set_is_runnable(true);
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& vmlib = Library::Handle();
@@ -393,6 +395,7 @@
     "}";
 
   Isolate* isolate = thread->isolate();
+  isolate->set_is_runnable(true);
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Library& vmlib = Library::Handle();
@@ -443,6 +446,7 @@
       "}";
 
   Isolate* isolate = thread->isolate();
+  isolate->set_is_runnable(true);
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
 
@@ -603,6 +607,7 @@
       "}";
 
   Isolate* isolate = thread->isolate();
+  isolate->set_is_runnable(true);
   Dart_Handle lib = TestCase::LoadTestScript(kScript, NULL);
   EXPECT_VALID(lib);
   Dart_Handle result = Dart_Invoke(lib, NewString("main"), 0, NULL);
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index b65ae80..76292c0 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -95,11 +95,11 @@
   bool GetFValue(char* desc, float* value);
   bool GetDValue(char* desc, double* value);
 
-  static intptr_t GetApproximateTokenIndex(const Code& code, uword pc);
+  static TokenPosition GetApproximateTokenIndex(const Code& code, uword pc);
 
   static void PrintDartFrame(uword pc, uword fp, uword sp,
                              const Function& function,
-                             intptr_t token_pos,
+                             TokenPosition token_pos,
                              bool is_optimized,
                              bool is_inlined);
   void PrintBacktrace();
@@ -245,9 +245,9 @@
 }
 
 
-intptr_t SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
-                                                     uword pc) {
-  intptr_t token_pos = -1;
+TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
+                                                            uword pc) {
+  TokenPosition token_pos = TokenPosition::kNoSource;
   uword pc_offset = pc - code.EntryPoint();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
@@ -255,7 +255,7 @@
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
       return iter.TokenPos();
-    } else if ((token_pos <= 0) && (iter.PcOffset() > pc_offset)) {
+    } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) {
       token_pos = iter.TokenPos();
     }
   }
@@ -265,7 +265,7 @@
 
 void SimulatorDebugger::PrintDartFrame(uword pc, uword fp, uword sp,
                                        const Function& function,
-                                       intptr_t token_pos,
+                                       TokenPosition token_pos,
                                        bool is_optimized,
                                        bool is_inlined) {
   const Script& script = Script::Handle(function.script());
@@ -273,7 +273,7 @@
   const String& url = String::Handle(script.url());
   intptr_t line = -1;
   intptr_t column = -1;
-  if (token_pos >= 0) {
+  if (token_pos.IsReal()) {
     script.GetTokenLocation(token_pos, &line, &column);
   }
   OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index e0df115..8ab8455 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -95,11 +95,11 @@
   bool GetDValue(char* desc, uint64_t* value);
   bool GetQValue(char* desc, simd_value_t* value);
 
-  static intptr_t GetApproximateTokenIndex(const Code& code, uword pc);
+  static TokenPosition GetApproximateTokenIndex(const Code& code, uword pc);
 
   static void PrintDartFrame(uword pc, uword fp, uword sp,
                              const Function& function,
-                             intptr_t token_pos,
+                             TokenPosition token_pos,
                              bool is_optimized,
                              bool is_inlined);
   void PrintBacktrace();
@@ -263,9 +263,9 @@
 }
 
 
-intptr_t SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
-                                                     uword pc) {
-  intptr_t token_pos = -1;
+TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
+                                                            uword pc) {
+  TokenPosition token_pos = TokenPosition::kNoSource;
   uword pc_offset = pc - code.EntryPoint();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
@@ -273,7 +273,7 @@
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
       return iter.TokenPos();
-    } else if ((token_pos <= 0) && (iter.PcOffset() > pc_offset)) {
+    } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) {
       token_pos = iter.TokenPos();
     }
   }
@@ -283,7 +283,7 @@
 
 void SimulatorDebugger::PrintDartFrame(uword pc, uword fp, uword sp,
                                        const Function& function,
-                                       intptr_t token_pos,
+                                       TokenPosition token_pos,
                                        bool is_optimized,
                                        bool is_inlined) {
   const Script& script = Script::Handle(function.script());
@@ -291,7 +291,7 @@
   const String& url = String::Handle(script.url());
   intptr_t line = -1;
   intptr_t column = -1;
-  if (token_pos >= 0) {
+  if (token_pos.IsReal()) {
     script.GetTokenLocation(token_pos, &line, &column);
   }
   OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd
diff --git a/runtime/vm/simulator_mips.cc b/runtime/vm/simulator_mips.cc
index f8007ed..5491c6b 100644
--- a/runtime/vm/simulator_mips.cc
+++ b/runtime/vm/simulator_mips.cc
@@ -94,11 +94,11 @@
   bool GetFValue(char* desc, double* value);
   bool GetDValue(char* desc, double* value);
 
-  static intptr_t GetApproximateTokenIndex(const Code& code, uword pc);
+  static TokenPosition GetApproximateTokenIndex(const Code& code, uword pc);
 
   static void PrintDartFrame(uword pc, uword fp, uword sp,
                              const Function& function,
-                             intptr_t token_pos,
+                             TokenPosition token_pos,
                              bool is_optimized,
                              bool is_inlined);
   void PrintBacktrace();
@@ -256,9 +256,9 @@
 }
 
 
-intptr_t SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
+TokenPosition SimulatorDebugger::GetApproximateTokenIndex(const Code& code,
                                                      uword pc) {
-  intptr_t token_pos = -1;
+  TokenPosition token_pos = TokenPosition::kNoSource;
   uword pc_offset = pc - code.EntryPoint();
   const PcDescriptors& descriptors =
       PcDescriptors::Handle(code.pc_descriptors());
@@ -266,7 +266,7 @@
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
       return iter.TokenPos();
-    } else if ((token_pos <= 0) && (iter.PcOffset() > pc_offset)) {
+    } else if (!token_pos.IsReal() && (iter.PcOffset() > pc_offset)) {
       token_pos = iter.TokenPos();
     }
   }
@@ -276,7 +276,7 @@
 
 void SimulatorDebugger::PrintDartFrame(uword pc, uword fp, uword sp,
                                        const Function& function,
-                                       intptr_t token_pos,
+                                       TokenPosition token_pos,
                                        bool is_optimized,
                                        bool is_inlined) {
   const Script& script = Script::Handle(function.script());
@@ -284,7 +284,7 @@
   const String& url = String::Handle(script.url());
   intptr_t line = -1;
   intptr_t column = -1;
-  if (token_pos >= 0) {
+  if (token_pos.IsReal()) {
     script.GetTokenLocation(token_pos, &line, &column);
   }
   OS::Print("pc=0x%" Px " fp=0x%" Px " sp=0x%" Px " %s%s (%s:%" Pd
diff --git a/runtime/vm/snapshot.h b/runtime/vm/snapshot.h
index f635618..b1071d6 100644
--- a/runtime/vm/snapshot.h
+++ b/runtime/vm/snapshot.h
@@ -121,16 +121,12 @@
 static const intptr_t kInvalidPatchIndex = -1;
 
 
-class SerializedHeaderTag : public BitField<enum SerializedHeaderType,
-                                            0,
-                                            kHeaderTagBits> {
-};
+class SerializedHeaderTag :
+    public BitField<intptr_t, enum SerializedHeaderType, 0, kHeaderTagBits> {};
 
 
-class SerializedHeaderData : public BitField<intptr_t,
-                                             kHeaderTagBits,
-                                             kObjectIdBits> {
-};
+class SerializedHeaderData :
+    public BitField<intptr_t, intptr_t, kHeaderTagBits, kObjectIdBits> {};
 
 
 enum DeserializeState {
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index c67a8ce..2b3df5e 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -864,7 +864,9 @@
   // the same.
   const TokenStream& expected_tokens = TokenStream::Handle(script.tokens());
   TokenStream::Iterator expected_iterator(
-      expected_tokens, 0, TokenStream::Iterator::kAllTokens);
+      expected_tokens,
+      TokenPosition::kMinSource,
+      TokenStream::Iterator::kAllTokens);
   const String& str = String::Handle(expected_tokens.GenerateSource());
   const String& private_key = String::Handle(expected_tokens.PrivateKey());
   Scanner scanner(str, private_key);
@@ -872,9 +874,11 @@
       TokenStream::Handle(TokenStream::New(scanner.GetStream(),
                                            private_key,
                                            false));
-  expected_iterator.SetCurrentPosition(0);
+  expected_iterator.SetCurrentPosition(TokenPosition::kMinSource);
   TokenStream::Iterator reconstructed_iterator(
-      reconstructed_tokens, 0, TokenStream::Iterator::kAllTokens);
+      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();
@@ -971,8 +975,10 @@
   const ExternalTypedData& serialized_data =
       ExternalTypedData::Handle(serialized_tokens.GetStream());
   EXPECT_EQ(expected_data.Length(), serialized_data.Length());
-  TokenStream::Iterator expected_iterator(expected_tokens, 0);
-  TokenStream::Iterator serialized_iterator(serialized_tokens, 0);
+  TokenStream::Iterator expected_iterator(expected_tokens,
+                                          TokenPosition::kMinSource);
+  TokenStream::Iterator serialized_iterator(serialized_tokens,
+                                            TokenPosition::kMinSource);
   Token::Kind expected_kind = expected_iterator.CurrentTokenKind();
   Token::Kind serialized_kind = serialized_iterator.CurrentTokenKind();
   while (expected_kind != Token::kEOS && serialized_kind != Token::kEOS) {
@@ -1120,7 +1126,7 @@
   }
 }
 
-TEST_CASE(GenerateSource) {
+VM_TEST_CASE(GenerateSource) {
   Zone* zone = thread->zone();
   Isolate* isolate = thread->isolate();
   const GrowableObjectArray& libs = GrowableObjectArray::Handle(
@@ -1841,10 +1847,12 @@
   EXPECT(Dart_IsString(crappy_string_result));
 
   {
-    DARTSCOPE(Thread::Current());
+    Thread* thread = Thread::Current();
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
 
     {
-      StackZone zone(Thread::Current());
+      StackZone zone(thread);
       Smi& smi = Smi::Handle();
       smi ^= Api::UnwrapHandle(smi_result);
       uint8_t* buffer;
@@ -1862,7 +1870,7 @@
       CheckEncodeDecodeMessage(root);
     }
     {
-      StackZone zone(Thread::Current());
+      StackZone zone(thread);
       Bigint& bigint = Bigint::Handle();
       bigint ^= Api::UnwrapHandle(bigint_result);
       uint8_t* buffer;
@@ -1933,7 +1941,8 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE(thread);
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     StackZone zone(thread);
     intptr_t buf_len = 0;
     {
@@ -2057,7 +2066,8 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE(thread);
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     StackZone zone(thread);
     intptr_t buf_len = 0;
     {
@@ -2296,7 +2306,8 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE(thread);
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     StackZone zone(thread);
     intptr_t buf_len = 0;
     {
@@ -2521,7 +2532,8 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE(thread);
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     StackZone zone(thread);
     intptr_t buf_len = 0;
     {
@@ -2762,7 +2774,8 @@
   EXPECT_VALID(lib);
 
   {
-    DARTSCOPE(thread);
+    CHECK_API_SCOPE(thread);
+    HANDLESCOPE(thread);
     StackZone zone(thread);
     intptr_t buf_len = 0;
     {
diff --git a/runtime/vm/source_report.cc b/runtime/vm/source_report.cc
index 93400bb..6290b6e 100644
--- a/runtime/vm/source_report.cc
+++ b/runtime/vm/source_report.cc
@@ -15,16 +15,16 @@
       compile_mode_(compile_mode),
       thread_(NULL),
       script_(NULL),
-      start_pos_(-1),
-      end_pos_(-1),
+      start_pos_(TokenPosition::kNoSource),
+      end_pos_(TokenPosition::kNoSource),
       next_script_index_(0) {
 }
 
 
 void SourceReport::Init(Thread* thread,
                         const Script* script,
-                        intptr_t start_pos,
-                        intptr_t end_pos) {
+                        TokenPosition start_pos,
+                        TokenPosition end_pos) {
   thread_ = thread;
   script_ = script;
   start_pos_ = start_pos;
@@ -46,8 +46,10 @@
       // The function is from the wrong script.
       return true;
     }
-    if (((start_pos_ > 0) && (func.end_token_pos() < start_pos_)) ||
-        ((end_pos_ > 0) && (func.token_pos() > end_pos_))) {
+    if (((start_pos_ > TokenPosition::kMinSource) &&
+         (func.end_token_pos() < start_pos_)) ||
+        ((end_pos_ > TokenPosition::kMinSource) &&
+         (func.token_pos() > end_pos_))) {
       // The function does not intersect with the requested token range.
       return true;
     }
@@ -111,8 +113,8 @@
 void SourceReport::PrintCallSitesData(JSONObject* jsobj,
                                       const Function& func,
                                       const Code& code) {
-  const intptr_t begin_pos = func.token_pos();
-  const intptr_t end_pos = func.end_token_pos();
+  const TokenPosition begin_pos = func.token_pos();
+  const TokenPosition end_pos = func.end_token_pos();
 
   ZoneGrowableArray<const ICData*>* ic_data_array =
       new(zone()) ZoneGrowableArray<const ICData*>();
@@ -129,7 +131,7 @@
     HANDLESCOPE(thread());
     const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
     if (!ic_data->IsNull()) {
-      const intptr_t token_pos = iter.TokenPos();
+      const TokenPosition token_pos = iter.TokenPos();
       if ((token_pos < begin_pos) || (token_pos > end_pos)) {
         // Does not correspond to a valid source position.
         continue;
@@ -143,8 +145,8 @@
 void SourceReport::PrintCoverageData(JSONObject* jsobj,
                                      const Function& func,
                                      const Code& code) {
-  const intptr_t begin_pos = func.token_pos();
-  const intptr_t end_pos = func.end_token_pos();
+  const TokenPosition begin_pos = func.token_pos();
+  const TokenPosition end_pos = func.end_token_pos();
 
   ZoneGrowableArray<const ICData*>* ic_data_array =
       new(zone()) ZoneGrowableArray<const ICData*>();
@@ -156,7 +158,7 @@
   const int kCoverageMiss = 1;
   const int kCoverageHit = 2;
 
-  intptr_t func_length = (end_pos - begin_pos) + 1;
+  intptr_t func_length = (end_pos.Pos() - begin_pos.Pos()) + 1;
   GrowableArray<char> coverage(func_length);
   coverage.SetLength(func_length);
   for (int i = 0; i < func_length; i++) {
@@ -170,13 +172,13 @@
     HANDLESCOPE(thread());
     const ICData* ic_data = (*ic_data_array)[iter.DeoptId()];
     if (!ic_data->IsNull()) {
-      const intptr_t token_pos = iter.TokenPos();
+      const TokenPosition token_pos = iter.TokenPos();
       if ((token_pos < begin_pos) || (token_pos > end_pos)) {
         // Does not correspond to a valid source position.
         continue;
       }
       intptr_t count = ic_data->AggregateCount();
-      intptr_t token_offset = token_pos - begin_pos;
+      intptr_t token_offset = token_pos.Pos() - begin_pos.Pos();
       if (count > 0) {
         coverage[token_offset] = kCoverageHit;
       } else {
@@ -192,7 +194,8 @@
     JSONArray hits(&cov, "hits");
     for (int i = 0; i < func_length; i++) {
       if (coverage[i] == kCoverageHit) {
-        hits.AddValue(begin_pos + i);  // Add the token position of the hit.
+        // Add the token position of the hit.
+        hits.AddValue(begin_pos.Pos() + i);
       }
     }
   }
@@ -200,7 +203,8 @@
     JSONArray misses(&cov, "misses");
     for (int i = 0; i < func_length; i++) {
       if (coverage[i] == kCoverageMiss) {
-        misses.AddValue(begin_pos + i);  // Add the token position of the miss.
+        // Add the token position of the miss.
+        misses.AddValue(begin_pos.Pos() + i);
       }
     }
   }
@@ -212,13 +216,13 @@
   const uint8_t kSafepointKind = (RawPcDescriptors::kIcCall |
                                   RawPcDescriptors::kUnoptStaticCall |
                                   RawPcDescriptors::kRuntimeCall);
-  const intptr_t begin_pos = func.token_pos();
-  const intptr_t end_pos = func.end_token_pos();
+  const TokenPosition begin_pos = func.token_pos();
+  const TokenPosition end_pos = func.end_token_pos();
 
   const PcDescriptors& descriptors = PcDescriptors::Handle(
       zone(), code.pc_descriptors());
 
-  intptr_t func_length = (end_pos - begin_pos) + 1;
+  intptr_t func_length = (end_pos.Pos() - begin_pos.Pos()) + 1;
   GrowableArray<char> possible(func_length);
   possible.SetLength(func_length);
   for (int i = 0; i < func_length; i++) {
@@ -227,19 +231,20 @@
 
   PcDescriptors::Iterator iter(descriptors, kSafepointKind);
   while (iter.MoveNext()) {
-    const intptr_t token_pos = iter.TokenPos();
+    const TokenPosition token_pos = iter.TokenPos();
     if ((token_pos < begin_pos) || (token_pos > end_pos)) {
       // Does not correspond to a valid source position.
       continue;
     }
-    intptr_t token_offset = token_pos - begin_pos;
+    intptr_t token_offset = token_pos.Pos() - begin_pos.Pos();
     possible[token_offset] = true;
   }
 
   JSONArray bpts(jsobj, "possibleBreakpoints");
   for (int i = 0; i < func_length; i++) {
     if (possible[i]) {
-      bpts.AddValue(begin_pos + i);  // Add the token position.
+      // Add the token position.
+      bpts.AddValue(begin_pos.Pos() + i);
     }
   }
 }
@@ -259,8 +264,8 @@
   }
 
   const Script& script = Script::Handle(zone(), func.script());
-  const intptr_t begin_pos = func.token_pos();
-  const intptr_t end_pos = func.end_token_pos();
+  const TokenPosition begin_pos = func.token_pos();
+  const TokenPosition end_pos = func.end_token_pos();
 
   Code& code = Code::Handle(zone(), func.unoptimized_code());
   if (code.IsNull()) {
@@ -341,7 +346,8 @@
 
 void SourceReport::PrintJSON(JSONStream* js,
                              const Script& script,
-                             intptr_t start_pos, intptr_t end_pos) {
+                             TokenPosition start_pos,
+                             TokenPosition end_pos) {
   Init(Thread::Current(), &script, start_pos, end_pos);
 
   JSONObject report(js);
diff --git a/runtime/vm/source_report.h b/runtime/vm/source_report.h
index 9b03a23..77bf6c2 100644
--- a/runtime/vm/source_report.h
+++ b/runtime/vm/source_report.h
@@ -9,6 +9,7 @@
 #include "vm/flags.h"
 #include "vm/hash_map.h"
 #include "vm/object.h"
+#include "vm/token_position.h"
 
 namespace dart {
 
@@ -38,11 +39,12 @@
   // If script is null, then the report is generated for all scripts
   // in the isolate.
   void PrintJSON(JSONStream* js, const Script& script,
-                 intptr_t start_pos = -1, intptr_t end_pos = -1);
+                 TokenPosition start_pos = TokenPosition::kNoSource,
+                 TokenPosition end_pos = TokenPosition::kNoSource);
 
  private:
   void Init(Thread* thread, const Script* script,
-            intptr_t start_pos, intptr_t end_pos);
+            TokenPosition start_pos, TokenPosition end_pos);
 
   Thread* thread() const { return thread_; }
   Zone* zone() const { return thread_->zone(); }
@@ -100,8 +102,8 @@
   CompileMode compile_mode_;
   Thread* thread_;
   const Script* script_;
-  intptr_t start_pos_;
-  intptr_t end_pos_;
+  TokenPosition start_pos_;
+  TokenPosition end_pos_;
   GrowableArray<ScriptTableEntry> script_table_entries_;
   DirectChainedHashMap<ScriptTableTrait> script_table_;
   intptr_t next_script_index_;
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 65f7c3b..fb3d8d8 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -240,10 +240,10 @@
 }
 
 
-intptr_t StackFrame::GetTokenPos() const {
+TokenPosition StackFrame::GetTokenPos() const {
   const Code& code = Code::Handle(LookupDartCode());
   if (code.IsNull()) {
-    return -1;  // Stub frames do not have token_pos.
+    return TokenPosition::kNoSource;  // Stub frames do not have token_pos.
   }
   uword pc_offset = pc() - code.EntryPoint();
   const PcDescriptors& descriptors =
@@ -252,10 +252,10 @@
   PcDescriptors::Iterator iter(descriptors, RawPcDescriptors::kAnyKind);
   while (iter.MoveNext()) {
     if (iter.PcOffset() == pc_offset) {
-      return iter.TokenPos();
+      return TokenPosition(iter.TokenPos());
     }
   }
-  return -1;
+  return TokenPosition::kNoSource;
 }
 
 
diff --git a/runtime/vm/stack_frame.h b/runtime/vm/stack_frame.h
index 1c59ccb..2d1b12c 100644
--- a/runtime/vm/stack_frame.h
+++ b/runtime/vm/stack_frame.h
@@ -82,7 +82,7 @@
                             bool* needs_stacktrace,
                             bool* is_catch_all) const;
   // Returns token_pos of the pc(), or -1 if none exists.
-  intptr_t GetTokenPos() const;
+  TokenPosition GetTokenPos() const;
 
  protected:
   explicit StackFrame(Thread* thread)
diff --git a/runtime/vm/stack_frame_test.cc b/runtime/vm/stack_frame_test.cc
index c5f280a..533eb93 100644
--- a/runtime/vm/stack_frame_test.cc
+++ b/runtime/vm/stack_frame_test.cc
@@ -19,7 +19,7 @@
 DECLARE_FLAG(bool, lazy_dispatchers);
 
 // Unit test for empty stack frame iteration.
-TEST_CASE(EmptyStackFrameIteration) {
+VM_TEST_CASE(EmptyStackFrameIteration) {
   StackFrameIterator iterator(StackFrameIterator::kValidateFrames);
   EXPECT(!iterator.HasNextFrame());
   EXPECT(iterator.NextFrame() == NULL);
@@ -28,7 +28,7 @@
 
 
 // Unit test for empty dart stack frame iteration.
-TEST_CASE(EmptyDartStackFrameIteration) {
+VM_TEST_CASE(EmptyDartStackFrameIteration) {
   DartFrameIterator iterator;
   EXPECT(iterator.NextFrame() == NULL);
   VerifyPointersVisitor::VerifyPointers();
diff --git a/runtime/vm/stub_code_arm64_test.cc b/runtime/vm/stub_code_arm64_test.cc
index a64d6f7..7cc0b65 100644
--- a/runtime/vm/stub_code_arm64_test.cc
+++ b/runtime/vm/stub_code_arm64_test.cc
@@ -22,14 +22,15 @@
 static Function* CreateFunction(const char* name) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
   Function& function = Function::ZoneHandle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
   return &function;
 }
 
diff --git a/runtime/vm/stub_code_arm_test.cc b/runtime/vm/stub_code_arm_test.cc
index 36d703e..e7c5bb9 100644
--- a/runtime/vm/stub_code_arm_test.cc
+++ b/runtime/vm/stub_code_arm_test.cc
@@ -22,14 +22,15 @@
 static Function* CreateFunction(const char* name) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
   Function& function = Function::ZoneHandle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
   return &function;
 }
 
diff --git a/runtime/vm/stub_code_ia32_test.cc b/runtime/vm/stub_code_ia32_test.cc
index fff4bc7..a3c20ec 100644
--- a/runtime/vm/stub_code_ia32_test.cc
+++ b/runtime/vm/stub_code_ia32_test.cc
@@ -22,14 +22,15 @@
 static Function* CreateFunction(const char* name) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
   Function& function = Function::ZoneHandle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kMinSource));
   return &function;
 }
 
diff --git a/runtime/vm/stub_code_mips_test.cc b/runtime/vm/stub_code_mips_test.cc
index 21e7768..7f6d177 100644
--- a/runtime/vm/stub_code_mips_test.cc
+++ b/runtime/vm/stub_code_mips_test.cc
@@ -22,14 +22,15 @@
 static Function* CreateFunction(const char* name) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
   Function& function = Function::ZoneHandle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
   return &function;
 }
 
diff --git a/runtime/vm/stub_code_x64_test.cc b/runtime/vm/stub_code_x64_test.cc
index 2716433..b320f60 100644
--- a/runtime/vm/stub_code_x64_test.cc
+++ b/runtime/vm/stub_code_x64_test.cc
@@ -22,14 +22,15 @@
 static Function* CreateFunction(const char* name) {
   const String& class_name = String::Handle(Symbols::New("ownerClass"));
   const Script& script = Script::Handle();
-  const Class& owner_class =
-      Class::Handle(Class::New(class_name, script, Token::kNoSourcePos));
+  const Class& owner_class = Class::Handle(
+      Class::New(class_name, script, TokenPosition::kNoSource));
   const Library& lib = Library::Handle(Library::New(class_name));
   owner_class.set_library(lib);
   const String& function_name = String::ZoneHandle(Symbols::New(name));
   Function& function = Function::ZoneHandle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, owner_class, 0));
+                    true, false, false, false, false, owner_class,
+                    TokenPosition::kNoSource));
   return &function;
 }
 
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index e984c1b..bee034f 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -331,6 +331,91 @@
 }
 
 
+intptr_t Symbols::Compact(Isolate* isolate) {
+  ASSERT(isolate != Dart::vm_isolate());
+
+  Zone* zone = Thread::Current()->zone();
+  intptr_t initial_size = -1;
+  intptr_t final_size = -1;
+
+  // 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();
+
+    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();
+  }
+
+  // 2. Knock out 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.
+  GrowableArray<String*> symbols;
+  class SymbolCollector : public ObjectVisitor {
+   public:
+    SymbolCollector(Thread* thread,
+                    GrowableArray<String*>* symbols)
+        : ObjectVisitor(thread->isolate()),
+          symbols_(symbols),
+          zone_(thread->zone()) {}
+
+    void VisitObject(RawObject* obj) {
+      if (obj->IsString() && obj->IsCanonical()) {
+        symbols_->Add(&String::ZoneHandle(zone_, String::RawCast(obj)));
+      }
+    }
+
+   private:
+    GrowableArray<String*>* symbols_;
+    Zone* zone_;
+  };
+
+  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());
+  }
+
+  return initial_size - final_size;
+}
+
+
 void Symbols::GetStats(Isolate* isolate, intptr_t* size, intptr_t* capacity) {
   ASSERT(isolate != NULL);
   SymbolTable table(isolate->object_store()->symbol_table());
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index eae0796..e9033d1 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -572,6 +572,11 @@
   // 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);
+
   // Creates a Symbol given a C string that is assumed to contain
   // UTF-8 encoded characters and '\0' is considered a termination character.
   // TODO(7123) - Rename this to FromCString(....).
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index c220913..adfc4b4 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -41,6 +41,7 @@
 Thread::Thread(Isolate* isolate)
     : BaseThread(false),
       os_thread_(NULL),
+      thread_lock_(new Monitor()),
       isolate_(NULL),
       heap_(NULL),
       zone_(NULL),
@@ -63,6 +64,8 @@
       pending_functions_(GrowableObjectArray::null()),
       REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_INITIALIZERS)
       REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_SCOPE_INIT)
+      safepoint_state_(0),
+      execution_state_(kThreadInVM),
       next_(NULL) {
 #define DEFAULT_INIT(type_name, member_name, init_expr, default_init_value)    \
   member_name = default_init_value;
@@ -174,13 +177,8 @@
 
 bool Thread::EnterIsolate(Isolate* isolate) {
   const bool kIsMutatorThread = true;
-  const bool kDontBypassSafepoints = false;
-  ThreadRegistry* tr = isolate->thread_registry();
-  Thread* thread = tr->Schedule(
-      isolate, kIsMutatorThread, kDontBypassSafepoints);
+  Thread* thread = isolate->ScheduleThread(kIsMutatorThread);
   if (thread != NULL) {
-    isolate->MakeCurrentThreadMutator(thread);
-    thread->set_vm_tag(VMTag::kVMTagId);
     ASSERT(thread->store_buffer_block_ == NULL);
     thread->StoreBufferAcquire();
     return true;
@@ -191,33 +189,29 @@
 
 void Thread::ExitIsolate() {
   Thread* thread = Thread::Current();
-  ASSERT(thread != NULL);
-  ASSERT(thread->IsMutatorThread());
-#if defined(DEBUG)
-  ASSERT(!thread->IsAnyReusableHandleScopeActive());
-#endif  // DEBUG
+  ASSERT(thread != NULL && thread->IsMutatorThread());
+  DEBUG_ASSERT(!thread->IsAnyReusableHandleScopeActive());
+
+  Isolate* isolate = thread->isolate();
+  ASSERT(isolate != NULL);
+  ASSERT(thread->execution_state() == Thread::kThreadInVM);
   // Clear since GC will not visit the thread once it is unscheduled.
   thread->ClearReusableHandles();
   thread->StoreBufferRelease();
-  Isolate* isolate = thread->isolate();
-  ASSERT(isolate != NULL);
   if (isolate->is_runnable()) {
     thread->set_vm_tag(VMTag::kIdleTagId);
   } else {
     thread->set_vm_tag(VMTag::kLoadWaitTagId);
   }
   const bool kIsMutatorThread = true;
-  const bool kDontBypassSafepoints = false;
-  ThreadRegistry* tr = isolate->thread_registry();
-  tr->Unschedule(thread, kIsMutatorThread, kDontBypassSafepoints);
-  isolate->ClearMutatorThread();
+  isolate->UnscheduleThread(thread, kIsMutatorThread);
 }
 
 
 bool Thread::EnterIsolateAsHelper(Isolate* isolate, bool bypass_safepoint) {
   const bool kIsNotMutatorThread = false;
-  ThreadRegistry* tr = isolate->thread_registry();
-  Thread* thread = tr->Schedule(isolate, kIsNotMutatorThread, bypass_safepoint);
+  Thread* thread = isolate->ScheduleThread(kIsNotMutatorThread,
+                                           bypass_safepoint);
   if (thread != NULL) {
     ASSERT(thread->store_buffer_block_ == NULL);
     // TODO(koda): Use StoreBufferAcquire once we properly flush
@@ -236,18 +230,19 @@
   Thread* thread = Thread::Current();
   ASSERT(thread != NULL);
   ASSERT(!thread->IsMutatorThread());
+  ASSERT(thread->execution_state() == Thread::kThreadInVM);
   thread->StoreBufferRelease();
   Isolate* isolate = thread->isolate();
   ASSERT(isolate != NULL);
   const bool kIsNotMutatorThread = false;
-  ThreadRegistry* tr = isolate->thread_registry();
-  tr->Unschedule(thread, kIsNotMutatorThread, bypass_safepoint);
+  isolate->UnscheduleThread(thread, kIsNotMutatorThread, bypass_safepoint);
 }
 
 
 void Thread::PrepareForGC() {
-  ASSERT(isolate()->thread_registry()->AtSafepoint());
+  ASSERT(IsAtSafepoint());
   // Prevent scheduling another GC by ignoring the threshold.
+  ASSERT(store_buffer_block_ != NULL);
   StoreBufferRelease(StoreBuffer::kIgnoreThreshold);
   // Make sure to get an *empty* block; the isolate needs all entries
   // at GC time.
@@ -299,9 +294,7 @@
   // We have non mutator threads grow the heap instead of triggering
   // a garbage collection when they are at a safepoint (e.g: background
   // compiler thread finalizing and installing code at a safepoint).
-  // Note: This code will change once the new Safepoint logic is in place.
-  return (IsMutatorThread() ||
-          (isolate_ != NULL && !isolate_->thread_registry()->AtSafepoint()));
+  return (IsMutatorThread() || IsAtSafepoint());
 }
 
 
@@ -454,6 +447,21 @@
 }
 
 
+void Thread::EnterSafepointUsingLock() {
+  isolate()->safepoint_handler()->EnterSafepointUsingLock(this);
+}
+
+
+void Thread::ExitSafepointUsingLock() {
+  isolate()->safepoint_handler()->ExitSafepointUsingLock(this);
+}
+
+
+void Thread::BlockForSafepoint() {
+  isolate()->safepoint_handler()->BlockForSafepoint(this);
+}
+
+
 DisableThreadInterruptsScope::DisableThreadInterruptsScope(Thread* thread)
     : StackResource(thread) {
   if (thread != NULL) {
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index ad073af..c5a0c8f 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -6,6 +6,9 @@
 #define VM_THREAD_H_
 
 #include "include/dart_api.h"
+#include "platform/assert.h"
+#include "vm/atomic.h"
+#include "vm/bitfield.h"
 #include "vm/globals.h"
 #include "vm/handles.h"
 #include "vm/os_thread.h"
@@ -143,6 +146,9 @@
     os_thread_ = os_thread;
   }
 
+  // Monitor corresponding to this thread.
+  Monitor* thread_lock() const { return thread_lock_; }
+
   // The topmost zone used for allocation in this thread.
   Zone* zone() const { return zone_; }
 
@@ -209,7 +215,9 @@
     return OFFSET_OF(Thread, store_buffer_block_);
   }
 
-  uword top_exit_frame_info() const { return top_exit_frame_info_; }
+  uword top_exit_frame_info() const {
+    return top_exit_frame_info_;
+  }
   static intptr_t top_exit_frame_info_offset() {
     return OFFSET_OF(Thread, top_exit_frame_info_);
   }
@@ -356,6 +364,8 @@
     return OFFSET_OF(Thread, vm_tag_);
   }
 
+  RawGrowableObjectArray* pending_functions();
+
 #if defined(DEBUG)
 #define REUSABLE_HANDLE_SCOPE_ACCESSORS(object)                                \
   void set_reusable_##object##_handle_scope_active(bool value) {               \
@@ -385,7 +395,120 @@
   REUSABLE_HANDLE_LIST(REUSABLE_HANDLE)
 #undef REUSABLE_HANDLE
 
-  RawGrowableObjectArray* pending_functions();
+  /*
+   * Fields used to support safepointing a thread.
+   *
+   * - Bit 0 of the safepoint_state_ field is used to indicate if the thread is
+   *   already at a safepoint,
+   * - Bit 1 of the safepoint_state_ field is used to indicate if a safepoint
+   *   operation is requested for this thread.
+   * - Bit 2 of the safepoint_state_ field is used to indicate that the thread
+   *   is blocked for the safepoint operation to complete.
+   *
+   * The safepoint execution state (described above) for a thread is stored in
+   * in the execution_state_ field.
+   * Potential execution states a thread could be in:
+   *   kThreadInGenerated - The thread is running jitted dart/stub code.
+   *   kThreadInVM - The thread is running VM code.
+   *   kThreadInNative - The thread is running native code.
+   *   kThreadInBlockedState - The thread is blocked waiting for a resource.
+   */
+  static intptr_t safepoint_state_offset() {
+    return OFFSET_OF(Thread, safepoint_state_);
+  }
+  static bool IsAtSafepoint(uint32_t state) {
+    return AtSafepointField::decode(state);
+  }
+  bool IsAtSafepoint() const {
+    return AtSafepointField::decode(safepoint_state_);
+  }
+  static uint32_t SetAtSafepoint(bool value, uint32_t state) {
+    return AtSafepointField::update(value, state);
+  }
+  void SetAtSafepoint(bool value) {
+    ASSERT(thread_lock()->IsOwnedByCurrentThread());
+    safepoint_state_ = AtSafepointField::update(value, safepoint_state_);
+  }
+  bool IsSafepointRequested() const {
+    return SafepointRequestedField::decode(safepoint_state_);
+  }
+  static uint32_t SetSafepointRequested(bool value, uint32_t state) {
+    return SafepointRequestedField::update(value, state);
+  }
+  uint32_t SetSafepointRequested(bool value) {
+    ASSERT(thread_lock()->IsOwnedByCurrentThread());
+    uint32_t old_state;
+    uint32_t new_state;
+    do {
+      old_state = safepoint_state_;
+      new_state = SafepointRequestedField::update(value, old_state);
+    } while (AtomicOperations::CompareAndSwapUint32(&safepoint_state_,
+                                                    old_state,
+                                                    new_state) != old_state);
+    return old_state;
+  }
+  static bool IsBlockedForSafepoint(uint32_t state) {
+    return BlockedForSafepointField::decode(state);
+  }
+  bool IsBlockedForSafepoint() const {
+    return BlockedForSafepointField::decode(safepoint_state_);
+  }
+  void SetBlockedForSafepoint(bool value) {
+    ASSERT(thread_lock()->IsOwnedByCurrentThread());
+    safepoint_state_ =
+        BlockedForSafepointField::update(value, safepoint_state_);
+  }
+
+  enum ExecutionState {
+    kThreadInVM = 0,
+    kThreadInGenerated,
+    kThreadInNative,
+    kThreadInBlockedState
+  };
+
+  ExecutionState execution_state() const {
+    return static_cast<ExecutionState>(execution_state_);
+  }
+  void set_execution_state(ExecutionState state) {
+    execution_state_ = static_cast<uint32_t>(state);
+  }
+  static intptr_t execution_state_offset() {
+    return OFFSET_OF(Thread, execution_state_);
+  }
+
+  void EnterSafepoint() {
+    // First try a fast update of the thread state to indicate it is at a
+    // safepoint.
+    uint32_t new_state = SetAtSafepoint(true, 0);
+    uword addr = reinterpret_cast<uword>(this) + safepoint_state_offset();
+    if (AtomicOperations::CompareAndSwapUint32(
+            reinterpret_cast<uint32_t*>(addr), 0, new_state) != 0) {
+      // Fast update failed which means we could potentially be in the middle
+      // of a safepoint operation.
+      EnterSafepointUsingLock();
+    }
+  }
+
+  void ExitSafepoint() {
+    // First try a fast update of the thread state to indicate it is not at a
+    // safepoint anymore.
+    uint32_t old_state = SetAtSafepoint(true, 0);
+    uword addr = reinterpret_cast<uword>(this) + safepoint_state_offset();
+    if (AtomicOperations::CompareAndSwapUint32(
+            reinterpret_cast<uint32_t*>(addr), old_state, 0) != old_state) {
+      // Fast update failed which means we could potentially be in the middle
+      // of a safepoint operation.
+      ExitSafepointUsingLock();
+    }
+  }
+
+  void CheckForSafepoint() {
+    if (IsSafepointRequested()) {
+      BlockForSafepoint();
+    }
+  }
+
+  Thread* next() const { return next_; }
 
   // Visit all object pointers.
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
@@ -401,6 +524,7 @@
   template<class T> T* AllocateReusableHandle();
 
   OSThread* os_thread_;
+  Monitor* thread_lock_;
   Isolate* isolate_;
   Heap* heap_;
   Zone* zone_;
@@ -453,6 +577,12 @@
 #undef REUSABLE_HANDLE_SCOPE_VARIABLE
 #endif  // defined(DEBUG)
 
+  class AtSafepointField : public BitField<uint32_t, bool, 0, 1> {};
+  class SafepointRequestedField : public BitField<uint32_t, bool, 1, 1> {};
+  class BlockedForSafepointField : public BitField<uint32_t, bool, 2, 1> {};
+  uint32_t safepoint_state_;
+  uint32_t execution_state_;
+
   Thread* next_;  // Used to chain the thread structures in an isolate.
 
   explicit Thread(Isolate* isolate);
@@ -469,6 +599,13 @@
     top_exit_frame_info_ = top_exit_frame_info;
   }
 
+  void set_safepoint_state(uint32_t value) {
+    safepoint_state_ = value;
+  }
+  void EnterSafepointUsingLock();
+  void ExitSafepointUsingLock();
+  void BlockForSafepoint();
+
   static void SetCurrent(Thread* current) {
     OSThread::SetCurrentTLS(reinterpret_cast<uword>(current));
   }
diff --git a/runtime/vm/thread_registry.cc b/runtime/vm/thread_registry.cc
index 2d2dee3..111ae57 100644
--- a/runtime/vm/thread_registry.cc
+++ b/runtime/vm/thread_registry.cc
@@ -12,7 +12,7 @@
 ThreadRegistry::~ThreadRegistry() {
   // Go over the free thread list and delete the thread objects.
   {
-    MonitorLocker ml(monitor_);
+    MonitorLocker ml(threads_lock());
     // At this point the active list should be empty.
     ASSERT(active_list_ == NULL);
     // We have cached the mutator thread, delete it.
@@ -27,114 +27,44 @@
   }
 
   // Delete monitor.
-  delete monitor_;
+  delete threads_lock_;
 }
 
 
-void ThreadRegistry::SafepointThreads() {
-  MonitorLocker ml(monitor_);
-  // First wait for any older rounds that are still in progress.
-  while (in_rendezvous_) {
-    // Assert we are not the organizer trying to nest calls to SafepointThreads.
-    ASSERT(remaining_ > 0);
-    CheckSafepointLocked();
-  }
-  // Start a new round.
-  in_rendezvous_ = true;
-  ++round_;  // Overflows after 240+ years @ 10^9 safepoints per second.
-  remaining_ = CountScheduledLocked();
-  Isolate* isolate = Isolate::Current();
-  // We only expect this method to be called from within the isolate itself.
-  ASSERT(isolate->thread_registry() == this);
-  --remaining_;  // Exclude this thread from the count.
-  // Ensure the main mutator will reach a safepoint (could be running Dart).
-  if (!Thread::Current()->IsMutatorThread()) {
-    isolate->ScheduleInterrupts(Isolate::kVMInterrupt);
-  }
-  while (remaining_ > 0) {
-    ml.Wait(Monitor::kNoTimeout);
-  }
-}
-
-
-void ThreadRegistry::ResumeAllThreads() {
-  MonitorLocker ml(monitor_);
-  ASSERT(in_rendezvous_);
-  in_rendezvous_ = false;
-  ml.NotifyAll();
-}
-
-
-Thread* ThreadRegistry::Schedule(Isolate* isolate,
-                                 bool is_mutator,
-                                 bool bypass_safepoint) {
-  MonitorLocker ml(monitor_);
-  // Wait for any rendezvous in progress.
-  while (!bypass_safepoint && in_rendezvous_) {
-    ml.Wait(Monitor::kNoTimeout);
-  }
-  Thread* thread = NULL;
-  OSThread* os_thread = OSThread::Current();
-  if (os_thread != NULL) {
-    ASSERT(isolate->heap() != NULL);
-    // First get a Thread structure. (we special case the mutator thread
-    // by reusing the cached structure, see comment in 'thread_registry.h').
-    if (is_mutator) {
-      if (mutator_thread_ == NULL) {
-        mutator_thread_ = GetThreadFromFreelist(isolate);
-      }
-      thread = mutator_thread_;
-    } else {
-      thread = GetThreadFromFreelist(isolate);
-      ASSERT(thread->api_top_scope() == NULL);
+// Gets a free Thread structure, we special case the mutator thread
+// by reusing the cached structure, see comment in 'thread_registry.h'.
+Thread* ThreadRegistry::GetFreeThreadLocked(Isolate* isolate, bool is_mutator) {
+  ASSERT(threads_lock()->IsOwnedByCurrentThread());
+  Thread* thread;
+  if (is_mutator) {
+    if (mutator_thread_ == NULL) {
+      mutator_thread_ = GetFromFreelistLocked(isolate);
     }
-    // Now add this Thread to the active list for the isolate.
-    AddThreadToActiveList(thread);
-    // Set up other values and set the TLS value.
-    thread->isolate_ = isolate;
-    thread->heap_ = isolate->heap();
-    thread->set_os_thread(os_thread);
-    os_thread->set_thread(thread);
-    Thread::SetCurrent(thread);
-    os_thread->EnableThreadInterrupts();
+    thread = mutator_thread_;
+  } else {
+    thread = GetFromFreelistLocked(isolate);
+    ASSERT(thread->api_top_scope() == NULL);
   }
+  // Now add this Thread to the active list for the isolate.
+  AddToActiveListLocked(thread);
   return thread;
 }
 
 
-void ThreadRegistry::Unschedule(Thread* thread,
-                                bool is_mutator,
-                                bool bypass_safepoint) {
-  MonitorLocker ml(monitor_);
-  OSThread* os_thread = thread->os_thread();
-  ASSERT(os_thread != NULL);
-  os_thread->DisableThreadInterrupts();
-  os_thread->set_thread(NULL);
-  OSThread::SetCurrent(os_thread);
-  thread->isolate_ = NULL;
-  thread->heap_ = NULL;
-  thread->set_os_thread(NULL);
+void ThreadRegistry::ReturnThreadLocked(bool is_mutator, Thread* thread) {
+  ASSERT(threads_lock()->IsOwnedByCurrentThread());
   // Remove thread from the active list for the isolate.
-  RemoveThreadFromActiveList(thread);
-  // Return thread to the free list (we special case the mutator
-  // thread by holding on to it, see comment in 'thread_registry.h').
+  RemoveFromActiveListLocked(thread);
   if (!is_mutator) {
     ASSERT(thread->api_top_scope() == NULL);
-    ReturnThreadToFreelist(thread);
-  }
-  if (!bypass_safepoint && in_rendezvous_) {
-    // Don't wait for this thread.
-    ASSERT(remaining_ > 0);
-    if (--remaining_ == 0) {
-      ml.NotifyAll();
-    }
+    ReturnToFreelistLocked(thread);
   }
 }
 
 
 void ThreadRegistry::VisitObjectPointers(ObjectPointerVisitor* visitor,
                                          bool validate_frames) {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(threads_lock());
   Thread* thread = active_list_;
   while (thread != NULL) {
     if (thread->zone() != NULL) {
@@ -155,7 +85,7 @@
 
 
 void ThreadRegistry::PrepareForGC() {
-  MonitorLocker ml(monitor_);
+  MonitorLocker ml(threads_lock());
   Thread* thread = active_list_;
   while (thread != NULL) {
     thread->PrepareForGC();
@@ -164,17 +94,17 @@
 }
 
 
-void ThreadRegistry::AddThreadToActiveList(Thread* thread) {
+void ThreadRegistry::AddToActiveListLocked(Thread* thread) {
   ASSERT(thread != NULL);
-  ASSERT(monitor_->IsOwnedByCurrentThread());
+  ASSERT(threads_lock()->IsOwnedByCurrentThread());
   thread->next_ = active_list_;
   active_list_ = thread;
 }
 
 
-void ThreadRegistry::RemoveThreadFromActiveList(Thread* thread) {
+void ThreadRegistry::RemoveFromActiveListLocked(Thread* thread) {
   ASSERT(thread != NULL);
-  ASSERT(monitor_->IsOwnedByCurrentThread());
+  ASSERT(threads_lock()->IsOwnedByCurrentThread());
   Thread* prev = NULL;
   Thread* current = active_list_;
   while (current != NULL) {
@@ -192,8 +122,8 @@
 }
 
 
-Thread* ThreadRegistry::GetThreadFromFreelist(Isolate* isolate) {
-  ASSERT(monitor_->IsOwnedByCurrentThread());
+Thread* ThreadRegistry::GetFromFreelistLocked(Isolate* isolate) {
+  ASSERT(threads_lock()->IsOwnedByCurrentThread());
   Thread* thread = NULL;
   // Get thread structure from free list or create a new one.
   if (free_list_ == NULL) {
@@ -205,51 +135,15 @@
   return thread;
 }
 
-void ThreadRegistry::ReturnThreadToFreelist(Thread* thread) {
+void ThreadRegistry::ReturnToFreelistLocked(Thread* thread) {
   ASSERT(thread != NULL);
   ASSERT(thread->os_thread_ == NULL);
   ASSERT(thread->isolate_ == NULL);
   ASSERT(thread->heap_ == NULL);
-  ASSERT(monitor_->IsOwnedByCurrentThread());
+  ASSERT(threads_lock()->IsOwnedByCurrentThread());
   // Add thread to the free list.
   thread->next_ = free_list_;
   free_list_ = thread;
 }
 
-
-void ThreadRegistry::CheckSafepointLocked() {
-  int64_t last_round = -1;
-  while (in_rendezvous_) {
-    ASSERT(round_ >= last_round);
-    if (round_ != last_round) {
-      ASSERT((last_round == -1) || (round_ == (last_round + 1)));
-      last_round = round_;
-      // Participate in this round.
-      if (--remaining_ == 0) {
-        // Ensure the organizing thread is notified.
-        // TODO(koda): Use separate condition variables and plain 'Notify'.
-        monitor_->NotifyAll();
-      }
-    }
-    monitor_->Wait(Monitor::kNoTimeout);
-    // Note: Here, round_ is needed to detect and distinguish two cases:
-    // a) The old rendezvous is still in progress, so just keep waiting, or
-    // b) after ResumeAllThreads, another call to SafepointThreads was
-    // made before this thread got a chance to reaquire monitor_, thus this
-    // thread should (again) decrease remaining_ to indicate cooperation in
-    // this new round.
-  }
-}
-
-
-intptr_t ThreadRegistry::CountScheduledLocked() {
-  intptr_t count = 0;
-  Thread* current = active_list_;
-  while (current != NULL) {
-    ++count;
-    current = current->next_;
-  }
-  return count;
-}
-
 }  // namespace dart
diff --git a/runtime/vm/thread_registry.h b/runtime/vm/thread_registry.h
index 555e513..c765a5d 100644
--- a/runtime/vm/thread_registry.h
+++ b/runtime/vm/thread_registry.h
@@ -18,62 +18,32 @@
 class ThreadRegistry {
  public:
   ThreadRegistry()
-      : monitor_(new Monitor()),
+      : threads_lock_(new Monitor()),
         active_list_(NULL),
         free_list_(NULL),
-        mutator_thread_(NULL),
-        in_rendezvous_(false),
-        remaining_(0),
-        round_(0) {}
-
+        mutator_thread_(NULL) {}
   ~ThreadRegistry();
 
-  Thread* active_list() const { return active_list_; }
-
-  // Bring all threads in this isolate to a safepoint. The caller is
-  // expected to be implicitly at a safepoint. The threads will wait
-  // until ResumeAllThreads is called. First participates in any
-  // already pending rendezvous requested by another thread. Any
-  // thread that tries to enter this isolate during rendezvous will
-  // wait in RestoreStateTo. Nesting is not supported: the caller must
-  // call ResumeAllThreads before making further calls to
-  // SafepointThreads.
-  void SafepointThreads();
-
-  // Unblocks all threads participating in the rendezvous that was organized
-  // by a prior call to SafepointThreads.
-  // TODO(koda): Consider adding a scope helper to avoid omitting this call.
-  void ResumeAllThreads();
-
-  // Indicate that the current thread is at a safepoint, and offer to wait for
-  // any pending rendezvous request (if none, returns immediately).
-  void CheckSafepoint() {
-    MonitorLocker ml(monitor_);
-    CheckSafepointLocked();
-  }
-
-  bool AtSafepoint() const { return in_rendezvous_; }
-  Thread* Schedule(Isolate* isolate, bool is_mutator, bool bypass_safepoint);
-  void Unschedule(Thread* thread, bool is_mutator, bool bypass_safepoint);
   void VisitObjectPointers(ObjectPointerVisitor* visitor, bool validate_frames);
   void PrepareForGC();
 
  private:
-  void AddThreadToActiveList(Thread* thread);
-  void RemoveThreadFromActiveList(Thread* thread);
-  Thread* GetThreadFromFreelist(Isolate* isolate);
-  void ReturnThreadToFreelist(Thread* thread);
+  Thread* active_list() const { return active_list_; }
+  Monitor* threads_lock() const { return threads_lock_; }
 
-  // Note: Lock should be taken before this function is called.
-  void CheckSafepointLocked();
+  Thread* GetFreeThreadLocked(Isolate* isolate, bool is_mutator);
+  void ReturnThreadLocked(bool is_mutator, Thread* thread);
+  void AddToActiveListLocked(Thread* thread);
+  void RemoveFromActiveListLocked(Thread* thread);
+  Thread* GetFromFreelistLocked(Isolate* isolate);
+  void ReturnToFreelistLocked(Thread* thread);
 
-  // Returns the number threads that are scheduled on this isolate.
-  // Note: Lock should be taken before this function is called.
-  intptr_t CountScheduledLocked();
-
-  Monitor* monitor_;  // All access is synchronized through this monitor.
+  // This monitor protects the threads list for an isolate, it is used whenever
+  // we need to iterate over threads (both active and free) in an isolate.
+  Monitor* threads_lock_;
   Thread* active_list_;  // List of active threads in the isolate.
   Thread* free_list_;  // Free list of Thread objects that can be reused.
+
   // TODO(asiva): Currently we treat a mutator thread as a special thread
   // and always schedule execution of Dart code on the same mutator thread
   // object. The ApiLocalScope has been made thread specific but we still
@@ -89,12 +59,8 @@
   // added.
   Thread* mutator_thread_;
 
-  // Safepoint rendezvous state.
-  bool in_rendezvous_;    // A safepoint rendezvous request is in progress.
-  intptr_t remaining_;    // Number of threads yet to reach their safepoint.
-  int64_t round_;         // Counter, to prevent missing updates to remaining_
-                          // (see comments in CheckSafepointLocked).
-
+  friend class Isolate;
+  friend class SafepointHandler;
   DISALLOW_COPY_AND_ASSIGN(ThreadRegistry);
 };
 
diff --git a/runtime/vm/thread_test.cc b/runtime/vm/thread_test.cc
index f619d51..95ea190 100644
--- a/runtime/vm/thread_test.cc
+++ b/runtime/vm/thread_test.cc
@@ -7,8 +7,9 @@
 #include "vm/lockers.h"
 #include "vm/unit_test.h"
 #include "vm/profiler.h"
+#include "vm/safepoint.h"
+#include "vm/stack_frame.h"
 #include "vm/thread_pool.h"
-#include "vm/thread_registry.h"
 
 namespace dart {
 
@@ -172,7 +173,7 @@
 };
 
 
-TEST_CASE(ManyTasksWithZones) {
+VM_TEST_CASE(ManyTasksWithZones) {
   const int kTaskCount = 100;
   Monitor sync[kTaskCount];
   bool done[kTaskCount];
@@ -208,7 +209,7 @@
   Isolate* orig = Thread::Current()->isolate();
   Zone* orig_zone = Thread::Current()->zone();
   char* orig_str = orig_zone->PrintToString("foo");
-  Thread::ExitIsolate();
+  Dart_ExitIsolate();
   // Create and enter a new isolate.
   Dart_CreateIsolate(
       NULL, NULL, bin::isolate_snapshot_buffer, NULL, NULL, NULL);
@@ -226,7 +227,7 @@
     EXPECT(zone1 != orig_zone);
   }
   Dart_ShutdownIsolate();
-  Thread::EnterIsolate(orig);
+  Dart_EnterIsolate(reinterpret_cast<Dart_Isolate>(orig));
   // Original zone should be preserved.
   EXPECT_EQ(orig_zone, Thread::Current()->zone());
   EXPECT_STREQ("foo", orig_str);
@@ -244,12 +245,12 @@
   static const intptr_t kTaskCount;
 
   SafepointTestTask(Isolate* isolate,
-                    Mutex* mutex,
+                    Monitor* monitor,
                     intptr_t* expected_count,
                     intptr_t* total_done,
                     intptr_t* exited)
     : isolate_(isolate),
-      mutex_(mutex),
+      monitor_(monitor),
       expected_count_(expected_count),
       total_done_(total_done),
       exited_(exited),
@@ -258,11 +259,11 @@
   virtual void Run() {
     Thread::EnterIsolateAsHelper(isolate_);
     {
-      MutexLocker ml(mutex_);
+      MonitorLocker ml(monitor_);
       ++*expected_count_;
     }
-    for (int i = 0; ; ++i) {
-      Thread* thread = Thread::Current();
+    Thread* thread = Thread::Current();
+    for (int i = reinterpret_cast<intptr_t>(thread); ; ++i) {
       StackZone stack_zone(thread);
       Zone* zone = thread->zone();
       HANDLESCOPE(thread);
@@ -270,23 +271,23 @@
       Smi& smi = Smi::Handle(zone, Smi::New(kUniqueSmi));
       if ((i % 100) != 0) {
         // Usually, we just cooperate.
-        isolate_->thread_registry()->CheckSafepoint();
+        TransitionVMToBlocked transition(thread);
       } else {
         // But occasionally, organize a rendezvous.
-        isolate_->thread_registry()->SafepointThreads();
+        SafepointOperationScope safepoint_scope(thread);
         ObjectCounter counter(isolate_, &smi);
         isolate_->IterateObjectPointers(
             &counter,
             StackFrameIterator::kValidateFrames);
         {
-          MutexLocker ml(mutex_);
+          MonitorLocker ml(monitor_);
           EXPECT_EQ(*expected_count_, counter.count());
         }
         UserTag& tag = UserTag::Handle(zone, isolate_->current_tag());
         if (tag.raw() != isolate_->default_tag()) {
           String& label = String::Handle(zone, tag.label());
           EXPECT(label.Equals("foo"));
-          MutexLocker ml(mutex_);
+          MonitorLocker ml(monitor_);
           if (*expected_count_ == kTaskCount && !local_done_) {
             // Success for the first time! Remember that we are done, and
             // update the total count.
@@ -294,11 +295,10 @@
             ++*total_done_;
           }
         }
-        isolate_->thread_registry()->ResumeAllThreads();
       }
       // Check whether everyone is done.
       {
-        MutexLocker ml(mutex_);
+        MonitorLocker ml(monitor_);
         if (*total_done_ == kTaskCount) {
           // Another task might be at SafepointThreads when resuming. Ensure its
           // expectation reflects reality, since we pop our handles here.
@@ -309,14 +309,15 @@
     }
     Thread::ExitIsolateAsHelper();
     {
-      MutexLocker ml(mutex_);
+      MonitorLocker ml(monitor_);
       ++*exited_;
+      ml.Notify();
     }
   }
 
  private:
   Isolate* isolate_;
-  Mutex* mutex_;
+  Monitor* monitor_;
   intptr_t* expected_count_;  // # copies of kUniqueSmi we expect to visit.
   intptr_t* total_done_;      // # tasks that successfully safepointed once.
   intptr_t* exited_;          // # tasks that are no longer running.
@@ -334,13 +335,13 @@
 // - helpers.
 TEST_CASE(SafepointTestDart) {
   Isolate* isolate = Thread::Current()->isolate();
-  Mutex mutex;
+  Monitor monitor;
   intptr_t expected_count = 0;
   intptr_t total_done = 0;
   intptr_t exited = 0;
   for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
     Dart::thread_pool()->Run(new SafepointTestTask(
-        isolate, &mutex, &expected_count, &total_done, &exited));
+        isolate, &monitor, &expected_count, &total_done, &exited));
   }
   // Run Dart code on the main thread long enough to allow all helpers
   // to get their verification done and exit. Use a specific UserTag
@@ -367,7 +368,10 @@
   EXPECT_VALID(result);
   // Ensure we looped long enough to allow all helpers to succeed and exit.
   {
-    MutexLocker ml(&mutex);
+    MonitorLocker ml(&monitor);
+    while (exited != SafepointTestTask::kTaskCount) {
+      ml.Wait();
+    }
     EXPECT_EQ(SafepointTestTask::kTaskCount, total_done);
     EXPECT_EQ(SafepointTestTask::kTaskCount, exited);
   }
@@ -379,30 +383,27 @@
 // - main thread in VM code,
 // organized by
 // - helpers.
-TEST_CASE(SafepointTestVM) {
+VM_TEST_CASE(SafepointTestVM) {
   Isolate* isolate = thread->isolate();
-  Mutex mutex;
+  Monitor monitor;
   intptr_t expected_count = 0;
   intptr_t total_done = 0;
   intptr_t exited = 0;
   for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
     Dart::thread_pool()->Run(new SafepointTestTask(
-        isolate, &mutex, &expected_count, &total_done, &exited));
+        isolate, &monitor, &expected_count, &total_done, &exited));
   }
   String& label = String::Handle(String::New("foo"));
   UserTag& tag = UserTag::Handle(UserTag::New(label));
   isolate->set_current_tag(tag);
-  while (true) {
-    isolate->thread_registry()->CheckSafepoint();
-    MutexLocker ml(&mutex);
-    if (exited == SafepointTestTask::kTaskCount) {
-      break;
-    }
+  MonitorLocker ml(&monitor);
+  while (exited != SafepointTestTask::kTaskCount) {
+    ml.WaitWithSafepointCheck(thread);
   }
 }
 
 
-TEST_CASE(ThreadIterator_Count) {
+VM_TEST_CASE(ThreadIterator_Count) {
   intptr_t thread_count_0 = 0;
   intptr_t thread_count_1 = 0;
 
@@ -430,7 +431,7 @@
 }
 
 
-TEST_CASE(ThreadIterator_FindSelf) {
+VM_TEST_CASE(ThreadIterator_FindSelf) {
   OSThread* current = OSThread::Current();
   EXPECT(OSThread::IsThreadInList(current->join_id()));
 }
@@ -490,36 +491,32 @@
 // organized by
 // - main thread, and
 // - helpers.
-TEST_CASE(SafepointTestVM2) {
+VM_TEST_CASE(SafepointTestVM2) {
   Isolate* isolate = thread->isolate();
-  Mutex mutex;
+  Monitor monitor;
   intptr_t expected_count = 0;
   intptr_t total_done = 0;
   intptr_t exited = 0;
   for (int i = 0; i < SafepointTestTask::kTaskCount; i++) {
     Dart::thread_pool()->Run(new SafepointTestTask(
-        isolate, &mutex, &expected_count, &total_done, &exited));
+        isolate, &monitor, &expected_count, &total_done, &exited));
   }
   bool all_helpers = false;
   do {
-    isolate->thread_registry()->SafepointThreads();
+    SafepointOperationScope safepoint_scope(thread);
     {
-      MutexLocker ml(&mutex);
+      MonitorLocker ml(&monitor);
       if (expected_count == SafepointTestTask::kTaskCount) {
         all_helpers = true;
       }
     }
-    isolate->thread_registry()->ResumeAllThreads();
   } while (!all_helpers);
   String& label = String::Handle(String::New("foo"));
   UserTag& tag = UserTag::Handle(UserTag::New(label));
   isolate->set_current_tag(tag);
-  while (true) {
-    isolate->thread_registry()->CheckSafepoint();
-    MutexLocker ml(&mutex);
-    if (exited == SafepointTestTask::kTaskCount) {
-      break;
-    }
+  MonitorLocker ml(&monitor);
+  while (exited != SafepointTestTask::kTaskCount) {
+    ml.WaitWithSafepointCheck(thread);
   }
 }
 
@@ -562,14 +559,14 @@
 };
 
 
-TEST_CASE(HelperAllocAndGC) {
+VM_TEST_CASE(HelperAllocAndGC) {
   Monitor done_monitor;
   bool done = false;
-  Isolate* isolate = Thread::Current()->isolate();
+  Isolate* isolate = thread->isolate();
   Dart::thread_pool()->Run(new AllocAndGCTask(isolate, &done_monitor, &done));
   {
     while (true) {
-      isolate->thread_registry()->CheckSafepoint();
+      TransitionVMToBlocked transition(thread);
       MonitorLocker ml(&done_monitor);
       if (done) {
         break;
diff --git a/runtime/vm/timeline.cc b/runtime/vm/timeline.cc
index 76d4729..ca6e9a2 100644
--- a/runtime/vm/timeline.cc
+++ b/runtime/vm/timeline.cc
@@ -190,12 +190,14 @@
 
 
 void TimelineEvent::Reset() {
-  set_event_type(kNone);
+  state_ = 0;
   thread_ = OSThread::kInvalidThreadId;
   isolate_id_ = ILLEGAL_PORT;
   category_ = "";
   label_ = NULL;
   FreeArguments();
+  set_pre_serialized_json(false);
+  set_event_type(kNone);
 }
 
 
@@ -367,7 +369,7 @@
 void TimelineEvent::Init(EventType event_type,
                          const char* label) {
   ASSERT(label != NULL);
-  set_event_type(event_type);
+  state_ = 0;
   timestamp0_ = 0;
   timestamp1_ = 0;
   OSThread* os_thread = OSThread::Current();
@@ -381,6 +383,8 @@
   }
   label_ = label;
   FreeArguments();
+  set_pre_serialized_json(false);
+  set_event_type(event_type);
 }
 
 
@@ -717,6 +721,7 @@
   TimelineEvent* event = stream()->StartEvent();
   if (event == NULL) {
     // Stream is now disabled.
+    set_enabled(false);
     return;
   }
   ASSERT(event != NULL);
@@ -733,6 +738,7 @@
   TimelineEvent* event = stream()->StartEvent();
   if (event == NULL) {
     // Stream is now disabled.
+    set_enabled(false);
     return;
   }
   ASSERT(event != NULL);
@@ -1156,17 +1162,35 @@
   return head_;
 }
 
+static int TimelineEventBlockCompare(TimelineEventBlock* const* a,
+                                     TimelineEventBlock* const* b) {
+  return (*a)->LowerTimeBound() - (*b)->LowerTimeBound();
+}
+
 
 void TimelineEventEndlessRecorder::PrintJSONEvents(
     JSONArray* events,
     TimelineEventFilter* filter) {
   MutexLocker ml(&lock_);
+  // Collect all interesting blocks.
+  MallocGrowableArray<TimelineEventBlock*> blocks(8);
   TimelineEventBlock* current = head_;
   while (current != NULL) {
-    if (!filter->IncludeBlock(current)) {
-      current = current->next();
-      continue;
+    if (filter->IncludeBlock(current)) {
+      blocks.Add(current);
     }
+    current = current->next();
+  }
+  // Bail early.
+  if (blocks.length() == 0) {
+    return;
+  }
+  // Sort the interesting blocks so that blocks with earlier events are
+  // outputted first.
+  blocks.Sort(TimelineEventBlockCompare);
+  // Output blocks in sorted order.
+  for (intptr_t block_idx = 0; block_idx < blocks.length(); block_idx++) {
+    current = blocks[block_idx];
     intptr_t length = current->length();
     for (intptr_t i = 0; i < length; i++) {
       TimelineEvent* event = current->At(i);
@@ -1176,7 +1200,6 @@
         events->AddValue(event);
       }
     }
-    current = current->next();
   }
 }
 
diff --git a/runtime/vm/timeline.h b/runtime/vm/timeline.h
index 168956a..a229acf 100644
--- a/runtime/vm/timeline.h
+++ b/runtime/vm/timeline.h
@@ -94,7 +94,6 @@
   // Keep in sync with StateBits below.
   enum EventType {
     kNone,
-    kSerializedJSON,  // Events from Dart code.
     kBegin,
     kEnd,
     kDuration,
@@ -283,9 +282,9 @@
     kNextBit = 5,
   };
 
-  class EventTypeField : public BitField<EventType, kEventTypeBit, 4> {};
+  class EventTypeField : public BitField<uword, EventType, kEventTypeBit, 4> {};
   class PreSerializedJSON :
-      public BitField<bool, kPreSerializedJSON, 1> {};
+      public BitField<uword, bool, kPreSerializedJSON, 1> {};
 
   int64_t timestamp0_;
   int64_t timestamp1_;
@@ -387,6 +386,10 @@
     return enabled_;
   }
 
+  void set_enabled(bool enabled) {
+    enabled_ = enabled;
+  }
+
   const char* label() const {
     return label_;
   }
@@ -530,7 +533,6 @@
   void Finish();
 
   friend class Thread;
-  friend class ThreadRegistry;
   friend class TimelineEventRecorder;
   friend class TimelineEventRingRecorder;
   friend class TimelineEventEndlessRecorder;
diff --git a/runtime/vm/token.cc b/runtime/vm/token.cc
index 504b6d9..b6a34ce 100644
--- a/runtime/vm/token.cc
+++ b/runtime/vm/token.cc
@@ -77,22 +77,4 @@
   return (token == kBIT_NOT) || (token == kNEGATE);
 }
 
-
-const char* ClassifyingTokenPositions::ToCString(intptr_t token_pos) {
-  ASSERT(token_pos < Token::kMinSourcePos);
-  COMPILE_ASSERT(ClassifyingTokenPositions::kPrivate ==
-                 (Token::kNoSourcePos - 1));
-  COMPILE_ASSERT(kLast < kPrivate);
-  switch (token_pos) {
-    case Token::kNoSourcePos: return "NoSource";
-#define DEFINE_CASE(name, value)                                               \
-    case value: return #name;
-    CLASSIFYING_TOKEN_POSITIONS(DEFINE_CASE);
-#undef DEFINE_CASE
-    default:
-      UNIMPLEMENTED();
-      return NULL;
-  }
-}
-
 }  // namespace dart
diff --git a/runtime/vm/token.h b/runtime/vm/token.h
index 39659d9..6ddf17b 100644
--- a/runtime/vm/token.h
+++ b/runtime/vm/token.h
@@ -196,53 +196,6 @@
 
 class String;
 
-// The token space is organized as follows:
-//
-// Sentinel values start at -1 and move towards negative infinity:
-// kNoSourcePos                -> -1
-// ClassifyingTokenPositions 1 -> -1 - 1
-// ClassifyingTokenPositions N -> -1 - N
-//
-// Synthetically created AstNodes are given real source positions but encoded
-// as negative numbers from [kSmiMin32, -1 - N]. For example:
-//
-// A source position of 0 in a synthetic AstNode would be encoded as -2 - N.
-// A source position of 1 in a synthetic AstNode would be encoded as -3 - N.
-//
-// All other AstNodes are given real source positions encoded as positive
-// integers.
-//
-// This organization allows for ~1 billion token positions.
-//
-// NOTE: While token positions are passed around as an intptr_t they are encoded
-// into the snapshot as an int32_t.
-
-// These token positions are used to classify instructions that can't be
-// directly tied to an actual source position.
-#define CLASSIFYING_TOKEN_POSITIONS(V)                                         \
-    V(Private, -2)                                                             \
-    V(Box, -3)                                                                 \
-    V(ParallelMove, -4)                                                        \
-    V(TempMove, -5)                                                            \
-    V(Constant, -6)                                                            \
-    V(PushArgument, -7)                                                        \
-    V(ControlFlow, -8)                                                         \
-    V(Context, -9)                                                             \
-    V(MethodExtractor, -10)                                                    \
-    V(Last, -11)   // Always keep this at the end.
-
-
-class ClassifyingTokenPositions : public AllStatic {
- public:
-#define DEFINE_VALUES(name, value)                                             \
-  static const intptr_t k##name = value;
-  CLASSIFYING_TOKEN_POSITIONS(DEFINE_VALUES);
-#undef DEFINE_VALUES
-
-  static const char* ToCString(intptr_t token_pos);
-};
-
-
 class Token {
  public:
 #define T(t, s, p, a) t,
@@ -259,78 +212,6 @@
     kPseudoKeyword   = 1 << 1,
   };
 
-  // Token position constants.
-  static const intptr_t kNoSourcePos = -1;
-  static const intptr_t kMinSourcePos = 0;
-  static const intptr_t kMaxSourcePos =
-      kSmiMax32 - (-ClassifyingTokenPositions::kLast) - 2;
-
-  // Is |token_pos| a classifying sentinel source position?
-  static bool IsClassifying(intptr_t token_pos) {
-    return (token_pos >= ClassifyingTokenPositions::kPrivate) &&
-           (token_pos <= ClassifyingTokenPositions::kLast);
-  }
-
-  // Is |token_pos| a synthetic source position?
-  static bool IsSynthetic(intptr_t token_pos) {
-    if (token_pos >= kMinSourcePos) {
-      return false;
-    }
-    if (token_pos < ClassifyingTokenPositions::kLast) {
-      return true;
-    }
-    return false;
-  }
-
-  // Is |token_pos| the no source position sentinel?
-  static bool IsNoSource(intptr_t token_pos) {
-    return token_pos == kNoSourcePos;
-  }
-
-  // Is |token_pos| a real source position?
-  static bool IsReal(intptr_t token_pos) {
-    return token_pos >= kMinSourcePos;
-  }
-
-  // Is |token_pos| a source position?
-  static bool IsSourcePosition(intptr_t token_pos) {
-    return IsReal(token_pos) || IsNoSource(token_pos) || IsSynthetic(token_pos);
-  }
-
-  // Is |token_pos| a debug pause source position?
-  static bool IsDebugPause(intptr_t token_pos) {
-    return IsReal(token_pos);
-  }
-
-  // Encode |token_pos| into a synthetic source position.
-  static intptr_t ToSynthetic(intptr_t token_pos) {
-    if (IsClassifying(token_pos) || IsNoSource(token_pos)) {
-      return token_pos;
-    }
-    if (IsSynthetic(token_pos)) {
-      return token_pos;
-    }
-    ASSERT(!IsSynthetic(token_pos));
-    const intptr_t value = (ClassifyingTokenPositions::kLast - 1) - token_pos;
-    ASSERT(IsSynthetic(value));
-    ASSERT(value < ClassifyingTokenPositions::kLast);
-    return value;
-  }
-
-  // Decode |token_pos| from a synthetic source position.
-  static intptr_t FromSynthetic(intptr_t token_pos) {
-    if (IsClassifying(token_pos) || IsNoSource(token_pos)) {
-      return token_pos;
-    }
-    if (!IsSynthetic(token_pos)) {
-      return token_pos;
-    }
-    ASSERT(IsSynthetic(token_pos));
-    const intptr_t value = -token_pos + (ClassifyingTokenPositions::kLast - 1);
-    ASSERT(!IsSynthetic(value));
-    return value;
-  }
-
   static const Kind kFirstKeyword = kABSTRACT;
   static const Kind kLastKeyword = kWITH;
   static const int kNumKeywords = kLastKeyword - kFirstKeyword + 1;
diff --git a/runtime/vm/token_position.cc b/runtime/vm/token_position.cc
new file mode 100644
index 0000000..a6490cd
--- /dev/null
+++ b/runtime/vm/token_position.cc
@@ -0,0 +1,63 @@
+// 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 "vm/token_position.h"
+
+#include "vm/object.h"
+
+namespace dart {
+
+
+TokenPosition TokenPosition::SnapshotDecode(int32_t value) {
+  return TokenPosition(static_cast<intptr_t>(value));
+}
+
+
+int32_t TokenPosition::SnapshotEncode() {
+  return static_cast<int32_t>(value_);
+}
+
+
+bool TokenPosition::IsSynthetic() const {
+  if (value_ >= kMinSourcePos) {
+    return false;
+  }
+  if (value_ < kLast.value()) {
+    return true;
+  }
+  return false;
+}
+
+
+#define DEFINE_VALUES(name, value)                                             \
+const TokenPosition TokenPosition::k##name = TokenPosition(value);
+  SENTINEL_TOKEN_DESCRIPTORS(DEFINE_VALUES);
+#undef DEFINE_VALUES
+const TokenPosition TokenPosition::kMinSource =
+    TokenPosition(kMinSourcePos);
+
+const TokenPosition TokenPosition::kMaxSource =
+    TokenPosition(kMaxSourcePos);
+
+
+const char* TokenPosition::ToCString() const {
+  switch (value_) {
+#define DEFINE_CASE(name, value)                                               \
+    case value: return #name;
+    SENTINEL_TOKEN_DESCRIPTORS(DEFINE_CASE);
+#undef DEFINE_CASE
+    default: {
+      Zone* zone = Thread::Current()->zone();
+      ASSERT(zone != NULL);
+      if (IsSynthetic()) {
+        // TODO(johnmccutchan): Print synthetic positions differently.
+        return FromSynthetic().ToCString();
+      } else {
+        return OS::SCreate(zone, "%d", value_);
+      }
+    }
+  }
+}
+
+}  // namespace dart
diff --git a/runtime/vm/token_position.h b/runtime/vm/token_position.h
new file mode 100644
index 0000000..b36d58a
--- /dev/null
+++ b/runtime/vm/token_position.h
@@ -0,0 +1,204 @@
+// 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.
+
+#ifndef VM_TOKEN_POSITION_H_
+#define VM_TOKEN_POSITION_H_
+
+#include "platform/utils.h"
+#include "vm/allocation.h"
+
+namespace dart {
+
+// The token space is organized as follows:
+//
+// Sentinel values start at -1 and move towards negative infinity:
+// kNoSourcePos                -> -1
+// ClassifyingTokenPositions 1 -> -1 - 1
+// ClassifyingTokenPositions N -> -1 - N
+//
+// Synthetically created AstNodes are given real source positions but encoded
+// as negative numbers from [kSmiMin32, -1 - N]. For example:
+//
+// A source position of 0 in a synthetic AstNode would be encoded as -2 - N.
+// A source position of 1 in a synthetic AstNode would be encoded as -3 - N.
+//
+// All other AstNodes are given real source positions encoded as positive
+// integers.
+//
+// This organization allows for ~1 billion token positions.
+
+#define SENTINEL_TOKEN_DESCRIPTORS(V)                                          \
+    V(NoSource, -1)                                                            \
+    V(Box, -2)                                                                 \
+    V(ParallelMove, -3)                                                        \
+    V(TempMove, -4)                                                            \
+    V(Constant, -5)                                                            \
+    V(PushArgument, -6)                                                        \
+    V(ControlFlow, -7)                                                         \
+    V(Context, -8)                                                             \
+    V(MethodExtractor, -9)                                                     \
+    V(Last, -10)   // Always keep this at the end.
+
+// A token position representing a debug safe source (real) position,
+// non-debug safe source (synthetic) positions, or a classifying value used
+// by the profiler.
+class TokenPosition {
+ public:
+  TokenPosition()
+      : value_(kNoSource.value()) {
+  }
+
+  explicit TokenPosition(intptr_t value)
+      : value_(value) {
+  }
+
+  bool operator==(const TokenPosition& b) const {
+    return value() == b.value();
+  }
+
+  bool operator!=(const TokenPosition& b) const {
+    return !(*this == b);
+  }
+
+  bool operator<(const TokenPosition& b) const {
+    // TODO(johnmccutchan): Assert that this is a source position.
+    return value() < b.value();
+  }
+
+  bool operator>(const TokenPosition& b) const {
+    // TODO(johnmccutchan): Assert that this is a source position.
+    return b < *this;
+  }
+
+  bool operator<=(const TokenPosition& b) {
+    // TODO(johnmccutchan): Assert that this is a source position.
+    return !(*this > b);
+  }
+
+  bool operator>=(const TokenPosition& b) {
+    // TODO(johnmccutchan): Assert that this is a source position.
+    return !(*this < b);
+  }
+
+  static const intptr_t kMaxSentinelDescriptors = 64;
+
+#define DECLARE_VALUES(name, value)                                            \
+  static const TokenPosition k##name;
+  SENTINEL_TOKEN_DESCRIPTORS(DECLARE_VALUES);
+#undef DECLARE_VALUES
+  static const TokenPosition kMinSource;
+  static const TokenPosition kMaxSource;
+
+  // Decode from a snapshot.
+  static TokenPosition SnapshotDecode(int32_t value);
+
+  // Encode for writing into a snapshot.
+  int32_t SnapshotEncode();
+
+  // Increment the token position.
+  TokenPosition Next() {
+    ASSERT(IsReal());
+    value_++;
+    return *this;
+  }
+
+  // The raw value.
+  // TODO(johnmccutchan): Make this private.
+  intptr_t value() const {
+    return value_;
+  }
+
+  // Return the source position.
+  intptr_t Pos() const {
+    if (IsSynthetic()) {
+      return FromSynthetic().Pos();
+    }
+    return value_;
+  }
+
+  // Token position constants.
+  static const intptr_t kNoSourcePos = -1;
+  static const intptr_t kMinSourcePos = 0;
+  static const intptr_t kMaxSourcePos = kSmiMax32 - kMaxSentinelDescriptors - 2;
+
+  // Is |this| a classifying sentinel source position?
+  // Classifying positions are used by the profiler to group instructions whose
+  // cost isn't naturally attributable to a source location.
+  bool IsClassifying() const {
+    return (value_ >= kBox.value()) && (value_ <= kLast.value());
+  }
+
+  // Is |this| the no source position sentinel?
+  bool IsNoSource() const {
+    return *this == kNoSource;
+  }
+
+  // Is |this| a synthetic source position?
+  // Synthetic source positions are used by the profiler to attribute ticks to a
+  // pieces of source, but ignored by the debugger as potential breakpoints.
+  bool IsSynthetic() const;
+
+  // Is |this| a real source position?
+  bool IsReal() const {
+    return value_ >= kMinSourcePos;
+  }
+
+  // Is |this| a source position?
+  bool IsSourcePosition() const {
+    return IsReal() || IsNoSource() || IsSynthetic();
+  }
+
+  // Is |this| a debug pause source position?
+  bool IsDebugPause() const {
+    // Sanity check some values here.
+    ASSERT(kNoSource.value() == kNoSourcePos);
+    ASSERT(kLast.value() < kNoSource.value());
+    ASSERT(kLast.value() > -kMaxSentinelDescriptors);
+    return IsReal();
+  }
+
+  // Convert |this| into a synthetic source position. Sentinel values remain
+  // unchanged.
+  TokenPosition ToSynthetic() const {
+    const intptr_t value = value_;
+    if (IsClassifying() || IsNoSource()) {
+      return *this;
+    }
+    if (IsSynthetic()) {
+      return *this;
+    }
+    const TokenPosition synthetic_value =
+        TokenPosition((kLast.value() - 1) - value);
+    ASSERT(synthetic_value.IsSynthetic());
+    ASSERT(synthetic_value.value() < kLast.value());
+    return synthetic_value;
+  }
+
+  // Convert |this| from a synthetic source position. Sentinel values remain
+  // unchanged.
+  TokenPosition FromSynthetic() const {
+    const intptr_t synthetic_value = value_;
+    if (IsClassifying() || IsNoSource()) {
+      return *this;
+    }
+    if (!IsSynthetic()) {
+      return *this;
+    }
+    const TokenPosition value =
+        TokenPosition(-synthetic_value + (kLast.value() - 1));
+    ASSERT(!value.IsSynthetic());
+    return value;
+  }
+
+  const char* ToCString() const;
+
+ private:
+  int32_t value_;
+
+  DISALLOW_ALLOCATION();
+};
+
+}  // namespace dart
+
+#endif  // VM_TOKEN_POSITION_H_
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 2861fab..05d8d3f 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -200,12 +200,15 @@
 void AssemblerTest::Assemble() {
   const String& function_name = String::ZoneHandle(Symbols::New(name_));
   const Class& cls = Class::ZoneHandle(
-      Class::New(function_name, Script::Handle(), 0));
+      Class::New(function_name,
+                 Script::Handle(),
+                 TokenPosition::kMinSource));
   const Library& lib = Library::ZoneHandle(Library::New(function_name));
   cls.set_library(lib);
   Function& function = Function::ZoneHandle(
       Function::New(function_name, RawFunction::kRegularFunction,
-                    true, false, false, false, false, cls, 0));
+                    true, false, false, false, false, cls,
+                    TokenPosition::kMinSource));
   code_ = Code::FinalizeCode(function, assembler_);
   if (FLAG_disassemble) {
     OS::Print("Code for test '%s' {\n", name_);
@@ -220,7 +223,7 @@
 
 CodeGenTest::CodeGenTest(const char* name)
   : function_(Function::ZoneHandle()),
-    node_sequence_(new SequenceNode(0,
+    node_sequence_(new SequenceNode(TokenPosition::kMinSource,
                                     new LocalScope(NULL, 0, 0))),
     default_parameter_values_(new ZoneGrowableArray<const Instance*> ()) {
   ASSERT(name != NULL);
@@ -228,10 +231,11 @@
   // Add function to a class and that class to the class dictionary so that
   // frame walking can be used.
   const Class& cls = Class::ZoneHandle(
-       Class::New(function_name, Script::Handle(), 0));
+       Class::New(function_name, Script::Handle(),
+                  TokenPosition::kMinSource));
   function_ = Function::New(
       function_name, RawFunction::kRegularFunction,
-      true, false, false, false, false, cls, 0);
+      true, false, false, false, false, cls, TokenPosition::kMinSource);
   function_.set_result_type(Type::Handle(Type::DynamicType()));
   const Array& functions = Array::Handle(Array::New(1));
   functions.SetAt(0, function_);
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index a8b063a..8e6267e 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -27,8 +27,29 @@
   static const dart::TestCase kRegister##name(Dart_Test##name, #name);         \
   void Dart_Test##name()
 
+// The VM_TEST_CASE macro is used for tests that need an isolate and zone
+// in order to test its functionality. This macro is used for tests that
+// are implemented using the VM code directly and do not use the Dart API
+// for calling into the VM. The safepoint execution state of threads using
+// this macro is transitioned from kThreadInNative to kThreadInVM.
+#define VM_TEST_CASE(name)                                                     \
+  static void Dart_TestHelper##name(Thread* thread);                           \
+  UNIT_TEST_CASE(name)                                                         \
+  {                                                                            \
+    TestIsolateScope __test_isolate__;                                         \
+    Thread* __thread__ = Thread::Current();                                    \
+    ASSERT(__thread__->isolate() == __test_isolate__.isolate());               \
+    TransitionNativeToVM transition(__thread__);                               \
+    StackZone __zone__(__thread__);                                            \
+    HandleScope __hs__(__thread__);                                            \
+    Dart_TestHelper##name(__thread__);                                         \
+  }                                                                            \
+  static void Dart_TestHelper##name(Thread* thread)
+
 // The TEST_CASE macro is used for tests that need an isolate and zone
-// in order to test its functionality.
+// in order to test its functionality. This macro is used for tests that
+// are implemented using the Dart API for calling into the VM. The safepoint
+// execution state of threads using this macro remains kThreadNative.
 #define TEST_CASE(name)                                                        \
   static void Dart_TestHelper##name(Thread* thread);                           \
   UNIT_TEST_CASE(name)                                                         \
@@ -57,7 +78,7 @@
 // C++ callee-saved registers are not preserved. Arguments may be passed in.
 #define ASSEMBLER_TEST_RUN(name, test)                                         \
   static void AssemblerTestRun##name(AssemblerTest* test);                     \
-  TEST_CASE(name) {                                                            \
+  VM_TEST_CASE(name) {                                                         \
     Assembler __assembler__;                                                   \
     AssemblerTest test(""#name, &__assembler__);                               \
     AssemblerTestGenerate##name(test.assembler());                             \
@@ -80,7 +101,7 @@
 // Pass the name of test and the expected results as RawObject.
 #define CODEGEN_TEST_RUN(name, expected)                                       \
   static void CodeGenTestRun##name(const Function& function);                  \
-  TEST_CASE(name) {                                                            \
+  VM_TEST_CASE(name) {                                                         \
     CodeGenTest __test__(""#name);                                             \
     CodeGenTestGenerate##name(&__test__);                                      \
     __test__.Compile();                                                        \
@@ -100,7 +121,7 @@
 // and evaluate its result.
 #define CODEGEN_TEST_RAW_RUN(name, function)                                   \
   static void CodeGenTestRun##name(const Function& function);                  \
-  TEST_CASE(name) {                                                            \
+  VM_TEST_CASE(name) {                                                         \
     CodeGenTest __test__(""#name);                                             \
     CodeGenTestGenerate##name(&__test__);                                      \
     __test__.Compile();                                                        \
@@ -113,7 +134,7 @@
 // The first one may reference the Function object generated by the second one.
 #define CODEGEN_TEST2_RUN(name1, name2, expected)                              \
   static void CodeGenTestRun##name1(const Function& function);                 \
-  TEST_CASE(name1) {                                                           \
+  VM_TEST_CASE(name1) {                                                        \
     /* Generate code for name2 */                                              \
     CodeGenTest __test2__(""#name2);                                           \
     CodeGenTestGenerate##name2(&__test2__);                                    \
diff --git a/runtime/vm/vm_sources.gypi b/runtime/vm/vm_sources.gypi
index aa1ee40..7570631 100644
--- a/runtime/vm/vm_sources.gypi
+++ b/runtime/vm/vm_sources.gypi
@@ -258,6 +258,7 @@
     'json_test.cc',
     'locations.cc',
     'locations.h',
+    'lockers.cc',
     'lockers.h',
     'log_test.cc',
     'log.cc',
@@ -384,6 +385,8 @@
     'runtime_entry_mips.cc',
     'runtime_entry.cc',
     'runtime_entry_x64.cc',
+    'safepoint.cc',
+    'safepoint.h',
     'scanner.cc',
     'scanner.h',
     'scanner_test.cc',
@@ -472,6 +475,8 @@
     'timer.h',
     'token.cc',
     'token.h',
+    'token_position.cc',
+    'token_position.h',
     'trace_buffer.cc',
     'trace_buffer.h',
     'trace_buffer_test.cc',
diff --git a/runtime/vm/weak_code.cc b/runtime/vm/weak_code.cc
index 7c817d0..53a1d40 100644
--- a/runtime/vm/weak_code.cc
+++ b/runtime/vm/weak_code.cc
@@ -8,12 +8,13 @@
 
 #include "vm/code_generator.h"
 #include "vm/code_patcher.h"
-#include "vm/compiler.h"
 #include "vm/object.h"
 #include "vm/stack_frame.h"
 
 namespace dart {
 
+DECLARE_FLAG(bool, precompilation);
+
 bool WeakCodeReferences::HasCodes() const {
   return !array_.IsNull() && (array_.Length() > 0);
 }
@@ -67,7 +68,7 @@
   if (code_objects.IsNull()) {
     return;
   }
-  ASSERT(Compiler::allow_recompilation());
+  ASSERT(!FLAG_precompilation);
   UpdateArrayTo(Object::null_array());
   // Disable all code on stack.
   Code& code = Code::Handle();
diff --git a/sdk/bin/dart2js b/sdk/bin/dart2js
index 988a6fe..248ab07 100755
--- a/sdk/bin/dart2js
+++ b/sdk/bin/dart2js
@@ -52,17 +52,41 @@
 
 DART2JS="$DART_ROOT/pkg/compiler/lib/src/dart2js.dart"
 
-if [ -z "$DART_CONFIGURATION" ];
-then
-  DART_CONFIGURATION="ReleaseX64"
+if [[ `uname` == 'Darwin' ]]; then
+  OUT_DIR="$DART_ROOT/xcodebuild/"
+else
+  OUT_DIR="$DART_ROOT/out/"
 fi
 
-if [[ `uname` == 'Darwin' ]]; then
-  BUILD_DIR="$DART_ROOT/xcodebuild/$DART_CONFIGURATION"
-else
-  BUILD_DIR="$DART_ROOT/out/$DART_CONFIGURATION"
+if [ -z "$DART_CONFIGURATION" ];
+then
+  DIRS=$( ls "$OUT_DIR" )
+  # list of possible configurations in decreasing desirability
+  CONFIGS=("ReleaseX64" "ReleaseIA32" "DebugX64" "DebugIA32"
+    "ReleaseARM"    "ReleaseARM64"    "ReleaseARMV5TE"    "ReleaseMIPS"
+    "DebugARM"      "DebugARM64"      "DebugARMV5TE"      "DebugMIPS")
+  DART_CONFIGURATION="None"
+  for CONFIG in ${CONFIGS[*]}
+  do
+    for DIR in $DIRS;
+    do
+      if [ "$CONFIG" = "$DIR" ];
+      then
+        # choose most desirable configuration that is available and break
+        DART_CONFIGURATION="$DIR"
+        break 2
+      fi
+    done
+  done
+  if [ "$DART_CONFIGURATION" = "None" ]
+  then
+    echo "No valid dart configuration found in $OUT_DIR"
+    exit 1
+  fi
 fi
 
+BUILD_DIR="$OUT_DIR$DART_CONFIGURATION"
+
 PACKAGE_ROOT="$BUILD_DIR/packages/"
 
 exec "$DART" "${EXTRA_VM_OPTIONS[@]}" "--package-root=$PACKAGE_ROOT" "$DART2JS" "${EXTRA_OPTIONS[@]}" "$@"
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart
index 66c1f0c..eb7519a 100644
--- a/sdk/lib/convert/base64.dart
+++ b/sdk/lib/convert/base64.dart
@@ -270,7 +270,7 @@
 class _AsciiBase64EncoderSink extends _Base64EncoderSink {
   final _Base64Encoder _encoder = new _BufferCachingBase64Encoder();
 
-  final ChunkedConversionSink<String> _sink;
+  final Sink<String> _sink;
 
   _AsciiBase64EncoderSink(this._sink);
 
@@ -684,7 +684,7 @@
 
 class _Base64DecoderSink extends StringConversionSinkBase {
   /** Output sink */
-  final ChunkedConversionSink<List<int>> _sink;
+  final Sink<List<int>> _sink;
   final _Base64Decoder _decoder = new _Base64Decoder();
 
   _Base64DecoderSink(this._sink);
diff --git a/sdk/lib/io/file_impl.dart b/sdk/lib/io/file_impl.dart
index 6b0dc96..5dd559c 100644
--- a/sdk/lib/io/file_impl.dart
+++ b/sdk/lib/io/file_impl.dart
@@ -446,8 +446,8 @@
       var completer = new Completer();
       void read() {
         file.read(_BLOCK_SIZE).then((data) {
-          if (data.length > 0) builder.add(data);
-          if (data.length == _BLOCK_SIZE) {
+          if (data.length > 0) {
+            builder.add(data);
             read();
           } else {
             completer.complete(builder.takeBytes());
@@ -480,7 +480,7 @@
         do {
           data = opened.readSync(_BLOCK_SIZE);
           if (data.length > 0) builder.add(data);
-        } while (data.length == _BLOCK_SIZE);
+        } while (data.length > 0);
         data = builder.takeBytes();
       } else {
         data = opened.readSync(length);
diff --git a/sdk/lib/io/http.dart b/sdk/lib/io/http.dart
index c63d28b..406af67 100644
--- a/sdk/lib/io/http.dart
+++ b/sdk/lib/io/http.dart
@@ -100,7 +100,7 @@
  *     import 'dart:io';
  *     import "dart:isolate";
  *
- *     main() {
+ *     main() async {
  *       SecurityContext context = new SecurityContext();
  *       var chain =
  *           Platform.script.resolve('certificates/server_chain.pem')
@@ -108,8 +108,8 @@
  *       var key =
  *           Platform.script.resolve('certificates/server_key.pem')
  *           .toFilePath();
- *       context.useCertificateChain(chain);
- *       context.usePrivateKey(key, password: 'dartdart');
+ *       await context.useCertificateChain(chain);
+ *       await context.usePrivateKey(key, password: 'dartdart');
  *
  *       HttpServer
  *           .bindSecure(InternetAddress.ANY_IP_V6,
diff --git a/sdk/lib/io/security_context.dart b/sdk/lib/io/security_context.dart
index 48e8111..4675b60 100644
--- a/sdk/lib/io/security_context.dart
+++ b/sdk/lib/io/security_context.dart
@@ -8,7 +8,7 @@
  * The object containing the certificates to trust when making
  * a secure client connection, and the certificate chain and
  * private key to serve from a secure server.
- * 
+ *
  * The [SecureSocket]  and [SecureServer] classes take a SecurityContext
  * as an argument to their connect and bind methods.
  *
@@ -35,13 +35,28 @@
 
   /**
    * Sets the private key for a server certificate or client certificate.
+   *
    * A secure connection using this SecurityContext will use this key with
    * the server or client certificate to sign and decrypt messages.
    * [keyFile] is a PEM file containing an encrypted
    * private key, encrypted with [password].  An unencrypted file can be
    * used, but this is not usual.
+   *
+   * The function returns a [Future] that completes when the key has been added
+   * to the context.
    */
-  void usePrivateKey(String keyFile, {String password});
+  Future usePrivateKey(String keyFile, {String password});
+
+  /**
+   * Sets the private key for a server certificate or client certificate.
+   *
+   * A secure connection using this SecurityContext will use this key with
+   * the server or client certificate to sign and decrypt messages.
+   * [keyBytes] is the contents of a PEM file containing an encrypted
+   * private key, encrypted with [password].  An unencrypted file can be
+   * used, but this is not usual.
+   */
+  void usePrivateKeyBytes(List<int> keyBytes, {String password});
 
   /**
    * Sets the set of trusted X509 certificates used by [SecureSocket]
@@ -65,12 +80,28 @@
   /**
    * Sets the chain of X509 certificates served by [SecureServer]
    * when making secure connections, including the server certificate.
-   * [file] is an PEM file containing X509 certificates, starting with
+   *
+   * [file] is a PEM file containing X509 certificates, starting with
    * the root authority and intermediate authorities forming the signed
    * chain to the server certificate, and ending with the server certificate.
    * The private key for the server certificate is set by [usePrivateKey].
+   *
+   * The function returns a [Future] that completes when the certificate chain
+   * has been set.
    */
-  void useCertificateChain(String file);
+  Future useCertificateChain(String file);
+
+  /**
+   * Sets the chain of X509 certificates served by [SecureServer]
+   * when making secure connections, including the server certificate.
+   *
+   * [chainBytes] is the contents of a PEM file containing X509 certificates,
+   * starting with the root authority and intermediate authorities forming the
+   * signed chain to the server certificate, and ending with the server
+   * certificate. The private key for the server certificate is set by
+   * [usePrivateKey].
+   */
+  void useCertificateChainBytes(List<int> chainBytes);
 
   /**
    * Sets the list of authority names that a [SecureServer] will advertise
diff --git a/sdk/lib/vmservice/asset.dart b/sdk/lib/vmservice/asset.dart
index 8155e8a..b8f6c20 100644
--- a/sdk/lib/vmservice/asset.dart
+++ b/sdk/lib/vmservice/asset.dart
@@ -59,6 +59,17 @@
   String toString() => '$name ($mimeType)';
 }
 
+HashMap<String, Asset> _assets;
+HashMap<String, Asset> get assets {
+  if (_assets == null) {
+    try {
+      _assets = Asset.request();
+    } catch (e) {
+      print('Could not load Observatory assets: $e');
+    }
+  }
+  return _assets;
+}
 
 class _ByteStream {
   final Uint8List bytes;
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index fa7790f..445f5d5 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -21,8 +21,6 @@
 final RawReceivePort isolateLifecyclePort = new RawReceivePort();
 final RawReceivePort scriptLoadPort = new RawReceivePort();
 
-typedef ShutdownCallback();
-
 // These must be kept in sync with the declarations in vm/json_stream.h.
 const kInvalidParams = -32602;
 const kInternalError = -32603;
@@ -62,6 +60,23 @@
   return JSON.encode(response);
 }
 
+const shortDelay = const Duration(milliseconds: 10);
+
+/// Called when the server should be started.
+typedef Future ServerStartCallback();
+
+/// Called when the server should be stopped.
+typedef Future ServerStopCallback();
+
+/// Called when the service is exiting.
+typedef Future CleanupCallback();
+
+/// Hooks that are setup by the embedder.
+class VMServiceEmbedderHooks {
+  static ServerStartCallback serverStart;
+  static ServerStopCallback serverStop;
+  static CleanupCallback cleanup;
+}
 
 class VMService extends MessageRouter {
   static VMService _instance;
@@ -75,8 +90,6 @@
   /// A port used to receive events from the VM.
   final RawReceivePort eventPort;
 
-  ShutdownCallback onShutdown;
-
   void _addClient(Client client) {
     assert(client.streams.isEmpty);
     clients.add(client);
@@ -115,19 +128,26 @@
     }
   }
 
-  void _exit() {
+  Future _exit() async {
+    // Stop the server.
+    if (VMServiceEmbedderHooks.serverStop != null) {
+      await VMServiceEmbedderHooks.serverStop();
+    }
+
+    // Close receive ports.
     isolateLifecyclePort.close();
     scriptLoadPort.close();
+
     // Create a copy of the set as a list because client.disconnect() will
     // alter the connected clients set.
     var clientsList = clients.toList();
     for (var client in clientsList) {
       client.disconnect();
     }
-    // Call embedder shutdown hook after the internal shutdown.
-    if (onShutdown != null) {
-      onShutdown();
+    if (VMServiceEmbedderHooks.cleanup != null) {
+      await VMServiceEmbedderHooks.cleanup();
     }
+    // Notify the VM that we have exited.
     _onExit();
   }
 
@@ -156,13 +176,8 @@
     print('Internal vm-service error: ignoring illegal message: $message');
   }
 
-  void _notSupported(_) {
-    throw new UnimplementedError('Service script loading not supported.');
-  }
-
   VMService._internal()
       : eventPort = isolateLifecyclePort {
-    scriptLoadPort.handler = _notSupported;
     eventPort.handler = messageHandler;
   }
 
@@ -174,17 +189,6 @@
     return _instance;
   }
 
-  void _clientCollection(Message message) {
-    var members = [];
-    var result = {};
-    clients.forEach((client) {
-      members.add(client.toJson());
-    });
-    result['type'] = 'ClientList';
-    result['members'] = members;
-    message.setResponse(JSON.encode(result));
-  }
-
   bool _isAnyClientSubscribed(String streamId) {
     for (var client in clients) {
       if (client.streams.contains(streamId)) {
@@ -293,10 +297,6 @@
       return message.response;
     }
     // TODO(turnidge): Update to json rpc.  BEFORE SUBMIT.
-    if ((message.path.length == 1) && (message.path[0] == 'clients')) {
-      _clientCollection(message);
-      return message.response;
-    }
     if (message.method == '_getCrashDump') {
       return _getCrashDump(message);
     }
@@ -323,12 +323,20 @@
   service.runningIsolates.isolateStartup(port_id, sp, name);
 }
 
+/// Notify the VM that the service is running.
 external void _onStart();
 
+/// Notify the VM that the service is no longer running.
 external void _onExit();
 
+/// Notify the VM that the server's address has changed.
+external void onServerAddressChange(String address);
+
+/// Subscribe to a service stream.
 external bool _vmListenStream(String streamId);
 
+/// Cancel a subscription to a service stream.
 external void _vmCancelStream(String streamId);
 
+/// Get the bytes to the tar archive.
 external Uint8List _requestAssets();
diff --git a/tests/co19/co19-analyzer2.status b/tests/co19/co19-analyzer2.status
index 3c67e8e..603365c 100644
--- a/tests/co19/co19-analyzer2.status
+++ b/tests/co19/co19-analyzer2.status
@@ -288,7 +288,6 @@
 Language/Types/Interface_Types/subtype_t22: StaticWarning # co19 issue 745
 Language/Types/Interface_Types/subtype_t24: StaticWarning # co19 issue 745
 Language/Statements/Assert/type_t07: StaticWarning # Issue 23663
-Language/Statements/Assert/execution_t08: StaticWarning # Issue 23663
 
 # isProtocolHandlerRegistered and unregisterProtocolHandler don't exist
 LayoutTests/fast/dom/navigatorcontentutils/is-protocol-handler-registered_t01: Skip # Please triage this failure.
diff --git a/tests/co19/co19-dart2js.status b/tests/co19/co19-dart2js.status
index f47d3ce..c9f507c 100644
--- a/tests/co19/co19-dart2js.status
+++ b/tests/co19/co19-dart2js.status
@@ -609,6 +609,7 @@
 LibTest/typed_data/Uint8ClampedList/map_A02_t01: Pass, Slow # Please triage this failure.
 
 [ $compiler == dart2js && $runtime == chrome ]
+
 LayoutTests/fast/alignment/parse-align-items_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-align-self_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/alignment/parse-justify-self_t01: RuntimeError # Please triage this failure
@@ -618,10 +619,9 @@
 LayoutTests/fast/animation/request-animation-frame-timestamps-advance_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/animation/request-animation-frame-timestamps_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/animation/request-animation-frame-within-callback_t01: Skip # Times out. Please triage this failure
-LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/backgrounds/background-shorthand-with-backgroundSize-style_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/backgrounds/multiple-backgrounds-computed-style_t01: RuntimeError # co19 issue 14
-LayoutTests/fast/borders/border-radius-child_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/backgrounds/repeat/parsing-background-repeat_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/borders/border-width-percent_t01: RuntimeError # Issue 25155
 LayoutTests/fast/canvas/2d.fillText.gradient_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/2d.text.draw.fill.maxWidth.gradient_t01: RuntimeError # Please triage this failure
@@ -631,7 +631,9 @@
 LayoutTests/fast/canvas/alpha_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-arc-negative-radius_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-as-image-incremental-repaint_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/canvas/canvas-as-image_t01: RuntimeError # co19 issue 19
 LayoutTests/fast/canvas/canvas-blending-text_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/canvas-css-crazy_t01: RuntimeError # co19 issue 19
 LayoutTests/fast/canvas/canvas-currentTransform_t01: RuntimeError # Feature is behind a flag.
 LayoutTests/fast/canvas/canvas-empty-image-pattern_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-getImageData-invalid_t01: RuntimeError # Please triage this failure
@@ -646,14 +648,18 @@
 LayoutTests/fast/canvas/canvas-putImageData_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/canvas-resize-after-paint_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/canvas/canvas-scale-drawImage-shadow_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/crash-set-font_t01: RuntimeError # co19 issue 19
 LayoutTests/fast/canvas/draw-custom-focus-ring_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/getPutImageDataPairTest_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/setWidthResetAfterForcedRender_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/canvas/webgl/bad-arguments-test_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-attributes-alpha-depth-stencil-antialias-t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-lost-restored_t01: Pass, Timeout # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-lost_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/copy-tex-image-and-sub-image-2d_t01: RuntimeError # 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
@@ -735,6 +741,7 @@
 LayoutTests/fast/css-grid-layout/percent-padding-margin-resolution-grid-item_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-grid-layout/percent-resolution-grid-item_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css-grid-layout/place-cell-by-index_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css-intrinsic-dimensions/multicol_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/MarqueeLayoutTest_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/add-remove-stylesheets-at-once-minimal-recalc-style_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/aspect-ratio-inheritance_t01: Pass, RuntimeError # Please triage this failure
@@ -742,10 +749,8 @@
 LayoutTests/fast/css/auto-min-size_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/background-position-serialize_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/background-serialize_t01: RuntimeError # https://github.com/dart-lang/co19/issues/14
-LayoutTests/fast/css/css-selector-text_t01: RuntimeError # co19 Issue 15
-LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/checked-pseudo-selector_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/collapsed-whitespace-reattach-in-style-recalc_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/computed-offset-with-zoom_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/content-language-case-insensitivity_t01: RuntimeError # Issue 23506
 LayoutTests/fast/css/content-language-dynamically-added_t01: RuntimeError # Issue 23506
 LayoutTests/fast/css/content-language-dynamically-removed_t01: RuntimeError # Issue 23506
@@ -756,18 +761,21 @@
 LayoutTests/fast/css/content/content-normal_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/counters/complex-before_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/counters/counter-cssText_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/css-escaped-identifier_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/css-properties-case-insensitive_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/css-selector-text_t01: RuntimeError # co19 Issue 15
 LayoutTests/fast/css/css3-nth-tokens-style_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/cssText-shorthand_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/csstext-of-content-string_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/css/cursor-parsing_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/cursor-parsing-image-set_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/cursor-parsing-quirks_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/cursor-parsing_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/deprecated-flexbox-auto-min-size_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/ex-unit-with-no-x-height_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/first-child-display-change-inverse_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/focus-display-block-inline_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-cache-bug_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/css/font-face-insert-link_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-multiple-ranges-for-unicode-range_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-unicode-range-load_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/css/font-face-unicode-range-monospace_t01: Pass, RuntimeError # Please triage this failure
@@ -824,9 +832,10 @@
 LayoutTests/fast/css/stylesheet-enable-first-alternate-on-load-sheet_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/stylesheet-enable-second-alternate-link_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/transform-origin-parsing_t01: Pass, RuntimeError # Please triage this failure
+LayoutTests/fast/css/unicode-bidi-computed-value_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/css/url-with-multi-byte-unicode-escape_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css/webkit-keyframes-errors_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css/word-break-user-modify-allowed-values_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/css/url-with-multi-byte-unicode-escape_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-color_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-line_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css3-text/css3-text-decoration/getComputedStyle/getComputedStyle-text-decoration-style_t01: RuntimeError # Please triage this failure
@@ -835,7 +844,6 @@
 LayoutTests/fast/css3-text/css3-text-indent/getComputedStyle/getComputedStyle-text-indent_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/css3-text/css3-text-justify/getComputedStyle/getComputedStyle-text-justify_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/52776_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/click-method-on-html-element_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/DOMException/XPathException_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/DOMImplementation/createDocument-namespace-err_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/basic_t01: RuntimeError # Please triage this failure
@@ -845,6 +853,7 @@
 LayoutTests/fast/dom/Document/CaretRangeFromPoint/replace-element_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Document/createElementNS-namespace-err_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Element/attribute-uppercase_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/Element/getBoundingClientRect-getClientRects-relative-to-viewport_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Element/getClientRects_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/Element/setAttributeNS-namespace-err_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLAnchorElement/remove-href-from-focused-anchor_t01: Skip # Times out. Please triage this failure
@@ -873,10 +882,10 @@
 LayoutTests/fast/dom/HTMLLinkElement/link-beforeload-recursive_t01: Skip # Times out. Please triage this failure
 LayoutTests/fast/dom/HTMLLinkElement/resolve-url-on-insertion_t01: RuntimeError # Issue 18010
 LayoutTests/fast/dom/HTMLObjectElement/beforeload-set-text-crash_t01: Skip # Times out. Please triage this failure
+LayoutTests/fast/dom/HTMLObjectElement/form/test1_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/HTMLObjectElement/set-type-to-null-crash_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/HTMLOptionElement/collection-setter-getter_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLOutputElement/dom-settable-token-list_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/dom/HTMLObjectElement/form/test1_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/HTMLScriptElement/async-false-inside-async-false-load_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLScriptElement/async-inline-script_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLScriptElement/async-onbeforeload_t01: RuntimeError # Please triage this failure
@@ -885,7 +894,6 @@
 LayoutTests/fast/dom/HTMLScriptElement/remove-in-beforeload_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLScriptElement/remove-source_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLScriptElement/script-set-src_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/dom/HTMLSelectElement/selected-index-preserved-when-option-text-changes_t01: RuntimeError # Issue 18127
 LayoutTests/fast/dom/HTMLTemplateElement/custom-element-wrapper-gc_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLTemplateElement/innerHTML_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/HTMLTemplateElement/ownerDocumentXHTML_t01: RuntimeError # Please triage this failure
@@ -917,6 +925,7 @@
 LayoutTests/fast/dom/background-shorthand-csstext_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/blur-contenteditable_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/dom/characterdata-api-arguments_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/dom/click-method-on-html-element_t01: RuntimeError # Issue 25155
 LayoutTests/fast/dom/client-width-height-quirks_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/css-selectorText_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/custom/document-register-basic_t01: RuntimeError # Dartium JSInterop failure
@@ -939,6 +948,7 @@
 LayoutTests/fast/dom/navigatorcontentutils/register-protocol-handler_t01: Skip # API not supported.
 LayoutTests/fast/dom/navigatorcontentutils/unregister-protocol-handler_t01: Skip # API not supported.
 LayoutTests/fast/dom/object-plugin-hides-properties_t01: RuntimeError # Issue 25155
+LayoutTests/fast/dom/offset-position-writing-modes_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/option-properties_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/partial-layout-overlay-scrollbars_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/dom/set-innerHTML_t01: RuntimeError # Please triage this failure
@@ -1057,8 +1067,9 @@
 LayoutTests/fast/inline/out-of-flow-objects-and-whitespace-after-empty-inline_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/inline/parent-inline-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/inline/positioned-element-padding-contributes-width_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
+LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
+LayoutTests/fast/innerHTML/javascript-url_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/layers/normal-flow-hit-test_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/layers/zindex-hit-test_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/loader/about-blank-hash-change_t01: Skip # Times out. Please triage this failure
@@ -1068,7 +1079,6 @@
 LayoutTests/fast/loader/scroll-position-restored-on-back_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/loader/scroll-position-restored-on-reload-at-load-event_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/loader/stateobjects/replacestate-in-onunload_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/innerHTML/innerHTML-uri-resolution_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/masking/parsing-clip-path-iri_t01: RuntimeError # co19 issue 14
 LayoutTests/fast/masking/parsing-clip-path-shape_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/masking/parsing-mask-source-type_t01: RuntimeError # Please triage this failure
@@ -1086,7 +1096,6 @@
 LayoutTests/fast/multicol/hit-test-end-of-column-with-line-height_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/hit-test-end-of-column_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/hit-test-float_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/hit-test-gap-between-pages_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/newmulticol/balance-images_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/newmulticol/balance-maxheight_t01: RuntimeError # Please triage this failure
@@ -1100,6 +1109,7 @@
 LayoutTests/fast/multicol/vertical-rl/image-inside-nested-blocks-with-border_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/multicol/widows_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/overflow/replaced-child-100percent-height-inside-fixed-container-with-overflow-auto_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/overflow/scrollbar-restored_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/parser/foster-parent-adopted_t02: RuntimeError # Please triage this failure
 LayoutTests/fast/parser/fragment-parser-doctype_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/parser/innerhtml-with-prefixed-elements_t01: RuntimeError # Please triage this failure
@@ -1131,7 +1141,6 @@
 LayoutTests/fast/sub-pixel/cssom-subpixel-precision_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/sub-pixel/float-containing-block-with-margin_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/sub-pixel/replaced-element-baseline_t01: Pass, RuntimeError # Please triage this failure
-LayoutTests/fast/sub-pixel/table-rows-have-stable-height_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/anonymous-table-section-removed_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/caption-orthogonal-writing-mode-sizing_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/table/col-width-span-expand_t01: RuntimeError # Please triage this failure
@@ -1191,6 +1200,7 @@
 LayoutTests/fast/url/segments_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/url/standard-url_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/writing-mode/auto-sizing-orthogonal-flows_t01: RuntimeError # Please triage this failure
+LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow-scroll_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/writing-mode/flipped-blocks-hit-test-overflow_t01: Pass, RuntimeError # Please triage this failure
 LayoutTests/fast/writing-mode/positionForPoint_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/writing-mode/table-hit-test_t01: RuntimeError # Please triage this failure
@@ -1323,10 +1333,10 @@
 WebPlatformTest/custom-elements/concepts/type_A03_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/concepts/type_A05_t01: RuntimeError # Please triage this failure
 WebPlatformTest/custom-elements/concepts/type_A06_t01: RuntimeError # Please triage this failure
-WebPlatformTest/custom-elements/instantiating/createElement_A02_t01: RuntimeError # Issue 25155
-WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: RuntimeError # Issue 25155
 WebPlatformTest/custom-elements/instantiating/createElementNS_A02_t01: RuntimeError # Issue 25155
 WebPlatformTest/custom-elements/instantiating/createElementNS_A03_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElement_A02_t01: RuntimeError # Issue 25155
+WebPlatformTest/custom-elements/instantiating/createElement_A03_t01: RuntimeError # Issue 25155
 WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t01: RuntimeError # Issue 25155
 WebPlatformTest/custom-elements/instantiating/isAttribute_A01_t02: RuntimeError # Issue 25155
 WebPlatformTest/dom/EventTarget/dispatchEvent_A02_t01: RuntimeError # Please triage this failure
@@ -1377,7 +1387,6 @@
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/cues_t01: Skip # Times out. Please triage this failure
 WebPlatformTest/html/semantics/embedded-content/media-elements/interfaces/TextTrack/mode_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/attributes-common-to-form-controls/formaction_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/forms/textfieldselection/selection_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setRangeText_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/textfieldselection/textfieldselection-setSelectionRange_t01: Pass, RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-button-element/button-validation_t01: RuntimeError # Please triage this failure
@@ -1399,7 +1408,6 @@
 WebPlatformTest/html/semantics/forms/the-input-element/time_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/time_t02: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/type-change-state_t01: RuntimeError # Please triage this failure
-WebPlatformTest/html/semantics/forms/the-input-element/url_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/valueMode_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-input-element/week_t01: RuntimeError # Please triage this failure
 WebPlatformTest/html/semantics/forms/the-meter-element/meter_t01: RuntimeError # Please triage this failure
@@ -1467,9 +1475,9 @@
 WebPlatformTest/shadow-dom/shadow-trees/lower-boundary-encapsulation/test-004_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/dom-tree-accessors-002_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/ownerdocument-002_t01: RuntimeError # Please triage this failure
-WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-005_t01: RuntimeError # Issue 25155
 WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-007_t01: RuntimeError # Issue 25155
+WebPlatformTest/shadow-dom/shadow-trees/upper-boundary-encapsulation/test-009_t01: RuntimeError # Please triage this failure
 WebPlatformTest/webstorage/event_constructor_t01: RuntimeError # Please triage this failure
 WebPlatformTest/webstorage/event_constructor_t02: RuntimeError # Please triage this failure
 
@@ -1564,7 +1572,6 @@
 LayoutTests/fast/canvas/webgl/array-bounds-clamping_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/attrib-location-length-limits_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/buffer-bind-test_t01: RuntimeError # Please triage this failure
-LayoutTests/fast/canvas/webgl/buffer-data-array-buffer_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/canvas-2d-webgl-texture_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/canvas-resize-crash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/canvas-test_t01: RuntimeError # Please triage this failure
@@ -1572,8 +1579,6 @@
 LayoutTests/fast/canvas/webgl/compressed-tex-image_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-destroyed-crash_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/context-lost-restored_t01: RuntimeError # 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/draw-arrays-out-of-bounds_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/draw-elements-out-of-bounds_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/canvas/webgl/draw-webgl-to-canvas-2d_t01: RuntimeError # Please triage this failure
@@ -1643,9 +1648,11 @@
 LayoutTests/fast/text/text-combine-shrink-to-fit_t01: RuntimeError # Please triage this failure
 
 [ $compiler == dart2js && $runtime == chrome && $system != linux ]
+LayoutTests/fast/multicol/hit-test-gap-between-pages-flipped_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Issue 24398
 
 [ $compiler == dart2js && $runtime == chrome && $system == linux]
+LayoutTests/fast/text/international/combining-marks-position_t01: RuntimeError # Please triage this failure
 LayoutTests/fast/xpath/py-dom-xpath/abbreviations_t01: RuntimeError # Dartium JSInterop failure
 
 [ $compiler == dart2js && $runtime == ff ]
@@ -9617,7 +9624,6 @@
 
 [ $compiler == dart2js && $cps_ir ]
 Language/Types/Interface_Types/subtype_t09: Crash # Pending static: JSArray
-Language/Types/Interface_Types/subtype_t39: RuntimeError # Please triage this failure.
 LibTest/collection/ListBase/ListBase_class_A01_t02: Pass, Timeout
 LibTest/core/Invocation/isAccessor_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 LibTest/core/Invocation/isGetter_A01_t01: RuntimeError # Please triage this failure.
@@ -9628,5 +9634,3 @@
 LibTest/core/Invocation/memberName_A01_t01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 LibTest/core/Invocation/namedArguments_A01_t01: RuntimeError # Please triage this failure.
 LibTest/core/Invocation/positionalArguments_A01_t01: RuntimeError # Please triage this failure.
-LibTest/core/Symbol/Symbol_A01_t03: RuntimeError # Please triage this failure.
-LibTest/core/Symbol/Symbol_A01_t05: RuntimeError # Please triage this failure.
diff --git a/tests/compiler/dart2js/sourcemaps/diff_view.dart b/tests/compiler/dart2js/sourcemaps/diff_view.dart
index 0448a7f..b689360 100644
--- a/tests/compiler/dart2js/sourcemaps/diff_view.dart
+++ b/tests/compiler/dart2js/sourcemaps/diff_view.dart
@@ -26,11 +26,15 @@
   List<String> currentOptions = [];
   List<List<String>> options = [currentOptions];
   int argGroup = 0;
+  bool addAnnotations = true;
   for (String arg in args) {
     if (arg == '--') {
       currentOptions = [];
       options.add(currentOptions);
       argGroup++;
+    } else if (arg == '-h') {
+      addAnnotations = false;
+      print('Hiding annotations');
     } else if (arg.startsWith('-o')) {
       out = arg.substring('-o'.length);
     } else if (arg.startsWith('--out=')) {
@@ -60,9 +64,11 @@
   }
 
   print('Compiling ${options1.join(' ')} $filename');
-  CodeLinesResult result1 = await computeCodeLines(options1, filename);
+  CodeLinesResult result1 = await computeCodeLines(
+      options1, filename, addAnnotations: addAnnotations);
   print('Compiling ${options2.join(' ')} $filename');
-  CodeLinesResult result2 = await computeCodeLines(options2, filename);
+  CodeLinesResult result2 = await computeCodeLines(
+      options2, filename, addAnnotations: addAnnotations);
 
   StringBuffer sb = new StringBuffer();
   sb.write('''
@@ -107,21 +113,27 @@
   sb.write('''
 <div class="header" style="left: 0px;">[${options1.join(',')}]</div>
 <div class="header" style="right: 0px;">[${options2.join(',')}]</div>
-<div style="position:absolute;top:22px;width:100%;height:18px;">
+<div style="position:absolute;left:0px;top:22px;width:100%;height:18px;">
   <span class="identical1">&nbsp;&nbsp;&nbsp;</span> 
   <span class="identical2">&nbsp;&nbsp;&nbsp;</span>
   identical blocks
   <span class="corresponding1">&nbsp;&nbsp;&nbsp;</span>
   <span class="corresponding2">&nbsp;&nbsp;&nbsp;</span> 
   corresponding blocks
+''');
+  if (addAnnotations) {
+    sb.write('''
   <span style="$WITH_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
   offset with source information
   <span style="$WITHOUT_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
   offset without source information
   <span style="$ADDITIONAL_SOURCE_INFO_STYLE">&nbsp;&nbsp;&nbsp;</span>
   offset with unneeded source information
+''');
+  }
+  sb.write('''
 </div>
-<table style="position:absolute;top:40px;width:100%;"><tr>
+<table style="position:absolute;left:0px;top:40px;width:100%;"><tr>
 ''');
 
   void addCell(String content) {
@@ -804,7 +816,8 @@
 /// Compute [CodeLine]s and [Coverage] for [filename] using the given [options].
 Future<CodeLinesResult> computeCodeLines(
     List<String> options,
-    String filename) async {
+    String filename,
+    {bool addAnnotations: true}) async {
   SourceMapProcessor processor = new SourceMapProcessor(filename);
   List<SourceMapInfo> sourceMapInfoList =
       await processor.process(options, perElement: false);
@@ -819,29 +832,32 @@
     List<CodeLine> codeLines;
     Coverage coverage = new Coverage();
     List<Annotation> annotations = <Annotation>[];
+
     String code = info.code;
     TraceGraph graph = createTraceGraph(info, coverage);
-    Set<js.Node> mappedNodes = new Set<js.Node>();
-    for (TraceStep step in graph.steps) {
-      int offset;
-      if (options.contains(USE_NEW_SOURCE_INFO)) {
-        offset = step.offset.subexpressionOffset;
-      } else {
-        offset = info.jsCodePositions[step.node].startPosition;
-      }
-      if (offset != null) {
-        int id = step.sourceLocation != null
-            ? WITH_SOURCE_INFO : WITHOUT_SOURCE_INFO;
-        annotations.add(
-            new Annotation(id, offset, null));
-      }
-    }
-    if (!options.contains(USE_NEW_SOURCE_INFO)) {
-      for (js.Node node in info.nodeMap.nodes) {
-        if (!mappedNodes.contains(node)) {
-          int offset = info.jsCodePositions[node].startPosition;
+    if (addAnnotations) {
+      Set<js.Node> mappedNodes = new Set<js.Node>();
+      for (TraceStep step in graph.steps) {
+        int offset;
+        if (options.contains(USE_NEW_SOURCE_INFO)) {
+          offset = step.offset.subexpressionOffset;
+        } else {
+          offset = info.jsCodePositions[step.node].startPosition;
+        }
+        if (offset != null) {
+          int id = step.sourceLocation != null
+              ? WITH_SOURCE_INFO : WITHOUT_SOURCE_INFO;
           annotations.add(
-                      new Annotation(ADDITIONAL_SOURCE_INFO, offset, null));
+              new Annotation(id, offset, null));
+        }
+      }
+      if (!options.contains(USE_NEW_SOURCE_INFO)) {
+        for (js.Node node in info.nodeMap.nodes) {
+          if (!mappedNodes.contains(node)) {
+            int offset = info.jsCodePositions[node].startPosition;
+            annotations.add(
+                        new Annotation(ADDITIONAL_SOURCE_INFO, offset, null));
+          }
         }
       }
     }
diff --git a/tests/compiler/dart2js_extra/deferred_custom_loader_lib.dart b/tests/compiler/dart2js_extra/deferred_custom_loader_lib.dart
new file mode 100644
index 0000000..e863607
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_custom_loader_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+foo() => 499;
diff --git a/tests/compiler/dart2js_extra/deferred_custom_loader_test.dart b/tests/compiler/dart2js_extra/deferred_custom_loader_test.dart
new file mode 100644
index 0000000..4889aca
--- /dev/null
+++ b/tests/compiler/dart2js_extra/deferred_custom_loader_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'deferred_custom_loader_lib.dart' deferred as def;
+
+void setup() native """
+// In d8 we don't have any way to load the content of the file, so just use
+// the preamble's loader.
+if (!self.dartDeferredLibraryLoader) {
+  self.dartDeferredLibraryLoader = function(uri, success, error) {
+    var req = new XMLHttpRequest();
+    req.addEventListener("load", function() {
+      eval(this.responseText);
+      success();
+    });
+    req.open("GET", uri);
+    req.send();
+  };
+}
+""";
+
+
+runTest() async {
+  setup();
+  await def.loadLibrary();
+  Expect.equals(499, def.foo());
+}
+
+main() {
+  asyncStart();
+  runTest().then((_) => asyncEnd());
+}
diff --git a/tests/corelib/corelib.status b/tests/corelib/corelib.status
index 407ea29..586d145 100644
--- a/tests/corelib/corelib.status
+++ b/tests/corelib/corelib.status
@@ -29,9 +29,8 @@
 symbol_reserved_word_test/02: RuntimeError # bug 20191 / dartium/drt cannot detect CompileTimeErrors
 symbol_reserved_word_test/05: RuntimeError # bug 20191 / dartium/drt cannot detect CompileTimeErrors
 
-# new Symbol('void') should be allowed.
 [ $compiler == dart2js ]
-symbol_reserved_word_test/03: RuntimeError # bug 19972
+symbol_reserved_word_test/03: RuntimeError # bug 19972, new Symbol('void') should be allowed.
 int_parse_radix_test/01: Pass, Fail # JS implementations disagree on U+0085 being whitespace.
 int_parse_radix_test/02: Fail # No bigints.
 double_parse_test/01: Pass, Fail # JS implementations disagree on U+0085 being whitespace.
@@ -188,15 +187,8 @@
 
 [ $compiler == dart2js && $cps_ir ]
 data_resource_test: Crash # (await for(var byteSlice in resource.openRead()){streamBytes.addAll(byteSlice);}): await for
-error_stack_trace1_test: Pass # H.unwrapException(...).get$stackTrace is not a function
 package_resource_test: Crash # (await for(var byteSlice in resource.openRead()){streamBytes.addAll(byteSlice);}): await for
 regexp/pcre_test: Crash # Stack Overflow in LoopHierarchy.
-symbol_operator_test/03: RuntimeError # Issue 24878
-symbol_reserved_word_test/03: Pass # Please triage this failure.
-symbol_reserved_word_test/06: RuntimeError # Please triage this failure.
-symbol_reserved_word_test/09: RuntimeError # Please triage this failure.
-symbol_reserved_word_test/12: RuntimeError # Please triage this failure.
-symbol_test/none: RuntimeError # Please triage this failure.
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 regexp/pcre_test: Crash # Stack Overflow
diff --git a/tests/language/accessor_conflict_export2_helper.dart b/tests/language/accessor_conflict_export2_helper.dart
new file mode 100644
index 0000000..a6cf7e0
--- /dev/null
+++ b/tests/language/accessor_conflict_export2_helper.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export "accessor_conflict_setter.dart";
+export "accessor_conflict_getter.dart";
diff --git a/tests/language/accessor_conflict_export2_test.dart b/tests/language/accessor_conflict_export2_test.dart
new file mode 100644
index 0000000..725f8e0
--- /dev/null
+++ b/tests/language/accessor_conflict_export2_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Verify that a getter and its corresponding setter can be imported from two
+// different files via a common export.  In this test the setter is imported
+// first.
+
+import "package:expect/expect.dart";
+
+import "accessor_conflict_export2_helper.dart";
+
+main() {
+  getValue = 123;
+  Expect.equals(x, 123);
+  x = 456;
+  Expect.equals(setValue, 456);
+}
diff --git a/tests/language/accessor_conflict_export_helper.dart b/tests/language/accessor_conflict_export_helper.dart
new file mode 100644
index 0000000..ff065ec
--- /dev/null
+++ b/tests/language/accessor_conflict_export_helper.dart
@@ -0,0 +1,6 @@
+// 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.
+
+export "accessor_conflict_getter.dart";
+export "accessor_conflict_setter.dart";
diff --git a/tests/language/accessor_conflict_export_test.dart b/tests/language/accessor_conflict_export_test.dart
new file mode 100644
index 0000000..bac516c
--- /dev/null
+++ b/tests/language/accessor_conflict_export_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Verify that a getter and its corresponding setter can be imported from two
+// different files via a common export.  In this test the getter is imported
+// first.
+
+import "package:expect/expect.dart";
+
+import "accessor_conflict_export_helper.dart";
+
+main() {
+  getValue = 123;
+  Expect.equals(x, 123);
+  x = 456;
+  Expect.equals(setValue, 456);
+}
diff --git a/tests/language/accessor_conflict_getter.dart b/tests/language/accessor_conflict_getter.dart
new file mode 100644
index 0000000..5b8d72f
--- /dev/null
+++ b/tests/language/accessor_conflict_getter.dart
@@ -0,0 +1,7 @@
+// 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.
+
+var getValue;
+
+get x => getValue;
diff --git a/tests/language/accessor_conflict_import2_test.dart b/tests/language/accessor_conflict_import2_test.dart
new file mode 100644
index 0000000..99a4007
--- /dev/null
+++ b/tests/language/accessor_conflict_import2_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Verify that a getter and its corresponding setter can be imported from two
+// different files.  In this test the setter is imported first.
+
+import "package:expect/expect.dart";
+
+import "accessor_conflict_setter.dart";
+import "accessor_conflict_getter.dart";
+
+main() {
+  getValue = 123;
+  Expect.equals(x, 123);
+  x = 456;
+  Expect.equals(setValue, 456);
+}
diff --git a/tests/language/accessor_conflict_import_prefixed2_test.dart b/tests/language/accessor_conflict_import_prefixed2_test.dart
new file mode 100644
index 0000000..88ab758
--- /dev/null
+++ b/tests/language/accessor_conflict_import_prefixed2_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Verify that a getter and its corresponding setter can be imported from two
+// different files.  In this test the setter is imported first.
+
+import "package:expect/expect.dart";
+
+import "accessor_conflict_setter.dart" as p;
+import "accessor_conflict_getter.dart" as p;
+
+main() {
+  p.getValue = 123;
+  Expect.equals(p.x, 123);
+  p.x = 456;
+  Expect.equals(p.setValue, 456);
+}
diff --git a/tests/language/accessor_conflict_import_prefixed_test.dart b/tests/language/accessor_conflict_import_prefixed_test.dart
new file mode 100644
index 0000000..0c286cb
--- /dev/null
+++ b/tests/language/accessor_conflict_import_prefixed_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Verify that a getter and its corresponding setter can be imported from two
+// different files.  In this test the getter is imported first.
+
+import "package:expect/expect.dart";
+
+import "accessor_conflict_getter.dart" as p;
+import "accessor_conflict_setter.dart" as p;
+
+main() {
+  p.getValue = 123;
+  Expect.equals(p.x, 123);
+  p.x = 456;
+  Expect.equals(p.setValue, 456);
+}
diff --git a/tests/language/accessor_conflict_import_test.dart b/tests/language/accessor_conflict_import_test.dart
new file mode 100644
index 0000000..0b485ce
--- /dev/null
+++ b/tests/language/accessor_conflict_import_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Verify that a getter and its corresponding setter can be imported from two
+// different files.  In this test the getter is imported first.
+
+import "package:expect/expect.dart";
+
+import "accessor_conflict_getter.dart";
+import "accessor_conflict_setter.dart";
+
+main() {
+  getValue = 123;
+  Expect.equals(x, 123);
+  x = 456;
+  Expect.equals(setValue, 456);
+}
diff --git a/tests/language/accessor_conflict_setter.dart b/tests/language/accessor_conflict_setter.dart
new file mode 100644
index 0000000..9dcf67d
--- /dev/null
+++ b/tests/language/accessor_conflict_setter.dart
@@ -0,0 +1,7 @@
+// 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.
+
+var setValue;
+
+set x(value) { setValue = value; }
diff --git a/tests/language/deferred_type_dependency_test.dart b/tests/language/deferred_type_dependency_test.dart
index 766834e..dd285c8 100644
--- a/tests/language/deferred_type_dependency_test.dart
+++ b/tests/language/deferred_type_dependency_test.dart
@@ -7,9 +7,10 @@
 
 import "deferred_type_dependency_lib1.dart" deferred as lib1;
 import "deferred_type_dependency_lib2.dart" deferred as lib2;
+import "package:async_helper/async_helper.dart";
 import "package:expect/expect.dart";
 
-main() async {
+runTest() async {
   await lib1.loadLibrary();
   // Split the cases into a multi-test to test each feature separately.
   Expect.isFalse(
@@ -27,4 +28,9 @@
       (lib2.getInstance())
       is! String /// none: ok
   );
-}
\ No newline at end of file
+}
+
+main() {
+  asyncStart();
+  runTest().then((_) => asyncEnd());
+}
diff --git a/tests/language/language.status b/tests/language/language.status
index 319fdb8..484b88e 100644
--- a/tests/language/language.status
+++ b/tests/language/language.status
@@ -44,6 +44,11 @@
 
 library_env_test: RuntimeError
 
+accessor_conflict_export2_test: RuntimeError # Issue 25625
+accessor_conflict_import2_test: RuntimeError # Issue 25625
+accessor_conflict_import_prefixed2_test: RuntimeError # Issue 25625
+accessor_conflict_import_prefixed_test: RuntimeError # Issue 25625
+
 [ ($compiler == none || $compiler == precompiler) && ($runtime == vm || $runtime == dart_precompiled) ]
 
 class_keyword_test/02: MissingCompileTimeError # Issue 13627
diff --git a/tests/language/language_analyzer2.status b/tests/language/language_analyzer2.status
index f549de2..5f20fea 100644
--- a/tests/language/language_analyzer2.status
+++ b/tests/language/language_analyzer2.status
@@ -484,3 +484,39 @@
 transitive_private_library_access_test: StaticWarning
 
 conflicting_type_variable_and_setter_test: CompileTimeError # Issue 25525
+
+mixin_supertype_subclass_test/02: MissingStaticWarning # Issue 25614
+mixin_supertype_subclass_test/05: MissingStaticWarning # Issue 25614
+mixin_supertype_subclass2_test/02: MissingStaticWarning # Issue 25614
+mixin_supertype_subclass2_test/05: MissingStaticWarning # Issue 25614
+mixin_supertype_subclass3_test/02: MissingStaticWarning # Issue 25614
+mixin_supertype_subclass3_test/05: MissingStaticWarning # Issue 25614
+mixin_supertype_subclass4_test/01: MissingStaticWarning # Issue 25614
+mixin_supertype_subclass4_test/02: MissingStaticWarning # Issue 25614
+mixin_supertype_subclass4_test/03: MissingStaticWarning # Issue 25614
+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
+accessor_conflict_import_prefixed2_test: StaticWarning # Issue 25624
+accessor_conflict_import_prefixed_test: StaticWarning # Issue 25624
+accessor_conflict_import_test: StaticWarning # Issue 25624
diff --git a/tests/language/language_dart2js.status b/tests/language/language_dart2js.status
index a1bb9e3..949b714 100644
--- a/tests/language/language_dart2js.status
+++ b/tests/language/language_dart2js.status
@@ -21,6 +21,11 @@
 deep_nesting2_negative_test: Crash # Issue 25557
 
 call_function_apply_test: RuntimeError # Issue 23873
+mixin_supertype_subclass_test: CompileTimeError # Issue 23773
+mixin_supertype_subclass2_test: CompileTimeError # Issue 23773
+mixin_supertype_subclass3_test: CompileTimeError # Issue 23773
+mixin_supertype_subclass4_test: CompileTimeError # Issue 23773
+mixin_of_mixin_test: CompileTimeError # Issue 23773
 
 # The following tests are supposed to fail.
 # When run for testing dart2js supports all dart:X libraries (because it
@@ -29,6 +34,13 @@
 library_env_test/has_no_io_support: RuntimeError, OK
 library_env_test/has_no_mirror_support: RuntimeError, OK
 
+accessor_conflict_export2_test: Crash # Issue 25626
+accessor_conflict_export_test: Crash # Issue 25626
+accessor_conflict_import2_test: RuntimeError # Issue 25626
+accessor_conflict_import_prefixed2_test: RuntimeError # Issue 25626
+accessor_conflict_import_prefixed_test: RuntimeError # Issue 25626
+accessor_conflict_import_test: RuntimeError # Issue 25626
+
 [ $compiler == dart2js && $runtime == jsshell ]
 await_for_test: Skip # Jsshell does not provide periodic timers, Issue 7728
 async_star_test: RuntimeError # Jsshell does not provide non-zero timers, Issue 7728
@@ -283,6 +295,11 @@
 deferred_super_dependency_test/01: Crash # Class 'PartialMethodElement' has no instance getter 'initializer'.
 field3a_negative_test: Fail # Bogus result from type inference in case of invalid program.
 gc_test: Crash # Internal Error: Pending statics (see above).
+if_null_assignment_static_test/29: Crash # Pending statics: JSArray
+if_null_assignment_static_test/31: Crash # Pending statics: JSArray
+if_null_assignment_static_test/32: Crash # Pending statics: JSArray
+if_null_assignment_static_test/33: Crash # Pending statics: JSArray
+if_null_assignment_static_test/35: Crash # Pending statics: JSArray
 invocation_mirror_test: Crash # (super[37]=42): visitUnresolvedSuperIndexSet
 regress_23500_test/01: Crash # (await for(var c in new Stream.fromIterable([] )){}): await for
 savannah_test: RuntimeError # Success depends on the variable hints.
diff --git a/tests/language/mixin_of_mixin_test.dart b/tests/language/mixin_of_mixin_test.dart
new file mode 100644
index 0000000..005f959
--- /dev/null
+++ b/tests/language/mixin_of_mixin_test.dart
@@ -0,0 +1,59 @@
+// 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.
+// SharedOptions=--supermixin
+
+// Validate the following text from section 12 ("Mixins") of the spec:
+//
+//     "A mixin application of the form S with M; defines a class C ...
+//     ... C declares the same instance members as M ..."
+//
+// This means that if M is itself a mixin application, then things
+// mixed into M are accessible through C.  But if M simply *extends* a
+// mixin application (e.g. because M is declared as `class M extends X
+// with Y { ... }`) then things mixed into the mixin application that
+// M extends are not accessible through C.
+
+class A { a() => null; }
+class B { b() => null; }
+class C { c() => null; }
+class D { d() => null; }
+
+// Note: by a slight abuse of syntax, `class M1 = A with B, C;` effectively
+// means `class M1 = (A with B) with C;`, therefore M1 declares c(), but it
+// merely inherits a() and b().
+class M1 = A with B, C; // declares c()
+
+class M2 extends M1 { m2() => null; }
+class M3 extends A with B, C { m3() => null; }
+class T1 = D with M1; // declares c()
+class T2 = D with M2; // declares m2()
+class T3 = D with M3; // declares m3()
+class T4 extends D with M1 {} // extends a class which declares c()
+class T5 extends D with M2 {} // extends a class which declares m2()
+class T6 extends D with M3 {} // extends a class which declares m3()
+
+main() {
+  new T1().a();  /// 01: static type warning, runtime error
+  new T1().b();  /// 02: static type warning, runtime error
+  new T1().c();  /// 03: 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 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 T4().a();  /// 12: static type warning, runtime error
+  new T4().b();  /// 13: static type warning, runtime error
+  new T4().c();  /// 14: 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 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
+}
diff --git a/tests/language/mixin_supertype_subclass2_test.dart b/tests/language/mixin_supertype_subclass2_test.dart
new file mode 100644
index 0000000..d7ee562
--- /dev/null
+++ b/tests/language/mixin_supertype_subclass2_test.dart
@@ -0,0 +1,30 @@
+// 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.
+// SharedOptions=--supermixin
+
+// Validate the following test from section 12 ("Mixins") of the spec:
+//
+//     "Let M_A be a mixin derived from a class M with direct superclass
+//     S_static.
+//
+//     Let A be an application of M_A.  It is a static warning if the
+//     superclass of A is not a subtype of S_static."
+
+class B {}
+class C {}
+class D {}
+class E extends B with C implements D {}
+class F extends E {}
+class A extends E with M {}
+class M
+  extends B /// 01: ok
+  extends C /// 02: static type warning
+  extends D /// 03: ok
+  extends E /// 04: ok
+  extends F /// 05: static type warning
+  {}
+
+main() {
+  new A();
+}
diff --git a/tests/language/mixin_supertype_subclass3_test.dart b/tests/language/mixin_supertype_subclass3_test.dart
new file mode 100644
index 0000000..7ca889d
--- /dev/null
+++ b/tests/language/mixin_supertype_subclass3_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+// SharedOptions=--supermixin
+
+// Validate the following test from section 12 ("Mixins") of the spec:
+//
+//     "Let M_A be a mixin derived from a class M with direct superclass
+//     S_static.
+//
+//     Let A be an application of M_A.  It is a static warning if the
+//     superclass of A is not a subtype of S_static."
+
+// In this test, M is declared as `class M = S_static with G;`.
+
+class B {}
+class C {}
+class D {}
+class E extends B with C implements D {}
+class F extends E {}
+class A
+  = E with M; class M = B with G; class G /// 01: ok
+  = E with M; class M = C with G; class G /// 02: static type warning
+  = E with M; class M = D with G; class G /// 03: ok
+  = E with M; class M = E with G; class G /// 04: ok
+  = E with M; class M = F with G; class G /// 05: static type warning
+  {}
+
+main() {
+  new A();
+}
diff --git a/tests/language/mixin_supertype_subclass4_test.dart b/tests/language/mixin_supertype_subclass4_test.dart
new file mode 100644
index 0000000..e1a501a
--- /dev/null
+++ b/tests/language/mixin_supertype_subclass4_test.dart
@@ -0,0 +1,36 @@
+// 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.
+// SharedOptions=--supermixin
+
+// Validate the following test from section 12 ("Mixins") of the spec:
+//
+//     "Let M_A be a mixin derived from a class M with direct superclass
+//     S_static.
+//
+//     Let A be an application of M_A.  It is a static warning if the
+//     superclass of A is not a subtype of S_static."
+
+// In this test, M is declared as `class M extends ... with G {}`, so
+// `S_static` is the unnamed mixin application `... with G`.  Since this
+// unnamed mixin application can't be derived from, all the cases should yield
+// a warning.
+
+class B {}
+class C {}
+class D {}
+class E extends B with C implements D {}
+class F extends E {}
+class G {}
+class A = E with M;
+class M
+  extends B with G /// 01: static type warning
+  extends C with G /// 02: static type warning
+  extends D with G /// 03: static type warning
+  extends E with G /// 04: static type warning
+  extends F with G /// 05: static type warning
+  {}
+
+main() {
+  new A();
+}
diff --git a/tests/language/mixin_supertype_subclass_test.dart b/tests/language/mixin_supertype_subclass_test.dart
new file mode 100644
index 0000000..70627f6
--- /dev/null
+++ b/tests/language/mixin_supertype_subclass_test.dart
@@ -0,0 +1,30 @@
+// 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.
+// SharedOptions=--supermixin
+
+// Validate the following test from section 12 ("Mixins") of the spec:
+//
+//     "Let M_A be a mixin derived from a class M with direct superclass
+//     S_static.
+//
+//     Let A be an application of M_A.  It is a static warning if the
+//     superclass of A is not a subtype of S_static."
+
+class B {}
+class C {}
+class D {}
+class E extends B with C implements D {}
+class F extends E {}
+class A = E with M;
+class M
+  extends B /// 01: ok
+  extends C /// 02: static type warning
+  extends D /// 03: ok
+  extends E /// 04: ok
+  extends F /// 05: static type warning
+  {}
+
+main() {
+  new A();
+}
diff --git a/tests/language/regress_24935_test.dart b/tests/language/regress_24935_test.dart
new file mode 100644
index 0000000..53f6f49
--- /dev/null
+++ b/tests/language/regress_24935_test.dart
@@ -0,0 +1,24 @@
+// 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';
+
+S() => new Stream.fromIterable([1]);
+
+Future main() async {
+  L: for (var s = 0; s < 10; s++) {
+    await for (var s1 in S()){
+      await for (var s2 in S()){
+        continue L;
+      }
+    }
+  }
+  // Regression check: make sure throwing an exception
+  // after breaking out of the innermost loop does not
+  // crash the VM. In other words, the expected test
+  // outcome is an unhandled exception.
+  throw "ball"; /// 01: runtime error
+}
+
+
diff --git a/tests/language/regress_25609_lib1.dart b/tests/language/regress_25609_lib1.dart
new file mode 100644
index 0000000..98fdb20
--- /dev/null
+++ b/tests/language/regress_25609_lib1.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library regress_25609_lib1;
+
+import 'regress_25609_lib2.dart';
+
+typedef Bar Foo(int y);
+
diff --git a/tests/language/regress_25609_lib2.dart b/tests/language/regress_25609_lib2.dart
new file mode 100644
index 0000000..d51c061
--- /dev/null
+++ b/tests/language/regress_25609_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+library regress_25609_lib2;
+
+typedef void Bar(double x);
diff --git a/tests/language/regress_25609_test.dart b/tests/language/regress_25609_test.dart
new file mode 100644
index 0000000..579f1c2
--- /dev/null
+++ b/tests/language/regress_25609_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// VMOptions=--error-on-bad-type
+
+import 'regress_25609_lib1.dart';
+
+Foo baz() => null;
+
+main () {
+  baz();
+}
diff --git a/tests/language/regress_25620_test.dart b/tests/language/regress_25620_test.dart
new file mode 100644
index 0000000..7ea9a6f
--- /dev/null
+++ b/tests/language/regress_25620_test.dart
@@ -0,0 +1,8 @@
+// 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";
+typedef Future<T> SyncedExecutionFn<T>(Future<T> fn());
+main() {}
+
diff --git a/tests/lib/convert/base64_test.dart b/tests/lib/convert/base64_test.dart
index ccbed3d..457e330 100644
--- a/tests/lib/convert/base64_test.dart
+++ b/tests/lib/convert/base64_test.dart
@@ -20,6 +20,7 @@
     testRoundtrip(new Uint8List.fromList(list), "Uint8List#${list.length}");
   }
   testErrors();
+  testIssue25577();
 
   // Decoder is lenienet with mixed styles.
   Expect.listEquals([0xfb, 0xff, 0xbf, 0x00], BASE64.decode("-_+/AA%3D="));
@@ -236,3 +237,18 @@
   badEncode(0x100000000);          /// 01: ok
   badEncode(0x10000000000000000);  /// 01: continued
 }
+
+void testIssue25577() {
+  // Regression test for http://dartbug.com/25577
+  // Should not fail in checked mode.
+  StringConversionSink decodeSink =
+      BASE64.decoder.startChunkedConversion(new TestSink<List<int>>());
+  ByteConversionSink encodeSink =
+      BASE64.encoder.startChunkedConversion(new TestSink<String>());
+}
+
+// Implementation of Sink<T> to test type constraints.
+class TestSink<T> implements Sink<T> {
+  void add(T value) {}
+  void close() {}
+}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index f5d5af2..d854ac9 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -338,7 +338,6 @@
 async/async_await_zones_test: Crash # (await for(var x in bar().take(100)){sum+= x;}): await for
 async/stream_iterator_test: Crash # (Stream createCancel...  cannot handle sync*/async* functions
 mirrors/parameter_annotation_mirror_test: Pass, Fail # Issue 25501.  Depends on inlining.
-mirrors/symbol_validation_test/none: RuntimeError # Please triage this failure.
 
 [ $compiler == dart2js && $cps_ir && $host_checked ]
 mirrors/circular_factory_redirection_test/02: Crash # Assertion failure: Constant constructor already computed for generative_constructor(A#circular2)
diff --git a/tests/standalone/io/http_proxy_advanced_test.dart b/tests/standalone/io/http_proxy_advanced_test.dart
index aeafaf0..5be2ad1 100644
--- a/tests/standalone/io/http_proxy_advanced_test.dart
+++ b/tests/standalone/io/http_proxy_advanced_test.dart
@@ -10,11 +10,12 @@
 import 'dart:convert';
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                       password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/http_proxy_test.dart b/tests/standalone/io/http_proxy_test.dart
index e5607e9..83d7640 100644
--- a/tests/standalone/io/http_proxy_test.dart
+++ b/tests/standalone/io/http_proxy_test.dart
@@ -10,11 +10,12 @@
 import 'dart:convert';
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/https_bad_certificate_test.dart b/tests/standalone/io/https_bad_certificate_test.dart
index fdd83e3..7c7f4b8 100644
--- a/tests/standalone/io/https_bad_certificate_test.dart
+++ b/tests/standalone/io/https_bad_certificate_test.dart
@@ -12,11 +12,12 @@
 final HOST_NAME = 'localhost';
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-      password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 class CustomException {}
 
diff --git a/tests/standalone/io/https_client_certificate_test.dart b/tests/standalone/io/https_client_certificate_test.dart
index 24d3978..7047f61 100644
--- a/tests/standalone/io/https_client_certificate_test.dart
+++ b/tests/standalone/io/https_client_certificate_test.dart
@@ -11,19 +11,20 @@
 
 const HOST_NAME = "localhost";
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                       password: 'dartdart');
 // TODO: Specify which client certificate roots to trust.
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'))
 // TODO: Set a client certificate here.
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 void main() {
   asyncStart();
diff --git a/tests/standalone/io/https_server_test.dart b/tests/standalone/io/https_server_test.dart
index 88a8b2a..7f6e28e 100644
--- a/tests/standalone/io/https_server_test.dart
+++ b/tests/standalone/io/https_server_test.dart
@@ -11,11 +11,12 @@
 InternetAddress HOST;
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/https_unauthorized_test.dart b/tests/standalone/io/https_unauthorized_test.dart
index 43f3e53..c96934f 100644
--- a/tests/standalone/io/https_unauthorized_test.dart
+++ b/tests/standalone/io/https_unauthorized_test.dart
@@ -14,11 +14,13 @@
 const CERTIFICATE = "localhost_cert";
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext untrustedServerContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/untrusted_server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/untrusted_server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile(
+      'certificates/untrusted_server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/untrusted_server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/raw_secure_server_closing_test.dart b/tests/standalone/io/raw_secure_server_closing_test.dart
index 63e9cd4..957f873 100644
--- a/tests/standalone/io/raw_secure_server_closing_test.dart
+++ b/tests/standalone/io/raw_secure_server_closing_test.dart
@@ -15,11 +15,12 @@
 
 InternetAddress HOST;
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/raw_secure_server_socket_test.dart b/tests/standalone/io/raw_secure_server_socket_test.dart
index 560722f..2c112b6 100644
--- a/tests/standalone/io/raw_secure_server_socket_test.dart
+++ b/tests/standalone/io/raw_secure_server_socket_test.dart
@@ -15,11 +15,12 @@
 
 InternetAddress HOST;
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                       password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/raw_secure_socket_pause_test.dart b/tests/standalone/io/raw_secure_socket_pause_test.dart
index c3bfc43..cb2dbfe 100644
--- a/tests/standalone/io/raw_secure_socket_pause_test.dart
+++ b/tests/standalone/io/raw_secure_socket_pause_test.dart
@@ -14,11 +14,12 @@
 import "dart:isolate";
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/raw_secure_socket_test.dart b/tests/standalone/io/raw_secure_socket_test.dart
index 9cd54a1..3462c30 100644
--- a/tests/standalone/io/raw_secure_socket_test.dart
+++ b/tests/standalone/io/raw_secure_socket_test.dart
@@ -14,11 +14,12 @@
 import "dart:isolate";
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/regress_21160_test.dart b/tests/standalone/io/regress_21160_test.dart
index 95ccfca..cfeeb2e 100644
--- a/tests/standalone/io/regress_21160_test.dart
+++ b/tests/standalone/io/regress_21160_test.dart
@@ -11,11 +11,12 @@
 import "dart:typed_data";
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_bad_certificate_test.dart b/tests/standalone/io/secure_bad_certificate_test.dart
index 6a7e93a..5510245 100644
--- a/tests/standalone/io/secure_bad_certificate_test.dart
+++ b/tests/standalone/io/secure_bad_certificate_test.dart
@@ -12,11 +12,12 @@
 final HOST_NAME = 'localhost';
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-      password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 class CustomException {}
 
@@ -81,4 +82,4 @@
       Expect.fail('Unknown expectation $result');
     }
   }
-}
\ No newline at end of file
+}
diff --git a/tests/standalone/io/secure_client_raw_server_test.dart b/tests/standalone/io/secure_client_raw_server_test.dart
index 318edeb..7168223 100644
--- a/tests/standalone/io/secure_client_raw_server_test.dart
+++ b/tests/standalone/io/secure_client_raw_server_test.dart
@@ -14,11 +14,12 @@
 import "package:expect/expect.dart";
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_client_server_test.dart b/tests/standalone/io/secure_client_server_test.dart
index b4f3db14..2b47342 100644
--- a/tests/standalone/io/secure_client_server_test.dart
+++ b/tests/standalone/io/secure_client_server_test.dart
@@ -16,11 +16,12 @@
 InternetAddress HOST;
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_multiple_client_server_test.dart b/tests/standalone/io/secure_multiple_client_server_test.dart
index 586105d..f6576ee 100644
--- a/tests/standalone/io/secure_multiple_client_server_test.dart
+++ b/tests/standalone/io/secure_multiple_client_server_test.dart
@@ -17,11 +17,12 @@
 SecureServerSocket SERVER;
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_server_client_certificate_test.dart b/tests/standalone/io/secure_server_client_certificate_test.dart
index c104dba..940ebf6 100644
--- a/tests/standalone/io/secure_server_client_certificate_test.dart
+++ b/tests/standalone/io/secure_server_client_certificate_test.dart
@@ -11,19 +11,20 @@
 InternetAddress HOST;
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-      password: 'dartdart')
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                       password: 'dartdart')
   ..setTrustedCertificates(file: localFile('certificates/client_authority.pem'))
   ..setClientAuthorities(localFile('certificates/client_authority.pem'));
 
 SecurityContext clientCertContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'))
-  ..useCertificateChain(localFile('certificates/client1.pem'))
-  ..usePrivateKey(localFile('certificates/client1_key.pem'),
-      password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/client1.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/client1_key.pem'),
+                                       password: 'dartdart');
 
 SecurityContext clientNoCertContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_server_closing_test.dart b/tests/standalone/io/secure_server_closing_test.dart
index 0677a41..77337a7 100644
--- a/tests/standalone/io/secure_server_closing_test.dart
+++ b/tests/standalone/io/secure_server_closing_test.dart
@@ -16,11 +16,12 @@
 InternetAddress HOST;
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_server_socket_test.dart b/tests/standalone/io/secure_server_socket_test.dart
index 6ef7f27..5bdccfa 100644
--- a/tests/standalone/io/secure_server_socket_test.dart
+++ b/tests/standalone/io/secure_server_socket_test.dart
@@ -16,11 +16,12 @@
 InternetAddress HOST;
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_session_resume_test.dart b/tests/standalone/io/secure_session_resume_test.dart
index 8ec99a4..a5885cc 100644
--- a/tests/standalone/io/secure_session_resume_test.dart
+++ b/tests/standalone/io/secure_session_resume_test.dart
@@ -26,11 +26,12 @@
 InternetAddress HOST;
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_socket_alpn_test.dart b/tests/standalone/io/secure_socket_alpn_test.dart
index 3ad9112..1db5c0c 100644
--- a/tests/standalone/io/secure_socket_alpn_test.dart
+++ b/tests/standalone/io/secure_socket_alpn_test.dart
@@ -15,14 +15,15 @@
     'The maximum message length supported is 2^13-1';
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext clientContext() => new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
 
 SecurityContext serverContext() => new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                    password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 // Tests that client/server with same protocol can securely establish a
 // connection, negotiate the protocol and can send data to each other.
@@ -67,7 +68,7 @@
 }
 
 void testInvalidArgumentServerContext(List<String> protocols,
-                                      String errorIncludes) { 
+                                      String errorIncludes) {
   Expect.throws(() => serverContext().setAlpnProtocols(protocols, true), (e) {
     Expect.isTrue(e is ArgumentError);
     Expect.isTrue(e.toString().contains(errorIncludes));
@@ -76,7 +77,7 @@
 }
 
 void testInvalidArgumentClientContext(List<String> protocols,
-                                      String errorIncludes) { 
+                                      String errorIncludes) {
   Expect.throws(() => clientContext().setAlpnProtocols(protocols, false), (e) {
     Expect.isTrue(e is ArgumentError);
     Expect.isTrue(e.toString().contains(errorIncludes));
diff --git a/tests/standalone/io/secure_socket_renegotiate_test.dart b/tests/standalone/io/secure_socket_renegotiate_test.dart
index 457cee6..906bfd8 100644
--- a/tests/standalone/io/secure_socket_renegotiate_test.dart
+++ b/tests/standalone/io/secure_socket_renegotiate_test.dart
@@ -15,11 +15,12 @@
 
 const HOST_NAME = "localhost";
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 Future<SecureServerSocket> runServer() {
   return SecureServerSocket.bind(HOST_NAME, 0, serverContext)
diff --git a/tests/standalone/io/secure_socket_test.dart b/tests/standalone/io/secure_socket_test.dart
index 897bd84..82fb84c 100644
--- a/tests/standalone/io/secure_socket_test.dart
+++ b/tests/standalone/io/secure_socket_test.dart
@@ -13,11 +13,12 @@
 import "dart:io";
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/secure_unauthorized_test.dart b/tests/standalone/io/secure_unauthorized_test.dart
index a600d74..995130f 100644
--- a/tests/standalone/io/secure_unauthorized_test.dart
+++ b/tests/standalone/io/secure_unauthorized_test.dart
@@ -12,11 +12,13 @@
 
 const HOST_NAME = "localhost";
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/untrusted_server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/untrusted_server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile(
+      'certificates/untrusted_server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/untrusted_server_key.pem'),
+                         password: 'dartdart');
 
 Future<SecureServerSocket> runServer() {
   return SecureServerSocket.bind(HOST_NAME, 0, serverContext)
diff --git a/tests/standalone/io/security_context_argument_test.dart b/tests/standalone/io/security_context_argument_test.dart
index 5e263f6..4048afd4 100644
--- a/tests/standalone/io/security_context_argument_test.dart
+++ b/tests/standalone/io/security_context_argument_test.dart
@@ -6,35 +6,39 @@
 import "dart:io";
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 bool printException(e) { print(e); return true; }
 bool argumentError(e) => e is ArgumentError;
 bool argumentOrTypeError(e) => e is ArgumentError || e is TypeError;
+bool fileSystemException(e) => e is FileSystemException;
 bool tlsException(e) => e is TlsException;
 
 void testUsePrivateKeyArguments() {
     var c = new SecurityContext();
-    c.useCertificateChain(localFile('certificates/server_chain.pem'));
-    Expect.throws(() => c.usePrivateKey(
-          localFile('certificates/server_key.pem'), password: "dart" * 1000),
+    c.useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'));
+    Expect.throws(() => c.usePrivateKeyBytes(
+          readLocalFile('certificates/server_key.pem'),
+                        password: "dart" * 1000),
         argumentError);
-    Expect.throws(() => c.usePrivateKey(
-          localFile('certificates/server_key.pem')),
+    Expect.throws(() => c.usePrivateKeyBytes(
+          readLocalFile('certificates/server_key.pem')),
         tlsException);
-    Expect.throws(() => c.usePrivateKey(
-          localFile('certificates/server_key.pem'), password: "iHackSites"),
+    Expect.throws(() => c.usePrivateKeyBytes(
+          readLocalFile('certificates/server_key.pem'), password: "iHackSites"),
         tlsException);
-    Expect.throws(() => c.usePrivateKey(
-          localFile('certificates/server_key_oops.pem'), password: "dartdart"),
-        tlsException);
-    Expect.throws(() => c.usePrivateKey(1), argumentOrTypeError);
-    Expect.throws(() => c.usePrivateKey(null), argumentError);
-    Expect.throws(() => c.usePrivateKey(
-          localFile('certificates/server_key_oops.pem'), password: 3),
-        argumentOrTypeError);
-    c.usePrivateKey(
-        localFile('certificates/server_key.pem'), password: "dartdart");
-}    
+    Expect.throws(() => c.usePrivateKeyBytes(
+          readLocalFile('certificates/server_key_oops.pem'),
+                        password: "dartdart"),
+        fileSystemException);
+    Expect.throws(() => c.usePrivateKeyBytes(1), argumentOrTypeError);
+    Expect.throws(() => c.usePrivateKeyBytes(null), argumentError);
+    Expect.throws(() => c.usePrivateKeyBytes(
+          readLocalFile('certificates/server_key_oops.pem'), password: 3),
+        fileSystemException);
+    c.usePrivateKeyBytes(
+        readLocalFile('certificates/server_key.pem'), password: "dartdart");
+}
 
 void main() {
   testUsePrivateKeyArguments();
diff --git a/tests/standalone/io/socket_upgrade_to_secure_test.dart b/tests/standalone/io/socket_upgrade_to_secure_test.dart
index 5873d00..4cdaa7f 100644
--- a/tests/standalone/io/socket_upgrade_to_secure_test.dart
+++ b/tests/standalone/io/socket_upgrade_to_secure_test.dart
@@ -15,11 +15,12 @@
 
 InternetAddress HOST;
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/web_socket_compression_test.dart b/tests/standalone/io/web_socket_compression_test.dart
index e25bc1b..6d2d84c 100644
--- a/tests/standalone/io/web_socket_compression_test.dart
+++ b/tests/standalone/io/web_socket_compression_test.dart
@@ -23,11 +23,12 @@
 const String HOST_NAME = 'localhost';
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 class SecurityConfiguration {
   final bool secure;
diff --git a/tests/standalone/io/web_socket_error_test.dart b/tests/standalone/io/web_socket_error_test.dart
index cc16bde..a9ed84a 100644
--- a/tests/standalone/io/web_socket_error_test.dart
+++ b/tests/standalone/io/web_socket_error_test.dart
@@ -26,11 +26,12 @@
 const String HOST_NAME = 'localhost';
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/io/web_socket_test.dart b/tests/standalone/io/web_socket_test.dart
index 695b2cd..ab37e93 100644
--- a/tests/standalone/io/web_socket_test.dart
+++ b/tests/standalone/io/web_socket_test.dart
@@ -22,11 +22,12 @@
 const String HOST_NAME = 'localhost';
 
 String localFile(path) => Platform.script.resolve(path).toFilePath();
+List<int> readLocalFile(path) => (new File(localFile(path))).readAsBytesSync();
 
 SecurityContext serverContext = new SecurityContext()
-  ..useCertificateChain(localFile('certificates/server_chain.pem'))
-  ..usePrivateKey(localFile('certificates/server_key.pem'),
-                  password: 'dartdart');
+  ..useCertificateChainBytes(readLocalFile('certificates/server_chain.pem'))
+  ..usePrivateKeyBytes(readLocalFile('certificates/server_key.pem'),
+                         password: 'dartdart');
 
 SecurityContext clientContext = new SecurityContext()
   ..setTrustedCertificates(file: localFile('certificates/trusted_certs.pem'));
diff --git a/tests/standalone/javascript_int_overflow_literal_test.dart b/tests/standalone/javascript_int_overflow_literal_test.dart
index 2d45ef0..d54df3a 100644
--- a/tests/standalone/javascript_int_overflow_literal_test.dart
+++ b/tests/standalone/javascript_int_overflow_literal_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// VMOptions=--throw_on_javascript_int_overflow
+// VMOptions=--throw_on_javascript_int_overflow --print_stacktrace_at_throw
 
 
 import "package:expect/expect.dart";
diff --git a/tests/standalone/javascript_int_overflow_test.dart b/tests/standalone/javascript_int_overflow_test.dart
index 3a5b932..2661cd2 100644
--- a/tests/standalone/javascript_int_overflow_test.dart
+++ b/tests/standalone/javascript_int_overflow_test.dart
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// VMOptions=--throw_on_javascript_int_overflow --optimization_counter_threshold=10 --no-use-osr
+// VMOptions=--throw_on_javascript_int_overflow --print_stacktrace_at_throw --optimization_counter_threshold=10 --no-use-osr
 
 
 import "package:expect/expect.dart";
diff --git a/tests/standalone/standalone.status b/tests/standalone/standalone.status
index 8b09928..2804e49 100644
--- a/tests/standalone/standalone.status
+++ b/tests/standalone/standalone.status
@@ -26,6 +26,9 @@
 package/package_isolate_test: Fail # Issue 12474
 io/observatory_test: Fail
 package/scenarios/invalid/same_package_twice_test: Pass # Issue 24119
+javascript_int_overflow_test: Skip  # Fails if the bot's uptime becomes too high.
+javascript_int_overflow_literal_test: Skip  # Fails if the bot's uptime becomes too high.
+
 
 [ ($runtime == vm || $runtime == dart_precompiled) && $checked ]
 # These tests have type errors on purpose.
@@ -46,6 +49,14 @@
 # of allowed open files ('ulimit -n' says something like 256).
 io/socket_many_connections_test: Skip
 
+[ $runtime == vm && $system == linux ]
+# These tests have started timing out and issue 25649 has been filed to
+# investigate, skipping these tests temporarily to get the bots to be
+# green again.
+io/http_proxy_test: Skip
+io/secure_builtin_roots_test: Skip
+
+
 [ ($compiler == none || $compiler == precompiler) && ($runtime == drt || $runtime == dartium || $runtime == ContentShellOnAndroid) ]
 typed_array_test: RuntimeError, OK  # Uses Isolate.spawn
 typed_array_int64_uint64_test: RuntimeError, OK  # Uses Isolate.spawn
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index 4a2c46d..63b6b4b 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -16,3 +16,4 @@
 Purple is the new green.
 googlecode back up
 CIT outage - all slaves rebooted
+Authentication failure flake - rerun all bots
diff --git a/tools/VERSION b/tools/VERSION
index a14f088..37bc6da 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 1
 MINOR 15
 PATCH 0
-PRERELEASE 0
+PRERELEASE 1
 PRERELEASE_PATCH 0
diff --git a/tools/bots/bot_utils.py b/tools/bots/bot_utils.py
index 53bd1ca..1feaf2c 100644
--- a/tools/bots/bot_utils.py
+++ b/tools/bots/bot_utils.py
@@ -199,13 +199,11 @@
     self.channel = channel
     self.bucket = 'gs://dartlang-api-docs'
 
-  def docs_dirpath(self, revision):
-    assert len('%s' % revision) > 0
-    return '%s/channels/%s/%s' % (self.bucket, self.channel, revision)
-
   def dartdocs_dirpath(self, revision):
     assert len('%s' % revision) > 0
-    return '%s/gen-dartdocs/%s' % (self.bucket, revision)
+    if self.channel == Channel.BLEEDING_EDGE:
+      return '%s/gen-dartdocs/builds/%s' % (self.bucket, revision)
+    return '%s/gen-dartdocs/%s/%s' % (self.bucket, self.channel, revision)
 
   def docs_latestpath(self, revision):
     assert len('%s' % revision) > 0
diff --git a/tools/observatory_tool.py b/tools/observatory_tool.py
index a8595dc..fb3f364 100755
--- a/tools/observatory_tool.py
+++ b/tools/observatory_tool.py
@@ -135,6 +135,7 @@
       # development flow.
       # REMOVE THE FOLLOWING LINE TO USE the dart_bootstrap binary.
       # return False
+    print >> sys.stderr, ('Running command "%s"') % (executable + command)
     return subprocess.call(executable + command,
                            stdout=silent_sink if silent else None,
                            stderr=silent_sink if silent else None)