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